summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT2
-rw-r--r--Makefile.inc110
-rw-r--r--ObsoleteFiles.inc9
-rw-r--r--UPDATING25
-rw-r--r--bin/chmod/chmod.18
-rw-r--r--bin/dd/dd.17
-rw-r--r--bin/kenv/kenv.122
-rw-r--r--bin/ln/ln.113
-rw-r--r--bin/pax/file_subs.c40
-rw-r--r--bin/test/test.12
-rw-r--r--cddl/contrib/opensolaris/cmd/zinject/zinject.c1
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c6
-rw-r--r--contrib/bind9/CHANGES8
-rw-r--r--contrib/bind9/lib/dns/api2
-rw-r--r--contrib/bind9/lib/dns/openssldsa_link.c4
-rw-r--r--contrib/bind9/lib/dns/opensslrsa_link.c4
-rw-r--r--contrib/bind9/lib/isc/unix/socket.c7
-rw-r--r--contrib/bind9/version6
-rw-r--r--contrib/csup/GNUmakefile5
-rw-r--r--contrib/csup/Makefile5
-rw-r--r--contrib/csup/TODO1
-rw-r--r--contrib/csup/config.c5
-rw-r--r--contrib/csup/csup.12
-rw-r--r--contrib/csup/detailer.c282
-rw-r--r--contrib/csup/diff.c238
-rw-r--r--contrib/csup/diff.h4
-rw-r--r--contrib/csup/fattr.c53
-rw-r--r--contrib/csup/fattr.h3
-rw-r--r--contrib/csup/keyword.c23
-rw-r--r--contrib/csup/keyword.h1
-rw-r--r--contrib/csup/lex.rcs.c2094
-rw-r--r--contrib/csup/lister.c130
-rw-r--r--contrib/csup/misc.c153
-rw-r--r--contrib/csup/misc.h40
-rw-r--r--contrib/csup/mux.c1
-rw-r--r--contrib/csup/proto.c33
-rw-r--r--contrib/csup/proto.h1
-rw-r--r--contrib/csup/rcsfile.c1367
-rw-r--r--contrib/csup/rcsfile.h73
-rw-r--r--contrib/csup/rcsparse.c357
-rw-r--r--contrib/csup/rcsparse.h41
-rw-r--r--contrib/csup/rcstokenizer.h333
-rw-r--r--contrib/csup/rcstokenizer.l73
-rw-r--r--contrib/csup/rsyncfile.c223
-rw-r--r--contrib/csup/rsyncfile.h41
-rw-r--r--contrib/csup/status.c32
-rw-r--r--contrib/csup/stream.c231
-rw-r--r--contrib/csup/stream.h14
-rw-r--r--contrib/csup/updater.c1032
-rw-r--r--contrib/file/AUTHORS1
-rw-r--r--contrib/file/COPYING (renamed from contrib/file/LEGAL.NOTICE)2
-rw-r--r--contrib/file/ChangeLog273
-rw-r--r--contrib/file/FREEBSD-upgrade8
-rw-r--r--contrib/file/INSTALL234
-rw-r--r--contrib/file/MAINT5
-rw-r--r--contrib/file/Magdir/adventure10
-rw-r--r--contrib/file/Magdir/animation397
-rw-r--r--contrib/file/Magdir/apple31
-rw-r--r--contrib/file/Magdir/archive71
-rw-r--r--contrib/file/Magdir/audio92
-rw-r--r--contrib/file/Magdir/c-lang13
-rw-r--r--contrib/file/Magdir/c641
-rw-r--r--contrib/file/Magdir/cafebabe20
-rw-r--r--contrib/file/Magdir/cddb3
-rw-r--r--contrib/file/Magdir/clarion26
-rw-r--r--contrib/file/Magdir/commands42
-rw-r--r--contrib/file/Magdir/compress37
-rw-r--r--contrib/file/Magdir/console12
-rw-r--r--contrib/file/Magdir/cracklib2
-rw-r--r--contrib/file/Magdir/ctags3
-rw-r--r--contrib/file/Magdir/database26
-rw-r--r--contrib/file/Magdir/diff16
-rw-r--r--contrib/file/Magdir/dump38
-rw-r--r--contrib/file/Magdir/elf77
-rw-r--r--contrib/file/Magdir/erlang18
-rw-r--r--contrib/file/Magdir/filesystems136
-rw-r--r--contrib/file/Magdir/flash3
-rw-r--r--contrib/file/Magdir/fonts9
-rw-r--r--contrib/file/Magdir/fortran1
-rw-r--r--contrib/file/Magdir/frame14
-rw-r--r--contrib/file/Magdir/freebsd4
-rw-r--r--contrib/file/Magdir/fsav10
-rw-r--r--contrib/file/Magdir/games110
-rw-r--r--contrib/file/Magdir/gimp4
-rw-r--r--contrib/file/Magdir/gnome-keyring23
-rw-r--r--contrib/file/Magdir/gnu8
-rw-r--r--contrib/file/Magdir/gnumeric7
-rw-r--r--contrib/file/Magdir/graphviz7
-rw-r--r--contrib/file/Magdir/hp104
-rw-r--r--contrib/file/Magdir/iff3
-rw-r--r--contrib/file/Magdir/images151
-rw-r--r--contrib/file/Magdir/inform8
-rw-r--r--contrib/file/Magdir/java3
-rw-r--r--contrib/file/Magdir/jpeg9
-rw-r--r--contrib/file/Magdir/kde10
-rw-r--r--contrib/file/Magdir/lex9
-rw-r--r--contrib/file/Magdir/linux34
-rw-r--r--contrib/file/Magdir/lisp36
-rw-r--r--contrib/file/Magdir/llvm10
-rw-r--r--contrib/file/Magdir/lua19
-rw-r--r--contrib/file/Magdir/luks12
-rw-r--r--contrib/file/Magdir/macintosh132
-rw-r--r--contrib/file/Magdir/mail.news14
-rw-r--r--contrib/file/Magdir/mathcad7
-rw-r--r--contrib/file/Magdir/mathematica4
-rw-r--r--contrib/file/Magdir/mercurial12
-rw-r--r--contrib/file/Magdir/misctools14
-rw-r--r--contrib/file/Magdir/mozilla8
-rw-r--r--contrib/file/Magdir/msdos335
-rw-r--r--contrib/file/Magdir/mup2
-rw-r--r--contrib/file/Magdir/netware6
-rw-r--r--contrib/file/Magdir/ole2compounddocs13
-rw-r--r--contrib/file/Magdir/os25
-rw-r--r--contrib/file/Magdir/palm2
-rw-r--r--contrib/file/Magdir/pdf3
-rw-r--r--contrib/file/Magdir/perl48
-rw-r--r--contrib/file/Magdir/pgp23
-rw-r--r--contrib/file/Magdir/pkgadd1
-rw-r--r--contrib/file/Magdir/printer33
-rw-r--r--contrib/file/Magdir/psion2
-rw-r--r--contrib/file/Magdir/revision10
-rw-r--r--contrib/file/Magdir/riff6
-rw-r--r--contrib/file/Magdir/rpm3
-rw-r--r--contrib/file/Magdir/rtf13
-rw-r--r--contrib/file/Magdir/ruby10
-rw-r--r--contrib/file/Magdir/sc1
-rw-r--r--contrib/file/Magdir/scientific13
-rw-r--r--contrib/file/Magdir/securitycerts3
-rw-r--r--contrib/file/Magdir/sgi18
-rw-r--r--contrib/file/Magdir/sgml60
-rw-r--r--contrib/file/Magdir/sharc8
-rw-r--r--contrib/file/Magdir/sketch3
-rw-r--r--contrib/file/Magdir/softquad10
-rw-r--r--contrib/file/Magdir/spectrum11
-rw-r--r--contrib/file/Magdir/tex60
-rw-r--r--contrib/file/Magdir/troff38
-rw-r--r--contrib/file/Magdir/unicode7
-rw-r--r--contrib/file/Magdir/uuencode15
-rw-r--r--contrib/file/Magdir/varied.script6
-rw-r--r--contrib/file/Magdir/vorbis28
-rw-r--r--contrib/file/Magdir/warc6
-rw-r--r--contrib/file/Magdir/weak15
-rw-r--r--contrib/file/Magdir/windows115
-rw-r--r--contrib/file/Magdir/wordprocessors30
-rw-r--r--contrib/file/Magdir/xilinx34
-rw-r--r--contrib/file/Makefile.am435
-rw-r--r--contrib/file/Makefile.in451
-rw-r--r--contrib/file/Makefile.std167
-rw-r--r--contrib/file/NEWS1
-rw-r--r--contrib/file/PORTING0
-rw-r--r--contrib/file/README38
-rw-r--r--contrib/file/TODO9
-rw-r--r--contrib/file/acinclude.m4240
-rw-r--r--contrib/file/aclocal.m463
-rw-r--r--contrib/file/apprentice.c622
-rw-r--r--contrib/file/ascmagic.c198
-rw-r--r--contrib/file/asprintf.c (renamed from contrib/file/test.c)42
-rwxr-xr-xcontrib/file/compile142
-rw-r--r--contrib/file/compress.c11
-rwxr-xr-xcontrib/file/config.guess1504
-rw-r--r--contrib/file/config.h.in114
-rwxr-xr-xcontrib/file/config.sub1622
-rwxr-xr-xcontrib/file/configure1754
-rw-r--r--contrib/file/configure.ac151
-rw-r--r--contrib/file/configure.in139
-rw-r--r--contrib/file/elfclass.h69
-rw-r--r--contrib/file/file.c93
-rw-r--r--contrib/file/file.h152
-rw-r--r--contrib/file/file.man155
-rw-r--r--contrib/file/fsmagic.c165
-rw-r--r--contrib/file/funcs.c151
-rw-r--r--contrib/file/getopt_long.c496
-rw-r--r--contrib/file/is_tar.c7
-rw-r--r--contrib/file/libmagic.man13
-rw-r--r--contrib/file/magic.c70
-rw-r--r--contrib/file/magic.h5
-rw-r--r--contrib/file/magic.man199
-rw-r--r--contrib/file/magic.mime991
-rw-r--r--[-rwxr-xr-x]contrib/file/magic2mime0
-rw-r--r--contrib/file/mkinstalldirs161
-rw-r--r--contrib/file/mygetopt.h68
-rw-r--r--contrib/file/names.h29
-rw-r--r--contrib/file/patchlevel.h13
-rw-r--r--contrib/file/print.c14
-rw-r--r--contrib/file/readelf.c518
-rw-r--r--contrib/file/readelf.h81
-rw-r--r--contrib/file/softmagic.c191
-rw-r--r--contrib/file/tar.h64
-rw-r--r--contrib/file/tests/Makefile.am11
-rw-r--r--contrib/file/tests/Makefile.in455
-rw-r--r--contrib/file/tests/README17
-rw-r--r--contrib/file/tests/gedcom.magic6
-rw-r--r--contrib/file/tests/gedcom.result1
-rw-r--r--contrib/file/tests/gedcom.testfile8
-rw-r--r--contrib/file/tests/test.c114
-rw-r--r--contrib/file/vasprintf.c641
-rw-r--r--contrib/gdtoa/README13
-rw-r--r--contrib/gdtoa/g_Qfmt.c15
-rw-r--r--contrib/gdtoa/g__fmt.c70
-rw-r--r--contrib/gdtoa/g_ddfmt.c23
-rw-r--r--contrib/gdtoa/g_dfmt.c22
-rw-r--r--contrib/gdtoa/g_ffmt.c15
-rw-r--r--contrib/gdtoa/g_xLfmt.c15
-rw-r--r--contrib/gdtoa/g_xfmt.c15
-rw-r--r--contrib/gdtoa/gdtoa.c12
-rw-r--r--contrib/gdtoa/gdtoa.h13
-rw-r--r--contrib/gdtoa/gdtoa_fltrnds.h18
-rw-r--r--contrib/gdtoa/gdtoaimp.h18
-rw-r--r--contrib/gdtoa/gethex.c63
-rw-r--r--contrib/gdtoa/makefile8
-rw-r--r--contrib/gdtoa/smisc.c8
-rw-r--r--contrib/gdtoa/strtod.c46
-rw-r--r--contrib/gdtoa/strtodg.c39
-rw-r--r--contrib/gdtoa/strtof.c13
-rw-r--r--contrib/gdtoa/strtopQ.c9
-rw-r--r--contrib/gdtoa/strtopd.c7
-rw-r--r--contrib/gdtoa/strtopdd.c11
-rw-r--r--contrib/gdtoa/strtopf.c9
-rw-r--r--contrib/gdtoa/strtopx.c9
-rw-r--r--contrib/gdtoa/strtopxL.c9
-rw-r--r--contrib/gdtoa/test/README9
-rw-r--r--contrib/gdtoa/test/getround.c21
-rw-r--r--contrib/gdtoa/test/makefile17
-rw-r--r--contrib/gdtoa/test/obad/strtodt.out6
-rw-r--r--contrib/gdtoa/test/obad/xL.out1460
-rw-r--r--contrib/gdtoa/test/xsum0.out6
-rw-r--r--contrib/gdtoa/xsum0.out47
-rw-r--r--contrib/lukemftpd/src/extern.h2
-rw-r--r--contrib/lukemftpd/src/ftpcmd.y39
-rw-r--r--contrib/lukemftpd/src/ftpd.c10
-rw-r--r--contrib/ntp/ntpd/ntp_crypto.c2
-rw-r--r--contrib/openbsm/INSTALL6
-rw-r--r--contrib/openbsm/Makefile.am12
-rw-r--r--contrib/openbsm/Makefile.in16
-rw-r--r--contrib/openbsm/NEWS66
-rw-r--r--contrib/openbsm/README5
-rw-r--r--contrib/openbsm/TODO4
-rw-r--r--contrib/openbsm/VERSION2
-rw-r--r--contrib/openbsm/bin/Makefile.in2
-rw-r--r--contrib/openbsm/bin/audit/Makefile.am10
-rw-r--r--contrib/openbsm/bin/audit/Makefile.in16
-rw-r--r--contrib/openbsm/bin/audit/audit.823
-rw-r--r--contrib/openbsm/bin/audit/audit.c33
-rw-r--r--contrib/openbsm/bin/auditd/Makefile.am18
-rw-r--r--contrib/openbsm/bin/auditd/Makefile.in41
-rw-r--r--contrib/openbsm/bin/auditd/audit_warn.c15
-rw-r--r--contrib/openbsm/bin/auditd/auditd.856
-rw-r--r--contrib/openbsm/bin/auditd/auditd.c1190
-rw-r--r--contrib/openbsm/bin/auditd/auditd.h39
-rw-r--r--contrib/openbsm/bin/auditd/auditd_darwin.c484
-rw-r--r--contrib/openbsm/bin/auditd/auditd_fbsd.c274
-rw-r--r--contrib/openbsm/bin/auditfilterd/Makefile.in2
-rw-r--r--contrib/openbsm/bin/auditreduce/Makefile.in2
-rw-r--r--contrib/openbsm/bin/auditreduce/auditreduce.c7
-rw-r--r--contrib/openbsm/bin/praudit/Makefile.in2
-rw-r--r--contrib/openbsm/bsm/Makefile.am3
-rw-r--r--contrib/openbsm/bsm/Makefile.in3
-rw-r--r--contrib/openbsm/bsm/audit_uevents.h96
-rw-r--r--contrib/openbsm/bsm/auditd_lib.h105
-rw-r--r--contrib/openbsm/bsm/libbsm.h40
-rw-r--r--contrib/openbsm/compat/endian.h4
-rw-r--r--contrib/openbsm/config/config.h12
-rw-r--r--contrib/openbsm/config/config.h.in6
-rwxr-xr-xcontrib/openbsm/configure93
-rw-r--r--contrib/openbsm/configure.ac25
-rw-r--r--contrib/openbsm/etc/audit_event127
-rw-r--r--contrib/openbsm/libauditd/Makefile.am17
-rw-r--r--contrib/openbsm/libauditd/Makefile.in525
-rw-r--r--contrib/openbsm/libauditd/auditd_lib.c867
-rw-r--r--contrib/openbsm/libauditd/libauditd.360
-rw-r--r--contrib/openbsm/libbsm/Makefile.am8
-rw-r--r--contrib/openbsm/libbsm/Makefile.in24
-rw-r--r--contrib/openbsm/libbsm/au_domain.387
-rw-r--r--contrib/openbsm/libbsm/au_errno.3111
-rw-r--r--contrib/openbsm/libbsm/au_socket_type.393
-rw-r--r--contrib/openbsm/libbsm/au_token.315
-rw-r--r--contrib/openbsm/libbsm/audit_submit.37
-rw-r--r--contrib/openbsm/libbsm/bsm_audit.c35
-rw-r--r--contrib/openbsm/libbsm/bsm_class.c32
-rw-r--r--contrib/openbsm/libbsm/bsm_control.c84
-rw-r--r--contrib/openbsm/libbsm/bsm_domain.c499
-rw-r--r--contrib/openbsm/libbsm/bsm_errno.c661
-rw-r--r--contrib/openbsm/libbsm/bsm_event.c26
-rw-r--r--contrib/openbsm/libbsm/bsm_io.c108
-rw-r--r--contrib/openbsm/libbsm/bsm_mask.c16
-rw-r--r--contrib/openbsm/libbsm/bsm_socket_type.c104
-rw-r--r--contrib/openbsm/libbsm/bsm_token.c197
-rw-r--r--contrib/openbsm/libbsm/bsm_user.c24
-rw-r--r--contrib/openbsm/libbsm/bsm_wrappers.c57
-rw-r--r--contrib/openbsm/libbsm/libbsm.322
-rw-r--r--contrib/openbsm/man/Makefile.in2
-rw-r--r--contrib/openbsm/man/audit.log.532
-rw-r--r--contrib/openbsm/man/audit_user.56
-rw-r--r--contrib/openbsm/modules/Makefile.in2
-rw-r--r--contrib/openbsm/modules/auditfilter_noop/Makefile.in2
-rw-r--r--contrib/openbsm/sys/Makefile.in2
-rw-r--r--contrib/openbsm/sys/bsm/Makefile.am7
-rw-r--r--contrib/openbsm/sys/bsm/Makefile.in12
-rw-r--r--contrib/openbsm/sys/bsm/audit.h45
-rw-r--r--contrib/openbsm/sys/bsm/audit_domain.h114
-rw-r--r--contrib/openbsm/sys/bsm/audit_errno.h214
-rw-r--r--contrib/openbsm/sys/bsm/audit_internal.h4
-rw-r--r--contrib/openbsm/sys/bsm/audit_kevents.h85
-rw-r--r--contrib/openbsm/sys/bsm/audit_record.h39
-rw-r--r--contrib/openbsm/sys/bsm/audit_socket_type.h46
-rw-r--r--contrib/openbsm/test/Makefile.in2
-rw-r--r--contrib/openbsm/test/bsm/Makefile.in2
-rw-r--r--contrib/openbsm/test/bsm/generate.c144
-rw-r--r--contrib/openbsm/test/reference/E2BIG_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EACCES_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EBADF_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EBUSY_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ECHILD_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EDEADLK_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EEXIST_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EFAULT_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EFBIG_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EINTR_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EINVAL_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EIO_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EISDIR_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EMFILE_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EMLINK_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENFILE_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENODEV_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOENT_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOEXEC_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOMEM_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOSPC_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOTBLK_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOTDIR_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENOTTY_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ENXIO_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EPERM_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EPIPE_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EROFS_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ESPIPE_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ESRCH_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/ETXTBSY_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/EXDEV_recordbin0 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/arg32_recordbin50 -> 50 bytes
-rw-r--r--contrib/openbsm/test/reference/data_recordbin39 -> 39 bytes
-rw-r--r--contrib/openbsm/test/reference/data_tokenbin14 -> 14 bytes
-rw-r--r--contrib/openbsm/test/reference/file_recordbin41 -> 41 bytes
-rw-r--r--contrib/openbsm/test/reference/header32_tokenbin18 -> 18 bytes
-rw-r--r--contrib/openbsm/test/reference/in_addr_recordbin30 -> 30 bytes
-rw-r--r--contrib/openbsm/test/reference/ip_recordbin46 -> 46 bytes
-rw-r--r--contrib/openbsm/test/reference/ipc_recordbin31 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/iport_recordbin28 -> 28 bytes
-rw-r--r--contrib/openbsm/test/reference/opaque_recordbin32 -> 32 bytes
-rw-r--r--contrib/openbsm/test/reference/path_recordbin49 -> 49 bytes
-rw-r--r--contrib/openbsm/test/reference/process32_recordbin62 -> 62 bytes
-rw-r--r--contrib/openbsm/test/reference/process32ex_record-IPv4bin66 -> 66 bytes
-rw-r--r--contrib/openbsm/test/reference/process32ex_record-IPv6bin78 -> 78 bytes
-rw-r--r--contrib/openbsm/test/reference/process64_recordbin66 -> 66 bytes
-rw-r--r--contrib/openbsm/test/reference/process64ex_record-IPv4bin70 -> 70 bytes
-rw-r--r--contrib/openbsm/test/reference/process64ex_record-IPv6bin82 -> 82 bytes
-rw-r--r--contrib/openbsm/test/reference/return32_recordbin31 -> 31 bytes
-rw-r--r--contrib/openbsm/test/reference/return32_token2
-rw-r--r--contrib/openbsm/test/reference/seq_recordbin30 -> 30 bytes
-rw-r--r--contrib/openbsm/test/reference/socketex_recordbin0 -> 44 bytes
-rw-r--r--contrib/openbsm/test/reference/socketex_tokenbin0 -> 19 bytes
-rw-r--r--contrib/openbsm/test/reference/subject32_recordbin62 -> 62 bytes
-rw-r--r--contrib/openbsm/test/reference/subject32ex_recordbin78 -> 78 bytes
-rw-r--r--contrib/openbsm/test/reference/text_recordbin44 -> 44 bytes
-rw-r--r--contrib/openbsm/test/reference/zonename_recordbin37 -> 37 bytes
-rw-r--r--contrib/openbsm/tools/Makefile.in2
-rw-r--r--contrib/opie/opiekey.13
-rw-r--r--contrib/smbfs/mount_smbfs/mount_smbfs.85
-rw-r--r--contrib/smbfs/mount_smbfs/mount_smbfs.c2
-rw-r--r--contrib/wpa_supplicant/ChangeLog26
-rw-r--r--contrib/wpa_supplicant/Makefile5
-rw-r--r--contrib/wpa_supplicant/base64.c2
-rw-r--r--contrib/wpa_supplicant/ctrl_iface.c4
-rw-r--r--contrib/wpa_supplicant/ctrl_iface_dbus.c4
-rw-r--r--contrib/wpa_supplicant/ctrl_iface_unix.c2
-rw-r--r--contrib/wpa_supplicant/dbus_dict_helpers.c102
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_background.82
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_cli.825
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml23
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_passphrase.82
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.855
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.56
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml4
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml61
-rw-r--r--contrib/wpa_supplicant/driver_ndis.c2
-rw-r--r--contrib/wpa_supplicant/eap.c16
-rw-r--r--contrib/wpa_supplicant/eap_aka.c2
-rw-r--r--contrib/wpa_supplicant/eap_gpsk.c14
-rw-r--r--contrib/wpa_supplicant/eap_gpsk_common.c4
-rw-r--r--contrib/wpa_supplicant/eap_ttls.c8
-rw-r--r--contrib/wpa_supplicant/eloop.c24
-rw-r--r--contrib/wpa_supplicant/eloop.h13
-rw-r--r--contrib/wpa_supplicant/eloop_none.c20
-rw-r--r--contrib/wpa_supplicant/mlme.c3
-rw-r--r--contrib/wpa_supplicant/os_unix.c7
-rw-r--r--contrib/wpa_supplicant/preauth_test.c7
-rw-r--r--contrib/wpa_supplicant/radius.c3
-rw-r--r--contrib/wpa_supplicant/sha1.c4
-rw-r--r--contrib/wpa_supplicant/tls_openssl.c10
-rw-r--r--contrib/wpa_supplicant/version.h2
-rw-r--r--contrib/wpa_supplicant/wpa.c8
-rw-r--r--contrib/wpa_supplicant/wpa.h1
-rw-r--r--contrib/wpa_supplicant/wpa_cli.c6
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp1
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/scanresults.cpp2
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp1
-rw-r--r--contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h1
-rw-r--r--contrib/wpa_supplicant/wpa_gui/userdatarequest.ui.h2
-rw-r--r--contrib/wpa_supplicant/wpa_gui/wpagui.ui.h1
-rw-r--r--contrib/wpa_supplicant/wpa_i.h5
-rw-r--r--contrib/wpa_supplicant/wpa_supplicant.c51
-rw-r--r--crypto/openssl/apps/speed.c2
-rw-r--r--crypto/openssl/apps/spkac.c2
-rw-r--r--crypto/openssl/apps/verify.c3
-rw-r--r--crypto/openssl/apps/x509.c2
-rw-r--r--crypto/openssl/ssl/s2_clnt.c2
-rw-r--r--crypto/openssl/ssl/s2_srvr.c4
-rw-r--r--crypto/openssl/ssl/s3_clnt.c6
-rw-r--r--crypto/openssl/ssl/s3_srvr.c2
-rw-r--r--crypto/openssl/ssl/ssltest.c2
-rw-r--r--etc/defaults/rc.conf19
-rw-r--r--etc/devd.conf11
-rw-r--r--etc/network.subr4
-rw-r--r--etc/periodic/weekly/Makefile2
-rwxr-xr-xetc/rc.d/defaultroute18
-rwxr-xr-xetc/rc.d/jail224
-rwxr-xr-xetc/rc.d/named28
-rw-r--r--etc/rc.shutdown2
-rw-r--r--etc/regdomain.xml114
-rw-r--r--games/fortune/datfiles/freebsd-tips4
-rw-r--r--gnu/lib/libstdc++/Makefile1
-rw-r--r--gnu/usr.bin/grep/savedir.c7
-rw-r--r--gnu/usr.bin/man/manpath/manpath.config2
-rw-r--r--include/paths.h8
-rw-r--r--include/stdlib.h4
-rw-r--r--include/string.h4
-rw-r--r--include/wchar.h2
-rw-r--r--lib/Makefile4
-rw-r--r--lib/libarchive/archive_read_support_compression_gzip.c5
-rw-r--r--lib/libarchive/archive_read_support_format_ar.c7
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c7
-rw-r--r--lib/libarchive/archive_write_disk.c82
-rw-r--r--lib/libarchive/test/Makefile2
-rw-r--r--lib/libarchive/test/test_write_disk_failures.c62
-rw-r--r--lib/libarchive/test/test_write_disk_secure.c2
-rw-r--r--lib/libarchive/test/test_write_disk_sparse.c278
-rw-r--r--lib/libauditd/Makefile22
-rw-r--r--lib/libbsm/Makefile13
-rw-r--r--lib/libc/db/man/dbm.32
-rw-r--r--lib/libc/gen/sysctl.38
-rw-r--r--lib/libc/locale/mbstowcs.c4
-rw-r--r--lib/libc/locale/wcsftime.c11
-rw-r--r--lib/libc/locale/wcstombs.c4
-rw-r--r--lib/libc/net/getaddrinfo.357
-rw-r--r--lib/libc/sparc64/sys/__sparc_utrap.c2
-rw-r--r--lib/libc/stdio/ferror.311
-rw-r--r--lib/libc/stdio/fputws.c4
-rw-r--r--lib/libc/stdio/printf.33
-rw-r--r--lib/libc/stdio/printfcommon.h301
-rw-r--r--lib/libc/stdio/vfprintf.c477
-rw-r--r--lib/libc/stdio/vfscanf.c46
-rw-r--r--lib/libc/stdio/vfwprintf.c536
-rw-r--r--lib/libc/stdio/vfwscanf.c26
-rw-r--r--lib/libc/stdio/vswscanf.c4
-rw-r--r--lib/libc/stdio/wsetup.c1
-rw-r--r--lib/libc/string/Makefile.inc53
-rw-r--r--lib/libc/string/ffs.32
-rw-r--r--lib/libc/string/memccpy.c6
-rw-r--r--lib/libc/string/memchr.c5
-rw-r--r--lib/libc/string/memcmp.c4
-rw-r--r--lib/libc/string/memmem.c4
-rw-r--r--lib/libc/string/strcasecmp.c7
-rw-r--r--lib/libc/string/strcasestr.c3
-rw-r--r--lib/libc/string/strcmp.c5
-rw-r--r--lib/libc/string/strcoll.c3
-rw-r--r--lib/libc/string/strdup.c3
-rw-r--r--lib/libc/string/strlcat.c41
-rw-r--r--lib/libc/string/strlcpy.334
-rw-r--r--lib/libc/string/strlen.c93
-rw-r--r--lib/libc/string/strmode.c4
-rw-r--r--lib/libc/string/strncmp.c6
-rw-r--r--lib/libc/string/strncpy.c4
-rw-r--r--lib/libc/string/strnstr.c5
-rw-r--r--lib/libc/string/strpbrk.c5
-rw-r--r--lib/libc/string/strsep.c4
-rw-r--r--lib/libc/string/strstr.c7
-rw-r--r--lib/libc/string/wcscat.c4
-rw-r--r--lib/libc/string/wcscmp.c5
-rw-r--r--lib/libc/string/wcscpy.c4
-rw-r--r--lib/libc/string/wcscspn.c4
-rw-r--r--lib/libc/string/wcslcat.c5
-rw-r--r--lib/libc/string/wcslcpy.c5
-rw-r--r--lib/libc/string/wcslen.c3
-rw-r--r--lib/libc/string/wcsncat.c5
-rw-r--r--lib/libc/string/wcsncmp.c4
-rw-r--r--lib/libc/string/wcspbrk.c4
-rw-r--r--lib/libc/string/wcsspn.c4
-rw-r--r--lib/libc/string/wcsstr.c2
-rw-r--r--lib/libc/string/wmemchr.c5
-rw-r--r--lib/libc/string/wmemcmp.c5
-rw-r--r--lib/libc/string/wmemcpy.c6
-rw-r--r--lib/libc/string/wmemmove.c6
-rw-r--r--lib/libc/string/wmemset.c5
-rw-r--r--lib/libc/sys/jail.28
-rw-r--r--lib/libc/sys/send.24
-rw-r--r--lib/libc/sys/socket.27
-rw-r--r--lib/libc/sys/timer_create.25
-rw-r--r--lib/libelf/README12
-rw-r--r--lib/libmagic/Makefile7
-rw-r--r--lib/libmd/mdX.35
-rw-r--r--lib/libpmc/libpmc.c24
-rw-r--r--lib/libstand/bootp.c2
-rw-r--r--lib/libusb20/libusb20.c2
-rw-r--r--lib/libusb20/libusb20_desc.c42
-rw-r--r--lib/libusbhid/Makefile2
-rw-r--r--lib/libusbhid/descr.c72
-rw-r--r--lib/libusbhid/descr_compat.c77
-rw-r--r--lib/libusbhid/usbhid.315
-rw-r--r--lib/libusbhid/usbhid.h2
-rw-r--r--lib/libusbhid/usbvar.h5
-rw-r--r--lib/msun/src/e_rem_pio2.c2
-rw-r--r--lib/msun/src/e_rem_pio2f.c2
-rw-r--r--lib/msun/src/k_cosf.c2
-rw-r--r--lib/msun/src/k_sinf.c2
-rw-r--r--lib/msun/src/k_tanf.c2
-rw-r--r--lib/msun/src/math.h10
-rw-r--r--libexec/comsat/comsat.c23
-rw-r--r--libexec/ftpd/ftpd.82
-rw-r--r--release/doc/en_US.ISO8859-1/relnotes/article.sgml7
-rw-r--r--sbin/dumpfs/dumpfs.818
-rw-r--r--sbin/dumpfs/dumpfs.c73
-rw-r--r--sbin/fdisk/fdisk.c286
-rw-r--r--sbin/fsck/fsck.89
-rw-r--r--sbin/fsck/fsck.c7
-rw-r--r--sbin/fsck/fsutil.h1
-rw-r--r--sbin/fsck_ffs/fsck.h7
-rw-r--r--sbin/fsck_ffs/fsck_ffs.847
-rw-r--r--sbin/fsck_ffs/fsutil.c96
-rw-r--r--sbin/fsck_ffs/inode.c57
-rw-r--r--sbin/fsck_ffs/main.c26
-rw-r--r--sbin/fsck_ffs/pass1.c81
-rw-r--r--sbin/fsck_ffs/setup.c4
-rw-r--r--sbin/geom/class/virstor/gvirstor.8192
-rw-r--r--sbin/geom/core/geom.c6
-rw-r--r--sbin/ifconfig/ifconfig.862
-rw-r--r--sbin/ifconfig/ifconfig.c4
-rw-r--r--sbin/ifconfig/ifieee80211.c587
-rw-r--r--sbin/ifconfig/regdomain.c7
-rw-r--r--sbin/ifconfig/regdomain.h8
-rw-r--r--sbin/ipfw/Makefile4
-rw-r--r--sbin/ipfw/altq.c150
-rw-r--r--sbin/ipfw/dummynet.c719
-rw-r--r--sbin/ipfw/ipfw.8167
-rw-r--r--sbin/ipfw/ipfw2.c3061
-rw-r--r--sbin/ipfw/ipfw2.h270
-rw-r--r--sbin/ipfw/ipv6.c501
-rw-r--r--sbin/ipfw/main.c539
-rw-r--r--sbin/ipfw/nat.c940
-rw-r--r--sbin/md5/md5.125
-rw-r--r--sbin/mdconfig/mdconfig.81
-rw-r--r--sbin/mdconfig/mdconfig.c12
-rw-r--r--sbin/mount/mount.c71
-rw-r--r--sbin/mount_msdosfs/mount_msdosfs.82
-rw-r--r--sbin/mount_nfs/mount_nfs.c18
-rw-r--r--sbin/mount_ntfs/mount_ntfs.83
-rw-r--r--sbin/ping/ping.822
-rw-r--r--sbin/reboot/reboot.c3
-rw-r--r--sbin/recoverdisk/recoverdisk.c5
-rw-r--r--sbin/restore/interactive.c1
-rw-r--r--sbin/route/route.c53
-rw-r--r--share/examples/cvsup/refuse.README6
-rw-r--r--share/man/man4/Makefile5
-rw-r--r--share/man/man4/ae.49
-rw-r--r--share/man/man4/ath.432
-rw-r--r--share/man/man4/bce.422
-rw-r--r--share/man/man4/bge.44
-rw-r--r--share/man/man4/cd.496
-rw-r--r--share/man/man4/cpuctl.446
-rw-r--r--share/man/man4/gem.43
-rw-r--r--share/man/man4/hme.45
-rw-r--r--share/man/man4/iic.48
-rw-r--r--share/man/man4/man4.powerpc/Makefile4
-rw-r--r--share/man/man4/man4.powerpc/snd_ai2s.490
-rw-r--r--share/man/man4/man4.powerpc/snd_davbus.483
-rw-r--r--share/man/man4/ng_bpf.423
-rw-r--r--share/man/man4/nge.44
-rw-r--r--share/man/man4/rum.41
-rw-r--r--share/man/man4/sdhci.442
-rw-r--r--share/man/man4/sk.46
-rw-r--r--share/man/man4/smb.45
-rw-r--r--share/man/man4/snd_hda.442
-rw-r--r--share/man/man4/snd_ich.414
-rw-r--r--share/man/man4/sysmouse.42
-rw-r--r--share/man/man4/urtw.4118
-rw-r--r--share/man/man5/Makefile1
-rw-r--r--share/man/man5/portindex.5101
-rw-r--r--share/man/man5/rc.conf.557
-rw-r--r--share/man/man7/Makefile3
-rw-r--r--share/man/man7/adding_user.7 (renamed from share/man/man8/adding_user.8)9
-rw-r--r--share/man/man7/build.786
-rw-r--r--share/man/man7/ports.79
-rw-r--r--share/man/man7/tuning.715
-rw-r--r--share/man/man8/Makefile6
-rw-r--r--share/man/man8/alias_sctp.8241
-rw-r--r--share/man/man9/dev_clone.930
-rw-r--r--share/man/man9/domain.92
-rw-r--r--share/man/man9/insmntque.99
-rw-r--r--share/man/man9/kthread.940
-rw-r--r--share/man/man9/lock.919
-rw-r--r--share/man/man9/redzone.94
-rw-r--r--share/misc/bsd-family-tree11
-rw-r--r--share/misc/committers-src.dot3
-rw-r--r--share/misc/pci_vendors2
-rw-r--r--share/mk/bsd.libnames.mk1
-rw-r--r--share/mk/bsd.own.mk4
-rw-r--r--share/zoneinfo/asia4
-rw-r--r--share/zoneinfo/backward3
-rw-r--r--share/zoneinfo/europe63
-rw-r--r--share/zoneinfo/leapseconds23
-rw-r--r--share/zoneinfo/northamerica19
-rw-r--r--share/zoneinfo/zone.tab6
-rw-r--r--sys/amd64/amd64/amd64_mem.c12
-rw-r--r--sys/amd64/amd64/cpu_switch.S19
-rw-r--r--sys/amd64/amd64/exception.S78
-rw-r--r--sys/amd64/amd64/fpu.c5
-rw-r--r--sys/amd64/amd64/identcpu.c78
-rw-r--r--sys/amd64/amd64/initcpu.c75
-rw-r--r--sys/amd64/amd64/io_apic.c57
-rw-r--r--sys/amd64/amd64/local_apic.c84
-rw-r--r--sys/amd64/amd64/machdep.c14
-rw-r--r--sys/amd64/amd64/mp_machdep.c13
-rw-r--r--sys/amd64/amd64/msi.c81
-rw-r--r--sys/amd64/conf/GENERIC22
-rw-r--r--sys/amd64/conf/NOTES16
-rw-r--r--sys/amd64/conf/USB2114
-rw-r--r--sys/amd64/ia32/ia32_signal.c8
-rw-r--r--sys/amd64/ia32/ia32_sigtramp.S8
-rw-r--r--sys/amd64/include/apicvar.h17
-rw-r--r--sys/amd64/include/cpufunc.h18
-rw-r--r--sys/amd64/include/cputypes.h2
-rw-r--r--sys/amd64/include/fpu.h1
-rw-r--r--sys/amd64/include/intr_machdep.h11
-rw-r--r--sys/amd64/include/md_var.h2
-rw-r--r--sys/amd64/include/specialreg.h37
-rw-r--r--sys/amd64/linux32/linux32_locore.s8
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c107
-rw-r--r--sys/arm/arm/busdma_machdep.c4
-rw-r--r--sys/arm/arm/cpufunc.c26
-rw-r--r--sys/arm/arm/cpufunc_asm_sheeva.S (renamed from sys/arm/arm/cpufunc_asm_feroceon.S)54
-rw-r--r--sys/arm/arm/dump_machdep.c2
-rw-r--r--sys/arm/arm/elf_trampoline.c6
-rw-r--r--sys/arm/arm/pmap.c3
-rw-r--r--sys/arm/arm/vm_machdep.c3
-rw-r--r--sys/arm/at91/at91.c2
-rw-r--r--sys/arm/at91/at91_mci.c49
-rw-r--r--sys/arm/at91/at91_twi.c3
-rw-r--r--sys/arm/at91/at91_twireg.h2
-rw-r--r--sys/arm/at91/at91var.h2
-rw-r--r--sys/arm/at91/uart_bus_at91usart.c5
-rw-r--r--sys/arm/at91/uart_cpu_at91rm9200usart.c6
-rw-r--r--sys/arm/at91/uart_dev_at91usart.c6
-rw-r--r--sys/arm/conf/AVILA4
-rw-r--r--sys/arm/conf/AVILA.hints4
-rw-r--r--sys/arm/include/atomic.h3
-rw-r--r--sys/arm/include/cpufunc.h22
-rw-r--r--sys/arm/include/vmparam.h7
-rw-r--r--sys/arm/mv/common.c565
-rw-r--r--sys/arm/mv/discovery/db78xxx.c55
-rw-r--r--sys/arm/mv/discovery/discovery.c47
-rw-r--r--sys/arm/mv/files.mv2
-rw-r--r--sys/arm/mv/gpio.c40
-rw-r--r--sys/arm/mv/kirkwood/db88f6xxx.c50
-rw-r--r--sys/arm/mv/kirkwood/kirkwood.c33
-rw-r--r--sys/arm/mv/mv_machdep.c5
-rw-r--r--sys/arm/mv/mv_pci.c89
-rw-r--r--sys/arm/mv/mvreg.h91
-rw-r--r--sys/arm/mv/mvvar.h24
-rw-r--r--sys/arm/mv/obio.c3
-rw-r--r--sys/arm/mv/orion/db88f5xxx.c145
-rw-r--r--sys/arm/mv/orion/orion.c27
-rw-r--r--sys/arm/sa11x0/assabet_machdep.c8
-rw-r--r--sys/arm/xscale/i8134x/i81342_mcu.c1
-rw-r--r--sys/arm/xscale/ixp425/avila_machdep.c4
-rw-r--r--sys/arm/xscale/ixp425/files.ixp4251
-rw-r--r--sys/arm/xscale/ixp425/ixp425.c2
-rw-r--r--sys/arm/xscale/ixp425/ixp425reg.h8
-rw-r--r--sys/boot/common/load.c101
-rw-r--r--sys/boot/forth/loader.4th112
-rw-r--r--sys/boot/forth/loader.conf1
-rw-r--r--sys/boot/forth/pnp.4th33
-rw-r--r--sys/boot/forth/support.4th680
-rw-r--r--sys/boot/i386/boot0/Makefile2
-rw-r--r--sys/boot/i386/boot0/boot0.S53
-rw-r--r--sys/boot/i386/libi386/bootinfo64.c5
-rw-r--r--sys/boot/i386/pxeldr/pxeboot.82
-rw-r--r--sys/bsm/audit.h33
-rw-r--r--sys/bsm/audit_domain.h115
-rw-r--r--sys/bsm/audit_errno.h215
-rw-r--r--sys/bsm/audit_internal.h4
-rw-r--r--sys/bsm/audit_kevents.h85
-rw-r--r--sys/bsm/audit_record.h35
-rw-r--r--sys/bsm/audit_socket_type.h47
-rw-r--r--sys/cam/cam_periph.c29
-rw-r--r--sys/cam/cam_xpt.c56
-rw-r--r--sys/cam/cam_xpt_sim.h1
-rw-r--r--sys/cam/scsi/scsi_all.c1
-rw-r--r--sys/cam/scsi/scsi_cd.c9
-rw-r--r--sys/cam/scsi/scsi_ch.c4
-rw-r--r--sys/cam/scsi/scsi_da.c2
-rw-r--r--sys/cam/scsi/scsi_low.c6
-rw-r--r--sys/cam/scsi/scsi_pass.c11
-rw-r--r--sys/cam/scsi/scsi_pt.c6
-rw-r--r--sys/cam/scsi/scsi_sa.c7
-rw-r--r--sys/cam/scsi/scsi_ses.c5
-rw-r--r--sys/cam/scsi/scsi_sg.c8
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c2
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c7
-rw-r--r--sys/compat/linprocfs/linprocfs.c14
-rw-r--r--sys/compat/linux/linux_misc.c16
-rw-r--r--sys/compat/linux/linux_stats.c6
-rw-r--r--sys/compat/ndis/winx32_wrap.S2
-rw-r--r--sys/compat/svr4/svr4_types.h4
-rw-r--r--sys/conf/Makefile.arm2
-rw-r--r--sys/conf/NOTES24
-rw-r--r--sys/conf/files12
-rw-r--r--sys/conf/files.amd6413
-rw-r--r--sys/conf/files.i38619
-rw-r--r--sys/conf/files.ia643
-rw-r--r--sys/conf/files.pc9812
-rw-r--r--sys/conf/files.powerpc11
-rw-r--r--sys/conf/files.sparc643
-rw-r--r--sys/conf/kern.post.mk10
-rw-r--r--sys/conf/kern.pre.mk1
-rw-r--r--sys/conf/kmod.mk3
-rw-r--r--sys/conf/newvers.sh3
-rw-r--r--sys/conf/options38
-rw-r--r--sys/conf/options.amd643
-rw-r--r--sys/conf/options.i3863
-rw-r--r--sys/conf/options.ia643
-rw-r--r--sys/conf/options.mips2
-rw-r--r--sys/conf/options.pc981
-rw-r--r--sys/contrib/altq/altq/altq_subr.c2
-rw-r--r--sys/crypto/via/padlock.c6
-rw-r--r--sys/crypto/via/padlock_hash.c2
-rw-r--r--sys/dev/acpi_support/acpi_panasonic.c5
-rw-r--r--sys/dev/acpica/acpi_battery.c2
-rw-r--r--sys/dev/acpica/acpi_pcib_acpi.c17
-rw-r--r--sys/dev/adb/adb_kbd.c159
-rw-r--r--sys/dev/adb/adb_mouse.c3
-rw-r--r--sys/dev/ae/if_ae.c4
-rw-r--r--sys/dev/agp/agp.c7
-rw-r--r--sys/dev/agp/agp_amd64.c8
-rw-r--r--sys/dev/agp/agp_via.c9
-rw-r--r--sys/dev/an/if_an.c4
-rw-r--r--sys/dev/an/if_anreg.h2
-rw-r--r--sys/dev/ata/ata-disk.c3
-rw-r--r--sys/dev/ata/ata-queue.c3
-rw-r--r--sys/dev/ata/atapi-cam.c8
-rw-r--r--sys/dev/ata/atapi-cd.c3
-rw-r--r--sys/dev/ata/atapi-fd.c3
-rw-r--r--sys/dev/ata/atapi-tape.c3
-rw-r--r--sys/dev/ath/ath_hal/ah.c131
-rw-r--r--sys/dev/ath/ath_hal/ah.h166
-rw-r--r--sys/dev/ath/ath_hal/ah_internal.h209
-rw-r--r--sys/dev/ath/ath_hal/ah_regdomain.c2113
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210.h20
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_attach.c27
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_misc.c7
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_reset.c77
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c8
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211.h26
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_attach.c32
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_misc.c10
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_reset.c330
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c8
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2316.c88
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2317.c81
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2413.c97
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar2425.c91
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5111.c70
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5112.c130
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212.h68
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_ani.c89
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_attach.c9
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_misc.c20
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_reset.c625
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_rfgain.c27
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c8
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5413.c113
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312.h8
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_reset.c166
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar2133.c33
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416.h21
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_ani.c88
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.c81
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.h13
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_reset.c487
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c4
-rw-r--r--sys/dev/ath/ath_rate/amrr/amrr.c27
-rw-r--r--sys/dev/ath/ath_rate/onoe/onoe.c27
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c54
-rw-r--r--sys/dev/ath/if_ath.c1098
-rw-r--r--sys/dev/ath/if_ath_pci.c1
-rw-r--r--sys/dev/ath/if_athioctl.h12
-rw-r--r--sys/dev/ath/if_athvar.h36
-rw-r--r--sys/dev/atkbdc/atkbdc_isa.c6
-rw-r--r--sys/dev/bce/if_bce.c43
-rw-r--r--sys/dev/bge/if_bge.c7
-rw-r--r--sys/dev/bm/if_bm.c6
-rw-r--r--sys/dev/cardbus/cardbus.c5
-rw-r--r--sys/dev/cardbus/cardbus_device.c2
-rw-r--r--sys/dev/cfi/cfi_bus_ixp4xx.c80
-rw-r--r--sys/dev/cfi/cfi_core.c200
-rw-r--r--sys/dev/cfi/cfi_dev.c59
-rw-r--r--sys/dev/cfi/cfi_reg.h22
-rw-r--r--sys/dev/cfi/cfi_var.h7
-rw-r--r--sys/dev/dcons/dcons_crom.c15
-rw-r--r--sys/dev/dcons/dcons_os.c20
-rw-r--r--sys/dev/digi/con.CX-IBM.h1555
-rw-r--r--sys/dev/digi/con.CX.h1561
-rw-r--r--sys/dev/digi/con.EPCX.h3975
-rw-r--r--sys/dev/digi/con.MBank.h7870
-rw-r--r--sys/dev/e1000/if_igb.c2
-rw-r--r--sys/dev/exca/exca.c76
-rw-r--r--sys/dev/firewire/firewire.c85
-rw-r--r--sys/dev/firewire/fwohci.c40
-rw-r--r--sys/dev/firewire/fwohci_pci.c11
-rw-r--r--sys/dev/firewire/fwohcivar.h7
-rw-r--r--sys/dev/firewire/sbp.c13
-rw-r--r--sys/dev/fxp/if_fxp.c8
-rw-r--r--sys/dev/hifn/hifn7751.c5
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c344
-rw-r--r--sys/dev/hwpmc/hwpmc_intel.c5
-rw-r--r--sys/dev/hwpmc/pmc_events.h542
-rw-r--r--sys/dev/ichsmb/ichsmb.c20
-rw-r--r--sys/dev/if_ndis/if_ndis.c35
-rw-r--r--sys/dev/iicbus/ad7418.c2
-rw-r--r--sys/dev/iicbus/ds1672.c2
-rw-r--r--sys/dev/iicbus/icee.c2
-rw-r--r--sys/dev/iicbus/if_ic.c2
-rw-r--r--sys/dev/iicbus/iic.c9
-rw-r--r--sys/dev/iicbus/iic.h1
-rw-r--r--sys/dev/iicbus/iicbus.c6
-rw-r--r--sys/dev/iicbus/iicsmb.c2
-rw-r--r--sys/dev/ipmi/ipmi_acpi.c2
-rw-r--r--sys/dev/ipmi/ipmi_smbios.c4
-rw-r--r--sys/dev/kbdmux/kbdmux.c2
-rw-r--r--sys/dev/lmc/if_lmc.c3
-rw-r--r--sys/dev/lmc/if_lmc.h2
-rw-r--r--sys/dev/md/md.c6
-rw-r--r--sys/dev/mge/if_mge.c106
-rw-r--r--sys/dev/mge/if_mgevar.h36
-rw-r--r--sys/dev/mmc/mmc.c130
-rw-r--r--sys/dev/mmc/mmcreg.h18
-rw-r--r--sys/dev/mpt/mpt.c142
-rw-r--r--sys/dev/mpt/mpt.h25
-rw-r--r--sys/dev/mpt/mpt_cam.c50
-rw-r--r--sys/dev/mpt/mpt_raid.c10
-rw-r--r--sys/dev/mpt/mpt_user.c33
-rw-r--r--sys/dev/msk/if_msk.c748
-rw-r--r--sys/dev/msk/if_mskreg.h83
-rw-r--r--sys/dev/my/if_my.c6
-rw-r--r--sys/dev/nve/if_nve.c6
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c23
-rw-r--r--sys/dev/ofw/ofw_iicbus.c183
-rw-r--r--sys/dev/ofw/openfirm.c17
-rw-r--r--sys/dev/ofw/openfirm.h2
-rw-r--r--sys/dev/pccard/card_if.m2
-rw-r--r--sys/dev/pccard/pccard.c28
-rw-r--r--sys/dev/pccard/pccard_cis.c44
-rw-r--r--sys/dev/pccard/pccardvar.h4
-rw-r--r--sys/dev/pccard/pccardvarp.h19
-rw-r--r--sys/dev/pccbb/pccbb.c24
-rw-r--r--sys/dev/pccbb/pccbb_pci.c11
-rw-r--r--sys/dev/pccbb/pccbbvar.h6
-rw-r--r--sys/dev/pci/pci.c20
-rw-r--r--sys/dev/pci/pci_user.c73
-rw-r--r--sys/dev/pci/pcireg.h4
-rw-r--r--sys/dev/pcn/if_pcn.c14
-rw-r--r--sys/dev/ppbus/if_plip.c253
-rw-r--r--sys/dev/ppbus/immio.c2
-rw-r--r--sys/dev/ppbus/lpbb.c59
-rw-r--r--sys/dev/ppbus/lpt.c287
-rw-r--r--sys/dev/ppbus/pcfclock.c26
-rw-r--r--sys/dev/ppbus/ppb_1284.c7
-rw-r--r--sys/dev/ppbus/ppb_base.c95
-rw-r--r--sys/dev/ppbus/ppb_msq.c7
-rw-r--r--sys/dev/ppbus/ppbconf.c122
-rw-r--r--sys/dev/ppbus/ppbconf.h92
-rw-r--r--sys/dev/ppbus/ppi.c154
-rw-r--r--sys/dev/ppbus/pps.c89
-rw-r--r--sys/dev/ppbus/vpo.c30
-rw-r--r--sys/dev/ppbus/vpoio.c2
-rw-r--r--sys/dev/ppc/ppc.c136
-rw-r--r--sys/dev/ppc/ppc_acpi.c3
-rw-r--r--sys/dev/ppc/ppc_isa.c14
-rw-r--r--sys/dev/ppc/ppc_pci.c3
-rw-r--r--sys/dev/ppc/ppc_puc.c3
-rw-r--r--sys/dev/ppc/ppcreg.h13
-rw-r--r--sys/dev/ppc/ppcvar.h8
-rw-r--r--sys/dev/puc/pucdata.c6
-rw-r--r--sys/dev/re/if_re.c181
-rw-r--r--sys/dev/safe/safe.c5
-rw-r--r--sys/dev/scc/scc_if.m2
-rw-r--r--sys/dev/sdhci/sdhci.c43
-rw-r--r--sys/dev/si/si.c4
-rw-r--r--sys/dev/smbus/smb.c4
-rw-r--r--sys/dev/snp/snp.c1
-rw-r--r--sys/dev/sound/macio/aoa.c384
-rw-r--r--sys/dev/sound/macio/aoa.h47
-rw-r--r--sys/dev/sound/macio/davbus.c595
-rw-r--r--sys/dev/sound/macio/davbusreg.h285
-rw-r--r--sys/dev/sound/macio/i2s.c745
-rw-r--r--sys/dev/sound/macio/snapper.c486
-rw-r--r--sys/dev/sound/macio/tumbler.c432
-rw-r--r--sys/dev/sound/pci/au88x0.c730
-rw-r--r--sys/dev/sound/pci/au88x0.h178
-rw-r--r--sys/dev/sound/pci/cmi.c4
-rw-r--r--sys/dev/sound/pci/hda/hdac.c257
-rw-r--r--sys/dev/sound/pcm/dsp.c32
-rw-r--r--sys/dev/sound/pcm/mixer.c38
-rw-r--r--sys/dev/sound/pcm/sound.c35
-rw-r--r--sys/dev/sound/pcm/sound.h1
-rw-r--r--sys/dev/speaker/spkr.c27
-rw-r--r--sys/dev/syscons/scterm-dumb.c155
-rw-r--r--sys/dev/syscons/scterm-sc.c811
-rw-r--r--sys/dev/syscons/scterm-teken.c504
-rw-r--r--sys/dev/syscons/scterm.c1
-rw-r--r--sys/dev/syscons/syscons.c37
-rw-r--r--sys/dev/syscons/syscons.h3
-rw-r--r--sys/dev/syscons/teken/Makefile13
-rw-r--r--sys/dev/syscons/teken/gensequences157
-rw-r--r--sys/dev/syscons/teken/sequences109
-rw-r--r--sys/dev/syscons/teken/teken.c411
-rw-r--r--sys/dev/syscons/teken/teken.h178
-rw-r--r--sys/dev/syscons/teken/teken_demo.c367
-rw-r--r--sys/dev/syscons/teken/teken_scs.h98
-rw-r--r--sys/dev/syscons/teken/teken_stress.c123
-rw-r--r--sys/dev/syscons/teken/teken_subr.h1206
-rw-r--r--sys/dev/syscons/teken/teken_subr_compat.h77
-rw-r--r--sys/dev/syscons/teken/teken_wcwidth.h120
-rw-r--r--sys/dev/uart/uart_cpu_mv.c3
-rw-r--r--sys/dev/usb/ehci.c2
-rw-r--r--sys/dev/usb/ehci_mbus.c76
-rw-r--r--sys/dev/usb/ehci_pci.c8
-rw-r--r--sys/dev/usb/if_rum.c1
-rw-r--r--sys/dev/usb/if_urtw.c3324
-rw-r--r--sys/dev/usb/if_urtwreg.h256
-rw-r--r--sys/dev/usb/if_urtwvar.h151
-rw-r--r--sys/dev/usb/u3g.c11
-rw-r--r--sys/dev/usb/uftdi.c15
-rw-r--r--sys/dev/usb/uhci_pci.c6
-rw-r--r--sys/dev/usb/usbdevs32
-rw-r--r--sys/dev/usb/usbdi.c2
-rw-r--r--sys/dev/usb/uscanner.c15
-rw-r--r--sys/dev/usb2/bluetooth/ng_ubt2.c2178
-rw-r--r--sys/dev/usb2/bluetooth/ng_ubt2_var.h143
-rw-r--r--sys/dev/usb2/bluetooth/ubtbcmfw2.c434
-rw-r--r--sys/dev/usb2/controller/at91dci.c99
-rw-r--r--sys/dev/usb2/controller/at91dci.h5
-rw-r--r--sys/dev/usb2/controller/at91dci_atmelarm.c30
-rw-r--r--sys/dev/usb2/controller/atmegadci.c2327
-rw-r--r--sys/dev/usb2/controller/atmegadci.h273
-rw-r--r--sys/dev/usb2/controller/atmegadci_atmelarm.c27
-rw-r--r--sys/dev/usb2/controller/ehci2.c628
-rw-r--r--sys/dev/usb2/controller/ehci2.h24
-rw-r--r--sys/dev/usb2/controller/ehci2_pci.c30
-rw-r--r--sys/dev/usb2/controller/musb2_otg.c68
-rw-r--r--sys/dev/usb2/controller/musb2_otg.h6
-rw-r--r--sys/dev/usb2/controller/musb2_otg_atmelarm.c28
-rw-r--r--sys/dev/usb2/controller/ohci2.c240
-rw-r--r--sys/dev/usb2/controller/ohci2.h4
-rw-r--r--sys/dev/usb2/controller/ohci2_atmelarm.c21
-rw-r--r--sys/dev/usb2/controller/ohci2_pci.c31
-rw-r--r--sys/dev/usb2/controller/uhci2.c334
-rw-r--r--sys/dev/usb2/controller/uhci2.h7
-rw-r--r--sys/dev/usb2/controller/uhci2_pci.c26
-rw-r--r--sys/dev/usb2/controller/usb2_bus.h20
-rw-r--r--sys/dev/usb2/controller/usb2_controller.c167
-rw-r--r--sys/dev/usb2/controller/usb2_controller.h35
-rw-r--r--sys/dev/usb2/controller/uss820dci.c73
-rw-r--r--sys/dev/usb2/controller/uss820dci.h4
-rw-r--r--sys/dev/usb2/controller/uss820dci_atmelarm.c19
-rw-r--r--sys/dev/usb2/core/usb2_busdma.c39
-rw-r--r--sys/dev/usb2/core/usb2_compat_linux.c13
-rw-r--r--sys/dev/usb2/core/usb2_core.h15
-rw-r--r--sys/dev/usb2/core/usb2_debug.c12
-rw-r--r--sys/dev/usb2/core/usb2_device.c132
-rw-r--r--sys/dev/usb2/core/usb2_device.h14
-rw-r--r--sys/dev/usb2/core/usb2_dynamic.c23
-rw-r--r--sys/dev/usb2/core/usb2_dynamic.h4
-rw-r--r--sys/dev/usb2/core/usb2_error.c34
-rw-r--r--sys/dev/usb2/core/usb2_generic.c58
-rw-r--r--sys/dev/usb2/core/usb2_handle_request.c28
-rw-r--r--sys/dev/usb2/core/usb2_hub.c657
-rw-r--r--sys/dev/usb2/core/usb2_hub.h2
-rw-r--r--sys/dev/usb2/core/usb2_mbuf.h5
-rw-r--r--sys/dev/usb2/core/usb2_msctest.c161
-rw-r--r--sys/dev/usb2/core/usb2_msctest.h25
-rw-r--r--sys/dev/usb2/core/usb2_parse.c51
-rw-r--r--sys/dev/usb2/core/usb2_process.c6
-rw-r--r--sys/dev/usb2/core/usb2_request.c86
-rw-r--r--sys/dev/usb2/core/usb2_request.h2
-rw-r--r--sys/dev/usb2/core/usb2_sw_transfer.c2
-rw-r--r--sys/dev/usb2/core/usb2_transfer.c281
-rw-r--r--sys/dev/usb2/core/usb2_transfer.h12
-rw-r--r--sys/dev/usb2/ethernet/if_aue2.c60
-rw-r--r--sys/dev/usb2/ethernet/if_auereg.h (renamed from sys/dev/usb2/ethernet/if_aue2_reg.h)16
-rw-r--r--sys/dev/usb2/ethernet/if_axe2.c207
-rw-r--r--sys/dev/usb2/ethernet/if_axereg.h (renamed from sys/dev/usb2/ethernet/if_axe2_reg.h)42
-rw-r--r--sys/dev/usb2/ethernet/if_cdce2.c26
-rw-r--r--sys/dev/usb2/ethernet/if_cdcereg.h (renamed from sys/dev/usb2/ethernet/if_cdce2_reg.h)11
-rw-r--r--sys/dev/usb2/ethernet/if_cue2.c44
-rw-r--r--sys/dev/usb2/ethernet/if_cuereg.h (renamed from sys/dev/usb2/ethernet/if_cue2_reg.h)13
-rw-r--r--sys/dev/usb2/ethernet/if_kue2.c46
-rw-r--r--sys/dev/usb2/ethernet/if_kuefw.h (renamed from sys/dev/usb2/ethernet/if_kue2_fw.h)0
-rw-r--r--sys/dev/usb2/ethernet/if_kuereg.h (renamed from sys/dev/usb2/ethernet/if_kue2_reg.h)12
-rw-r--r--sys/dev/usb2/ethernet/if_rue2.c60
-rw-r--r--sys/dev/usb2/ethernet/if_ruereg.h (renamed from sys/dev/usb2/ethernet/if_rue2_reg.h)17
-rw-r--r--sys/dev/usb2/ethernet/if_udav2.c60
-rw-r--r--sys/dev/usb2/ethernet/if_udavreg.h (renamed from sys/dev/usb2/ethernet/if_udav2_reg.h)17
-rw-r--r--sys/dev/usb2/image/uscanner2.c47
-rw-r--r--sys/dev/usb2/include/usb2_defs.h17
-rw-r--r--sys/dev/usb2/include/usb2_devid.h41
-rw-r--r--sys/dev/usb2/include/usb2_devtable.h140
-rw-r--r--sys/dev/usb2/include/usb2_error.h69
-rw-r--r--sys/dev/usb2/include/usb2_hid.h2
-rw-r--r--sys/dev/usb2/include/usb2_ioctl.h9
-rw-r--r--sys/dev/usb2/include/usb2_mfunc.h8
-rw-r--r--sys/dev/usb2/include/usb2_revision.h48
-rw-r--r--sys/dev/usb2/include/usb2_standard.h11
-rw-r--r--sys/dev/usb2/input/uhid2.c75
-rw-r--r--sys/dev/usb2/input/ukbd2.c29
-rw-r--r--sys/dev/usb2/input/ums2.c27
-rw-r--r--sys/dev/usb2/misc/udbp2.c3
-rw-r--r--sys/dev/usb2/misc/ufm2.c4
-rw-r--r--sys/dev/usb2/quirk/usb2_quirk.c30
-rw-r--r--sys/dev/usb2/quirk/usb2_quirk.h78
-rw-r--r--sys/dev/usb2/serial/u3g2.c296
-rw-r--r--sys/dev/usb2/serial/uark2.c46
-rw-r--r--sys/dev/usb2/serial/ubsa2.c65
-rw-r--r--sys/dev/usb2/serial/ubser2.c62
-rw-r--r--sys/dev/usb2/serial/uchcom2.c71
-rw-r--r--sys/dev/usb2/serial/ucycom2.c42
-rw-r--r--sys/dev/usb2/serial/ufoma2.c252
-rw-r--r--sys/dev/usb2/serial/uftdi2.c68
-rw-r--r--sys/dev/usb2/serial/ugensa2.c48
-rw-r--r--sys/dev/usb2/serial/uipaq2.c55
-rw-r--r--sys/dev/usb2/serial/ulpt2.c51
-rw-r--r--sys/dev/usb2/serial/umct2.c84
-rw-r--r--sys/dev/usb2/serial/umodem2.c4
-rw-r--r--sys/dev/usb2/serial/umoscom2.c73
-rw-r--r--sys/dev/usb2/serial/uplcom2.c71
-rw-r--r--sys/dev/usb2/serial/usb2_serial.c258
-rw-r--r--sys/dev/usb2/serial/usb2_serial.h27
-rw-r--r--sys/dev/usb2/serial/uvisor2.c45
-rw-r--r--sys/dev/usb2/serial/uvscom2.c76
-rw-r--r--sys/dev/usb2/sound/uaudio2.c182
-rw-r--r--sys/dev/usb2/storage/ata-usb2.c8
-rw-r--r--sys/dev/usb2/storage/umass2.c26
-rw-r--r--sys/dev/usb2/storage/urio2.c4
-rw-r--r--sys/dev/usb2/storage/ustorage2_fs.c5
-rw-r--r--sys/dev/usb2/wlan/if_rum2.c49
-rw-r--r--sys/dev/usb2/wlan/if_rumfw.h (renamed from sys/dev/usb2/wlan/if_rum2_fw.h)0
-rw-r--r--sys/dev/usb2/wlan/if_rumreg.h (renamed from sys/dev/usb2/wlan/if_rum2_reg.h)0
-rw-r--r--sys/dev/usb2/wlan/if_rumvar.h (renamed from sys/dev/usb2/wlan/if_rum2_var.h)13
-rw-r--r--sys/dev/usb2/wlan/if_ural2.c57
-rw-r--r--sys/dev/usb2/wlan/if_uralreg.h (renamed from sys/dev/usb2/wlan/if_ural2_reg.h)0
-rw-r--r--sys/dev/usb2/wlan/if_uralvar.h (renamed from sys/dev/usb2/wlan/if_ural2_var.h)13
-rw-r--r--sys/dev/usb2/wlan/if_zyd2.c345
-rw-r--r--sys/dev/usb2/wlan/if_zydfw.h (renamed from sys/dev/usb2/wlan/if_zyd2_fw.h)0
-rw-r--r--sys/dev/usb2/wlan/if_zydreg.h (renamed from sys/dev/usb2/wlan/if_zyd2_reg.h)191
-rw-r--r--sys/dev/xen/blkback/blkback.c4
-rw-r--r--sys/dev/xen/blkfront/blkfront.c49
-rw-r--r--sys/dev/xen/console/console.c27
-rw-r--r--sys/dev/xen/console/xencons_ring.c11
-rw-r--r--sys/dev/xen/evtchn/evtchn_dev.c4
-rw-r--r--sys/dev/xen/netback/netback.c13
-rw-r--r--sys/dev/xen/netfront/netfront.c127
-rw-r--r--sys/fs/cd9660/cd9660_lookup.c138
-rw-r--r--sys/fs/cd9660/cd9660_node.c3
-rw-r--r--sys/fs/cd9660/cd9660_node.h2
-rw-r--r--sys/fs/cd9660/cd9660_rrip.c4
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c23
-rw-r--r--sys/fs/cd9660/cd9660_vnops.c10
-rw-r--r--sys/fs/coda/coda_vfsops.c2
-rw-r--r--sys/fs/devfs/devfs_devs.c5
-rw-r--r--sys/fs/devfs/devfs_vnops.c23
-rw-r--r--sys/fs/fifofs/fifo_vnops.c10
-rw-r--r--sys/fs/hpfs/hpfs_vfsops.c7
-rw-r--r--sys/fs/msdosfs/msdosfs_conv.c7
-rw-r--r--sys/fs/msdosfs/msdosfs_denode.c1
-rw-r--r--sys/fs/nullfs/null_vnops.c2
-rw-r--r--sys/fs/nwfs/nwfs_subr.c2
-rw-r--r--sys/fs/nwfs/nwfs_vnops.c5
-rw-r--r--sys/fs/procfs/procfs_map.c18
-rw-r--r--sys/fs/pseudofs/pseudofs_vncache.c43
-rw-r--r--sys/fs/pseudofs/pseudofs_vnops.c112
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c3
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c2
-rw-r--r--sys/fs/udf/ecma167-udf.h12
-rw-r--r--sys/fs/udf/udf.h2
-rw-r--r--sys/fs/udf/udf_vfsops.c1
-rw-r--r--sys/fs/udf/udf_vnops.c178
-rw-r--r--sys/geom/geom.h5
-rw-r--r--sys/geom/geom_dev.c18
-rw-r--r--sys/geom/geom_subr.c7
-rw-r--r--sys/geom/geom_vfs.c12
-rw-r--r--sys/geom/part/g_part.c6
-rw-r--r--sys/geom/part/g_part_pc98.c14
-rw-r--r--sys/geom/part/g_part_vtoc8.c22
-rw-r--r--sys/gnu/fs/ext2fs/ext2_bitops.h2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_fs.h4
-rw-r--r--sys/gnu/fs/ext2fs/ext2_fs_sb.h2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_inode.c2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_linux_ialloc.c4
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c58
-rw-r--r--sys/i386/conf/GENERIC13
-rw-r--r--sys/i386/conf/NOTES12
-rw-r--r--sys/i386/conf/USB2114
-rw-r--r--sys/i386/conf/XEN6
-rw-r--r--sys/i386/cpufreq/est.c4
-rw-r--r--sys/i386/cpufreq/smist.c3
-rw-r--r--sys/i386/i386/genassym.c2
-rw-r--r--sys/i386/i386/i686_mem.c12
-rw-r--r--sys/i386/i386/identcpu.c15
-rw-r--r--sys/i386/i386/initcpu.c15
-rw-r--r--sys/i386/i386/io_apic.c57
-rw-r--r--sys/i386/i386/local_apic.c84
-rw-r--r--sys/i386/i386/locore.s6
-rw-r--r--sys/i386/i386/machdep.c4
-rw-r--r--sys/i386/i386/mp_machdep.c3
-rw-r--r--sys/i386/i386/msi.c81
-rw-r--r--sys/i386/i386/swtch.s6
-rw-r--r--sys/i386/i386/vm_machdep.c7
-rw-r--r--sys/i386/ibcs2/ibcs2_sysi86.c8
-rw-r--r--sys/i386/include/apicvar.h17
-rw-r--r--sys/i386/include/cpufunc.h10
-rw-r--r--sys/i386/include/intr_machdep.h2
-rw-r--r--sys/i386/include/xen/xenfunc.h2
-rw-r--r--sys/i386/isa/npx.c2
-rw-r--r--sys/i386/linux/linux_locore.s4
-rw-r--r--sys/i386/svr4/svr4_locore.s2
-rw-r--r--sys/i386/xen/clock.c160
-rw-r--r--sys/i386/xen/mp_machdep.c24
-rw-r--r--sys/i386/xen/mptable.c2
-rw-r--r--sys/i386/xen/pmap.c2
-rw-r--r--sys/i386/xen/xen_machdep.c10
-rw-r--r--sys/ia64/conf/NOTES3
-rw-r--r--sys/ia64/ia64/mca.c70
-rw-r--r--sys/ia64/ia64/pmap.c16
-rw-r--r--sys/ia64/include/mca.h1
-rw-r--r--sys/kern/imgact_elf.c3
-rw-r--r--sys/kern/kern_clock.c4
-rw-r--r--sys/kern/kern_descrip.c14
-rw-r--r--sys/kern/kern_jail.c206
-rw-r--r--sys/kern/kern_linker.c11
-rw-r--r--sys/kern/kern_lock.c6
-rw-r--r--sys/kern/kern_malloc.c5
-rw-r--r--sys/kern/kern_mbuf.c2
-rw-r--r--sys/kern/kern_mib.c15
-rw-r--r--sys/kern/kern_proc.c75
-rw-r--r--sys/kern/kern_synch.c27
-rw-r--r--sys/kern/kern_sysctl.c367
-rw-r--r--sys/kern/kern_timeout.c16
-rw-r--r--sys/kern/kern_xxx.c259
-rw-r--r--sys/kern/sched_4bsd.c72
-rw-r--r--sys/kern/sched_ule.c77
-rw-r--r--sys/kern/subr_autoconf.c9
-rw-r--r--sys/kern/subr_bus.c10
-rw-r--r--sys/kern/subr_clist.c89
-rw-r--r--sys/kern/subr_devstat.c6
-rw-r--r--sys/kern/subr_disk.c4
-rw-r--r--sys/kern/subr_firmware.c2
-rw-r--r--sys/kern/subr_kobj.c12
-rw-r--r--sys/kern/subr_param.c4
-rw-r--r--sys/kern/subr_pcpu.c3
-rw-r--r--sys/kern/subr_prf.c2
-rw-r--r--sys/kern/subr_prof.c4
-rw-r--r--sys/kern/subr_rman.c2
-rw-r--r--sys/kern/subr_rtc.c2
-rw-r--r--sys/kern/subr_smp.c2
-rw-r--r--sys/kern/subr_taskqueue.c10
-rw-r--r--sys/kern/subr_witness.c55
-rw-r--r--sys/kern/sys_generic.c141
-rw-r--r--sys/kern/sysv_sem.c281
-rw-r--r--sys/kern/tty.c76
-rw-r--r--sys/kern/tty_info.c2
-rw-r--r--sys/kern/tty_inq.c78
-rw-r--r--sys/kern/tty_outq.c94
-rw-r--r--sys/kern/tty_pty.c13
-rw-r--r--sys/kern/uipc_cow.c6
-rw-r--r--sys/kern/uipc_debug.c2
-rw-r--r--sys/kern/uipc_domain.c19
-rw-r--r--sys/kern/uipc_mbuf.c4
-rw-r--r--sys/kern/uipc_socket.c12
-rw-r--r--sys/kern/uipc_usrreq.c10
-rw-r--r--sys/kern/vfs_aio.c2
-rw-r--r--sys/kern/vfs_bio.c1
-rw-r--r--sys/kern/vfs_cache.c178
-rw-r--r--sys/kern/vfs_extattr.c49
-rw-r--r--sys/kern/vfs_init.c3
-rw-r--r--sys/kern/vfs_mount.c16
-rw-r--r--sys/kern/vfs_subr.c117
-rw-r--r--sys/kern/vfs_syscalls.c12
-rw-r--r--sys/kern/vfs_vnops.c32
-rw-r--r--sys/kern/vnode_if.src5
-rw-r--r--sys/mips/idt/idtpci.c7
-rw-r--r--sys/mips/include/pmap.h28
-rw-r--r--sys/mips/malta/gt_pci.c16
-rw-r--r--sys/mips/mips/busdma_machdep.c2
-rw-r--r--sys/mips/mips/cpu.c6
-rw-r--r--sys/mips/mips/elf64_machdep.c117
-rw-r--r--sys/mips/mips/machdep.c167
-rw-r--r--sys/mips/mips/nexus.c18
-rw-r--r--sys/mips/mips/pmap.c18
-rw-r--r--sys/modules/Makefile8
-rw-r--r--sys/modules/agp/Makefile2
-rw-r--r--sys/modules/iwnfw/Makefile1
-rw-r--r--sys/modules/sound/driver/Makefile21
-rw-r--r--sys/modules/sound/driver/ai2s/Makefile10
-rw-r--r--sys/modules/sound/driver/au88x0/Makefile9
-rw-r--r--sys/modules/sound/driver/davbus/Makefile10
-rw-r--r--sys/modules/urtw/Makefile9
-rw-r--r--sys/modules/usb2/Makefile5
-rw-r--r--sys/modules/usb2/controller_atmegadci/Makefile41
-rw-r--r--sys/modules/usb2/serial_3g/Makefile38
-rw-r--r--sys/net/if.c30
-rw-r--r--sys/net/if_ethersubr.c4
-rw-r--r--sys/net/if_llatbl.c5
-rw-r--r--sys/net/if_loop.c18
-rw-r--r--sys/net/route.c2
-rw-r--r--sys/net/route.h3
-rw-r--r--sys/net/rtsock.c180
-rw-r--r--sys/net80211/_ieee80211.h24
-rw-r--r--sys/net80211/ieee80211.c59
-rw-r--r--sys/net80211/ieee80211.h37
-rw-r--r--sys/net80211/ieee80211_adhoc.c27
-rw-r--r--sys/net80211/ieee80211_crypto.h7
-rw-r--r--sys/net80211/ieee80211_ddb.c124
-rw-r--r--sys/net80211/ieee80211_freebsd.c12
-rw-r--r--sys/net80211/ieee80211_hostap.c2
-rw-r--r--sys/net80211/ieee80211_ht.h3
-rw-r--r--sys/net80211/ieee80211_input.c6
-rw-r--r--sys/net80211/ieee80211_input.h8
-rw-r--r--sys/net80211/ieee80211_ioctl.c103
-rw-r--r--sys/net80211/ieee80211_ioctl.h38
-rw-r--r--sys/net80211/ieee80211_node.c42
-rw-r--r--sys/net80211/ieee80211_node.h8
-rw-r--r--sys/net80211/ieee80211_output.c28
-rw-r--r--sys/net80211/ieee80211_proto.h4
-rw-r--r--sys/net80211/ieee80211_regdomain.c26
-rw-r--r--sys/net80211/ieee80211_regdomain.h53
-rw-r--r--sys/net80211/ieee80211_scan.h3
-rw-r--r--sys/net80211/ieee80211_scan_sta.c70
-rw-r--r--sys/net80211/ieee80211_tdma.c731
-rw-r--r--sys/net80211/ieee80211_tdma.h66
-rw-r--r--sys/net80211/ieee80211_var.h48
-rw-r--r--sys/net80211/ieee80211_wds.c2
-rw-r--r--sys/netatalk/ddp_usrreq.c8
-rw-r--r--sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c46
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c5
-rw-r--r--sys/netgraph/ng_deflate.c41
-rw-r--r--sys/netgraph/ng_iface.c18
-rw-r--r--sys/netgraph/ng_iface.h3
-rw-r--r--sys/netgraph/ng_mppc.c122
-rw-r--r--sys/netgraph/ng_ppp.c11
-rw-r--r--sys/netgraph/ng_pred1.c43
-rw-r--r--sys/netgraph/ng_vjc.c3
-rw-r--r--sys/netinet/in.c25
-rw-r--r--sys/netinet/in.h2
-rw-r--r--sys/netinet/in_pcb.c66
-rw-r--r--sys/netinet/in_pcb.h2
-rw-r--r--sys/netinet/ip_divert.c13
-rw-r--r--sys/netinet/ip_fw2.c10
-rw-r--r--sys/netinet/ip_fw_nat.c3
-rw-r--r--sys/netinet/ip_ipsec.c11
-rw-r--r--sys/netinet/ip_output.c50
-rw-r--r--sys/netinet/libalias/alias.c17
-rw-r--r--sys/netinet/libalias/alias.h12
-rw-r--r--sys/netinet/libalias/alias_db.c115
-rw-r--r--sys/netinet/libalias/alias_ftp.c1
-rw-r--r--sys/netinet/libalias/alias_irc.c1
-rw-r--r--sys/netinet/libalias/alias_local.h76
-rw-r--r--sys/netinet/libalias/alias_nbt.c1
-rw-r--r--sys/netinet/libalias/alias_sctp.c2826
-rw-r--r--sys/netinet/libalias/alias_sctp.h104
-rw-r--r--sys/netinet/raw_ip.c37
-rw-r--r--sys/netinet/sctp_auth.c6
-rw-r--r--sys/netinet/sctp_constants.h68
-rw-r--r--sys/netinet/sctp_crc32.c211
-rw-r--r--sys/netinet/sctp_crc32.h12
-rw-r--r--sys/netinet/sctp_input.c46
-rw-r--r--sys/netinet/sctp_os_bsd.h5
-rw-r--r--sys/netinet/sctp_output.c806
-rw-r--r--sys/netinet/sctp_pcb.c44
-rw-r--r--sys/netinet/sctp_pcb.h1
-rw-r--r--sys/netinet/sctp_sysctl.c18
-rw-r--r--sys/netinet/sctp_uio.h8
-rw-r--r--sys/netinet/sctp_usrreq.c22
-rw-r--r--sys/netinet/sctputil.c332
-rw-r--r--sys/netinet/sctputil.h2
-rw-r--r--sys/netinet/tcp_input.c70
-rw-r--r--sys/netinet/tcp_subr.c2
-rw-r--r--sys/netinet/tcp_syncache.c2
-rw-r--r--sys/netinet/tcp_timer.c1
-rw-r--r--sys/netinet/tcp_usrreq.c13
-rw-r--r--sys/netinet/tcp_var.h3
-rw-r--r--sys/netinet/udp_usrreq.c101
-rw-r--r--sys/netinet/udp_var.h4
-rw-r--r--sys/netinet/vinet.h4
-rw-r--r--sys/netinet6/frag6.c16
-rw-r--r--sys/netinet6/in6.c68
-rw-r--r--sys/netinet6/in6_gif.c19
-rw-r--r--sys/netinet6/in6_ifattach.c6
-rw-r--r--sys/netinet6/in6_pcb.c34
-rw-r--r--sys/netinet6/in6_src.c23
-rw-r--r--sys/netinet6/ip6_forward.c112
-rw-r--r--sys/netinet6/ip6_input.c85
-rw-r--r--sys/netinet6/ip6_var.h6
-rw-r--r--sys/netinet6/ip6protosw.h5
-rw-r--r--sys/netinet6/nd6.c1
-rw-r--r--sys/netinet6/nd6_nbr.c2
-rw-r--r--sys/netinet6/nd6_rtr.c6
-rw-r--r--sys/netinet6/raw_ip6.c18
-rw-r--r--sys/netinet6/sctp6_usrreq.c21
-rw-r--r--sys/netinet6/udp6_usrreq.c95
-rw-r--r--sys/netinet6/vinet6.h15
-rw-r--r--sys/netipsec/ipsec_mbuf.c105
-rw-r--r--sys/netipsec/ipsec_output.c4
-rw-r--r--sys/netipsec/xform_ipip.c30
-rw-r--r--sys/nfs4client/nfs4_subs.c2
-rw-r--r--sys/nfsclient/nfs_vfsops.c12
-rw-r--r--sys/nfsclient/nfs_vnops.c8
-rw-r--r--sys/nfsserver/nfs_srvsubs.c4
-rw-r--r--sys/opencrypto/cryptosoft.c12
-rw-r--r--sys/pc98/cbus/scterm-sck.c6
-rw-r--r--sys/pc98/cbus/sctermvar.h (renamed from sys/dev/syscons/sctermvar.h)0
-rw-r--r--sys/pc98/conf/GENERIC10
-rw-r--r--sys/pc98/conf/NOTES20
-rw-r--r--sys/pci/if_rlreg.h10
-rw-r--r--sys/powerpc/booke/locore.S81
-rw-r--r--sys/powerpc/booke/machdep.c1
-rw-r--r--sys/powerpc/booke/pmap.c1095
-rw-r--r--sys/powerpc/booke/support.S106
-rw-r--r--sys/powerpc/booke/trap_subr.S198
-rw-r--r--sys/powerpc/conf/GENERIC4
-rw-r--r--sys/powerpc/conf/NOTES3
-rw-r--r--sys/powerpc/include/pcpu.h3
-rw-r--r--sys/powerpc/include/pmap.h14
-rw-r--r--sys/powerpc/include/pte.h6
-rw-r--r--sys/powerpc/include/tlb.h29
-rw-r--r--sys/powerpc/powermac/ata_macio.c2
-rw-r--r--sys/powerpc/powermac/grackle.c17
-rw-r--r--sys/powerpc/powermac/gracklevar.h1
-rw-r--r--sys/powerpc/powermac/kiic.c390
-rw-r--r--sys/powerpc/powermac/macgpio.c37
-rw-r--r--sys/powerpc/powermac/macio.c18
-rw-r--r--sys/powerpc/powermac/uninorth.c15
-rw-r--r--sys/powerpc/powermac/uninorthvar.h1
-rw-r--r--sys/powerpc/powerpc/genassym.c7
-rw-r--r--sys/powerpc/powerpc/intr_machdep.c9
-rw-r--r--sys/rpc/clnt_rc.c5
-rw-r--r--sys/security/audit/audit.h6
-rw-r--r--sys/security/audit/audit_bsm.c2
-rw-r--r--sys/security/audit/audit_bsm_domain.c502
-rw-r--r--sys/security/audit/audit_bsm_errno.c663
-rw-r--r--sys/security/audit/audit_bsm_socket_type.c107
-rw-r--r--sys/security/audit/audit_bsm_token.c209
-rw-r--r--sys/security/audit/audit_pipe.c12
-rw-r--r--sys/security/mac/mac_audit.c5
-rw-r--r--sys/security/mac/mac_framework.c77
-rw-r--r--sys/security/mac/mac_inet6.c2
-rw-r--r--sys/security/mac/mac_internal.h29
-rw-r--r--sys/security/mac/mac_policy.h33
-rw-r--r--sys/security/mac/mac_priv.c5
-rw-r--r--sys/security/mac_biba/mac_biba.c22
-rw-r--r--sys/security/mac_bsdextended/mac_bsdextended.c2
-rw-r--r--sys/security/mac_ifoff/mac_ifoff.c2
-rw-r--r--sys/security/mac_lomac/mac_lomac.c22
-rw-r--r--sys/security/mac_mls/mac_mls.c22
-rw-r--r--sys/security/mac_none/mac_none.c2
-rw-r--r--sys/security/mac_partition/mac_partition.c2
-rw-r--r--sys/security/mac_portacl/mac_portacl.c2
-rw-r--r--sys/security/mac_seeotheruids/mac_seeotheruids.c2
-rw-r--r--sys/security/mac_stub/mac_stub.c22
-rw-r--r--sys/security/mac_test/mac_test.c22
-rw-r--r--sys/sparc64/include/tlb.h2
-rw-r--r--sys/sparc64/sparc64/machdep.c17
-rw-r--r--sys/sparc64/sparc64/pmap.c12
-rw-r--r--sys/sun4v/include/pcpu.h8
-rw-r--r--sys/sys/_null.h4
-rw-r--r--sys/sys/cdefs.h2
-rw-r--r--sys/sys/cfictl.h6
-rw-r--r--sys/sys/clist.h2
-rw-r--r--sys/sys/conf.h7
-rw-r--r--sys/sys/copyright.h4
-rw-r--r--sys/sys/elf64.h16
-rw-r--r--sys/sys/elf_common.h642
-rw-r--r--sys/sys/elf_generic.h28
-rw-r--r--sys/sys/file.h2
-rw-r--r--sys/sys/imgact_elf.h12
-rw-r--r--sys/sys/jail.h5
-rw-r--r--sys/sys/kobj.h8
-rw-r--r--sys/sys/ktr.h89
-rw-r--r--sys/sys/link_elf.h11
-rw-r--r--sys/sys/lock.h10
-rw-r--r--sys/sys/lockmgr.h2
-rw-r--r--sys/sys/malloc.h4
-rw-r--r--sys/sys/mbuf.h2
-rw-r--r--sys/sys/mount.h1
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pciio.h9
-rw-r--r--sys/sys/pcpu.h6
-rw-r--r--sys/sys/pmc.h5
-rw-r--r--sys/sys/protosw.h27
-rw-r--r--sys/sys/sched.h6
-rw-r--r--sys/sys/soundcard.h112
-rw-r--r--sys/sys/sysctl.h43
-rw-r--r--sys/sys/tty.h35
-rw-r--r--sys/sys/ttyqueue.h48
-rw-r--r--sys/sys/types.h10
-rw-r--r--sys/sys/unistd.h2
-rw-r--r--sys/sys/vnode.h4
-rw-r--r--sys/ufs/ffs/ffs_alloc.c31
-rw-r--r--sys/ufs/ffs/ffs_balloc.c42
-rw-r--r--sys/ufs/ffs/ffs_extern.h6
-rw-r--r--sys/ufs/ffs/ffs_inode.c24
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c17
-rw-r--r--sys/ufs/ffs/ffs_vnops.c14
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c12
-rw-r--r--sys/ufs/ufs/ufs_extattr.c45
-rw-r--r--sys/ufs/ufs/ufs_lookup.c23
-rw-r--r--sys/ufs/ufs/ufs_vnops.c33
-rw-r--r--sys/vm/uma.h27
-rw-r--r--sys/vm/uma_core.c933
-rw-r--r--sys/vm/uma_dbg.c16
-rw-r--r--sys/vm/uma_int.h40
-rw-r--r--sys/vm/vm_map.c178
-rw-r--r--sys/vm/vm_map.h11
-rw-r--r--sys/vm/vm_meter.c106
-rw-r--r--sys/vm/vm_mmap.c4
-rw-r--r--sys/vm/vm_page.c6
-rw-r--r--sys/vm/vm_page.h8
-rw-r--r--sys/xen/evtchn.h (renamed from sys/i386/include/xen/evtchn.h)2
-rw-r--r--sys/xen/evtchn/evtchn.c118
-rw-r--r--sys/xen/evtchn/evtchn_dev.c6
-rw-r--r--sys/xen/features.c2
-rw-r--r--sys/xen/gnttab.c65
-rw-r--r--sys/xen/gnttab.h5
-rw-r--r--sys/xen/hypervisor.h (renamed from sys/i386/include/xen/hypervisor.h)2
-rw-r--r--sys/xen/xen_intr.h (renamed from sys/i386/include/xen/xen_intr.h)17
-rw-r--r--sys/xen/xenbus/xenbus_client.c183
-rw-r--r--sys/xen/xenbus/xenbus_comms.c317
-rw-r--r--sys/xen/xenbus/xenbus_comms.h116
-rw-r--r--sys/xen/xenbus/xenbus_dev.c133
-rw-r--r--sys/xen/xenbus/xenbus_probe.c118
-rw-r--r--sys/xen/xenbus/xenbus_probe_backend.c5
-rw-r--r--sys/xen/xenbus/xenbus_xs.c1307
-rw-r--r--sys/xen/xenbus/xenbusvar.h65
-rw-r--r--tools/regression/fstest/tests/conf10
-rw-r--r--tools/regression/fstest/tests/misc.sh2
-rw-r--r--tools/regression/lib/libc/stdio/test-printfloat.c22
-rw-r--r--tools/regression/lib/msun/Makefile2
-rw-r--r--tools/regression/lib/msun/test-conj.c158
-rw-r--r--tools/regression/lib/msun/test-conj.t10
-rw-r--r--tools/regression/usr.bin/jot/regress.sh2
-rw-r--r--tools/regression/usr.bin/jot/regress.wX1.out (renamed from tools/regression/usr.bin/jot/regress.wX.out)0
-rw-r--r--tools/sched/schedgraph.py1890
-rw-r--r--tools/tools/README1
-rw-r--r--tools/tools/ath/Makefile2
-rw-r--r--tools/tools/ath/Makefile.inc7
-rw-r--r--tools/tools/ath/athdebug/athdebug.c4
-rw-r--r--tools/tools/ath/athrd/Makefile21
-rw-r--r--tools/tools/ath/athrd/athrd.1172
-rw-r--r--tools/tools/ath/athrd/athrd.c1674
-rwxr-xr-xtools/tools/ath/athrd/run.sh17
-rw-r--r--tools/tools/ath/athstats/Makefile5
-rw-r--r--tools/tools/ath/athstats/athstats.c27
-rw-r--r--tools/tools/ath/athstats/main.c8
-rw-r--r--tools/tools/cfi/Makefile7
-rw-r--r--tools/tools/cfi/cfi.c156
-rw-r--r--tools/tools/nanobsd/gateworks/Files/root/.profile15
-rw-r--r--tools/tools/nanobsd/gateworks/G2348120
-rw-r--r--tools/tools/nanobsd/gateworks/G2358121
-rw-r--r--tools/tools/nanobsd/gateworks/avila10
-rw-r--r--tools/tools/nanobsd/gateworks/cambria10
-rw-r--r--tools/tools/nanobsd/gateworks/cfg/motd1
-rw-r--r--tools/tools/nanobsd/gateworks/cfg/rc.conf24
-rw-r--r--tools/tools/nanobsd/gateworks/cfg/ssh/sshd_config126
-rw-r--r--tools/tools/nanobsd/gateworks/common346
-rw-r--r--tools/tools/net80211/Makefile2
-rw-r--r--tools/tools/net80211/scripts/setup.tdma-master20
-rw-r--r--tools/tools/net80211/scripts/setup.tdma-slave19
-rw-r--r--tools/tools/net80211/wlanstats/main.c39
-rw-r--r--tools/tools/net80211/wlanstats/wlanstats.c46
-rw-r--r--tools/tools/net80211/wlantxtime/Makefile7
-rw-r--r--tools/tools/net80211/wlantxtime/wlantxtime.c596
-rw-r--r--tools/tools/sysbuild/README153
-rw-r--r--tools/tools/sysbuild/sysbuild.sh529
-rw-r--r--tools/tools/usb/print-usb-if-vids.sh2
-rw-r--r--usr.bin/basename/basename.11
-rw-r--r--usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c18
-rw-r--r--usr.bin/csplit/csplit.135
-rw-r--r--usr.bin/csup/Makefile6
-rw-r--r--usr.bin/dirname/dirname.c13
-rw-r--r--usr.bin/fetch/fetch.c7
-rw-r--r--usr.bin/fstat/zfs.c2
-rw-r--r--usr.bin/gprof/gprof.c2
-rw-r--r--usr.bin/mail/Makefile4
-rw-r--r--usr.bin/mail/util.c (renamed from usr.bin/mail/aux.c)0
-rw-r--r--usr.bin/make/Makefile1
-rw-r--r--usr.bin/make/buf.c6
-rw-r--r--usr.bin/make/for.c2
-rw-r--r--usr.bin/make/globals.h1
-rw-r--r--usr.bin/make/job.c20
-rw-r--r--usr.bin/make/job.h1
-rw-r--r--usr.bin/make/main.c67
-rw-r--r--usr.bin/make/make.132
-rw-r--r--usr.bin/make/make.h2
-rw-r--r--usr.bin/make/parse.c4
-rw-r--r--usr.bin/make/suff.c5
-rw-r--r--usr.bin/make/var.c34
-rw-r--r--usr.bin/netstat/inet6.c5
-rw-r--r--usr.bin/netstat/main.c15
-rw-r--r--usr.bin/netstat/netstat.111
-rw-r--r--usr.bin/netstat/unix.c23
-rw-r--r--usr.bin/procstat/procstat.c2
-rw-r--r--usr.bin/procstat/procstat_args.c2
-rw-r--r--usr.bin/procstat/procstat_basic.c2
-rw-r--r--usr.bin/procstat/procstat_bin.c2
-rw-r--r--usr.bin/procstat/procstat_cred.c2
-rw-r--r--usr.bin/procstat/procstat_files.c2
-rw-r--r--usr.bin/procstat/procstat_kstack.c2
-rw-r--r--usr.bin/procstat/procstat_threads.c2
-rw-r--r--usr.bin/procstat/procstat_vm.c2
-rw-r--r--usr.bin/sockstat/sockstat.c12
-rw-r--r--usr.bin/split/split.16
-rw-r--r--usr.bin/truss/truss.14
-rw-r--r--usr.bin/usbhidaction/usbhidaction.c7
-rw-r--r--usr.bin/usbhidctl/usbhid.c7
-rw-r--r--usr.sbin/Makefile1
-rw-r--r--usr.sbin/auditd/Makefile6
-rw-r--r--usr.sbin/bluetooth/Makefile1
-rw-r--r--usr.sbin/bluetooth/btpand/Makefile13
-rw-r--r--usr.sbin/bluetooth/btpand/bnep.c755
-rw-r--r--usr.sbin/bluetooth/btpand/bnep.h72
-rw-r--r--usr.sbin/bluetooth/btpand/btpand.8241
-rw-r--r--usr.sbin/bluetooth/btpand/btpand.c293
-rw-r--r--usr.sbin/bluetooth/btpand/btpand.h212
-rw-r--r--usr.sbin/bluetooth/btpand/channel.c335
-rw-r--r--usr.sbin/bluetooth/btpand/client.c192
-rw-r--r--usr.sbin/bluetooth/btpand/event.c309
-rw-r--r--usr.sbin/bluetooth/btpand/event.h147
-rw-r--r--usr.sbin/bluetooth/btpand/packet.c110
-rw-r--r--usr.sbin/bluetooth/btpand/sdp.c209
-rw-r--r--usr.sbin/bluetooth/btpand/sdp.h38
-rw-r--r--usr.sbin/bluetooth/btpand/server.c277
-rw-r--r--usr.sbin/bluetooth/btpand/tap.c167
-rw-r--r--usr.sbin/bluetooth/hcsecd/hcsecd.c5
-rw-r--r--usr.sbin/bluetooth/hcseriald/hcseriald.c21
-rw-r--r--usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c20
-rw-r--r--usr.sbin/boot0cfg/boot0cfg.833
-rw-r--r--usr.sbin/burncd/burncd.c2
-rw-r--r--usr.sbin/config/config.814
-rw-r--r--usr.sbin/config/main.c28
-rw-r--r--usr.sbin/cpucontrol/cpucontrol.833
-rw-r--r--usr.sbin/crunch/crunchgen/crunchgen.c7
-rw-r--r--usr.sbin/fifolog/lib/fifolog_reader.c1
-rw-r--r--usr.sbin/fifolog/lib/fifolog_write_poll.c15
-rw-r--r--usr.sbin/fwcontrol/fwcontrol.c1
-rw-r--r--usr.sbin/fwcontrol/fwdv.c18
-rw-r--r--usr.sbin/fwcontrol/fwmpegts.c7
-rw-r--r--usr.sbin/gssd/Makefile2
-rw-r--r--usr.sbin/gssd/gssd.82
-rw-r--r--usr.sbin/i2c/Makefile8
-rw-r--r--usr.sbin/i2c/i2c.8168
-rw-r--r--usr.sbin/i2c/i2c.c633
-rw-r--r--usr.sbin/jail/jail.837
-rw-r--r--usr.sbin/kldxref/ef_i386.c3
-rw-r--r--usr.sbin/kldxref/ef_obj.c4
-rw-r--r--usr.sbin/kldxref/fileformat15
-rw-r--r--usr.sbin/kldxref/kldxref.c159
-rw-r--r--usr.sbin/mergemaster/mergemaster.858
-rwxr-xr-xusr.sbin/mergemaster/mergemaster.sh165
-rw-r--r--usr.sbin/mld6query/mld6query.82
-rw-r--r--usr.sbin/mtree/create.c2
-rw-r--r--usr.sbin/mtree/mtree.54
-rw-r--r--usr.sbin/mtree/mtree.84
-rw-r--r--usr.sbin/mtree/spec.c15
-rw-r--r--usr.sbin/pciconf/pciconf.828
-rw-r--r--usr.sbin/pciconf/pciconf.c75
-rw-r--r--usr.sbin/pkg_install/add/pkg_add.14
-rw-r--r--usr.sbin/pkg_install/lib/lib.h2
-rw-r--r--usr.sbin/pkg_install/lib/plist.c83
-rw-r--r--usr.sbin/pstat/pstat.82
-rw-r--r--usr.sbin/pstat/pstat.c39
-rw-r--r--usr.sbin/rrenumd/rrenumd.82
-rw-r--r--usr.sbin/rtadvd/rtadvd.86
-rw-r--r--usr.sbin/rtsold/rtsold.86
-rw-r--r--usr.sbin/sade/disks.c92
-rw-r--r--usr.sbin/sysinstall/devices.c8
-rw-r--r--usr.sbin/sysinstall/disks.c88
-rw-r--r--usr.sbin/sysinstall/menus.c19
-rw-r--r--usr.sbin/sysinstall/sysinstall.86
-rw-r--r--usr.sbin/traceroute6/traceroute6.82
-rw-r--r--usr.sbin/usbconfig/usbconfig.c4
-rw-r--r--usr.sbin/usbdevs/usbdevs.c2
-rw-r--r--usr.sbin/wlandebug/wlandebug.c6
1610 files changed, 87383 insertions, 49216 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index 36893f9..d13e662 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -4,7 +4,7 @@
The compilation of software known as FreeBSD is distributed under the
following terms:
-Copyright (C) 1992-2008 The FreeBSD Project. All rights reserved.
+Copyright (c) 1992-2009 The FreeBSD 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/Makefile.inc1 b/Makefile.inc1
index d247cb1..f6a9c74 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -5,6 +5,7 @@
# -DNO_CLEANDIR run ${MAKE} clean, instead of ${MAKE} cleandir
# -DNO_CLEAN do not clean at all
# -DNO_SHARE do not go into share subdir
+# -DKERNFAST define NO_KERNELCONFIG, NO_KERNELCLEAN and NO_KERNELCONFIG
# -DNO_KERNELCONFIG do not run config in ${MAKE} buildkernel
# -DNO_KERNELCLEAN do not run ${MAKE} clean in ${MAKE} buildkernel
# -DNO_KERNELDEPEND do not run ${MAKE} depend in ${MAKE} buildkernel
@@ -697,6 +698,15 @@ distrib-dirs distribution:
# be set to cross-build, we have to make sure TARGET is set
# properly.
+.if defined(KERNFAST)
+NO_KERNELCLEAN= t
+NO_KERNELCONFIG= t
+NO_KERNELDEPEND= t
+# Shortcut for KERNCONF=Blah -DKERNFAST is now KERNFAST=Blah
+.if !defined(KERNCONF) && ${KERNFAST} != "1"
+KERNCONF=${KERNFAST}
+.endif
+.endif
.if !defined(KERNCONF) && defined(KERNEL)
KERNCONF= ${KERNEL}
KERNWARN=
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 3e25424..530d69c 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -14,6 +14,15 @@
# The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
#
+# 20090203: adding_user.8 moved to adding_user.7
+OLD_FILES+=usr/share/man/man8/adding_user.8.gz
+# 20090122: tzdata2009a import
+OLD_FILES+=usr/share/zoneinfo/Asia/Katmandu
+# 20090102: file 4.26 import
+OLD_FILES+=usr/share/misc/magic.mime
+OLD_FILES+=usr/share/misc/magic.mime.mgc
+# 20081223: bind 9.4.3 import, nsupdate.8 moved to nsupdate.1
+OLD_FILES+=usr/share/man/man8/nsupdate.8.gz
# 20081223: ipprotosw.h removed
OLD_FILES+=usr/include/netinet/ipprotosw.h
# 20081123: vfs_mountedon.9 removed
diff --git a/UPDATING b/UPDATING
index 70c2265..c67b73e 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,31 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
+20090203:
+ The ichsmb(4) driver has been changed to require SMBus slave
+ addresses be left-justified (xxxxxxx0b) rather than right-justified.
+ All of the other SMBus controller drivers require left-justified
+ slave addresses, so this change makes all the drivers provide the
+ same interface.
+
+20090201:
+ INET6 statistics (struct ip6stat) was updated.
+ netstat(1) needs to be recompiled.
+
+20090119:
+ NTFS has been removed from GENERIC kernel on amd64 to match
+ GENERIC on i386. Should not cause any issues since mount_ntfs(8)
+ will load ntfs.ko module automatically when NTFS support is
+ actually needed, unless ntfs.ko is not installed or security
+ level prohibits loading kernel modules. If either is the case,
+ "options NTFS" has to be added into kernel config.
+
+20090115:
+ TCP Appropriate Byte Counting (RFC 3465) support added to kernel.
+ New field in struct tcpcb breaks ABI, so bump __FreeBSD_version to
+ 800061. User space tools that rely on the size of struct tcpcb in
+ tcp_var.h (e.g. sockstat) need to be recompiled.
+
20081225:
ng_tty(4) module updated to match the new TTY subsystem.
Due to API change, user-level applications must be updated.
diff --git a/bin/chmod/chmod.1 b/bin/chmod/chmod.1
index 37d64bb..4ba231b 100644
--- a/bin/chmod/chmod.1
+++ b/bin/chmod/chmod.1
@@ -32,7 +32,7 @@
.\" @(#)chmod.1 8.4 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd December 22, 2006
+.Dd January 26, 2009
.Dt CHMOD 1
.Os
.Sh NAME
@@ -281,6 +281,10 @@ Operations upon the other permissions only (specified by the symbol
``o'' by itself), in combination with the
.Ar perm
symbols ``s'' or ``t'', are ignored.
+.Pp
+The ``w'' permission on directories will permit file creation, relocation,
+and copy into that directory.
+Files created within the directory itself will inherit its group ID.
.Sh EXAMPLES
.Bl -tag -width "u=rwx,go=u-w" -compact
.It Li 644
@@ -343,4 +347,4 @@ command appeared in
.Sh BUGS
There is no
.Ar perm
-option for the naughty bits.
+option for the naughty bits of a horse.
diff --git a/bin/dd/dd.1 b/bin/dd/dd.1
index 31a5d3e..60b0b3e 100644
--- a/bin/dd/dd.1
+++ b/bin/dd/dd.1
@@ -32,7 +32,7 @@
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
.\" $FreeBSD$
.\"
-.Dd August 15, 2004
+.Dd January 23, 2009
.Dt DD 1
.Os
.Sh NAME
@@ -392,6 +392,11 @@ Remove parity bit from a file:
Check for (even) parity errors on a file:
.Pp
.Dl "dd if=file conv=pareven | cmp -x - file"
+.Pp
+To create an image of a Mode-1 CD-ROM, which is a commonly used format
+for data CD-ROM disks, use a block size of 2048 bytes:
+.Pp
+.Dl "dd if=/dev/acd0 of=filename.iso bs=2048"
.Sh SEE ALSO
.Xr cp 1 ,
.Xr mt 1 ,
diff --git a/bin/kenv/kenv.1 b/bin/kenv/kenv.1
index 29260f0..28d89a5 100644
--- a/bin/kenv/kenv.1
+++ b/bin/kenv/kenv.1
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 13, 2005
+.Dd January 13, 2009
.Dt KENV 1
.Os
.Sh NAME
@@ -67,8 +67,28 @@ If the
.Fl q
option is set, warnings normally printed as a result of being unable to
perform the requested operation will be suppressed.
+.Pp
+Variables can be added to the kernel environment using the
+.Xr /boot/loader.conf
+file, or also statically compiled into the kernel using the statement
+.Pp
+.Dl Ic env Ar filename
+.Pp
+in the kernel config file.
+The file can contain lines of the form
+.Pp
+.Dl name = "value" # this is a comment
+.Pp
+where whitespace around name and '=', and
+everything after a '#' character, are ignored. Almost any printable
+character except '=' is acceptable as part of a name. Quotes
+are optional and necessary only if the value contains
+whitespace.
+.Pp
.Sh SEE ALSO
.Xr kenv 2 ,
+.Xr config 5 ,
+.Xr loader.conf 5 ,
.Xr loader 8
.Sh HISTORY
The
diff --git a/bin/ln/ln.1 b/bin/ln/ln.1
index 7ae4ea8..2cb2639 100644
--- a/bin/ln/ln.1
+++ b/bin/ln/ln.1
@@ -38,7 +38,7 @@
.Sh NAME
.Nm ln ,
.Nm link
-.Nd make links
+.Nd link files
.Sh SYNOPSIS
.Nm
.Op Fl s Op Fl F
@@ -57,8 +57,13 @@
.Sh DESCRIPTION
The
.Nm
-utility creates a new directory entry (linked file) which has the
-same modes as the original file.
+utility creates a new directory entry (linked file) for the file name
+specified by
+.Ar target_file .
+The
+.Ar target_file
+will be created with the same file modes as the
+.Ar source_file .
It is useful for maintaining multiple copies of a file in many places
at once without using up storage for the
.Dq copies ;
@@ -148,7 +153,7 @@ links.
A hard link to a file is indistinguishable from the original directory entry;
any changes to a file are effectively independent of the name used to reference
the file.
-Hard links may not normally refer to directories and may not span file systems.
+Directories may not be hardlinked, and hard links may not span file systems.
.Pp
A symbolic link contains the name of the file to
which it is linked.
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index cda1180..0fad68e 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -425,19 +425,11 @@ node_creat(ARCHD *arcn)
* we were able to create the node. set uid/gid, modes and times
*/
if (pids)
- res = ((arcn->type == PAX_SLK) ?
- set_lids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid) :
- set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid));
+ res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid);
else
res = 0;
/*
- * symlinks are done now.
- */
- if (arcn->type == PAX_SLK)
- return(0);
-
- /*
* IMPORTANT SECURITY NOTE:
* if not preserving mode or we cannot set uid/gid, then PROHIBIT any
* set uid/gid bits
@@ -632,7 +624,7 @@ chk_path( char *name, uid_t st_uid, gid_t st_gid)
* used by -t to reset access times).
* When ign is zero, only those times the user has asked for are set, the
* other ones are left alone. We do not assume the un-documented feature
- * of many utimes() implementations that consider a 0 time value as a do
+ * of many lutimes() implementations that consider a 0 time value as a do
* not set request.
*/
@@ -661,7 +653,7 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc)
/*
* set the times
*/
- if (utimes(fnm, tv) < 0)
+ if (lutimes(fnm, tv) < 0)
syswarn(1, errno, "Access/modification time set failed on: %s",
fnm);
return;
@@ -677,30 +669,6 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc)
int
set_ids(char *fnm, uid_t uid, gid_t gid)
{
- if (chown(fnm, uid, gid) < 0) {
- /*
- * ignore EPERM unless in verbose mode or being run by root.
- * if running as pax, POSIX requires a warning.
- */
- if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag ||
- geteuid() == 0)
- syswarn(1, errno, "Unable to set file uid/gid of %s",
- fnm);
- return(-1);
- }
- return(0);
-}
-
-/*
- * set_lids()
- * set the uid and gid of a file system node
- * Return:
- * 0 when set, -1 on failure
- */
-
-int
-set_lids(char *fnm, uid_t uid, gid_t gid)
-{
if (lchown(fnm, uid, gid) < 0) {
/*
* ignore EPERM unless in verbose mode or being run by root.
@@ -724,7 +692,7 @@ void
set_pmode(char *fnm, mode_t mode)
{
mode &= ABITS;
- if (chmod(fnm, mode) < 0)
+ if (lchmod(fnm, mode) < 0)
syswarn(1, errno, "Could not set permissions on %s", fnm);
return;
}
diff --git a/bin/test/test.1 b/bin/test/test.1
index 91b95c7..6b0ca78 100644
--- a/bin/test/test.1
+++ b/bin/test/test.1
@@ -310,7 +310,7 @@ are evaluated consistently according to the rules specified in the
standards document.
All other cases are subject to the ambiguity in the
command semantics.
-.Sh RETURN VALUES
+.Sh EXIT STATUS
The
.Nm
utility exits with one of the following values:
diff --git a/cddl/contrib/opensolaris/cmd/zinject/zinject.c b/cddl/contrib/opensolaris/cmd/zinject/zinject.c
index 2302dc4..cd48b68 100644
--- a/cddl/contrib/opensolaris/cmd/zinject/zinject.c
+++ b/cddl/contrib/opensolaris/cmd/zinject/zinject.c
@@ -146,6 +146,7 @@
#include <unistd.h>
#include <sys/fs/zfs.h>
+#include <sys/param.h>
#include <sys/mount.h>
#include <libzfs.h>
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
index 30377b5..aa78658 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -1739,15 +1739,11 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
* Arches which are 32-bit only just use the normal
* library path.
*/
-#if defined(__i386__)
- int use_32 = 1; /* use /usr/lib/... -sson */
-#else
int use_32 = 0;
#endif
-#endif
(void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o",
- use_32 ? "":"32");
+ use_32 ? "32":"");
len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile,
drti) + 1;
diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES
index 65980ea..f3d53ee 100644
--- a/contrib/bind9/CHANGES
+++ b/contrib/bind9/CHANGES
@@ -1,3 +1,11 @@
+ --- 9.4.3-P1 released ---
+
+2522. [security] Handle -1 from DSA_do_verify().
+
+2498. [bug] Removed a bogus function argument used with
+ ISC_SOCKET_USE_POLLWATCH: it could cause compiler
+ warning or crash named with the debug 1 level
+ of logging. [RT #18917]
--- 9.4.3 released ---
diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api
index 7949ab0..0b8a3bc 100644
--- a/contrib/bind9/lib/dns/api
+++ b/contrib/bind9/lib/dns/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 36
-LIBREVISION = 1
+LIBREVISION = 2
LIBAGE = 0
diff --git a/contrib/bind9/lib/dns/openssldsa_link.c b/contrib/bind9/lib/dns/openssldsa_link.c
index d2b0833..2ff33f32 100644
--- a/contrib/bind9/lib/dns/openssldsa_link.c
+++ b/contrib/bind9/lib/dns/openssldsa_link.c
@@ -16,7 +16,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: openssldsa_link.c,v 1.1.6.9 2007/08/28 07:20:04 tbox Exp $ */
+/* $Id: openssldsa_link.c,v 1.1.6.9.28.1 2008/12/24 00:21:22 marka Exp $ */
#ifdef OPENSSL
@@ -133,7 +133,7 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
DSA_SIG_free(dsasig);
- if (status == 0)
+ if (status != 1)
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
return (ISC_R_SUCCESS);
diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c
index 2609df6..aacba45 100644
--- a/contrib/bind9/lib/dns/opensslrsa_link.c
+++ b/contrib/bind9/lib/dns/opensslrsa_link.c
@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: opensslrsa_link.c,v 1.1.6.11 2006/11/07 21:28:49 marka Exp $
+ * $Id: opensslrsa_link.c,v 1.1.6.11.58.1 2008/12/24 00:21:22 marka Exp $
*/
#ifdef OPENSSL
@@ -246,7 +246,7 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
status = RSA_verify(type, digest, digestlen, sig->base,
RSA_size(rsa), rsa);
- if (status == 0)
+ if (status != 1)
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
return (ISC_R_SUCCESS);
diff --git a/contrib/bind9/lib/isc/unix/socket.c b/contrib/bind9/lib/isc/unix/socket.c
index 3239614..8b006e4 100644
--- a/contrib/bind9/lib/isc/unix/socket.c
+++ b/contrib/bind9/lib/isc/unix/socket.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.237.18.56 2008/11/12 03:58:36 marka Exp $ */
+/* $Id: socket.c,v 1.237.18.56.2.1 2008/12/23 00:14:34 marka Exp $ */
/*! \file */
@@ -501,7 +501,7 @@ FIX_IPV6_RECVPKTINFO(isc_socket_t *sock)
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
(void *)&on, sizeof(on)) < 0) {
-
+
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_RECVPKTINFO) "
"%s: %s", sock->fd,
@@ -3163,7 +3163,6 @@ watcher(void *uap) {
ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET,
ISC_LOG_DEBUG(1),
- ISC_LOG_INFO,
"unexpected POLL timeout");
}
pollstate = poll_active;
@@ -4902,7 +4901,7 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
(void *)&onoff, sizeof(int)) < 0) {
char strbuf[ISC_STRERRORSIZE];
-
+
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_V6ONLY) "
"%s: %s", sock->fd,
diff --git a/contrib/bind9/version b/contrib/bind9/version
index 61ba428..e956921 100644
--- a/contrib/bind9/version
+++ b/contrib/bind9/version
@@ -1,4 +1,4 @@
-# $Id: version,v 1.29.134.23 2008/11/12 04:17:12 marka Exp $
+# $Id: version,v 1.29.134.23.2.1 2008/12/24 00:21:22 marka Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
@@ -6,5 +6,5 @@
MAJORVER=9
MINORVER=4
PATCHVER=3
-RELEASETYPE=
-RELEASEVER=
+RELEASETYPE=-P
+RELEASEVER=1
diff --git a/contrib/csup/GNUmakefile b/contrib/csup/GNUmakefile
index 7aceccd..18fb071 100644
--- a/contrib/csup/GNUmakefile
+++ b/contrib/csup/GNUmakefile
@@ -12,8 +12,9 @@ GROUP?= 0
UNAME= $(shell uname -s)
SRCS= attrstack.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 pathcomp.c \
- parse.c proto.c status.c stream.c threads.c token.c updater.c
+ globtree.c idcache.c keyword.c lex.rcs.c lister.c main.c misc.c mux.c \
+ pathcomp.c parse.c proto.c rcsfile.c rcsparse.c rsyncfile.c status.c \
+ stream.c threads.c token.c updater.c
OBJS= $(SRCS:.c=.o)
WARNS= -Wall -W -Wno-unused-parameter -Wmissing-prototypes -Wpointer-arith \
diff --git a/contrib/csup/Makefile b/contrib/csup/Makefile
index b672c5d..d82a0f1 100644
--- a/contrib/csup/Makefile
+++ b/contrib/csup/Makefile
@@ -9,10 +9,11 @@ UNAME!= /usr/bin/uname -s
PROG= csup
SRCS= attrstack.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
+ pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
+ rcsfile.c rcsparse.c lex.rcs.c rsyncfile.c
CFLAGS+= -I. -I${.CURDIR} -g -pthread -DHAVE_FFLAGS -DNDEBUG
-WARNS?= 6
+WARNS?= 1
# A bit of tweaking is needed to get this Makefile working
# with the bsd.prog.mk of all the *BSD OSes...
diff --git a/contrib/csup/TODO b/contrib/csup/TODO
index 66988e1..41b2408 100644
--- a/contrib/csup/TODO
+++ b/contrib/csup/TODO
@@ -28,4 +28,3 @@ MISSING FEATURES:
checkout files (files in CVS/ subdirectores), a command line override
to only update a specific collection and a third verbosity level to
display commit log messages.
-- Add support for CVS mode (maybe?).
diff --git a/contrib/csup/config.c b/contrib/csup/config.c
index 5b71e74..46ae6cd 100644
--- a/contrib/csup/config.c
+++ b/contrib/csup/config.c
@@ -133,7 +133,6 @@ config_init(const char *file, struct coll *override, int overridemask)
coll->co_options &= ~CO_CHECKRCS;
/* In recent versions, we always try to set the file modes. */
coll->co_options |= CO_SETMODE;
- /* XXX We don't support the rsync updating algorithm yet. */
coll->co_options |= CO_NORSYNC;
error = config_parse_refusefiles(coll);
if (error)
@@ -444,10 +443,6 @@ coll_add(char *name)
"\"%s\"\n", cur_coll->co_name);
exit(1);
}
- if (!(cur_coll->co_options & CO_CHECKOUTMODE)) {
- lprintf(-1, "Client only supports checkout mode\n");
- exit(1);
- }
if (!STAILQ_EMPTY(&colls)) {
coll = STAILQ_LAST(&colls, coll, co_next);
if (strcmp(coll->co_host, cur_coll->co_host) != 0) {
diff --git a/contrib/csup/csup.1 b/contrib/csup/csup.1
index f8c7c13..4d22fc4 100644
--- a/contrib/csup/csup.1
+++ b/contrib/csup/csup.1
@@ -442,8 +442,6 @@ They are called
mode and
.Em checkout
mode.
-.Nm
-only supports the checkout mode for now.
.Pp
In CVS mode, the client receives copies of the actual RCS files making
up the master CVS repository. CVS mode is the default mode of operation.
diff --git a/contrib/csup/detailer.c b/contrib/csup/detailer.c
index bf2ddb7..5592655 100644
--- a/contrib/csup/detailer.c
+++ b/contrib/csup/detailer.c
@@ -30,13 +30,21 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "config.h"
#include "detailer.h"
#include "fixups.h"
+#include "globtree.h"
#include "misc.h"
#include "mux.h"
#include "proto.h"
+#include "rcsfile.h"
+#include "rsyncfile.h"
#include "status.h"
#include "stream.h"
@@ -56,8 +64,16 @@ struct detailer {
static int detailer_batch(struct detailer *);
static int detailer_coll(struct detailer *, struct coll *,
struct status *);
-static int detailer_dofile(struct detailer *, struct coll *,
+static int detailer_dofile_co(struct detailer *, struct coll *,
struct status *, char *);
+static int detailer_dofile_rcs(struct detailer *, struct coll *,
+ char *, char *);
+static int detailer_dofile_regular(struct detailer *, char *, char *);
+static int detailer_dofile_rsync(struct detailer *, char *, char *);
+static int detailer_checkrcsattr(struct detailer *, struct coll *, char *,
+ struct fattr *, int);
+int detailer_send_details(struct detailer *, struct coll *, char *,
+ char *, struct fattr *);
void *
detailer(void *arg)
@@ -186,8 +202,13 @@ detailer_batch(struct detailer *d)
}
if (fixup->f_coll != coll)
break;
- error = proto_printf(wr, "Y %s %s %s\n", fixup->f_name,
- coll->co_tag, coll->co_date);
+ if (coll->co_options & CO_CHECKOUTMODE)
+ error = proto_printf(wr, "Y %s %s %s\n",
+ fixup->f_name, coll->co_tag, coll->co_date);
+ else {
+ error = proto_printf(wr, "A %s\n",
+ fixup->f_name);
+ }
if (error)
return (DETAILER_ERR_WRITE);
fixup = NULL;
@@ -208,12 +229,14 @@ detailer_batch(struct detailer *d)
static int
detailer_coll(struct detailer *d, struct coll *coll, struct status *st)
{
+ struct fattr *rcsattr;
struct stream *rd, *wr;
- char *cmd, *file, *line, *msg;
- int error;
+ char *attr, *cmd, *file, *line, *msg, *path, *target;
+ int error, attic;
rd = d->rd;
wr = d->wr;
+ attic = 0;
line = stream_getln(rd, NULL);
if (line == NULL)
return (DETAILER_ERR_READ);
@@ -226,17 +249,84 @@ detailer_coll(struct detailer *d, struct coll *coll, struct status *st)
/* Delete file. */
file = proto_get_ascii(&line);
if (file == NULL || line != NULL)
- return (DETAILER_ERR_PROTO);
+ return (DETAILER_ERR_PROTO);
error = proto_printf(wr, "D %s\n", file);
if (error)
return (DETAILER_ERR_WRITE);
break;
+ case 'I':
+ case 'i':
+ case 'j':
+ /* Directory operations. */
+ file = proto_get_ascii(&line);
+ if (file == NULL || line != NULL)
+ return (DETAILER_ERR_PROTO);
+ error = proto_printf(wr, "%s %s\n", cmd, file);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ break;
+ case 'J':
+ /* Set directory attributes. */
+ file = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ if (file == NULL || line != NULL || attr == NULL)
+ return (DETAILER_ERR_PROTO);
+ error = proto_printf(wr, "%s %s %s\n", cmd, file, attr);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ break;
+ case 'H':
+ case 'h':
+ /* Create a hard link. */
+ file = proto_get_ascii(&line);
+ target = proto_get_ascii(&line);
+ if (file == NULL || target == NULL)
+ return (DETAILER_ERR_PROTO);
+ error = proto_printf(wr, "%s %s %s\n", cmd, file,
+ target);
+ break;
+ case 't':
+ file = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ if (file == NULL || attr == NULL || line != NULL) {
+ return (DETAILER_ERR_PROTO);
+ }
+ rcsattr = fattr_decode(attr);
+ if (rcsattr == NULL) {
+ return (DETAILER_ERR_PROTO);
+ }
+ error = detailer_checkrcsattr(d, coll, file, rcsattr,
+ 1);
+ break;
+
+ case 'T':
+ file = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ if (file == NULL || attr == NULL || line != NULL)
+ return (DETAILER_ERR_PROTO);
+ rcsattr = fattr_decode(attr);
+ if (rcsattr == NULL)
+ return (DETAILER_ERR_PROTO);
+ error = detailer_checkrcsattr(d, coll, file, rcsattr,
+ 0);
+ break;
+
case 'U':
/* Add or update file. */
file = proto_get_ascii(&line);
if (file == NULL || line != NULL)
return (DETAILER_ERR_PROTO);
- error = detailer_dofile(d, coll, st, file);
+ if (coll->co_options & CO_CHECKOUTMODE) {
+ error = detailer_dofile_co(d, coll, st, file);
+ } else {
+ path = cvspath(coll->co_prefix, file, 0);
+ rcsattr = fattr_frompath(path, FATTR_NOFOLLOW);
+ error = detailer_send_details(d, coll, file,
+ path, rcsattr);
+ if (rcsattr != NULL)
+ fattr_free(rcsattr);
+ free(path);
+ }
if (error)
return (error);
break;
@@ -261,14 +351,110 @@ detailer_coll(struct detailer *d, struct coll *coll, struct status *st)
return (0);
}
+/*
+ * Tell the server to update a regular file.
+ */
static int
-detailer_dofile(struct detailer *d, struct coll *coll, struct status *st,
- char *file)
+detailer_dofile_regular(struct detailer *d, char *name, char *path)
{
+ struct stream *wr;
+ struct stat st;
char md5[MD5_DIGEST_SIZE];
+ int error;
+
+ wr = d->wr;
+ error = stat(path, &st);
+ /* If we don't have it or it's unaccessible, we want it again. */
+ if (error) {
+ proto_printf(wr, "A %s\n", name);
+ return (0);
+ }
+
+ /* If not, we want the file to be updated. */
+ error = MD5_File(path, md5);
+ if (error) {
+ lprintf(-1, "Error reading \"%s\"\n", name);
+ return (error);
+ }
+ error = proto_printf(wr, "R %s %O %s\n", name, st.st_size, md5);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ return (0);
+}
+
+/*
+ * Tell the server to update a file with the rsync algorithm.
+ */
+static int
+detailer_dofile_rsync(struct detailer *d, char *name, char *path)
+{
+ struct stream *wr;
+ struct rsyncfile *rf;
+
+ wr = d->wr;
+ rf = rsync_open(path, 0, 1);
+ if (rf == NULL) {
+ /* Fallback if we fail in opening it. */
+ proto_printf(wr, "A %s\n", name);
+ return (0);
+ }
+ proto_printf(wr, "r %s %z %z\n", name, rsync_filesize(rf),
+ rsync_blocksize(rf));
+ /* Detail the blocks. */
+ while (rsync_nextblock(rf) != 0)
+ proto_printf(wr, "%s %s\n", rsync_rsum(rf), rsync_blockmd5(rf));
+ proto_printf(wr, ".\n");
+ rsync_close(rf);
+ return (0);
+}
+
+/*
+ * Tell the server to update an RCS file that we have, or send it if we don't.
+ */
+static int
+detailer_dofile_rcs(struct detailer *d, struct coll *coll, char *name,
+ char *path)
+{
+ struct stream *wr;
+ struct fattr *fa;
+ struct rcsfile *rf;
+ int error;
+
+ wr = d->wr;
+ path = atticpath(coll->co_prefix, name);
+ fa = fattr_frompath(path, FATTR_NOFOLLOW);
+ if (fa == NULL) {
+ /* We don't have it, so send request to get it. */
+ error = proto_printf(wr, "A %s\n", name);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ free(path);
+ return (0);
+ }
+
+ rf = rcsfile_frompath(path, name, coll->co_cvsroot, coll->co_tag, 1);
+ free(path);
+ if (rf == NULL) {
+ error = proto_printf(wr, "A %s\n", name);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ return (0);
+ }
+ /* Tell to update the RCS file. The client version details follow. */
+ rcsfile_send_details(rf, wr);
+ rcsfile_free(rf);
+ fattr_free(fa);
+ return (0);
+}
+
+static int
+detailer_dofile_co(struct detailer *d, struct coll *coll, struct status *st,
+ char *file)
+{
struct stream *wr;
struct fattr *fa;
struct statusrec *sr;
+ char md5[MD5_DIGEST_SIZE];
char *path;
int error, ret;
@@ -337,3 +523,81 @@ detailer_dofile(struct detailer *d, struct coll *coll, struct status *st,
return (DETAILER_ERR_WRITE);
return (0);
}
+
+int
+detailer_checkrcsattr(struct detailer *d, struct coll *coll, char *name,
+ struct fattr *server_attr, int attic)
+{
+ struct fattr *client_attr;
+ char *attr, *path;
+ int error;
+
+ /*
+ * I don't think we can use the status file, since it only records file
+ * attributes in cvsmode.
+ */
+ client_attr = NULL;
+ path = cvspath(coll->co_prefix, name, attic);
+ if (path == NULL) {
+ return (DETAILER_ERR_PROTO);
+ }
+
+ if (access(path, F_OK) == 0 &&
+ ((client_attr = fattr_frompath(path, FATTR_NOFOLLOW)) != NULL) &&
+ fattr_equal(client_attr, server_attr)) {
+ attr = fattr_encode(client_attr, NULL, 0);
+ if (attic) {
+ error = proto_printf(d->wr, "l %s %s\n", name, attr);
+ } else {
+ error = proto_printf(d->wr, "L %s %s\n", name, attr);
+ }
+ free(attr);
+ free(path);
+ fattr_free(client_attr);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ return (0);
+ }
+ /* We don't have it, so tell the server to send it. */
+ error = detailer_send_details(d, coll, name, path, client_attr);
+ fattr_free(client_attr);
+ free(path);
+ return (error);
+}
+
+int
+detailer_send_details(struct detailer *d, struct coll *coll, char *name,
+ char *path, struct fattr *fa)
+{
+ int error;
+ size_t len;
+
+ /*
+ * Try to check if the file exists either live or dead to see if we can
+ * edit it and put it live or dead, rather than receiving the entire
+ * file.
+ */
+ if (fa == NULL) {
+ path = atticpath(coll->co_prefix, name);
+ fa = fattr_frompath(path, FATTR_NOFOLLOW);
+ }
+ if (fa == NULL) {
+ error = proto_printf(d->wr, "A %s\n", name);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ } else if (fattr_type(fa) == FT_FILE) {
+ if (isrcs(name, &len) && !(coll->co_options & CO_NORCS)) {
+ detailer_dofile_rcs(d, coll, name, path);
+ } else if (!(coll->co_options & CO_NORSYNC) &&
+ !globtree_test(coll->co_norsync, name)) {
+ detailer_dofile_rsync(d, name, path);
+ } else {
+ detailer_dofile_regular(d, name, path);
+ }
+ } else {
+ error = proto_printf(d->wr, "N %s\n", name);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ }
+ return (0);
+}
diff --git a/contrib/csup/diff.c b/contrib/csup/diff.c
index ea53c36..8059676 100644
--- a/contrib/csup/diff.c
+++ b/contrib/csup/diff.c
@@ -26,9 +26,12 @@
* $FreeBSD$
*/
+#include <sys/limits.h>
+
#include <assert.h>
#include <err.h>
#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -36,15 +39,20 @@
#include "keyword.h"
#include "misc.h"
#include "stream.h"
+#include "queue.h"
typedef long lineno_t;
#define EC_ADD 0
#define EC_DEL 1
+#define MAXKEY LONG_MAX
/* Editing command and state. */
struct editcmd {
int cmd;
+ long key;
+ int havetext;
+ int offset;
lineno_t where;
lineno_t count;
lineno_t lasta;
@@ -55,20 +63,28 @@ struct editcmd {
struct diffinfo *di;
struct stream *orig;
struct stream *dest;
+ LIST_ENTRY(editcmd) next;
+};
+
+struct diffstart {
+ LIST_HEAD(, editcmd) dhead;
};
static int diff_geteditcmd(struct editcmd *, char *);
static int diff_copyln(struct editcmd *, lineno_t);
+static int diff_ignoreln(struct editcmd *, lineno_t);
static void diff_write(struct editcmd *, void *, size_t);
+static int diff_insert_edit(struct diffstart *, struct editcmd *);
+static void diff_free(struct diffstart *);
int
diff_apply(struct stream *rd, struct stream *orig, struct stream *dest,
- struct keyword *keyword, struct diffinfo *di)
+ struct keyword *keyword, struct diffinfo *di, int comode)
{
struct editcmd ec;
lineno_t i;
- char *line;
size_t size;
+ char *line;
int empty, error, noeol;
memset(&ec, 0, sizeof(ec));
@@ -104,7 +120,7 @@ diff_apply(struct stream *rd, struct stream *orig, struct stream *dest,
line = stream_getln(rd, &size);
if (line == NULL)
return (-1);
- if (line[0] == '.') {
+ if (comode && line[0] == '.') {
line++;
size--;
}
@@ -124,10 +140,10 @@ diff_apply(struct stream *rd, struct stream *orig, struct stream *dest,
}
line = stream_getln(rd, NULL);
}
- if (line == NULL)
+ if (comode && line == NULL)
return (-1);
/* If we got ".+", there's no ending newline. */
- if (strcmp(line, ".+") == 0 && !empty)
+ if (comode && strcmp(line, ".+") == 0 && !empty)
noeol = 1;
ec.where = 0;
while ((line = stream_getln(orig, &size)) != NULL)
@@ -143,6 +159,198 @@ diff_apply(struct stream *rd, struct stream *orig, struct stream *dest,
return (0);
}
+/*
+ * Reverse a diff using the same algorithm as in cvsup.
+ */
+static int
+diff_write_reverse(struct stream *dest, struct diffstart *ds)
+{
+ struct editcmd *ec, *nextec;
+ long editline, endline, firstoutputlinedeleted;
+ long num_added, num_deleted, startline;
+ int num;
+
+ nextec = LIST_FIRST(&ds->dhead);
+ editline = 0;
+ num = 0;
+ while (nextec != NULL) {
+ ec = nextec;
+ nextec = LIST_NEXT(nextec, next);
+ if (nextec == NULL)
+ break;
+ num++;
+ num_deleted = 0;
+ if (ec->havetext)
+ num_deleted = ec->count;
+ num_added = num_deleted + nextec->offset - ec->offset;
+ if (num_deleted > 0) {
+ firstoutputlinedeleted = ec->key - num_deleted + 1;
+ stream_printf(dest, "d%ld %ld\n", firstoutputlinedeleted,
+ num_deleted);
+ if (num_added <= 0)
+ continue;
+ }
+ if (num_added > 0) {
+ stream_printf(dest, "a%ld %ld\n", ec->key, num_added);
+ startline = ec->key - num_deleted + 1 + ec->offset;
+ endline = startline + num_added - 1;
+
+ /* Copy lines from original file. First ignore some. */
+ ec->editline = editline;
+ diff_ignoreln(ec, startline - 1);
+ diff_copyln(ec, endline);
+ editline = ec->editline;
+ }
+ }
+ return (0);
+}
+
+/*
+ * Insert a diff into the list sorted on key. Should perhaps use quicker
+ * algorithms than insertion sort, but do this for now.
+ */
+static int
+diff_insert_edit(struct diffstart *ds, struct editcmd *ec)
+{
+ struct editcmd *curec;
+
+ if (ec == NULL)
+ return (0);
+
+ if (LIST_EMPTY(&ds->dhead)) {
+ LIST_INSERT_HEAD(&ds->dhead, ec, next);
+ return (0);
+ }
+
+ /* Insertion sort based on key. */
+ LIST_FOREACH(curec, &ds->dhead, next) {
+ if (ec->key < curec->key) {
+ LIST_INSERT_BEFORE(curec, ec, next);
+ return (0);
+ }
+ if (LIST_NEXT(curec, next) == NULL)
+ break;
+ }
+ /* Just insert it after. */
+ LIST_INSERT_AFTER(curec, ec, next);
+ return (0);
+}
+
+static void
+diff_free(struct diffstart *ds)
+{
+ struct editcmd *ec;
+
+ while(!LIST_EMPTY(&ds->dhead)) {
+ ec = LIST_FIRST(&ds->dhead);
+ LIST_REMOVE(ec, next);
+ free(ec);
+ }
+}
+
+/*
+ * Write the reverse diff from the diff in rd, and original file into
+ * destination. This algorithm is the same as used in cvsup.
+ */
+int
+diff_reverse(struct stream *rd, struct stream *orig, struct stream *dest,
+ struct keyword *keyword, struct diffinfo *di)
+{
+ struct diffstart ds;
+ struct editcmd ec, *addec, *delec;
+ lineno_t i;
+ char *line;
+ int error, offset;
+
+ memset(&ec, 0, sizeof(ec));
+ ec.orig = orig;
+ ec.dest = dest;
+ ec.keyword = keyword;
+ ec.di = di;
+ addec = NULL;
+ delec = NULL;
+ ec.havetext = 0;
+ offset = 0;
+ LIST_INIT(&ds.dhead);
+
+ /* Start with next since we need it. */
+ line = stream_getln(rd, NULL);
+ /* First we build up the list of diffs from input. */
+ while (line != NULL) {
+ error = diff_geteditcmd(&ec, line);
+ if (error)
+ break;
+ if (ec.cmd == EC_ADD) {
+ addec = xmalloc(sizeof(struct editcmd));
+ *addec = ec;
+ addec->havetext = 1;
+ /* Ignore the lines we was supposed to add. */
+ for (i = 0; i < ec.count; i++) {
+ line = stream_getln(rd, NULL);
+ if (line == NULL)
+ return (-1);
+ }
+
+ /* Get the next diff command if we have one. */
+ addec->key = addec->where + addec->count - offset;
+ if (delec != NULL &&
+ delec->key == addec->key - addec->count) {
+ delec->key = addec->key;
+ delec->havetext = addec->havetext;
+ delec->count = addec->count;
+ diff_insert_edit(&ds, delec);
+ free(addec);
+ delec = NULL;
+ addec = NULL;
+ } else {
+ if (delec != NULL) {
+ diff_insert_edit(&ds, delec);
+ }
+ delec = NULL;
+ addec->offset = offset;
+ diff_insert_edit(&ds, addec);
+ addec = NULL;
+ }
+ offset -= ec.count;
+ } else if (ec.cmd == EC_DEL) {
+ if (delec != NULL) {
+ /* Update offset to our next. */
+ diff_insert_edit(&ds, delec);
+ delec = NULL;
+ }
+ delec = xmalloc(sizeof(struct editcmd));
+ *delec = ec;
+ delec->key = delec->where - 1 - offset;
+ delec->offset = offset;
+ delec->count = 0;
+ delec->havetext = 0;
+ /* Important to use the count we had before reset.*/
+ offset += ec.count;
+ }
+ line = stream_getln(rd, NULL);
+ }
+
+ while (line != NULL)
+ line = stream_getln(rd, NULL);
+ if (delec != NULL) {
+ diff_insert_edit(&ds, delec);
+ delec = NULL;
+ }
+
+ addec = xmalloc(sizeof(struct editcmd));
+ /* Should be filesize, but we set it to max value. */
+ addec->key = MAXKEY;
+ addec->offset = offset;
+ addec->havetext = 0;
+ addec->count = 0;
+ diff_insert_edit(&ds, addec);
+ addec = NULL;
+ diff_write_reverse(dest, &ds);
+ diff_free(&ds);
+ stream_flush(dest);
+ return (0);
+}
+
/* Get an editing command from the diff. */
static int
diff_geteditcmd(struct editcmd *ec, char *line)
@@ -181,8 +389,8 @@ diff_geteditcmd(struct editcmd *ec, char *line)
static int
diff_copyln(struct editcmd *ec, lineno_t to)
{
- char *line;
size_t size;
+ char *line;
while (ec->editline < to) {
line = stream_getln(ec->orig, &size);
@@ -194,12 +402,28 @@ diff_copyln(struct editcmd *ec, lineno_t to)
return (0);
}
+/* Ignore lines from the original version of the file up to line "to". */
+static int
+diff_ignoreln(struct editcmd *ec, lineno_t to)
+{
+ size_t size;
+ char *line;
+
+ while (ec->editline < to) {
+ line = stream_getln(ec->orig, &size);
+ if (line == NULL)
+ return (-1);
+ ec->editline++;
+ }
+ return (0);
+}
+
/* Write a new line to the file, expanding RCS keywords appropriately. */
static void
diff_write(struct editcmd *ec, void *buf, size_t size)
{
- char *line, *newline;
size_t newsize;
+ char *line, *newline;
int ret;
line = buf;
diff --git a/contrib/csup/diff.h b/contrib/csup/diff.h
index cbd9e50..b0c8c97 100644
--- a/contrib/csup/diff.h
+++ b/contrib/csup/diff.h
@@ -45,6 +45,8 @@ struct diffinfo {
};
int diff_apply(struct stream *, struct stream *, struct stream *,
- struct keyword *, struct diffinfo *);
+ struct keyword *, struct diffinfo *, int);
+int diff_reverse(struct stream *, struct stream *,
+ struct stream *, struct keyword *, struct diffinfo *);
#endif /* !_DIFF_H_ */
diff --git a/contrib/csup/fattr.c b/contrib/csup/fattr.c
index b29d73d..b141c2c 100644
--- a/contrib/csup/fattr.c
+++ b/contrib/csup/fattr.c
@@ -44,7 +44,7 @@
/*
* Include the appropriate definition for the file attributes we support.
* There are two different files: fattr_bsd.h for BSD-like systems that
- * support the extended file flags à la chflags() and fattr_posix.h for
+ * support the extended file flags a la chflags() and fattr_posix.h for
* bare POSIX systems that don't.
*/
#ifdef HAVE_FFLAGS
@@ -449,7 +449,7 @@ fattr_encode(const struct fattr *fa, fattr_support_t support, int ignore)
piece++;
}
if (mask & FA_DEV) {
- vallen = snprintf(piece->val, sizeof(piece->val), "%lld",
+ vallen = snprintf(piece->val, sizeof(piece->val), "%llx",
(long long)fa->dev);
len += snprintf(piece->len, sizeof(piece->len), "%lld",
(long long)vallen) + vallen + 1;
@@ -534,6 +534,13 @@ fattr_getlinkcount(const struct fattr *fa)
return (fa->linkcount);
}
+char *
+fattr_getlinktarget(const struct fattr *fa)
+{
+
+ return (fa->linktarget);
+}
+
/*
* Eat the specified attribute and put it in the file attribute
* structure. Returns NULL on error, or a pointer to the next
@@ -732,18 +739,28 @@ fattr_makenode(const struct fattr *fa, const char *path)
mode_t modemask, mode;
int error;
+ error = 0;
+
if (fa->mask & FA_OWNER && fa->mask & FA_GROUP)
modemask = FA_SETIDMASK | FA_PERMMASK;
else
modemask = FA_PERMMASK;
/* We only implement fattr_makenode() for dirs for now. */
- assert(fa->type == FT_DIRECTORY);
if (fa->mask & FA_MODE)
mode = fa->mode & modemask;
else
mode = 0700;
- error = mkdir(path, mode);
+
+ if (fa->type == FT_DIRECTORY)
+ error = mkdir(path, mode);
+ else if (fa->type == FT_SYMLINK) {
+ error = symlink(fa->linktarget, path);
+ } else if (fa->type == FT_CDEV) {
+ lprintf(-1, "Character devices not supported!\n");
+ } else if (fa->type == FT_BDEV) {
+ lprintf(-1, "Block devices not supported!\n");
+ }
return (error);
}
@@ -823,6 +840,19 @@ fattr_install(struct fattr *fa, const char *topath, const char *frompath)
}
#endif
+ /*
+ * If it is changed from a file to a symlink, remove the file
+ * and create the symlink.
+ */
+ if (inplace && (fa->type == FT_SYMLINK) &&
+ (old->type == FT_FILE)) {
+ error = unlink(topath);
+ if (error)
+ goto bad;
+ error = symlink(fa->linktarget, topath);
+ if (error)
+ goto bad;
+ }
/* Determine whether we need to remove the target first. */
if (!inplace && (fa->type == FT_DIRECTORY) !=
(old->type == FT_DIRECTORY)) {
@@ -853,8 +883,9 @@ fattr_install(struct fattr *fa, const char *topath, const char *frompath)
if (mask & FA_GROUP)
gid = fa->gid;
error = chown(frompath, uid, gid);
- if (error)
+ if (error) {
goto bad;
+ }
}
if (mask & FA_MODE) {
newmode = fa->mode & modemask;
@@ -901,6 +932,9 @@ fattr_equal(const struct fattr *fa1, const struct fattr *fa2)
mask = fa1->mask & fa2->mask;
if (fa1->type == FT_UNKNOWN || fa2->type == FT_UNKNOWN)
return (0);
+ if (mask & FA_FILETYPE)
+ if (fa1->type != fa2->type)
+ return (0);
if (mask & FA_MODTIME)
if (fa1->modtime != fa2->modtime)
return (0);
@@ -936,3 +970,12 @@ fattr_equal(const struct fattr *fa1, const struct fattr *fa2)
return (0);
return (1);
}
+
+/*
+ * Must have to get the correct filesize sendt by the server.
+ */
+off_t
+fattr_filesize(const struct fattr *fa)
+{
+ return (fa->size);
+}
diff --git a/contrib/csup/fattr.h b/contrib/csup/fattr.h
index 6015fbb..bd4e649 100644
--- a/contrib/csup/fattr.h
+++ b/contrib/csup/fattr.h
@@ -101,6 +101,7 @@ int fattr_type(const struct fattr *);
void fattr_maskout(struct fattr *, int);
int fattr_getmask(const struct fattr *);
nlink_t fattr_getlinkcount(const struct fattr *);
+char *fattr_getlinktarget(const struct fattr *);
void fattr_umask(struct fattr *, mode_t);
void fattr_merge(struct fattr *, const struct fattr *);
void fattr_mergedefault(struct fattr *);
@@ -111,5 +112,7 @@ int fattr_install(struct fattr *, const char *, const char *);
int fattr_equal(const struct fattr *, const struct fattr *);
void fattr_free(struct fattr *);
int fattr_supported(int);
+off_t fattr_filesize(const struct fattr *);
+
#endif /* !_FATTR_H_ */
diff --git a/contrib/csup/keyword.c b/contrib/csup/keyword.c
index dab44f0..049a011 100644
--- a/contrib/csup/keyword.c
+++ b/contrib/csup/keyword.c
@@ -152,6 +152,29 @@ keyword_decode_expand(const char *expand)
return (-1);
}
+const char *
+keyword_encode_expand(int expand)
+{
+
+ switch (expand) {
+ case EXPAND_DEFAULT:
+ return (".");
+ case EXPAND_KEYVALUE:
+ return ("kv");
+ case EXPAND_KEYVALUELOCKER:
+ return ("kvl");
+ case EXPAND_KEY:
+ return ("k");
+ case EXPAND_OLD:
+ return ("o");
+ case EXPAND_BINARY:
+ return ("b");
+ case EXPAND_VALUE:
+ return ("v");
+ }
+ return (NULL);
+}
+
void
keyword_free(struct keyword *keyword)
{
diff --git a/contrib/csup/keyword.h b/contrib/csup/keyword.h
index 3f152c1..033cb0a 100644
--- a/contrib/csup/keyword.h
+++ b/contrib/csup/keyword.h
@@ -42,6 +42,7 @@ struct keyword;
struct keyword *keyword_new(void);
int keyword_decode_expand(const char *);
+const char *keyword_encode_expand(int);
int keyword_alias(struct keyword *, const char *, const char *);
int keyword_enable(struct keyword *, const char *);
int keyword_disable(struct keyword *, const char *);
diff --git a/contrib/csup/lex.rcs.c b/contrib/csup/lex.rcs.c
new file mode 100644
index 0000000..5db7a7b
--- /dev/null
+++ b/contrib/csup/lex.rcs.c
@@ -0,0 +1,2094 @@
+
+#line 3 "lex.rcs.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE rcsrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via rcsrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void rcsrestart (FILE *input_file ,yyscan_t yyscanner );
+void rcs_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE rcs_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void rcs_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void rcs_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void rcspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void rcspop_buffer_state (yyscan_t yyscanner );
+
+static void rcsensure_buffer_stack (yyscan_t yyscanner );
+static void rcs_load_buffer_state (yyscan_t yyscanner );
+static void rcs_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER rcs_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE rcs_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE rcs_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE rcs_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *rcsalloc (yy_size_t ,yyscan_t yyscanner );
+void *rcsrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void rcsfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer rcs_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ rcsensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ rcsensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define rcswrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 10
+#define YY_END_OF_BUFFER 11
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[89] =
+ { 0,
+ 0, 0, 11, 5, 9, 8, 10, 4, 4, 7,
+ 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 9, 5, 4, 4, 5,
+ 4, 4, 5, 0, 0, 5, 5, 3, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 3, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 2, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 1, 5, 5, 5, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 1, 4, 1, 1, 1, 1,
+ 1, 1, 1, 4, 1, 5, 1, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 7, 8, 1,
+ 1, 1, 1, 9, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 10, 11, 12, 13,
+
+ 14, 1, 15, 16, 17, 1, 18, 19, 20, 21,
+ 22, 23, 1, 24, 25, 26, 27, 1, 1, 28,
+ 29, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[30] =
+ { 0,
+ 1, 2, 2, 2, 1, 1, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[94] =
+ { 0,
+ 0, 0, 136, 25, 127, 297, 297, 27, 29, 297,
+ 297, 34, 39, 41, 47, 44, 50, 54, 57, 66,
+ 68, 70, 76, 80, 82, 91, 84, 86, 90, 93,
+ 95, 97, 102, 58, 61, 0, 0, 107, 109, 112,
+ 114, 117, 120, 122, 125, 129, 137, 127, 135, 145,
+ 148, 74, 152, 155, 157, 162, 167, 174, 164, 178,
+ 182, 184, 187, 189, 191, 193, 196, 200, 204, 206,
+ 214, 211, 218, 224, 228, 230, 236, 239, 241, 243,
+ 245, 248, 250, 254, 260, 265, 267, 297, 76, 56,
+ 47, 292, 294
+
+ } ;
+
+static yyconst flex_int16_t yy_def[94] =
+ { 0,
+ 88, 1, 88, 89, 88, 88, 88, 90, 91, 88,
+ 88, 92, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 88, 89, 90, 91, 89,
+ 91, 91, 92, 93, 93, 33, 33, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 88, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 0, 88, 88,
+ 88, 88, 88
+
+ } ;
+
+static yyconst flex_int16_t yy_nxt[327] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 4, 18, 4, 4, 19, 4,
+ 20, 4, 4, 4, 21, 22, 4, 4, 4, 24,
+ 25, 28, 29, 31, 32, 34, 35, 34, 36, 37,
+ 34, 34, 38, 24, 25, 24, 25, 30, 24, 25,
+ 39, 24, 25, 43, 24, 25, 27, 44, 24, 25,
+ 35, 24, 25, 35, 41, 40, 52, 46, 42, 52,
+ 24, 25, 24, 25, 24, 25, 23, 45, 47, 48,
+ 24, 25, 34, 51, 24, 25, 24, 25, 24, 25,
+ 28, 29, 26, 49, 31, 32, 50, 24, 25, 31,
+
+ 32, 31, 32, 34, 35, 34, 36, 37, 34, 34,
+ 38, 24, 25, 24, 25, 33, 24, 25, 24, 25,
+ 53, 24, 25, 55, 24, 25, 24, 25, 26, 24,
+ 25, 24, 25, 24, 25, 88, 56, 54, 60, 24,
+ 25, 24, 25, 88, 64, 57, 58, 59, 61, 24,
+ 25, 62, 24, 25, 63, 88, 24, 25, 65, 24,
+ 25, 24, 25, 88, 66, 68, 24, 25, 24, 25,
+ 69, 24, 25, 72, 88, 67, 88, 70, 24, 25,
+ 62, 71, 24, 25, 88, 62, 24, 25, 24, 25,
+ 62, 24, 25, 24, 25, 24, 25, 24, 25, 73,
+
+ 24, 25, 88, 76, 24, 25, 88, 75, 24, 25,
+ 24, 25, 62, 88, 74, 24, 25, 79, 24, 25,
+ 88, 62, 24, 25, 77, 78, 88, 80, 24, 25,
+ 88, 81, 24, 25, 24, 25, 88, 62, 88, 82,
+ 24, 25, 62, 24, 25, 24, 25, 24, 25, 24,
+ 25, 83, 24, 25, 24, 25, 84, 62, 24, 25,
+ 62, 88, 62, 85, 24, 25, 88, 87, 86, 24,
+ 25, 24, 25, 62, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 62, 88, 88, 88, 62,
+ 88, 62, 33, 33, 34, 34, 3, 88, 88, 88,
+
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88
+ } ;
+
+static yyconst flex_int16_t yy_chk[327] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 8, 8, 9, 9, 12, 12, 12, 12, 12,
+ 12, 12, 12, 13, 13, 14, 14, 91, 16, 16,
+ 13, 15, 15, 16, 17, 17, 90, 16, 18, 18,
+ 34, 19, 19, 35, 14, 13, 34, 18, 15, 35,
+ 20, 20, 21, 21, 22, 22, 89, 17, 19, 20,
+ 23, 23, 52, 22, 24, 24, 25, 25, 27, 27,
+ 28, 28, 26, 21, 29, 29, 21, 30, 30, 31,
+
+ 31, 32, 32, 33, 33, 33, 33, 33, 33, 33,
+ 33, 38, 38, 39, 39, 38, 40, 40, 41, 41,
+ 39, 42, 42, 41, 43, 43, 44, 44, 5, 45,
+ 45, 48, 48, 46, 46, 3, 42, 40, 46, 49,
+ 49, 47, 47, 0, 49, 43, 44, 45, 47, 50,
+ 50, 47, 51, 51, 48, 0, 53, 53, 49, 54,
+ 54, 55, 55, 0, 50, 53, 56, 56, 59, 59,
+ 54, 57, 57, 59, 0, 51, 0, 55, 58, 58,
+ 57, 56, 60, 60, 0, 58, 61, 61, 62, 62,
+ 60, 63, 63, 64, 64, 65, 65, 66, 66, 61,
+
+ 67, 67, 0, 66, 68, 68, 0, 65, 69, 69,
+ 70, 70, 63, 0, 64, 72, 72, 70, 71, 71,
+ 0, 67, 73, 73, 68, 69, 0, 71, 74, 74,
+ 0, 72, 75, 75, 76, 76, 0, 74, 0, 75,
+ 77, 77, 73, 78, 78, 79, 79, 80, 80, 81,
+ 81, 76, 82, 82, 83, 83, 79, 81, 84, 84,
+ 77, 0, 78, 80, 85, 85, 0, 84, 83, 86,
+ 86, 87, 87, 82, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 85, 0, 0, 0, 86,
+ 0, 87, 92, 92, 93, 93, 88, 88, 88, 88,
+
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "rcstokenizer.l"
+/*-
+ * Copyright (c) 2007-2008, Ulf Lilleengen <lulf@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$
+ *
+ */
+/*
+ * This tokenizer must be generated by a lexxer with support for reentrancy.
+ */
+#line 34 "rcstokenizer.l"
+#include <string.h>
+#include "misc.h"
+#include "rcsparse.h"
+
+#line 567 "lex.rcs.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+int rcslex_init (yyscan_t* scanner);
+
+int rcslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int rcslex_destroy (yyscan_t yyscanner );
+
+int rcsget_debug (yyscan_t yyscanner );
+
+void rcsset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE rcsget_extra (yyscan_t yyscanner );
+
+void rcsset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *rcsget_in (yyscan_t yyscanner );
+
+void rcsset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *rcsget_out (yyscan_t yyscanner );
+
+void rcsset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int rcsget_leng (yyscan_t yyscanner );
+
+char *rcsget_text (yyscan_t yyscanner );
+
+int rcsget_lineno (yyscan_t yyscanner );
+
+void rcsset_lineno (int line_number ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int rcswrap (yyscan_t yyscanner );
+#else
+extern int rcswrap (yyscan_t yyscanner );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int rcslex (yyscan_t yyscanner);
+
+#define YY_DECL int rcslex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 51 "rcstokenizer.l"
+
+
+#line 791 "lex.rcs.c"
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ rcsensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ rcs_load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 89 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 297 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 53 "rcstokenizer.l"
+{
+ return (KEYWORD_TWO);
+}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 56 "rcstokenizer.l"
+{
+ return (KEYWORD);
+}
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 59 "rcstokenizer.l"
+{
+ return (STRING);
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 62 "rcstokenizer.l"
+{
+ return (NUM);
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 65 "rcstokenizer.l"
+{
+/* This will use ID as both ID and SYM. Do extra checking elsewhere.*/
+ return (ID);
+}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 69 "rcstokenizer.l"
+{ return (SEMIC); }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 70 "rcstokenizer.l"
+{ return (COLON); }
+ YY_BREAK
+case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+#line 71 "rcstokenizer.l"
+;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 72 "rcstokenizer.l"
+;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 73 "rcstokenizer.l"
+ECHO;
+ YY_BREAK
+#line 937 "lex.rcs.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * rcslex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( rcswrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of rcslex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ rcsrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ rcsrestart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) rcsrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 89 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 89 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 88);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+{
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yyg->yy_n_chars + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ rcsrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( rcswrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void rcsrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ rcsensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ rcs_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ rcs_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void rcs_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * rcspop_buffer_state();
+ * rcspush_buffer_state(new_buffer);
+ */
+ rcsensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ rcs_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (rcswrap()) processing, but the only time this flag
+ * is looked at is after rcswrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void rcs_load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE rcs_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) rcsalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in rcs_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) rcsalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in rcs_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ rcs_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with rcs_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void rcs_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ rcsfree((void *) b->yy_ch_buf ,yyscanner );
+
+ rcsfree((void *) b ,yyscanner );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a rcsrestart() or at EOF.
+ */
+ static void rcs_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ rcs_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then rcs_init_buffer was _probably_
+ * called from rcsrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void rcs_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ rcs_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void rcspush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ rcsensure_buffer_stack(yyscanner);
+
+ /* This block is copied from rcs_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from rcs_switch_to_buffer. */
+ rcs_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void rcspop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ rcs_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ rcs_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void rcsensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)rcsalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in rcsensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)rcsrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in rcsensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE rcs_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) rcsalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in rcs_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ rcs_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to rcslex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * rcs_scan_bytes() instead.
+ */
+YY_BUFFER_STATE rcs_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return rcs_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to rcslex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE rcs_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) rcsalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in rcs_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = rcs_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in rcs_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE rcsget_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int rcsget_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int rcsget_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *rcsget_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *rcsget_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int rcsget_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *rcsget_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void rcsset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void rcsset_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "rcsset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void rcsset_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "rcsset_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see rcs_switch_to_buffer
+ */
+void rcsset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void rcsset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int rcsget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void rcsset_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+/* User-visible API */
+
+/* rcslex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int rcslex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) rcsalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* rcslex_init_extra has the same functionality as rcslex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to rcsalloc in
+ * the yyextra field.
+ */
+
+int rcslex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ rcsset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) rcsalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ rcsset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from rcslex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * rcslex_init()
+ */
+ return 0;
+}
+
+/* rcslex_destroy is for both reentrant and non-reentrant scanners. */
+int rcslex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ rcs_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ rcspop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ rcsfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ rcsfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * rcslex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ rcsfree ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *rcsalloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *rcsrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void rcsfree (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see rcsrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 73 "rcstokenizer.l"
+
+
+
diff --git a/contrib/csup/lister.c b/contrib/csup/lister.c
index 98a9c83..b10dbd3 100644
--- a/contrib/csup/lister.c
+++ b/contrib/csup/lister.c
@@ -64,6 +64,10 @@ static int lister_dofile(struct lister *, struct coll *,
struct statusrec *);
static int lister_dodead(struct lister *, struct coll *,
struct statusrec *);
+static int lister_dorcsfile(struct lister *, struct coll *,
+ struct statusrec *);
+static int lister_dorcsdead(struct lister *, struct coll *,
+ struct statusrec *);
void *
lister(void *arg)
@@ -189,6 +193,24 @@ lister_coll(struct lister *l, struct coll *coll, struct status *st)
goto bad;
}
break;
+ case SR_FILEDEAD:
+ if (depth < prunedepth) {
+ if (!(coll->co_options & CO_CHECKOUTMODE)) {
+ error = lister_dorcsdead(l, coll, sr);
+ if (error)
+ goto bad;
+ }
+ }
+ break;
+ case SR_FILELIVE:
+ if (depth < prunedepth) {
+ if (!(coll->co_options & CO_CHECKOUTMODE)) {
+ error = lister_dorcsfile(l, coll, sr);
+ if (error)
+ goto bad;
+ }
+ }
+ break;
}
}
if (ret == -1) {
@@ -383,6 +405,60 @@ send:
return (0);
}
+/* Handle a rcs file live entry found in the status file. */
+static int
+lister_dorcsfile(struct lister *l, struct coll *coll, struct statusrec *sr)
+{
+ struct config *config;
+ struct stream *wr;
+ const struct fattr *sendattr;
+ struct fattr *fa;
+ char *path, *spath;
+ size_t len;
+ int error;
+
+ if (!globtree_test(coll->co_filefilter, sr->sr_file))
+ return (0);
+ config = l->config;
+ wr = l->wr;
+ if (!(coll->co_options & CO_TRUSTSTATUSFILE)) {
+ path = cvspath(coll->co_prefix, sr->sr_file, 0);
+ if (path == NULL) {
+ spath = coll_statuspath(coll);
+ xasprintf(&l->errmsg, "Error in \"%s\": "
+ "Invalid filename \"%s\"", spath, sr->sr_file);
+ free(spath);
+ return (LISTER_ERR_STATUS);
+ }
+ fa = fattr_frompath(path, FATTR_NOFOLLOW);
+ free(path);
+ } else
+ fa = sr->sr_clientattr;
+ if (fa != NULL && fattr_equal(fa, sr->sr_clientattr)) {
+ /*
+ * If the file is an RCS file, we use "loose" equality, so sizes
+ * may disagress because of differences in whitespace.
+ */
+ if (isrcs(sr->sr_file, &len) &&
+ !(coll->co_options & CO_NORCS) &&
+ !(coll->co_options & CO_STRICTCHECKRCS)) {
+ fattr_maskout(fa, FA_SIZE);
+ }
+ sendattr = fa;
+ } else {
+ /*
+ * If different, the user may have changed it, so we report
+ * bogus attributes to force a full comparison.
+ */
+ sendattr = fattr_bogus;
+ }
+ error = proto_printf(wr, "F %s %F\n", pathlast(sr->sr_file), sendattr,
+ config->fasupport, coll->co_attrignore);
+ if (error)
+ return (LISTER_ERR_WRITE);
+ return (0);
+}
+
/* Handle a checkout dead entry found in the status file. */
static int
lister_dodead(struct lister *l, struct coll *coll, struct statusrec *sr)
@@ -437,3 +513,57 @@ lister_dodead(struct lister *l, struct coll *coll, struct statusrec *sr)
return (LISTER_ERR_WRITE);
return (0);
}
+
+/* Handle a rcs file dead entry found in the status file. */
+static int
+lister_dorcsdead(struct lister *l, struct coll *coll, struct statusrec *sr)
+{
+ struct config *config;
+ struct stream *wr;
+ const struct fattr *sendattr;
+ struct fattr *fa;
+ char *path, *spath;
+ size_t len;
+ int error;
+
+ if (!globtree_test(coll->co_filefilter, sr->sr_file))
+ return (0);
+ config = l->config;
+ wr = l->wr;
+ if (!coll->co_options & CO_TRUSTSTATUSFILE) {
+ path = cvspath(coll->co_prefix, sr->sr_file, 1);
+ if (path == NULL) {
+ spath = coll_statuspath(coll);
+ xasprintf(&l->errmsg, "Error in \"%s\": "
+ "Invalid filename \"%s\"", spath, sr->sr_file);
+ free(spath);
+ return (LISTER_ERR_STATUS);
+ }
+ fa = fattr_frompath(path, FATTR_NOFOLLOW);
+ free(path);
+ } else
+ fa = sr->sr_clientattr;
+ if (fattr_equal(fa, sr->sr_clientattr)) {
+ /*
+ * If the file is an RCS file, we use "loose" equality, so sizes
+ * may disagress because of differences in whitespace.
+ */
+ if (isrcs(sr->sr_file, &len) &&
+ !(coll->co_options & CO_NORCS) &&
+ !(coll->co_options & CO_STRICTCHECKRCS)) {
+ fattr_maskout(fa, FA_SIZE);
+ }
+ sendattr = fa;
+ } else {
+ /*
+ * If different, the user may have changed it, so we report
+ * bogus attributes to force a full comparison.
+ */
+ sendattr = fattr_bogus;
+ }
+ error = proto_printf(wr, "f %s %F\n", pathlast(sr->sr_file), sendattr,
+ config->fasupport, coll->co_attrignore);
+ if (error)
+ return (LISTER_ERR_WRITE);
+ return (0);
+}
diff --git a/contrib/csup/misc.c b/contrib/csup/misc.c
index 97a02ab..ae16b59 100644
--- a/contrib/csup/misc.c
+++ b/contrib/csup/misc.c
@@ -202,10 +202,10 @@ commonpathlength(const char *a, size_t alen, const char *b, size_t blen)
return (minlen);
}
-char *
-pathlast(char *path)
+const char *
+pathlast(const char *path)
{
- char *s;
+ const char *s;
s = strrchr(path, '/');
if (s == NULL)
@@ -249,34 +249,87 @@ rcsdatetotime(const char *revdate)
}
/*
- * Returns a buffer allocated with malloc() containing the absolute
- * pathname to the checkout file made from the prefix and the path
- * of the corresponding RCS file relatively to the prefix. If the
- * filename is not an RCS filename, NULL will be returned.
+ * Checks if a file is an RCS file.
*/
-char *
-checkoutpath(const char *prefix, const char *file)
+int
+isrcs(const char *file, size_t *len)
{
const char *cp;
- char *path;
- size_t len;
if (file[0] == '/')
- return (NULL);
+ return (0);
cp = file;
while ((cp = strstr(cp, "..")) != NULL) {
if (cp == file || cp[2] == '\0' ||
(cp[-1] == '/' && cp[2] == '/'))
- return (NULL);
+ return (0);
cp += 2;
}
- len = strlen(file);
- if (len < 2 || file[len - 1] != 'v' || file[len - 2] != ',')
+ *len = strlen(file);
+ if (*len < 2 || file[*len - 1] != 'v' || file[*len - 2] != ',') {
+ return (0);
+ }
+
+ return (1);
+}
+
+/*
+ * Returns a buffer allocated with malloc() containing the absolute
+ * pathname to the checkout file made from the prefix and the path
+ * of the corresponding RCS file relatively to the prefix. If the
+ * filename is not an RCS filename, NULL will be returned.
+ */
+char *
+checkoutpath(const char *prefix, const char *file)
+{
+ char *path;
+ size_t len;
+
+ if (!isrcs(file, &len))
return (NULL);
xasprintf(&path, "%s/%.*s", prefix, (int)len - 2, file);
return (path);
}
+/*
+ * Returns a cvs path allocated with malloc() containing absolute pathname to a
+ * file in cvs mode which can reside in the attic. XXX: filename has really no
+ * restrictions.
+ */
+char *
+cvspath(const char *prefix, const char *file, int attic)
+{
+ const char *last;
+ char *path;
+
+ last = pathlast(file);
+ if (attic)
+ xasprintf(&path, "%s/%.*sAttic/%s", prefix, (int)(last - file),
+ file, last);
+ else
+ xasprintf(&path, "%s/%s", prefix, file);
+
+ return (path);
+}
+
+/*
+ * Regular or attic path if regular fails.
+ * XXX: This should perhaps also check if the Attic file exists too, and return
+ * NULL if not.
+ */
+char *
+atticpath(const char *prefix, const char *file)
+{
+ char *path;
+
+ path = cvspath(prefix, file, 0);
+ if (access(path, F_OK) != 0) {
+ free(path);
+ path = cvspath(prefix, file, 1);
+ }
+ return (path);
+}
+
int
mkdirhier(char *path, mode_t mask)
{
@@ -520,3 +573,73 @@ bt_free(struct backoff_timer *bt)
free(bt);
}
+
+/* Compare two revisions. */
+int
+rcsnum_cmp(char *revision1, char *revision2)
+{
+ char *ptr1, *ptr2, *dot1, *dot2;
+ int num1len, num2len, ret;
+
+ ptr1 = revision1;
+ ptr2 = revision2;
+ while (*ptr1 != '\0' && *ptr2 != '\0') {
+ dot1 = strchr(ptr1, '.');
+ dot2 = strchr(ptr2, '.');
+ if (dot1 == NULL)
+ dot1 = strchr(ptr1, '\0');
+ if (dot2 == NULL)
+ dot2 = strchr(ptr2, '\0');
+
+ num1len = dot1 - ptr1;
+ num2len = dot2 - ptr2;
+ /* Check the distance between each, showing how many digits */
+ if (num1len > num2len)
+ return (1);
+ else if (num1len < num2len)
+ return (-1);
+
+ /* Equal distance means we must check each character. */
+ ret = strncmp(ptr1, ptr2, num1len);
+ if (ret != 0)
+ return (ret);
+ ptr1 = (*dot1 == '.') ? (dot1 + 1) : dot1;
+ ptr2 = (*dot2 == '.') ? (dot2 + 1) : dot2;
+ }
+
+ if (*ptr1 != '\0' && *ptr2 == '\0')
+ return (1);
+ if (*ptr1 == '\0' && *ptr2 != '\0')
+ return (-1);
+ return (0);
+
+}
+
+/* Returns 0 if a rcsrev is not a trunk revision number. */
+int
+rcsrev_istrunk(char *revnum)
+{
+ char *tmp;
+
+ tmp = strchr(revnum, '.');
+ tmp++;
+ if (strchr(tmp, '.') != NULL)
+ return (0);
+ return (1);
+}
+
+/* Return prefix of rcsfile. */
+char *
+rcsrev_prefix(char *revnum)
+{
+ char *modrev, *pos;
+
+ modrev = xstrdup(revnum);
+ pos = strrchr(modrev, '.');
+ if (pos == NULL) {
+ free(modrev);
+ return (NULL);
+ }
+ *pos = '\0';
+ return (modrev);
+}
diff --git a/contrib/csup/misc.h b/contrib/csup/misc.h
index f0d0352..a7ca3a6 100644
--- a/contrib/csup/misc.h
+++ b/contrib/csup/misc.h
@@ -99,22 +99,30 @@ struct backoff_timer;
struct pattlist;
struct tm;
-int asciitoint(const char *, int *, int);
-int lprintf(int, const char *, ...) __printflike(2, 3);
-int MD5_File(char *, char *);
-void MD5_End(char *, MD5_CTX *);
-int rcsdatetotm(const char *, struct tm *);
-time_t rcsdatetotime(const char *);
-int pathcmp(const char *, const char *);
-size_t commonpathlength(const char *, size_t, const char *, size_t);
-char *pathlast(char *);
-char *checkoutpath(const char *, const char *);
-int mkdirhier(char *, mode_t);
-char *tempname(const char *);
-void *xmalloc(size_t);
-void *xrealloc(void *, size_t);
-char *xstrdup(const char *);
-int xasprintf(char **, const char *, ...) __printflike(2, 3);
+int asciitoint(const char *, int *, int);
+int lprintf(int, const char *, ...) __printflike(2, 3);
+int MD5_File(char *, char *);
+void MD5_End(char *, MD5_CTX *);
+int rcsdatetotm(const char *, struct tm *);
+time_t rcsdatetotime(const char *);
+int pathcmp(const char *, const char *);
+size_t commonpathlength(const char *, size_t, const char *, size_t);
+const char *pathlast(const char *);
+int isrcs(const char *, size_t *);
+char *checkoutpath(const char *, const char *);
+char *cvspath(const char *, const char *, int);
+char *atticpath(const char *, const char *);
+char *path_prefix(char *);
+char *path_first(char *);
+int mkdirhier(char *, mode_t);
+char *tempname(const char *);
+void *xmalloc(size_t);
+void *xrealloc(void *, size_t);
+char *xstrdup(const char *);
+int xasprintf(char **, const char *, ...) __printflike(2, 3);
+int rcsnum_cmp(char *, char *);
+int rcsrev_istrunk(char *);
+char *rcsrev_prefix(char *);
struct pattlist *pattlist_new(void);
void pattlist_add(struct pattlist *, const char *);
diff --git a/contrib/csup/mux.c b/contrib/csup/mux.c
index 2be1245..b344be1 100644
--- a/contrib/csup/mux.c
+++ b/contrib/csup/mux.c
@@ -785,6 +785,7 @@ sender_loop(void *arg)
int error, id, iovcnt, what = 0;
m = (struct mux *)arg;
+ what = 0;
again:
id = sender_waitforwork(m, &what);
chan = chan_get(m, id);
diff --git a/contrib/csup/proto.c b/contrib/csup/proto.c
index 0a89858..421ccff 100644
--- a/contrib/csup/proto.c
+++ b/contrib/csup/proto.c
@@ -365,6 +365,8 @@ proto_xchgcoll(struct config *config)
s = config->server;
lprintf(2, "Exchanging collection information\n");
STAILQ_FOREACH(coll, &config->colls, co_next) {
+ if (coll->co_options & CO_SKIP)
+ continue;
proto_printf(s, "COLL %s %s %o %d\n", coll->co_name,
coll->co_release, coll->co_umask, coll->co_options);
for (i = 0; i < pattlist_size(coll->co_accepts); i++) {
@@ -768,6 +770,8 @@ proto_printf(struct stream *wr, const char *format, ...)
va_list ap;
char *cp, *s, *attr;
ssize_t n;
+ size_t size;
+ off_t off;
int rv, val, ignore;
char c;
@@ -801,6 +805,10 @@ proto_printf(struct stream *wr, const char *format, ...)
val = va_arg(ap, int);
rv = stream_printf(wr, "%o", val);
break;
+ case 'O':
+ off = va_arg(ap, off_t);
+ rv = stream_printf(wr, "%llu", off);
+ break;
case 'S':
s = va_arg(ap, char *);
assert(s != NULL);
@@ -829,6 +837,11 @@ proto_printf(struct stream *wr, const char *format, ...)
rv = proto_escape(wr, attr);
free(attr);
break;
+ case 'z':
+ size = va_arg(ap, size_t);
+ rv = stream_printf(wr, "%zu", size);
+ break;
+
case '%':
n = stream_write(wr, "%", 1);
if (n == -1)
@@ -939,6 +952,26 @@ proto_get_int(char **s, int *val, int base)
}
/*
+ * Get a size_t token.
+ */
+int
+proto_get_sizet(char **s, size_t *val, int base)
+{
+ unsigned long long tmp;
+ char *cp, *end;
+
+ cp = proto_get_ascii(s);
+ if (cp == NULL)
+ return (-1);
+ errno = 0;
+ tmp = strtoll(cp, &end, base);
+ if (errno || *end != '\0')
+ return (-1);
+ *val = (size_t)tmp;
+ return (0);
+}
+
+/*
* Get a time_t token.
*
* Ideally, we would use an intmax_t and strtoimax() here, but strtoll()
diff --git a/contrib/csup/proto.h b/contrib/csup/proto.h
index ea9c012..0c4a782 100644
--- a/contrib/csup/proto.h
+++ b/contrib/csup/proto.h
@@ -44,6 +44,7 @@ int proto_printf(struct stream *, const char *, ...);
char *proto_get_ascii(char **);
char *proto_get_rest(char **);
int proto_get_int(char **, int *, int);
+int proto_get_sizet(char **, size_t *, int);
int proto_get_time(char **, time_t *);
#endif /* !_PROTO_H_ */
diff --git a/contrib/csup/rcsfile.c b/contrib/csup/rcsfile.c
new file mode 100644
index 0000000..0d823e8
--- /dev/null
+++ b/contrib/csup/rcsfile.c
@@ -0,0 +1,1367 @@
+/*-
+ * Copyright (c) 2007-2009, Ulf Lilleengen <lulf@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 <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "diff.h"
+#include "keyword.h"
+#include "misc.h"
+#include "proto.h"
+#include "queue.h"
+#include "rcsfile.h"
+#include "rcsparse.h"
+#include "stream.h"
+
+#define BUF_SIZE_DEFAULT 128
+
+/*
+ * RCS parser library. This is the part of the library that handles the
+ * importing, editing and exporting of RCS files. It currently supports only the
+ * part of the RCS file specification that is needed for csup (for instance,
+ * newphrases are not supported), and assumes that you can store the whole RCS
+ * file in memory.
+ */
+
+/*
+ * Linked list for string tokens.
+ */
+struct string {
+ char *str;
+ STAILQ_ENTRY(string) string_next;
+};
+
+/*
+ * Linked list of tags and revision numbers, in the RCS file header.
+ */
+struct tag {
+ char *tag;
+ char *revnum;
+ STAILQ_ENTRY(tag) tag_next;
+};
+
+/*
+ * A RCS delta. The delta is identified by a revision number, and contains the
+ * most important RCS attributes that is needed by csup. It also contains
+ * pointers to other nodes in the RCS file delta structure.
+ */
+struct delta {
+ char *revdate;
+ char *revnum;
+ char *author;
+ char *state;
+ struct buf *log;
+ struct buf *text;
+ int placeholder;
+ struct delta *diffbase;
+ struct delta *prev;
+
+ LIST_ENTRY(delta) delta_next;
+ STAILQ_ENTRY(delta) delta_prev;
+ LIST_ENTRY(delta) table_next;
+ STAILQ_ENTRY(delta) stack_next;
+ LIST_HEAD(, branch) branchlist;
+ LIST_ENTRY(delta) branch_next_date;
+};
+
+/*
+ * A branch data structure containing information about deltas in the branch as
+ * well as a base revision number.
+ */
+struct branch {
+ char *revnum;
+ LIST_HEAD(, delta) deltalist; /* Next delta in our branch. */
+ LIST_ENTRY(branch) branch_next;
+};
+
+/*
+ * The rcsfile structure is the "main" structure of the RCS parser library. It
+ * contains administrative data as well as pointers to the deltas within the
+ * file.
+ */
+struct rcsfile {
+ char *name;
+ char *head;
+ char *branch; /* Default branch. */
+ char *cvsroot;
+ char *colltag;
+ STAILQ_HEAD(, string) accesslist;
+ STAILQ_HEAD(, tag) taglist;
+ int strictlock;
+ char *comment;
+ int expand;
+ int ro;
+ struct branch *trunk; /* The tip delta. */
+
+ LIST_HEAD(, delta) deltatable;
+
+ char *desc;
+};
+
+static void rcsfile_freedelta(struct delta *);
+static void rcsfile_insertdelta(struct branch *, struct delta *,
+ int);
+static struct delta *rcsfile_createdelta(char *);
+static int rcsfile_write_deltatext(struct rcsfile *,
+ struct stream *);
+static int rcsfile_puttext(struct rcsfile *, struct stream *,
+ struct delta *, struct delta *);
+static struct branch *rcsfile_getbranch(struct rcsfile *, char *);
+static void rcsfile_insertsorteddelta(struct rcsfile *,
+ struct delta *);
+static struct stream *rcsfile_getdeltatext(struct rcsfile *, struct delta *,
+ struct buf **);
+static void rcsdelta_writestring(char *, size_t, struct stream *);
+static void rcsdelta_insertbranch(struct delta *, struct branch *);
+
+/* Space formatting of RCS file. */
+const char *head_space = "\t";
+const char *branch_space = "\t";
+const char *tag_space = "\t";
+const char *date_space = "\t";
+const char *auth_space = "\t";
+const char *state_space = "\t";
+const char *next_space = "\t";
+const char *branches_space = "\t";
+const char *comment_space ="\t";
+const char *expand_space = "\t";
+
+void print_stream(struct stream *);
+
+/* Print the contents of a stream, for debugging. */
+void
+print_stream(struct stream *s)
+{
+ char *line;
+
+ line = stream_getln(s, NULL);
+ while (line != NULL) {
+ lprintf(-1, "%s\n", line);
+ line = stream_getln(s, NULL);
+ }
+ lprintf(-1, "\n");
+}
+
+/*
+ * Parse rcsfile from path and return a pointer to it.
+ */
+struct rcsfile *
+rcsfile_frompath(char *path, char *name, char *cvsroot, char *colltag, int ro)
+{
+ struct rcsfile *rf;
+ FILE *infp;
+ int error;
+
+ if (path == NULL || name == NULL || cvsroot == NULL || colltag == NULL)
+ return (NULL);
+
+ rf = xmalloc(sizeof(struct rcsfile));
+ rf->name = xstrdup(name);
+ rf->cvsroot = xstrdup(cvsroot);
+ rf->colltag = xstrdup(colltag);
+
+ /* Initialize head branch. */
+ rf->trunk = xmalloc(sizeof(struct branch));
+ rf->trunk->revnum = xstrdup("1");
+ LIST_INIT(&rf->trunk->deltalist);
+ /* Initialize delta list. */
+ LIST_INIT(&rf->deltatable);
+ /* Initialize tag list. */
+ STAILQ_INIT(&rf->taglist);
+ /* Initialize accesslist. */
+ STAILQ_INIT(&rf->accesslist);
+
+ /* Initialize all fields. */
+ rf->head = NULL;
+ rf->branch = NULL;
+ rf->strictlock = 0;
+ rf->comment = NULL;
+ rf->expand = EXPAND_DEFAULT;
+ rf->desc = NULL;
+ rf->ro = ro;
+
+ infp = fopen(path, "r");
+ if (infp == NULL) {
+ lprintf(-1, "Cannot open \"%s\": %s\n", path, strerror(errno));
+ rcsfile_free(rf);
+ return (NULL);
+ }
+ error = rcsparse_run(rf, infp, ro);
+ fclose(infp);
+ if (error) {
+ lprintf(-1, "Error parsing \"%s\"\n", name);
+ rcsfile_free(rf);
+ return (NULL);
+ }
+ return (rf);
+}
+
+/*
+ * Write content of rcsfile to server. Assumes we have a complete RCS file
+ * loaded.
+ */
+int
+rcsfile_send_details(struct rcsfile *rf, struct stream *wr)
+{
+ struct delta *d;
+ struct tag *t;
+ const char *keyword;
+ int error;
+
+ assert(rf != NULL);
+
+ error = proto_printf(wr, "V %s\n", rf->name);
+ if (error)
+ return(error);
+
+ /* Write default branch. */
+ if (rf->branch == NULL)
+ error = proto_printf(wr, "b\n");
+ else
+ error = proto_printf(wr, "B %s\n", rf->branch);
+ if (error)
+ return(error);
+
+ /* Write deltas to server. */
+ error = proto_printf(wr, "D\n");
+ if (error)
+ return(error);
+
+ LIST_FOREACH(d, &rf->deltatable, table_next) {
+ error = proto_printf(wr, "%s %s\n", d->revnum, d->revdate);
+ if (error)
+ return(error);
+ }
+ error = proto_printf(wr, ".\n");
+
+ if (error)
+ return(error);
+ /* Write expand. */
+ if (rf->expand != EXPAND_DEFAULT) {
+ keyword = keyword_encode_expand(rf->expand);
+ if (keyword != NULL) {
+ error = proto_printf(wr, "E %s\n",
+ keyword_encode_expand(rf->expand));
+ if (error)
+ return(error);
+ }
+ }
+
+ /* Write tags to server. */
+ error = proto_printf(wr, "T\n");
+ if (error)
+ return(error);
+ STAILQ_FOREACH(t, &rf->taglist, tag_next) {
+ error = proto_printf(wr, "%s %s\n", t->tag, t->revnum);
+ if (error)
+ return(error);
+ }
+ error = proto_printf(wr, ".\n");
+ if (error)
+ return(error);
+ error = proto_printf(wr, ".\n");
+ return (error);
+}
+
+/*
+ * Write a RCS file to disk represented by the destination stream. Keep track of
+ * deltas with a stack and an inverted stack.
+ */
+int
+rcsfile_write(struct rcsfile *rf, struct stream *dest)
+{
+ STAILQ_HEAD(, delta) deltastack;
+ STAILQ_HEAD(, delta) deltalist_inverted;
+ struct tag *t;
+ struct branch *b;
+ struct delta *d, *d_tmp, *d_next;
+ int error;
+
+ /* First write head. */
+ d = LIST_FIRST(&rf->trunk->deltalist);
+ stream_printf(dest, "head%s%s;\n", head_space, d->revnum);
+
+ /* Write branch, if we have. */
+ if (rf->branch != NULL)
+ stream_printf(dest, "branch%s%s;\n", branch_space, rf->branch);
+
+ /* Write access. */
+ stream_printf(dest, "access");
+#if 0
+ if (!STAILQ_EMPTY(&rf->accesslist)) {
+ /*
+ * XXX: Write out access. This doesn't seem to be necessary for
+ * the time being.
+ */
+ }
+#endif
+ stream_printf(dest, ";\n");
+
+ /* Write out taglist. */
+ stream_printf(dest, "symbols");
+ if (!STAILQ_EMPTY(&rf->taglist)) {
+ STAILQ_FOREACH(t, &rf->taglist, tag_next) {
+ stream_printf(dest, "\n%s%s:%s", tag_space, t->tag,
+ t->revnum);
+ }
+ }
+ stream_printf(dest, ";\n");
+
+ /* Write out locks and strict. */
+ stream_printf(dest, "locks;");
+ if (rf->strictlock)
+ stream_printf(dest, " strict;");
+ stream_printf(dest, "\n");
+
+ /* Write out the comment. */
+ if (rf->comment != NULL)
+ stream_printf(dest, "comment%s%s;\n", comment_space, rf->comment);
+ if (rf->expand != EXPAND_DEFAULT)
+ stream_printf(dest, "expand%s@%s@;\n", expand_space,
+ keyword_encode_expand(rf->expand));
+
+ stream_printf(dest, "\n\n");
+
+ /*
+ * Write out deltas. We use a stack where we push the appropriate deltas
+ * that is to be written out during the loop.
+ */
+ STAILQ_INIT(&deltastack);
+ d = LIST_FIRST(&rf->trunk->deltalist);
+ STAILQ_INSERT_HEAD(&deltastack, d, stack_next);
+ while (!STAILQ_EMPTY(&deltastack)) {
+ d = STAILQ_FIRST(&deltastack);
+ STAILQ_REMOVE_HEAD(&deltastack, stack_next);
+ /* Do not write out placeholders just to be safe. */
+ if (d->placeholder)
+ continue;
+ stream_printf(dest, "%s\n", d->revnum);
+ stream_printf(dest, "date%s%s;%sauthor %s;%sstate",
+ date_space, d->revdate, auth_space, d->author,
+ state_space);
+ if (d->state != NULL)
+ stream_printf(dest, " %s", d->state);
+ stream_printf(dest, ";\n");
+ stream_printf(dest, "branches");
+ /*
+ * Write out our branches. Add them to a reversed list for use
+ * later when we write out the text.
+ */
+ STAILQ_INIT(&deltalist_inverted);
+ LIST_FOREACH(b, &d->branchlist, branch_next) {
+ d_tmp = LIST_FIRST(&b->deltalist);
+ STAILQ_INSERT_HEAD(&deltalist_inverted, d_tmp, delta_prev);
+ STAILQ_INSERT_HEAD(&deltastack, d_tmp, stack_next);
+ }
+
+ /* Push branch heads on stack. */
+ STAILQ_FOREACH(d_tmp, &deltalist_inverted, delta_prev) {
+ if (d_tmp == NULL)
+ err(1, "empty branch!");
+ stream_printf(dest, "\n%s%s", branches_space,
+ d_tmp->revnum);
+ }
+ stream_printf(dest, ";\n");
+
+ stream_printf(dest, "next%s", next_space);
+ /* Push next delta on stack. */
+ d_next = LIST_NEXT(d, delta_next);
+ if (d_next != NULL) {
+ stream_printf(dest, "%s", d_next->revnum);
+ STAILQ_INSERT_HEAD(&deltastack, d_next, stack_next);
+ }
+ stream_printf(dest, ";\n\n");
+ }
+ stream_printf(dest, "\n");
+ /* Write out desc. */
+ stream_printf(dest, "desc\n@@");
+ d = LIST_FIRST(&rf->trunk->deltalist);
+
+ /* Write out deltatexts. */
+ error = rcsfile_write_deltatext(rf, dest);
+ stream_printf(dest, "\n");
+ return (error);
+}
+
+/*
+ * Write out deltatexts of a delta and it's subbranches recursively.
+ */
+int
+rcsfile_write_deltatext(struct rcsfile *rf, struct stream *dest)
+{
+ STAILQ_HEAD(, delta) deltastack;
+ LIST_HEAD(, delta) branchlist_datesorted;
+ struct delta *d, *d_tmp, *d_next, *d_tmp2, *d_tmp3;
+ struct stream *in;
+ struct branch *b;
+ size_t size;
+ char *line;
+ int error;
+
+ error = 0;
+ STAILQ_INIT(&deltastack);
+ d = LIST_FIRST(&rf->trunk->deltalist);
+ d->prev = NULL;
+ STAILQ_INSERT_HEAD(&deltastack, d, stack_next);
+ while (!STAILQ_EMPTY(&deltastack)) {
+ d = STAILQ_FIRST(&deltastack);
+ STAILQ_REMOVE_HEAD(&deltastack, stack_next);
+ /* Do not write out placeholders just to be safe. */
+ if (d->placeholder)
+ return (0);
+ stream_printf(dest, "\n\n\n%s\n", d->revnum);
+ stream_printf(dest, "log\n@");
+ in = stream_open_buf(d->log);
+ line = stream_getln(in, &size);
+ while (line != NULL) {
+ stream_write(dest, line, size);
+ line = stream_getln(in, &size);
+ }
+ stream_close(in);
+ stream_printf(dest, "@\n");
+ stream_printf(dest, "text\n@");
+ error = rcsfile_puttext(rf, dest, d, d->prev);
+ if (error)
+ return (error);
+ stream_printf(dest, "@");
+
+ LIST_INIT(&branchlist_datesorted);
+ d_next = LIST_NEXT(d, delta_next);
+ if (d_next != NULL) {
+ d_next->prev = d;
+ /*
+ * If it's trunk, treat it like the oldest, if not treat
+ * it like a child.
+ */
+ if (rcsrev_istrunk(d_next->revnum))
+ STAILQ_INSERT_HEAD(&deltastack, d_next,
+ stack_next);
+ else
+ LIST_INSERT_HEAD(&branchlist_datesorted, d_next,
+ branch_next_date);
+ }
+
+ /*
+ * First, we need to sort our branches based on their date to
+ * take into account some self-hacked RCS files.
+ */
+ LIST_FOREACH(b, &d->branchlist, branch_next) {
+ d_tmp = LIST_FIRST(&b->deltalist);
+ if (LIST_EMPTY(&branchlist_datesorted)) {
+ LIST_INSERT_HEAD(&branchlist_datesorted, d_tmp,
+ branch_next_date);
+ continue;
+ }
+
+ d_tmp2 = LIST_FIRST(&branchlist_datesorted);
+ if (rcsnum_cmp(d_tmp->revdate, d_tmp2->revdate) <= 0) {
+ LIST_INSERT_BEFORE(d_tmp2, d_tmp,
+ branch_next_date);
+ continue;
+ }
+ while ((d_tmp3 = LIST_NEXT(d_tmp2, branch_next_date))
+ != NULL) {
+ if (rcsnum_cmp(d_tmp->revdate, d_tmp3->revdate)
+ <= 0)
+ break;
+ d_tmp2 = d_tmp3;
+ }
+ LIST_INSERT_AFTER(d_tmp2, d_tmp, branch_next_date);
+ }
+ /*
+ * Invert the deltalist of a branch, since we're writing them
+ * the opposite way.
+ */
+ LIST_FOREACH(d_tmp, &branchlist_datesorted, branch_next_date) {
+ d_tmp->prev = d;
+ STAILQ_INSERT_HEAD(&deltastack, d_tmp, stack_next);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Generates text given a delta and a diffbase.
+ */
+static int
+rcsfile_puttext(struct rcsfile *rf, struct stream *dest, struct delta *d,
+ struct delta *diffbase)
+{
+ struct stream *in, *rd, *orig;
+ struct keyword *k;
+ struct diffinfo dibuf, *di;
+ struct buf *b;
+ size_t size;
+ char *line;
+ int error;
+
+ di = &dibuf;
+ b = NULL;
+ error = 0;
+
+ /* Write if the diffbase is the previous */
+ if (d->diffbase == diffbase) {
+
+ /* Write out the text. */
+ in = stream_open_buf(d->text);
+ line = stream_getln(in, &size);
+ while (line != NULL) {
+ stream_write(dest, line, size);
+ line = stream_getln(in, &size);
+ }
+ stream_close(in);
+ /* We need to apply diff to produce text, this is probably HEAD. */
+ } else if (diffbase == NULL) {
+ /* Apply diff. */
+ orig = rcsfile_getdeltatext(rf, d, &b);
+ if (orig == NULL) {
+ error = -1;
+ goto cleanup;
+ }
+ line = stream_getln(orig, &size);
+ while (line != NULL) {
+ stream_write(dest, line, size);
+ line = stream_getln(orig, &size);
+ }
+ stream_close(orig);
+ /*
+ * A new head was probably added, and now the previous HEAD must be
+ * changed to include the diff instead.
+ */
+ } else if (diffbase->diffbase == d) {
+ /* Get reverse diff. */
+ orig = rcsfile_getdeltatext(rf, d, &b);
+ if (orig == NULL) {
+ error = -1;
+ goto cleanup;
+ }
+ di->di_rcsfile = rf->name;
+ di->di_cvsroot = rf->cvsroot;
+ di->di_revnum = d->revnum;
+ di->di_revdate = d->revdate;
+ di->di_author = d->author;
+ di->di_tag = rf->colltag;
+ di->di_state = d->state;
+ di->di_expand = EXPAND_OLD;
+ k = keyword_new();
+
+ rd = stream_open_buf(diffbase->text);
+ error = diff_reverse(rd, orig, dest, k, di);
+ if (error) {
+ lprintf(-1, "Error applying reverse diff: %d\n", error);
+ goto cleanup;
+ }
+ keyword_free(k);
+ stream_close(rd);
+ stream_close(orig);
+ }
+cleanup:
+ if (b != NULL)
+ buf_free(b);
+ return (error);
+}
+
+/*
+ * Return a stream with an applied diff of a delta.
+ * XXX: extra overhead on the last apply. Could write directly to file, but
+ * makes things complicated though.
+ */
+static struct stream *
+rcsfile_getdeltatext(struct rcsfile *rf, struct delta *d, struct buf **buf_dest)
+{
+ struct diffinfo dibuf, *di;
+ struct stream *orig, *dest, *rd;
+ struct buf *buf_orig;
+ struct keyword *k;
+ int error;
+
+ buf_orig = NULL;
+ error = 0;
+
+ /*
+ * If diffbase is NULL or we are head (the old head), we have a normal
+ * complete deltatext.
+ */
+ if (d->diffbase == NULL && !strcmp(rf->head, d->revnum)) {
+ orig = stream_open_buf(d->text);
+ return (orig);
+ }
+
+ di = &dibuf;
+ /* If not, we need to apply our diff to that of our diffbase. */
+ orig = rcsfile_getdeltatext(rf, d->diffbase, &buf_orig);
+ if (orig == NULL)
+ return (NULL);
+
+ /*
+ * Now that we are sure we have a complete deltatext in ret, let's apply
+ * our diff to it.
+ */
+ *buf_dest = buf_new(BUF_SIZE_DEFAULT);
+ dest = stream_open_buf(*buf_dest);
+
+ di->di_rcsfile = rf->name;
+ di->di_cvsroot = rf->cvsroot;
+ di->di_revnum = d->revnum;
+ di->di_revdate = d->revdate;
+ di->di_author = d->author;
+ di->di_tag = rf->colltag;
+ di->di_state = d->state;
+ di->di_expand = EXPAND_OLD;
+ rd = stream_open_buf(d->text);
+ k = keyword_new();
+ error = diff_apply(rd, orig, dest, k, di, 0);
+ stream_flush(dest);
+ stream_close(rd);
+ stream_close(orig);
+ stream_close(dest);
+ keyword_free(k);
+ if (buf_orig != NULL)
+ buf_free(buf_orig);
+ if (error) {
+ lprintf(-1, "Error applying diff: %d\n", error);
+ return (NULL);
+ }
+
+ /* Now reopen the stream for the reading. */
+ dest = stream_open_buf(*buf_dest);
+ return (dest);
+}
+
+/* Print content of rcsfile. Useful for debugging. */
+void
+rcsfile_print(struct rcsfile *rf)
+{
+ struct delta *d;
+ struct tag *t;
+ struct string *s;
+ struct stream *in;
+ char *line;
+
+ lprintf(1, "\n");
+ if (rf->name != NULL)
+ lprintf(1, "name: '%s'\n", rf->name);
+ if (rf->head != NULL)
+ lprintf(1, "head: '%s'\n", rf->head);
+ if (rf->branch != NULL)
+ lprintf(1, "branch: '%s'\n", rf->branch);
+ lprintf(1, "Access: ");
+ STAILQ_FOREACH(s, &rf->accesslist, string_next)
+ lprintf(1, "'%s' ", s->str);
+ lprintf(1, "\n");
+
+ /* Print all tags. */
+ STAILQ_FOREACH(t, &rf->taglist, tag_next) {
+ lprintf(1, "Tag: ");
+ if (t->tag != NULL)
+ lprintf(1, "name: %s ", t->tag);
+ if (t->revnum != NULL)
+ lprintf(1, "rev: %s", t->revnum);
+ lprintf(1, "\n");
+ }
+
+ if (rf->strictlock)
+ lprintf(1, "Strict!\n");
+ if (rf->comment != NULL)
+ lprintf(1, "comment: '%s'\n", rf->comment);
+ if (rf->expand != EXPAND_DEFAULT);
+ lprintf(1, "expand: '%s'\n", keyword_encode_expand(rf->expand));
+
+ /* Print all deltas. */
+ LIST_FOREACH(d, &rf->deltatable, table_next) {
+ lprintf(1, "Delta: ");
+ if (d->revdate != NULL)
+ lprintf(1, "date: %s ", d->revdate);
+ if (d->revnum != NULL)
+ lprintf(1, "rev: %s", d->revnum);
+ if (d->author != NULL)
+ lprintf(1, "author: %s", d->author);
+ if (d->state != NULL)
+ lprintf(1, "state: %s", d->state);
+
+ lprintf(1, "Text:\n");
+ in = stream_open_buf(d->text);
+ line = stream_getln(in, NULL);
+ while (line != NULL) {
+ lprintf(1, "TEXT: %s\n", line);
+ line = stream_getln(in, NULL);
+ }
+ stream_close(in);
+ lprintf(1, "\n");
+ }
+
+ if (rf->desc != NULL)
+ lprintf(1, "desc: '%s'\n", rf->desc);
+}
+
+/* Free all memory associated with a struct rcsfile. */
+void
+rcsfile_free(struct rcsfile *rf)
+{
+ struct delta *d;
+ struct tag *t;
+ struct string *s;
+
+ if (rf->name != NULL)
+ free(rf->name);
+ if (rf->head != NULL)
+ free(rf->head);
+ if (rf->branch != NULL)
+ free(rf->branch);
+ if (rf->cvsroot != NULL)
+ free(rf->cvsroot);
+ if (rf->colltag != NULL)
+ free(rf->colltag);
+
+ /* Free all access ids. */
+ while (!STAILQ_EMPTY(&rf->accesslist)) {
+ s = STAILQ_FIRST(&rf->accesslist);
+ STAILQ_REMOVE_HEAD(&rf->accesslist, string_next);
+ if (s->str != NULL)
+ free(s->str);
+ free(s);
+ }
+
+ /* Free all tags. */
+ while (!STAILQ_EMPTY(&rf->taglist)) {
+ t = STAILQ_FIRST(&rf->taglist);
+ STAILQ_REMOVE_HEAD(&rf->taglist, tag_next);
+ if (t->tag != NULL)
+ free(t->tag);
+ if (t->revnum != NULL)
+ free(t->revnum);
+ free(t);
+ }
+
+ if (rf->comment != NULL)
+ free(rf->comment);
+
+ /* Free all deltas in global list */
+ while (!LIST_EMPTY(&rf->deltatable)) {
+ d = LIST_FIRST(&rf->deltatable);
+ if (!rf->ro)
+ LIST_REMOVE(d, delta_next);
+ LIST_REMOVE(d, table_next);
+ rcsfile_freedelta(d);
+ }
+
+ /* Free global branch. */
+ if (rf->trunk->revnum != NULL)
+ free(rf->trunk->revnum);
+ free(rf->trunk);
+
+ if (rf->desc != NULL)
+ free(rf->desc);
+
+ free(rf);
+}
+
+/*
+ * Free a RCS delta.
+ */
+static void
+rcsfile_freedelta(struct delta *d)
+{
+ struct branch *b;
+
+ if (d->revdate != NULL)
+ free(d->revdate);
+ if (d->revnum != NULL)
+ free(d->revnum);
+ if (d->author != NULL)
+ free(d->author);
+ if (d->state != NULL)
+ free(d->state);
+ if (d->log != NULL)
+ buf_free(d->log);
+ if (d->text != NULL)
+ buf_free(d->text);
+
+ /* Free all subbranches of a delta. */
+ while (!LIST_EMPTY(&d->branchlist)) {
+ b = LIST_FIRST(&d->branchlist);
+ LIST_REMOVE(b, branch_next);
+ free(b->revnum);
+ free(b);
+ }
+ free(d);
+}
+
+/*
+ * Functions for editing RCS deltas.
+ */
+
+/* Add a new entry to the access list. */
+void
+rcsfile_addaccess(struct rcsfile *rf, char *id)
+{
+ struct string *s;
+
+ s = xmalloc(sizeof(struct string));
+ s->str = xstrdup(id);
+ STAILQ_INSERT_TAIL(&rf->accesslist, s, string_next);
+}
+
+/* Add a tag to a RCS file. */
+void
+rcsfile_addtag(struct rcsfile *rf, char *tag, char *revnum)
+{
+ struct tag *t;
+
+ t = xmalloc(sizeof(struct tag));
+ t->tag = xstrdup(tag);
+ t->revnum = xstrdup(revnum);
+
+ STAILQ_INSERT_HEAD(&rf->taglist, t, tag_next);
+}
+
+/* Import a tag to a RCS file. */
+void
+rcsfile_importtag(struct rcsfile *rf, char *tag, char *revnum)
+{
+ struct tag *t;
+
+ t = xmalloc(sizeof(struct tag));
+ t->tag = xstrdup(tag);
+ t->revnum = xstrdup(revnum);
+
+ STAILQ_INSERT_TAIL(&rf->taglist, t, tag_next);
+}
+
+/*
+ * Delete a revision from the global delta list and the branch it is in. Csup
+ * will tell us to delete the tags involved.
+ */
+void
+rcsfile_deleterev(struct rcsfile *rf, char *revname)
+{
+ struct delta *d;
+
+ d = rcsfile_getdelta(rf, revname);
+ if (!rf->ro)
+ LIST_REMOVE(d, delta_next);
+ LIST_REMOVE(d, table_next);
+ rcsfile_freedelta(d);
+}
+
+/* Delete a tag from the tag list. */
+void
+rcsfile_deletetag(struct rcsfile *rf, char *tag, char *revnum)
+{
+ struct tag *t;
+
+ STAILQ_FOREACH(t, &rf->taglist, tag_next) {
+ if ((strcmp(tag, t->tag) == 0) &&
+ (strcmp(revnum, t->revnum) == 0)) {
+ STAILQ_REMOVE(&rf->taglist, t, tag, tag_next);
+ free(t->tag);
+ free(t->revnum);
+ free(t);
+ return;
+ }
+ }
+}
+
+/*
+ * Searches the global deltalist for a delta.
+ */
+struct delta *
+rcsfile_getdelta(struct rcsfile *rf, char *revnum)
+{
+ struct delta *d;
+
+ LIST_FOREACH(d, &rf->deltatable, table_next) {
+ if (strcmp(revnum, d->revnum) == 0)
+ return (d);
+ }
+ return (NULL);
+}
+
+/* Set rcsfile head. */
+void
+rcsfile_setval(struct rcsfile *rf, int field, char *val)
+{
+ size_t len;
+
+ switch (field) {
+ case RCSFILE_HEAD:
+ if (rf->head != NULL)
+ free(rf->head);
+ rf->head = xstrdup(val);
+ break;
+ case RCSFILE_BRANCH:
+ if (rf->branch != NULL)
+ free(rf->branch);
+ rf->branch = (val == NULL) ? NULL : xstrdup(val);
+ break;
+ case RCSFILE_STRICT:
+ if (val != NULL)
+ rf->strictlock = 1;
+ break;
+ case RCSFILE_COMMENT:
+ if (rf->comment != NULL)
+ free(rf->comment);
+ rf->comment = xstrdup(val);
+ break;
+ case RCSFILE_EXPAND:
+ len = strlen(val) - 1;
+ val++;
+ val[len - 1] = '\0';
+ rf->expand = keyword_decode_expand(val);
+ break;
+ case RCSFILE_DESC:
+ if (rf->desc != NULL)
+ free(rf->desc);
+ rf->desc = xstrdup(val);
+ break;
+ default:
+ lprintf(-1, "Setting invalid RCSfile value.\n");
+ break;
+ }
+}
+
+/* Create and initialize a delta. */
+static struct delta *
+rcsfile_createdelta(char *revnum)
+{
+ struct delta *d;
+
+ d = xmalloc(sizeof(struct delta));
+ d->revnum = xstrdup(revnum);
+ d->revdate = NULL;
+ d->state = NULL;
+ d->author = NULL;
+ d->log = buf_new(BUF_SIZE_DEFAULT);
+ d->text = buf_new(BUF_SIZE_DEFAULT);
+ d->diffbase = NULL;
+
+ LIST_INIT(&d->branchlist);
+ return (d);
+}
+
+/* Add a delta to a imported delta tree. Used by the updater. */
+struct delta *
+rcsfile_addelta(struct rcsfile *rf, char *revnum, char *revdate, char *author,
+ char *diffbase)
+{
+ struct branch *b;
+ struct delta *d, *d_bp, *d_next;
+ char *brev, *bprev;
+ int trunk;
+
+ d_next = NULL;
+ d = rcsfile_getdelta(rf, revnum);
+ if (d != NULL) {
+ lprintf(-1, "Delta %s already exists!\n", revnum);
+ return (NULL);
+ }
+ d = rcsfile_createdelta(revnum);
+ d->placeholder = 0;
+ d->revdate = xstrdup(revdate);
+ d->author = xstrdup(author);
+ d->diffbase = rcsfile_getdelta(rf, diffbase);
+
+ /* If it's trunk, insert it in the head branch list. */
+ b = rcsrev_istrunk(d->revnum) ? rf->trunk :
+ rcsfile_getbranch(rf, d->revnum);
+
+ /*
+ * We didn't find a branch, check if we can find a branchpoint and
+ * create a branch there.
+ */
+ if (b == NULL) {
+ brev = rcsrev_prefix(d->revnum);
+ bprev = rcsrev_prefix(brev);
+
+ d_bp = rcsfile_getdelta(rf, bprev);
+ free(bprev);
+ if (d_bp == NULL) {
+ lprintf(-1, "No branch point for adding delta %s\n",
+ d->revnum);
+ return (NULL);
+ }
+
+ /* Create the branch and insert in delta. */
+ b = xmalloc(sizeof(struct branch));
+ b->revnum = brev;
+ LIST_INIT(&b->deltalist);
+ rcsdelta_insertbranch(d_bp, b);
+ }
+
+ /* Insert both into the tree, and into the lookup list. */
+ trunk = rcsrev_istrunk(d->revnum);
+ rcsfile_insertdelta(b, d, trunk);
+ rcsfile_insertsorteddelta(rf, d);
+ return (d);
+}
+
+/* Adds a delta to a rcsfile struct. Used by the parser. */
+void
+rcsfile_importdelta(struct rcsfile *rf, char *revnum, char *revdate, char *author,
+ char *state, char *next)
+{
+ struct branch *b;
+ struct delta *d, *d_bp, *d_next;
+ char *brev, *bprev;
+ int trunk;
+
+ d_next = NULL;
+ d = rcsfile_getdelta(rf, revnum);
+
+ if (d == NULL) {
+ /* If not, we'll just create a new entry. */
+ d = rcsfile_createdelta(revnum);
+ d->placeholder = 0;
+ } else {
+ if (d->placeholder == 0) {
+ lprintf(-1, "Trying to import already existing delta\n");
+ return;
+ }
+ }
+ /*
+ * If already exists, assume that only revnum is filled out, and set the
+ * rest of the fields. This should be an OK assumption given that we can
+ * be sure internally that the structure is sufficiently initialized so
+ * we won't have any unfreed memory.
+ */
+ d->revdate = xstrdup(revdate);
+ d->author = xstrdup(author);
+ if (state != NULL)
+ d->state = xstrdup(state);
+
+ /* If we have a next, create a placeholder for it. */
+ if (next != NULL) {
+ d_next = rcsfile_createdelta(next);
+ d_next->placeholder = 1;
+ /* Diffbase should be the previous. */
+ d_next->diffbase = d;
+ }
+
+ /* If we're opening read-only, do minimal work. */
+ if (rf->ro) {
+ if (!d->placeholder)
+ rcsfile_insertsorteddelta(rf, d);
+ else
+ d->placeholder = 0;
+ if (d_next != NULL)
+ rcsfile_insertsorteddelta(rf, d_next);
+ return;
+ }
+
+ /* If it's trunk, insert it in the head branch list. */
+ b = rcsrev_istrunk(d->revnum) ? rf->trunk : rcsfile_getbranch(rf,
+ d->revnum);
+
+ /*
+ * We didn't find a branch, check if we can find a branchpoint and
+ * create a branch there.
+ */
+ if (b == NULL) {
+ brev = rcsrev_prefix(d->revnum);
+ bprev = rcsrev_prefix(brev);
+
+ d_bp = rcsfile_getdelta(rf, bprev);
+ free(bprev);
+ if (d_bp == NULL) {
+ lprintf(-1, "No branch point for adding delta %s\n",
+ d->revnum);
+ return;
+ }
+
+ /* Create the branch and insert in delta. */
+ b = xmalloc(sizeof(struct branch));
+ b->revnum = brev;
+ LIST_INIT(&b->deltalist);
+ rcsdelta_insertbranch(d_bp, b);
+ }
+
+ /* Insert if not a placeholder. */
+ if (!d->placeholder) {
+ /* Insert both into the tree, and into the lookup list. */
+ if (rcsrev_istrunk(d->revnum))
+ rcsfile_insertdelta(b, d, 1);
+ else {
+ rcsfile_insertdelta(b, d, 0);
+ /*
+ * On import we need to set the diffbase to our
+ * branchpoint for writing out later.
+ */
+ if (LIST_FIRST(&b->deltalist) == d) {
+ brev = rcsrev_prefix(d->revnum);
+ bprev = rcsrev_prefix(brev);
+ d_bp = rcsfile_getdelta(rf, bprev);
+ /* This should really not happen. */
+ assert(d_bp != NULL);
+ d->diffbase = d_bp;
+ free(brev);
+ free(bprev);
+ }
+ }
+ rcsfile_insertsorteddelta(rf, d);
+ } else /* Not a placeholder anymore. */ {
+ d->placeholder = 0;
+ /* Put it into the tree. */
+ trunk = rcsrev_istrunk(d->revnum);
+ rcsfile_insertdelta(b, d, trunk);
+ }
+
+ /* If we have a next, insert the placeholder into the lookup list. */
+ if (d_next != NULL)
+ rcsfile_insertsorteddelta(rf, d_next);
+}
+
+/*
+ * Find the branch of a revision number.
+ */
+static struct branch *
+rcsfile_getbranch(struct rcsfile *rf, char *revnum)
+{
+ struct branch *b;
+ struct delta *d;
+ char *branchrev, *bprev;
+
+ branchrev = rcsrev_prefix(revnum);
+ bprev = rcsrev_prefix(branchrev);
+ d = rcsfile_getdelta(rf, bprev);
+ free(bprev);
+ LIST_FOREACH(b, &d->branchlist, branch_next) {
+ if(rcsnum_cmp(b->revnum, branchrev) == 0) {
+ free(branchrev);
+ return (b);
+ }
+ }
+ free(branchrev);
+ return (NULL);
+}
+
+/* Insert a branch into a delta, sorted by branch revision date. */
+static void
+rcsdelta_insertbranch(struct delta *d, struct branch *b)
+{
+ struct branch *b_iter;
+
+ /* If it's empty, insert into head. */
+ if (LIST_EMPTY(&d->branchlist)) {
+ LIST_INSERT_HEAD(&d->branchlist, b, branch_next);
+ return;
+ }
+
+ /* Just put it in before the revdate that is lower. */
+ LIST_FOREACH(b_iter, &d->branchlist, branch_next) {
+ if (rcsnum_cmp(b->revnum, b_iter->revnum) > 0) {
+ LIST_INSERT_BEFORE(b_iter, b, branch_next);
+ return;
+ }
+ if (LIST_NEXT(b_iter, branch_next) == NULL)
+ break;
+ }
+ /* Insert after last element. */
+ LIST_INSERT_AFTER(b_iter, b, branch_next);
+}
+
+/* Insert a delta into the correct place in the table of the rcsfile. */
+static void
+rcsfile_insertsorteddelta(struct rcsfile *rf, struct delta *d)
+{
+ struct delta *d2;
+
+ /* If it's empty, insert into head. */
+ if (LIST_EMPTY(&rf->deltatable)) {
+ LIST_INSERT_HEAD(&rf->deltatable, d, table_next);
+ return;
+ }
+
+ /* Just put it in before the revdate that is lower. */
+ LIST_FOREACH(d2, &rf->deltatable, table_next) {
+ if (rcsnum_cmp(d->revnum, d2->revnum) <= 0) {
+ LIST_INSERT_BEFORE(d2, d, table_next);
+ return;
+ }
+ if (LIST_NEXT(d2, table_next) == NULL)
+ break;
+ }
+ /* Insert after last element. */
+ LIST_INSERT_AFTER(d2, d, table_next);
+}
+
+/*
+ * Insert a delta into the correct place in branch. A trunk branch will have
+ * different ordering scheme and be sorted by revision number, but a normal
+ * branch will be sorted by date to maintain compability with branches that is
+ * "hand-hacked".
+ */
+static void
+rcsfile_insertdelta(struct branch *b, struct delta *d, int trunk)
+{
+ struct delta *d2;
+
+ /* If it's empty, insert into head. */
+ if (LIST_EMPTY(&b->deltalist)) {
+ LIST_INSERT_HEAD(&b->deltalist, d, delta_next);
+ return;
+ }
+
+ /*
+ * Just put it in before the revnum that is lower. Sort trunk branch by
+ * branchnum but the subbranches after deltadate.
+ */
+ LIST_FOREACH(d2, &b->deltalist, delta_next) {
+ if (trunk) {
+ if (rcsnum_cmp(d->revnum, d2->revnum) >= 0) {
+ LIST_INSERT_BEFORE(d2, d, delta_next);
+ return;
+ }
+ } else {
+ /* XXX: here we depend on the date being set, but it
+ * should be before this is called anyway. */
+ if (rcsnum_cmp(d->revnum, d2->revnum) < 0) {
+ LIST_INSERT_BEFORE(d2, d, delta_next);
+ return;
+ }
+ }
+ if (LIST_NEXT(d2, delta_next) == NULL)
+ break;
+ }
+ /* Insert after last element. */
+ LIST_INSERT_AFTER(d2, d, delta_next);
+}
+
+
+/* Add logtext to a delta. Assume the delta already exists. */
+int
+rcsdelta_addlog(struct delta *d, char *log, int len)
+{
+ struct stream *dest;
+
+ assert(d != NULL);
+ /* Strip away '@' at beginning and end. */
+ log++;
+ len--;
+ log[len - 1] = '\0';
+ dest = stream_open_buf(d->log);
+ stream_write(dest, log, len - 1);
+ stream_close(dest);
+ return (0);
+}
+
+/* Add deltatext to a delta. Assume the delta already exists. */
+int
+rcsdelta_addtext(struct delta *d, char *text, int len)
+{
+ struct stream *dest;
+
+ assert(d != NULL);
+ /* Strip away '@' at beginning and end. */
+ text++;
+ len--;
+ text[len - 1] = '\0';
+
+ dest = stream_open_buf(d->text);
+ stream_write(dest, text, len - 1);
+ stream_close(dest);
+ return (0);
+}
+
+/* Add a deltatext logline to a delta. */
+void
+rcsdelta_appendlog(struct delta *d, char *logline, size_t size)
+{
+ struct stream *dest;
+
+ assert(d != NULL);
+ dest = stream_open_buf(d->log);
+ rcsdelta_writestring(logline, size, dest);
+ stream_close(dest);
+}
+
+/* Add a deltatext textline to a delta. */
+void
+rcsdelta_appendtext(struct delta *d, char *textline, size_t size)
+{
+ struct stream *dest;
+
+ assert(d != NULL);
+ dest = stream_open_buf(d->text);
+ rcsdelta_writestring(textline, size, dest);
+ stream_close(dest);
+}
+
+static void
+rcsdelta_writestring(char *textline, size_t size, struct stream *dest)
+{
+ char buf[3];
+ size_t i;
+ int count;
+
+ for (i = 0; i < size; i++) {
+ buf[0] = textline[i];
+ buf[1] = '\0';
+ count = 1;
+ /* Expand @'s */
+ if (buf[0] == '@') {
+ buf[1] = '@';
+ buf[2] = '\0';
+ count = 2;
+ }
+ stream_write(dest, buf, count);
+ }
+}
+
+/* Set delta state. */
+void
+rcsdelta_setstate(struct delta *d, char *state)
+{
+
+ if (d->state != NULL)
+ free(state);
+ if (state != NULL) {
+ d->state = xstrdup(state);
+ return;
+ }
+ d->state = NULL;
+}
+
+/* Truncate the deltalog with a certain offset. */
+void
+rcsdelta_truncatelog(struct delta *d, off_t offset)
+{
+
+ stream_truncate_buf(d->log, offset);
+}
+
+/* Truncate the deltatext with a certain offset. */
+void
+rcsdelta_truncatetext(struct delta *d, off_t offset)
+{
+
+ stream_truncate_buf(d->text, offset);
+}
diff --git a/contrib/csup/rcsfile.h b/contrib/csup/rcsfile.h
new file mode 100644
index 0000000..7eb38be
--- /dev/null
+++ b/contrib/csup/rcsfile.h
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2007-2009, Ulf Lilleengen <lulf@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 _RCSFILE_H_
+#define _RCSFILE_H_
+
+/* RCSFILE fields. */
+#define RCSFILE_HEAD 0
+#define RCSFILE_BRANCH 1
+#define RCSFILE_STRICT 2
+#define RCSFILE_COMMENT 3
+#define RCSFILE_EXPAND 4
+#define RCSFILE_DESC 5
+
+struct rcsfile;
+struct delta;
+struct stream;
+
+/* Fetching, sending and writing an RCS file. */
+struct rcsfile *rcsfile_frompath(char *, char *, char *, char *, int);
+int rcsfile_send_details(struct rcsfile *, struct stream *);
+int rcsfile_write(struct rcsfile *, struct stream *);
+void rcsfile_print(struct rcsfile *);
+void rcsfile_free(struct rcsfile *);
+
+/* Used for adding and setting rcsfile values. */
+void rcsfile_addaccess(struct rcsfile *, char *);
+void rcsfile_addtag(struct rcsfile *, char *, char *);
+void rcsfile_importtag(struct rcsfile *, char *, char *);
+void rcsfile_deleterev(struct rcsfile *, char *);
+void rcsfile_deletetag(struct rcsfile *, char *, char *);
+struct delta *rcsfile_getdelta(struct rcsfile *, char *);
+void rcsfile_setval(struct rcsfile *, int, char *);
+
+/* Functions used for operating on RCS deltas. */
+struct delta *rcsfile_addelta(struct rcsfile *, char *, char *, char *,
+ char *);
+void rcsfile_importdelta(struct rcsfile *, char *, char *, char *,
+ char *, char *);
+
+int rcsdelta_addlog(struct delta *, char *, int);
+int rcsdelta_addtext(struct delta *, char *, int);
+void rcsdelta_appendlog(struct delta *, char *, size_t);
+void rcsdelta_appendtext(struct delta *, char *, size_t);
+void rcsdelta_setstate(struct delta *, char *);
+void rcsdelta_truncatetext(struct delta *, off_t);
+void rcsdelta_truncatelog(struct delta *, off_t);
+#endif /* !_RCSFILE_H_ */
diff --git a/contrib/csup/rcsparse.c b/contrib/csup/rcsparse.c
new file mode 100644
index 0000000..682f113
--- /dev/null
+++ b/contrib/csup/rcsparse.c
@@ -0,0 +1,357 @@
+/*-
+ * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "misc.h"
+#include "queue.h"
+#include "rcsfile.h"
+#include "rcsparse.h"
+#include "rcstokenizer.h"
+
+/*
+ * This is an RCS-parser using lex for tokenizing and makes sure the RCS syntax
+ * is correct as it constructs an RCS file that is used by csup.
+ */
+
+static void asserttoken(yyscan_t *, int);
+static int parse_admin(struct rcsfile *, yyscan_t *);
+static int parse_deltas(struct rcsfile *, yyscan_t *, int);
+static int parse_deltatexts(struct rcsfile *, yyscan_t *, int);
+static char *duptext(yyscan_t *, int *);
+
+struct string {
+ char *str;
+ STAILQ_ENTRY(string) next;
+};
+
+static void
+asserttoken(yyscan_t *sp, int token)
+{
+ int t;
+
+ t = token;
+ t = rcslex(*sp);
+ assert(t == token);
+}
+
+static char *
+duptext(yyscan_t *sp, int *arglen)
+{
+ char *tmp, *val;
+ int len;
+
+ tmp = rcsget_text(*sp);
+ len = rcsget_leng(*sp);
+ val = xmalloc(len + 1);
+ memcpy(val, tmp, len);
+ val[len] = '\0';
+ if (arglen != NULL)
+ *arglen = len;
+ return (val);
+}
+
+/*
+ * Start up parser, and use the rcsfile hook to add objects.
+ */
+int
+rcsparse_run(struct rcsfile *rf, FILE *infp, int ro)
+{
+ yyscan_t scanner;
+ char *desc;
+ int error, tok;
+
+ error = 0;
+ rcslex_init(&scanner);
+ rcsset_in(infp, scanner);
+ tok = parse_admin(rf, &scanner);
+ tok = parse_deltas(rf, &scanner, tok);
+ assert(tok == KEYWORD);
+ asserttoken(&scanner, STRING);
+ desc = duptext(&scanner, NULL);
+ rcsfile_setval(rf, RCSFILE_DESC, desc);
+ free(desc);
+ tok = rcslex(scanner);
+ /* Parse deltatexts if we need to edit. */
+ if (!ro) {
+ error = parse_deltatexts(rf, &scanner, tok);
+ if (error)
+ return (error);
+ }
+ rcslex_destroy(scanner);
+ return (0);
+}
+
+/*
+ * Parse the admin part of a RCS file.
+ */
+static int
+parse_admin(struct rcsfile *rf, yyscan_t *sp)
+{
+ char *branch, *comment, *expand, *head, *id, *revnum, *tag, *tmp;
+ int strict, token;
+
+ strict = 0;
+ branch = NULL;
+
+ /* head {num}; */
+ asserttoken(sp, KEYWORD);
+ asserttoken(sp, NUM);
+ head = duptext(sp, NULL);
+ rcsfile_setval(rf, RCSFILE_HEAD, head);
+ free(head);
+ asserttoken(sp, SEMIC);
+
+ /* { branch {num}; } */
+ token = rcslex(*sp);
+ if (token == KEYWORD_TWO) {
+ asserttoken(sp, NUM);
+ branch = duptext(sp, NULL);
+ rcsfile_setval(rf, RCSFILE_BRANCH, branch);
+ free(branch);
+ asserttoken(sp, SEMIC);
+ token = rcslex(*sp);
+ }
+
+ /* access {id]*; */
+ assert(token == KEYWORD);
+ token = rcslex(*sp);
+ while (token == ID) {
+ id = duptext(sp, NULL);
+ rcsfile_addaccess(rf, id);
+ free(id);
+ token = rcslex(*sp);
+ }
+ assert(token == SEMIC);
+
+ /* symbols {sym : num}*; */
+ asserttoken(sp, KEYWORD);
+ token = rcslex(*sp);
+ while (token == ID) {
+ tag = duptext(sp, NULL);
+ asserttoken(sp, COLON);
+ asserttoken(sp, NUM);
+ revnum = duptext(sp, NULL);
+ rcsfile_importtag(rf, tag, revnum);
+ free(tag);
+ free(revnum);
+ token = rcslex(*sp);
+ }
+ assert(token == SEMIC);
+
+ /* locks {id : num}*; */
+ asserttoken(sp, KEYWORD);
+ token = rcslex(*sp);
+ while (token == ID) {
+ /* XXX: locks field is skipped */
+ asserttoken(sp, COLON);
+ asserttoken(sp, NUM);
+ token = rcslex(*sp);
+ }
+ assert(token == SEMIC);
+ token = rcslex(*sp);
+ while (token == KEYWORD) {
+ tmp = rcsget_text(*sp);
+
+ /* {strict ;} */
+ if (!strcmp(tmp, "strict")) {
+ rcsfile_setval(rf, RCSFILE_STRICT, tmp);
+ asserttoken(sp, SEMIC);
+ /* { comment {string}; } */
+ } else if (!strcmp(tmp, "comment")) {
+ token = rcslex(*sp);
+ if (token == STRING) {
+ comment = duptext(sp, NULL);
+ rcsfile_setval(rf, RCSFILE_COMMENT, comment);
+ free(comment);
+ }
+ asserttoken(sp, SEMIC);
+ /* { expand {string}; } */
+ } else if (!strcmp(tmp, "expand")) {
+ token = rcslex(*sp);
+ if (token == STRING) {
+ expand = duptext(sp, NULL);
+ rcsfile_setval(rf, RCSFILE_EXPAND, expand);
+ free(expand);
+ }
+ asserttoken(sp, SEMIC);
+ }
+ /* {newphrase }* */
+ token = rcslex(*sp);
+ while (token == ID) {
+ token = rcslex(*sp);
+ /* XXX: newphrases ignored */
+ while (token == ID || token == NUM || token == STRING ||
+ token == COLON) {
+ token = rcslex(*sp);
+ }
+ asserttoken(sp, SEMIC);
+ token = rcslex(*sp);
+ }
+ }
+ return (token);
+}
+
+/*
+ * Parse RCS deltas.
+ */
+static int
+parse_deltas(struct rcsfile *rf, yyscan_t *sp, int token)
+{
+ STAILQ_HEAD(, string) branchlist;
+ char *revnum, *revdate, *author, *state, *next;
+
+ /* In case we don't have deltas. */
+ if (token != NUM)
+ return (token);
+ do {
+ next = NULL;
+ state = NULL;
+
+ /* num */
+ assert(token == NUM);
+ revnum = duptext(sp, NULL);
+ /* date num; */
+ asserttoken(sp, KEYWORD);
+ asserttoken(sp, NUM);
+ revdate = duptext(sp, NULL);
+ asserttoken(sp, SEMIC);
+ /* author id; */
+ asserttoken(sp, KEYWORD);
+ asserttoken(sp, ID);
+ author = duptext(sp, NULL);
+ asserttoken(sp, SEMIC);
+ /* state {id}; */
+ asserttoken(sp, KEYWORD);
+ token = rcslex(*sp);
+ if (token == ID) {
+ state = duptext(sp, NULL);
+ token = rcslex(*sp);
+ }
+ assert(token == SEMIC);
+ /* branches {num}*; */
+ asserttoken(sp, KEYWORD);
+ token = rcslex(*sp);
+ STAILQ_INIT(&branchlist);
+ while (token == NUM)
+ token = rcslex(*sp);
+ assert(token == SEMIC);
+ /* next {num}; */
+ asserttoken(sp, KEYWORD);
+ token = rcslex(*sp);
+ if (token == NUM) {
+ next = duptext(sp, NULL);
+ token = rcslex(*sp);
+ }
+ assert(token == SEMIC);
+ /* {newphrase }* */
+ token = rcslex(*sp);
+ while (token == ID) {
+ token = rcslex(*sp);
+ /* XXX: newphrases ignored. */
+ while (token == ID || token == NUM || token == STRING ||
+ token == COLON) {
+ token = rcslex(*sp);
+ }
+ asserttoken(sp, SEMIC);
+ token = rcslex(*sp);
+ }
+ rcsfile_importdelta(rf, revnum, revdate, author, state, next);
+ free(revnum);
+ free(revdate);
+ free(author);
+ if (state != NULL)
+ free(state);
+ if (next != NULL)
+ free(next);
+ } while (token == NUM);
+
+ return (token);
+}
+
+/*
+ * Parse RCS deltatexts.
+ */
+static int
+parse_deltatexts(struct rcsfile *rf, yyscan_t *sp, int token)
+{
+ struct delta *d;
+ char *log, *revnum, *text;
+ int error, len;
+
+ error = 0;
+ /* In case we don't have deltatexts. */
+ if (token != NUM)
+ return (token);
+ do {
+ /* num */
+ assert(token == NUM);
+ revnum = duptext(sp, NULL);
+ /* Get delta we're adding text to. */
+ d = rcsfile_getdelta(rf, revnum);
+ free(revnum);
+
+ /* log string */
+ asserttoken(sp, KEYWORD);
+ asserttoken(sp, STRING);
+ log = duptext(sp, &len);
+ error = rcsdelta_addlog(d, log, len);
+ free(log);
+ if (error)
+ return (-1);
+ /* { newphrase }* */
+ token = rcslex(*sp);
+ while (token == ID) {
+ token = rcslex(*sp);
+ /* XXX: newphrases ignored. */
+ while (token == ID || token == NUM || token == STRING ||
+ token == COLON) {
+ token = rcslex(*sp);
+ }
+ asserttoken(sp, SEMIC);
+ token = rcslex(*sp);
+ }
+ /* text string */
+ assert(token == KEYWORD);
+ asserttoken(sp, STRING);
+ text = duptext(sp, &len);
+ error = rcsdelta_addtext(d, text, len);
+ /*
+ * If this happens, something is wrong with the RCS file, and it
+ * should be resent.
+ */
+ free(text);
+ if (error)
+ return (-1);
+ token = rcslex(*sp);
+ } while (token == NUM);
+
+ return (0);
+}
diff --git a/contrib/csup/rcsparse.h b/contrib/csup/rcsparse.h
new file mode 100644
index 0000000..01b0156
--- /dev/null
+++ b/contrib/csup/rcsparse.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@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 _RCSPARSE_H_
+#define _RCSPARSE_H_
+#define ID 0
+#define NUM 1
+#define KEYWORD 2
+#define KEYWORD_TWO 3
+#define STRING 4
+#define SEMIC 5
+#define COLON 6
+
+struct rcsfile;
+int rcsparse_run(struct rcsfile *, FILE *, int);
+#endif /* !_RCSPARSE_H_ */
diff --git a/contrib/csup/rcstokenizer.h b/contrib/csup/rcstokenizer.h
new file mode 100644
index 0000000..66ea724
--- /dev/null
+++ b/contrib/csup/rcstokenizer.h
@@ -0,0 +1,333 @@
+#ifndef rcsHEADER_H
+#define rcsHEADER_H 1
+#define rcsIN_HEADER 1
+
+#line 6 "rcstokenizer.h"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+void rcsrestart (FILE *input_file ,yyscan_t yyscanner );
+void rcs_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE rcs_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void rcs_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void rcs_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void rcspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void rcspop_buffer_state (yyscan_t yyscanner );
+
+YY_BUFFER_STATE rcs_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE rcs_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE rcs_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *rcsalloc (yy_size_t ,yyscan_t yyscanner );
+void *rcsrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void rcsfree (void * ,yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define rcswrap(n) 1
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+
+#endif
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+int rcslex_init (yyscan_t* scanner);
+
+int rcslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int rcslex_destroy (yyscan_t yyscanner );
+
+int rcsget_debug (yyscan_t yyscanner );
+
+void rcsset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE rcsget_extra (yyscan_t yyscanner );
+
+void rcsset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *rcsget_in (yyscan_t yyscanner );
+
+void rcsset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *rcsget_out (yyscan_t yyscanner );
+
+void rcsset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int rcsget_leng (yyscan_t yyscanner );
+
+char *rcsget_text (yyscan_t yyscanner );
+
+int rcsget_lineno (yyscan_t yyscanner );
+
+void rcsset_lineno (int line_number ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int rcswrap (yyscan_t yyscanner );
+#else
+extern int rcswrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int rcslex (yyscan_t yyscanner);
+
+#define YY_DECL int rcslex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#line 73 "rcstokenizer.l"
+
+
+#line 332 "rcstokenizer.h"
+#undef rcsIN_HEADER
+#endif /* rcsHEADER_H */
diff --git a/contrib/csup/rcstokenizer.l b/contrib/csup/rcstokenizer.l
new file mode 100644
index 0000000..56f0f41
--- /dev/null
+++ b/contrib/csup/rcstokenizer.l
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2007-2009, Ulf Lilleengen <lulf@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$
+ */
+
+/*
+ * This tokenizer must be generated by a lexxer with support for reentrancy.
+ */
+%{
+#include <string.h>
+
+#include "misc.h"
+#include "rcsparse.h"
+
+%}
+%option reentrant noyywrap
+%option header-file="rcstokenizer.h"
+
+everything (.|\n)*
+num [0-9\.]+
+whitespace [\t\n ]
+digit [0-9]
+idchar [^$,.:;\t\n ]
+string @([^@]|\n|"@@")*@
+keyword head|access|symbols|locks|comment|expand|strict|date|author|state|branches|next|desc|log|text
+keyword2 branch
+newline \n
+%%
+
+{keyword2} {
+ return (KEYWORD_TWO);
+}
+{keyword} {
+ return (KEYWORD);
+}
+{string} {
+ return (STRING);
+}
+{num} {
+ return (NUM);
+}
+{num}?{idchar}({idchar}|{num})* {
+/* This will use ID as both ID and SYM. Do extra checking elsewhere.*/
+ return (ID);
+}
+; { return (SEMIC); }
+: { return (COLON); }
+\n ;
+[ \t]+ ;
+%%
diff --git a/contrib/csup/rsyncfile.c b/contrib/csup/rsyncfile.c
new file mode 100644
index 0000000..7680bcc
--- /dev/null
+++ b/contrib/csup/rsyncfile.c
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@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 <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "misc.h"
+#include "rsyncfile.h"
+
+#define MINBLOCKSIZE 1024
+#define MAXBLOCKSIZE (16 * 1024)
+#define RECEIVEBUFFERSIZE (15 * 1024)
+#define BLOCKINFOSIZE 26
+#define SEARCHREGION 10
+#define MAXBLOCKS (RECEIVEBUFFERSIZE / BLOCKINFOSIZE)
+
+#define CHAR_OFFSET 3
+#define RSUM_SIZE 9
+
+struct rsyncfile {
+ char *start;
+ char *buf;
+ char *end;
+ size_t blocksize;
+ size_t fsize;
+ int fd;
+
+ char *blockptr;
+ int blocknum;
+ char blockmd5[MD5_DIGEST_SIZE];
+ char rsumstr[RSUM_SIZE];
+ uint32_t rsum;
+};
+
+static size_t rsync_chooseblocksize(size_t);
+static uint32_t rsync_rollsum(char *, size_t);
+
+/* Open a file and initialize variable for rsync operation. */
+struct rsyncfile *
+rsync_open(char *path, size_t blocksize, int rdonly)
+{
+ struct rsyncfile *rf;
+ struct stat st;
+ int error;
+
+ rf = xmalloc(sizeof(*rf));
+ error = stat(path, &st);
+ if (error) {
+ free(rf);
+ return (NULL);
+ }
+ rf->fsize = st.st_size;
+
+ rf->fd = open(path, rdonly ? O_RDONLY : O_RDWR);
+ if (rf->fd < 0) {
+ free(rf);
+ return (NULL);
+ }
+ rf->buf = mmap(0, rf->fsize, PROT_READ, MAP_SHARED, rf->fd, 0);
+ if (rf->buf == MAP_FAILED) {
+ free(rf);
+ return (NULL);
+ }
+ rf->start = rf->buf;
+ rf->end = rf->buf + rf->fsize;
+ rf->blocksize = (blocksize == 0 ? rsync_chooseblocksize(rf->fsize) :
+ blocksize);
+ rf->blockptr = rf->buf;
+ rf->blocknum = 0;
+ return (rf);
+}
+
+/* Close and free all resources related to an rsync file transfer. */
+int
+rsync_close(struct rsyncfile *rf)
+{
+ int error;
+
+ error = munmap(rf->buf, rf->fsize);
+ if (error)
+ return (error);
+ close(rf->fd);
+ free(rf);
+ return (0);
+}
+
+/*
+ * Choose the most appropriate block size for an rsync transfer. Modeled
+ * algorithm after cvsup.
+ */
+static size_t
+rsync_chooseblocksize(size_t fsize)
+{
+ size_t bestrem, blocksize, bs, hisearch, losearch, rem;
+
+ blocksize = fsize / MAXBLOCKS;
+ losearch = blocksize - SEARCHREGION;
+ hisearch = blocksize + SEARCHREGION;
+
+ if (losearch < MINBLOCKSIZE) {
+ losearch = MINBLOCKSIZE;
+ hisearch = losearch + (2 * SEARCHREGION);
+ } else if (hisearch > MAXBLOCKSIZE) {
+ hisearch = MAXBLOCKSIZE;
+ losearch = hisearch - (2 * SEARCHREGION);
+ }
+
+ bestrem = MAXBLOCKSIZE;
+ for (bs = losearch; bs <= hisearch; bs++) {
+ rem = fsize % bs;
+ if (rem < bestrem) {
+ bestrem = rem;
+ blocksize = bs;
+ }
+ }
+ return (bestrem);
+}
+
+/* Get the next rsync block of a file. */
+int
+rsync_nextblock(struct rsyncfile *rf)
+{
+ MD5_CTX ctx;
+ size_t blocksize;
+
+ if (rf->blockptr >= rf->end)
+ return (0);
+ blocksize = min((size_t)(rf->end - rf->blockptr), rf->blocksize);
+ /* Calculate MD5 of the block. */
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, rf->blockptr, blocksize);
+ MD5_End(rf->blockmd5, &ctx);
+
+ rf->rsum = rsync_rollsum(rf->blockptr, blocksize);
+ snprintf(rf->rsumstr, RSUM_SIZE, "%x", rf->rsum);
+ rf->blocknum++;
+ rf->blockptr += blocksize;
+ return (1);
+}
+
+/* Get the rolling checksum of a file. */
+static uint32_t
+rsync_rollsum(char *buf, size_t len)
+{
+ uint32_t a, b;
+ char *ptr, *limit;
+
+ a = b = 0;
+ ptr = buf;
+ limit = buf + len;
+
+ while (ptr < limit) {
+ a += *ptr + CHAR_OFFSET;
+ b += a;
+ ptr++;
+ }
+ return ((b << 16) | a);
+}
+
+/* Get running sum so far. */
+char *
+rsync_rsum(struct rsyncfile *rf)
+{
+
+ return (rf->rsumstr);
+}
+
+/* Get MD5 of current block. */
+char *
+rsync_blockmd5(struct rsyncfile *rf)
+{
+
+ return (rf->blockmd5);
+}
+
+/* Accessor for blocksize. */
+size_t
+rsync_blocksize(struct rsyncfile *rf)
+{
+
+ return (rf->blocksize);
+}
+
+/* Accessor for filesize. */
+size_t
+rsync_filesize(struct rsyncfile *rf)
+{
+
+ return (rf->fsize);
+}
diff --git a/contrib/csup/rsyncfile.h b/contrib/csup/rsyncfile.h
new file mode 100644
index 0000000..2c41a28
--- /dev/null
+++ b/contrib/csup/rsyncfile.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@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 _RSYNCFILE_H_
+#define _RSYNCFILE_H_
+
+struct rsyncfile;
+struct rsyncfile *rsync_open(char *, size_t, int);
+int rsync_nextblock(struct rsyncfile *);
+char *rsync_rsum(struct rsyncfile *);
+char *rsync_blockmd5(struct rsyncfile *);
+int rsync_close(struct rsyncfile *);
+size_t rsync_blocksize(struct rsyncfile *);
+size_t rsync_filesize(struct rsyncfile *);
+
+#endif /* !_RSYNCFILE_H_ */
diff --git a/contrib/csup/status.c b/contrib/csup/status.c
index 32b6821..3482e8e 100644
--- a/contrib/csup/status.c
+++ b/contrib/csup/status.c
@@ -101,6 +101,15 @@ statusrec_cook(struct statusrec *sr, char *line)
char *clientattr, *serverattr;
switch (sr->sr_type) {
+ case SR_FILEDEAD:
+ case SR_FILELIVE:
+ clientattr = proto_get_ascii(&line);
+ if (clientattr == NULL || line != NULL)
+ return (-1);
+ sr->sr_clientattr = fattr_decode(clientattr);
+ if (sr->sr_clientattr == NULL)
+ return (-1);
+ break;
case SR_DIRDOWN:
/* Nothing to do. */
if (line != NULL)
@@ -197,6 +206,9 @@ status_rdraw(struct status *st, char **linep)
}
switch (cmd[0]) {
+ case 'A':
+ sr.sr_type = SR_FILELIVE;
+ break;
case 'D':
sr.sr_type = SR_DIRDOWN;
st->depth++;
@@ -215,6 +227,12 @@ status_rdraw(struct status *st, char **linep)
}
st->depth--;
break;
+ case 'V':
+ sr.sr_type = SR_FILELIVE;
+ break;
+ case 'v':
+ sr.sr_type = SR_FILEDEAD;
+ break;
default:
st->error = STATUS_ERR_BAD_TYPE;
st->suberror = cmd[0];
@@ -290,6 +308,14 @@ status_wr(struct status *st, struct statusrec *sr)
error = proto_printf(st->wr, "c %s %s %s %f\n", sr->sr_file,
sr->sr_tag, sr->sr_date, sr->sr_serverattr);
break;
+ case SR_FILELIVE:
+ error = proto_printf(st->wr, "V %s %f\n", sr->sr_file,
+ sr->sr_clientattr);
+ break;
+ case SR_FILEDEAD:
+ error = proto_printf(st->wr, "v %s %f\n", sr->sr_file,
+ sr->sr_clientattr);
+ break;
}
if (error)
goto bad;
@@ -346,6 +372,12 @@ status_wrraw(struct status *st, struct statusrec *sr, char *line)
case SR_CHECKOUTDEAD:
cmd = 'c';
break;
+ case SR_FILELIVE:
+ cmd = 'V';
+ break;
+ case SR_FILEDEAD:
+ cmd = 'v';
+ break;
default:
assert(0);
return (-1);
diff --git a/contrib/csup/stream.c b/contrib/csup/stream.c
index 34aa71e..aa229b4 100644
--- a/contrib/csup/stream.c
+++ b/contrib/csup/stream.c
@@ -97,6 +97,7 @@ struct buf {
struct stream {
void *cookie;
int fd;
+ int buf;
struct buf *rdbuf;
struct buf *wrbuf;
stream_readfn_t *readfn;
@@ -126,10 +127,8 @@ struct stream_filter {
#define buf_count(buf) ((buf)->in)
#define buf_size(buf) ((buf)->size)
-static struct buf *buf_new(size_t);
static void buf_more(struct buf *, size_t);
static void buf_less(struct buf *, size_t);
-static void buf_free(struct buf *);
static void buf_grow(struct buf *, size_t);
/* Internal stream functions. */
@@ -165,6 +164,12 @@ static int zfilter_flush(struct stream *, struct buf *,
struct md5filter {
MD5_CTX ctx;
char *md5;
+ char lastc;
+#define PRINT 1
+#define WS 2
+#define STRING 3
+#define SEEN 4
+ int state;
};
static int md5filter_init(struct stream *, void *);
@@ -172,6 +177,8 @@ static void md5filter_fini(struct stream *);
static ssize_t md5filter_fill(struct stream *, struct buf *);
static int md5filter_flush(struct stream *, struct buf *,
stream_flush_t);
+static int md5rcsfilter_flush(struct stream *, struct buf *,
+ stream_flush_t);
/* The available stream filters. */
struct stream_filter stream_filters[] = {
@@ -195,12 +202,20 @@ struct stream_filter stream_filters[] = {
md5filter_fini,
md5filter_fill,
md5filter_flush
+ },
+ {
+ STREAM_FILTER_MD5RCS,
+ md5filter_init,
+ md5filter_fini,
+ md5filter_fill,
+ md5rcsfilter_flush
}
+
};
/* Create a new buffer. */
-static struct buf *
+struct buf *
buf_new(size_t size)
{
struct buf *buf;
@@ -211,6 +226,7 @@ buf_new(size_t size)
* there in case the stream doesn't have an ending newline.
*/
buf->buf = xmalloc(size + 1);
+ memset(buf->buf, 0, size + 1);
buf->size = size;
buf->in = 0;
buf->off = 0;
@@ -272,7 +288,7 @@ buf_less(struct buf *buf, size_t n)
}
/* Free a buffer. */
-static void
+void
buf_free(struct buf *buf)
{
@@ -301,6 +317,7 @@ stream_new(stream_readfn_t *readfn, stream_writefn_t *writefn,
stream->wrbuf = NULL;
stream->cookie = NULL;
stream->fd = -1;
+ stream->buf = 0;
stream->readfn = readfn;
stream->writefn = writefn;
stream->closefn = closefn;
@@ -335,6 +352,29 @@ stream_open_fd(int fd, stream_readfn_t *readfn, stream_writefn_t *writefn,
return (stream);
}
+/* Associate a buf with a stream. */
+struct stream *
+stream_open_buf(struct buf *b)
+{
+ struct stream *stream;
+
+ stream = stream_new(stream_read_buf, stream_append_buf, stream_close_buf);
+ stream->cookie = b;
+ stream->buf = 1;
+ b->in = 0;
+ return (stream);
+}
+
+/*
+ * Truncate a buffer, just decrease offset pointer.
+ * XXX: this can be dangerous if not used correctly.
+ */
+void
+stream_truncate_buf(struct buf *b, off_t off)
+{
+ b->off += off;
+}
+
/* Like open() but returns a stream. */
struct stream *
stream_open_file(const char *path, int flags, ...)
@@ -391,6 +431,57 @@ stream_fileno(struct stream *stream)
return (stream->fd);
}
+/* Convenience read function for character buffers. */
+ssize_t
+stream_read_buf(void *cookie, void *buf, size_t size)
+{
+ struct buf *b;
+ size_t avail;
+
+ /* Use in to be read offset. */
+ b = (struct buf *)cookie;
+ /* Just return what we have if the request is to large. */
+ avail = b->off - b->in;
+ if (avail < size) {
+ memcpy(buf, (b->buf + b->in), avail);
+ b->in += avail;
+ return (avail);
+ }
+ memcpy(buf, (b->buf + b->in), size);
+ b->in += size;
+ return (size);
+}
+
+/* Convenience write function for appending character buffers. */
+ssize_t
+stream_append_buf(void *cookie, const void *buf, size_t size)
+{
+ struct buf *b;
+ size_t avail;
+
+ /* Use off to be write offset. */
+ b = (struct buf *)cookie;
+
+ avail = b->size - b->off;
+ if (size > avail)
+ buf_grow(b, b->size + size);
+ memcpy((b->buf + b->off), buf, size);
+ b->off += size;
+ b->buf[b->off] = '\0';
+ return (size);
+}
+
+/* Convenience close function for freeing character buffers. */
+int
+stream_close_buf(void *cookie)
+{
+ void *data;
+
+ data = cookie;
+ /* Basically a NOP. */
+ return (0);
+}
+
/* Convenience read function for file descriptors. */
ssize_t
stream_read_fd(void *cookie, void *buf, size_t size)
@@ -446,6 +537,28 @@ stream_read(struct stream *stream, void *buf, size_t size)
return (n);
}
+/* A blocking stream_read call. */
+ssize_t
+stream_read_blocking(struct stream *stream, void *buf, size_t size)
+{
+ struct buf *rdbuf;
+ ssize_t ret;
+ size_t n;
+
+ rdbuf = stream->rdbuf;
+ while (buf_count(rdbuf) <= size) {
+ ret = stream_fill(stream);
+ if (ret <= 0)
+ return (-1);
+ }
+ /* XXX: Should be at least size bytes in the buffer, right? */
+ /* Just do this to make sure. */
+ n = min(size, buf_count(rdbuf));
+ memcpy(buf, rdbuf->buf + rdbuf->off, n);
+ buf_less(rdbuf, n);
+ return (n);
+}
+
/*
* Read a line from the stream and return a pointer to it.
*
@@ -638,6 +751,10 @@ stream_truncate_rel(struct stream *stream, off_t off)
struct stat sb;
int error;
+ if (stream->buf) {
+ stream_truncate_buf(stream->cookie, off);
+ return (0);
+ }
if (stream->fd == -1) {
errno = EINVAL;
return (-1);
@@ -1043,6 +1160,8 @@ md5filter_init(struct stream *stream, void *data)
mf = xmalloc(sizeof(struct md5filter));
MD5_Init(&mf->ctx);
mf->md5 = data;
+ mf->lastc = ';';
+ mf->state = PRINT;
stream->fdata = mf;
return (0);
}
@@ -1078,3 +1197,107 @@ md5filter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
error = stream_flush_default(stream, buf, how);
return (error);
}
+
+/* MD5 flush for RCS, where whitespaces are omitted. */
+static int
+md5rcsfilter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
+{
+ struct md5filter *mf;
+ char *ptr, *end;
+ char *start;
+ char space[2];
+ int error;
+
+ mf = stream->fdata;
+ space[0] = ' ';
+ space[1] = '\0';
+ ptr = buf->buf + buf->off;
+ end = buf->buf + buf->off + buf->in;
+
+#define IS_WS(var) ((var) == ' ' || (var) == '\n' || (var) == '\t' || \
+ (var) == '\010' || (var) == '\013' || (var) == '\f' || \
+ (var) == '\r')
+
+#define IS_SPECIAL(var) ((var) == '$' || (var) == ',' || (var) == ':' || \
+ (var) == ';' || (var) == '@')
+
+#define IS_PRINT(var) (!IS_WS(var) && (var) != '@')
+
+ /* XXX: We can do better than this state machine. */
+ while (ptr < end) {
+ switch (mf->state) {
+ /* Outside RCS statements. */
+ case PRINT:
+ start = ptr;
+ while (ptr < end && IS_PRINT(*ptr)) {
+ mf->lastc = *ptr;
+ ptr++;
+ }
+ MD5_Update(&mf->ctx, start, (ptr - start));
+ if (ptr < end) {
+ if (*ptr == '@') {
+ MD5_Update(&mf->ctx, ptr, 1);
+ ptr++;
+ mf->state = STRING;
+ } else {
+ mf->state = WS;
+ }
+ }
+ break;
+ case WS:
+ while (ptr < end && IS_WS(*ptr)) {
+ ptr++;
+ }
+ if (ptr < end) {
+ if (*ptr == '@') {
+ if (mf->lastc == '@') {
+ MD5_Update(&mf->ctx,
+ space, 1);
+ }
+ MD5_Update(&mf->ctx, ptr, 1);
+ ptr++;
+ mf->state = STRING;
+ } else {
+ if (!IS_SPECIAL(*ptr) &&
+ !IS_SPECIAL(mf->lastc)) {
+ MD5_Update(&mf->ctx,
+ space, 1);
+ }
+ mf->state = PRINT;
+ }
+ }
+ break;
+ case STRING:
+ start = ptr;
+ while (ptr < end && *ptr != '@') {
+ ptr++;
+ }
+ MD5_Update(&mf->ctx, start, (ptr - start));
+ if (ptr < end) {
+ MD5_Update(&mf->ctx, ptr, 1);
+ ptr++;
+ mf->state = SEEN;
+ }
+ break;
+ case SEEN:
+ if (*ptr == '@') {
+ MD5_Update(&mf->ctx, ptr, 1);
+ ptr++;
+ mf->state = STRING;
+ } else if(IS_WS(*ptr)) {
+ mf->lastc = '@';
+ mf->state = WS;
+ } else {
+ mf->state = PRINT;
+ }
+ break;
+ default:
+ err(1, "Invalid state");
+ break;
+ }
+ }
+
+ error = stream_flush_default(stream, buf, how);
+ return (error);
+}
+
diff --git a/contrib/csup/stream.h b/contrib/csup/stream.h
index 062fd34..2128635 100644
--- a/contrib/csup/stream.h
+++ b/contrib/csup/stream.h
@@ -34,10 +34,12 @@
typedef enum {
STREAM_FILTER_NULL,
STREAM_FILTER_ZLIB,
- STREAM_FILTER_MD5
+ STREAM_FILTER_MD5,
+ STREAM_FILTER_MD5RCS
} stream_filter_t;
struct stream;
+struct buf;
typedef ssize_t stream_readfn_t(void *, void *, size_t);
typedef ssize_t stream_writefn_t(void *, const void *, size_t);
@@ -48,13 +50,20 @@ stream_readfn_t stream_read_fd;
stream_writefn_t stream_write_fd;
stream_closefn_t stream_close_fd;
+/* Convenience functions for handling character buffers. */
+stream_readfn_t stream_read_buf;
+stream_writefn_t stream_append_buf;
+stream_closefn_t stream_close_buf;
+
struct stream *stream_open(void *, stream_readfn_t *, stream_writefn_t *,
stream_closefn_t *);
struct stream *stream_open_fd(int, stream_readfn_t *, stream_writefn_t *,
stream_closefn_t *);
+struct stream *stream_open_buf(struct buf *);
struct stream *stream_open_file(const char *, int, ...);
int stream_fileno(struct stream *);
ssize_t stream_read(struct stream *, void *, size_t);
+ssize_t stream_read_blocking(struct stream *, void *, size_t);
ssize_t stream_write(struct stream *, const void *, size_t);
char *stream_getln(struct stream *, size_t *);
int stream_printf(struct stream *, const char *, ...)
@@ -62,6 +71,7 @@ int stream_printf(struct stream *, const char *, ...)
int stream_flush(struct stream *);
int stream_sync(struct stream *);
int stream_truncate(struct stream *, off_t);
+void stream_truncate_buf(struct buf *, off_t);
int stream_truncate_rel(struct stream *, off_t);
int stream_rewind(struct stream *);
int stream_eof(struct stream *);
@@ -69,4 +79,6 @@ int stream_close(struct stream *);
int stream_filter_start(struct stream *, stream_filter_t, void *);
void stream_filter_stop(struct stream *);
+struct buf *buf_new(size_t);
+void buf_free(struct buf *);
#endif /* !_STREAM_H_ */
diff --git a/contrib/csup/updater.c b/contrib/csup/updater.c
index df74d52..3dc10c5 100644
--- a/contrib/csup/updater.c
+++ b/contrib/csup/updater.c
@@ -30,6 +30,7 @@
#include <sys/stat.h>
#include <assert.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
@@ -47,6 +48,7 @@
#include "misc.h"
#include "mux.h"
#include "proto.h"
+#include "rcsfile.h"
#include "status.h"
#include "stream.h"
@@ -56,11 +58,14 @@
#define UPDATER_ERR_READ (-3) /* Error reading from server. */
#define UPDATER_ERR_DELETELIM (-4) /* File deletion limit exceeded. */
+#define BUFSIZE 4096
+
/* Everything needed to update a file. */
struct file_update {
struct statusrec srbuf;
char *destpath;
char *temppath;
+ char *origpath;
char *coname; /* Points somewhere in destpath. */
char *wantmd5;
struct coll *coll;
@@ -69,6 +74,7 @@ struct file_update {
char *author;
struct stream *orig;
struct stream *to;
+ int attic;
int expand;
};
@@ -80,7 +86,7 @@ struct updater {
};
static struct file_update *fup_new(struct coll *, struct status *);
-static int fup_prepare(struct file_update *, char *);
+static int fup_prepare(struct file_update *, char *, int);
static void fup_cleanup(struct file_update *);
static void fup_free(struct file_update *);
@@ -90,14 +96,27 @@ static int updater_docoll(struct updater *, struct file_update *, int);
static int updater_delete(struct updater *, struct file_update *);
static void updater_deletefile(const char *);
static int updater_checkout(struct updater *, struct file_update *, int);
+static int updater_addfile(struct updater *, struct file_update *,
+ char *, int);
+int updater_addelta(struct rcsfile *, struct stream *, char *);
static int updater_setattrs(struct updater *, struct file_update *,
char *, char *, char *, char *, char *, struct fattr *);
+static int updater_setdirattrs(struct updater *, struct coll *,
+ struct file_update *, char *, char *);
static int updater_updatefile(struct updater *, struct file_update *fup,
const char *, int);
+static int updater_updatenode(struct updater *, struct coll *,
+ struct file_update *, char *, char *);
static int updater_diff(struct updater *, struct file_update *);
static int updater_diff_batch(struct updater *, struct file_update *);
static int updater_diff_apply(struct updater *, struct file_update *,
char *);
+static int updater_rcsedit(struct updater *, struct file_update *, char *,
+ char *);
+int updater_append_file(struct updater *, struct file_update *,
+ off_t);
+static int updater_rsync(struct updater *, struct file_update *, size_t);
+static int updater_read_checkout(struct stream *, struct stream *);
static struct file_update *
fup_new(struct coll *coll, struct status *st)
@@ -112,12 +131,27 @@ fup_new(struct coll *coll, struct status *st)
}
static int
-fup_prepare(struct file_update *fup, char *name)
+fup_prepare(struct file_update *fup, char *name, int attic)
{
struct coll *coll;
coll = fup->coll;
- fup->destpath = checkoutpath(coll->co_prefix, name);
+ fup->attic = 0;
+ fup->origpath = NULL;
+
+ if (coll->co_options & CO_CHECKOUTMODE)
+ fup->destpath = checkoutpath(coll->co_prefix, name);
+ else {
+ fup->destpath = cvspath(coll->co_prefix, name, attic);
+ fup->origpath = atticpath(coll->co_prefix, name);
+ /* If they're equal, we don't need special care. */
+ if (fup->origpath != NULL &&
+ strcmp(fup->origpath, fup->destpath) == 0) {
+ free(fup->origpath);
+ fup->origpath = NULL;
+ }
+ fup->attic = attic;
+ }
if (fup->destpath == NULL)
return (-1);
fup->coname = fup->destpath + coll->co_prefixlen + 1;
@@ -140,6 +174,10 @@ fup_cleanup(struct file_update *fup)
free(fup->temppath);
fup->temppath = NULL;
}
+ if (fup->origpath != NULL) {
+ free(fup->origpath);
+ fup->origpath = NULL;
+ }
fup->coname = NULL;
if (fup->author != NULL) {
free(fup->author);
@@ -309,11 +347,13 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
struct coll *coll;
struct statusrec srbuf, *sr;
struct fattr *rcsattr, *tmp;
- char *cmd, *line, *msg, *attr;
+ char *attr, *cmd, *blocksize, *line, *msg;
char *name, *tag, *date, *revdate;
char *expand, *wantmd5, *revnum;
+ char *optstr, *rcsopt, *pos;
time_t t;
- int error, needfixupmsg;
+ off_t position;
+ int attic, error, needfixupmsg;
error = 0;
rd = up->rd;
@@ -347,7 +387,7 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
if (rcsattr == NULL)
return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name);
+ error = fup_prepare(fup, name, 0);
if (error)
return (UPDATER_ERR_PROTO);
error = updater_setattrs(up, fup, name, tag, date,
@@ -365,7 +405,7 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
if (attr == NULL || line != NULL)
return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name);
+ error = fup_prepare(fup, name, 0);
if (error)
return (UPDATER_ERR_PROTO);
/* Theoritically, the file does not exist on the client.
@@ -419,7 +459,7 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
fup->expand = keyword_decode_expand(expand);
if (fup->expand == -1)
return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name);
+ error = fup_prepare(fup, name, 0);
if (error)
return (UPDATER_ERR_PROTO);
@@ -438,7 +478,7 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
if (attr == NULL || line != NULL)
return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name);
+ error = fup_prepare(fup, name, 0);
if (error)
return (UPDATER_ERR_PROTO);
error = updater_delete(up, fup);
@@ -492,7 +532,7 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
fattr_override(sr->sr_clientattr, tmp, FA_MASK);
fattr_free(tmp);
fattr_mergedefault(sr->sr_clientattr);
- error = fup_prepare(fup, name);
+ error = fup_prepare(fup, name, 0);
if (error)
return (UPDATER_ERR_PROTO);
fup->temppath = tempname(fup->destpath);
@@ -508,7 +548,7 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
name = proto_get_ascii(&line);
if (name == NULL || line != NULL)
return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name);
+ error = fup_prepare(fup, name, 0);
if (error)
return (UPDATER_ERR_PROTO);
error = updater_delete(up, fup);
@@ -520,6 +560,265 @@ updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
return (UPDATER_ERR_MSG);
}
break;
+ case 'A':
+ case 'a':
+ case 'R':
+ name = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ if (name == NULL || attr == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ attic = (cmd[0] == 'a');
+ error = fup_prepare(fup, name, attic);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+
+ fup->temppath = tempname(fup->destpath);
+ sr = &fup->srbuf;
+ sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ if (sr->sr_serverattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ if (attic)
+ lprintf(1, " Create %s -> Attic\n", name);
+ else
+ lprintf(1, " Create %s\n", name);
+ error = updater_addfile(up, fup, attr, 0);
+ if (error)
+ return (error);
+ break;
+ case 'r':
+ name = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ blocksize = proto_get_ascii(&line);
+ wantmd5 = proto_get_ascii(&line);
+ if (name == NULL || attr == NULL || blocksize == NULL ||
+ wantmd5 == NULL) {
+ return (UPDATER_ERR_PROTO);
+ }
+ error = fup_prepare(fup, name, 0);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ fup->wantmd5 = xstrdup(wantmd5);
+ fup->temppath = tempname(fup->destpath);
+ sr = &fup->srbuf;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ sr->sr_type = SR_FILELIVE;
+ if (sr->sr_serverattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ error = updater_rsync(up, fup, strtol(blocksize, NULL,
+ 10));
+ if (error)
+ return (error);
+ break;
+ case 'I':
+ /*
+ * Create directory and add DirDown entry in status
+ * file.
+ */
+ name = proto_get_ascii(&line);
+ if (name == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ error = fup_prepare(fup, name, 0);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ sr = &fup->srbuf;
+ sr->sr_type = SR_DIRDOWN;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = NULL;
+ sr->sr_clientattr = fattr_new(FT_DIRECTORY, -1);
+ fattr_mergedefault(sr->sr_clientattr);
+
+ error = mkdirhier(fup->destpath, coll->co_umask);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ if (access(fup->destpath, F_OK) != 0) {
+ lprintf(1, " Mkdir %s\n", name);
+ error = fattr_makenode(sr->sr_clientattr,
+ fup->destpath);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ }
+ error = status_put(fup->st, sr);
+ if (error) {
+ up->errmsg = status_errmsg(fup->st);
+ return (UPDATER_ERR_MSG);
+ }
+ break;
+ case 'i':
+ /* Remove DirDown entry in status file. */
+ name = proto_get_ascii(&line);
+ if (name == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ error = fup_prepare(fup, name, 0);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ error = status_delete(fup->st, name, 0);
+ if (error) {
+ up->errmsg = status_errmsg(fup->st);
+ return (UPDATER_ERR_MSG);
+ }
+ break;
+ case 'J':
+ /*
+ * Set attributes of directory and update DirUp entry in
+ * status file.
+ */
+ name = proto_get_ascii(&line);
+ if (name == NULL)
+ return (UPDATER_ERR_PROTO);
+ attr = proto_get_ascii(&line);
+ if (attr == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ error = fup_prepare(fup, name, 0);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ error = updater_setdirattrs(up, coll, fup, name, attr);
+ if (error)
+ return (error);
+ break;
+ case 'j':
+ /*
+ * Remove directory and delete its DirUp entry in status
+ * file.
+ */
+ name = proto_get_ascii(&line);
+ if (name == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ error = fup_prepare(fup, name, 0);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ lprintf(1, " Rmdir %s\n", name);
+ updater_deletefile(fup->destpath);
+ error = status_delete(fup->st, name, 0);
+ if (error) {
+ up->errmsg = status_errmsg(fup->st);
+ return (UPDATER_ERR_MSG);
+ }
+ break;
+ case 'L':
+ case 'l':
+ name = proto_get_ascii(&line);
+ if (name == NULL)
+ return (UPDATER_ERR_PROTO);
+ attr = proto_get_ascii(&line);
+ if (attr == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ attic = (cmd[0] == 'l');
+ sr = &fup->srbuf;
+ sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ sr->sr_clientattr = fattr_decode(attr);
+ if (sr->sr_serverattr == NULL ||
+ sr->sr_clientattr == NULL)
+ return (UPDATER_ERR_PROTO);
+
+ /* Save space. Described in detail in updatefile. */
+ if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT)
+ || fattr_getlinkcount(sr->sr_clientattr) <= 1)
+ fattr_maskout(sr->sr_clientattr,
+ FA_DEV | FA_INODE);
+ fattr_maskout(sr->sr_clientattr, FA_FLAGS);
+ error = status_put(fup->st, sr);
+ if (error) {
+ up->errmsg = status_errmsg(fup->st);
+ return (UPDATER_ERR_MSG);
+ }
+ break;
+ case 'N':
+ case 'n':
+ name = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ if (name == NULL || attr == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ attic = (cmd[0] == 'n');
+ error = fup_prepare(fup, name, attic);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ sr = &fup->srbuf;
+ sr->sr_type = (attic ? SR_FILEDEAD : SR_FILELIVE);
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ sr->sr_clientattr = fattr_new(FT_SYMLINK, -1);
+ fattr_mergedefault(sr->sr_clientattr);
+ fattr_maskout(sr->sr_clientattr, FA_FLAGS);
+ error = updater_updatenode(up, coll, fup, name, attr);
+ if (error)
+ return (error);
+ break;
+ case 'V':
+ case 'v':
+ name = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ optstr = proto_get_ascii(&line);
+ wantmd5 = proto_get_ascii(&line);
+ rcsopt = NULL; /* XXX: Not supported. */
+ if (attr == NULL || line != NULL || wantmd5 == NULL)
+ return (UPDATER_ERR_PROTO);
+ attic = (cmd[0] == 'v');
+ error = fup_prepare(fup, name, attic);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ fup->temppath = tempname(fup->destpath);
+ fup->wantmd5 = xstrdup(wantmd5);
+ sr = &fup->srbuf;
+ sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ if (sr->sr_serverattr == NULL)
+ return (UPDATER_ERR_PROTO);
+
+ error = 0;
+ error = updater_rcsedit(up, fup, name, rcsopt);
+ if (error)
+ return (error);
+ break;
+ case 'X':
+ case 'x':
+ name = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ if (name == NULL || attr == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ attic = (cmd[0] == 'x');
+ error = fup_prepare(fup, name, attic);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+
+ fup->temppath = tempname(fup->destpath);
+ sr = &fup->srbuf;
+ sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ if (sr->sr_serverattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ lprintf(1, " Fixup %s\n", name);
+ error = updater_addfile(up, fup, attr, 1);
+ if (error)
+ return (error);
+ break;
+ case 'Z':
+ name = proto_get_ascii(&line);
+ attr = proto_get_ascii(&line);
+ pos = proto_get_ascii(&line);
+ if (name == NULL || attr == NULL || pos == NULL ||
+ line != NULL)
+ return (UPDATER_ERR_PROTO);
+ error = fup_prepare(fup, name, 0);
+ fup->temppath = tempname(fup->destpath);
+ sr = &fup->srbuf;
+ sr->sr_type = SR_FILELIVE;
+ sr->sr_file = xstrdup(name);
+ sr->sr_serverattr = fattr_decode(attr);
+ if (sr->sr_serverattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ position = strtol(pos, NULL, 10);
+ lprintf(1, " Append to %s\n", name);
+ error = updater_append_file(up, fup, position);
+ if (error)
+ return (error);
+ break;
case '!':
/* Warning from server. */
msg = proto_get_rest(&line);
@@ -725,6 +1024,55 @@ updater_updatefile(struct updater *up, struct file_update *fup,
return (0);
}
+/*
+ * Update attributes of a directory.
+ */
+static int
+updater_setdirattrs(struct updater *up, struct coll *coll,
+ struct file_update *fup, char *name, char *attr)
+{
+ struct statusrec *sr;
+ struct fattr *fa;
+ int error, rv;
+
+ sr = &fup->srbuf;
+ sr->sr_type = SR_DIRUP;
+ sr->sr_file = xstrdup(name);
+ sr->sr_clientattr = fattr_decode(attr);
+ sr->sr_serverattr = fattr_decode(attr);
+ if (sr->sr_clientattr == NULL || sr->sr_serverattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ fattr_mergedefault(sr->sr_clientattr);
+ fattr_umask(sr->sr_clientattr, coll->co_umask);
+ rv = fattr_install(sr->sr_clientattr, fup->destpath, NULL);
+ lprintf(1, " SetAttrs %s\n", name);
+ if (rv == -1) {
+ xasprintf(&up->errmsg, "Cannot install \"%s\" to \"%s\": %s",
+ fup->temppath, fup->destpath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ /*
+ * Now, make sure they were set and record what was set in the status
+ * file.
+ */
+ fa = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
+ if (fa == NULL) {
+ xasprintf(&up->errmsg, "Cannot open \%s\": %s", fup->destpath,
+ strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ fattr_free(sr->sr_clientattr);
+ fattr_maskout(fa, FA_FLAGS);
+ sr->sr_clientattr = fa;
+ error = status_put(fup->st, sr);
+ if (error) {
+ up->errmsg = status_errmsg(fup->st);
+ return (UPDATER_ERR_MSG);
+ }
+
+ return (0);
+}
+
static int
updater_diff(struct updater *up, struct file_update *fup)
{
@@ -812,6 +1160,9 @@ updater_diff(struct updater *up, struct file_update *fup)
return (error);
}
+/*
+ * Edit a file and add delta.
+ */
static int
updater_diff_batch(struct updater *up, struct file_update *fup)
{
@@ -895,7 +1246,7 @@ updater_diff_apply(struct updater *up, struct file_update *fup, char *state)
di->di_state = state;
di->di_expand = fup->expand;
- error = diff_apply(up->rd, fup->orig, fup->to, coll->co_keyword, di);
+ error = diff_apply(up->rd, fup->orig, fup->to, coll->co_keyword, di, 1);
if (error) {
/* XXX Bad error message */
xasprintf(&up->errmsg, "Bad diff from server");
@@ -904,6 +1255,167 @@ updater_diff_apply(struct updater *up, struct file_update *fup, char *state)
return (0);
}
+/* Update or create a node. */
+static int
+updater_updatenode(struct updater *up, struct coll *coll,
+ struct file_update *fup, char *name, char *attr)
+{
+ struct fattr *fa, *fileattr;
+ struct status *st;
+ struct statusrec *sr;
+ int error, rv;
+
+ sr = &fup->srbuf;
+ st = fup->st;
+ fa = fattr_decode(attr);
+
+ if (fattr_type(fa) == FT_SYMLINK) {
+ lprintf(1, " Symlink %s -> %s\n", name,
+ fattr_getlinktarget(fa));
+ } else {
+ lprintf(1, " Mknod %s\n", name);
+ }
+
+ /* Create directory. */
+ error = mkdirhier(fup->destpath, coll->co_umask);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+
+ /* If it does not exist, create it. */
+ if (access(fup->destpath, F_OK) != 0)
+ fattr_makenode(fa, fup->destpath);
+
+ /*
+ * Coming from attic? I don't think this is a problem since we have
+ * determined attic before we call this function (Look at UpdateNode in
+ * cvsup).
+ */
+ fattr_umask(fa, coll->co_umask);
+ rv = fattr_install(fa, fup->destpath, fup->temppath);
+ if (rv == -1) {
+ xasprintf(&up->errmsg, "Cannot update attributes on "
+ "\"%s\": %s", fup->destpath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ /*
+ * XXX: Executes not implemented. Have not encountered much use for it
+ * yet.
+ */
+ /*
+ * We weren't necessarily able to set all the file attributes to the
+ * desired values, and any executes may have altered the attributes.
+ * To make sure we record the actual attribute values, we fetch
+ * them from the file.
+ *
+ * However, we preserve the link count as received from the
+ * server. This is important for preserving hard links in mirror
+ * mode.
+ */
+ fileattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
+ if (fileattr == NULL) {
+ xasprintf(&up->errmsg, "Cannot stat \"%s\": %s", fup->destpath,
+ strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ fattr_override(fileattr, sr->sr_clientattr, FA_LINKCOUNT);
+ fattr_free(sr->sr_clientattr);
+ sr->sr_clientattr = fileattr;
+
+ /*
+ * To save space, don't write out the device and inode unless
+ * the link count is greater than 1. These attributes are used
+ * only for detecting hard links. If the link count is 1 then we
+ * know there aren't any hard links.
+ */
+ if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT) ||
+ fattr_getlinkcount(sr->sr_clientattr) <= 1)
+ fattr_maskout(sr->sr_clientattr, FA_DEV | FA_INODE);
+
+ /* If it is a symlink, write only out it's path. */
+ if (fattr_type(fa) == FT_SYMLINK) {
+ fattr_maskout(sr->sr_clientattr, ~(FA_FILETYPE |
+ FA_LINKTARGET));
+ }
+ fattr_maskout(sr->sr_clientattr, FA_FLAGS);
+ error = status_put(st, sr);
+ if (error) {
+ up->errmsg = status_errmsg(st);
+ return (UPDATER_ERR_MSG);
+ }
+ fattr_free(fa);
+
+ return (0);
+}
+
+/*
+ * Fetches a new file in CVS mode.
+ */
+static int
+updater_addfile(struct updater *up, struct file_update *fup, char *attr,
+ int isfixup)
+{
+ struct coll *coll;
+ struct stream *to;
+ struct statusrec *sr;
+ struct fattr *fa;
+ char buf[BUFSIZE];
+ char md5[MD5_DIGEST_SIZE];
+ ssize_t nread;
+ off_t fsize, remains;
+ char *cmd, *line, *path;
+ int error;
+
+ coll = fup->coll;
+ path = fup->destpath;
+ sr = &fup->srbuf;
+ fa = fattr_decode(attr);
+ fsize = fattr_filesize(fa);
+
+ error = mkdirhier(path, coll->co_umask);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+ to = stream_open_file(fup->temppath, O_WRONLY | O_CREAT | O_TRUNC, 0755);
+ if (to == NULL) {
+ xasprintf(&up->errmsg, "%s: Cannot create: %s",
+ fup->temppath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ stream_filter_start(to, STREAM_FILTER_MD5, md5);
+ remains = fsize;
+ do {
+ nread = stream_read(up->rd, buf, (BUFSIZE > remains ?
+ remains : BUFSIZE));
+ remains -= nread;
+ stream_write(to, buf, nread);
+ } while (remains > 0);
+ stream_close(to);
+ line = stream_getln(up->rd, NULL);
+ if (line == NULL)
+ return (UPDATER_ERR_PROTO);
+ /* Check for EOF. */
+ if (!(*line == '.' || (strncmp(line, ".<", 2) != 0)))
+ return (UPDATER_ERR_PROTO);
+ line = stream_getln(up->rd, NULL);
+ if (line == NULL)
+ return (UPDATER_ERR_PROTO);
+
+ cmd = proto_get_ascii(&line);
+ fup->wantmd5 = proto_get_ascii(&line);
+ if (fup->wantmd5 == NULL || line != NULL || strcmp(cmd, "5") != 0)
+ return (UPDATER_ERR_PROTO);
+
+ sr->sr_clientattr = fattr_frompath(fup->temppath, FATTR_NOFOLLOW);
+ if (sr->sr_clientattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ fattr_override(sr->sr_clientattr, sr->sr_serverattr,
+ FA_MODTIME | FA_MASK);
+ error = updater_updatefile(up, fup, md5, isfixup);
+ fup->wantmd5 = NULL; /* So that it doesn't get freed. */
+ if (error)
+ return (error);
+ return (0);
+}
+
static int
updater_checkout(struct updater *up, struct file_update *fup, int isfixup)
{
@@ -911,9 +1423,9 @@ updater_checkout(struct updater *up, struct file_update *fup, int isfixup)
struct statusrec *sr;
struct coll *coll;
struct stream *to;
- char *cmd, *path, *line;
- size_t size;
ssize_t nbytes;
+ size_t size;
+ char *cmd, *path, *line;
int error, first;
coll = fup->coll;
@@ -1009,3 +1521,495 @@ updater_prunedirs(char *base, char *file)
return;
}
}
+
+/*
+ * Edit an RCS file.
+ */
+static int
+updater_rcsedit(struct updater *up, struct file_update *fup, char *name,
+ char *rcsopt)
+{
+ struct coll *coll;
+ struct stream *dest;
+ struct statusrec *sr;
+ struct status *st;
+ struct rcsfile *rf;
+ struct fattr *oldfattr;
+ char md5[MD5_DIGEST_SIZE];
+ char *branch, *cmd, *expand, *line, *path, *revnum, *tag, *temppath;
+ int error;
+
+ coll = fup->coll;
+ sr = &fup->srbuf;
+ st = fup->st;
+ temppath = fup->temppath;
+ path = fup->origpath != NULL ? fup->origpath : fup->destpath;
+ error = 0;
+
+ /* If the path is new, we must create the Attic dir if needed. */
+ if (fup->origpath != NULL) {
+ error = mkdirhier(fup->destpath, coll->co_umask);
+ if (error) {
+ xasprintf(&up->errmsg, "Unable to create Attic dir for "
+ "%s\n", fup->origpath);
+ return (UPDATER_ERR_MSG);
+ }
+ }
+ /*
+ * XXX: we could avoid parsing overhead if we're reading ahead before we
+ * parse the file.
+ */
+ oldfattr = fattr_frompath(path, FATTR_NOFOLLOW);
+ if (oldfattr == NULL) {
+ xasprintf(&up->errmsg, "%s: Cannot get attributes: %s", path,
+ strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ fattr_merge(sr->sr_serverattr, oldfattr);
+ rf = NULL;
+
+ /* Macro for making touching an RCS file faster. */
+#define UPDATER_OPENRCS(rf, up, path, name, cvsroot, tag) do { \
+ if ((rf) == NULL) { \
+ lprintf(1, " Edit %s", fup->coname); \
+ if (fup->attic) \
+ lprintf(1, " -> Attic"); \
+ lprintf(1, "\n"); \
+ (rf) = rcsfile_frompath((path), (name), (cvsroot), \
+ (tag), 0); \
+ if ((rf) == NULL) { \
+ xasprintf(&(up)->errmsg, \
+ "Error reading rcsfile %s\n", (name)); \
+ return (UPDATER_ERR_MSG); \
+ } \
+ } \
+} while (0)
+
+ while ((line = stream_getln(up->rd, NULL)) != NULL) {
+ if (strcmp(line, ".") == 0)
+ break;
+ cmd = proto_get_ascii(&line);
+ if (cmd == NULL) {
+ lprintf(-1, "Error editing %s\n", name);
+ return (UPDATER_ERR_PROTO);
+ }
+ switch(cmd[0]) {
+ case 'B':
+ branch = proto_get_ascii(&line);
+ if (branch == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ break;
+ case 'b':
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ rcsfile_setval(rf, RCSFILE_BRANCH, NULL);
+ break;
+ case 'D':
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ error = updater_addelta(rf, up->rd, line);
+ if (error)
+ return (error);
+ break;
+ case 'd':
+ revnum = proto_get_ascii(&line);
+ if (revnum == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ rcsfile_deleterev(rf, revnum);
+ break;
+ case 'E':
+ expand = proto_get_ascii(&line);
+ if (expand == NULL || line != NULL)
+ return (UPDATER_ERR_PROTO);
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ rcsfile_setval(rf, RCSFILE_EXPAND, expand);
+ break;
+ case 'T':
+ tag = proto_get_ascii(&line);
+ revnum = proto_get_ascii(&line);
+ if (tag == NULL || revnum == NULL ||
+ line != NULL)
+ return (UPDATER_ERR_PROTO);
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ rcsfile_addtag(rf, tag, revnum);
+ break;
+ case 't':
+ tag = proto_get_ascii(&line);
+ revnum = proto_get_ascii(&line);
+ if (tag == NULL || revnum == NULL ||
+ line != NULL)
+ return (UPDATER_ERR_PROTO);
+ UPDATER_OPENRCS(rf, up, path, name,
+ coll->co_cvsroot, coll->co_tag);
+ rcsfile_deletetag(rf, tag, revnum);
+ break;
+ default:
+ return (UPDATER_ERR_PROTO);
+ }
+ }
+
+ if (rf == NULL) {
+ fattr_maskout(oldfattr, ~FA_MODTIME);
+ if (fattr_equal(oldfattr, sr->sr_serverattr) == 0)
+ lprintf(1, " SetAttrs %s", fup->coname);
+ else
+ lprintf(1, " Touch %s", fup->coname);
+ if (fup->attic)
+ lprintf(1, " -> Attic");
+ lprintf(1, "\n");
+ fattr_free(oldfattr);
+ goto finish;
+ }
+
+ /* Write and rename temp file. */
+ dest = stream_open_file(fup->temppath,
+ O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (dest == NULL) {
+ xasprintf(&up->errmsg, "Error opening file %s for writing: %s\n",
+ fup->temppath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ stream_filter_start(dest, STREAM_FILTER_MD5RCS, md5);
+ error = rcsfile_write(rf, dest);
+ stream_close(dest);
+ rcsfile_free(rf);
+ if (error)
+ return (UPDATER_ERR_PROTO);
+
+finish:
+ sr->sr_clientattr = fattr_frompath(path, FATTR_NOFOLLOW);
+ if (sr->sr_clientattr == NULL) {
+ xasprintf(&up->errmsg, "%s: Cannot get attributes: %s",
+ fup->destpath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ fattr_override(sr->sr_clientattr, sr->sr_serverattr,
+ FA_MODTIME | FA_MASK);
+ if (rf != NULL) {
+ error = updater_updatefile(up, fup, md5, 0);
+ fup->wantmd5 = NULL; /* So that it doesn't get freed. */
+ if (error)
+ return (error);
+ } else {
+ /* Record its attributes since we touched it. */
+ if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT) ||
+ fattr_getlinkcount(sr->sr_clientattr) <= 1)
+ fattr_maskout(sr->sr_clientattr, FA_DEV | FA_INODE);
+ error = status_put(st, sr);
+ if (error) {
+ up->errmsg = status_errmsg(st);
+ return (UPDATER_ERR_MSG);
+ }
+ }
+
+ /* In this case, we need to remove the old file afterwards. */
+ /* XXX: Can we be sure that a file not edited is moved? I don't think
+ * this is a problem, since if a file is moved, it should be edited to
+ * show if it's dead or not.
+ */
+ if (fup->origpath != NULL)
+ updater_deletefile(fup->origpath);
+ return (0);
+}
+
+/*
+ * Add a delta to a RCS file.
+ */
+int
+updater_addelta(struct rcsfile *rf, struct stream *rd, char *cmdline)
+{
+ struct delta *d;
+ size_t size;
+ char *author, *cmd, *diffbase, *line, *logline;
+ char *revdate, *revnum, *state, *textline;
+
+ revnum = proto_get_ascii(&cmdline);
+ diffbase = proto_get_ascii(&cmdline);
+ revdate = proto_get_ascii(&cmdline);
+ author = proto_get_ascii(&cmdline);
+ size = 0;
+
+ if (revnum == NULL || revdate == NULL || author == NULL)
+ return (UPDATER_ERR_PROTO);
+
+ /* First add the delta so we have it. */
+ d = rcsfile_addelta(rf, revnum, revdate, author, diffbase);
+ if (d == NULL) {
+ lprintf(-1, "Error adding delta %s\n", revnum);
+ return (UPDATER_ERR_READ);
+ }
+ while ((line = stream_getln(rd, NULL)) != NULL) {
+ if (strcmp(line, ".") == 0)
+ break;
+ cmd = proto_get_ascii(&line);
+ switch (cmd[0]) {
+ case 'L':
+ /* Do the same as in 'C' command. */
+ logline = stream_getln(rd, &size);
+ while (logline != NULL) {
+ if (size == 2 && *logline == '.')
+ break;
+ if (size == 3 &&
+ memcmp(logline, ".+", 2) == 0) {
+ rcsdelta_truncatelog(d, -1);
+ break;
+ }
+ if (size >= 3 &&
+ memcmp(logline, "..", 2) == 0) {
+ size--;
+ logline++;
+ }
+ rcsdelta_appendlog(d, logline, size);
+ logline = stream_getln(rd, &size);
+ }
+ break;
+ case 'N':
+ case 'n':
+ /* XXX: Not supported. */
+ break;
+ case 'S':
+ state = proto_get_ascii(&line);
+ if (state == NULL)
+ return (UPDATER_ERR_PROTO);
+ rcsdelta_setstate(d, state);
+ break;
+ case 'T':
+ /* Do the same as in 'C' command. */
+ textline = stream_getln(rd, &size);
+ while (textline != NULL) {
+ if (size == 2 && *textline == '.')
+ break;
+ if (size == 3 &&
+ memcmp(textline, ".+", 2) == 0) {
+ /* Truncate newline. */
+ rcsdelta_truncatetext(d, -1);
+ break;
+ }
+ if (size >= 3 &&
+ memcmp(textline, "..", 2) == 0) {
+ size--;
+ textline++;
+ }
+ rcsdelta_appendtext(d, textline, size);
+ textline = stream_getln(rd, &size);
+ }
+ break;
+ }
+ }
+
+ return (0);
+}
+
+int
+updater_append_file(struct updater *up, struct file_update *fup, off_t pos)
+{
+ struct fattr *fa;
+ struct stream *to;
+ struct statusrec *sr;
+ ssize_t nread;
+ off_t bytes;
+ char buf[BUFSIZE], md5[MD5_DIGEST_SIZE];
+ char *line, *cmd;
+ int error, fd;
+
+ sr = &fup->srbuf;
+ fa = sr->sr_serverattr;
+ to = stream_open_file(fup->temppath, O_WRONLY | O_CREAT | O_TRUNC,
+ 0755);
+ if (to == NULL) {
+ xasprintf(&up->errmsg, "%s: Cannot open: %s", fup->temppath,
+ strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ fd = open(fup->destpath, O_RDONLY);
+ if (fd < 0) {
+ xasprintf(&up->errmsg, "%s: Cannot open: %s", fup->destpath,
+ strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+
+ stream_filter_start(to, STREAM_FILTER_MD5, md5);
+ /* First write the existing content. */
+ while ((nread = read(fd, buf, BUFSIZE)) > 0)
+ stream_write(to, buf, nread);
+ close(fd);
+
+ bytes = fattr_filesize(fa) - pos;
+ /* Append the new data. */
+ do {
+ nread = stream_read(up->rd, buf,
+ (BUFSIZE > bytes) ? bytes : BUFSIZE);
+ bytes -= nread;
+ stream_write(to, buf, nread);
+ } while (bytes > 0);
+ stream_close(to);
+
+ line = stream_getln(up->rd, NULL);
+ if (line == NULL)
+ return (UPDATER_ERR_PROTO);
+ /* Check for EOF. */
+ if (!(*line == '.' || (strncmp(line, ".<", 2) != 0)))
+ return (UPDATER_ERR_PROTO);
+ line = stream_getln(up->rd, NULL);
+ if (line == NULL)
+ return (UPDATER_ERR_PROTO);
+
+ cmd = proto_get_ascii(&line);
+ fup->wantmd5 = proto_get_ascii(&line);
+ if (fup->wantmd5 == NULL || line != NULL || strcmp(cmd, "5") != 0)
+ return (UPDATER_ERR_PROTO);
+
+ sr->sr_clientattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
+ if (sr->sr_clientattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ fattr_override(sr->sr_clientattr, sr->sr_serverattr,
+ FA_MODTIME | FA_MASK);
+ error = updater_updatefile(up, fup, md5, 0);
+ fup->wantmd5 = NULL; /* So that it doesn't get freed. */
+ if (error)
+ return (error);
+ return (0);
+}
+
+/*
+ * Read file data from stream of checkout commands, and write it to the
+ * destination.
+ */
+static int
+updater_read_checkout(struct stream *src, struct stream *dest)
+{
+ ssize_t nbytes;
+ size_t size;
+ char *line;
+ int first;
+
+ first = 1;
+ line = stream_getln(src, &size);
+ while (line != NULL) {
+ if (line[size - 1] == '\n')
+ size--;
+ if ((size == 1 && *line == '.') ||
+ (size == 2 && strncmp(line, ".+", 2) == 0))
+ break;
+ if (size >= 2 && strncmp(line, "..", 2) == 0) {
+ size--;
+ line++;
+ }
+ if (!first) {
+ nbytes = stream_write(dest, "\n", 1);
+ if (nbytes == -1)
+ return (UPDATER_ERR_MSG);
+ }
+ nbytes = stream_write(dest, line, size);
+ if (nbytes == -1)
+ return (UPDATER_ERR_MSG);
+ line = stream_getln(src, &size);
+ first = 0;
+ }
+ if (line == NULL)
+ return (UPDATER_ERR_READ);
+ if (size == 1 && *line == '.') {
+ nbytes = stream_write(dest, "\n", 1);
+ if (nbytes == -1)
+ return (UPDATER_ERR_MSG);
+ }
+ return (0);
+}
+
+/* Update file using the rsync protocol. */
+static int
+updater_rsync(struct updater *up, struct file_update *fup, size_t blocksize)
+{
+ struct statusrec *sr;
+ struct stream *to;
+ char md5[MD5_DIGEST_SIZE];
+ ssize_t nbytes;
+ size_t blocknum, blockstart, blockcount;
+ char *buf, *line;
+ int error, orig;
+
+ sr = &fup->srbuf;
+
+ lprintf(1, " Rsync %s\n", fup->coname);
+ /* First open all files that we are going to work on. */
+ to = stream_open_file(fup->temppath, O_WRONLY | O_CREAT | O_TRUNC,
+ 0600);
+ if (to == NULL) {
+ xasprintf(&up->errmsg, "%s: Cannot create: %s",
+ fup->temppath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ orig = open(fup->destpath, O_RDONLY);
+ if (orig < 0) {
+ xasprintf(&up->errmsg, "%s: Cannot open: %s",
+ fup->destpath, strerror(errno));
+ return (UPDATER_ERR_MSG);
+ }
+ stream_filter_start(to, STREAM_FILTER_MD5, md5);
+
+ error = updater_read_checkout(up->rd, to);
+ if (error) {
+ xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath,
+ strerror(errno));
+ return (error);
+ }
+
+ /* Buffer must contain blocksize bytes. */
+ buf = xmalloc(blocksize);
+ /* Done with the initial text, read and write chunks. */
+ line = stream_getln(up->rd, NULL);
+ while (line != NULL) {
+ if (strcmp(line, ".") == 0)
+ break;
+ error = UPDATER_ERR_PROTO;
+ if (proto_get_sizet(&line, &blockstart, 10) != 0)
+ goto bad;
+ if (proto_get_sizet(&line, &blockcount, 10) != 0)
+ goto bad;
+ /* Read blocks from original file. */
+ lseek(orig, (blocksize * blockstart), SEEK_SET);
+ error = UPDATER_ERR_MSG;
+ for (blocknum = 0; blocknum < blockcount; blocknum++) {
+ nbytes = read(orig, buf, blocksize);
+ if (nbytes < 0) {
+ xasprintf(&up->errmsg, "%s: Cannot read: %s",
+ fup->destpath, strerror(errno));
+ goto bad;
+ }
+ nbytes = stream_write(to, buf, nbytes);
+ if (nbytes == -1) {
+ xasprintf(&up->errmsg, "%s: Cannot write: %s",
+ fup->temppath, strerror(errno));
+ goto bad;
+ }
+ }
+ /* Get the remaining text from the server. */
+ error = updater_read_checkout(up->rd, to);
+ if (error) {
+ xasprintf(&up->errmsg, "%s: Cannot write: %s",
+ fup->temppath, strerror(errno));
+ goto bad;
+ }
+ line = stream_getln(up->rd, NULL);
+ }
+ stream_close(to);
+ close(orig);
+
+ sr->sr_clientattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
+ if (sr->sr_clientattr == NULL)
+ return (UPDATER_ERR_PROTO);
+ fattr_override(sr->sr_clientattr, sr->sr_serverattr,
+ FA_MODTIME | FA_MASK);
+
+ error = updater_updatefile(up, fup, md5, 0);
+ fup->wantmd5 = NULL; /* So that it doesn't get freed. */
+bad:
+ free(buf);
+ return (error);
+}
diff --git a/contrib/file/AUTHORS b/contrib/file/AUTHORS
new file mode 100644
index 0000000..3d3d34a
--- /dev/null
+++ b/contrib/file/AUTHORS
@@ -0,0 +1 @@
+See COPYING. \ No newline at end of file
diff --git a/contrib/file/LEGAL.NOTICE b/contrib/file/COPYING
index 68148e2..b3db8b2 100644
--- a/contrib/file/LEGAL.NOTICE
+++ b/contrib/file/COPYING
@@ -1,4 +1,4 @@
-$File: LEGAL.NOTICE,v 1.15 2006/05/03 18:48:33 christos Exp $
+$File: COPYING,v 1.1 2008/02/05 19:08:11 christos Exp $
Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
Software written by Ian F. Darwin and others;
maintained 1994- Christos Zoulas.
diff --git a/contrib/file/ChangeLog b/contrib/file/ChangeLog
index 2beffb0..2c62a72 100644
--- a/contrib/file/ChangeLog
+++ b/contrib/file/ChangeLog
@@ -1,4 +1,135 @@
-2007-12-28 15:06 Christos Zoulas <christos@zoulas.com>
+2008-08-30 12:54 Christos Zoulas <christos@astron.com>
+
+ * Don't eat trailing \n in magic enties.
+
+ * Cast defines to allow compilation using a c++ compiler.
+
+2008-07-26 00:59 Reuben Thomas <rrt@sc3d.org>
+
+ * Add MIME types for special files.
+
+ * Use access to give more accurate information for files that
+ can't be opened.
+
+ * Add a TODO list.
+
+2008-07-02 11:15 Christos Zoulas <christos@astron.com>
+
+ * add !:strength op to adjust magic strength (experimental)
+
+2008-06-16 21:41 Reuben Thomas <rrt@sc3d.org>
+
+ * Fix automake error in configure.ac.
+
+ * Add MIME type for Psion Sketch files.
+
+2008-06-05 08:59 Christos Zoulas <christos@astron.com>
+
+ * Don't print warnings about bad namesize in stripped
+ binaries with PT_NOTE is still there, and the actual
+ note is gone (Jakub Jelinek)
+
+2008-05-28 15:12 Robert Byrnes <byrnes@wildpumpkin.net>
+
+ * magic/Magdir/elf:
+ Note invalid byte order for little-endian SPARC32PLUS.
+ Add SPARC V9 vendor extensions and memory model.
+
+ * src/elfclass.h:
+ Pass target machine to doshn (for Solaris hardware capabilities).
+
+ * src/readelf.c (doshn):
+ Add support for Solaris hardware/software capabilities.
+
+ * src/readelf.h:
+ Ditto.
+
+ * src/vasprintf.c (dispatch):
+ Add support for ll modifier.
+
+2008-05-16 10:25 Christos Zoulas <christos@astron.com>
+
+ * Fix compiler warnings.
+
+ * remove stray printf, and fix a vprintf bug. (Martin Dorey)
+
+2008-05-06 00:13 Robert Byrnes <byrnes@wildpumpkin.net>
+
+ * src/Makefile.am:
+ Ensure that getopt_long and [v]asprintf are included in libmagic,
+ as needed.
+
+ Remove unnecessary EXTRA_DIST.
+
+ * src/Makefile.in:
+ Rerun automake.
+
+ * src/vasprintf.c (dispatch):
+ Fix variable precision bug: be sure to step past '*'.
+
+ * src/vasprintf.c (core):
+ Remove unreachable code.
+
+ * src/apprentice.c (set_test_type):
+ Add cast to avoid compiler warning.
+
+2008-04-22 23:45 Christos Zoulas <christos@astron.com>
+
+ * Add magic submission guidelines (Abel Cheung)
+
+ * split msdos and windows magic (Abel Cheung)
+
+2008-04-04 11:00 Christos Zoulas <christos@astron.com>
+
+ * >= <= is not supported, so fix the magic and warn about it.
+ reported by: Thien-Thi Nguyen <ttn@gnuvola.org>
+
+2008-03-27 16:16 Robert Byrnes <byrnes@wildpumpkin.net>
+
+ * src/readelf.c (donote):
+ ELF core file command name/line bug fixes and enhancements:
+
+ Try larger offsets first to avoid false matches
+ from earlier data that happen to look like strings;
+ this primarily affected SunOS 5.x 32-bit Intel core files.
+
+ Add support for command line (instead of just short name)
+ for SunOS 5.x.
+
+ Add information about NT_PSINFO for SunOS 5.x.
+
+ Only trim whitespace from end of command line.
+
+2007-02-11 01:36 Reuben Thomas <rrt@sc3d.org>
+
+ * Change strength of ! from MULT to 0, as it matches almost
+ anything (Reuben Thomas)
+
+ * Debian fixes (Reuben Thomas)
+
+2007-02-11 00:17 Reuben Thomas <rrt@sc3d.org>
+
+ * Clarify UTF-8 BOM message (Reuben Thomas)
+
+ * Add HTML comment to token list in names.h
+
+2007-02-04 15:50 Christos Zoulas <christos@astron.com>
+
+ * Debian fixes (Reuben Thomas)
+
+2007-02-04 11:31 Christos Zoulas <christos@astron.com>
+
+ * !:mime annotations in magic files (Reuben Thomas)
+
+2007-01-29 15:35 Christos Zoulas <christos@astron.com>
+
+ * zero out utime/utimes structs (Gavin Atkinson)
+
+2007-01-26 13:45 Christos Zoulas <christos@astron.com>
+
+ * reduce writable data from Diego "Flameeyes" Petten
+
+2007-12-28 15:06 Christos Zoulas <christos@astron.com>
* strtof detection
@@ -6,7 +137,7 @@
* better mismatch version message
-2007-12-27 11:35 Christos Zoulas <christos@zoulas.com>
+2007-12-27 11:35 Christos Zoulas <christos@astron.com>
* bring back some fixes from OpenBSD
@@ -14,46 +145,46 @@
* fix gcc warnings
-2007-12-01 19:55 Christos Zoulas <christos@zoulas.com>
+2007-12-01 19:55 Christos Zoulas <christos@astron.com>
* make sure we have zlib.h and libz to compile the builtin
decompress code
-2007-10-28 20:48 Christos Zoulas <christos@zoulas.com>
+2007-10-28 20:48 Christos Zoulas <christos@astron.com>
* float and double magic support (Behan Webster)
-2007-10-28 20:48 Christos Zoulas <christos@zoulas.com>
+2007-10-28 20:48 Christos Zoulas <christos@astron.com>
* Convert fortran to a soft test (Reuben Thomas)
-2007-10-23 5:25 Christos Zoulas <christos@zoulas.com>
+2007-10-23 5:25 Christos Zoulas <christos@astron.com>
* Add --with-filename, and --no-filename (Reuben Thomas)
-2007-10-23 3:59 Christos Zoulas <christos@zoulas.com>
+2007-10-23 3:59 Christos Zoulas <christos@astron.com>
* Rest of the mime split (Reuben Thomas)
* Make usage message generated from the flags so that
they stay consistent (Reuben Thomas)
-2007-10-20 3:06 Christos Zoulas <christos@zoulas.com>
+2007-10-20 3:06 Christos Zoulas <christos@astron.com>
* typo in comment, missing ifdef QUICK, remove unneeded code
(Charles Longeau)
-2007-10-17 3:33 Christos Zoulas <christos@zoulas.com>
+2007-10-17 3:33 Christos Zoulas <christos@astron.com>
* Fix problem printing -\012 in some entries
* Separate magic type and encoding flags (Reuben Thomas)
-2007-10-09 3:55 Christos Zoulas <christos@zoulas.com>
+2007-10-09 3:55 Christos Zoulas <christos@astron.com>
* configure fix for int64 and strndup (Reuben Thomas)
-2007-09-26 4:45 Christos Zoulas <christos@zoulas.com>
+2007-09-26 4:45 Christos Zoulas <christos@astron.com>
* Add magic_descriptor() function.
@@ -62,7 +193,7 @@
* Don't convert NUL's to spaces in {l,b}estring16 (Daniel Dawson)
-2007-08-19 6:30 Christos Zoulas <christos@zoulas.com>
+2007-08-19 6:30 Christos Zoulas <christos@astron.com>
* Make mime format consistent so that it can
be easily parsed:
@@ -79,38 +210,38 @@
This work was done by Reuben Thomas
-2007-05-24 10:00 Christos Zoulas <christos@zoulas.com>
+2007-05-24 10:00 Christos Zoulas <christos@astron.com>
* Fix another integer overflow (Colin Percival)
-2007-03-26 13:58 Christos Zoulas <christos@zoulas.com>
+2007-03-26 13:58 Christos Zoulas <christos@astron.com>
* make sure that all of struct magic_set is initialized appropriately
(Brett)
-2007-03-25 17:44 Christos Zoulas <christos@zoulas.com>
+2007-03-25 17:44 Christos Zoulas <christos@astron.com>
* reset left bytes in the buffer (Dmitry V. Levin)
* compilation failed with COMPILE_ONLY and ENABLE_CONDITIONALS
(Peter Avalos)
-2007-03-15 10:51 Christos Zoulas <christos@zoulas.com>
+2007-03-15 10:51 Christos Zoulas <christos@astron.com>
* fix fortran and nroff reversed tests (Dmitry V. Levin)
* fix exclude option (Dmitry V. Levin)
-2007-02-08 17:30 Christos Zoulas <christos@zoulas.com>
+2007-02-08 17:30 Christos Zoulas <christos@astron.com>
* fix integer underflow in file_printf which can lead to
to exploitable heap overflow (Jean-Sebastien Guay-Lero)
-2007-02-05 11:35 Christos Zoulas <christos@zoulas.com>
+2007-02-05 11:35 Christos Zoulas <christos@astron.com>
* make socket/pipe reading more robust
-2007-01-25 16:01 Christos Zoulas <christos@zoulas.com>
+2007-01-25 16:01 Christos Zoulas <christos@astron.com>
* Centralize all the tests in file_buffer.
@@ -184,7 +315,7 @@
* make file.c compile with gcc warnings and pass lint
-2006-12-11 16:49 Christos Zoulas <christos@zoulas.com>
+2006-12-11 16:49 Christos Zoulas <christos@astron.com>
* fix byteswapping issue
@@ -193,7 +324,7 @@
* add a few missed cases in the strength routine
-2006-12-08 16:32 Christos Zoulas <christos@zoulas.com>
+2006-12-08 16:32 Christos Zoulas <christos@astron.com>
* store and print the line number of the magic
entry for debugging.
@@ -210,7 +341,7 @@
* propagate the error return from match to
file_softmagic.
-2006-11-25 13:35 Christos Zoulas <christos@zoulas.com>
+2006-11-25 13:35 Christos Zoulas <christos@astron.com>
* Don't store the current offset in the magic
struct, because it needs to be restored and
@@ -221,12 +352,12 @@
print it as an additional separator; print
it as the only separator.
-2006-11-17 10:51 Christos Zoulas <christos@zoulas.com>
+2006-11-17 10:51 Christos Zoulas <christos@astron.com>
* Added a -0 option to print a '\0' separator
Etienne Buira <etienne.buira@free.fr>
-2006-10-31 15:14 Christos Zoulas <christos@zoulas.com>
+2006-10-31 15:14 Christos Zoulas <christos@astron.com>
* Check offset before copying (Mike Frysinger)
@@ -242,7 +373,7 @@
* use calloc to initialize the ascii buffers (Jos van den Oever)
-2006-06-08 11:11 Christos Zoulas <christos@zoulas.com>
+2006-06-08 11:11 Christos Zoulas <christos@astron.com>
* QNX fixes (Mike Gorchak)
@@ -256,7 +387,7 @@
* Magic format function improvent (Karl Chen)
-2006-05-03 11:11 Christos Zoulas <christos@zoulas.com>
+2006-05-03 11:11 Christos Zoulas <christos@astron.com>
* Pick up some elf changes and some constant fixes from SUSE
@@ -264,13 +395,13 @@
* When keep going, don't print spurious newlines (Radek Vokál)
-2006-04-01 12:02 Christos Zoulas <christos@zoulas.com>
+2006-04-01 12:02 Christos Zoulas <christos@astron.com>
* Use calloc instead of malloc (Mike Frysinger)
* Fix configure script to detect wctypes.h (Mike Frysinger)
-2006-03-02 16:06 Christos Zoulas <christos@zoulas.com>
+2006-03-02 16:06 Christos Zoulas <christos@astron.com>
* Print empty if the file is (Mike Frysinger)
@@ -278,21 +409,21 @@
* Sort magic entries by strength [experimental]
-2005-11-29 13:26 Christos Zoulas <christos@zoulas.com>
+2005-11-29 13:26 Christos Zoulas <christos@astron.com>
* Use iswprint() to convert the output string.
(Bastien Nocera)
-2005-10-31 8:54 Christos Zoulas <christos@zoulas.com>
+2005-10-31 8:54 Christos Zoulas <christos@astron.com>
* Fix regression where the core info was not completely processed
(Radek Vokál)
-2005-10-20 11:15 Christos Zoulas <christos@zoulas.com>
+2005-10-20 11:15 Christos Zoulas <christos@astron.com>
* Middle Endian magic (Diomidis Spinellis)
-2005-10-17 11:15 Christos Zoulas <christos@zoulas.com>
+2005-10-17 11:15 Christos Zoulas <christos@astron.com>
* Open with O_BINARY for CYGWIN (Corinna Vinschen)
@@ -300,39 +431,39 @@
* Look for note sections in non executables.
-2005-09-20 13:33 Christos Zoulas <christos@zoulas.com>
+2005-09-20 13:33 Christos Zoulas <christos@astron.com>
* Don't print SVR4 Style in core files multiple times
(Radek Vokál)
-2005-08-27 04:09 Christos Zoulas <christos@zoulas.com>
+2005-08-27 04:09 Christos Zoulas <christos@astron.com>
* Cygwin changes Corinna Vinschen
-2005-08-18 09:53 Christos Zoulas <christos@zoulas.com>
+2005-08-18 09:53 Christos Zoulas <christos@astron.com>
* Remove erroreous mention of /etc/magic in the file man page
This is gentoo bug 101639. (Mike Frysinger)
* Cross-compile support and detection (Mike Frysinger)
-2005-08-12 10:17 Christos Zoulas <christos@zoulas.com>
+2005-08-12 10:17 Christos Zoulas <christos@astron.com>
* Add -h flag and dereference symlinks if POSIXLY_CORRECT
is set.
-2005-07-29 13:57 Christos Zoulas <christos@zoulas.com>
+2005-07-29 13:57 Christos Zoulas <christos@astron.com>
* Avoid search and regex buffer overflows (Kelledin)
-2005-07-12 11:48 Christos Zoulas <christos@zoulas.com>
+2005-07-12 11:48 Christos Zoulas <christos@astron.com>
* Provide stub implementations for {v,}nsprintf() for older
OS's that don't have them.
* Change mbstate_t autoconf detection macro from AC_MBSTATE_T
to AC_TYPE_MBSTATE_T.
-2005-06-25 11:48 Christos Zoulas <christos@zoulas.com>
+2005-06-25 11:48 Christos Zoulas <christos@astron.com>
* Dynamically allocate the string buffers and make the
default read size 256K.
@@ -361,43 +492,43 @@
With CRLF, the line length was not computed correctly, and even
lines of length MAXLINELEN - 1 were treated as ``very long''.
-2004-12-07 14:15 Christos Zoulas <christos@zoulas.com>
+2004-12-07 14:15 Christos Zoulas <christos@astron.com>
* bzip2 needs a lot of input buffer space on some files
before it can begin uncompressing. This makes file -z
fail on some bz2 files. Fix it by giving it a copy of
the file descriptor to read as much as it wants if we
- have access to it. <christos@zoulas.com>
+ have access to it. <christos@astron.com>
-2004-11-24 12:39 Christos Zoulas <christos@zoulas.com>
+2004-11-24 12:39 Christos Zoulas <christos@astron.com>
* Stack smash fix, and ELF more conservative reading.
Jakub Bogusz <qboosh@pld-linux.org>
-2004-11-20 18:50 Christos Zoulas <christos@zoulas.com>
+2004-11-20 18:50 Christos Zoulas <christos@astron.com>
* New FreeBSD version parsing code:
Jon Noack <noackjr@alumni.rice.edu>
- * Hackish support for ucs16 strings <christos@zoulas.com>
+ * Hackish support for ucs16 strings <christos@astron.com>
-2004-11-13 03:07 Christos Zoulas <christos@zoulas.com>
+2004-11-13 03:07 Christos Zoulas <christos@astron.com>
* print the file name and line number in syntax errors.
-2004 10-12 10:50 Christos Zoulas <christos@zoulas.com>
+2004 10-12 10:50 Christos Zoulas <christos@astron.com>
* Fix stack overwriting on 0 length strings: Tim Waugh
<twaugh@redhat.com> Ned Ludd <solar@gentoo.org>
-2004-09-27 11:30 Christos Zoulas <christos@zoulas.com>
+2004-09-27 11:30 Christos Zoulas <christos@astron.com>
* Remove 3rd and 4th copyright clause; approved by Ian Darwin.
* Fix small memory leaks; caught by: Tamas Sarlos
<stamas@csillag.ilab.sztaki.hu>
-2004-07-24 16:33 Christos Zoulas <christos@zoulas.com>
+2004-07-24 16:33 Christos Zoulas <christos@astron.com>
* magic.mime update Danny Milosavljevic <danny.milo@gmx.net>
@@ -407,19 +538,19 @@
* errors reading elf magic Jakub Bogusz <qboosh@pld-linux.org>
-2004-04-12 10:55 Christos Zoulas <christos@zoulas.com>
+2004-04-12 10:55 Christos Zoulas <christos@astron.com>
* make sure that magic formats match magic types during compilation
* fix broken sgi magic file
-2004-04-06 20:36 Christos Zoulas <christos@zoulas.com>
+2004-04-06 20:36 Christos Zoulas <christos@astron.com>
* detect present of mbstate_t Petter Reinholdtsen <pere@hungry.com>
* magic fixes
-2004-03-22 15:25 Christos Zoulas <christos@zoulas.com>
+2004-03-22 15:25 Christos Zoulas <christos@astron.com>
* Lots of mime fixes
(Joerg Ostertag) <ostertag@rechengilde.de>
@@ -428,7 +559,7 @@
(Edwin Groothuis) <edwin@mavetju.org>
* correct cleanup in all cases; don't just close the file.
- (Christos Zoulas) <christos@zoulas.com>
+ (Christos Zoulas) <christos@astron.com>
* add gettext message catalogue support
(Michael Piefel) <piefel@debian.org>
@@ -446,37 +577,37 @@
or name and description note sizes. Reported by
(Mikael Magnusson) <mmikael@comhem.se>
-2004-03-09 13:55 Christos Zoulas <christos@zoulas.com>
+2004-03-09 13:55 Christos Zoulas <christos@astron.com>
* Fix possible memory leak on error and add missing regfree
(Dmitry V. Levin) <ldv@altlinux.org>
-2003-12-23 12:12 Christos Zoulas <christos@zoulas.com>
+2003-12-23 12:12 Christos Zoulas <christos@astron.com>
* fix -k flag (Maciej W. Rozycki)
-2003-11-18 14:10 Christos Zoulas <christos@zoulas.com>
+2003-11-18 14:10 Christos Zoulas <christos@astron.com>
* Try to give us much info as possible on corrupt elf files.
(Willy Tarreau) <willy@w.ods.org>
* Updated python bindings (Brett Funderburg)
<brettf@deepfile.com>
-2003-11-11 15:03 Christos Zoulas <christos@zoulas.com>
+2003-11-11 15:03 Christos Zoulas <christos@astron.com>
* Include file.h first, because it includes config.h
breaks largefile test macros otherwise.
(Paul Eggert <eggert@CS.UCLA.EDU> via
Lars Hecking <lhecking@nmrc.ie>)
-2003-10-14 21:39 Christos Zoulas <christos@zoulas.com>
+2003-10-14 21:39 Christos Zoulas <christos@astron.com>
* Python bindings (Brett Funderburg) <brettf@deepfile.com>
* Don't lookup past the end of the buffer
(Chad Hanson) <chanson@tcs-sec.com>
* Add MAGIC_ERROR and api on magic_errno()
-2003-10-08 12:40 Christos Zoulas <christos@zoulas.com>
+2003-10-08 12:40 Christos Zoulas <christos@astron.com>
* handle error conditions from compile as fatal
(Antti Kantee) <pooka@netbsd.org>
@@ -486,32 +617,32 @@
* describe magic file handling
(Bryan Henderson) <bryanh@giraffe-data.com>
-2003-09-12 15:09 Christos Zoulas <christos@zoulas.com>
+2003-09-12 15:09 Christos Zoulas <christos@astron.com>
* update magic files.
* remove largefile support from file.h; it breaks things on most OS's
-2003-08-10 10:25 Christos Zoulas <christos@zoulas.com>
+2003-08-10 10:25 Christos Zoulas <christos@astron.com>
* fix unmapping'ing of mmaped files.
-2003-07-10 12:03 Christos Zoulas <christos@zoulas.com>
+2003-07-10 12:03 Christos Zoulas <christos@astron.com>
* don't exit with -1 on error; always exit 1 (Marty Leisner)
* restore utimes code.
-2003-06-10 17:03 Christos Zoulas <christos@zoulas.com>
+2003-06-10 17:03 Christos Zoulas <christos@astron.com>
* make sure we don't access uninitialized memory.
* pass lint
* #ifdef __cplusplus in magic.h
-2003-05-25 19:23 Christos Zoulas <christos@zoulas.com>
+2003-05-25 19:23 Christos Zoulas <christos@astron.com>
* rename cvs magic file to revision to deal with
case insensitive filesystems.
-2003-05-23 17:03 Christos Zoulas <christos@zoulas.com>
+2003-05-23 17:03 Christos Zoulas <christos@astron.com>
* documentation fixes from Michael Piefel <piefel@debian.org>
* magic fixes (various)
@@ -521,30 +652,30 @@
close files
Maciej W. Rozycki <macro@ds2.pg.gda.pl
-2003-04-21 20:12 Christos Zoulas <christos@zoulas.com>
+2003-04-21 20:12 Christos Zoulas <christos@astron.com>
* fix zsh magic
-2003-04-04 16:59 Christos Zoulas <christos@zoulas.com>
+2003-04-04 16:59 Christos Zoulas <christos@astron.com>
* fix operand sort order in string.
-2003-04-02 17:30 Christos Zoulas <christos@zoulas.com>
+2003-04-02 17:30 Christos Zoulas <christos@astron.com>
* cleanup namespace in magic.h
-2003-04-02 13:50 Christos Zoulas <christos@zoulas.com>
+2003-04-02 13:50 Christos Zoulas <christos@astron.com>
* Magic additions (Alex Ott)
* Fix bug that broke VPATH compilation (Peter Breitenlohner)
-2003-03-28 16:03 Christos Zoulas <christos@zoulas.com>
+2003-03-28 16:03 Christos Zoulas <christos@astron.com>
* remove packed attribute from magic struct.
* make the magic struct properly aligned.
* bump version number of compiled files to 2.
-2003-03-27 13:10 Christos Zoulas <christos@zoulas.com>
+2003-03-27 13:10 Christos Zoulas <christos@astron.com>
* separate tar detection and run it before softmagic.
* fix reversed symlink test.
@@ -552,7 +683,7 @@
* make separator a string instead of a char.
* update manual page and sort options.
-2003-03-26 11:00 Christos Zoulas <christos@zoulas.com>
+2003-03-26 11:00 Christos Zoulas <christos@astron.com>
* Pass lint
* make NULL in magic_file mean stdin
diff --git a/contrib/file/FREEBSD-upgrade b/contrib/file/FREEBSD-upgrade
index 735c996..ee8f7a8 100644
--- a/contrib/file/FREEBSD-upgrade
+++ b/contrib/file/FREEBSD-upgrade
@@ -1,5 +1,5 @@
# ex:ts=8
-$FreeBSD$
+$FreeBSD: vendor/file/dist/contrib/file/FREEBSD-upgrade 169962 2007-05-24 21:59:38Z obrien $
Christos Zoulas `file'
originals can be found at: ftp://ftp.astron.com/pub/file/
@@ -17,14 +17,14 @@ Imported by:
rm -f missing depcomp
rm -f config.{guess,sub}
- cvs import -m "Virgin import of Christos Zoulas's FILE 4.23." \
- src/contrib/file ZOULAS file_4_23
+ cvs import -m "Virgin import of Christos Zoulas's FILE 4.21." \
+ src/contrib/file ZOULAS file_4_21
Never make local changes to ZOULAS `file'. Christos is very willing to
work with us to meet our FreeBSD needs. Thus submit any desired changes
to him <christos@zoulas.com> and wait for the next release and vendor
import to get them.
-
+
obrien@NUXI.com
15-Sept-2002
diff --git a/contrib/file/INSTALL b/contrib/file/INSTALL
new file mode 100644
index 0000000..5458714
--- /dev/null
+++ b/contrib/file/INSTALL
@@ -0,0 +1,234 @@
+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/file/MAINT b/contrib/file/MAINT
index 077f9d6..b881615 100644
--- a/contrib/file/MAINT
+++ b/contrib/file/MAINT
@@ -1,4 +1,4 @@
-$File: MAINT,v 1.9 2007/01/19 21:15:27 christos Exp $
+$File: MAINT,v 1.10 2008/02/05 19:08:11 christos Exp $
Maintenance notes:
@@ -41,5 +41,4 @@ ascmagic.c file_ascmagic()
readelf.c file_tryelf()
"unknown"
-Christos Zoulas
-christos@astron.com
+Christos Zoulas (see README for email address)
diff --git a/contrib/file/Magdir/adventure b/contrib/file/Magdir/adventure
index 405d3cc..7b30c49 100644
--- a/contrib/file/Magdir/adventure
+++ b/contrib/file/Magdir/adventure
@@ -73,3 +73,13 @@
>10 belong 0x0A0D1A00
>>14 string >\0 %s saved game data
+# Danny Milosavljevic <danny.milo@gmx.net>
+# this are adrift (adventure game standard) game files, extension .taf
+# depending on version magic continues with 0x93453E6139FA (V 4.0)
+# 0x9445376139FA (V 3.90)
+# 0x9445366139FA (V 3.80)
+# this is from source (http://www.adrift.org.uk/) and I have some taf
+# files, and checked them.
+#0 belong 0x3C423FC9
+#>4 belong 0x6A87C2CF Adrift game file
+#!:mime application/x-adrift
diff --git a/contrib/file/Magdir/animation b/contrib/file/Magdir/animation
index 6392f85..443338a 100644
--- a/contrib/file/Magdir/animation
+++ b/contrib/file/Magdir/animation
@@ -8,57 +8,78 @@
# SGI and Apple formats
0 string MOVI Silicon Graphics movie file
+!:mime video/x-sgi-movie
4 string moov Apple QuickTime
+!:mime video/quicktime
>12 string mvhd \b movie (fast start)
>12 string mdra \b URL
>12 string cmov \b movie (fast start, compressed header)
>12 string rmra \b multiple URLs
4 string mdat Apple QuickTime movie (unoptimized)
-4 string wide Apple QuickTime movie (unoptimized)
-4 string skip Apple QuickTime movie (modified)
-4 string free Apple QuickTime movie (modified)
+!:mime video/quicktime
+#4 string wide Apple QuickTime movie (unoptimized)
+#!:mime video/quicktime
+#4 string skip Apple QuickTime movie (modified)
+#!:mime video/quicktime
+#4 string free Apple QuickTime movie (modified)
+#!:mime video/quicktime
4 string idsc Apple QuickTime image (fast start)
-4 string idat Apple QuickTime image (unoptimized)
+!:mime image/x-quicktime
+#4 string idat Apple QuickTime image (unoptimized)
+#!:mime image/x-quicktime
4 string pckg Apple QuickTime compressed archive
+!:mime application/x-quicktime-player
4 string/B jP JPEG 2000 image
+!:mime image/jp2
4 string ftyp ISO Media
>8 string isom \b, MPEG v4 system, version 1
+!:mime video/mp4
>8 string iso2 \b, MPEG v4 system, part 12 revision
>8 string mp41 \b, MPEG v4 system, version 1
+!:mime video/mp4
>8 string mp42 \b, MPEG v4 system, version 2
+!:mime video/mp4
>8 string mp7t \b, MPEG v4 system, MPEG v7 XML
>8 string mp7b \b, MPEG v4 system, MPEG v7 binary XML
>8 string/B jp2 \b, JPEG 2000
+!:mime image/jp2
>8 string 3gp \b, MPEG v4 system, 3GPP
+!:mime video/3gpp
>>11 byte 4 \b v4 (H.263/AMR GSM 6.10)
>>11 byte 5 \b v5 (H.263/AMR GSM 6.10)
>>11 byte 6 \b v6 (ITU H.264/AMR GSM 6.10)
>8 string mmp4 \b, MPEG v4 system, 3GPP Mobile
+!:mime video/mp4
>8 string avc1 \b, MPEG v4 system, 3GPP JVT AVC
+!:mime video/3gpp
>8 string/B M4A \b, MPEG v4 system, iTunes AAC-LC
+!:mime audio/mp4
+>8 string/B M4V \b, MPEG v4 system, iTunes AVC-LC
+!:mime video/mp4
>8 string/B M4P \b, MPEG v4 system, iTunes AES encrypted
>8 string/B M4B \b, MPEG v4 system, iTunes bookmarked
>8 string/B qt \b, Apple QuickTime movie
+!:mime video/quicktime
# MPEG sequences
# Scans for all common MPEG header start codes
-0 belong 0x00000001 JVT NAL sequence
->4 byte&0x1F 0x07 \b, H.264 video
+0 belong 0x00000001
+>4 byte&0x1F 0x07 JVT NAL sequence, H.264 video
>>5 byte 66 \b, baseline
>>5 byte 77 \b, main
>>5 byte 88 \b, extended
>>7 byte x \b @ L %u
-0 belong&0xFFFFFF00 0x00000100 MPEG sequence
->3 byte 0xBA
+0 belong&0xFFFFFF00 0x00000100
+>3 byte 0xBA MPEG sequence
>>4 byte &0x40 \b, v2, program multiplex
>>4 byte ^0x40 \b, v1, system multiplex
->3 byte 0xBB \b, v1/2, multiplex (missing pack header)
->3 byte&0x1F 0x07 \b, H.264 video
+>3 byte 0xBB MPEG sequence, v1/2, multiplex (missing pack header)
+>3 byte&0x1F 0x07 MPEG sequence, H.264 video
>>4 byte 66 \b, baseline
>>4 byte 77 \b, main
>>4 byte 88 \b, extended
>>6 byte x \b @ L %u
->3 byte 0xB0 \b, v4
+>3 byte 0xB0 MPEG sequence, v4
>>5 belong 0x000001B5
>>>9 byte &0x80
>>>>10 byte&0xF0 16 \b, video
@@ -127,7 +148,7 @@
>>4 byte 251 \b, FGS @ L3
>>4 byte 252 \b, FGS @ L4
>>4 byte 253 \b, FGS @ L5
->3 byte 0xB5 \b, v4
+>3 byte 0xB5 MPEG sequence, v4
>>4 byte &0x80
>>>5 byte&0xF0 16 \b, video (missing profile header)
>>>5 byte&0xF0 32 \b, still texture (missing profile header)
@@ -137,7 +158,7 @@
>>4 byte&0xF8 16 \b, still texture (missing profile header)
>>4 byte&0xF8 24 \b, mesh (missing profile header)
>>4 byte&0xF8 32 \b, face (missing profile header)
->3 byte 0xB3
+>3 byte 0xB3 MPEG sequence
>>12 belong 0x000001B8 \b, v1, progressive Y'CbCr 4:2:0 video
>>12 belong 0x000001B2 \b, v1, progressive Y'CbCr 4:2:0 video
>>12 belong 0x000001B5 \b, v2,
@@ -252,22 +273,39 @@
# modified to fully support MPEG ADTS
# MP3, M1A
-0 beshort&0xFFFE 0xFFFA MPEG ADTS, layer III, v1
+# modified by Joerg Jenderek
+# GRR the original test are too common for many DOS files
+# so don't accept as MP3 until we've tested the rate
+0 beshort&0xFFFE 0xFFFA
# rates
->2 byte&0xF0 0x10 \b, 32 kBits
->2 byte&0xF0 0x20 \b, 40 kBits
->2 byte&0xF0 0x30 \b, 48 kBits
->2 byte&0xF0 0x40 \b, 56 kBits
->2 byte&0xF0 0x50 \b, 64 kBits
->2 byte&0xF0 0x60 \b, 80 kBits
->2 byte&0xF0 0x70 \b, 96 kBits
->2 byte&0xF0 0x80 \b, 112 kBits
->2 byte&0xF0 0x90 \b, 128 kBits
->2 byte&0xF0 0xA0 \b, 160 kBits
->2 byte&0xF0 0xB0 \b, 192 kBits
->2 byte&0xF0 0xC0 \b, 224 kBits
->2 byte&0xF0 0xD0 \b, 256 kBits
->2 byte&0xF0 0xE0 \b, 320 kBits
+>2 byte&0xF0 0x10 MPEG ADTS, layer III, v1, 32 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x20 MPEG ADTS, layer III, v1, 40 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x30 MPEG ADTS, layer III, v1, 48 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x40 MPEG ADTS, layer III, v1, 56 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x50 MPEG ADTS, layer III, v1, 64 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x60 MPEG ADTS, layer III, v1, 80 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x70 MPEG ADTS, layer III, v1, 96 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x80 MPEG ADTS, layer III, v1, 112 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0x90 MPEG ADTS, layer III, v1, 128 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0xA0 MPEG ADTS, layer III, v1, 160 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0xB0 MPEG ADTS, layer III, v1, 192 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0xC0 MPEG ADTS, layer III, v1, 224 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0xD0 MPEG ADTS, layer III, v1, 256 kbps
+!:mime audio/mpeg
+>2 byte&0xF0 0xE0 MPEG ADTS, layer III, v1, 320 kbps
+!:mime audio/mpeg
# timing
>2 byte&0x0C 0x00 \b, 44.1 kHz
>2 byte&0x0C 0x04 \b, 48 kHz
@@ -288,20 +326,20 @@
# MP2, M1A
0 beshort&0xFFFE 0xFFFC MPEG ADTS, layer II, v1
# rates
->2 byte&0xF0 0x10 \b, 32 kBits
->2 byte&0xF0 0x20 \b, 48 kBits
->2 byte&0xF0 0x30 \b, 56 kBits
->2 byte&0xF0 0x40 \b, 64 kBits
->2 byte&0xF0 0x50 \b, 80 kBits
->2 byte&0xF0 0x60 \b, 96 kBits
->2 byte&0xF0 0x70 \b, 112 kBits
->2 byte&0xF0 0x80 \b, 128 kBits
->2 byte&0xF0 0x90 \b, 160 kBits
->2 byte&0xF0 0xA0 \b, 192 kBits
->2 byte&0xF0 0xB0 \b, 224 kBits
->2 byte&0xF0 0xC0 \b, 256 kBits
->2 byte&0xF0 0xD0 \b, 320 kBits
->2 byte&0xF0 0xE0 \b, 384 kBits
+>2 byte&0xF0 0x10 \b, 32 kbps
+>2 byte&0xF0 0x20 \b, 48 kbps
+>2 byte&0xF0 0x30 \b, 56 kbps
+>2 byte&0xF0 0x40 \b, 64 kbps
+>2 byte&0xF0 0x50 \b, 80 kbps
+>2 byte&0xF0 0x60 \b, 96 kbps
+>2 byte&0xF0 0x70 \b, 112 kbps
+>2 byte&0xF0 0x80 \b, 128 kbps
+>2 byte&0xF0 0x90 \b, 160 kbps
+>2 byte&0xF0 0xA0 \b, 192 kbps
+>2 byte&0xF0 0xB0 \b, 224 kbps
+>2 byte&0xF0 0xC0 \b, 256 kbps
+>2 byte&0xF0 0xD0 \b, 320 kbps
+>2 byte&0xF0 0xE0 \b, 384 kbps
# timing
>2 byte&0x0C 0x00 \b, 44.1 kHz
>2 byte&0x0C 0x04 \b, 48 kHz
@@ -322,58 +360,60 @@
# MPA, M1A
# updated by Joerg Jenderek
# GRR the original test are too common for many DOS files, so test 32 <= kbits <= 448
-0 beshort&0xFFFE 0xFFFE
->2 ubyte&0xF0 >0x0F
->>2 ubyte&0xF0 <0xE1 MPEG ADTS, layer I, v1
-# rate
->>>2 byte&0xF0 0x10 \b, 32 kBits
->>>2 byte&0xF0 0x20 \b, 64 kBits
->>>2 byte&0xF0 0x30 \b, 96 kBits
->>>2 byte&0xF0 0x40 \b, 128 kBits
->>>2 byte&0xF0 0x50 \b, 160 kBits
->>>2 byte&0xF0 0x60 \b, 192 kBits
->>>2 byte&0xF0 0x70 \b, 224 kBits
->>>2 byte&0xF0 0x80 \b, 256 kBits
->>>2 byte&0xF0 0x90 \b, 288 kBits
->>>2 byte&0xF0 0xA0 \b, 320 kBits
->>>2 byte&0xF0 0xB0 \b, 352 kBits
->>>2 byte&0xF0 0xC0 \b, 384 kBits
->>>2 byte&0xF0 0xD0 \b, 416 kBits
->>>2 byte&0xF0 0xE0 \b, 448 kBits
-# timing
->>>2 byte&0x0C 0x00 \b, 44.1 kHz
->>>2 byte&0x0C 0x04 \b, 48 kHz
->>>2 byte&0x0C 0x08 \b, 32 kHz
-# channels/options
->>>3 byte&0xC0 0x00 \b, Stereo
->>>3 byte&0xC0 0x40 \b, JntStereo
->>>3 byte&0xC0 0x80 \b, 2x Monaural
->>>3 byte&0xC0 0xC0 \b, Monaural
-#>1 byte ^0x01 \b, Data Verify
-#>2 byte &0x02 \b, Packet Pad
-#>2 byte &0x01 \b, Custom Flag
-#>3 byte &0x08 \b, Copyrighted
-#>3 byte &0x04 \b, Original Source
-#>3 byte&0x03 1 \b, NR: 50/15 ms
-#>3 byte&0x03 3 \b, NR: CCIT J.17
+# GRR this test is still too general as it catches a BOM of UTF-16 files (0xFFFE)
+# FIXME: Almost all little endian UTF-16 text with BOM are clobbered by these entries
+#0 beshort&0xFFFE 0xFFFE
+#>2 ubyte&0xF0 >0x0F
+#>>2 ubyte&0xF0 <0xE1 MPEG ADTS, layer I, v1
+## rate
+#>>>2 byte&0xF0 0x10 \b, 32 kbps
+#>>>2 byte&0xF0 0x20 \b, 64 kbps
+#>>>2 byte&0xF0 0x30 \b, 96 kbps
+#>>>2 byte&0xF0 0x40 \b, 128 kbps
+#>>>2 byte&0xF0 0x50 \b, 160 kbps
+#>>>2 byte&0xF0 0x60 \b, 192 kbps
+#>>>2 byte&0xF0 0x70 \b, 224 kbps
+#>>>2 byte&0xF0 0x80 \b, 256 kbps
+#>>>2 byte&0xF0 0x90 \b, 288 kbps
+#>>>2 byte&0xF0 0xA0 \b, 320 kbps
+#>>>2 byte&0xF0 0xB0 \b, 352 kbps
+#>>>2 byte&0xF0 0xC0 \b, 384 kbps
+#>>>2 byte&0xF0 0xD0 \b, 416 kbps
+#>>>2 byte&0xF0 0xE0 \b, 448 kbps
+## timing
+#>>>2 byte&0x0C 0x00 \b, 44.1 kHz
+#>>>2 byte&0x0C 0x04 \b, 48 kHz
+#>>>2 byte&0x0C 0x08 \b, 32 kHz
+## channels/options
+#>>>3 byte&0xC0 0x00 \b, Stereo
+#>>>3 byte&0xC0 0x40 \b, JntStereo
+#>>>3 byte&0xC0 0x80 \b, 2x Monaural
+#>>>3 byte&0xC0 0xC0 \b, Monaural
+##>1 byte ^0x01 \b, Data Verify
+##>2 byte &0x02 \b, Packet Pad
+##>2 byte &0x01 \b, Custom Flag
+##>3 byte &0x08 \b, Copyrighted
+##>3 byte &0x04 \b, Original Source
+##>3 byte&0x03 1 \b, NR: 50/15 ms
+##>3 byte&0x03 3 \b, NR: CCIT J.17
# MP3, M2A
0 beshort&0xFFFE 0xFFF2 MPEG ADTS, layer III, v2
# rate
->2 byte&0xF0 0x10 \b, 8 kBits
->2 byte&0xF0 0x20 \b, 16 kBits
->2 byte&0xF0 0x30 \b, 24 kBits
->2 byte&0xF0 0x40 \b, 32 kBits
->2 byte&0xF0 0x50 \b, 40 kBits
->2 byte&0xF0 0x60 \b, 48 kBits
->2 byte&0xF0 0x70 \b, 56 kBits
->2 byte&0xF0 0x80 \b, 64 kBits
->2 byte&0xF0 0x90 \b, 80 kBits
->2 byte&0xF0 0xA0 \b, 96 kBits
->2 byte&0xF0 0xB0 \b, 112 kBits
->2 byte&0xF0 0xC0 \b, 128 kBits
->2 byte&0xF0 0xD0 \b, 144 kBits
->2 byte&0xF0 0xE0 \b, 160 kBits
+>2 byte&0xF0 0x10 \b, 8 kbps
+>2 byte&0xF0 0x20 \b, 16 kbps
+>2 byte&0xF0 0x30 \b, 24 kbps
+>2 byte&0xF0 0x40 \b, 32 kbps
+>2 byte&0xF0 0x50 \b, 40 kbps
+>2 byte&0xF0 0x60 \b, 48 kbps
+>2 byte&0xF0 0x70 \b, 56 kbps
+>2 byte&0xF0 0x80 \b, 64 kbps
+>2 byte&0xF0 0x90 \b, 80 kbps
+>2 byte&0xF0 0xA0 \b, 96 kbps
+>2 byte&0xF0 0xB0 \b, 112 kbps
+>2 byte&0xF0 0xC0 \b, 128 kbps
+>2 byte&0xF0 0xD0 \b, 144 kbps
+>2 byte&0xF0 0xE0 \b, 160 kbps
# timing
>2 byte&0x0C 0x00 \b, 22.05 kHz
>2 byte&0x0C 0x04 \b, 24 kHz
@@ -394,20 +434,20 @@
# MP2, M2A
0 beshort&0xFFFE 0xFFF4 MPEG ADTS, layer II, v2
# rate
->2 byte&0xF0 0x10 \b, 8 kBits
->2 byte&0xF0 0x20 \b, 16 kBits
->2 byte&0xF0 0x30 \b, 24 kBits
->2 byte&0xF0 0x40 \b, 32 kBits
->2 byte&0xF0 0x50 \b, 40 kBits
->2 byte&0xF0 0x60 \b, 48 kBits
->2 byte&0xF0 0x70 \b, 56 kBits
->2 byte&0xF0 0x80 \b, 64 kBits
->2 byte&0xF0 0x90 \b, 80 kBits
->2 byte&0xF0 0xA0 \b, 96 kBits
->2 byte&0xF0 0xB0 \b, 112 kBits
->2 byte&0xF0 0xC0 \b, 128 kBits
->2 byte&0xF0 0xD0 \b, 144 kBits
->2 byte&0xF0 0xE0 \b, 160 kBits
+>2 byte&0xF0 0x10 \b, 8 kbps
+>2 byte&0xF0 0x20 \b, 16 kbps
+>2 byte&0xF0 0x30 \b, 24 kbps
+>2 byte&0xF0 0x40 \b, 32 kbps
+>2 byte&0xF0 0x50 \b, 40 kbps
+>2 byte&0xF0 0x60 \b, 48 kbps
+>2 byte&0xF0 0x70 \b, 56 kbps
+>2 byte&0xF0 0x80 \b, 64 kbps
+>2 byte&0xF0 0x90 \b, 80 kbps
+>2 byte&0xF0 0xA0 \b, 96 kbps
+>2 byte&0xF0 0xB0 \b, 112 kbps
+>2 byte&0xF0 0xC0 \b, 128 kbps
+>2 byte&0xF0 0xD0 \b, 144 kbps
+>2 byte&0xF0 0xE0 \b, 160 kbps
# timing
>2 byte&0x0C 0x00 \b, 22.05 kHz
>2 byte&0x0C 0x04 \b, 24 kHz
@@ -428,20 +468,20 @@
# MPA, M2A
0 beshort&0xFFFE 0xFFF6 MPEG ADTS, layer I, v2
# rate
->2 byte&0xF0 0x10 \b, 32 kBits
->2 byte&0xF0 0x20 \b, 48 kBits
->2 byte&0xF0 0x30 \b, 56 kBits
->2 byte&0xF0 0x40 \b, 64 kBits
->2 byte&0xF0 0x50 \b, 80 kBits
->2 byte&0xF0 0x60 \b, 96 kBits
->2 byte&0xF0 0x70 \b, 112 kBits
->2 byte&0xF0 0x80 \b, 128 kBits
->2 byte&0xF0 0x90 \b, 144 kBits
->2 byte&0xF0 0xA0 \b, 160 kBits
->2 byte&0xF0 0xB0 \b, 176 kBits
->2 byte&0xF0 0xC0 \b, 192 kBits
->2 byte&0xF0 0xD0 \b, 224 kBits
->2 byte&0xF0 0xE0 \b, 256 kBits
+>2 byte&0xF0 0x10 \b, 32 kbps
+>2 byte&0xF0 0x20 \b, 48 kbps
+>2 byte&0xF0 0x30 \b, 56 kbps
+>2 byte&0xF0 0x40 \b, 64 kbps
+>2 byte&0xF0 0x50 \b, 80 kbps
+>2 byte&0xF0 0x60 \b, 96 kbps
+>2 byte&0xF0 0x70 \b, 112 kbps
+>2 byte&0xF0 0x80 \b, 128 kbps
+>2 byte&0xF0 0x90 \b, 144 kbps
+>2 byte&0xF0 0xA0 \b, 160 kbps
+>2 byte&0xF0 0xB0 \b, 176 kbps
+>2 byte&0xF0 0xC0 \b, 192 kbps
+>2 byte&0xF0 0xD0 \b, 224 kbps
+>2 byte&0xF0 0xE0 \b, 256 kbps
# timing
>2 byte&0x0C 0x00 \b, 22.05 kHz
>2 byte&0x0C 0x04 \b, 24 kHz
@@ -462,20 +502,20 @@
# MP3, M25A
0 beshort&0xFFFE 0xFFE2 MPEG ADTS, layer III, v2.5
# rate
->2 byte&0xF0 0x10 \b, 8 kBits
->2 byte&0xF0 0x20 \b, 16 kBits
->2 byte&0xF0 0x30 \b, 24 kBits
->2 byte&0xF0 0x40 \b, 32 kBits
->2 byte&0xF0 0x50 \b, 40 kBits
->2 byte&0xF0 0x60 \b, 48 kBits
->2 byte&0xF0 0x70 \b, 56 kBits
->2 byte&0xF0 0x80 \b, 64 kBits
->2 byte&0xF0 0x90 \b, 80 kBits
->2 byte&0xF0 0xA0 \b, 96 kBits
->2 byte&0xF0 0xB0 \b, 112 kBits
->2 byte&0xF0 0xC0 \b, 128 kBits
->2 byte&0xF0 0xD0 \b, 144 kBits
->2 byte&0xF0 0xE0 \b, 160 kBits
+>2 byte&0xF0 0x10 \b, 8 kbps
+>2 byte&0xF0 0x20 \b, 16 kbps
+>2 byte&0xF0 0x30 \b, 24 kbps
+>2 byte&0xF0 0x40 \b, 32 kbps
+>2 byte&0xF0 0x50 \b, 40 kbps
+>2 byte&0xF0 0x60 \b, 48 kbps
+>2 byte&0xF0 0x70 \b, 56 kbps
+>2 byte&0xF0 0x80 \b, 64 kbps
+>2 byte&0xF0 0x90 \b, 80 kbps
+>2 byte&0xF0 0xA0 \b, 96 kbps
+>2 byte&0xF0 0xB0 \b, 112 kbps
+>2 byte&0xF0 0xC0 \b, 128 kbps
+>2 byte&0xF0 0xD0 \b, 144 kbps
+>2 byte&0xF0 0xE0 \b, 160 kbps
# timing
>2 byte&0x0C 0x00 \b, 11.025 kHz
>2 byte&0x0C 0x04 \b, 12 kHz
@@ -497,6 +537,7 @@
# Stored AAC streams (instead of the MP4 format)
0 string ADIF MPEG ADIF, AAC
+!:mime audio/x-hx-aac-adif
>4 byte &0x80
>>13 byte &0x10 \b, VBR
>>13 byte ^0x10 \b, CBR
@@ -521,6 +562,7 @@
# Live or stored single AAC stream (used with MPEG-2 systems)
0 beshort&0xFFF6 0xFFF0 MPEG ADTS, AAC
+!:mime audio/x-hx-aac-adts
>1 byte &0x08 \b, v2
>1 byte ^0x08 \b, v4
# profile
@@ -557,6 +599,7 @@
# Live MPEG-4 audio streams (instead of RTP FlexMux)
0 beshort&0xFFE0 0x56E0 MPEG-4 LOAS
+!:mime audio/x-mp4a-latm
#>1 beshort&0x1FFF x \b, %u byte packet
>3 byte&0xE0 0x40
>>4 byte&0x3C 0x04 \b, single stream
@@ -570,22 +613,34 @@
>>4 byte&0x78 0x18 \b, 3 streams
>>4 byte &0x20 \b, 4 or more streams
>>4 byte &0x40 \b, 8 or more streams
-0 beshort 0x4DE1 MPEG-4 LO-EP audio stream
+# This magic isn't strong enough (matches plausible ISO-8859-1 text)
+#0 beshort 0x4DE1 MPEG-4 LO-EP audio stream
+#!:mime audio/x-mp4a-latm
+
+# Summary: FLI animation format
+# Created by: Daniel Quinlan <quinlan@yggdrasil.com>
+# Modified by (1): Abel Cheung <abelcheung@gmail.com> (avoid over-generic detection)
+4 leshort 0xAF11
+# standard FLI always has 320x200 resolution and 8 bit color
+>8 leshort 320
+>>10 leshort 200
+>>>12 leshort 8 FLI animation, 320x200x8
+!:mime video/x-fli
+>>>>6 leshort x \b, %d frames
+# frame speed is multiple of 1/70s
+>>>>16 leshort x \b, %d/70s per frame
-# FLI animation format
-4 leshort 0xAF11 FLI file
->6 leshort x - %d frames,
->8 leshort x width=%d pixels,
->10 leshort x height=%d pixels,
->12 leshort x depth=%d,
->16 leshort x ticks/frame=%d
-# FLC animation format
-4 leshort 0xAF12 FLC file
->6 leshort x - %d frames
->8 leshort x width=%d pixels,
->10 leshort x height=%d pixels,
->12 leshort x depth=%d,
->16 leshort x ticks/frame=%d
+# Summary: FLC animation format
+# Created by: Daniel Quinlan <quinlan@yggdrasil.com>
+# Modified by (1): Abel Cheung <abelcheung@gmail.com> (avoid over-generic detection)
+4 leshort 0xAF12
+# standard FLC always use 8 bit color
+>12 leshort 8 FLC animation
+!:mime video/x-flc
+>>8 leshort x \b, %d
+>>10 leshort x \bx%dx8
+>>6 uleshort x \b, %d frames
+>>16 uleshort x \b, %dms per frame
# DL animation format
# XXX - collision with most `mips' magic
@@ -599,9 +654,11 @@
# 255 (hex FF)! The DL format is really bad.
#
#0 byte 1 DL version 1, medium format (160x100, 4 images/screen)
+#!:mime video/x-unknown
#>42 byte x - %d screens,
#>43 byte x %d commands
#0 byte 2 DL version 2
+#!:mime video/x-unknown
#>1 byte 1 - large format (320x200,1 image/screen),
#>1 byte 2 - medium format (160x100,4 images/screen),
#>1 byte >2 - unknown format,
@@ -641,6 +698,7 @@
# MNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/>
0 string \x8aMNG MNG video data,
+!:mime video/x-mng
>4 belong !0x0d0a1a0a CORRUPTED,
>4 belong 0x0d0a1a0a
>>16 belong x %ld x
@@ -648,6 +706,7 @@
# JNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/>
0 string \x8bJNG JNG video data,
+!:mime video/x-jng
>4 belong !0x0d0a1a0a CORRUPTED,
>4 belong 0x0d0a1a0a
>>16 belong x %ld x
@@ -658,7 +717,16 @@
# VRML (Virtual Reality Modelling Language)
0 string/b #VRML\ V1.0\ ascii VRML 1 file
+!:mime model/vrml
0 string/b #VRML\ V2.0\ utf8 ISO/IEC 14772 VRML 97 file
+!:mime model/vrml
+
+# X3D (Extensible 3D) [http://www.web3d.org/specifications/x3d-3.0.dtd]
+# From Michel Briand <michelbriand@free.fr>
+0 string \<?xml\ version="
+!:strength +1
+>20 search/1000/cb \<!DOCTYPE\ X3D X3D (Extensible 3D) model xml text
+!:mime model/x3d
#---------------------------------------------------------------------------
# HVQM4: compressed movie format designed by Hudson for Nintendo GameCube
@@ -681,7 +749,18 @@
# From: Behan Webster <behanw@websterwood.com>
# NuppelVideo used by Mythtv (*.nuv)
-0 regex NuppelVideo|MythTVVideo MythTV NuppelVideo
+# Note: there are two identical stanzas here differing only in the
+# initial string matched. It used to be done with a regex, but we're
+# trying to get rid of those.
+0 string NuppelVideo MythTV NuppelVideo
+>12 string x v%s
+>20 lelong x (%d
+>24 lelong x \bx%d),
+>36 string P \bprogressive,
+>36 string I \binterlaced,
+>40 ledouble x \baspect:%.2f,
+>48 ledouble x \bfps:%.2f
+0 string MythTV MythTV NuppelVideo
>12 string x v%s
>20 lelong x (%d
>24 lelong x \bx%d),
@@ -689,3 +768,25 @@
>36 string I \binterlaced,
>40 ledouble x \baspect:%.2f,
>48 ledouble x \bfps:%.2f
+
+# MPEG file
+# MPEG sequences
+# FIXME: This section is from the old magic.mime file and needs integrating with the rest
+0 belong 0x000001BA
+>4 byte &0x40
+!:mime video/mp2p
+>4 byte ^0x40
+!:mime video/mpeg
+0 belong 0x000001BB
+!:mime video/mpeg
+0 belong 0x000001B0
+!:mime video/mp4v-es
+0 belong 0x000001B5
+!:mime video/mp4v-es
+0 belong 0x000001B3
+!:mime video/mpv
+0 belong&0xFF5FFF1F 0x47400010
+!:mime video/mp2t
+0 belong 0x00000001
+>4 byte&0x1F 0x07
+!:mime video/h264
diff --git a/contrib/file/Magdir/apple b/contrib/file/Magdir/apple
index 4a593ea2..669ab04 100644
--- a/contrib/file/Magdir/apple
+++ b/contrib/file/Magdir/apple
@@ -1,8 +1,7 @@
-
#------------------------------------------------------------------------------
# apple: file(1) magic for Apple file formats
#
-0 string FiLeStArTfIlEsTaRt binscii (apple ][) text
+0 search/1 FiLeStArTfIlEsTaRt binscii (apple ][) text
0 string \x0aGL Binary II (apple ][) data
0 string \x76\xff Squeezed (apple ][) data
0 string NuFile NuFile archive (apple ][) data
@@ -10,6 +9,23 @@
0 belong 0x00051600 AppleSingle encoded Macintosh file
0 belong 0x00051607 AppleDouble encoded Macintosh file
+# Type: Apple Emulator 2IMG format
+# From: Radek Vokal <rvokal@redhat.com>
+0 string 2IMG Apple ][ 2IMG Disk Image
+>4 string XGS! \b, XGS
+>4 string CTKG \b, Catakig
+>4 string ShIm \b, Sheppy's ImageMaker
+>4 string WOOF \b, Sweet 16
+>4 string B2TR \b, Bernie ][ the Rescue
+>4 string !nfc \b, ASIMOV2
+>4 string x \b, Unknown Format
+>0xc byte 00 \b, DOS 3.3 sector order
+>>0x10 byte 00 \b, Volume 254
+>>0x10 byte&0x7f x \b, Volume %u
+>0xc byte 01 \b, ProDOS sector order
+>>0x14 short x \b, %u Blocks
+>0xc byte 02 \b, NIB data
+
# magic for Newton PDA package formats
# from Ruda Moura <ruda@helllabs.org>
0 string package0 Newton package, NOS 1.x,
@@ -118,11 +134,12 @@
# Nevertheless this will manage to catch a lot of images that happen
# to have a solid-colored line at the bottom of the screen.
-8144 string \x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F Apple II image with white background
-8144 string \x55\x2A\x55\x2A\x55\x2A\x55\x2A Apple II image with purple background
-8144 string \x2A\x55\x2A\x55\x2A\x55\x2A\x55 Apple II image with green background
-8144 string \xD5\xAA\xD5\xAA\xD5\xAA\xD5\xAA Apple II image with blue background
-8144 string \xAA\xD5\xAA\xD5\xAA\xD5\xAA\xD5 Apple II image with orange background
+# GRR: Magic too weak
+#8144 string \x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F Apple II image with white background
+#8144 string \x55\x2A\x55\x2A\x55\x2A\x55\x2A Apple II image with purple background
+#8144 string \x2A\x55\x2A\x55\x2A\x55\x2A\x55 Apple II image with green background
+#8144 string \xD5\xAA\xD5\xAA\xD5\xAA\xD5\xAA Apple II image with blue background
+#8144 string \xAA\xD5\xAA\xD5\xAA\xD5\xAA\xD5 Apple II image with orange background
# Beagle Bros. Apple Mechanic fonts
diff --git a/contrib/file/Magdir/archive b/contrib/file/Magdir/archive
index 0b3a9ba..b75fac0 100644
--- a/contrib/file/Magdir/archive
+++ b/contrib/file/Magdir/archive
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# archive: file(1) magic for archive formats (see also "msdos" for self-
# extracting compressed archives)
@@ -8,7 +7,9 @@
# POSIX tar archives
257 string ustar\0 POSIX tar archive
+!:mime application/x-tar # encoding: posix
257 string ustar\040\040\0 GNU tar archive
+!:mime application/x-tar # encoding: gnu
# cpio archives
#
@@ -22,7 +23,9 @@
# are defined as "short"s; I think all the new formats are
# character-header formats and thus are strings, not numbers.
0 short 070707 cpio archive
+!:mime application/x-cpio
0 short 0143561 byte-swapped cpio archive
+!:mime application/x-cpio # encoding: swapped
0 string 070707 ASCII cpio archive (pre-SVR4 or odc)
0 string 070701 ASCII cpio archive (SVR4 with no CRC)
0 string 070702 ASCII cpio archive (SVR4 with CRC)
@@ -30,8 +33,10 @@
# Debian package (needs to go before regular portable archives)
#
0 string =!<arch>\ndebian
+!:mime application/x-debian-package
>8 string debian-split part of multipart Debian package
>8 string debian-binary Debian binary package
+>8 string !debian
>68 string >\0 (format %s)
# These next two lines do not work, because a bzip2 Debian archive
# still uses gzip for the control.tar (first in the archive). Only
@@ -49,6 +54,7 @@
0 short 0177545 old PDP-11 archive
0 long 0100554 apl workspace
0 string =<ar> archive
+!:mime application/x-archive
# MIPS archive (needs to go before regular portable archives)
#
@@ -60,7 +66,7 @@
>19 string B and an EB hash table
>22 string X -- out of date
-0 string -h- Software Tools format archive text
+0 search/1 -h- Software Tools format archive text
#
# XXX - why are there multiple <ar> thingies? Note that 0x213c6172 is
@@ -79,6 +85,7 @@
# "ar" archives?
#
0 string =!<arch> current ar archive
+!:mime application/x-archive
>8 string __.SYMDEF random library
>0 belong =65538 - pre SR9.5
>0 belong =65539 - post SR9.5
@@ -121,15 +128,24 @@
# we only test some types on basis of frequency: 0x08 (83%), 0x09 (5%),
# 0x02 (5%), 0x03 (3%), 0x04 (2%), 0x06 (2%). 0x01 collides with terminfo.
0 lelong&0x8080ffff 0x0000081a ARC archive data, dynamic LZW
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000091a ARC archive data, squashed
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000021a ARC archive data, uncompressed
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000031a ARC archive data, packed
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000041a ARC archive data, squeezed
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000061a ARC archive data, crunched
+!:mime application/x-arc
# [JW] stuff taken from idarc, obviously ARC successors:
0 lelong&0x8080ffff 0x00000a1a PAK archive data
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000141a ARC+ archive data
+!:mime application/x-arc
0 lelong&0x8080ffff 0x0000481a HYP archive data
+!:mime application/x-arc
# Acorn archive formats (Disaster prone simpleton, m91dps@ecs.ox.ac.uk)
# I can't create either SPARK or ArcFS archives so I have not tested this stuff
@@ -435,6 +451,7 @@
# ARJ archiver (jason@jarthur.Claremont.EDU)
0 leshort 0xea60 ARJ archive data
+!:mime application/x-arj
>5 byte x \b, v%d,
>8 byte &0x04 multi-volume,
>8 byte &0x10 slash-switched,
@@ -487,19 +504,32 @@
# LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu)
2 string -lh0- LHarc 1.x/ARX archive data [lh0]
+!:mime application/x-lharc
2 string -lh1- LHarc 1.x/ARX archive data [lh1]
+!:mime application/x-lharc
2 string -lz4- LHarc 1.x archive data [lz4]
+!:mime application/x-lharc
2 string -lz5- LHarc 1.x archive data [lz5]
+!:mime application/x-lharc
# [never seen any but the last; -lh4- reported in comp.compression:]
2 string -lzs- LHa/LZS archive data [lzs]
+!:mime application/x-lha
2 string -lh\40- LHa 2.x? archive data [lh ]
+!:mime application/x-lha
2 string -lhd- LHa 2.x? archive data [lhd]
+!:mime application/x-lha
2 string -lh2- LHa 2.x? archive data [lh2]
+!:mime application/x-lha
2 string -lh3- LHa 2.x? archive data [lh3]
+!:mime application/x-lha
2 string -lh4- LHa (2.x) archive data [lh4]
+!:mime application/x-lha
2 string -lh5- LHa (2.x) archive data [lh5]
+!:mime application/x-lha
2 string -lh6- LHa (2.x) archive data [lh6]
+!:mime application/x-lha
2 string -lh7- LHa (2.x)/LHark archive data [lh7]
+!:mime application/x-lha
>20 byte x - header level %d
# taken from idarc [JW]
2 string -lZ PUT archive data
@@ -508,6 +538,7 @@
# RAR archiver (Greg Roelofs, newt@uchicago.edu)
0 string Rar! RAR archive data,
+!:mime application/x-rar
>44 byte x v%0x,
>10 byte >0 flags:
>>10 byte &0x01 Archive volume,
@@ -532,17 +563,24 @@
# ZIP archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
0 string PK\003\004
>4 byte 0x00 Zip archive data
+!:mime application/zip
>4 byte 0x09 Zip archive data, at least v0.9 to extract
+!:mime application/zip
>4 byte 0x0a Zip archive data, at least v1.0 to extract
+!:mime application/zip
>4 byte 0x0b Zip archive data, at least v1.1 to extract
+!:mime application/zip
+>0x161 string WINZIP Zip archive data, WinZIP self-extracting
+!:mime application/zip
>4 byte 0x14
>>30 ubelong !0x6d696d65 Zip archive data, at least v2.0 to extract
->0x161 string WINZIP Zip archive data, WinZIP self-extracting
-
+!:mime application/zip
# OpenOffice.org / KOffice / StarOffice documents
+# Listed here because they ARE zip files
+#
# From: Abel Cheung <abel@oaka.org>
-# Listed here because they are basically zip files
+>4 byte 0x14
>>30 string mimetype
# KOffice (1.2 or above) formats
@@ -572,12 +610,14 @@
>>>>>69 byte !0x2e presentation
>>>>>69 string .template template
>>>>62 string math Math document
+>>>>62 string base Database file
# OpenDocument formats (for OpenOffice 2.x / StarOffice >= 8)
# http://lists.oasis-open.org/archives/office/200505/msg00006.html
>>>50 string vnd.oasis.opendocument. OpenDocument
>>>>73 string text
>>>>>77 byte !0x2d Text
+!:mime application/vnd.oasis.opendocument.text
>>>>>77 string -template Text Template
>>>>>77 string -web HTML Document Template
>>>>>77 string -master Master Document
@@ -596,6 +636,7 @@
# Zoo archiver
20 lelong 0xfdc4a7dc Zoo archive data
+!:mime application/x-zoo
>4 byte >48 \b, v%c.
>>6 byte >47 \b%c
>>>7 byte >47 \b%c
@@ -607,6 +648,7 @@
# Shell archives
10 string #\ This\ is\ a\ shell\ archive shell archive text
+!:mime application/octet-stream
#
# LBR. NB: May conflict with the questionable
@@ -652,6 +694,7 @@
# Felix von Leitner <felix-file@fefe.de>
0 string d8:announce BitTorrent file
+!:mime application/x-bittorrent
# Atari MSA archive - Teemu Hukkanen <tjhukkan@iki.fi>
0 beshort 0x0e0f Atari MSA archive data
@@ -709,6 +752,7 @@
# EET archive
# From: Tilman Sauerbeck <tilman@code-monkey.de>
0 belong 0x1ee7ff00 EET archive
+!:mime application/x-eet
# rzip archives
0 string RZIP rzip compressed data
@@ -729,12 +773,11 @@
# http://www.thouky.co.uk/software/psifs/sis.html
# http://developer.symbian.com/main/downloads/papers/SymbianOSv91/softwareinstallsis.pdf
8 lelong 0x10000419 Symbian installation file
+!:mime application/vnd.symbian.install
>4 lelong 0x1000006D (EPOC release 3/4/5)
>4 lelong 0x10003A12 (EPOC release 6)
0 lelong 0x10201A7A Symbian installation file (Symbian OS 9.x)
-
-# Pack200 Java archives, http://jcp.org/en/jsr/detail?id=200
-0 belong 0xcafed00d Pack200 Java archive
+!:mime x-epoc/x-sisx-app
# From "Nelson A. de Oliveira" <naoliv@gmail.com>
0 string MPQ\032 MoPaQ (MPQ) archive
@@ -748,3 +791,15 @@
# .kgb
0 string KGB_arch KGB Archiver file
>10 string x with compression level %.1s
+
+# xar (eXtensible ARchiver) archive
+# From: "David Remahl" <dremahl@apple.com>
+0 string xar! xar archive
+#>4 beshort x header size %d
+>6 beshort x version %d,
+#>8 quad x compressed TOC: %d,
+#>16 quad x uncompressed TOC: %d,
+>24 belong 0 no checksum
+>24 belong 1 SHA-1 checksum
+>24 belong 2 MD5 checksum
+
diff --git a/contrib/file/Magdir/audio b/contrib/file/Magdir/audio
index 511da1d..3a9c176 100644
--- a/contrib/file/Magdir/audio
+++ b/contrib/file/Magdir/audio
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# audio: file(1) magic for sound formats (see also "iff")
#
@@ -9,12 +8,19 @@
# Sun/NeXT audio data
0 string .snd Sun/NeXT audio data:
>12 belong 1 8-bit ISDN mu-law,
+!:mime audio/basic
>12 belong 2 8-bit linear PCM [REF-PCM],
+!:mime audio/basic
>12 belong 3 16-bit linear PCM,
+!:mime audio/basic
>12 belong 4 24-bit linear PCM,
+!:mime audio/basic
>12 belong 5 32-bit linear PCM,
+!:mime audio/basic
>12 belong 6 32-bit IEEE floating point,
+!:mime audio/basic
>12 belong 7 64-bit IEEE floating point,
+!:mime audio/basic
>12 belong 8 Fragmented sample data,
>12 belong 10 DSP program,
>12 belong 11 8-bit fixed point,
@@ -26,6 +32,7 @@
>12 belong 20 16-bit linear with emphasis and compression,
>12 belong 21 Music kit DSP commands,
>12 belong 23 8-bit ISDN mu-law compressed (CCITT G.721 ADPCM voice enc.),
+!:mime audio/x-adpcm
>12 belong 24 compressed (8-bit CCITT G.722 ADPCM)
>12 belong 25 compressed (3-bit CCITT G.723.3 ADPCM),
>12 belong 26 compressed (5-bit CCITT G.723.5 ADPCM),
@@ -39,12 +46,19 @@
# that uses little-endian encoding and has a different magic number
0 lelong 0x0064732E DEC audio data:
>12 lelong 1 8-bit ISDN mu-law,
+!:mime audio/x-dec-basic
>12 lelong 2 8-bit linear PCM [REF-PCM],
+!:mime audio/x-dec-basic
>12 lelong 3 16-bit linear PCM,
+!:mime audio/x-dec-basic
>12 lelong 4 24-bit linear PCM,
+!:mime audio/x-dec-basic
>12 lelong 5 32-bit linear PCM,
+!:mime audio/x-dec-basic
>12 lelong 6 32-bit IEEE floating point,
+!:mime audio/x-dec-basic
>12 lelong 7 64-bit IEEE floating point,
+!:mime audio/x-dec-basic
>12 belong 8 Fragmented sample data,
>12 belong 10 DSP program,
>12 belong 11 8-bit fixed point,
@@ -56,6 +70,7 @@
>12 belong 20 16-bit linear with emphasis and compression,
>12 belong 21 Music kit DSP commands,
>12 lelong 23 8-bit ISDN mu-law compressed (CCITT G.721 ADPCM voice enc.),
+!:mime audio/x-dec-basic
>12 belong 24 compressed (8-bit CCITT G.722 ADPCM)
>12 belong 25 compressed (3-bit CCITT G.723.3 ADPCM),
>12 belong 26 compressed (5-bit CCITT G.723.5 ADPCM),
@@ -67,6 +82,7 @@
# Creative Labs AUDIO stuff
0 string MThd Standard MIDI data
+!:mime audio/midi
>8 beshort x (format %d)
>10 beshort x using %d track
>10 beshort >1 \bs
@@ -74,8 +90,11 @@
>12 beshort&0x8000 >0 SMPTE
0 string CTMF Creative Music (CMF) data
+!:mime audio/x-unknown
0 string SBI SoundBlaster instrument data
+!:mime audio/x-unknown
0 string Creative\ Voice\ File Creative Labs voice data
+!:mime audio/x-unknown
# is this next line right? it came this way...
>19 byte 0x1A
>23 byte >0 - version %d
@@ -96,7 +115,13 @@
# Real Audio (Magic .ra\0375)
0 belong 0x2e7261fd RealAudio sound file
+!:mime audio/x-pn-realaudio
0 string .RMF RealMedia file
+!:mime application/vnd.rn-realmedia
+#video/x-pn-realvideo
+#video/vnd.rn-realvideo
+#application/vnd.rn-realmedia
+# sigh, there are many mimes for that but the above are the most common.
# MTM/669/FAR/S3M/ULT/XM format checking [Aaron Eppert, aeppert@dialin.ind.net]
# Oct 31, 1995
@@ -119,44 +144,84 @@
0 string GF1PATCH110\0ID#000002\0 GUS patch
0 string GF1PATCH100\0ID#000002\0 Old GUS patch
+# mime types according to http://www.geocities.com/nevilo/mod.htm:
+# audio/it .it
+# audio/x-zipped-it .itz
+# audio/xm fasttracker modules
+# audio/x-s3m screamtracker modules
+# audio/s3m screamtracker modules
+# audio/x-zipped-mod mdz
+# audio/mod mod
+# audio/x-mod All modules (mod, s3m, 669, mtm, med, xm, it, mdz, stm, itz, xmz, s3z)
+
#
# Taken from loader code from mikmod version 2.14
# by Steve McIntyre (stevem@chiark.greenend.org.uk)
# <doj@cubic.org> added title printing on 2003-06-24
0 string MAS_UTrack_V00
>14 string >/0 ultratracker V1.%.1s module sound data
+!:mime audio/x-mod
+#audio/x-tracker-module
0 string UN05 MikMod UNI format module sound data
0 string Extended\ Module: Fasttracker II module sound data
+!:mime audio/x-mod
+#audio/x-tracker-module
>17 string >\0 Title: "%s"
21 string/c =!SCREAM! Screamtracker 2 module sound data
+!:mime audio/x-mod
+#audio/x-screamtracker-module
21 string BMOD2STM Screamtracker 2 module sound data
+!:mime audio/x-mod
+#audio/x-screamtracker-module
1080 string M.K. 4-channel Protracker module sound data
+!:mime audio/x-mod
+#audio/x-protracker-module
>0 string >\0 Title: "%s"
1080 string M!K! 4-channel Protracker module sound data
+!:mime audio/x-mod
+#audio/x-protracker-module
>0 string >\0 Title: "%s"
1080 string FLT4 4-channel Startracker module sound data
+!:mime audio/x-mod
+#audio/x-startracker-module
>0 string >\0 Title: "%s"
1080 string FLT8 8-channel Startracker module sound data
+!:mime audio/x-mod
+#audio/x-startracker-module
>0 string >\0 Title: "%s"
1080 string 4CHN 4-channel Fasttracker module sound data
+!:mime audio/x-mod
+#audio/x-fasttracker-module
>0 string >\0 Title: "%s"
1080 string 6CHN 6-channel Fasttracker module sound data
+!:mime audio/x-mod
+#audio/x-fasttracker-module
>0 string >\0 Title: "%s"
1080 string 8CHN 8-channel Fasttracker module sound data
+!:mime audio/x-mod
+#audio/x-fasttracker-module
>0 string >\0 Title: "%s"
1080 string CD81 8-channel Octalyser module sound data
+!:mime audio/x-mod
+#audio/x-octalysertracker-module
>0 string >\0 Title: "%s"
-1080 string OKTA 8-channel Oktalyzer module sound data
+1080 string OKTA 8-channel Octalyzer module sound data
+!:mime audio/x-mod
+#audio/x-octalysertracker-module
>0 string >\0 Title: "%s"
# Not good enough.
#1082 string CH
#>1080 string >/0 %.2s-channel Fasttracker "oktalyzer" module sound data
1080 string 16CN 16-channel Taketracker module sound data
+!:mime audio/x-mod
+#audio/x-taketracker-module
>0 string >\0 Title: "%s"
1080 string 32CN 32-channel Taketracker module sound data
+!:mime audio/x-mod
+#audio/x-taketracker-module
>0 string >\0 Title: "%s"
# TOC sound files -Trevor Johnson <trevor@jpj.net>
@@ -208,7 +273,7 @@
>22 belong&0x00ffffff x %d Hz,
>18 beshort =0 no loop,
>18 beshort =-1 loop,
->21 ubyte <=127 note %d,
+>21 ubyte <128 note %d,
>22 byte =0 replay 5.485 KHz
>22 byte =1 replay 8.084 KHz
>22 byte =2 replay 10.971 Khz
@@ -221,9 +286,11 @@
# SGI SoundTrack <mpruett@sgi.com>
0 string _SGI_SoundTrack SGI SoundTrack project file
# ID3 version 2 tags <waschk@informatik.uni-rostock.de>
-0 string ID3 Audio file with ID3 version 2
->3 ubyte <0xff \b%d.
->4 ubyte <0xff \b%d tag
+0 string ID3 Audio file with ID3 version 2.
+# ??? Normally such a file is an MP3 file, but this will give false positives
+!:mime audio/mpeg
+>3 ubyte <0xff \b%d
+#>4 ubyte <0xff \b%d tag
>2584 string fLaC \b, FLAC encoding
>>2588 byte&0x7f >0 \b, unknown version
>>2588 byte&0x7f 0 \b
@@ -270,6 +337,7 @@
# Impulse tracker module (audio/x-it)
0 string IMPM Impulse Tracker module sound data -
+!:mime audio/x-mod
>4 string >\0 "%s"
>40 leshort !0 compatible w/ITv%x
>42 leshort !0 created w/ITv%x
@@ -380,6 +448,7 @@
# Free lossless audio codec <http://flac.sourceforge.net>
# From: Przemyslaw Augustyniak <silvathraec@rpg.pl>
0 string fLaC FLAC audio bitstream data
+!:mime audio/x-flac
>4 byte&0x7f >0 \b, unknown version
>4 byte&0x7f 0 \b
# some common bits/sample values
@@ -502,9 +571,9 @@
# .preset
0 string [Equalizer\ preset] XMMS equalizer preset
# .m3u
-0 string #EXTM3U M3U playlist
+0 search/1 #EXTM3U M3U playlist text
# .pls
-0 string [playlist] PLS playlist
+0 search/1 [playlist] PLS playlist text
# licq.conf
1 string [licq] LICQ configuration file
@@ -553,9 +622,6 @@
# http://www.wx800.com/msg/download/irda/iMelody.pdf
0 string BEGIN:IMELODY iMelody Ringtone Format
-# From: Matthew Flaschen <matthew.flaschen@gatech.edu>
-0 string #EXTM3U M3U playlist text
-
# From: "Mateus Caruccio" <mateus@caruccio.com>
# guitar pro v3,4,5 from http://filext.com/file-extension/gp3
0 string \030FICHIER\ GUITAR\ PRO\ v3. Guitar Pro Ver. 3 Tablature
@@ -563,3 +629,7 @@
# From: "Leslie P. Polzer" <leslie.polzer@gmx.net>
60 string SONG SoundFX Module sound file
+# Type: Adaptive Multi-Rate Codec
+# URL: http://filext.com/detaillist.php?extdetail=AMR
+# From: Russell Coker <russell@coker.com.au>
+0 string #!AMR Adaptive Multi-Rate Codec (GSM telephony)
diff --git a/contrib/file/Magdir/c-lang b/contrib/file/Magdir/c-lang
index fd3f9aa..895e37f 100644
--- a/contrib/file/Magdir/c-lang
+++ b/contrib/file/Magdir/c-lang
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# c-lang: file(1) magic for C programs (or REXX)
#
@@ -6,11 +5,15 @@
# XPM icons (Greg Roelofs, newt@uchicago.edu)
# if you uncomment "/*" for C/REXX below, also uncomment this entry
#0 string /*\ XPM\ */ X pixmap image data
+#!:mime image/x-xpmi
+
+# 3DS (3d Studio files) Conflicts with diff output 0x3d '='
+#16 beshort 0x3d3d image/x-3ds
# this first will upset you if you're a PL/1 shop...
# in which case rm it; ascmagic will catch real C programs
-#0 string /* C or REXX program text
-#0 string // C++ program text
+#0 search/1 /* C or REXX program text
+#0 search/1 // C++ program text
# From: Mikhail Teterin <mi@aldan.algebra.com>
0 string cscope cscope reference data
@@ -20,5 +23,5 @@
# The inverted index functionality was added some time betwen
# versions 11 and 15, so look for -q if version is above 14:
>7 string >14
->>10 regex .+\ -q\ with inverted index
->10 regex .+\ -c\ text (non-compressed)
+>>10 search/100 \ -q\ with inverted index
+>10 search/100 \ -c\ text (non-compressed)
diff --git a/contrib/file/Magdir/c64 b/contrib/file/Magdir/c64
index a224b21..f8a8b76 100644
--- a/contrib/file/Magdir/c64
+++ b/contrib/file/Magdir/c64
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# c64: file(1) magic for various commodore 64 related files
#
diff --git a/contrib/file/Magdir/cafebabe b/contrib/file/Magdir/cafebabe
index 233411c..db385ea 100644
--- a/contrib/file/Magdir/cafebabe
+++ b/contrib/file/Magdir/cafebabe
@@ -12,10 +12,16 @@
# (and use as a hack). Let's not use 18, because the Mach-O people
# might add another one or two as time goes by...
#
-0 belong 0xcafebabe
->4 belong >30 compiled Java class data,
->>6 beshort x version %d.
->>4 beshort x \b%d
->4 belong 1 Mach-O fat file with 1 architecture
->4 belong >1
->>4 belong <20 Mach-O fat file with %ld architectures
+0 beshort 0xcafe
+>2 beshort 0xbabe
+!:mime application/x-java-applet
+>>2 belong >30 compiled Java class data,
+>>>6 beshort x version %d.
+>>>4 beshort x \b%d
+>>4 belong 1 Mach-O fat file with 1 architecture
+>>4 belong >1
+>>>4 belong <20 Mach-O fat file with %ld architectures
+>2 beshort 0xd00d JAR compressed with pack200,
+>>5 byte x version %d.
+>>4 byte x \b%d
+!:mime application/x-java-pack200
diff --git a/contrib/file/Magdir/cddb b/contrib/file/Magdir/cddb
index 2ea97ee..42ca416 100644
--- a/contrib/file/Magdir/cddb
+++ b/contrib/file/Magdir/cddb
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# CDDB: file(1) magic for CDDB(tm) format CD text data files
#
@@ -8,4 +7,4 @@
# CDDB-enabled CD player applications.
#
-0 string/b #\040xmcd CDDB(tm) format CD text data
+0 search/1/b #\040xmcd CDDB(tm) format CD text data
diff --git a/contrib/file/Magdir/clarion b/contrib/file/Magdir/clarion
new file mode 100644
index 0000000..5f5f6e7
--- /dev/null
+++ b/contrib/file/Magdir/clarion
@@ -0,0 +1,26 @@
+
+#------------------------------------------------------------------------------
+# clarion: file(1) magic for # Clarion Personal/Professional Developer
+# (v2 and above)
+# From: Julien Blache <jb@jblache.org>
+
+# Database files
+# signature
+0 leshort 0x3343 Clarion Developer (v2 and above) data file
+# attributes
+>2 leshort &0x0001 \b, locked
+>2 leshort &0x0004 \b, encrypted
+>2 leshort &0x0008 \b, memo file exists
+>2 leshort &0x0010 \b, compressed
+>2 leshort &0x0040 \b, read only
+# number of records
+>5 lelong x \b, %ld records
+
+# Memo files
+0 leshort 0x334d Clarion Developer (v2 and above) memo data
+
+# Key/Index files
+# No magic? :(
+
+# Help files
+0 leshort 0x49e0 Clarion Developer (v2 and above) help data
diff --git a/contrib/file/Magdir/commands b/contrib/file/Magdir/commands
index 599c190..0942802 100644
--- a/contrib/file/Magdir/commands
+++ b/contrib/file/Magdir/commands
@@ -2,41 +2,62 @@
#------------------------------------------------------------------------------
# commands: file(1) magic for various shells and interpreters
#
-0 string : shell archive or script for antique kernel text
-0 string/b #!\ /bin/sh Bourne shell script text executable
+#0 string : shell archive or script for antique kernel text
+0 string/b #!\ /bin/sh POSIX shell script text executable
+!:mime text/x-shellscript
0 string/b #!\ /bin/csh C shell script text executable
+!:mime text/x-shellscript
# korn shell magic, sent by George Wu, gwu@clyde.att.com
0 string/b #!\ /bin/ksh Korn shell script text executable
+!:mime text/x-shellscript
0 string/b #!\ /bin/tcsh Tenex C shell script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/local/tcsh Tenex C shell script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/local/bin/tcsh Tenex C shell script text executable
+!:mime text/x-shellscript
#
# zsh/ash/ae/nawk/gawk magic from cameron@cs.unsw.oz.au (Cameron Simpson)
0 string/b #!\ /bin/zsh Paul Falstad's zsh script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/bin/zsh Paul Falstad's zsh script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/local/bin/zsh Paul Falstad's zsh script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/local/bin/ash Neil Brown's ash script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/local/bin/ae Neil Brown's ae script text executable
+!:mime text/x-shellscript
0 string/b #!\ /bin/nawk new awk script text executable
+!:mime text/x-nawk
0 string/b #!\ /usr/bin/nawk new awk script text executable
+!:mime text/x-nawk
0 string/b #!\ /usr/local/bin/nawk new awk script text executable
+!:mime text/x-nawk
0 string/b #!\ /bin/gawk GNU awk script text executable
+!:mime text/x-gawk
0 string/b #!\ /usr/bin/gawk GNU awk script text executable
+!:mime text/x-gawk
0 string/b #!\ /usr/local/bin/gawk GNU awk script text executable
+!:mime text/x-gawk
#
0 string/b #!\ /bin/awk awk script text executable
+!:mime text/x-awk
0 string/b #!\ /usr/bin/awk awk script text executable
+!:mime text/x-awk
# update to distinguish from *.vcf files
# this is broken because postscript has /EBEGIN{ for example.
-#0 regex BEGIN[[:space:]]*[{] awk script text
+#0 search/Bb BEGIN { awk script text
# AT&T Bell Labs' Plan 9 shell
0 string/b #!\ /bin/rc Plan 9 rc shell script text executable
# bash shell magic, from Peter Tobias (tobias@server.et-inf.fho-emden.de)
0 string/b #!\ /bin/bash Bourne-Again shell script text executable
+!:mime text/x-shellscript
0 string/b #!\ /usr/local/bin/bash Bourne-Again shell script text executable
+!:mime text/x-shellscript
# using env
0 string #!/usr/bin/env a
@@ -46,11 +67,16 @@
# PHP scripts
# Ulf Harnhammar <ulfh@update.uu.se>
-0 string/c =<?php PHP script text
-0 string =<?\n PHP script text
-0 string =<?\r PHP script text
-0 string/b #!\ /usr/local/bin/php PHP script text executable
-0 string/b #!\ /usr/bin/php PHP script text executable
+0 search/1/c =<?php PHP script text
+!:mime text/x-php
+0 search/1 =<?\n PHP script text
+!:mime text/x-php
+0 search/1 =<?\r PHP script text
+!:mime text/x-php
+0 search/1/b #!\ /usr/local/bin/php PHP script text executable
+!:mime text/x-php
+0 search/1/b #!\ /usr/bin/php PHP script text executable
+!:mime text/x-php
0 string Zend\x00 PHP script Zend Optimizer data
diff --git a/contrib/file/Magdir/compress b/contrib/file/Magdir/compress
index e9be46b..e2e4e03 100644
--- a/contrib/file/Magdir/compress
+++ b/contrib/file/Magdir/compress
@@ -10,6 +10,7 @@
# standard unix compress
0 string \037\235 compress'd data
+!:mime application/x-compress
>2 byte&0x80 >0 block compressed
>2 byte&0x1f x %d bits
@@ -19,6 +20,7 @@
# * Produce shorter output - notably, only report compression methods
# other than 8 ("deflate", the only method defined in RFC 1952).
0 string \037\213 gzip compressed data
+!:mime application/x-gzip
>2 byte <8 \b, reserved method
>2 byte >8 \b, unknown method
>3 byte &0x01 \b, ASCII
@@ -49,23 +51,29 @@
# packed data, Huffman (minimum redundancy) codes on a byte-by-byte basis
0 string \037\036 packed data
+!:mime application/octet-stream
>2 belong >1 \b, %d characters originally
>2 belong =1 \b, %d character originally
#
# This magic number is byte-order-independent.
0 short 0x1f1f old packed data
+!:mime application/octet-stream
# XXX - why *two* entries for "compacted data", one of which is
# byte-order independent, and one of which is byte-order dependent?
#
0 short 0x1fff compacted data
+!:mime application/octet-stream
# This string is valid for SunOS (BE) and a matching "short" is listed
# in the Ultrix (LE) magic file.
0 string \377\037 compacted data
+!:mime application/octet-stream
0 short 0145405 huf output
+!:mime application/octet-stream
# bzip2
0 string BZh bzip2 compressed data
+!:mime application/x-bzip2
>3 byte >47 \b, block size = %c00k
# squeeze and crunch
@@ -102,17 +110,17 @@
# bzip a block-sorting file compressor
# by Julian Seward <sewardj@cs.man.ac.uk> and others
#
-0 string BZ bzip compressed data
->2 byte x \b, version: %c
->3 string =1 \b, compression block size 100k
->3 string =2 \b, compression block size 200k
->3 string =3 \b, compression block size 300k
->3 string =4 \b, compression block size 400k
->3 string =5 \b, compression block size 500k
->3 string =6 \b, compression block size 600k
->3 string =7 \b, compression block size 700k
->3 string =8 \b, compression block size 800k
->3 string =9 \b, compression block size 900k
+#0 string BZ bzip compressed data
+#>2 byte x \b, version: %c
+#>3 string =1 \b, compression block size 100k
+#>3 string =2 \b, compression block size 200k
+#>3 string =3 \b, compression block size 300k
+#>3 string =4 \b, compression block size 400k
+#>3 string =5 \b, compression block size 500k
+#>3 string =6 \b, compression block size 600k
+#>3 string =7 \b, compression block size 700k
+#>3 string =8 \b, compression block size 800k
+#>3 string =9 \b, compression block size 900k
# lzop from <markus.oberhumer@jk.uni-linz.ac.at>
0 string \x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a lzop compressed data
@@ -174,6 +182,13 @@
>6 byte x version %d
>7 byte x \b.%d
+# Type: LZMA
+# URL: http://www.7-zip.org/sdk.html
+# From: Robert Millan <rmh@aybabtu.com> and Reuben Thomas <rrt@sc3d.org>
+# Commented out because apparently not reliable (according to Debian
+# bug #364260)
+#0 string ]\000\000\200\000 LZMA compressed data
+
# AFX compressed files (Wolfram Kleff)
2 string -afx- AFX compressed file data
diff --git a/contrib/file/Magdir/console b/contrib/file/Magdir/console
index 775472d..2af6575 100644
--- a/contrib/file/Magdir/console
+++ b/contrib/file/Magdir/console
@@ -117,6 +117,12 @@
#
0 belong 0x37804012 V64 Nintendo 64 ROM dump
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+# Nintendo .nds
+192 string \044\377\256Qi\232 Nintendo DS Game ROM Image
+# Nintendo .gba
+0 string \056\000\000\352$\377\256Qi Nintendo Game Boy Advance ROM Image
+
#------------------------------------------------------------------------------
# msx: file(1) magic for MSX game cartridge dumps
# Too simple - MPi
@@ -246,9 +252,3 @@
>>>(0x18.l-26) lelong x CRC32 0x%08x
>>>(0x18.l-23) string x "%s"
-# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
-# .w3g
-0 string Warcraft\ III\ recorded\ game %s
-# .w3m
-0 string HM3W Warcraft III map file
-
diff --git a/contrib/file/Magdir/cracklib b/contrib/file/Magdir/cracklib
index 8f7e0d4..a1a5a27 100644
--- a/contrib/file/Magdir/cracklib
+++ b/contrib/file/Magdir/cracklib
@@ -9,5 +9,5 @@
0 belong 0x70775631 Cracklib password index, big endian
>4 belong >-1 (%i words)
# really bellong 0x0000000070775631
-4 belong 0x70775631 Cracklib password index, big endian ("64-bit")
+0 search/1 \0\0\0\0pwV1 Cracklib password index, big endian ("64-bit")
>12 belong >0 (%i words)
diff --git a/contrib/file/Magdir/ctags b/contrib/file/Magdir/ctags
index 84c5b7f..f326cf5 100644
--- a/contrib/file/Magdir/ctags
+++ b/contrib/file/Magdir/ctags
@@ -1,5 +1,4 @@
-
# ----------------------------------------------------------------------------
# ctags: file (1) magic for Exuberant Ctags files
# From: Alexander Mai <mai@migdal.ikp.physik.tu-darmstadt.de>
-0 string =!_TAG Exuberant Ctags tag file text
+0 search/1 =!_TAG Exuberant Ctags tag file text
diff --git a/contrib/file/Magdir/database b/contrib/file/Magdir/database
index 8f2fc0a..2e6ad2f 100644
--- a/contrib/file/Magdir/database
+++ b/contrib/file/Magdir/database
@@ -9,8 +9,11 @@
# Will be maintained as part of the GDBM distribution in the future.
# <downsj@teeny.org>
0 belong 0x13579ace GNU dbm 1.x or ndbm database, big endian
+!:mime application/x-gdbm
0 lelong 0x13579ace GNU dbm 1.x or ndbm database, little endian
+!:mime application/x-gdbm
0 string GDBM GNU dbm 2.x database
+!:mime application/x-gdbm
#
# Berkeley DB
#
@@ -21,6 +24,7 @@
# Hash and Btree 2.X and later databases store the metadata in host byte order.
0 long 0x00061561 Berkeley DB
+!:mime application/x-dbm
>8 belong 4321
>>4 belong >2 1.86
>>4 belong <3 1.85
@@ -107,74 +111,87 @@
#>>0x04 byte 6 non-incrementing secondary index .XGn file
#>>0x04 byte 7 secondary index .YGn file
#>>>0x04 byte 8 incrementing secondary index .XGn file
+
## XBase database files
#0 byte 0x02
#>8 leshort >0
#>>12 leshort 0 FoxBase
+#!:mime application/x-dbf
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x03
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 FoxBase+, FoxPro, dBaseIII+, dBaseIV, no memo
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x04
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 dBASE IV no memo file
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x05
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 dBASE V no memo file
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x30
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 Visual FoxPro
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x43
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 FlagShip with memo var size
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x7b
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 dBASEIV with memo
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x83
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 FoxBase+, dBaseIII+ with memo
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x8b
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 dBaseIV with memo
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0x8e
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 dBaseIV with SQL Table
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0xb3
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 FlagShip with .dbt memo
#>>>0x04 lelong 0 (no records)
#>>>0x04 lelong >0 (%ld records)
#
#0 byte 0xf5
+#!:mime application/x-dbf
#>8 leshort >0
#>>12 leshort 0 FoxPro with memo
#>>>0x04 lelong 0 (no records)
@@ -183,7 +200,8 @@
#0 leshort 0x0006 DBase 3 index file
# MS Access database
-4 string Standard\ Jet\ DB Microsoft Access Database
+4 string Standard\ Jet\ DB Microsoft Access Database
+!:mime application/x-msaccess
# TDB database from Samba et al - Martin Pool <mbp@samba.org>
0 string TDB\ file TDB database
@@ -216,7 +234,11 @@
0 string PGDMP PostgreSQL custom database dump
>5 byte x - v%d
>6 byte x \b.%d
->5 beshort <=0x100 \b-0
+>5 beshort <0x101 \b-0
>5 beshort >0x100
>>7 byte x \b-%d
+# Type: Advanced Data Format (ADF) database
+# URL: http://www.grc.nasa.gov/WWW/cgns/adf/
+# From: Nicolas Chauvat <nicolas.chauvat@logilab.fr>
+0 string @(#)ADF\ Database CGNS Advanced Data Format
diff --git a/contrib/file/Magdir/diff b/contrib/file/Magdir/diff
index 187e892..291bae6 100644
--- a/contrib/file/Magdir/diff
+++ b/contrib/file/Magdir/diff
@@ -1,10 +1,14 @@
-
#------------------------------------------------------------------------------
# diff: file(1) magic for diff(1) output
#
-0 string diff\ 'diff' output text
-0 string ***\ 'diff' output text
-0 string Only\ in\ 'diff' output text
-0 string Common\ subdirectories:\ 'diff' output text
+0 search/1 diff\ diff output text
+!:mime text/x-diff
+0 search/1 ***\ diff output text
+!:mime text/x-diff
+0 search/1 Only\ in\ diff output text
+!:mime text/x-diff
+0 search/1 Common\ subdirectories:\ diff output text
+!:mime text/x-diff
-0 string Index: RCS/CVS diff output text
+0 search/1 Index: RCS/CVS diff output text
+!:mime text/x-diff
diff --git a/contrib/file/Magdir/dump b/contrib/file/Magdir/dump
index addd954..cef191a 100644
--- a/contrib/file/Magdir/dump
+++ b/contrib/file/Magdir/dump
@@ -91,3 +91,41 @@
>0 leshort 5 end of volume.
>0 leshort 6 map of inodes deleted.
>0 leshort 7 end of medium (for floppy).
+
+24 belong 0x19540119 new-fs dump file (ufs2, big endian),
+>896 beqdate x Previous dump %s,
+>904 beqdate x This dump %s,
+>12 belong >0 Volume %ld,
+>692 belong 0 Level zero, type:
+>692 belong >0 Level %d, type:
+>0 belong 1 tape header,
+>0 belong 2 beginning of file record,
+>0 belong 3 map of inodes on tape,
+>0 belong 4 continuation of file record,
+>0 belong 5 end of volume,
+>0 belong 6 map of inodes deleted,
+>0 belong 7 end of medium (for floppy),
+>676 string >\0 Label %s,
+>696 string >\0 Filesystem %s,
+>760 string >\0 Device %s,
+>824 string >\0 Host %s,
+>888 belong >0 Flags %x
+
+24 lelong 0x19540119 new-fs dump file (ufs2, little endian),
+>896 leqdate x This dump %s,
+>904 leqdate x Previous dump %s,
+>12 lelong >0 Volume %ld,
+>692 lelong 0 Level zero, type:
+>692 lelong >0 Level %d, type:
+>0 lelong 1 tape header,
+>0 lelong 2 beginning of file record,
+>0 lelong 3 map of inodes on tape,
+>0 lelong 4 continuation of file record,
+>0 lelong 5 end of volume,
+>0 lelong 6 map of inodes deleted,
+>0 lelong 7 end of medium (for floppy),
+>676 string >\0 Label %s,
+>696 string >\0 Filesystem %s,
+>760 string >\0 Device %s,
+>824 string >\0 Host %s,
+>888 lelong >0 Flags %x
diff --git a/contrib/file/Magdir/elf b/contrib/file/Magdir/elf
index 464b436..891e2ad 100644
--- a/contrib/file/Magdir/elf
+++ b/contrib/file/Magdir/elf
@@ -7,7 +7,12 @@
#
# What're the correct byte orders for the nCUBE and the Fujitsu VPP500?
#
-# updated by Daniel Quinlan (quinlan@yggdrasil.com)
+# Created by: unknown
+# Modified by (1): Daniel Quinlan <quinlan@yggdrasil.com>
+# Modified by (2): Peter Tobias <tobias@server.et-inf.fho-emden.de> (core support)
+# Modified by (3): Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de> (fix of core support)
+# Modified by (4): <gerardo.cacciari@gmail.com> (VMS Itanium)
+# Modified by (5): Matthias Urlichs <smurf@debian.org> (Listing of many architectures)
0 string \177ELF ELF
>4 byte 0 invalid class
>4 byte 1 32-bit
@@ -15,12 +20,16 @@
>5 byte 0 invalid byte order
>5 byte 1 LSB
>>16 leshort 0 no file type,
+!:strength *2
+!:mime application/octet-stream
>>16 leshort 1 relocatable,
+!:mime application/x-object
>>16 leshort 2 executable,
+!:mime application/x-executable
>>16 leshort 3 shared object,
-# Core handling from Peter Tobias <tobias@server.et-inf.fho-emden.de>
-# corrections by Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de>
+!:mime application/x-sharedlib
>>16 leshort 4 core file
+!:mime application/x-coredump
# Core file detection is not reliable.
#>>>(0x38+0xcc) string >\0 of '%s'
#>>>(0x38+0x10) lelong >0 (signal %d),
@@ -74,7 +83,7 @@
>>>48 leshort &0x0008 (LP64),
>>18 leshort 16 nCUBE,
>>18 leshort 17 Fujitsu VPP500,
->>18 leshort 18 SPARC32PLUS,
+>>18 leshort 18 SPARC32PLUS - invalid byte order,
>>18 leshort 20 PowerPC,
>>18 leshort 22 IBM S/390,
>>18 leshort 36 NEC V800,
@@ -96,9 +105,46 @@
>>18 leshort 51 Stanford MIPS-X,
>>18 leshort 52 Motorola Coldfire,
>>18 leshort 53 Motorola M68HC12,
+>>18 leshort 54 Fujitsu MMA,
+>>18 leshort 55 Siemens PCP,
+>>18 leshort 56 Sony nCPU,
+>>18 leshort 57 Denso NDR1,
+>>18 leshort 58 Start*Core,
+>>18 leshort 59 Toyota ME16,
+>>18 leshort 60 ST100,
+>>18 leshort 61 Tinyj emb.,
>>18 leshort 62 x86-64,
+>>18 leshort 63 Sony DSP,
+>>18 leshort 66 FX66,
+>>18 leshort 67 ST9+ 8/16 bit,
+>>18 leshort 68 ST7 8 bit,
+>>18 leshort 69 MC68HC16,
+>>18 leshort 70 MC68HC11,
+>>18 leshort 71 MC68HC08,
+>>18 leshort 72 MC68HC05,
+>>18 leshort 73 SGI SVx,
+>>18 leshort 74 ST19 8 bit,
>>18 leshort 75 Digital VAX,
+>>18 leshort 76 Axis cris,
+>>18 leshort 77 Infineon 32-bit embedded,
+>>18 leshort 78 Element 14 64-bit DSP,
+>>18 leshort 79 LSI Logic 16-bit DSP,
+>>18 leshort 80 MMIX,
+>>18 leshort 81 Harvard machine-independent,
+>>18 leshort 82 SiTera Prism,
+>>18 leshort 83 Atmel AVR 8-bit,
+>>18 leshort 84 Fujitsu FR30,
+>>18 leshort 85 Mitsubishi D10V,
+>>18 leshort 86 Mitsubishi D30V,
+>>18 leshort 87 NEC v850,
>>18 leshort 88 Renesas M32R,
+>>18 leshort 89 Matsushita MN10300,
+>>18 leshort 90 Matsushita MN10200,
+>>18 leshort 91 picoJava,
+>>18 leshort 92 OpenRISC,
+>>18 leshort 93 ARC Cores Tangent-A5,
+>>18 leshort 0x3426 OpenRISC (obsolete),
+>>18 leshort 0x8472 OpenRISC (obsolete),
>>18 leshort 94 Tensilica Xtensa,
>>18 leshort 97 NatSemi 32k,
>>18 leshort 106 Analog Devices Blackfin,
@@ -108,10 +154,15 @@
>>36 lelong 1 MathCoPro/FPU/MAU Required
>5 byte 2 MSB
>>16 beshort 0 no file type,
+!:mime application/octet-stream
>>16 beshort 1 relocatable,
+!:mime application/x-object
>>16 beshort 2 executable,
+!:mime application/x-executable
>>16 beshort 3 shared object,
+!:mime application/x-sharedlib
>>16 beshort 4 core file,
+!:mime application/x-coredump
#>>>(0x38+0xcc) string >\0 of '%s'
#>>>(0x38+0x10) belong >0 (signal %d),
>>16 beshort &0xff00 processor-specific,
@@ -163,10 +214,10 @@
>>18 beshort 16 nCUBE,
>>18 beshort 17 Fujitsu VPP500,
>>18 beshort 18 SPARC32PLUS,
->>>36 belong&0xffff00 &0x000100 V8+ Required,
->>>36 belong&0xffff00 &0x000200 Sun UltraSPARC1 Extensions Required,
->>>36 belong&0xffff00 &0x000400 HaL R1 Extensions Required,
->>>36 belong&0xffff00 &0x000800 Sun UltraSPARC3 Extensions Required,
+>>>36 belong&0xffff00 0x000100 V8+ Required,
+>>>36 belong&0xffff00 0x000200 Sun UltraSPARC1 Extensions Required,
+>>>36 belong&0xffff00 0x000400 HaL R1 Extensions Required,
+>>>36 belong&0xffff00 0x000800 Sun UltraSPARC3 Extensions Required,
>>18 beshort 20 PowerPC or cisco 4500,
>>18 beshort 21 64-bit PowerPC or cisco 7500,
>>18 beshort 22 IBM S/390,
@@ -181,6 +232,12 @@
>>18 beshort 41 Alpha,
>>18 beshort 42 Renesas SH,
>>18 beshort 43 SPARC V9,
+>>>48 belong&0xffff00 0x000200 Sun UltraSPARC1 Extensions Required,
+>>>48 belong&0xffff00 0x000400 HaL R1 Extensions Required,
+>>>48 belong&0xffff00 0x000800 Sun UltraSPARC3 Extensions Required,
+>>>48 belong&0x3 0 total store ordering,
+>>>48 belong&0x3 1 partial store ordering,
+>>>48 belong&0x3 2 relaxed memory ordering,
>>18 beshort 44 Siemens Tricore Embedded Processor,
>>18 beshort 45 Argonaut RISC Core, Argonaut Technologies Inc.,
>>18 beshort 46 Renesas H8/300,
@@ -194,6 +251,9 @@
>>18 beshort 73 Cray NV1,
>>18 beshort 75 Digital VAX,
>>18 beshort 88 Renesas M32R,
+>>18 leshort 92 OpenRISC,
+>>18 leshort 0x3426 OpenRISC (obsolete),
+>>18 leshort 0x8472 OpenRISC (obsolete),
>>18 beshort 94 Tensilica Xtensa,
>>18 beshort 97 NatSemi 32k,
>>18 beshort 0x18ad AVR32 (unofficial),
@@ -220,7 +280,6 @@
>>7 byte 10 (Tru64)
>>7 byte 11 (Novell Modesto)
>>7 byte 12 (OpenBSD)
-# VMS Itanium added by gerardo.cacciari@gmail.com
>8 string \2
>>7 byte 13 (OpenVMS)
>>7 byte 97 (ARM)
diff --git a/contrib/file/Magdir/erlang b/contrib/file/Magdir/erlang
new file mode 100644
index 0000000..59f55ec
--- /dev/null
+++ b/contrib/file/Magdir/erlang
@@ -0,0 +1,18 @@
+
+#------------------------------------------------------------------------------
+# erlang: file(1) magic for Erlang JAM and BEAM files
+# URL: http://www.erlang.org/faq/x779.html#AEN812
+
+# OTP R3-R4
+0 string \0177BEAM! Old Erlang BEAM file
+>6 short >0 - version %d
+
+# OTP R5 and onwards
+0 string FOR1
+>8 string BEAM Erlang BEAM file
+
+# 4.2 version may have a copyright notice!
+4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
+79 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
+
+4 string 1.0 Fri Feb 3 09:55:56 MET 1995 Erlang JAM file - version 4.3
diff --git a/contrib/file/Magdir/filesystems b/contrib/file/Magdir/filesystems
index 20b257b..36c2f72 100644
--- a/contrib/file/Magdir/filesystems
+++ b/contrib/file/Magdir/filesystems
@@ -833,7 +833,7 @@
# Minix filesystems - Juan Cespedes <cespedes@debian.org>
0x410 leshort 0x137f Minix filesystem
-0x410 beshort 0x137f Minix filesystem (big endian),
+0x410 beshort 0x137f Minix filesystem (big endian)
>0x402 beshort !0 \b, %d zones
>0x1e string minix \b, bootable
0x410 leshort 0x138f Minix filesystem, 30 char names
@@ -1025,19 +1025,42 @@
>&-1248 belong 0 TIME optimization
>&-1248 belong 1 SPACE optimization
-# ext2/ext3 filesystems - Andreas Dilger <adilger@turbolabs.com>
-0x438 leshort 0xEF53 Linux
->0x44c lelong x rev %d
->0x43e leshort x \b.%d
->0x45c lelong ^0x0000004 ext2 filesystem data
->>0x43a leshort ^0x0000001 (mounted or unclean)
->0x45c lelong &0x0000004 ext3 filesystem data
->>0x460 lelong &0x0000004 (needs journal recovery)
->0x43a leshort &0x0000002 (errors)
->0x460 lelong &0x0000001 (compressed)
-#>0x460 lelong &0x0000002 (filetype)
-#>0x464 lelong &0x0000001 (sparse_super)
->0x464 lelong &0x0000002 (large files)
+# ext2/ext3 filesystems - Andreas Dilger <adilger@dilger.ca>
+# ext4 filesystem - Eric Sandeen <sandeen@sandeen.net>
+0x438 leshort 0xEF53 Linux
+>0x44c lelong x rev %d
+>0x43e leshort x \b.%d
+# No journal? ext2
+>0x45c lelong ^0x0000004 ext2 filesystem data
+>>0x43a leshort ^0x0000001 (mounted or unclean)
+# Has a journal? ext3 or ext4
+>0x45c lelong &0x0000004
+# and small INCOMPAT?
+>>0x460 lelong <0x0000040
+# and small RO_COMPAT?
+>>>0x464 lelong <0x0000008 ext3 filesystem data
+# else large RO_COMPAT?
+>>>0x464 lelong >0x0000007 ext4 filesystem data
+# else large INCOMPAT?
+>>0x460 lelong >0x000003f ext4 filesystem data
+# General flags for any ext* fs
+>0x460 lelong &0x0000004 (needs journal recovery)
+>0x43a leshort &0x0000002 (errors)
+# INCOMPAT flags
+>0x460 lelong &0x0000001 (compressed)
+#>0x460 lelong &0x0000002 (filetype)
+#>0x460 lelong &0x0000010 (meta bg)
+>0x460 lelong &0x0000040 (extents)
+>0x460 lelong &0x0000080 (64bit)
+#>0x460 lelong &0x0000100 (mmp)
+#>0x460 lelong &0x0000200 (flex bg)
+# RO_INCOMPAT flags
+#>0x464 lelong &0x0000001 (sparse super)
+>0x464 lelong &0x0000002 (large files)
+>0x464 lelong &0x0000008 (huge files)
+#>0x464 lelong &0x0000010 (gdt checksum)
+#>0x464 lelong &0x0000020 (many subdirs)
+#>0x463 lelong &0x0000040 (extra isize)
# SGI disk labels - Nathan Scott <nathans@debian.org>
0 belong 0x0BE5A941 SGI disk label (volume header)
@@ -1115,40 +1138,42 @@
# CDROM Filesystems
# Modified for UDF by gerardo.cacciari@gmail.com
-32769 string CD001
->38913 string !NSR0 ISO 9660 CD-ROM filesystem data
->38913 string NSR0 UDF filesystem data
->>38917 string 1 (version 1.0)
->>38917 string 2 (version 1.5)
->>38917 string 3 (version 2.0)
->>38917 byte >0x33 (unknown version, ID 0x%X)
->>38917 byte <0x31 (unknown version, ID 0x%X)
+32769 string CD001
+!:mime application/x-iso9660-image
+>38913 string !NSR0 ISO 9660 CD-ROM filesystem data
+>38913 string NSR0 UDF filesystem data
+>>38917 string 1 (version 1.0)
+>>38917 string 2 (version 1.5)
+>>38917 string 3 (version 2.0)
+>>38917 byte >0x33 (unknown version, ID 0x%X)
+>>38917 byte <0x31 (unknown version, ID 0x%X)
# "application id" which appears to be used as a volume label
->32808 string >\0 '%s'
->34816 string \000CD001\001EL\ TORITO\ SPECIFICATION (bootable)
-37633 string CD001 ISO 9660 CD-ROM filesystem data (raw 2352 byte sectors)
-32776 string CDROM High Sierra CD-ROM filesystem data
+>32808 string >\0 '%s'
+>34816 string \000CD001\001EL\ TORITO\ SPECIFICATION (bootable)
+37633 string CD001 ISO 9660 CD-ROM filesystem data (raw 2352 byte sectors)
+!:mime application/x-iso9660-image
+32776 string CDROM High Sierra CD-ROM filesystem data
# cramfs filesystem - russell@coker.com.au
0 lelong 0x28cd3d45 Linux Compressed ROM File System data, little endian
->4 lelong x size %d
+>4 lelong x size %lu
>8 lelong &1 version #2
>8 lelong &2 sorted_dirs
>8 lelong &4 hole_support
>32 lelong x CRC 0x%x,
->36 lelong x edition %d,
->40 lelong x %d blocks,
->44 lelong x %d files
+>36 lelong x edition %lu,
+>40 lelong x %lu blocks,
+>44 lelong x %lu files
0 belong 0x28cd3d45 Linux Compressed ROM File System data, big endian
->4 belong x size %d
+>4 belong x size %lu
>8 belong &1 version #2
>8 belong &2 sorted_dirs
>8 belong &4 hole_support
>32 belong x CRC 0x%x,
->36 belong x edition %d,
->40 belong x %d blocks,
->44 belong x %d files
+>36 belong x edition %lu,
+>40 belong x %lu blocks,
+>44 belong x %lu files
# reiserfs - russell@coker.com.au
0x10034 string ReIsErFs ReiserFS V3.5
@@ -1241,6 +1266,34 @@
>>>2 short 2048 AXP generated)
>>>2 short 4096 I64 generated)
+# Summary: Oracle Clustered Filesystem
+# Created by: Aaron Botsis <redhat@digitalmafia.org>
+8 string OracleCFS Oracle Clustered Filesystem,
+>4 long x rev %d
+>0 long x \b.%d,
+>560 string x label: %.64s,
+>136 string x mountpoint: %.128s
+
+# Summary: Oracle ASM tagged volume
+# Created by: Aaron Botsis <redhat@digitalmafia.org>
+32 string ORCLDISK Oracle ASM Volume,
+>40 string x Disk Name: %0.12s
+32 string ORCLCLRD Oracle ASM Volume (cleared),
+>40 string x Disk Name: %0.12s
+
+# Oracle Clustered Filesystem - Aaron Botsis <redhat@digitalmafia.org>
+8 string OracleCFS Oracle Clustered Filesystem,
+>4 long x rev %d
+>0 long x \b.%d,
+>560 string x label: %.64s,
+>136 string x mountpoint: %.128s
+
+# Oracle ASM tagged volume - Aaron Botsis <redhat@digitalmafia.org>
+32 string ORCLDISK Oracle ASM Volume,
+>40 string x Disk Name: %0.12s
+32 string ORCLCLRD Oracle ASM Volume (cleared),
+>40 string x Disk Name: %0.12s
+
# Compaq/HP RILOE floppy image
# From: Dirk Jagdmann <doj@cubic.org>
0 string CPQRFBLO Compaq/HP RILOE floppy image
@@ -1259,3 +1312,18 @@
# http://filext.com/file-extension/DAA
# describes the daa file format. The magic would be:
0 string DAA\x0\x0\x0\x0\x0 PowerISO Direct-Access-Archive
+
+# From Albert Cahalan <acahalan@gmail.com>
+# really le32 operation,destination,payloadsize (but quite predictable)
+# 01 00 00 00 00 00 00 c0 00 02 00 00
+0 string \1\0\0\0\0\0\0\300\0\2\0\0 Marvell Libertas firmware
+
+# From Eric Sandeen
+# GFS2
+0x10000 belong 0x01161970 GFS2 Filesystem
+>0x10024 belong x (blocksize %d,
+>0x10060 string >\0 lockproto %s)
+
+# dvdisaster's .ecc
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0 string *dvdisaster* dvdisaster error correction file
diff --git a/contrib/file/Magdir/flash b/contrib/file/Magdir/flash
index f14b460..0b985f2 100644
--- a/contrib/file/Magdir/flash
+++ b/contrib/file/Magdir/flash
@@ -8,10 +8,13 @@
#
0 string FWS Macromedia Flash data,
>3 byte x version %d
+!:mime application/x-shockwave-flash
0 string CWS Macromedia Flash data (compressed),
+!:mime application/x-shockwave-flash
>3 byte x version %d
# From: Cal Peake <cp@absolutedigital.net>
0 string FLV Macromedia Flash Video
+!:mime video/x-flv
#
# From Dave Wilson
diff --git a/contrib/file/Magdir/fonts b/contrib/file/Magdir/fonts
index cf6e0d7..a6f43e7 100644
--- a/contrib/file/Magdir/fonts
+++ b/contrib/file/Magdir/fonts
@@ -1,14 +1,13 @@
-
#------------------------------------------------------------------------------
# fonts: file(1) magic for font data
#
-0 string FONT ASCII vfont text
+0 search/1 FONT ASCII vfont text
0 short 0436 Berkeley vfont data
0 short 017001 byte-swapped Berkeley vfont data
# PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com
-0 string %!PS-AdobeFont-1. PostScript Type 1 font text
->20 string >\0 (%s)
+0 search/1 %!PS-AdobeFont-1. PostScript Type 1 font text
+>20 search/1 >\0 (%s)
6 string %!PS-AdobeFont-1. PostScript Type 1 font program data
# X11 font files in SNF (Server Natural Format) format
@@ -16,7 +15,7 @@
0 lelong 00000004 X11 SNF font data, LSB first
# X11 Bitmap Distribution Format, from Daniel Quinlan (quinlan@yggdrasil.com)
-0 string STARTFONT\040 X11 BDF font text
+0 search/1 STARTFONT\ X11 BDF font text
# X11 fonts, from Daniel Quinlan (quinlan@yggdrasil.com)
# PCF must come before SGI additions ("MIPSEL MIPS-II COFF" collides)
diff --git a/contrib/file/Magdir/fortran b/contrib/file/Magdir/fortran
index ce004ad..3e49033 100644
--- a/contrib/file/Magdir/fortran
+++ b/contrib/file/Magdir/fortran
@@ -1,2 +1,3 @@
# FORTRAN source
0 string/c c\ FORTRAN program
+!:mime text/x-fortran
diff --git a/contrib/file/Magdir/frame b/contrib/file/Magdir/frame
index 1b397df..3699b44 100644
--- a/contrib/file/Magdir/frame
+++ b/contrib/file/Magdir/frame
@@ -1,11 +1,14 @@
-
#------------------------------------------------------------------------------
# frame: file(1) magic for FrameMaker files
#
# This stuff came on a FrameMaker demo tape, most of which is
# copyright, but this file is "published" as witness the following:
#
+# Note that this is the Framemaker Maker Interchange Format, not the
+# Normal format which would be application/vnd.framemaker.
+#
0 string \<MakerFile FrameMaker document
+!:mime application/x-mif
>11 string 5.5 (5.5
>11 string 5.0 (5.0
>11 string 4.0 (4.0
@@ -14,25 +17,32 @@
>11 string 1.0 (1.0
>14 byte x %c)
0 string \<MIFFile FrameMaker MIF (ASCII) file
+!:mime application/x-mif
>9 string 4.0 (4.0)
>9 string 3.0 (3.0)
>9 string 2.0 (2.0)
>9 string 1.0 (1.x)
-0 string \<MakerDictionary FrameMaker Dictionary text
+0 search/1 \<MakerDictionary FrameMaker Dictionary text
+!:mime application/x-mif
>17 string 3.0 (3.0)
>17 string 2.0 (2.0)
>17 string 1.0 (1.x)
0 string \<MakerScreenFont FrameMaker Font file
+!:mime application/x-mif
>17 string 1.01 (%s)
0 string \<MML FrameMaker MML file
+!:mime application/x-mif
0 string \<BookFile FrameMaker Book file
+!:mime application/x-mif
>10 string 3.0 (3.0
>10 string 2.0 (2.0
>10 string 1.0 (1.0
>13 byte x %c)
# XXX - this book entry should be verified, if you find one, uncomment this
#0 string \<Book\ FrameMaker Book (ASCII) file
+#!:mime application/x-mif
#>6 string 3.0 (3.0)
#>6 string 2.0 (2.0)
#>6 string 1.0 (1.0)
0 string \<Maker Intermediate Print File FrameMaker IPL file
+!:mime application/x-mif
diff --git a/contrib/file/Magdir/freebsd b/contrib/file/Magdir/freebsd
index ee710fa..be30417 100644
--- a/contrib/file/Magdir/freebsd
+++ b/contrib/file/Magdir/freebsd
@@ -128,10 +128,10 @@
# What are you laughing about?
0 lelong 011421044151 ld.so hints file (Little Endian
>4 lelong >0 \b, version %d)
->4 belong <=0 \b)
+>4 belong <1 \b)
0 belong 011421044151 ld.so hints file (Big Endian
>4 belong >0 \b, version %d)
->4 belong <=0 \b)
+>4 belong <1 \b)
#
# Files generated by FreeBSD scrshot(1)/vidcontrol(1) utilities
diff --git a/contrib/file/Magdir/fsav b/contrib/file/Magdir/fsav
index 4d61beb..ccc6d59 100644
--- a/contrib/file/Magdir/fsav
+++ b/contrib/file/Magdir/fsav
@@ -46,7 +46,7 @@
0 string ClamAV-VDB:
>11 string >\0 Clam AntiVirus database %-.23s
>>34 string :
->>>35 regex [^:]+ \b, version
+>>>35 string !: \b, version
>>>>35 string x \b%-.1s
>>>>>36 string !:
>>>>>>36 string x \b%-.1s
@@ -54,7 +54,9 @@
>>>>>>>>37 string x \b%-.1s
>>>>>>>>>38 string !:
>>>>>>>>>>38 string x \b%-.1s
->>>>512 string \037\213 \b, gzipped
->>>>769 string ustar\0 \b, tared
>512 string \037\213 \b, gzipped
->769 string ustar\0 \b, tared
+>769 string ustar\0 \b, tarred
+
+# Type: Grisoft AVG AntiVirus
+# From: David Newgas <david@newgas.net>
+0 string AVG7_ANTIVIRUS_VAULT_FILE AVG 7 Antivirus vault file data
diff --git a/contrib/file/Magdir/games b/contrib/file/Magdir/games
index 2dc17da..32ccdfe 100644
--- a/contrib/file/Magdir/games
+++ b/contrib/file/Magdir/games
@@ -1,12 +1,6 @@
#------------------------------------------------------------------------------
# games: file(1) for games
-# Thomas M. Ott (ThMO)
-1 string =WAD DOOM data,
->0 string =I main wad
->0 string =P patch wad
->0 byte x unknown junk
-
# Fabio Bonelli <fabiobonelli@libero.it>
# Quake II - III data files
0 string IDP2 Quake II 3D Model file,
@@ -29,11 +23,6 @@
# Doom and Quake
# submitted by Nicolas Patrois
-# DOOM
-
-0 string IWAD DOOM or DOOM ][ world
-0 string PWAD DOOM or DOOM ][ extension world
-
0 string \xcb\x1dBoom\xe6\xff\x03\x01 Boom or linuxdoom demo
# some doom lmp files don't match, I've got one beginning with \x6d\x02\x01\x01
@@ -155,3 +144,102 @@
0 string MComprHD MAME CHD compressed hard disk image,
>12 belong x version %lu
+
+# doom - submitted by Jon Dowland
+
+0 string =IWAD doom main IWAD data
+>4 lelong x containing %d lumps
+0 string =PWAD doom patch PWAD data
+>4 lelong x containing %d lumps
+
+
+# Summary: Warcraft 3 save
+# Extension: .w3g
+# Created by: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0 string Warcraft\ III\ recorded\ game %s
+
+
+# Summary: Warcraft 3 map
+# Extension: .w3m
+# Created by: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0 string HM3W Warcraft III map file
+
+
+# Summary: SGF Smart Game Format
+# Extension: .sgf
+# Reference: http://www.red-bean.com/sgf/
+# Created by: Eduardo Sabbatella <eduardo_sabbatella@yahoo.com.ar>
+# Modified by (1): Abel Cheung (regex, more game format)
+# FIXME: Some games don't have GM (game type)
+0 regex \\(;.*GM\\[[0-9]{1,2}\\] Smart Game Format
+>2 search/0x200 GM[
+>>&0 string 1] (Go)
+>>&0 string 2] (Othello)
+>>&0 string 3] (chess)
+>>&0 string 4] (Gomoku+Renju)
+>>&0 string 5] (Nine Men's Morris)
+>>&0 string 6] (Backgammon)
+>>&0 string 7] (Chinese chess)
+>>&0 string 8] (Shogi)
+>>&0 string 9] (Lines of Action)
+>>&0 string 10] (Ataxx)
+>>&0 string 11] (Hex)
+>>&0 string 12] (Jungle)
+>>&0 string 13] (Neutron)
+>>&0 string 14] (Philosopher's Football)
+>>&0 string 15] (Quadrature)
+>>&0 string 16] (Trax)
+>>&0 string 17] (Tantrix)
+>>&0 string 18] (Amazons)
+>>&0 string 19] (Octi)
+>>&0 string 20] (Gess)
+>>&0 string 21] (Twixt)
+>>&0 string 22] (Zertz)
+>>&0 string 23] (Plateau)
+>>&0 string 24] (Yinsh)
+>>&0 string 25] (Punct)
+>>&0 string 26] (Gobblet)
+>>&0 string 27] (hive)
+>>&0 string 28] (Exxit)
+>>&0 string 29] (Hnefatal)
+>>&0 string 30] (Kuba)
+>>&0 string 31] (Tripples)
+>>&0 string 32] (Chase)
+>>&0 string 33] (Tumbling Down)
+>>&0 string 34] (Sahara)
+>>&0 string 35] (Byte)
+>>&0 string 36] (Focus)
+>>&0 string 37] (Dvonn)
+>>&0 string 38] (Tamsk)
+>>&0 string 39] (Gipf)
+>>&0 string 40] (Kropki)
+
+
+# Summary: Civilization 4 video
+# Extension: .bik
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0 string BIKi Civilization 4 Video
+
+
+##############################################
+# NetImmerse/Gamebryo game engine entries
+
+# Summary: Gamebryo game engine file
+# Extension: .nif, .kf
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0 string Gamebryo\ File\ Format,\ Version\ Gamebryo game engine file
+>&0 regex [0-9a-z.]+ \b, version %s
+
+# Summary: Gamebryo game engine file
+# Extension: .kfm
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0 string ;Gamebryo\ KFM\ File\ Version\ Gamebryo game engine animation File
+>&0 regex [0-9a-z.]+ \b, version %s
+
+# Summary: NetImmerse game engine file
+# Extension .nif
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0 string NetImmerse\ File\ Format,\ Versio
+>&0 string n\ NetImmerse game engine file
+>>&0 regex [0-9a-z.]+ \b, version %s
+
diff --git a/contrib/file/Magdir/gimp b/contrib/file/Magdir/gimp
index 9a9d61e..674bbfb 100644
--- a/contrib/file/Magdir/gimp
+++ b/contrib/file/Magdir/gimp
@@ -34,3 +34,7 @@
# ('Bucky' LaDieu, nega@vt.edu)
20 string GIMP GIMP brush data
+
+# GIMP Curves File
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0 string #\040GIMP\040Curves\040File GIMP curve file
diff --git a/contrib/file/Magdir/gnome-keyring b/contrib/file/Magdir/gnome-keyring
new file mode 100644
index 0000000..80a4f88
--- /dev/null
+++ b/contrib/file/Magdir/gnome-keyring
@@ -0,0 +1,23 @@
+# GNOME keyring
+# Contributed by Josh Triplett
+# FIXME: Could be simplified if pstring supported two-byte counts
+0 string GnomeKeyring\n\r\0\n GNOME keyring
+>&0 ubyte 0 \b, major version 0
+>>&0 ubyte 0 \b, minor version 0
+>>>&0 ubyte 0 \b, crypto type 0 (AEL)
+>>>&0 ubyte >0 \b, crypto type %hhu (unknown)
+>>>&1 ubyte 0 \b, hash type 0 (MD5)
+>>>&1 ubyte >0 \b, hash type %hhu (unknown)
+>>>&2 ubelong 0xFFFFFFFF \b, name NULL
+>>>&2 ubelong !0xFFFFFFFF
+>>>>&-4 ubelong >255 \b, name too long for file's pstring type
+>>>>&-4 ubelong <256
+>>>>>&-1 pstring x \b, name "%s"
+>>>>>>&0 ubeqdate x \b, last modified %s
+>>>>>>&8 ubeqdate x \b, created %s
+>>>>>>&16 ubelong &1
+>>>>>>>&0 ubelong x \b, locked if idle for %u seconds
+>>>>>>&16 ubelong ^1 \b, not locked if idle
+>>>>>>&24 ubelong x \b, hash iterations %u
+>>>>>>&28 ubequad x \b, salt %llu
+>>>>>>&52 ubelong x \b, %u item(s)
diff --git a/contrib/file/Magdir/gnu b/contrib/file/Magdir/gnu
index 42d9c7b..66c670c 100644
--- a/contrib/file/Magdir/gnu
+++ b/contrib/file/Magdir/gnu
@@ -17,10 +17,14 @@
# The format is very similar to pgp
0 string \001gpg GPG key trust database
>4 byte x version %d
+# Note: magic.mime had 0x8501 for the next line instead of 0x8502
0 beshort 0x8502 GPG encrypted data
+!:mime text/PGP # encoding: data
+
# This magic is not particularly good, as the keyrings don't have true
# magic. Nevertheless, it covers many keyrings.
0 beshort 0x9901 GPG key public ring
+!:mime application/x-gnupg-keyring
# Gnumeric spreadsheet
# This entry is only semi-helpful, as Gnumeric compresses its files, so
@@ -32,3 +36,7 @@
0 string \0LOCATE GNU findutils locate database data
>7 string >\0 \b, format %s
>7 string 02 \b (frcode)
+
+# Files produced by GNU gettext
+0 long 0xDE120495 GNU-format message catalog data
+0 long 0x950412DE GNU-format message catalog data
diff --git a/contrib/file/Magdir/gnumeric b/contrib/file/Magdir/gnumeric
new file mode 100644
index 0000000..76dfa90
--- /dev/null
+++ b/contrib/file/Magdir/gnumeric
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# gnumeric: file(1) magic for Gnumeric spreadsheet
+# This entry is only semi-helpful, as Gnumeric compresses its files, so
+# they will ordinarily reported as "compressed", but at least -z helps
+39 string =<gmr:Workbook Gnumeric spreadsheet
+!:mime application/x-gnumeric
diff --git a/contrib/file/Magdir/graphviz b/contrib/file/Magdir/graphviz
new file mode 100644
index 0000000..cf47f4e
--- /dev/null
+++ b/contrib/file/Magdir/graphviz
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# graphviz: file(1) magic for http://www.graphviz.org/
+0 regex/100 [\r\n\t\ ]*graph[\r\n\t\ ]*.*\\{ graphviz graph text
+!:mime text/vnd.graphviz
+0 regex/100 [\r\n\t\ ]*digraph[\r\n\t\ ]*.*\\{ graphviz digraph text
+!:mime text/vnd.graphviz
diff --git a/contrib/file/Magdir/hp b/contrib/file/Magdir/hp
index 052f09a..2d064cc 100644
--- a/contrib/file/Magdir/hp
+++ b/contrib/file/Magdir/hp
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# hp: file(1) magic for Hewlett Packard machines (see also "printer")
#
@@ -202,34 +201,40 @@
0 string msgcat01 HP NLS message catalog,
>8 long >0 %d messages
-# addendum to /etc/magic with HP-48sx file-types by phk@data.fls.dk 1jan92
-0 string HPHP48- HP48 binary
->7 byte >0 - Rev %c
->8 beshort 0x1129 (ADR)
->8 beshort 0x3329 (REAL)
->8 beshort 0x5529 (LREAL)
->8 beshort 0x7729 (COMPLX)
->8 beshort 0x9d29 (LCOMPLX)
->8 beshort 0xbf29 (CHAR)
->8 beshort 0xe829 (ARRAY)
->8 beshort 0x0a2a (LNKARRAY)
->8 beshort 0x2c2a (STRING)
->8 beshort 0x4e2a (HXS)
->8 beshort 0x742a (LIST)
->8 beshort 0x962a (DIR)
->8 beshort 0xb82a (ALG)
->8 beshort 0xda2a (UNIT)
->8 beshort 0xfc2a (TAGGED)
->8 beshort 0x1e2b (GROB)
->8 beshort 0x402b (LIB)
->8 beshort 0x622b (BACKUP)
->8 beshort 0x882b (LIBDATA)
->8 beshort 0x9d2d (PROG)
->8 beshort 0xcc2d (CODE)
->8 beshort 0x482e (GNAME)
->8 beshort 0x6d2e (LNAME)
->8 beshort 0x922e (XLIB)
-0 string %%HP: HP48 text
+# Summary: HP-48/49 calculator
+# Created by: phk@data.fls.dk
+# Modified by (1): AMAKAWA Shuhei <sa264@cam.ac.uk>
+# Modified by (2): Samuel Thibault <samuel.thibault@ens-lyon.org> (HP49 support)
+0 string HPHP HP
+>4 string 48 48 binary
+>4 string 49 49 binary
+>7 byte >64 - Rev %c
+>8 leshort 0x2911 (ADR)
+>8 leshort 0x2933 (REAL)
+>8 leshort 0x2955 (LREAL)
+>8 leshort 0x2977 (COMPLX)
+>8 leshort 0x299d (LCOMPLX)
+>8 leshort 0x29bf (CHAR)
+>8 leshort 0x29e8 (ARRAY)
+>8 leshort 0x2a0a (LNKARRAY)
+>8 leshort 0x2a2c (STRING)
+>8 leshort 0x2a4e (HXS)
+>8 leshort 0x2a74 (LIST)
+>8 leshort 0x2a96 (DIR)
+>8 leshort 0x2ab8 (ALG)
+>8 leshort 0x2ada (UNIT)
+>8 leshort 0x2afc (TAGGED)
+>8 leshort 0x2b1e (GROB)
+>8 leshort 0x2b40 (LIB)
+>8 leshort 0x2b62 (BACKUP)
+>8 leshort 0x2b88 (LIBDATA)
+>8 leshort 0x2d9d (PROG)
+>8 leshort 0x2dcc (CODE)
+>8 leshort 0x2e48 (GNAME)
+>8 leshort 0x2e6d (LNAME)
+>8 leshort 0x2e92 (XLIB)
+
+0 string %%HP: HP text
>6 string T(0) - T(0)
>6 string T(1) - T(1)
>6 string T(2) - T(2)
@@ -240,6 +245,45 @@
>14 string F(.) F(.);
>14 string F(,) F(,);
+
+# Summary: HP-38/39 calculator
+# Created by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+0 string HP3
+>3 string 8 HP 38
+>3 string 9 HP 39
+>4 string Bin binary
+>4 string Asc ASCII
+>7 string A (Directory List)
+>7 string B (Zaplet)
+>7 string C (Note)
+>7 string D (Program)
+>7 string E (Variable)
+>7 string F (List)
+>7 string G (Matrix)
+>7 string H (Library)
+>7 string I (Target List)
+>7 string J (ASCII Vector specification)
+>7 string K (wildcard)
+
+# Summary: HP-38/39 calculator
+# Created by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+0 string HP3
+>3 string 8 HP 38
+>3 string 9 HP 39
+>4 string Bin binary
+>4 string Asc ASCII
+>7 string A (Directory List)
+>7 string B (Zaplet)
+>7 string C (Note)
+>7 string D (Program)
+>7 string E (Variable)
+>7 string F (List)
+>7 string G (Matrix)
+>7 string H (Library)
+>7 string I (Target List)
+>7 string J (ASCII Vector specification)
+>7 string K (wildcard)
+
# hpBSD magic numbers
0 beshort 200 hp200 (68010) BSD
>2 beshort 0407 impure binary
@@ -390,6 +434,4 @@
>>>>>>>>>0xC4 belong 33 - received SIGXCPU
>>>>>>>>>0xC4 belong 34 - received SIGXFSZ
-# From: AMAKAWA Shuhei <sa264@cam.ac.uk>
-0 string HPHP49- HP49 binary
diff --git a/contrib/file/Magdir/iff b/contrib/file/Magdir/iff
index 3c88f90..4d2a832 100644
--- a/contrib/file/Magdir/iff
+++ b/contrib/file/Magdir/iff
@@ -13,8 +13,11 @@
#>4 belong x \b, FORM is %d bytes long
# audio formats
>8 string AIFF \b, AIFF audio
+!:mime audio/x-aiff
>8 string AIFC \b, AIFF-C compressed audio
+!:mime audio/x-aiff
>8 string 8SVX \b, 8SVX 8-bit sampled sound voice
+!:mime audio/x-aiff
>8 string 16SV \b, 16SV 16-bit sampled sound voice
>8 string SAMP \b, SAMP sampled audio
>8 string MAUD \b, MAUD MacroSystem audio
diff --git a/contrib/file/Magdir/images b/contrib/file/Magdir/images
index fd9e14f..cccc70b 100644
--- a/contrib/file/Magdir/images
+++ b/contrib/file/Magdir/images
@@ -1,6 +1,6 @@
-
#------------------------------------------------------------------------------
-# images: file(1) magic for image formats (see also "iff")
+# images: file(1) magic for image formats (see also "iff", and "c-lang" for
+# XPM bitmaps)
#
# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
# additions by janl@ifi.uio.no as well as others. Jan also suggested
@@ -30,13 +30,20 @@
# PBMPLUS images
# The next byte following the magic is always whitespace.
-0 string P1 Netpbm PBM image text
-0 string P2 Netpbm PGM image text
-0 string P3 Netpbm PPM image text
+0 search/1 P1 Netpbm PBM image text
+!:mime image/x-portable-bitmap
+0 search/1 P2 Netpbm PGM image text
+!:mime image/x-portable-greymap
+0 search/1 P3 Netpbm PPM image text
+!:mime image/x-portable-pixmap
0 string P4 Netpbm PBM "rawbits" image data
+!:mime image/x-portable-bitmap
0 string P5 Netpbm PGM "rawbits" image data
+!:mime image/x-portable-greymap
0 string P6 Netpbm PPM "rawbits" image data
+!:mime image/x-portable-pixmap
0 string P7 Netpbm PAM image file
+!:mime image/x-portable-pixmap
# From: bryanh@giraffe-data.com (Bryan Henderson)
0 string \117\072 Solitaire Image Recorder format
@@ -50,13 +57,17 @@
>21 byte 51 version 3
# NIFF (Navy Interchange File Format, a modification of TIFF) images
+# [GRR: this *must* go before TIFF]
0 string IIN1 NIFF image data
+!:mime image/x-niff
# Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com)
# The second word of TIFF files is the TIFF version number, 42, which has
# never changed. The TIFF specification recommends testing for it.
0 string MM\x00\x2a TIFF image data, big-endian
+!:mime image/tiff
0 string II\x2a\x00 TIFF image data, little-endian
+!:mime image/tiff
# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
# (Greg Roelofs, newt@uchicago.edu)
@@ -64,24 +75,41 @@
#
# 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ...
#
-0 string \x89PNG PNG image data,
->4 belong !0x0d0a1a0a CORRUPTED,
->4 belong 0x0d0a1a0a
->>16 belong x %ld x
->>20 belong x %ld,
->>24 byte x %d-bit
->>25 byte 0 grayscale,
->>25 byte 2 \b/color RGB,
->>25 byte 3 colormap,
->>25 byte 4 gray+alpha,
->>25 byte 6 \b/color RGBA,
-#>>26 byte 0 deflate/32K,
->>28 byte 0 non-interlaced
->>28 byte 1 interlaced
-1 string PNG PNG image data, CORRUPTED
+0 string \x89PNG\x0d\x0a\x1a\x0a PNG image
+!:mime image/png
+>16 belong x \b, %ld x
+>20 belong x %ld,
+>24 byte x %d-bit
+>25 byte 0 grayscale,
+>25 byte 2 \b/color RGB,
+>25 byte 3 colormap,
+>25 byte 4 gray+alpha,
+>25 byte 6 \b/color RGBA,
+#>26 byte 0 deflate/32K,
+>28 byte 0 non-interlaced
+>28 byte 1 interlaced
+
+# possible GIF replacements; none yet released!
+# (Greg Roelofs, newt@uchicago.edu)
+#
+# GRR 950115: this was mine ("Zip GIF"):
+0 string GIF94z ZIF image (GIF+deflate alpha)
+!:mime image/x-unknown
+#
+# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better):
+#
+0 string FGF95a FGF image (GIF+deflate beta)
+!:mime image/x-unknown
+#
+# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal
+# (best; not yet implemented):
+#
+0 string PBF PBF image (deflate compression)
+!:mime image/x-unknown
# GIF
0 string GIF8 GIF image data
+!:mime image/gif
>4 string 7a \b, version 8%s,
>4 string 9a \b, version 8%s,
>6 leshort >0 %hd x
@@ -113,7 +141,7 @@
>4 long 3 \b, rectangular 32-bit (24-bit with matte)
# FIG (Facility for Interactive Generation of figures), an object-based format
-0 string #FIG FIG image text
+0 search/1 #FIG FIG image text
>5 string x \b, version %.3s
# PHIGS
@@ -129,9 +157,6 @@
# CGM image files
0 string BEGMF clear text Computer Graphics Metafile
-# XXX - questionable magic
-0 beshort&0xffe0 0x0020 binary Computer Graphics Metafile
-0 beshort 0x3020 character Computer Graphics Metafile
# MGR bitmaps (Michael Haardt, u31b3hs@pool.informatik.rwth-aachen.de)
0 string yz MGR bitmap, modern format, 8-bit aligned
@@ -152,15 +177,23 @@
0 string Sfff structured fax file
-# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
-0 string BM PC bitmap data
->14 leshort 12 \b, OS/2 1.x format
+# PC bitmaps (OS/2, Windows BMP files) (Greg Roelofs, newt@uchicago.edu)
+0 string BM
+>14 leshort 12 PC bitmap, OS/2 1.x format
+!:mime image/x-ms-bmp
>>18 leshort x \b, %d x
>>20 leshort x %d
->14 leshort 64 \b, OS/2 2.x format
+>14 leshort 64 PC bitmap, OS/2 2.x format
+!:mime image/x-ms-bmp
>>18 leshort x \b, %d x
>>20 leshort x %d
->14 leshort 40 \b, Windows 3.x format
+>14 leshort 40 PC bitmap, Windows 3.x format
+!:mime image/x-ms-bmp
+>>18 lelong x \b, %d x
+>>22 lelong x %d x
+>>28 leshort x %d
+>14 leshort 128 PC bitmap, Windows NT/2000 format
+!:mime image/x-ms-bmp
>>18 lelong x \b, %d x
>>22 lelong x %d x
>>28 leshort x %d
@@ -174,7 +207,7 @@
# XPM icons (Greg Roelofs, newt@uchicago.edu)
# note possible collision with C/REXX entry in c-lang; currently commented out
-0 string /*\ XPM\ */ X pixmap image text
+0 search/1 /*\ XPM\ */ X pixmap image text
# Utah Raster Toolkit RLE images (janl@ifi.uio.no)
0 leshort 0xcc52 RLE image data,
@@ -260,7 +293,6 @@
# other images
0 string This\ is\ a\ BitMap\ file Lisp Machine bit-array-file
-0 string =!! Bennet Yee's "face" format
# From SunOS 5.5.1 "/etc/magic" - appeared right before Sun raster image
# stuff.
@@ -269,6 +301,7 @@
# DICOM medical imaging data
128 string DICM DICOM medical imaging data
+!:mime application/dicom
# XWD - X Window Dump file.
# As described in /usr/X11R6/include/X11/XWDFile.h
@@ -367,6 +400,7 @@
# Adobe Photoshop
0 string 8BPS Adobe Photoshop Image
+!:mime image/vnd.adobe.photoshop
# XV thumbnail indicator (ThMO)
0 string P7\ 332 XV thumbnail image data
@@ -456,9 +490,9 @@
>12 long x \b, track size %d bytes
>16 byte x \b, device type 33%2.2X
-# Squeak images and - etoffi@softhome.net
-0 string \146\031\0\0 Squeak image data
-0 string 'From\040Squeak Squeak program text
+# Squeak images and programs - etoffi@softhome.net
+0 string \146\031\0\0 Squeak image data
+0 search/1 'From\040Squeak Squeak program text
# partimage: file(1) magic for PartImage files (experimental, incomplete)
# Author: Hans-Joachim Baader <hjb@pro-linux.de>
@@ -505,12 +539,18 @@
# http://www.dalibor.cz/minolta/raw_file_format.htm
0 string \000MRM Minolta Dimage camera raw image data
-# From: stephane.loeuillet@tiscali.f
-# http://www.djvuzone.org/
-0 string AT&TFORM DjVu Image file
+# Summary: DjVu image / document
+# Extension: .djvu
+# Reference: http://djvu.org/docs/DjVu3Spec.djvu
+# Submitted by: Stephane Loeuillet <stephane.loeuillet@tiscali.fr>
+# Modified by (1): Abel Cheung <abelcheung@gmail.com>
+0 string AT&TFORM
+!:mime image/vnd.djvu
+>12 string DJVM DjVu multiple page document
+>12 string DJVU DjVu image or single page document
+>12 string DJVI DjVu shared document
+>12 string THUM DjVu page thumbnails
-# From: Jason Bacon <bacon@smithers.neuro.mcw.edu>
-0 beshort 0x3020 character Computer Graphics Metafile
# From Marc Espie
0 lelong 20000630 OpenEXR image data
@@ -523,9 +563,40 @@
# Hierarchical Data Format, used to facilitate scientific data exchange
# specifications at http://hdf.ncsa.uiuc.edu/
0 belong 0x0e031301 Hierarchical Data Format (version 4) data
+!:mime application/x-hdf
0 string \211HDF\r\n\032 Hierarchical Data Format (version 5) data
+!:mime application/x-hdf
# From: Tobias Burnus <burnus@net-b.de>
# Xara (for a while: Corel Xara) is a graphic package, see
-# http://www.xara.com/ for Windows and as GPL application for
+# http://www.xara.com/ for Windows and as GPL application for Linux
0 string XARA\243\243 Xara graphics file
+
+# http://www.cartesianinc.com/Tech/
+0 string CPC\262 Cartesian Perceptual Compression image
+!:mime image/x-cpi
+
+# From Albert Cahalan <acahalan@gmail.com>
+# puredigital used it for the CVS disposable camcorder
+#8 lelong 4 ZBM bitmap image data
+#>4 leshort x %u x
+#>6 leshort x %u
+
+# From Albert Cahalan <acahalan@gmail.com>
+# uncompressed 5:6:5 HighColor image for OLPC XO firmware icons
+0 string C565 OLPC firmware icon image data
+>4 leshort x %u x
+>6 leshort x %u
+
+# Applied Images - Image files from Cytovision
+# Gustavo Junior Alves <gjalves@gjalves.com.br>
+0 string \xce\xda\xde\xfa Cytovision Metaphases file
+0 string \xed\xad\xef\xac Cytovision Karyotype file
+0 string \x0b\x00\x03\x00 Cytovision FISH Probe file
+0 string \xed\xfe\xda\xbe Cytovision FLEX file
+0 string \xed\xab\xed\xfe Cytovision FLEX file
+0 string \xad\xfd\xea\xad Cytovision RATS file
+
+# Wavelet Scalar Quantization format used in gray-scale fingerprint images
+# From Tano M Fotang <mfotang@quanteq.com>
+0 string \xff\xa0\xff\xa8\x00 Wavelet Scalar Quantization image data
diff --git a/contrib/file/Magdir/inform b/contrib/file/Magdir/inform
new file mode 100644
index 0000000..ba35d61
--- /dev/null
+++ b/contrib/file/Magdir/inform
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# inform: file(1) magic for Inform interactive fiction language
+
+# URL: http://www.inform-fiction.org/
+# From: Reuben Thomas <rrt@sc3d.org>
+
+0 search/cB/100 constant\ story Inform source text
diff --git a/contrib/file/Magdir/java b/contrib/file/Magdir/java
index 971b72ce..cca5542 100644
--- a/contrib/file/Magdir/java
+++ b/contrib/file/Magdir/java
@@ -9,8 +9,9 @@
>2 beshort >0x0004 \b, version %d
0 belong 0xfeedfeed Java KeyStore
-
+!:mime application/x-java-keystore
0 belong 0xcececece Java JCE KeyStore
+!:mime application/x-java-jce-keystore
# Dalvik .dex format. http://retrodev.com/android/dexformat.html
# From <mkf@google.com> "Mike Fleming"
diff --git a/contrib/file/Magdir/jpeg b/contrib/file/Magdir/jpeg
index af646d6..d728de6 100644
--- a/contrib/file/Magdir/jpeg
+++ b/contrib/file/Magdir/jpeg
@@ -9,6 +9,8 @@
# both of which turn into "JPEG image data" here.
#
0 beshort 0xffd8 JPEG image data
+!:mime image/jpeg
+!:strength +1
>6 string JFIF \b, JFIF standard
# The following added by Erik Rossen <rossen@freesurf.ch> 1999-09-06
# in a vain attempt to add image size reporting for JFIF. Note that these
@@ -125,6 +127,8 @@
# At least we can show a comment if no other segments got inserted before:
>(4.S+5) byte 0xFE
>>(4.S+8) string >\0 \b, comment: "%s"
+# FIXME: When we can do non-byte counted strings, we can use that to get
+# the string's count, and fix Debian bug #283760
#>(4.S+5) byte 0xFE \b, comment
#>>(4.S+6) beshort x \b length=%d
#>>(4.S+8) string >\0 \b, "%s"
@@ -153,3 +157,8 @@
# From: David Santinoli <david@santinoli.com>
0 string \x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A JPEG 2000 image data
+
+# Type: JPEG 2000 codesream
+# From: Mathieu Malaterre <mathieu.malaterre@gmail.com>
+0 belong 0xff4fff51 JPEG 2000 codestream
+45 beshort 0xff52
diff --git a/contrib/file/Magdir/kde b/contrib/file/Magdir/kde
new file mode 100644
index 0000000..d81ee69
--- /dev/null
+++ b/contrib/file/Magdir/kde
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# kde: file(1) magic for KDE
+
+0 string [KDE\ Desktop\ Entry] KDE desktop entry
+!:mime application/x-kdelnk
+0 string #\ KDE\ Config\ File KDE config file
+!:mime application/x-kdelnk
+0 string #\ xmcd xmcd database file for kscd
+!:mime text/x-xmcd
diff --git a/contrib/file/Magdir/lex b/contrib/file/Magdir/lex
index 7b6d0f7..eae9b10 100644
--- a/contrib/file/Magdir/lex
+++ b/contrib/file/Magdir/lex
@@ -1,11 +1,10 @@
-
#------------------------------------------------------------------------------
# lex: file(1) magic for lex
#
# derived empirically, your offsets may vary!
-53 string yyprevious C program text (from lex)
->3 string >\0 for %s
+0 search/100 yyprevious C program text (from lex)
+>3 search/1 >\0 for %s
# C program text from GNU flex, from Daniel Quinlan <quinlan@yggdrasil.com>
-21 string generated\ by\ flex C program text (from flex)
+0 search/100 generated\ by\ flex C program text (from flex)
# lex description file, from Daniel Quinlan <quinlan@yggdrasil.com>
-0 string %{ lex description text
+0 search/1 %{ lex description text
diff --git a/contrib/file/Magdir/linux b/contrib/file/Magdir/linux
index fe68013..aaedff4 100644
--- a/contrib/file/Magdir/linux
+++ b/contrib/file/Magdir/linux
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# linux: file(1) magic for Linux files
#
@@ -84,7 +83,7 @@
# Linux kernel boot images (i386 arch) (Wolfram Kleff)
514 string HdrS Linux kernel
>510 leshort 0xAA55 x86 boot executable
->>518 leshort >=0x200
+>>518 leshort >0x1ff
>>529 byte 0 zImage,
>>>529 byte 1 bzImage,
>>>(526.s+0x200) string >\0 version %s,
@@ -103,16 +102,18 @@
>0x1e9 string Loading from prehistoric times
# System.map files - Nicolás Lichtmaier <nick@debian.org>
-8 string \ A\ _text Linux kernel symbol map text
+8 search/1 \ A\ _text Linux kernel symbol map text
# LSM entries - Nicolás Lichtmaier <nick@debian.org>
-0 string Begin3 Linux Software Map entry text
-0 string Begin4 Linux Software Map entry text (new format)
+0 search/1 Begin3 Linux Software Map entry text
+0 search/1 Begin4 Linux Software Map entry text (new format)
-# From Matt Zimmerman
-0 belong 0x4f4f4f4d User-mode Linux COW file
->4 belong x \b, version %d
->8 string >\0 \b, backing file %s
+# From Matt Zimmerman, enhanced for v3 by Matthew Palmer
+0 belong 0x4f4f4f4d User-mode Linux COW file
+>4 belong <3 \b, version %d
+>>8 string >\0 \b, backing file %s
+>4 belong >2 \b, version %d
+>>32 string >\0 \b, backing file %s
############################################################################
# Linux kernel versions
@@ -230,6 +231,14 @@
0x618 string LVM2\ 001 LVM2 (Linux Logical Volume Manager)
>(0x614.l+0x600) string >\0 , UUID: %s
+# LVM snapshot
+# from Jason Farrel
+0 string SnAp LVM Snapshot (CopyOnWrite store)
+>4 lelong !0 - valid,
+>4 lelong 0 - invalid,
+>8 lelong x version %d,
+>12 lelong x chunk_size %d
+
# SE Linux policy database
0 lelong 0xf97cff8c SE Linux policy
>16 lelong x v%d
@@ -246,3 +255,10 @@
>72 string x %s]
>168 string x UUID: %s
+
+# Summary: Xen saved domain file
+# Created by: Radek Vokal <rvokal@redhat.com>
+0 string LinuxGuestRecord Xen saved domain
+>20 search/256 (name
+>>&1 string x (name %s)
+
diff --git a/contrib/file/Magdir/lisp b/contrib/file/Magdir/lisp
index e9c8ba8..60b740a 100644
--- a/contrib/file/Magdir/lisp
+++ b/contrib/file/Magdir/lisp
@@ -1,44 +1,52 @@
-
#------------------------------------------------------------------------------
# lisp: file(1) magic for lisp programs
#
# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
# updated by Joerg Jenderek
-0 string ;;
+# GRR: This lot is too weak
+#0 string ;;
# windows INF files often begin with semicolon and use CRLF as line end
# lisp files are mainly created on unix system with LF as line end
->2 search/2048 !\r Lisp/Scheme program text
->2 search/2048 \r Windows INF file
+#>2 search/2048 !\r Lisp/Scheme program text
+#>2 search/2048 \r Windows INF file
0 search/256 (if\ Lisp/Scheme program text
+!:mime text/x-lisp
0 search/256 (setq\ Lisp/Scheme program text
+!:mime text/x-lisp
0 search/256 (defvar\ Lisp/Scheme program text
+!:mime text/x-lisp
0 search/256 (defparam\ Lisp/Scheme program text
+!:mime text/x-lisp
0 search/256 (defun\ Lisp/Scheme program text
+!:mime text/x-lisp
0 search/256 (autoload\ Lisp/Scheme program text
+!:mime text/x-lisp
0 search/256 (custom-set-variables\ Lisp/Scheme program text
+!:mime text/x-lisp
# Emacs 18 - this is always correct, but not very magical.
0 string \012( Emacs v18 byte-compiled Lisp data
+!:mime application/x-elc
# Emacs 19+ - ver. recognition added by Ian Springer
-# Also applies to XEmacs 19+ .elc files; could tell them apart if we had regexp
-# support or similar - Chris Chittleborough <cchittleborough@yahoo.com.au>
-0 string ;ELC
->4 byte >19
+# Also applies to XEmacs 19+ .elc files; could tell them apart with regexs
+# - Chris Chittleborough <cchittleborough@yahoo.com.au>
+0 string ;ELC
+>4 byte >18
>4 byte <32 Emacs/XEmacs v%d byte-compiled Lisp data
+!:mime application/x-elc
# Files produced by CLISP Common Lisp From: Bruno Haible <haible@ilog.fr>
-0 string (SYSTEM::VERSION\040' CLISP byte-compiled Lisp program text
+0 string (SYSTEM::VERSION\040' CLISP byte-compiled Lisp program (pre 2004-03-27)
+0 string (|SYSTEM|::|VERSION|\040' CLISP byte-compiled Lisp program text
+
0 long 0x70768BD2 CLISP memory image data
0 long 0xD28B7670 CLISP memory image data, other endian
-# Files produced by GNU gettext
-0 long 0xDE120495 GNU-format message catalog data
-0 long 0x950412DE GNU-format message catalog data
-
#.com and .bin for MIT scheme
0 string \372\372\372\372 MIT scheme (library?)
# From: David Allouche <david@allouche.net>
-0 string \<TeXmacs| TeXmacs document text
+0 search/1 \<TeXmacs| TeXmacs document text
+!:mime text/texmacs
diff --git a/contrib/file/Magdir/llvm b/contrib/file/Magdir/llvm
new file mode 100644
index 0000000..8c1610c
--- /dev/null
+++ b/contrib/file/Magdir/llvm
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# llvm: file(1) magic for LLVM byte-codes
+# URL: http://llvm.cs.uiuc.edu/docs/BytecodeFormat.html#signature
+# From: Al Stone <ahs3@fc.hp.com>
+
+0 string llvm LLVM byte-codes, uncompressed
+0 string llvc0 LLVM byte-codes, null compression
+0 string llvc1 LLVM byte-codes, gzip compression
+0 string llvc2 LLVM byte-codes, bzip2 compression
diff --git a/contrib/file/Magdir/lua b/contrib/file/Magdir/lua
new file mode 100644
index 0000000..9aa87b1
--- /dev/null
+++ b/contrib/file/Magdir/lua
@@ -0,0 +1,19 @@
+#------------------------------------------------------------------------------
+# lua: file(1) magic for Lua scripting language
+# URL: http://www.lua.org/
+# From: Reuben Thomas <rrt@sc3d.org>, Seo Sanghyeon <tinuviel@sparcs.kaist.ac.kr>
+
+# Lua scripts
+0 search/1/b #!\ /usr/bin/lua Lua script text executable
+!:mime text/x-lua
+0 search/1/b #!\ /usr/local/bin/lua Lua script text executable
+!:mime text/x-lua
+0 search/1 #!/usr/bin/env\ lua Lua script text executable
+!:mime text/x-lua
+0 search/1 #!\ /usr/bin/env\ lua Lua script text executable
+!:mime text/x-lua
+
+# Lua bytecode
+0 string \033Lua Lua bytecode,
+>4 byte 0x50 version 5.0
+>4 byte 0x51 version 5.1
diff --git a/contrib/file/Magdir/luks b/contrib/file/Magdir/luks
new file mode 100644
index 0000000..2ab2393
--- /dev/null
+++ b/contrib/file/Magdir/luks
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# luks: file(1) magic for Linux Unified Key Setup
+# URL: http://luks.endorphin.org/spec
+# From: Anthon van der Neut <anthon@mnt.org>
+
+0 string LUKS\xba\xbe LUKS encrypted file,
+>6 beshort x ver %d
+>8 string x [%s,
+>40 string x %s,
+>72 string x %s]
+>168 string x UUID: %s
diff --git a/contrib/file/Magdir/macintosh b/contrib/file/Magdir/macintosh
index 4acd5c8..77187a3 100644
--- a/contrib/file/Magdir/macintosh
+++ b/contrib/file/Magdir/macintosh
@@ -5,6 +5,7 @@
# BinHex is the Macintosh ASCII-encoded file format (see also "apple")
# Daniel Quinlan, quinlan@yggdrasil.com
11 string must\ be\ converted\ with\ BinHex BinHex binary text
+!:mime application/mac-binhex40
>41 string x \b, version %.3s
# Stuffit archives are the de facto standard of compression for Macintosh
@@ -18,37 +19,41 @@
# Newer StuffIt archives (grant@netbsd.org)
0 string StuffIt StuffIt Archive
+!:mime application/x-stuffit
#>162 string >0 : %s
# Macintosh Applications and Installation binaries (franklsm@tuns.ca)
-0 string APPL Macintosh Application (data)
->2 string x \b: %s
+# GRR: Too weak
+#0 string APPL Macintosh Application (data)
+#>2 string x \b: %s
# Macintosh System files (franklsm@tuns.ca)
-0 string zsys Macintosh System File (data)
-0 string FNDR Macintosh Finder (data)
-0 string libr Macintosh Library (data)
->2 string x : %s
-0 string shlb Macintosh Shared Library (data)
->2 string x : %s
-0 string cdev Macintosh Control Panel (data)
->2 string x : %s
-0 string INIT Macintosh Extension (data)
->2 string x : %s
-0 string FFIL Macintosh Truetype Font (data)
->2 string x : %s
-0 string LWFN Macintosh Postscript Font (data)
->2 string x : %s
+# GRR: Too weak
+#0 string zsys Macintosh System File (data)
+#0 string FNDR Macintosh Finder (data)
+#0 string libr Macintosh Library (data)
+#>2 string x : %s
+#0 string shlb Macintosh Shared Library (data)
+#>2 string x : %s
+#0 string cdev Macintosh Control Panel (data)
+#>2 string x : %s
+#0 string INIT Macintosh Extension (data)
+#>2 string x : %s
+#0 string FFIL Macintosh Truetype Font (data)
+#>2 string x : %s
+#0 string LWFN Macintosh Postscript Font (data)
+#>2 string x : %s
# Additional Macintosh Files (franklsm@tuns.ca)
-0 string PACT Macintosh Compact Pro Archive (data)
->2 string x : %s
-0 string ttro Macintosh TeachText File (data)
->2 string x : %s
-0 string TEXT Macintosh TeachText File (data)
->2 string x : %s
-0 string PDF Macintosh PDF File (data)
->2 string x : %s
+# GRR: Too weak
+#0 string PACT Macintosh Compact Pro Archive (data)
+#>2 string x : %s
+#0 string ttro Macintosh TeachText File (data)
+#>2 string x : %s
+#0 string TEXT Macintosh TeachText File (data)
+#>2 string x : %s
+#0 string PDF Macintosh PDF File (data)
+#>2 string x : %s
# MacBinary format (Eric Fischer, enf@pobox.com)
#
@@ -320,41 +325,50 @@
# shorter than 32 bytes must be terminated with NULL" so I'll treat it as a
# cstring. Of course, partitions can contain more than four entries, but
# what're you gonna do?
-0x200 beshort 0x504D Apple Partition data
->0x2 beshort x block size: %d,
->0x230 string x first type: %s,
->0x210 string x name: %s,
->0x254 belong x number of blocks: %d,
->0x400 beshort 0x504D
->>0x430 string x second type: %s,
->>0x410 string x name: %s,
->>0x454 belong x number of blocks: %d,
->>0x800 beshort 0x504D
->>>0x830 string x third type: %s,
->>>0x810 string x name: %s,
->>>0x854 belong x number of blocks: %d,
->>>0xa00 beshort 0x504D
->>>>0xa30 string x fourth type: %s,
->>>>0xa10 string x name: %s,
->>>>0xa54 belong x number of blocks: %d
-# AFAIK, only the signature is different
-0x200 beshort 0x5453 Apple Old Partition data
->0x2 beshort x block size: %d,
->0x230 string x first type: %s,
->0x210 string x name: %s,
->0x254 belong x number of blocks: %d,
->0x400 beshort 0x504D
->>0x430 string x second type: %s,
->>0x410 string x name: %s,
->>0x454 belong x number of blocks: %d,
->>0x800 beshort 0x504D
->>>0x830 string x third type: %s,
->>>0x810 string x name: %s,
->>>0x854 belong x number of blocks: %d,
->>>0xa00 beshort 0x504D
->>>>0xa30 string x fourth type: %s,
->>>>0xa10 string x name: %s,
->>>>0xa54 belong x number of blocks: %d
+# GRR: This magic is too weak, it is just "PM"
+#0x200 beshort 0x504D Apple Partition data
+#>0x2 beshort x (block size: %d):
+#>0x230 string x first type: %s,
+#>0x210 string x name: %s,
+#>0x254 belong x number of blocks: %d,
+#>0x400 beshort 0x504D
+#>>0x430 string x second type: %s,
+#>>0x410 string x name: %s,
+#>>0x454 belong x number of blocks: %d,
+#>>0x600 beshort 0x504D
+#>>>0x630 string x third type: %s,
+#>>>0x610 string x name: %s,
+#>>>0x654 belong x number of blocks: %d,
+#>>0x800 beshort 0x504D
+#>>>0x830 string x fourth type: %s,
+#>>>0x810 string x name: %s,
+#>>>0x854 belong x number of blocks: %d,
+#>>>0xa00 beshort 0x504D
+#>>>>0xa30 string x fifth type: %s,
+#>>>>0xa10 string x name: %s,
+#>>>>0xa54 belong x number of blocks: %d
+#>>>0xc00 beshort 0x504D
+#>>>>0xc30 string x sixth type: %s,
+#>>>>0xc10 string x name: %s,
+#>>>>0xc54 belong x number of blocks: %d
+## AFAIK, only the signature is different
+#0x200 beshort 0x5453 Apple Old Partition data
+#>0x2 beshort x block size: %d,
+#>0x230 string x first type: %s,
+#>0x210 string x name: %s,
+#>0x254 belong x number of blocks: %d,
+#>0x400 beshort 0x504D
+#>>0x430 string x second type: %s,
+#>>0x410 string x name: %s,
+#>>0x454 belong x number of blocks: %d,
+#>>0x800 beshort 0x504D
+#>>>0x830 string x third type: %s,
+#>>>0x810 string x name: %s,
+#>>>0x854 belong x number of blocks: %d,
+#>>>0xa00 beshort 0x504D
+#>>>>0xa30 string x fourth type: %s,
+#>>>>0xa10 string x name: %s,
+#>>>>0xa54 belong x number of blocks: %d
# From: Remi Mommsen <mommsen@slac.stanford.edu>
0 string BOMStore Mac OS X bill of materials (BOM) file
diff --git a/contrib/file/Magdir/mail.news b/contrib/file/Magdir/mail.news
index f08261c..0b9d90a 100644
--- a/contrib/file/Magdir/mail.news
+++ b/contrib/file/Magdir/mail.news
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# mail.news: file(1) magic for mail and news
#
@@ -6,17 +5,28 @@
#0 string From mail text
# There are tests to ascmagic.c to cope with mail and news.
0 string Relay-Version: old news text
+!:mime message/rfc822
0 string #!\ rnews batched news text
+!:mime message/rfc822
0 string N#!\ rnews mailed, batched news text
+!:mime message/rfc822
0 string Forward\ to mail forwarding text
+!:mime message/rfc822
0 string Pipe\ to mail piping text
+!:mime message/rfc822
0 string Return-Path: smtp mail text
+!:mime message/rfc822
0 string Path: news text
+!:mime message/news
0 string Xref: news text
+!:mime message/news
0 string From: news or mail text
+!:mime message/rfc822
0 string Article saved news text
+!:mime message/news
0 string BABYL Emacs RMAIL text
0 string Received: RFC 822 mail text
+!:mime message/rfc822
0 string MIME-Version: MIME entity text
#0 string Content- MIME entity text
@@ -39,3 +49,5 @@
# XXX: Weak magic
#256 leshort 0xAFAE4453 Squish message area data file
#>4 leshort >0 (%d messages)
+
+#0 string \<!--\ MHonArc text/html; x-type=mhonarc
diff --git a/contrib/file/Magdir/mathcad b/contrib/file/Magdir/mathcad
new file mode 100644
index 0000000..4180196
--- /dev/null
+++ b/contrib/file/Magdir/mathcad
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# mathcad: file(1) magic for Mathcad documents
+# URL: http://www.mathsoft.com/
+# From: Josh Triplett <josh@freedesktop.org>
+
+0 string .MCAD\t Mathcad document
diff --git a/contrib/file/Magdir/mathematica b/contrib/file/Magdir/mathematica
index 0eca5d4..abbc112 100644
--- a/contrib/file/Magdir/mathematica
+++ b/contrib/file/Magdir/mathematica
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# mathematica: file(1) magic for mathematica files
# "H. Nanosecond" <aldomel@ix.netcom.com>
@@ -56,7 +55,8 @@
0 string (*********************** Mathematica 3.0 notebook
# other (* matches it is a comment start in these langs
-0 string (* Mathematica, or Pascal, Modula-2 or 3 code text
+# GRR: Too weak; also matches other languages e.g. ML
+#0 string (* Mathematica, or Pascal, Modula-2 or 3 code text
#########################
# MatLab v5
diff --git a/contrib/file/Magdir/mercurial b/contrib/file/Magdir/mercurial
new file mode 100644
index 0000000..3f1bdfc
--- /dev/null
+++ b/contrib/file/Magdir/mercurial
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# mercurial: file(1) magic for Mercurial changeset bundles
+# http://www.selenic.com/mercurial/wiki/
+#
+# Jesse Glick (jesse.glick@sun.com)
+#
+
+0 string HG10 Mercurial changeset bundle
+>4 string UN (uncompressed)
+>4 string GZ (gzip compressed)
+>4 string BZ (bzip2 compressed)
diff --git a/contrib/file/Magdir/misctools b/contrib/file/Magdir/misctools
index bb995ba..9a43e7b 100644
--- a/contrib/file/Magdir/misctools
+++ b/contrib/file/Magdir/misctools
@@ -1,13 +1,21 @@
#-----------------------------------------------------------------------------
-# misctools: file(1) magic for miscelanous UNIX tools.
+# misctools: file(1) magic for miscellaneous UNIX tools.
#
-0 string %%!! X-Post-It-Note text
+0 search/1 %%!! X-Post-It-Note text
0 string/c BEGIN:VCALENDAR vCalendar calendar file
0 string/c BEGIN:VCARD vCard visiting card
+!:mime text/x-vcard
# From: Alex Beregszaszi <alex@fsn.hu>
4 string gtktalog GNOME Catalogue (gtktalog)
>13 string >\0 version %s
-# From: Tomasz Trojanowski <tomek@uninet.com.pl>
+# Summary: Libtool library file
+# Extension: .la
+# Submitted by: Tomasz Trojanowski <tomek@uninet.com.pl>
0 search/80 .la\ -\ a\ libtool\ library\ file libtool library file
+
+# Summary: Libtool object file
+# Extension: .lo
+# Submitted by: Abel Cheung <abelcheung@gmail.com>
+0 search/80 .lo\ -\ a\ libtool\ object\ file libtool object file
diff --git a/contrib/file/Magdir/mozilla b/contrib/file/Magdir/mozilla
new file mode 100644
index 0000000..0698860
--- /dev/null
+++ b/contrib/file/Magdir/mozilla
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# mozilla: file(1) magic for Mozilla XUL fastload files
+# (XUL.mfasl and XPC.mfasl)
+# URL: http://www.mozilla.org/
+# From: Josh Triplett <josh@freedesktop.org>
+
+0 string XPCOM\nMozFASL\r\n\x1A Mozilla XUL fastload data
diff --git a/contrib/file/Magdir/msdos b/contrib/file/Magdir/msdos
index 10ce8ae..cdd7c93 100644
--- a/contrib/file/Magdir/msdos
+++ b/contrib/file/Magdir/msdos
@@ -7,9 +7,13 @@
# updated by Joerg Jenderek
0 string @
>1 string/cB \ echo\ off MS-DOS batch file text
+!:mime text/x-msdos-batch
>1 string/cB echo\ off MS-DOS batch file text
+!:mime text/x-msdos-batch
>1 string/cB rem\ MS-DOS batch file text
+!:mime text/x-msdos-batch
>1 string/cB set\ MS-DOS batch file text
+!:mime text/x-msdos-batch
# OS/2 batch files are REXX. the second regex is a bit generic, oh well
@@ -39,13 +43,15 @@
#
# Required OS version and subsystem version were 4.0 on some NT 3.51
# executables built with Visual C++ 4.0, so it's not clear that
-# they're interesting. The user version was 0.0, but there's
+# they're interesting. The user version was 0.0, but there's
# probably some linker directive to set it. The linker version was
# 3.0, except for one ".exe" which had it as 4.20 (same damn linker!).
#
# many of the compressed formats were extraced from IDARC 1.23 source code
#
-0 string MZ MS-DOS executable
+0 string MZ
+!:mime application/x-dosexec
+>0x18 leshort <0x40 MS-DOS executable
>0 string MZ\0\0\0\0\0\0\0\0\0\0PE\0\0 \b, PE for MS Windows
>>&18 leshort&0x2000 >0 (DLL)
>>&88 leshort 0 (unknown subsystem)
@@ -64,29 +70,42 @@
>>&18 leshort&0x1000 >0 system file
>>&0xf4 search/0x140 \x0\x40\x1\x0
>>>(&0.l+(4)) string MSCF \b, WinHKI CAB self-extracting archive
+>30 string Copyright\ 1989-1990\ PKWARE\ Inc. Self-extracting PKZIP archive
+!:mime application/zip
+# Is next line correct? One might expect "Corp." not "Copr." If it is right, add a note to that effect.
+>30 string PKLITE\ Copr. Self-extracting PKZIP archive
+!:mime application/zip
>0x18 leshort >0x3f
->>(0x3c.l) string PE\0\0 PE
+>>(0x3c.l) string PE\0\0 PE
+>>>(0x3c.l+25) byte 1 \b32 executable
+>>>(0x3c.l+25) byte 2 \b32+ executable
# hooray, there's a DOS extender using the PE format, with a valid PE
# executable inside (which just prints a message and exits if run in win)
->>>(8.s*16) string 32STUB for MS-DOS, 32rtm DOS extender
->>>(8.s*16) string !32STUB for MS Windows
->>>>(0x3c.l+22) leshort&0x2000 >0 (DLL)
->>>>(0x3c.l+92) leshort 0 (unknown subsystem)
->>>>(0x3c.l+92) leshort 1 (native)
->>>>(0x3c.l+92) leshort 2 (GUI)
->>>>(0x3c.l+92) leshort 3 (console)
->>>>(0x3c.l+92) leshort 7 (POSIX)
->>>>(0x3c.l+4) leshort 0x0 unknown processor
->>>>(0x3c.l+4) leshort 0x14c Intel 80386
->>>>(0x3c.l+4) leshort 0x166 MIPS R4000
->>>>(0x3c.l+4) leshort 0x184 Alpha
->>>>(0x3c.l+4) leshort 0x268 Motorola 68000
->>>>(0x3c.l+4) leshort 0x1f0 PowerPC
->>>>(0x3c.l+4) leshort 0x290 PA-RISC
->>>>(0x3c.l+22) leshort&0x0100 >0 32-bit
->>>>(0x3c.l+22) leshort&0x1000 >0 system file
->>>>(0x3c.l+232) lelong >0 Mono/.Net assembly
+>>>(0x3c.l+92) leshort <10
+>>>>(8.s*16) string 32STUB for MS-DOS, 32rtm DOS extender
+>>>>(8.s*16) string !32STUB for MS Windows
+>>>>>(0x3c.l+22) leshort&0x2000 >0 (DLL)
+>>>>>(0x3c.l+92) leshort 0 (unknown subsystem)
+>>>>>(0x3c.l+92) leshort 1 (native)
+>>>>>(0x3c.l+92) leshort 2 (GUI)
+>>>>>(0x3c.l+92) leshort 3 (console)
+>>>>>(0x3c.l+92) leshort 7 (POSIX)
+>>>(0x3c.l+92) leshort 10 (EFI application)
+>>>(0x3c.l+92) leshort 11 (EFI boot service driver)
+>>>(0x3c.l+92) leshort 12 (EFI runtime driver)
+>>>(0x3c.l+92) leshort 13 (XBOX)
+>>>(0x3c.l+4) leshort 0x0 unknown processor
+>>>(0x3c.l+4) leshort 0x14c Intel 80386
+>>>(0x3c.l+4) leshort 0x166 MIPS R4000
+>>>(0x3c.l+4) leshort 0x184 Alpha
+>>>(0x3c.l+4) leshort 0x268 Motorola 68000
+>>>(0x3c.l+4) leshort 0x1f0 PowerPC
+>>>(0x3c.l+4) leshort 0x290 PA-RISC
+>>>(0x3c.l+4) leshort 0x200 Intel Itanium
+>>>(0x3c.l+22) leshort&0x0100 >0 32-bit
+>>>(0x3c.l+22) leshort&0x1000 >0 system file
+>>>(0x3c.l+232) lelong >0 Mono/.Net assembly
>>>>(0x3c.l+0xf8) string UPX0 \b, UPX compressed
>>>>(0x3c.l+0xf8) search/0x140 PEC2 \b, PECompact2 compressed
@@ -115,6 +134,8 @@
>>>>&(0x3c.l+0xf8) search/0x100 SharedD \b, Microsoft Installer self-extracting archive
>>>>0x30 string Inno \b, InnoSetup self-extracting archive
+>>(0x3c.l) string !PE\0\0 MS-DOS executable
+
>>(0x3c.l) string NE \b, NE
>>>(0x3c.l+0x36) byte 0 (unknown OS)
>>>(0x3c.l+0x36) byte 1 for OS/2 1.x
@@ -176,7 +197,7 @@
>>>(4.s*512) leshort !0x014c \b, MZ for MS-DOS
# header data too small for extended executable
>2 long !0
->>0x18 leshort <0x40
+>>0x18 leshort <0x40
>>>(4.s*512) leshort !0x014c
>>>>&(2.s-514) string !LE
@@ -206,29 +227,31 @@
# .EXE formats (Greg Roelofs, newt@uchicago.edu)
#
->0x35 string \x8e\xc0\xb9\x08\x00\xf3\xa5\x4a\x75\xeb\x8e\xc3\x8e\xd8\x33\xff\xbe\x30\x00\x05 \b, aPack compressed
+>0x35 string \x8e\xc0\xb9\x08\x00\xf3\xa5\x4a\x75\xeb\x8e\xc3\x8e\xd8\x33\xff\xbe\x30\x00\x05 \b, aPack compressed
>0xe7 string LH/2\ Self-Extract \b, %s
>0x1c string diet \b, diet compressed
>0x1c string LZ09 \b, LZEXE v0.90 compressed
>0x1c string LZ91 \b, LZEXE v0.91 compressed
->0x1c string tz \b, TinyProg compressed
+>0x1c string tz \b, TinyProg compressed
>0x1e string PKLITE \b, %s compressed
->0x64 string W\ Collis\0\0 \b, Compack compressed
+>0x64 string W\ Collis\0\0 \b, Compack compressed
>0x24 string LHa's\ SFX \b, LHa self-extracting archive
+!:mime application/x-lha
>0x24 string LHA's\ SFX \b, LHa self-extracting archive
->0x24 string \ $ARX \b, ARX self-extracting archive
->0x24 string \ $LHarc \b, LHarc self-extracting archive
->0x20 string SFX\ by\ LARC \b, LARC self-extracting archive
+!:mime application/x-lha
+>0x24 string \ $ARX \b, ARX self-extracting archive
+>0x24 string \ $LHarc \b, LHarc self-extracting archive
+>0x20 string SFX\ by\ LARC \b, LARC self-extracting archive
>1638 string -lh5- \b, LHa self-extracting archive v2.13S
->0x17888 string Rar! \b, RAR self-extracting archive
->0x40 string aPKG \b, aPackage self-extracting archive
+>0x17888 string Rar! \b, RAR self-extracting archive
+>0x40 string aPKG \b, aPackage self-extracting archive
->32 string AIN
->>35 string 2 \b, AIN 2.x compressed
->>35 string <2 \b, AIN 1.x compressed
->>35 string >2 \b, AIN 1.x compressed
->28 string UC2X \b, UCEXE compressed
->28 string WWP\ \b, WWPACK compressed
+>32 string AIN
+>>35 string 2 \b, AIN 2.x compressed
+>>35 string <2 \b, AIN 1.x compressed
+>>35 string >2 \b, AIN 1.x compressed
+>28 string UC2X \b, UCEXE compressed
+>28 string WWP\ \b, WWPACK compressed
# skip to the end of the exe
>(4.s*512) long x
@@ -255,15 +278,15 @@
# TELVOX Teleinformatica CODEC self-extractor for OS/2:
>49801 string \x79\xff\x80\xff\x76\xff \b, CODEC archive v3.21
->>49824 leshort =1 \b, 1 file
->>49824 leshort >1 \b, %u files
+>>49824 leshort =1 \b, 1 file
+>>49824 leshort >1 \b, %u files
# .COM formats (Daniel Quinlan, quinlan@yggdrasil.com)
# Uncommenting only the first two lines will cover about 2/3 of COM files,
# but it isn't feasible to match all COM files since there must be at least
# two dozen different one-byte "magics".
-0 byte 0xe9 DOS executable (COM)
->0x1FE leshort 0xAA55 \b, boot code
+#0 byte 0xe9 DOS executable (COM)
+#>0x1FE leshort 0xAA55 \b, boot code
>6 string SFX\ of\ LHarc (%s)
0 belong 0xffffffff DOS executable (device driver)
#CMD640X2.SYS
@@ -286,25 +309,25 @@
>>77 string >\x40
>>>77 string <\x5B
>>>>77 string x \b, name: %.8s
-0 byte 0x8c DOS executable (COM)
+#0 byte 0x8c DOS executable (COM)
# 0xeb conflicts with "sequent" magic
-0 byte 0xeb DOS executable (COM)
->0x1FE leshort 0xAA55 \b, boot code
->85 string UPX \b, UPX compressed
->4 string \ $ARX \b, ARX self-extracting archive
->4 string \ $LHarc \b, LHarc self-extracting archive
->0x20e string SFX\ by\ LARC \b, LARC self-extracting archive
-0 byte 0xb8 COM executable
+#0 byte 0xeb DOS executable (COM)
+#>0x1FE leshort 0xAA55 \b, boot code
+#>85 string UPX \b, UPX compressed
+#>4 string \ $ARX \b, ARX self-extracting archive
+#>4 string \ $LHarc \b, LHarc self-extracting archive
+#>0x20e string SFX\ by\ LARC \b, LARC self-extracting archive
+#0 byte 0xb8 COM executable
# modified by Joerg Jenderek
->1 lelong !0x21cd4cff for DOS
+>1 lelong !0x21cd4cff for DOS
# http://syslinux.zytor.com/comboot.php
# (32-bit COMBOOT) programs *.C32 contain 32-bit code and run in flat-memory 32-bit protected mode
# start with assembler instructions mov eax,21cd4cffh
->1 lelong 0x21cd4cff (32-bit COMBOOT)
+>1 lelong 0x21cd4cff (32-bit COMBOOT)
0 string \x81\xfc
>4 string \x77\x02\xcd\x20\xb9
->>36 string UPX! FREE-DOS executable (COM), UPX compressed
-252 string Must\ have\ DOS\ version DR-DOS executable (COM)
+>>36 string UPX! FREE-DOS executable (COM), UPX compressed
+252 string Must\ have\ DOS\ version DR-DOS executable (COM)
# GRR search is not working
#2 search/28 \xcd\x21 COM executable for MS-DOS
#WHICHFAT.cOM
@@ -341,14 +364,6 @@
#0 byte 0xf0 MS-DOS program library data
#
-#
-# Windows Registry files.
-# updated by Joerg Jenderek
-0 string regf Windows NT/XP registry file
-0 string CREG Windows 95/98/ME registry file
-0 string SHCC3 Windows 3.1 registry file
-
-
# AAF files:
# <stuartc@rd.bbc.co.uk> Stuart Cunningham
0 string \320\317\021\340\241\261\032\341AAFB\015\000OM\006\016\053\064\001\001\001\377 AAF legacy file using MS Structured Storage
@@ -360,54 +375,73 @@
# Popular applications
2080 string Microsoft\ Word\ 6.0\ Document %s
+!:mime application/msword
2080 string Documento\ Microsoft\ Word\ 6 Spanish Microsoft Word 6 document data
+!:mime application/msword
# Pawel Wiecek <coven@i17linuxb.ists.pwr.wroc.pl> (for polish Word)
2112 string MSWordDoc Microsoft Word document data
+!:mime application/msword
#
0 belong 0x31be0000 Microsoft Word Document
+!:mime application/msword
#
-0 string PO^Q` Microsoft Word 6.0 Document
+0 string PO^Q` Microsoft Word 6.0 Document
+!:mime application/msword
#
0 string \376\067\0\043 Microsoft Office Document
+!:mime application/msword
0 string \333\245-\0\0\0 Microsoft Office Document
+!:mime application/msword
+512 string \354\245\301 Microsoft Word Document
+!:mime application/msword
#
2080 string Microsoft\ Excel\ 5.0\ Worksheet %s
+!:mime application/vnd.ms-excel
+
2080 string Foglio\ di\ lavoro\ Microsoft\ Exce %s
+!:mime application/vnd.ms-excel
#
# Pawel Wiecek <coven@i17linuxb.ists.pwr.wroc.pl> (for polish Excel)
2114 string Biff5 Microsoft Excel 5.0 Worksheet
+!:mime application/vnd.ms-excel
# Italian MS-Excel
2121 string Biff5 Microsoft Excel 5.0 Worksheet
+!:mime application/vnd.ms-excel
0 string \x09\x04\x06\x00\x00\x00\x10\x00 Microsoft Excel Worksheet
+!:mime application/vnd.ms-excel
#
0 belong 0x00001a00 Lotus 1-2-3
+!:mime application/x-123
>4 belong 0x00100400 wk3 document data
>4 belong 0x02100400 wk4 document data
>4 belong 0x07800100 fm3 or fmb document data
>4 belong 0x07800000 fm3 or fmb document data
#
-0 belong 0x00000200 Lotus 1-2-3
+0 belong 0x00000200 Lotus 1-2-3
+!:mime application/x-123
>4 belong 0x06040600 wk1 document data
>4 belong 0x06800200 fmt document data
+0 string WordPro\0 Lotus WordPro
+!:mime application/vnd.lotus-wordpro
+0 string WordPro\r\373 Lotus WordPro
+!:mime application/vnd.lotus-wordpro
-# Help files
-0 string ?_\3\0 MS Windows Help Data
-# DeIsL1.isu what this is I don't know
-0 string \161\250\000\000\001\002 DeIsL1.isu whatever that is
+# Summary: Script used by InstallScield to uninstall applications
+# Extension: .isu
+# Submitted by: unknown
+# Modified by (1): Abel Cheung <abelcheung@gmail.com> (replace useless entry)
+0 string \x71\xa8\x00\x00\x01\x02
+>12 string Stirling\ Technologies, InstallShield Uninstall Script
# Winamp .avs
-#0 string Nullsoft\ AVS\ Preset\ \060\056\061\032 A plug in for Winamp ms-windows Freeware media player
+#0 string Nullsoft\ AVS\ Preset\ \060\056\061\032 A plug in for Winamp ms-windows Freeware media player
0 string Nullsoft\ AVS\ Preset\ Winamp plug in
-# Hyper terminal:
-0 string HyperTerminal\ hyperterm
->15 string 1.0\ --\ HyperTerminal\ data\ file MS-windows Hyperterminal
-
# Windows Metafont .WMF
-0 string \327\315\306\232 ms-windows metafont .wmf
-0 string \002\000\011\000 ms-windows metafont .wmf
-0 string \001\000\011\000 ms-windows metafont .wmf
+0 string \327\315\306\232 ms-windows metafont .wmf
+0 string \002\000\011\000 ms-windows metafont .wmf
+0 string \001\000\011\000 ms-windows metafont .wmf
#tz3 files whatever that is (MS Works files)
0 string \003\001\001\004\070\001\000\000 tz3 ms-works file
@@ -427,21 +461,12 @@
0 string MDIF\032\000\010\000\000\000\372\046\100\175\001\000\001\036\001\000 MS Windows special zipped file
-# Windows help file FTG FTS
-0 string \164\146\115\122\012\000\000\000\001\000\000\000 MS Windows help cache
-
-# grp old windows 3.1 group files
-0 string \120\115\103\103 MS Windows 3.1 group files
-
-
-# lnk files windows symlinks
-0 string \114\000\000\000\001\024\002\000\000\000\000\000\300\000\000\000\000\000\000\106 MS Windows shortcut
-
#ico files
0 string \102\101\050\000\000\000\056\000\000\000\000\000\000\000 Icon for MS Windows
# Windows icons (Ian Springer <ips@fpk.hp.com>)
0 string \000\000\001\000 MS Windows icon resource
+!:mime image/x-ico
>4 byte 1 - 1 icon
>4 byte >1 - %d icons
>>6 byte >0 \b, %dx
@@ -462,18 +487,27 @@
# then there is a copyright notice
-# recycled/info the windows trash bin index
-9 string \000\000\000\030\001\000\000\000 MS Windows recycled bin info
+# Windows Recycle Bin record file (named INFO2)
+# By Abel Cheung (abelcheung AT gmail dot com)
+# Version 4 always has 280 bytes (0x118) per record, version 5 has 800 bytes
+# Since Vista uses another structure, INFO2 structure probably won't change
+# anymore. Detailed analysis in:
+# http://www.cybersecurityinstitute.biz/downloads/INFO2.pdf
+0 lelong 0x00000004
+>12 lelong 0x00000118 Windows Recycle Bin INFO2 file (Win98 or below)
+
+0 lelong 0x00000005
+>12 lelong 0x00000320 Windows Recycle Bin INFO2 file (Win2k - WinXP)
##### put in Either Magic/font or Magic/news
-# Acroread or something files wrongly identified as G3 .pfm
+# Acroread or something files wrongly identified as G3 .pfm
# these have the form \000 \001 any? \002 \000 \000
# or \000 \001 any? \022 \000 \000
-#0 string \000\001 pfm?
-#>3 string \022\000\000Copyright\ yes
-#>3 string \002\000\000Copyright\ yes
-#>3 string >\0 oops, not a font file. Cancel that.
+#0 string \000\001 pfm?
+#>3 string \022\000\000Copyright\ yes
+#>3 string \002\000\000Copyright\ yes
+#>3 string >\0 oops, not a font file. Cancel that.
#it clashes with ttf files so put it lower down.
# From Doug Lee via a FreeBSD pr
@@ -516,10 +550,12 @@
>>>>24 long >0 length %d
# TNEF magic From "Joomy" <joomy@se-ed.net>
+# Microsoft Outlook's Transport Neutral Encapsulation Format (TNEF)
0 leshort 0x223e9f78 TNEF
+!:mime application/vnd.ms-tnef
# HtmlHelp files (.chm)
-0 string ITSF\003\000\000\000\x60\000\000\000\001\000\000\000 MS Windows HtmlHelp Data
+0 string ITSF\003\000\000\000\x60\000\000\000\001\000\000\000 MS Windows HtmlHelp Data
# GFA-BASIC (Wolfram Kleff)
2 string GFA-BASIC3 GFA-BASIC 3 data
@@ -534,8 +570,8 @@
# InstallShield Cabinet files
0 string ISc( InstallShield Cabinet archive data
->5 byte&0xf0 =0x60 version 6,
->5 byte&0xf0 !0x60 version 4/5,
+>5 byte&0xf0 =0x60 version 6,
+>5 byte&0xf0 !0x60 version 4/5,
>(12.l+40) lelong x %u files
# Windows CE package files
@@ -549,57 +585,27 @@
>20 lelong 10004 \b, Hitachi SH3E
>20 lelong 10005 \b, Hitachi SH4
>20 lelong 70001 \b, ARM 7TDMI
->52 leshort 1 \b, 1 file
->52 leshort >1 \b, %u files
->56 leshort 1 \b, 1 registry entry
->56 leshort >1 \b, %u registry entries
-
-# Outlook Personal Folders
-0 lelong 0x4E444221 Microsoft Outlook binary email folder
->10 leshort 0x0e (Outlook <=2002)
->10 leshort 0x17 (Outlook >=2003)
-
-
-# From: Dirk Jagdmann <doj@cubic.org>
-0 lelong 0x00035f3f Windows 3.x help file
-
-# Christophe Monniez
-0 string Client\ UrlCache\ MMF Microsoft Internet Explorer Cache File
->20 string >\0 Version %s
-0 string \xCF\xAD\x12\xFE Microsoft Outlook Express DBX File
->4 byte =0xC5 Message database
->4 byte =0xC6 Folder database
->4 byte =0xC7 Accounts informations
->4 byte =0x30 Offline database
+>52 leshort 1 \b, 1 file
+>52 leshort >1 \b, %u files
+>56 leshort 1 \b, 1 registry entry
+>56 leshort >1 \b, %u registry entries
# Windows Enhanced Metafile (EMF)
# See msdn.microsoft.com/archive/en-us/dnargdi/html/msdn_enhmeta.asp
-# for further information. Note that "0 lelong 1" should be true i.e.
-# the first double word in the file should be 1. With the extended
-# syntax available by some file commands you could write:
-# 0 lelong 1
-# &40 ulelong 0x464D4520 Windows Enhanced Metafile (EMF) image data
-40 ulelong 0x464D4520 Windows Enhanced Metafile (EMF) image data
->44 ulelong x version 0x%x.
-# If the description has a length greater than zero, it exists and is
-# found at offset (*64).
->64 ulelong >0 Description available at offset 0x%x
->>60 ulelong >0 (length 0x%x)
-# Note it would be better to print out the description, which is found
-# as below. Unfortunately the following only prints out the first couple
-# of characters instead of all the "description length"
-# number of characters -- indicated by the ulelong at offset 60.
->>(64.l) lestring16 >0 Description: %15.15s
+# for further information.
+0 ulelong 1
+>40 string \ EMF Windows Enhanced Metafile (EMF) image data
+>>44 ulelong x version 0x%x
# From: Alex Beregszaszi <alex@fsn.hu>
0 string COWD VMWare3
->4 byte 3 disk image
+>4 byte 3 disk image
>>32 lelong x (%d/
>>36 lelong x \b%d/
>>40 lelong x \b%d)
->4 byte 2 undoable disk image
->>32 string >\0 (%s)
+>4 byte 2 undoable disk image
+>>32 string >\0 (%s)
0 string VMDK VMware4 disk image
0 string KDMV VMware4 disk image
@@ -609,39 +615,39 @@
# Lines written by Friedrich Schwittay (f.schwittay@yousable.de)
# Made by reading sources and doing trial and error on existing
# qcow files
-0 string QFI Qemu Image, Format: Qcow
+0 string QFI Qemu Image, Format: Qcow
# Uncomment the following line to display Magic (only used for debugging
# this magic number)
-#>0 string x , Magic: %s
+#>0 string x , Magic: %s
# There are currently 2 Versions: "1" and "2"
# I do not use Version 2 and therefor branch here
# but can assure: it works (tested on both versions)
# Also my Qemu 0.9.0 which uses this Version 2 refuses
# to start in its bios
->0x04 belong 2 , Version: 2
->0x04 belong 1 , Version: 1
+>0x04 belong 2 , Version: 2
+>0x04 belong 1 , Version: 1
# Using the existence of the Backing File Offset to Branch or not
# to read Backing File Information
->>0xc belong >0 , Backing File( Offset: %d
->>>(0xc.L) string >\0 , Path: %s
+>>0xc belong >0 , Backing File( Offset: %lu
+>>>(0xc.L) string >\0 , Path: %s
-# Didnt got the Trick here how qemu stores the "Size" at this Position
+# Didn't get the trick here how qemu stores the "Size" at this Position
# There is actually something stored but nothing makes sense
# The header in the sources talks about it
-#>>>16 lelong x , Size: %d
+#>>>16 lelong x , Size: %lu
# Modification time of the Backing File
-# Really usefull if you want to know if your backing
+# Really useful if you want to know if your backing
# file is still usable together with this image
->>>20 bedate x , Mtime: %s )
+>>>20 bedate x , Mtime: %s )
-# Dont know how to calculate in Magicfiles
+# Don't know how to calculate in Magicfiles
# Also: this Information is not reliably
-# stored in image-files
->>24 lelong x , Disk Size could be: %d * 256 bytes
+# stored in image-files
+>>24 lelong x , Disk Size could be: %d * 256 bytes
0 string QEVM QEMU's suspend to disk image
@@ -652,9 +658,21 @@
0 lelong 0x02468ace Bochs Sparse disk image
# from http://filext.com by Derek M Jones <derek@knosof.co.uk>
-# False positive with PPT
-#0 string \xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x03\x00\xFE\xFF Microsoft Installer
+# False positive with PPT (also currently this string is too long)
+#0 string \xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x03\x00\xFE\xFF\x09\x00\x06 Microsoft Installer
0 string \320\317\021\340\241\261\032\341 Microsoft Office Document
+#>48 byte 0x1B Excel Document
+#!:mime application/vnd.ms-excel
+>546 string bjbj Microsoft Word Document
+!:mime application/msword
+>546 string jbjb Microsoft Word Document
+!:mime application/msword
+
+0 string \224\246\056 Microsoft Word Document
+!:mime application/msword
+
+512 string R\0o\0o\0t\0\ \0E\0n\0t\0r\0y Microsoft Word Document
+!:mime application/msword
# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
# Magic type for Dell's BIOS .hdr files
@@ -663,3 +681,20 @@
>23 string Dell %s system BIOS
>48 string x version %.3s
+# Type: Microsoft DirectDraw Surface
+# URL: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/DDSFileReference/ddsfileformat.asp
+# From: Morten Hustveit <morten@debian.org>
+0 string DDS\040\174\000\000\000 Microsoft DirectDraw Surface (DDS),
+>16 lelong >0 %hd x
+>12 lelong >0 %hd,
+>84 string x %.4s
+
+# Type: Microsoft Document Imaging Format (.mdi)
+# URL: http://en.wikipedia.org/wiki/Microsoft_Document_Imaging_Format
+# From: Daniele Sempione <scrows@oziosi.org>
+0 short 0x5045 Microsoft Document Imaging Format
+
+# MS eBook format (.lit)
+0 string ITOLITLS Microsoft Reader eBook Data
+>8 lelong x \b, version %u
+!:mime application/x-ms-reader
diff --git a/contrib/file/Magdir/mup b/contrib/file/Magdir/mup
index fd9a7b1..f1022e3 100644
--- a/contrib/file/Magdir/mup
+++ b/contrib/file/Magdir/mup
@@ -8,7 +8,7 @@
# compatibility. Noteedit also use mup format, but is not forcing
# user to use any header as well.
#
-0 string //!Mup Mup music publication program input text
+0 search/1 //!Mup Mup music publication program input text
>6 string -Arkkra (Arkkra)
>>13 string -
>>>16 string .
diff --git a/contrib/file/Magdir/netware b/contrib/file/Magdir/netware
new file mode 100644
index 0000000..fbc1605
--- /dev/null
+++ b/contrib/file/Magdir/netware
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# netware: file(1) magic for NetWare Loadable Modules (NLMs)
+# From: Mads Martin Joergensen <mmj@suse.de>
+
+0 string NetWare\ Loadable\ Module NetWare Loadable Module
diff --git a/contrib/file/Magdir/ole2compounddocs b/contrib/file/Magdir/ole2compounddocs
new file mode 100644
index 0000000..ee07514
--- /dev/null
+++ b/contrib/file/Magdir/ole2compounddocs
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# Microsoft OLE 2 Compound Documents : file(1) magic for Microsoft Structured
+# storage (http://en.wikipedia.org/wiki/Structured_Storage)
+# Additional tests for OLE 2 Compound Documents should be under this recipe.
+
+0 string \320\317\021\340\241\261\032\341 OLE 2 Compound Document
+# - Microstation V8 DGN files (www.bentley.com)
+# Last update on 10/23/2006 by Lester Hightower
+> 0x480 string D\000g\000n\000~\000H : Microstation V8 DGN
+# - Visio documents
+# Last update on 10/23/2006 by Lester Hightower
+> 0x480 string V\000i\000s\000i\000o\000D\000o\000c : Visio Document
diff --git a/contrib/file/Magdir/os2 b/contrib/file/Magdir/os2
index 99dd63a..35f79ef 100644
--- a/contrib/file/Magdir/os2
+++ b/contrib/file/Magdir/os2
@@ -1,12 +1,11 @@
-
#------------------------------------------------------------------------------
# os2: file(1) magic for OS/2 files
#
# Provided 1998/08/22 by
# David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
-1 string InternetShortcut MS Windows 95 Internet shortcut text
->24 string >\ (URL=<%s>)
+1 search/1 InternetShortcut MS Windows 95 Internet shortcut text
+>24 search/1 >\ (URL=<%s>)
# OS/2 URL objects
# Provided 1998/08/22 by
diff --git a/contrib/file/Magdir/palm b/contrib/file/Magdir/palm
index 79af1f0..e57e119 100644
--- a/contrib/file/Magdir/palm
+++ b/contrib/file/Magdir/palm
@@ -45,7 +45,7 @@
>0 string >\0 "%s"
60 string SM01SMem SuperMemo PalmOS document
>0 string >\0 "%s"
-60 string DataTlPt TealDoc PalmOS document
+60 string TEXtTlDc TealDoc PalmOS document
>0 string >\0 "%s"
60 string InfoTlIf TealInfo PalmOS document
>0 string >\0 "%s"
diff --git a/contrib/file/Magdir/pdf b/contrib/file/Magdir/pdf
index e90214e..8a4d2e7 100644
--- a/contrib/file/Magdir/pdf
+++ b/contrib/file/Magdir/pdf
@@ -3,11 +3,12 @@
#
0 string %PDF- PDF document
+!:mime application/pdf
>5 byte x \b, version %c
>7 byte x \b.%c
# From: Nick Schmalenberger <nick@schmalenberger.us>
# Forms Data Format
-0 string %FDF- FDF text
+0 string %FDF- FDF document
>5 byte x \b, version %c
>7 byte x \b.%c
diff --git a/contrib/file/Magdir/perl b/contrib/file/Magdir/perl
index a8daee4..73fb88b 100644
--- a/contrib/file/Magdir/perl
+++ b/contrib/file/Magdir/perl
@@ -1,26 +1,32 @@
-
#------------------------------------------------------------------------------
# perl: file(1) magic for Larry Wall's perl language.
#
-# The ``eval'' line recognizes an outrageously clever hack for USG systems.
+# The `eval' lines recognizes an outrageously clever hack.
# Keith Waclena <keith@cerberus.uchicago.edu>
# Send additions to <perl5-porters@perl.org>
-0 string/b #!\ /bin/perl perl script text executable
-0 string eval\ "exec\ /bin/perl perl script text
-0 string/b #!\ /usr/bin/perl perl script text executable
-0 string eval\ "exec\ /usr/bin/perl perl script text
-0 string/b #!\ /usr/local/bin/perl perl script text
-0 string eval\ "exec\ /usr/local/bin/perl perl script text executable
-0 string eval\ '(exit\ $?0)'\ &&\ eval\ 'exec perl script text
+0 search/1/b #!\ /bin/perl Perl script text executable
+!:mime text/x-perl
+0 search/1 eval\ "exec\ /bin/perl Perl script text
+!:mime text/x-perl
+0 search/1/b #!\ /usr/bin/perl Perl script text executable
+!:mime text/x-perl
+0 search/1 eval\ "exec\ /usr/bin/perl Perl script text
+!:mime text/x-perl
+0 search/1/b #!\ /usr/local/bin/perl Perl script text executable
+!:mime text/x-perl
+0 search/1 eval\ "exec\ /usr/local/bin/perl Perl script text
+!:mime text/x-perl
+0 search/1 eval\ '(exit\ $?0)'\ &&\ eval\ 'exec Perl script text
+!:mime text/x-perl
# by Dmitry V. Levin and Alexey Tourbin
# check the first line
-0 string package
->1 regex \^package[\ \t]+[A-Za-z_]
->>1 regex \^package[\ \t]+[0-9A-Za-z_:]*\ *; Perl5 module source text
+0 search/1 package
+0 regex \^package[\ \t]+[A-Za-z_]
+>0 regex \^package[\ \t]+[0-9A-Za-z_:]+\ *; Perl5 module source text
# not 'p', check other lines
-0 byte !0x70
+0 search/1 !p
>0 regex \^package[\ \t]+[0-9A-Za-z_:]+\ *;
>>0 regex \^1\ *;|\^(use|sub|my)\ .*[(;{=] Perl5 module source text
@@ -28,21 +34,21 @@
# Perl POD documents
# From: Tom Hukins <tom@eborcom.com>
-0 string/B \=pod\n Perl POD document
-0 string/B \n\=pod\n Perl POD document
-0 string/B \=head1\ Perl POD document
-0 string/B \n\=head1\ Perl POD document
-0 string/B \=head2\ Perl POD document
-0 string/B \n\=head2\ Perl POD document
+0 search/1/B \=pod\n Perl POD document text
+0 search/1/B \n\=pod\n Perl POD document text
+0 search/1/B \=head1\ Perl POD document text
+0 search/1/B \n\=head1\ Perl POD document text
+0 search/1/B \=head2\ Perl POD document text
+0 search/1/B \n\=head2\ Perl POD document text
# Perl Storable data files.
-0 string perl-store perl Storable(v0.6) data
+0 string perl-store perl Storable (v0.6) data
>4 byte >0 (net-order %d)
>>4 byte &01 (network-ordered)
>>4 byte =3 (major 1)
>>4 byte =2 (major 1)
-0 string pst0 perl Storable(v0.7) data
+0 string pst0 perl Storable (v0.7) data
>4 byte >0
>>4 byte &01 (network-ordered)
>>4 byte =5 (major 2)
diff --git a/contrib/file/Magdir/pgp b/contrib/file/Magdir/pgp
index 038d098..63042ad 100644
--- a/contrib/file/Magdir/pgp
+++ b/contrib/file/Magdir/pgp
@@ -1,13 +1,26 @@
#------------------------------------------------------------------------------
# pgp: file(1) magic for Pretty Good Privacy
+# see http://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html
#
0 beshort 0x9900 PGP key public ring
+!:mime application/x-pgp-keyring
0 beshort 0x9501 PGP key security ring
+!:mime application/x-pgp-keyring
0 beshort 0x9500 PGP key security ring
+!:mime application/x-pgp-keyring
0 beshort 0xa600 PGP encrypted data
-0 string -----BEGIN\040PGP PGP armored data
->15 string PUBLIC\040KEY\040BLOCK- public key block
->15 string MESSAGE- message
->15 string SIGNED\040MESSAGE- signed message
->15 string PGP\040SIGNATURE- signature
+#!:mime application/pgp-encrypted
+#0 string -----BEGIN\040PGP text/PGP armored data
+!:mime text/PGP # encoding: armored data
+#>15 string PUBLIC\040KEY\040BLOCK- public key block
+#>15 string MESSAGE- message
+#>15 string SIGNED\040MESSAGE- signed message
+#>15 string PGP\040SIGNATURE- signature
+
+2 string ---BEGIN\ PGP\ PUBLIC\ KEY\ BLOCK- PGP public key block
+!:mime application/pgp-keys
+0 string -----BEGIN\040PGP\40MESSAGE- PGP message
+!:mime application/pgp
+0 string -----BEGIN\040PGP\40SIGNATURE- PGP signature
+!:mime application/pgp-signature
diff --git a/contrib/file/Magdir/pkgadd b/contrib/file/Magdir/pkgadd
index dc8ef5d..876dacd 100644
--- a/contrib/file/Magdir/pkgadd
+++ b/contrib/file/Magdir/pkgadd
@@ -3,3 +3,4 @@
# pkgadd: file(1) magic for SysV R4 PKG Datastreams
#
0 string #\ PaCkAgE\ DaTaStReAm pkg Datastream (SVR4)
+!:mime application/x-svr4-package
diff --git a/contrib/file/Magdir/printer b/contrib/file/Magdir/printer
index 77ba780..15a1758 100644
--- a/contrib/file/Magdir/printer
+++ b/contrib/file/Magdir/printer
@@ -5,21 +5,26 @@
# PostScript, updated by Daniel Quinlan (quinlan@yggdrasil.com)
0 string %! PostScript document text
+!:mime application/postscript
>2 string PS-Adobe- conforming
->>11 string >\0 at level %.3s
->>>15 string EPS - type %s
->>>15 string Query - type %s
->>>15 string ExitServer - type %s
+>>11 string >\0 DSC level %.3s
+>>>15 string EPS \b, type %s
+>>>15 string Query \b, type %s
+>>>15 string ExitServer \b, type %s
+>>>15 search/1000 %%LanguageLevel:\
+>>>>&0 string >\0 \b, Level %s
# Some PCs have the annoying habit of adding a ^D as a document separator
0 string \004%! PostScript document text
+!:mime application/postscript
>3 string PS-Adobe- conforming
->>12 string >\0 at level %.3s
->>>16 string EPS - type %s
->>>16 string Query - type %s
->>>16 string ExitServer - type %s
+>>12 string >\0 DSC level %.3s
+>>>16 string EPS \b, type %s
+>>>16 string Query \b, type %s
+>>>16 string ExitServer \b, type %s
+>>>16 search/1000 %%LanguageLevel:\
+>>>>&0 string >\0 \b, Level %s
0 string \033%-12345X%!PS PostScript document
-
# DOS EPS Binary File Header
# From: Ed Sznyter <ews@Black.Market.NET>
0 belong 0xC5D0D3C6 DOS EPS Binary File
@@ -30,11 +35,13 @@
>>>20 long >0 TIFF starts at byte %d
>>>>24 long >0 length %d
-# Adobe's PostScript Printer Description (PPD) files
-# Yves Arrouye <arrouye@marin.fdn.fr>
+# Summary: Adobe's PostScript Printer Description File
+# Extension: .ppd
+# Reference: http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf, Section 3.8
+# Submitted by: Yves Arrouye <arrouye@marin.fdn.fr>
#
-0 string *PPD-Adobe: PPD file
->13 string x \b, ve
+0 string *PPD-Adobe:\x20 PPD file
+>&0 string x \b, version %s
# HP Printer Job Language
0 string \033%-12345X@PJL HP Printer Job Language data
diff --git a/contrib/file/Magdir/psion b/contrib/file/Magdir/psion
index 578ea59..7aa2d74 100644
--- a/contrib/file/Magdir/psion
+++ b/contrib/file/Magdir/psion
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# psion: file(1) magic for Psion handhelds data
# from: Peter Breitenlohner <peb@mppmu.mpg.de>
@@ -11,6 +10,7 @@
>4 lelong 0x1000006A application information file
>4 lelong 0x1000006D
>>8 lelong 0x1000007D sketch image
+!:mime image/x-psion-sketch
>>8 lelong 0x1000007E voice note
>>8 lelong 0x1000007F word file
>>8 lelong 0x10000085 OPL program
diff --git a/contrib/file/Magdir/revision b/contrib/file/Magdir/revision
index e47416a..a809cb9 100644
--- a/contrib/file/Magdir/revision
+++ b/contrib/file/Magdir/revision
@@ -7,3 +7,13 @@
# Conary changesets
# From: Jonathan Smith <smithj@rpath.com>
0 belong 0xea3f81bb Conary changeset data
+
+# Type: Git bundles (git-bundle)
+# From: Josh Triplett <josh@freedesktop.org>
+0 string #\ v2\ git\ bundle\n Git bundle
+
+# Type: Mercurial bundles
+# From: Seo Sanghyeon <tinuviel@sparcs.kaist.ac.kr>
+0 string HG10 Mercurial bundle,
+>4 string UN uncompressed
+>4 string BZ bzip2 compressed
diff --git a/contrib/file/Magdir/riff b/contrib/file/Magdir/riff
index 5aa9d10..c6e3070 100644
--- a/contrib/file/Magdir/riff
+++ b/contrib/file/Magdir/riff
@@ -33,6 +33,7 @@
>8 string RMP3 \b, MPEG Layer 3 audio
# Microsoft WAVE format (*.wav)
>8 string WAVE \b, WAVE audio
+!:mime audio/x-wav
>>20 leshort 1 \b, Microsoft PCM
>>>34 leshort >0 \b, %d bit
>>20 leshort 2 \b, Microsoft ADPCM
@@ -50,8 +51,10 @@
>>24 lelong >0 %d Hz
# Corel Draw Picture
>8 string CDRA \b, Corel Draw Picture
+!:mime image/x-coreldraw
# AVI == Audio Video Interleave
>8 string AVI\040 \b, AVI
+!:mime video/x-msvideo
>>12 string LIST
>>>20 string hdrlavih
>>>>&36 lelong x \b, %lu x
@@ -130,8 +133,9 @@
>>>>>>>(104.l+132) string/c divx DivX 4
>>>>>>>(104.l+132) string/c dx50 DivX 5
>>>>>>>(104.l+132) string/c xvid XviD
+>>>>>>>(104.l+132) string/c h264 H.264
>>>>>>>(104.l+132) string/c wmv3 Windows Media Video 9
->>>>>>>(104.l+132) string/c h264 X.264
+>>>>>>>(104.l+132) string/c h264 X.264 or H.264
>>>>>>>(104.l+132) lelong 0
##>>>>>>>(104.l+132) string x (%.4s)
# skip past first (video) LIST
diff --git a/contrib/file/Magdir/rpm b/contrib/file/Magdir/rpm
index 09ee51b..6d7e850 100644
--- a/contrib/file/Magdir/rpm
+++ b/contrib/file/Magdir/rpm
@@ -4,6 +4,7 @@
#
0 beshort 0xedab
>2 beshort 0xeedb RPM
+!:mime application/x-rpm
>>4 byte x v%d
>>6 beshort 0 bin
>>6 beshort 1 src
@@ -13,7 +14,7 @@
>>8 beshort 4 MIPS
>>8 beshort 5 PowerPC
>>8 beshort 6 68000
->>8 beshort 7 SGI
+>>8 beshort 7 SGI
>>8 beshort 8 RS6000
>>8 beshort 9 IA64
>>8 beshort 10 Sparc64
diff --git a/contrib/file/Magdir/rtf b/contrib/file/Magdir/rtf
index 8e2d416..8e5bfe0 100644
--- a/contrib/file/Magdir/rtf
+++ b/contrib/file/Magdir/rtf
@@ -5,8 +5,11 @@
# Duncan P. Simpson, D.P.Simpson@dcs.warwick.ac.uk
#
0 string {\\rtf Rich Text Format data,
->5 byte x version %c,
->6 string \\ansi ANSI
->6 string \\mac Apple Macintosh
->6 string \\pc IBM PC, code page 437
->6 string \\pca IBM PS/2, code page 850
+!:mime text/rtf
+>5 string 1 version 1,
+>>6 string \\ansi ANSI
+>>6 string \\mac Apple Macintosh
+>>6 string \\pc IBM PC, code page 437
+>>6 string \\pca IBM PS/2, code page 850
+>>6 default x unknown character set
+>5 default x unknown version
diff --git a/contrib/file/Magdir/ruby b/contrib/file/Magdir/ruby
new file mode 100644
index 0000000..de6f2a0
--- /dev/null
+++ b/contrib/file/Magdir/ruby
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# ruby: file(1) magic for Lua scripting language
+# URL: http://www.ruby-lang.org/
+# From: Reuben Thomas <rrt@sc3d.org>
+
+# Ruby scripts
+0 search/1/b #!\ /usr/bin/ruby Ruby script text executable
+0 search/1/b #!\ /usr/local/bin/ruby Ruby script text executable
+0 search/1 #!/usr/bin/env\ ruby Ruby script text executable
+0 search/1 #!\ /usr/bin/env\ ruby Ruby script text executable
diff --git a/contrib/file/Magdir/sc b/contrib/file/Magdir/sc
index 98599f2..72027d6 100644
--- a/contrib/file/Magdir/sc
+++ b/contrib/file/Magdir/sc
@@ -3,3 +3,4 @@
# sc: file(1) magic for "sc" spreadsheet
#
38 string Spreadsheet sc spreadsheet file
+!:mime application/x-sc
diff --git a/contrib/file/Magdir/scientific b/contrib/file/Magdir/scientific
index 81beac1..f7aedae 100644
--- a/contrib/file/Magdir/scientific
+++ b/contrib/file/Magdir/scientific
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# scientific: file(1) magic for scientific formats
#
@@ -58,3 +57,15 @@
>1104 ulong >0 %d x
>1108 ulong >0 %d,
>1120 ulong >0 %d bits/pixel
+
+# Type: GEDCOM genealogical (family history) data
+# From: Giuseppe Bilotta
+0 search/1/c 0\ HEAD GEDCOM genealogy text
+>&0 search 1\ GEDC
+>>&0 search 2\ VERS version
+>>>&1 search/1 >\0 %s
+# From: Phil Endecott <phil05@chezphil.org>
+0 string \000\060\000\040\000\110\000\105\000\101\000\104 GEDCOM data
+0 string \060\000\040\000\110\000\105\000\101\000\104\000 GEDCOM data
+0 string \376\377\000\060\000\040\000\110\000\105\000\101\000\104 GEDCOM data
+0 string \377\376\060\000\040\000\110\000\105\000\101\000\104\000 GEDCOM data
diff --git a/contrib/file/Magdir/securitycerts b/contrib/file/Magdir/securitycerts
new file mode 100644
index 0000000..aa55d21
--- /dev/null
+++ b/contrib/file/Magdir/securitycerts
@@ -0,0 +1,3 @@
+0 search/1 -----BEGIN\ CERTIFICATE------ RFC1421 Security Certificate text
+0 search/1 -----BEGIN\ NEW\ CERTIFICATE RFC1421 Security Certificate Signing Request text
+0 belong 0xedfeedfe Sun 'jks' Java Keystore File data
diff --git a/contrib/file/Magdir/sgi b/contrib/file/Magdir/sgi
index f7de138..5b54027 100644
--- a/contrib/file/Magdir/sgi
+++ b/contrib/file/Magdir/sgi
@@ -8,12 +8,17 @@
0 string PmNs PCP compiled namespace (V.0)
0 string PmN PCP compiled namespace
>3 string >\0 (V.%1.1s)
-3 lelong 0x84500526 PCP archive
+#3 lelong 0x84500526 PCP archive
+3 belong 0x84500526 PCP archive
>7 byte x (V.%d)
->20 lelong -2 temporal index
->20 lelong -1 metadata
->20 lelong 0 log volume #0
->20 lelong >0 log volume #%ld
+#>20 lelong -2 temporal index
+#>20 lelong -1 metadata
+#>20 lelong 0 log volume #0
+#>20 lelong >0 log volume #%ld
+>20 belong -2 temporal index
+>20 belong -1 metadata
+>20 belong 0 log volume #0
+>20 belong >0 log volume #%ld
>24 string >\0 host: %s
0 string PCPFolio PCP
>9 string Version: Archive Folio
@@ -30,6 +35,9 @@
0 string #pmlogger PCP pmlogger config
>10 string Version
>18 string >\0 (V%1.1s)
+0 string #pmdahotproc PCP pmdahotproc config
+>13 string Version
+>21 string >\0 (V%-3.3s)
0 string PcPh PCP Help
>4 string 1 Index
>4 string 2 Text
diff --git a/contrib/file/Magdir/sgml b/contrib/file/Magdir/sgml
index ba6c3ef..7e3391b 100644
--- a/contrib/file/Magdir/sgml
+++ b/contrib/file/Magdir/sgml
@@ -1,35 +1,63 @@
+#------------------------------------------------------------------------------
+# Type: SVG Vectorial Graphics
+# From: Noel Torres <tecnico@ejerciciosresueltos.com>
+0 string \<?xml\ version="
+>15 string >\0
+>>23 search/400 \<svg SVG Scalable Vector Graphics image
+!:mime image/svg+xml
+>>23 search/400 \<gnc-v2 GnuCash file
+!:mime application/x-gnucash
+
+# Sitemap file
+0 string \<?xml\ version="
+>15 string >\0
+>>23 search/400 \<urlset XML Sitemap document text
+!:mime application/xml-sitemap
#------------------------------------------------------------------------------
# sgml: file(1) magic for Standard Generalized Markup Language
# HyperText Markup Language (HTML) is an SGML document type,
# from Daniel Quinlan (quinlan@yggdrasil.com)
# adapted to string extenstions by Anthon van der Neut <anthon@mnt.org)
-0 string/cB \<!DOCTYPE\ html HTML document text
-0 string/cb \<head HTML document text
-0 string/cb \<title HTML document text
-0 string/cb \<html HTML document text
+0 search/1/cB \<!doctype\ html HTML document text
+!:mime text/html
+0 search/1/cb \<head HTML document text
+!:mime text/html
+0 search/1/cb \<title HTML document text
+!:mime text/html
+0 search/1/cb \<html HTML document text
+!:mime text/html
# Extensible markup language (XML), a subset of SGML
# from Marc Prud'hommeaux (marc@apocalypse.org)
-0 string/cb \<?xml XML document text
+0 search/1/cb \<?xml XML document text
+!:mime application/xml
0 string \<?xml\ version\ " XML
+!:mime application/xml
0 string \<?xml\ version=" XML
+!:mime application/xml
+>15 search/1 >\0 %.3s document text
+>>23 search/1 \<xsl:stylesheet (XSL stylesheet)
+>>24 search/1 \<xsl:stylesheet (XSL stylesheet)
0 string \<?xml\ version=' XML
->15 string >\0 %.3s document text
->>23 string \<xsl:stylesheet (XSL stylesheet)
->>24 string \<xsl:stylesheet (XSL stylesheet)
-0 string/b \<?xml XML document text
-0 string/cb \<?xml broken XML document text
+!:mime application/xml
+>15 search/1 >\0 %.3s document text
+>>23 search/1 \<xsl:stylesheet (XSL stylesheet)
+>>24 search/1 \<xsl:stylesheet (XSL stylesheet)
+0 search/1/b \<?xml XML document text
+!:mime application/xml
+0 search/1/b \<?XML broken XML document text
+!:mime application/xml
# SGML, mostly from rph@sq
-0 string/cb \<!doctype exported SGML document text
-0 string/cb \<!subdoc exported SGML subdocument text
-0 string/cb \<!-- exported SGML document text
+0 search/1/cb \<!doctype exported SGML document text
+0 search/1/cb \<!subdoc exported SGML subdocument text
+0 search/1/cb \<!-- exported SGML document text
# Web browser cookie files
# (Mozilla, Galeon, Netscape 4, Konqueror..)
# Ulf Harnhammar <ulfh@update.uu.se>
-0 string #\ HTTP\ Cookie\ File Web browser cookie text
-0 string #\ Netscape\ HTTP\ Cookie\ File Netscape cookie text
-0 string #\ KDE\ Cookie\ File Konqueror cookie text
+0 search/1 #\ HTTP\ Cookie\ File Web browser cookie text
+0 search/1 #\ Netscape\ HTTP\ Cookie\ File Netscape cookie text
+0 search/1 #\ KDE\ Cookie\ File Konqueror cookie text
diff --git a/contrib/file/Magdir/sharc b/contrib/file/Magdir/sharc
index 8c2cae4..0e0e4e3 100644
--- a/contrib/file/Magdir/sharc
+++ b/contrib/file/Magdir/sharc
@@ -6,14 +6,14 @@
# FutureGroove Music (dsp@futuregroove.de)
#------------------------------------------------------------------------
-0 string Draw RiscOS Drawfile
-0 string PACK RiscOS PackdDir archive
+#0 string Draw RiscOS Drawfile
+#0 string PACK RiscOS PackdDir archive
#------------------------------------------------------------------------
# SHARC DSP stuff (based on the FGM SHARC DSP SDK)
-0 string =! Assembler source
-0 string Analog ADi asm listing file
+#0 string =! Assembler source
+#0 string Analog ADi asm listing file
0 string .SYSTEM SHARC architecture file
0 string .system SHARC architecture file
diff --git a/contrib/file/Magdir/sketch b/contrib/file/Magdir/sketch
index d31d184..a14803e 100644
--- a/contrib/file/Magdir/sketch
+++ b/contrib/file/Magdir/sketch
@@ -1,5 +1,4 @@
-
#------------------------------------------------------------------------------
# Sketch Drawings: http://sketch.sourceforge.net/
# From: Edwin Mons <e@ik.nu>
-0 string ##Sketch Sketch document text
+0 search/1 ##Sketch Sketch document text
diff --git a/contrib/file/Magdir/softquad b/contrib/file/Magdir/softquad
index aa16904..ac7891d 100644
--- a/contrib/file/Magdir/softquad
+++ b/contrib/file/Magdir/softquad
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# softquad: file(1) magic for SoftQuad Publishing Software
#
@@ -19,7 +18,7 @@
0 short 0125252 SoftQuad DESC or font file binary
>2 short >0 - version %d
# Bitmaps...
-0 string SQ\ BITMAP1 SoftQuad Raster Format text
+0 search/1 SQ\ BITMAP1 SoftQuad Raster Format text
#0 string SQ\ BITMAP2 SoftQuad Raster Format data
# sqtroff intermediate language (replacement for ditroff int. lang.)
0 string X\ SoftQuad troff Context intermediate
@@ -27,3 +26,10 @@
>2 string hp for Hewlett-Packard LaserJet
>2 string impr for IMAGEN imPRESS
>2 string ps for PostScript
+
+# From: Michael Piefel <piefel@debian.org>
+# sqtroff intermediate language (replacement for ditroff int. lang.)
+0 string X\ 495 SoftQuad troff Context intermediate for AT&T 495 laser printer
+0 string X\ hp SoftQuad troff Context intermediate for HP LaserJet
+0 string X\ impr SoftQuad troff Context intermediate for IMAGEN imPRESS
+0 string X\ ps SoftQuad troff Context intermediate for PostScript
diff --git a/contrib/file/Magdir/spectrum b/contrib/file/Magdir/spectrum
index ab9fd04..a48ac41 100644
--- a/contrib/file/Magdir/spectrum
+++ b/contrib/file/Magdir/spectrum
@@ -31,14 +31,19 @@
# TZX tape images
0 string ZXTape!\x1a Spectrum .TZX data
>8 byte x version %d
->9 byte x .%d
+>9 byte x \b.%d
# RZX input recording files
0 string RZX! Spectrum .RZX data
>4 byte x version %d
->5 byte x .%d
+>5 byte x \b.%d
-# And three sorts of disk image
+# Floppy disk images
0 string MV\ -\ CPCEMU\ Disk-Fil Amstrad/Spectrum .DSK data
0 string MV\ -\ CPC\ format\ Dis Amstrad/Spectrum DU54 .DSK data
0 string EXTENDED\ CPC\ DSK\ Fil Amstrad/Spectrum Extended .DSK data
+0 string SINCLAIR Spectrum .SCL Betadisk image
+
+# Hard disk images
+0 string RS-IDE\x1a Spectrum .HDF hard disk image
+>7 byte x \b, version 0x%02x
diff --git a/contrib/file/Magdir/tex b/contrib/file/Magdir/tex
index 52adb87..5416db1 100644
--- a/contrib/file/Magdir/tex
+++ b/contrib/file/Magdir/tex
@@ -1,46 +1,61 @@
-
#------------------------------------------------------------------------------
# tex: file(1) magic for TeX files
#
+# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
+#
# From <conklin@talisman.kaleida.com>
# Although we may know the offset of certain text fields in TeX DVI
# and font files, we can't use them reliably because they are not
# zero terminated. [but we do anyway, christos]
0 string \367\002 TeX DVI file
+!:mime application/x-dvi
>16 string >\0 (%s)
0 string \367\203 TeX generic font data
0 string \367\131 TeX packed font data
>3 string >\0 (%s)
0 string \367\312 TeX virtual font data
-0 string This\ is\ TeX, TeX transcript text
-0 string This\ is\ METAFONT, METAFONT transcript text
+0 search/1 This\ is\ TeX, TeX transcript text
+0 search/1 This\ is\ METAFONT, METAFONT transcript text
# There is no way to detect TeX Font Metric (*.tfm) files without
# breaking them apart and reading the data. The following patterns
# match most *.tfm files generated by METAFONT or afm2tfm.
2 string \000\021 TeX font metric data
+!:mime application/x-tex-tfm
>33 string >\0 (%s)
2 string \000\022 TeX font metric data
+!:mime application/x-tex-tfm
>33 string >\0 (%s)
# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
-0 string \\input\ texinfo Texinfo source text
-0 string This\ is\ Info\ file GNU Info text
+0 search/1 \\input\ texinfo Texinfo source text
+!:mime text/x-texinfo
+0 search/1 This\ is\ Info\ file GNU Info text
+!:mime text/x-info
# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
0 search/400 \\input TeX document text
+!:mime text/x-tex
0 search/400 \\section LaTeX document text
+!:mime text/x-tex
0 search/400 \\setlength LaTeX document text
+!:mime text/x-tex
0 search/400 \\documentstyle LaTeX document text
+!:mime text/x-tex
0 search/400 \\chapter LaTeX document text
+!:mime text/x-tex
0 search/400 \\documentclass LaTeX 2e document text
+!:mime text/x-tex
0 search/400 \\relax LaTeX auxiliary file
+!:mime text/x-tex
0 search/400 \\contentsline LaTeX table of contents
+!:mime text/x-tex
0 search/400 %\ -*-latex-*- LaTeX document text
+!:mime text/x-tex
# Tex document, from Hendrik Scholz <hendrik@scholz.net>
-0 string \\ifx TeX document text
+0 search/1 \\ifx TeX document text
# Index and glossary files
0 search/400 \\indexentry LaTeX raw index file
@@ -55,25 +70,24 @@
# file(1) magic for BibTex text files
# From Hendrik Scholz <hendrik@scholz.net>
-0 string/c @article{ BibTeX text file
-0 string/c @book{ BibTeX text file
-0 string/c @inbook{ BibTeX text file
-0 string/c @incollection{ BibTeX text file
-0 string/c @inproceedings{ BibTeX text file
-0 string/c @manual{ BibTeX text file
-0 string/c @misc{ BibTeX text file
-0 string/c @preamble{ BibTeX text file
-0 string/c @phdthesis{ BibTeX text file
-0 string/c @techreport{ BibTeX text file
-0 string/c @unpublished{ BibTeX text file
-
-73 string %%%\ \ BibTeX-file{ BibTex text file (with full header)
+0 search/1/c @article{ BibTeX text file
+0 search/1/c @book{ BibTeX text file
+0 search/1/c @inbook{ BibTeX text file
+0 search/1/c @incollection{ BibTeX text file
+0 search/1/c @inproceedings{ BibTeX text file
+0 search/1/c @manual{ BibTeX text file
+0 search/1/c @misc{ BibTeX text file
+0 search/1/c @preamble{ BibTeX text file
+0 search/1/c @phdthesis{ BibTeX text file
+0 search/1/c @techreport{ BibTeX text file
+0 search/1/c @unpublished{ BibTeX text file
-73 string %%%\ \ @BibTeX-style-file{ BibTeX style text file (with full header)
+73 search/1 %%%\ \ BibTeX-file{ BibTex text file (with full header)
-0 string %\ BibTeX\ standard\ bibliography\ BibTeX standard bibliography style text file
+73 search/1 %%%\ \ @BibTeX-style-file{ BibTeX style text file (with full header)
-0 string %\ BibTeX\ ` BibTeX custom bibliography style text file
+0 search/1 %\ BibTeX\ standard\ bibliography\ BibTeX standard bibliography style text file
-0 string @c\ @mapfile{ TeX font aliases text file
+0 search/1 %\ BibTeX\ ` BibTeX custom bibliography style text file
+0 search/1 @c\ @mapfile{ TeX font aliases text file
diff --git a/contrib/file/Magdir/troff b/contrib/file/Magdir/troff
index 01ad88a..337ca68 100644
--- a/contrib/file/Magdir/troff
+++ b/contrib/file/Magdir/troff
@@ -1,28 +1,32 @@
-
#------------------------------------------------------------------------------
# troff: file(1) magic for *roff
#
# updated by Daniel Quinlan (quinlan@yggdrasil.com)
# troff input
-0 string .\\" troff or preprocessor input text
-0 string '\\" troff or preprocessor input text
-0 string '.\\" troff or preprocessor input text
-0 string \\" troff or preprocessor input text
-0 string ''' troff or preprocessor input text
+0 search/1 .\\" troff or preprocessor input text
+!:mime text/troff
+0 search/1 '\\" troff or preprocessor input text
+!:mime text/troff
+0 search/1 '.\\" troff or preprocessor input text
+!:mime text/troff
+0 search/1 \\" troff or preprocessor input text
+!:mime text/troff
+0 search/1 ''' troff or preprocessor input text
+!:mime text/troff
# ditroff intermediate output text
-0 string x\ T ditroff output text
->4 string cat for the C/A/T phototypesetter
->4 string ps for PostScript
->4 string dvi for DVI
->4 string ascii for ASCII
->4 string lj4 for LaserJet 4
->4 string latin1 for ISO 8859-1 (Latin 1)
->4 string X75 for xditview at 75dpi
->>7 string -12 (12pt)
->4 string X100 for xditview at 100dpi
->>8 string -12 (12pt)
+0 search/1 x\ T ditroff output text
+>4 search/1 cat for the C/A/T phototypesetter
+>4 search/1 ps for PostScript
+>4 search/1 dvi for DVI
+>4 search/1 ascii for ASCII
+>4 search/1 lj4 for LaserJet 4
+>4 search/1 latin1 for ISO 8859-1 (Latin 1)
+>4 search/1 X75 for xditview at 75dpi
+>>7 search/1 -12 (12pt)
+>4 search/1 X100 for xditview at 100dpi
+>>8 search/1 -12 (12pt)
# output data formats
0 string \100\357 very old (C/A/T) troff output data
diff --git a/contrib/file/Magdir/unicode b/contrib/file/Magdir/unicode
index 45a32d45..5f4a576 100644
--- a/contrib/file/Magdir/unicode
+++ b/contrib/file/Magdir/unicode
@@ -1,15 +1,14 @@
-
#---------------------------------------------------------------------------
# Unicode: BOM prefixed text files - Adrian Havill <havill@turbolinux.co.jp>
+# GRR: These types should be recognised in file_ascmagic so these
+# encodings can be treated by text patterns.
+# Missing types are already dealt with internally.
#
0 string +/v8 Unicode text, UTF-7
0 string +/v9 Unicode text, UTF-7
0 string +/v+ Unicode text, UTF-7
0 string +/v/ Unicode text, UTF-7
-0 string \357\273\277 Unicode text, UTF-8
0 string \335\163\146\163 Unicode text, UTF-8-EBCDIC
0 string \376\377\000\000 Unicode text, UTF-32, big-endian
0 string \377\376\000\000 Unicode text, UTF-32, little-endian
-0 string \376\377 Unicode text, UTF-16, big-endian
-0 string \377\376 Unicode text, UTF-16, little-endian
0 string \016\376\377 Unicode text, SCSU (Standard Compression Scheme for Unicode)
diff --git a/contrib/file/Magdir/uuencode b/contrib/file/Magdir/uuencode
index 7e88619..982cba9 100644
--- a/contrib/file/Magdir/uuencode
+++ b/contrib/file/Magdir/uuencode
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# uuencode: file(1) magic for ASCII-encoded files
#
@@ -9,22 +8,22 @@
# punctuation and survives BITNET gateways better.) If regular expressions
# were supported, this entry could possibly be split into two with
# "begin\040\.\*\012M" or "begin\040\.\*\012h" (where \. and \* are REs).
-0 string begin\040 uuencoded or xxencoded text
+0 search/1 begin\ uuencoded or xxencoded text
# btoa(1) is an alternative to uuencode that requires less space.
-0 string xbtoa\ Begin btoa'd text
+0 search/1 xbtoa\ Begin btoa'd text
# ship(1) is another, much cooler alternative to uuencode.
# Greg Roelofs, newt@uchicago.edu
-0 string $\012ship ship'd binary text
+0 search/1 $\012ship ship'd binary text
# bencode(8) is used to encode compressed news batches (Bnews/Cnews only?)
# Greg Roelofs, newt@uchicago.edu
-0 string Decode\ the\ following\ with\ bdeco bencoded News text
+0 search/1 Decode\ the\ following\ with\ bdeco bencoded News text
# BinHex is the Macintosh ASCII-encoded file format (see also "apple")
# Daniel Quinlan, quinlan@yggdrasil.com
-11 string must\ be\ converted\ with\ BinHex BinHex binary text
->41 string x \b, version %.3s
+11 search/1 must\ be\ converted\ with\ BinHex BinHex binary text
+>41 search/1 x \b, version %.3s
-# GRR: is MIME BASE64 encoding handled somewhere?
+# GRR: handle BASE64
diff --git a/contrib/file/Magdir/varied.script b/contrib/file/Magdir/varied.script
index ab5bece..61f935c 100644
--- a/contrib/file/Magdir/varied.script
+++ b/contrib/file/Magdir/varied.script
@@ -10,3 +10,9 @@
0 string #!\ script text executable
>3 string >\0 for %s
+# From: arno <arenevier@fdn.fr>
+# mozilla xpconnect typelib
+# see http://www.mozilla.org/scriptable/typelib_file.html
+0 string XPCOM\nTypeLib\r\n\032 XPConnect Typelib
+>0x10 byte x version %d
+>>0x11 byte x \b.%d
diff --git a/contrib/file/Magdir/vorbis b/contrib/file/Magdir/vorbis
index 5957ea0..cbef5fd 100644
--- a/contrib/file/Magdir/vorbis
+++ b/contrib/file/Magdir/vorbis
@@ -11,16 +11,40 @@
# probable things advanced users would want to uncomment are probably
# the number of comments and the encoder version.
#
+# FIXME: The first match has been made a search, so that it can skip
+# over prepended ID3 tags. This will work for MIME type detection, but
+# won't work for detecting other properties of the file (they all need
+# to be made relative to the search). In any case, if the file has ID3
+# tags, the ID3 information will be printed, not the Ogg information,
+# so until that's fixed, this doesn't matter.
+# FIXME[2]: Disable the above for now, since search assumes text mode.
+#
# --- Ogg Framing ---
-0 string OggS Ogg data
+#0 search/1000 OggS Ogg data
+0 string OggS Ogg data
+!:mime application/ogg
>4 byte !0 UNKNOWN REVISION %u
##>4 byte 0 revision 0
>4 byte 0
##>>14 lelong x (Serial %lX)
# non-Vorbis content: FLAC (Free Lossless Audio Codec, http://flac.sourceforge.net)
->>28 string fLaC \b, FLAC audio
+>>28 string \x7fFLAC \b, FLAC audio
# non-Vorbis content: Theora
>>28 string \x80theora \b, Theora video
+# non-Vorbis content: Kate
+>>28 string \x80kate\0\0\0\0 \b, Kate
+>>>37 ubyte x v%u
+>>>38 ubyte x \b.%u,
+>>>40 byte 0 utf8 encoding,
+>>>40 byte !0 unknown character encoding,
+>>>60 string >\0 language %s,
+>>>60 string \0 no language set,
+>>>76 string >\0 category %s
+>>>76 string \0 no category set
+# non-Vorbis content: Skeleton
+>>28 string fishead\0 \b, Skeleton
+>>>36 short x v%u
+>>>40 short x \b.%u
# non-Vorbis content: Speex
>>28 string Speex\ \ \ \b, Speex audio
# non-Vorbis content: OGM
diff --git a/contrib/file/Magdir/warc b/contrib/file/Magdir/warc
new file mode 100644
index 0000000..968e267
--- /dev/null
+++ b/contrib/file/Magdir/warc
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# warc: file(1) magic for WARC files
+
+0 string WARC/ WARC Archive
+>5 string x version %.4s
diff --git a/contrib/file/Magdir/weak b/contrib/file/Magdir/weak
new file mode 100644
index 0000000..21324ea
--- /dev/null
+++ b/contrib/file/Magdir/weak
@@ -0,0 +1,15 @@
+#------------------------------------------------------------------------------
+# weak: file(1) magic for very weak magic entries, disabled by default
+#
+# These entries are so weak that they might interfere identification of
+# other formats. Example include:
+# - Only identify for 1 or 2 bytes
+# - Match against very wide range of values
+# - Match against generic word in some spoken languages (e.g. English)
+
+# Summary: Computer Graphics Metafile
+# Extension: .cgm
+#0 beshort&0xffe0 0x0020 binary Computer Graphics Metafile
+#0 beshort 0x3020 character Computer Graphics Metafile
+
+#0 string =!! Bennet Yee's "face" format
diff --git a/contrib/file/Magdir/windows b/contrib/file/Magdir/windows
new file mode 100644
index 0000000..5cde739
--- /dev/null
+++ b/contrib/file/Magdir/windows
@@ -0,0 +1,115 @@
+
+#------------------------------------------------------------------------------
+# windows: file(1) magic for Microsoft Windows
+#
+# This file is mainly reserved for files where programs
+# using them are run almost always on MS Windows 3.x or
+# above, or files only used exclusively in Windows OS,
+# where there is no better category to allocate for.
+# For example, even though WinZIP almost run on Windows
+# only, it is better to treat them as "archive" instead.
+# For format usable in DOS, such as generic executable
+# format, please specify under "msdos" file.
+#
+
+
+# Summary: Outlook Express DBX file
+# Extension: .dbx
+# Created by: Christophe Monniez
+0 string \xCF\xAD\x12\xFE MS Outlook Express DBX file
+>4 byte =0xC5 \b, message database
+>4 byte =0xC6 \b, folder database
+>4 byte =0xC7 \b, account information
+>4 byte =0x30 \b, offline database
+
+
+# Summary: Windows crash dump
+# Extension: .dmp
+# Created by: Andreas Schuster (http://computer.forensikblog.de/)
+# Reference (1): http://computer.forensikblog.de/en/2008/02/64bit_magic.html
+# Modified by (1): Abel Cheung (Avoid match with first 4 bytes only)
+0 string PAGE
+>4 string DUMP MS Windows 32bit crash dump
+>>0x05c byte 0 \b, no PAE
+>>0x05c byte 1 \b, PAE
+>>0xf88 lelong 1 \b, full dump
+>>0xf88 lelong 2 \b, kernel dump
+>>0xf88 lelong 3 \b, small dump
+>>0x068 lelong x \b, %ld pages
+>4 string DU64 MS Windows 64bit crash dump
+>>0xf98 lelong 1 \b, full dump
+>>0xf98 lelong 2 \b, kernel dump
+>>0xf98 lelong 3 \b, small dump
+>>0x090 lequad x \b, %lld pages
+
+
+# Summary: Vista Event Log
+# Extension: .evtx
+# Created by: Andreas Schuster (http://computer.forensikblog.de/)
+# Reference (1): http://computer.forensikblog.de/en/2007/05/some_magic.html
+0 string ElfFile\0 MS Windows Vista Event Log
+>0x2a leshort x \b, %d chunks
+>>0x10 lelong x \b (no. %d in use)
+>0x18 lelong >1 \b, next record no. %d
+>0x18 lelong =1 \b, empty
+>0x78 lelong &1 \b, DIRTY
+>0x78 lelong &2 \b, FULL
+
+
+# Summary: Windows 3.1 group files
+# Extension: .grp
+# Created by: unknown
+0 string \120\115\103\103 MS Windows 3.1 group files
+
+
+# Summary: Old format help files
+# Extension: .hlp
+# Created by: Dirk Jagdmann <doj@cubic.org>
+0 lelong 0x00035f3f MS Windows 3.x help file
+
+
+# Summary: Hyper terminal
+# Extension: .ht
+# Created by: unknown
+0 string HyperTerminal\
+>15 string 1.0\ --\ HyperTerminal\ data\ file MS Windows HyperTerminal profile
+
+
+# Summary: Windows shortcut
+# Extension: .lnk
+# Created by: unknown
+0 string \114\0\0\0\001\024\002\0\0\0\0\0\300\0\0\0\0\0\0\106 MS Windows shortcut
+
+
+# Summary: Outlook Personal Folders
+# Created by: unknown
+0 lelong 0x4E444221 Microsoft Outlook email folder
+>10 leshort 0x0e (<=2002)
+>10 leshort 0x17 (>=2003)
+
+
+# Summary: Windows help cache
+# Created by: unknown
+0 string \164\146\115\122\012\000\000\000\001\000\000\000 MS Windows help cache
+
+
+# Summary: IE cache file
+# Created by: Christophe Monniez
+0 string Client\ UrlCache\ MMF Internet Explorer cache file
+>20 string >\0 version %s
+
+
+# Summary: Registry files
+# Created by: unknown
+# Modified by (1): Joerg Jenderek
+0 string regf MS Windows registry file, NT/2000 or above
+0 string CREG MS Windows 95/98/ME registry file
+0 string SHCC3 MS Windows 3.1 registry file
+
+
+# Summary: Windows Registry text
+# Extension: .reg
+# Submitted by: Abel Cheung <abelcheung@gmail.com>
+0 string REGEDIT4\r\n\r\n Windows Registry text (Win95 or above)
+0 string Windows\ Registry\ Editor\
+>&0 string Version\ 5.00\r\n\r\n Windows Registry text (Win2K or above)
diff --git a/contrib/file/Magdir/wordprocessors b/contrib/file/Magdir/wordprocessors
index 546d261..8965d33 100644
--- a/contrib/file/Magdir/wordprocessors
+++ b/contrib/file/Magdir/wordprocessors
@@ -1,4 +1,3 @@
-
#------------------------------------------------------------------------------
# wordprocessors: file(1) magic fo word processors.
#
@@ -12,7 +11,7 @@
>26 byte 0x46 \b, A4
#WordPerfect type files Version 1.6 - PLEASE DO NOT REMOVE THIS LINE
-0 string \377WPC\020\000\000\000\022\012\001\001\000\000\000\000 (WP) loadable text
+0 string \377WPC\020\000\000\000\022\012\001\001\000\000\000\000 (WP) loadable file
>15 byte 0 Optimized for Intel
>15 byte 1 Optimized for Non-Intel
1 string WPC (Corel/WP)
@@ -107,6 +106,7 @@
0 string HWP\ Document\ File Hangul (Korean) Word Processor File 3.0
# From: Won-Kyu Park <wkpark@kldp.org>
512 string R\0o\0o\0t\0 Hangul (Korean) Word Processor File 2000
+!:mime application/x-hwp
# CosmicBook, from Benoît Rouits
0 string CSBK Ted Neslson's CosmicBook hypertext file
@@ -122,15 +122,29 @@
2 string IIXPR3 Intel Quark Express Document (English)
2 string IIXPRa Intel Quark Express Document (Korean)
2 string MMXPR3 Motorola Quark Express Document (English)
+!:mime application/x-quark-xpress-3
2 string MMXPRa Motorola Quark Express Document (Korean)
# adobe indesign (document, whatever...) from querkan
0 belong 0x0606edf5 Adobe InDesign
>16 string DOCUMENT Document
-# From: Michael Piefel <piefel@debian.org>
-# sqtroff intermediate language (replacement for ditroff int. lang.)
-0 string X\ 495 SoftQuad troff Context intermediate for AT&T 495 laser printer
-0 string X\ hp SoftQuad troff Context intermediate for HP LaserJet
-0 string X\ impr SoftQuad troff Context intermediate for IMAGEN imPRESS
-0 string X\ ps SoftQuad troff Context intermediate for PostScript
+#------------------------------------------------------------------------------
+# ichitaro456: file(1) magic for Just System Word Processor Ichitaro
+#
+# Contributor kenzo-:
+# Reversed-engineered JS Ichitaro magic numbers
+#
+
+0 string DOC
+>43 byte 0x14 Just System Word Processor Ichitaro v4
+!:mime application/x-ichitaro4
+>144 string JDASH application/x-ichitaro4
+
+0 string DOC
+>43 byte 0x15 Just System Word Processor Ichitaro v5
+!:mime application/x-ichitaro5
+
+0 string DOC
+>43 byte 0x16 Just System Word Processor Ichitaro v6
+!:mime application/x-ichitaro6
diff --git a/contrib/file/Magdir/xilinx b/contrib/file/Magdir/xilinx
new file mode 100644
index 0000000..8f411ce
--- /dev/null
+++ b/contrib/file/Magdir/xilinx
@@ -0,0 +1,34 @@
+
+#------------------------------------------------------------------------------
+# This is Aaron's attempt at a MAGIC file for Xilinx .bit files.
+# Xilinx-Magic@RevRagnarok.com
+# Got the info from FPGA-FAQ 0026
+#
+# First there is the sync header and its length
+0 beshort 0x0009
+>2 belong =0x0ff00ff0
+>>&0 belong =0x0ff00ff0
+>>>&0 beshort =0x0000
+>>>>&0 pstring a Xilinx BIT data
+# Next is a Pascal-style string with the NCD name. We want to capture that.
+>>>>0x0F pstring x - from %s
+# It is followed by a NUL
+>>>>>&1 byte 0x00
+# And then 'b'
+>>>>>&2 string b
+# With the part number:
+#>>>>>&5 string 4v (Virtex4)
+#>>>>>&5 string 2v (Virtex II
+#>>>>>>&0 string !p \b)
+#>>>>>>&0 string p Pro)
+>>>>>&4 pstring x - for %s
+# And then NUL / 'c' / Build Data / NUL / 'd' / Date / NUL / 'e' / Data Length
+>>>>>>&1 byte 0x00
+>>>>>>&2 string c
+>>>>>>&4 pstring x - built %s
+>>>>>>>&1 byte 0x00
+>>>>>>>&2 string d
+>>>>>>>&4 pstring x \b(%s)
+>>>>>>>>&1 byte 0x00
+>>>>>>>>&2 string e
+>>>>>>>>&4 belong x - data length 0x%lx
diff --git a/contrib/file/Makefile.am b/contrib/file/Makefile.am
index 730ad32..104dd8f 100644
--- a/contrib/file/Makefile.am
+++ b/contrib/file/Makefile.am
@@ -1,219 +1,236 @@
-pkgdata_DATA = magic magic.mime magic.mgc magic.mime.mgc
+#
+# $File: Makefile.am,v 1.43 2008/08/08 08:24:06 christos Exp $
+#
+MAGIC_FRAGMENT_BASE = Magdir
+MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE)
-EXTRA_DIST = magic2mime Localstuff Header magic.mime $(magic_FRAGMENTS)
+pkgdata_DATA = magic.mgc
-CLEANFILES = magic magic.mgc magic.mime.mgc
+EXTRA_DIST = Header Localstuff \
+$(MAGIC_FRAGMENT_DIR)/acorn \
+$(MAGIC_FRAGMENT_DIR)/adi \
+$(MAGIC_FRAGMENT_DIR)/adventure \
+$(MAGIC_FRAGMENT_DIR)/allegro \
+$(MAGIC_FRAGMENT_DIR)/alliant \
+$(MAGIC_FRAGMENT_DIR)/alpha \
+$(MAGIC_FRAGMENT_DIR)/amanda \
+$(MAGIC_FRAGMENT_DIR)/amigaos \
+$(MAGIC_FRAGMENT_DIR)/animation \
+$(MAGIC_FRAGMENT_DIR)/apl \
+$(MAGIC_FRAGMENT_DIR)/apple \
+$(MAGIC_FRAGMENT_DIR)/applix \
+$(MAGIC_FRAGMENT_DIR)/archive \
+$(MAGIC_FRAGMENT_DIR)/asterix \
+$(MAGIC_FRAGMENT_DIR)/att3b \
+$(MAGIC_FRAGMENT_DIR)/audio \
+$(MAGIC_FRAGMENT_DIR)/basis \
+$(MAGIC_FRAGMENT_DIR)/bflt \
+$(MAGIC_FRAGMENT_DIR)/blender \
+$(MAGIC_FRAGMENT_DIR)/blit \
+$(MAGIC_FRAGMENT_DIR)/bout \
+$(MAGIC_FRAGMENT_DIR)/bsdi \
+$(MAGIC_FRAGMENT_DIR)/btsnoop \
+$(MAGIC_FRAGMENT_DIR)/c-lang \
+$(MAGIC_FRAGMENT_DIR)/c64 \
+$(MAGIC_FRAGMENT_DIR)/cad \
+$(MAGIC_FRAGMENT_DIR)/cafebabe \
+$(MAGIC_FRAGMENT_DIR)/cddb \
+$(MAGIC_FRAGMENT_DIR)/chord \
+$(MAGIC_FRAGMENT_DIR)/cisco \
+$(MAGIC_FRAGMENT_DIR)/citrus \
+$(MAGIC_FRAGMENT_DIR)/clarion \
+$(MAGIC_FRAGMENT_DIR)/claris \
+$(MAGIC_FRAGMENT_DIR)/clipper \
+$(MAGIC_FRAGMENT_DIR)/commands \
+$(MAGIC_FRAGMENT_DIR)/communications \
+$(MAGIC_FRAGMENT_DIR)/compress \
+$(MAGIC_FRAGMENT_DIR)/console \
+$(MAGIC_FRAGMENT_DIR)/convex \
+$(MAGIC_FRAGMENT_DIR)/cracklib \
+$(MAGIC_FRAGMENT_DIR)/ctags \
+$(MAGIC_FRAGMENT_DIR)/dact \
+$(MAGIC_FRAGMENT_DIR)/database \
+$(MAGIC_FRAGMENT_DIR)/diamond \
+$(MAGIC_FRAGMENT_DIR)/diff \
+$(MAGIC_FRAGMENT_DIR)/digital \
+$(MAGIC_FRAGMENT_DIR)/dolby \
+$(MAGIC_FRAGMENT_DIR)/dump \
+$(MAGIC_FRAGMENT_DIR)/dyadic \
+$(MAGIC_FRAGMENT_DIR)/editors \
+$(MAGIC_FRAGMENT_DIR)/efi \
+$(MAGIC_FRAGMENT_DIR)/elf \
+$(MAGIC_FRAGMENT_DIR)/encore \
+$(MAGIC_FRAGMENT_DIR)/epoc \
+$(MAGIC_FRAGMENT_DIR)/erlang \
+$(MAGIC_FRAGMENT_DIR)/esri \
+$(MAGIC_FRAGMENT_DIR)/fcs \
+$(MAGIC_FRAGMENT_DIR)/filesystems \
+$(MAGIC_FRAGMENT_DIR)/flash \
+$(MAGIC_FRAGMENT_DIR)/fonts \
+$(MAGIC_FRAGMENT_DIR)/fortran \
+$(MAGIC_FRAGMENT_DIR)/frame \
+$(MAGIC_FRAGMENT_DIR)/freebsd \
+$(MAGIC_FRAGMENT_DIR)/fsav \
+$(MAGIC_FRAGMENT_DIR)/games \
+$(MAGIC_FRAGMENT_DIR)/gcc \
+$(MAGIC_FRAGMENT_DIR)/geos \
+$(MAGIC_FRAGMENT_DIR)/gimp \
+$(MAGIC_FRAGMENT_DIR)/gnome-keyring \
+$(MAGIC_FRAGMENT_DIR)/gnu \
+$(MAGIC_FRAGMENT_DIR)/gnumeric \
+$(MAGIC_FRAGMENT_DIR)/grace \
+$(MAGIC_FRAGMENT_DIR)/graphviz \
+$(MAGIC_FRAGMENT_DIR)/gringotts \
+$(MAGIC_FRAGMENT_DIR)/hitachi-sh \
+$(MAGIC_FRAGMENT_DIR)/hp \
+$(MAGIC_FRAGMENT_DIR)/human68k \
+$(MAGIC_FRAGMENT_DIR)/ibm370 \
+$(MAGIC_FRAGMENT_DIR)/ibm6000 \
+$(MAGIC_FRAGMENT_DIR)/iff \
+$(MAGIC_FRAGMENT_DIR)/images \
+$(MAGIC_FRAGMENT_DIR)/inform \
+$(MAGIC_FRAGMENT_DIR)/intel \
+$(MAGIC_FRAGMENT_DIR)/interleaf \
+$(MAGIC_FRAGMENT_DIR)/island \
+$(MAGIC_FRAGMENT_DIR)/ispell \
+$(MAGIC_FRAGMENT_DIR)/java \
+$(MAGIC_FRAGMENT_DIR)/jpeg \
+$(MAGIC_FRAGMENT_DIR)/karma \
+$(MAGIC_FRAGMENT_DIR)/kde \
+$(MAGIC_FRAGMENT_DIR)/lecter \
+$(MAGIC_FRAGMENT_DIR)/lex \
+$(MAGIC_FRAGMENT_DIR)/lif \
+$(MAGIC_FRAGMENT_DIR)/linux \
+$(MAGIC_FRAGMENT_DIR)/lisp \
+$(MAGIC_FRAGMENT_DIR)/llvm \
+$(MAGIC_FRAGMENT_DIR)/lua \
+$(MAGIC_FRAGMENT_DIR)/luks \
+$(MAGIC_FRAGMENT_DIR)/mach \
+$(MAGIC_FRAGMENT_DIR)/macintosh \
+$(MAGIC_FRAGMENT_DIR)/magic \
+$(MAGIC_FRAGMENT_DIR)/mail.news \
+$(MAGIC_FRAGMENT_DIR)/maple \
+$(MAGIC_FRAGMENT_DIR)/mathcad \
+$(MAGIC_FRAGMENT_DIR)/mathematica \
+$(MAGIC_FRAGMENT_DIR)/matroska \
+$(MAGIC_FRAGMENT_DIR)/mcrypt \
+$(MAGIC_FRAGMENT_DIR)/mercurial \
+$(MAGIC_FRAGMENT_DIR)/mime \
+$(MAGIC_FRAGMENT_DIR)/mips \
+$(MAGIC_FRAGMENT_DIR)/mirage \
+$(MAGIC_FRAGMENT_DIR)/misctools \
+$(MAGIC_FRAGMENT_DIR)/mkid \
+$(MAGIC_FRAGMENT_DIR)/mlssa \
+$(MAGIC_FRAGMENT_DIR)/mmdf \
+$(MAGIC_FRAGMENT_DIR)/modem \
+$(MAGIC_FRAGMENT_DIR)/motorola \
+$(MAGIC_FRAGMENT_DIR)/mozilla \
+$(MAGIC_FRAGMENT_DIR)/msdos \
+$(MAGIC_FRAGMENT_DIR)/msvc \
+$(MAGIC_FRAGMENT_DIR)/mup \
+$(MAGIC_FRAGMENT_DIR)/natinst \
+$(MAGIC_FRAGMENT_DIR)/ncr \
+$(MAGIC_FRAGMENT_DIR)/netbsd \
+$(MAGIC_FRAGMENT_DIR)/netscape \
+$(MAGIC_FRAGMENT_DIR)/netware \
+$(MAGIC_FRAGMENT_DIR)/news \
+$(MAGIC_FRAGMENT_DIR)/nitpicker \
+$(MAGIC_FRAGMENT_DIR)/ocaml \
+$(MAGIC_FRAGMENT_DIR)/octave \
+$(MAGIC_FRAGMENT_DIR)/ole2compounddocs \
+$(MAGIC_FRAGMENT_DIR)/olf \
+$(MAGIC_FRAGMENT_DIR)/os2 \
+$(MAGIC_FRAGMENT_DIR)/os400 \
+$(MAGIC_FRAGMENT_DIR)/os9 \
+$(MAGIC_FRAGMENT_DIR)/osf1 \
+$(MAGIC_FRAGMENT_DIR)/palm \
+$(MAGIC_FRAGMENT_DIR)/parix \
+$(MAGIC_FRAGMENT_DIR)/pbm \
+$(MAGIC_FRAGMENT_DIR)/pdf \
+$(MAGIC_FRAGMENT_DIR)/pdp \
+$(MAGIC_FRAGMENT_DIR)/perl \
+$(MAGIC_FRAGMENT_DIR)/pgp \
+$(MAGIC_FRAGMENT_DIR)/pkgadd \
+$(MAGIC_FRAGMENT_DIR)/plan9 \
+$(MAGIC_FRAGMENT_DIR)/plus5 \
+$(MAGIC_FRAGMENT_DIR)/printer \
+$(MAGIC_FRAGMENT_DIR)/project \
+$(MAGIC_FRAGMENT_DIR)/psdbms \
+$(MAGIC_FRAGMENT_DIR)/psion \
+$(MAGIC_FRAGMENT_DIR)/pulsar \
+$(MAGIC_FRAGMENT_DIR)/pyramid \
+$(MAGIC_FRAGMENT_DIR)/python \
+$(MAGIC_FRAGMENT_DIR)/revision \
+$(MAGIC_FRAGMENT_DIR)/riff \
+$(MAGIC_FRAGMENT_DIR)/rpm \
+$(MAGIC_FRAGMENT_DIR)/rtf \
+$(MAGIC_FRAGMENT_DIR)/ruby \
+$(MAGIC_FRAGMENT_DIR)/sc \
+$(MAGIC_FRAGMENT_DIR)/sccs \
+$(MAGIC_FRAGMENT_DIR)/scientific \
+$(MAGIC_FRAGMENT_DIR)/securitycerts \
+$(MAGIC_FRAGMENT_DIR)/sendmail \
+$(MAGIC_FRAGMENT_DIR)/sequent \
+$(MAGIC_FRAGMENT_DIR)/sgi \
+$(MAGIC_FRAGMENT_DIR)/sgml \
+$(MAGIC_FRAGMENT_DIR)/sharc \
+$(MAGIC_FRAGMENT_DIR)/sinclair \
+$(MAGIC_FRAGMENT_DIR)/sketch \
+$(MAGIC_FRAGMENT_DIR)/smalltalk \
+$(MAGIC_FRAGMENT_DIR)/sniffer \
+$(MAGIC_FRAGMENT_DIR)/softquad \
+$(MAGIC_FRAGMENT_DIR)/spec \
+$(MAGIC_FRAGMENT_DIR)/spectrum \
+$(MAGIC_FRAGMENT_DIR)/sql \
+$(MAGIC_FRAGMENT_DIR)/sun \
+$(MAGIC_FRAGMENT_DIR)/sysex \
+$(MAGIC_FRAGMENT_DIR)/teapot \
+$(MAGIC_FRAGMENT_DIR)/terminfo \
+$(MAGIC_FRAGMENT_DIR)/tex \
+$(MAGIC_FRAGMENT_DIR)/tgif \
+$(MAGIC_FRAGMENT_DIR)/ti-8x \
+$(MAGIC_FRAGMENT_DIR)/timezone \
+$(MAGIC_FRAGMENT_DIR)/troff \
+$(MAGIC_FRAGMENT_DIR)/tuxedo \
+$(MAGIC_FRAGMENT_DIR)/typeset \
+$(MAGIC_FRAGMENT_DIR)/unicode \
+$(MAGIC_FRAGMENT_DIR)/unknown \
+$(MAGIC_FRAGMENT_DIR)/uuencode \
+$(MAGIC_FRAGMENT_DIR)/varied.out \
+$(MAGIC_FRAGMENT_DIR)/varied.script \
+$(MAGIC_FRAGMENT_DIR)/vax \
+$(MAGIC_FRAGMENT_DIR)/vicar \
+$(MAGIC_FRAGMENT_DIR)/virtutech \
+$(MAGIC_FRAGMENT_DIR)/visx \
+$(MAGIC_FRAGMENT_DIR)/vms \
+$(MAGIC_FRAGMENT_DIR)/vmware \
+$(MAGIC_FRAGMENT_DIR)/vorbis \
+$(MAGIC_FRAGMENT_DIR)/vxl \
+$(MAGIC_FRAGMENT_DIR)/warc \
+$(MAGIC_FRAGMENT_DIR)/weak \
+$(MAGIC_FRAGMENT_DIR)/windows \
+$(MAGIC_FRAGMENT_DIR)/wordprocessors \
+$(MAGIC_FRAGMENT_DIR)/xdelta \
+$(MAGIC_FRAGMENT_DIR)/xenix \
+$(MAGIC_FRAGMENT_DIR)/xilinx \
+$(MAGIC_FRAGMENT_DIR)/xo65 \
+$(MAGIC_FRAGMENT_DIR)/xwindows \
+$(MAGIC_FRAGMENT_DIR)/zilog \
+$(MAGIC_FRAGMENT_DIR)/zyxel
-magic: Header Localstuff $(magic_FRAGMENTS)
- cat $(srcdir)/Header $(srcdir)/Localstuff > $@
- for frag in $(magic_FRAGMENTS); do \
- if test -f $(srcdir)/$$frag; then \
- f=$(srcdir)/$$frag; \
- else \
- f=$$frag; \
- fi; \
- cat $$f; \
- done >> $@
+MAGIC = magic.mgc
+CLEANFILES = ${MAGIC}
+# FIXME: Build file natively as well so that it can be used to compile
+# the target's magic file
if IS_CROSS_COMPILE
FILE_COMPILE = file
+FILE_COMPILE_DEP =
else
FILE_COMPILE = $(top_builddir)/src/file
+FILE_COMPILE_DEP = $(FILE_COMPILE)
endif
-magic.mgc: magic
- $(FILE_COMPILE) -C -m magic
-
-magic.mime.mgc: magic.mime
- $(FILE_COMPILE) -C -m $(srcdir)/magic.mime
-
-magic_FRAGMENTS = \
-Magdir/acorn \
-Magdir/adi \
-Magdir/adventure \
-Magdir/allegro \
-Magdir/alliant \
-Magdir/alpha \
-Magdir/amanda \
-Magdir/amigaos \
-Magdir/animation \
-Magdir/apl \
-Magdir/apple \
-Magdir/applix \
-Magdir/archive \
-Magdir/asterix \
-Magdir/att3b \
-Magdir/audio \
-Magdir/basis \
-Magdir/bflt \
-Magdir/blender \
-Magdir/blit \
-Magdir/bout \
-Magdir/bsdi \
-Magdir/btsnoop \
-Magdir/cad \
-Magdir/cafebabe \
-Magdir/c-lang \
-Magdir/c64 \
-Magdir/cddb \
-Magdir/chord \
-Magdir/cisco \
-Magdir/citrus \
-Magdir/claris \
-Magdir/clipper \
-Magdir/cracklib \
-Magdir/spec \
-Magdir/commands \
-Magdir/communications \
-Magdir/compress \
-Magdir/console \
-Magdir/convex \
-Magdir/ctags \
-Magdir/dact \
-Magdir/database \
-Magdir/diamond \
-Magdir/diff \
-Magdir/digital \
-Magdir/dolby \
-Magdir/dump \
-Magdir/editors \
-Magdir/efi \
-Magdir/elf \
-Magdir/encore \
-Magdir/epoc \
-Magdir/esri \
-Magdir/fcs \
-Magdir/filesystems \
-Magdir/flash \
-Magdir/fonts \
-Magdir/fortran \
-Magdir/frame \
-Magdir/freebsd \
-Magdir/fsav \
-Magdir/games \
-Magdir/geos \
-Magdir/gcc \
-Magdir/gimp \
-Magdir/gnu \
-Magdir/grace \
-Magdir/gringotts \
-Magdir/hitachi-sh \
-Magdir/hp \
-Magdir/human68k \
-Magdir/ibm370 \
-Magdir/ibm6000 \
-Magdir/iff \
-Magdir/images \
-Magdir/intel \
-Magdir/interleaf \
-Magdir/island \
-Magdir/ispell \
-Magdir/java \
-Magdir/jpeg \
-Magdir/karma \
-Magdir/lecter \
-Magdir/lex \
-Magdir/lif \
-Magdir/linux \
-Magdir/lisp \
-Magdir/mach \
-Magdir/macintosh \
-Magdir/magic \
-Magdir/mail.news \
-Magdir/maple \
-Magdir/mathematica \
-Magdir/matroska \
-Magdir/mcrypt \
-Magdir/mime \
-Magdir/mips \
-Magdir/mirage \
-Magdir/misctools \
-Magdir/mkid \
-Magdir/mlssa \
-Magdir/mmdf \
-Magdir/modem \
-Magdir/motorola \
-Magdir/msdos \
-Magdir/msvc \
-Magdir/mup \
-Magdir/natinst \
-Magdir/ncr \
-Magdir/netbsd \
-Magdir/netscape \
-Magdir/news \
-Magdir/nitpicker \
-Magdir/ocaml \
-Magdir/octave \
-Magdir/olf \
-Magdir/os2 \
-Magdir/os400 \
-Magdir/os9 \
-Magdir/osf1 \
-Magdir/palm \
-Magdir/parix \
-Magdir/pbm \
-Magdir/pdf \
-Magdir/pdp \
-Magdir/perl \
-Magdir/pgp \
-Magdir/pkgadd \
-Magdir/plan9 \
-Magdir/plus5 \
-Magdir/printer \
-Magdir/project \
-Magdir/psdbms \
-Magdir/psion \
-Magdir/pulsar \
-Magdir/pyramid \
-Magdir/python \
-Magdir/revision \
-Magdir/riff \
-Magdir/rpm \
-Magdir/rtf \
-Magdir/sc \
-Magdir/sccs \
-Magdir/sendmail \
-Magdir/sequent \
-Magdir/sgi \
-Magdir/sgml \
-Magdir/sharc \
-Magdir/sinclair \
-Magdir/sketch \
-Magdir/smalltalk \
-Magdir/sniffer \
-Magdir/dyadic \
-Magdir/scientific \
-Magdir/softquad \
-Magdir/spectrum \
-Magdir/sql \
-Magdir/sun \
-Magdir/sysex \
-Magdir/teapot \
-Magdir/terminfo \
-Magdir/tex \
-Magdir/tgif \
-Magdir/ti-8x \
-Magdir/timezone \
-Magdir/troff \
-Magdir/tuxedo \
-Magdir/typeset \
-Magdir/unknown \
-Magdir/unicode \
-Magdir/uuencode \
-Magdir/varied.out \
-Magdir/varied.script \
-Magdir/vax \
-Magdir/vicar \
-Magdir/virtutech \
-Magdir/visx \
-Magdir/vms \
-Magdir/vmware \
-Magdir/vorbis \
-Magdir/vxl \
-Magdir/wordprocessors \
-Magdir/xdelta \
-Magdir/xenix \
-Magdir/xo65 \
-Magdir/xwindows \
-Magdir/zilog \
-Magdir/zyxel
+${MAGIC}: $(EXTRA_DIST) $(FILE_COMPILE_DEP)
+ $(FILE_COMPILE) -C -m $(MAGIC_FRAGMENT_DIR)
+ @mv $(MAGIC_FRAGMENT_BASE).mgc $@
diff --git a/contrib/file/Makefile.in b/contrib/file/Makefile.in
index ba2ef9d..d52e20d 100644
--- a/contrib/file/Makefile.in
+++ b/contrib/file/Makefile.in
@@ -36,10 +36,10 @@ subdir = magic
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SOURCES =
@@ -93,7 +93,6 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
@@ -109,6 +108,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
+WARNINGS = @WARNINGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -161,206 +161,238 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-pkgdata_DATA = magic magic.mime magic.mgc magic.mime.mgc
-EXTRA_DIST = magic2mime Localstuff Header magic.mime $(magic_FRAGMENTS)
-CLEANFILES = magic magic.mgc magic.mime.mgc
+
+#
+# $File: Makefile.am,v 1.43 2008/08/08 08:24:06 christos Exp $
+#
+MAGIC_FRAGMENT_BASE = Magdir
+MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE)
+pkgdata_DATA = magic.mgc
+EXTRA_DIST = Header Localstuff \
+$(MAGIC_FRAGMENT_DIR)/acorn \
+$(MAGIC_FRAGMENT_DIR)/adi \
+$(MAGIC_FRAGMENT_DIR)/adventure \
+$(MAGIC_FRAGMENT_DIR)/allegro \
+$(MAGIC_FRAGMENT_DIR)/alliant \
+$(MAGIC_FRAGMENT_DIR)/alpha \
+$(MAGIC_FRAGMENT_DIR)/amanda \
+$(MAGIC_FRAGMENT_DIR)/amigaos \
+$(MAGIC_FRAGMENT_DIR)/animation \
+$(MAGIC_FRAGMENT_DIR)/apl \
+$(MAGIC_FRAGMENT_DIR)/apple \
+$(MAGIC_FRAGMENT_DIR)/applix \
+$(MAGIC_FRAGMENT_DIR)/archive \
+$(MAGIC_FRAGMENT_DIR)/asterix \
+$(MAGIC_FRAGMENT_DIR)/att3b \
+$(MAGIC_FRAGMENT_DIR)/audio \
+$(MAGIC_FRAGMENT_DIR)/basis \
+$(MAGIC_FRAGMENT_DIR)/bflt \
+$(MAGIC_FRAGMENT_DIR)/blender \
+$(MAGIC_FRAGMENT_DIR)/blit \
+$(MAGIC_FRAGMENT_DIR)/bout \
+$(MAGIC_FRAGMENT_DIR)/bsdi \
+$(MAGIC_FRAGMENT_DIR)/btsnoop \
+$(MAGIC_FRAGMENT_DIR)/c-lang \
+$(MAGIC_FRAGMENT_DIR)/c64 \
+$(MAGIC_FRAGMENT_DIR)/cad \
+$(MAGIC_FRAGMENT_DIR)/cafebabe \
+$(MAGIC_FRAGMENT_DIR)/cddb \
+$(MAGIC_FRAGMENT_DIR)/chord \
+$(MAGIC_FRAGMENT_DIR)/cisco \
+$(MAGIC_FRAGMENT_DIR)/citrus \
+$(MAGIC_FRAGMENT_DIR)/clarion \
+$(MAGIC_FRAGMENT_DIR)/claris \
+$(MAGIC_FRAGMENT_DIR)/clipper \
+$(MAGIC_FRAGMENT_DIR)/commands \
+$(MAGIC_FRAGMENT_DIR)/communications \
+$(MAGIC_FRAGMENT_DIR)/compress \
+$(MAGIC_FRAGMENT_DIR)/console \
+$(MAGIC_FRAGMENT_DIR)/convex \
+$(MAGIC_FRAGMENT_DIR)/cracklib \
+$(MAGIC_FRAGMENT_DIR)/ctags \
+$(MAGIC_FRAGMENT_DIR)/dact \
+$(MAGIC_FRAGMENT_DIR)/database \
+$(MAGIC_FRAGMENT_DIR)/diamond \
+$(MAGIC_FRAGMENT_DIR)/diff \
+$(MAGIC_FRAGMENT_DIR)/digital \
+$(MAGIC_FRAGMENT_DIR)/dolby \
+$(MAGIC_FRAGMENT_DIR)/dump \
+$(MAGIC_FRAGMENT_DIR)/dyadic \
+$(MAGIC_FRAGMENT_DIR)/editors \
+$(MAGIC_FRAGMENT_DIR)/efi \
+$(MAGIC_FRAGMENT_DIR)/elf \
+$(MAGIC_FRAGMENT_DIR)/encore \
+$(MAGIC_FRAGMENT_DIR)/epoc \
+$(MAGIC_FRAGMENT_DIR)/erlang \
+$(MAGIC_FRAGMENT_DIR)/esri \
+$(MAGIC_FRAGMENT_DIR)/fcs \
+$(MAGIC_FRAGMENT_DIR)/filesystems \
+$(MAGIC_FRAGMENT_DIR)/flash \
+$(MAGIC_FRAGMENT_DIR)/fonts \
+$(MAGIC_FRAGMENT_DIR)/fortran \
+$(MAGIC_FRAGMENT_DIR)/frame \
+$(MAGIC_FRAGMENT_DIR)/freebsd \
+$(MAGIC_FRAGMENT_DIR)/fsav \
+$(MAGIC_FRAGMENT_DIR)/games \
+$(MAGIC_FRAGMENT_DIR)/gcc \
+$(MAGIC_FRAGMENT_DIR)/geos \
+$(MAGIC_FRAGMENT_DIR)/gimp \
+$(MAGIC_FRAGMENT_DIR)/gnome-keyring \
+$(MAGIC_FRAGMENT_DIR)/gnu \
+$(MAGIC_FRAGMENT_DIR)/gnumeric \
+$(MAGIC_FRAGMENT_DIR)/grace \
+$(MAGIC_FRAGMENT_DIR)/graphviz \
+$(MAGIC_FRAGMENT_DIR)/gringotts \
+$(MAGIC_FRAGMENT_DIR)/hitachi-sh \
+$(MAGIC_FRAGMENT_DIR)/hp \
+$(MAGIC_FRAGMENT_DIR)/human68k \
+$(MAGIC_FRAGMENT_DIR)/ibm370 \
+$(MAGIC_FRAGMENT_DIR)/ibm6000 \
+$(MAGIC_FRAGMENT_DIR)/iff \
+$(MAGIC_FRAGMENT_DIR)/images \
+$(MAGIC_FRAGMENT_DIR)/inform \
+$(MAGIC_FRAGMENT_DIR)/intel \
+$(MAGIC_FRAGMENT_DIR)/interleaf \
+$(MAGIC_FRAGMENT_DIR)/island \
+$(MAGIC_FRAGMENT_DIR)/ispell \
+$(MAGIC_FRAGMENT_DIR)/java \
+$(MAGIC_FRAGMENT_DIR)/jpeg \
+$(MAGIC_FRAGMENT_DIR)/karma \
+$(MAGIC_FRAGMENT_DIR)/kde \
+$(MAGIC_FRAGMENT_DIR)/lecter \
+$(MAGIC_FRAGMENT_DIR)/lex \
+$(MAGIC_FRAGMENT_DIR)/lif \
+$(MAGIC_FRAGMENT_DIR)/linux \
+$(MAGIC_FRAGMENT_DIR)/lisp \
+$(MAGIC_FRAGMENT_DIR)/llvm \
+$(MAGIC_FRAGMENT_DIR)/lua \
+$(MAGIC_FRAGMENT_DIR)/luks \
+$(MAGIC_FRAGMENT_DIR)/mach \
+$(MAGIC_FRAGMENT_DIR)/macintosh \
+$(MAGIC_FRAGMENT_DIR)/magic \
+$(MAGIC_FRAGMENT_DIR)/mail.news \
+$(MAGIC_FRAGMENT_DIR)/maple \
+$(MAGIC_FRAGMENT_DIR)/mathcad \
+$(MAGIC_FRAGMENT_DIR)/mathematica \
+$(MAGIC_FRAGMENT_DIR)/matroska \
+$(MAGIC_FRAGMENT_DIR)/mcrypt \
+$(MAGIC_FRAGMENT_DIR)/mercurial \
+$(MAGIC_FRAGMENT_DIR)/mime \
+$(MAGIC_FRAGMENT_DIR)/mips \
+$(MAGIC_FRAGMENT_DIR)/mirage \
+$(MAGIC_FRAGMENT_DIR)/misctools \
+$(MAGIC_FRAGMENT_DIR)/mkid \
+$(MAGIC_FRAGMENT_DIR)/mlssa \
+$(MAGIC_FRAGMENT_DIR)/mmdf \
+$(MAGIC_FRAGMENT_DIR)/modem \
+$(MAGIC_FRAGMENT_DIR)/motorola \
+$(MAGIC_FRAGMENT_DIR)/mozilla \
+$(MAGIC_FRAGMENT_DIR)/msdos \
+$(MAGIC_FRAGMENT_DIR)/msvc \
+$(MAGIC_FRAGMENT_DIR)/mup \
+$(MAGIC_FRAGMENT_DIR)/natinst \
+$(MAGIC_FRAGMENT_DIR)/ncr \
+$(MAGIC_FRAGMENT_DIR)/netbsd \
+$(MAGIC_FRAGMENT_DIR)/netscape \
+$(MAGIC_FRAGMENT_DIR)/netware \
+$(MAGIC_FRAGMENT_DIR)/news \
+$(MAGIC_FRAGMENT_DIR)/nitpicker \
+$(MAGIC_FRAGMENT_DIR)/ocaml \
+$(MAGIC_FRAGMENT_DIR)/octave \
+$(MAGIC_FRAGMENT_DIR)/ole2compounddocs \
+$(MAGIC_FRAGMENT_DIR)/olf \
+$(MAGIC_FRAGMENT_DIR)/os2 \
+$(MAGIC_FRAGMENT_DIR)/os400 \
+$(MAGIC_FRAGMENT_DIR)/os9 \
+$(MAGIC_FRAGMENT_DIR)/osf1 \
+$(MAGIC_FRAGMENT_DIR)/palm \
+$(MAGIC_FRAGMENT_DIR)/parix \
+$(MAGIC_FRAGMENT_DIR)/pbm \
+$(MAGIC_FRAGMENT_DIR)/pdf \
+$(MAGIC_FRAGMENT_DIR)/pdp \
+$(MAGIC_FRAGMENT_DIR)/perl \
+$(MAGIC_FRAGMENT_DIR)/pgp \
+$(MAGIC_FRAGMENT_DIR)/pkgadd \
+$(MAGIC_FRAGMENT_DIR)/plan9 \
+$(MAGIC_FRAGMENT_DIR)/plus5 \
+$(MAGIC_FRAGMENT_DIR)/printer \
+$(MAGIC_FRAGMENT_DIR)/project \
+$(MAGIC_FRAGMENT_DIR)/psdbms \
+$(MAGIC_FRAGMENT_DIR)/psion \
+$(MAGIC_FRAGMENT_DIR)/pulsar \
+$(MAGIC_FRAGMENT_DIR)/pyramid \
+$(MAGIC_FRAGMENT_DIR)/python \
+$(MAGIC_FRAGMENT_DIR)/revision \
+$(MAGIC_FRAGMENT_DIR)/riff \
+$(MAGIC_FRAGMENT_DIR)/rpm \
+$(MAGIC_FRAGMENT_DIR)/rtf \
+$(MAGIC_FRAGMENT_DIR)/ruby \
+$(MAGIC_FRAGMENT_DIR)/sc \
+$(MAGIC_FRAGMENT_DIR)/sccs \
+$(MAGIC_FRAGMENT_DIR)/scientific \
+$(MAGIC_FRAGMENT_DIR)/securitycerts \
+$(MAGIC_FRAGMENT_DIR)/sendmail \
+$(MAGIC_FRAGMENT_DIR)/sequent \
+$(MAGIC_FRAGMENT_DIR)/sgi \
+$(MAGIC_FRAGMENT_DIR)/sgml \
+$(MAGIC_FRAGMENT_DIR)/sharc \
+$(MAGIC_FRAGMENT_DIR)/sinclair \
+$(MAGIC_FRAGMENT_DIR)/sketch \
+$(MAGIC_FRAGMENT_DIR)/smalltalk \
+$(MAGIC_FRAGMENT_DIR)/sniffer \
+$(MAGIC_FRAGMENT_DIR)/softquad \
+$(MAGIC_FRAGMENT_DIR)/spec \
+$(MAGIC_FRAGMENT_DIR)/spectrum \
+$(MAGIC_FRAGMENT_DIR)/sql \
+$(MAGIC_FRAGMENT_DIR)/sun \
+$(MAGIC_FRAGMENT_DIR)/sysex \
+$(MAGIC_FRAGMENT_DIR)/teapot \
+$(MAGIC_FRAGMENT_DIR)/terminfo \
+$(MAGIC_FRAGMENT_DIR)/tex \
+$(MAGIC_FRAGMENT_DIR)/tgif \
+$(MAGIC_FRAGMENT_DIR)/ti-8x \
+$(MAGIC_FRAGMENT_DIR)/timezone \
+$(MAGIC_FRAGMENT_DIR)/troff \
+$(MAGIC_FRAGMENT_DIR)/tuxedo \
+$(MAGIC_FRAGMENT_DIR)/typeset \
+$(MAGIC_FRAGMENT_DIR)/unicode \
+$(MAGIC_FRAGMENT_DIR)/unknown \
+$(MAGIC_FRAGMENT_DIR)/uuencode \
+$(MAGIC_FRAGMENT_DIR)/varied.out \
+$(MAGIC_FRAGMENT_DIR)/varied.script \
+$(MAGIC_FRAGMENT_DIR)/vax \
+$(MAGIC_FRAGMENT_DIR)/vicar \
+$(MAGIC_FRAGMENT_DIR)/virtutech \
+$(MAGIC_FRAGMENT_DIR)/visx \
+$(MAGIC_FRAGMENT_DIR)/vms \
+$(MAGIC_FRAGMENT_DIR)/vmware \
+$(MAGIC_FRAGMENT_DIR)/vorbis \
+$(MAGIC_FRAGMENT_DIR)/vxl \
+$(MAGIC_FRAGMENT_DIR)/warc \
+$(MAGIC_FRAGMENT_DIR)/weak \
+$(MAGIC_FRAGMENT_DIR)/windows \
+$(MAGIC_FRAGMENT_DIR)/wordprocessors \
+$(MAGIC_FRAGMENT_DIR)/xdelta \
+$(MAGIC_FRAGMENT_DIR)/xenix \
+$(MAGIC_FRAGMENT_DIR)/xilinx \
+$(MAGIC_FRAGMENT_DIR)/xo65 \
+$(MAGIC_FRAGMENT_DIR)/xwindows \
+$(MAGIC_FRAGMENT_DIR)/zilog \
+$(MAGIC_FRAGMENT_DIR)/zyxel
+
+MAGIC = magic.mgc
+CLEANFILES = ${MAGIC}
@IS_CROSS_COMPILE_FALSE@FILE_COMPILE = $(top_builddir)/src/file
-@IS_CROSS_COMPILE_TRUE@FILE_COMPILE = file
-magic_FRAGMENTS = \
-Magdir/acorn \
-Magdir/adi \
-Magdir/adventure \
-Magdir/allegro \
-Magdir/alliant \
-Magdir/alpha \
-Magdir/amanda \
-Magdir/amigaos \
-Magdir/animation \
-Magdir/apl \
-Magdir/apple \
-Magdir/applix \
-Magdir/archive \
-Magdir/asterix \
-Magdir/att3b \
-Magdir/audio \
-Magdir/basis \
-Magdir/bflt \
-Magdir/blender \
-Magdir/blit \
-Magdir/bout \
-Magdir/bsdi \
-Magdir/btsnoop \
-Magdir/cad \
-Magdir/cafebabe \
-Magdir/c-lang \
-Magdir/c64 \
-Magdir/cddb \
-Magdir/chord \
-Magdir/cisco \
-Magdir/citrus \
-Magdir/claris \
-Magdir/clipper \
-Magdir/cracklib \
-Magdir/spec \
-Magdir/commands \
-Magdir/communications \
-Magdir/compress \
-Magdir/console \
-Magdir/convex \
-Magdir/ctags \
-Magdir/dact \
-Magdir/database \
-Magdir/diamond \
-Magdir/diff \
-Magdir/digital \
-Magdir/dolby \
-Magdir/dump \
-Magdir/editors \
-Magdir/efi \
-Magdir/elf \
-Magdir/encore \
-Magdir/epoc \
-Magdir/esri \
-Magdir/fcs \
-Magdir/filesystems \
-Magdir/flash \
-Magdir/fonts \
-Magdir/fortran \
-Magdir/frame \
-Magdir/freebsd \
-Magdir/fsav \
-Magdir/games \
-Magdir/geos \
-Magdir/gcc \
-Magdir/gimp \
-Magdir/gnu \
-Magdir/grace \
-Magdir/gringotts \
-Magdir/hitachi-sh \
-Magdir/hp \
-Magdir/human68k \
-Magdir/ibm370 \
-Magdir/ibm6000 \
-Magdir/iff \
-Magdir/images \
-Magdir/intel \
-Magdir/interleaf \
-Magdir/island \
-Magdir/ispell \
-Magdir/java \
-Magdir/jpeg \
-Magdir/karma \
-Magdir/lecter \
-Magdir/lex \
-Magdir/lif \
-Magdir/linux \
-Magdir/lisp \
-Magdir/mach \
-Magdir/macintosh \
-Magdir/magic \
-Magdir/mail.news \
-Magdir/maple \
-Magdir/mathematica \
-Magdir/matroska \
-Magdir/mcrypt \
-Magdir/mime \
-Magdir/mips \
-Magdir/mirage \
-Magdir/misctools \
-Magdir/mkid \
-Magdir/mlssa \
-Magdir/mmdf \
-Magdir/modem \
-Magdir/motorola \
-Magdir/msdos \
-Magdir/msvc \
-Magdir/mup \
-Magdir/natinst \
-Magdir/ncr \
-Magdir/netbsd \
-Magdir/netscape \
-Magdir/news \
-Magdir/nitpicker \
-Magdir/ocaml \
-Magdir/octave \
-Magdir/olf \
-Magdir/os2 \
-Magdir/os400 \
-Magdir/os9 \
-Magdir/osf1 \
-Magdir/palm \
-Magdir/parix \
-Magdir/pbm \
-Magdir/pdf \
-Magdir/pdp \
-Magdir/perl \
-Magdir/pgp \
-Magdir/pkgadd \
-Magdir/plan9 \
-Magdir/plus5 \
-Magdir/printer \
-Magdir/project \
-Magdir/psdbms \
-Magdir/psion \
-Magdir/pulsar \
-Magdir/pyramid \
-Magdir/python \
-Magdir/revision \
-Magdir/riff \
-Magdir/rpm \
-Magdir/rtf \
-Magdir/sc \
-Magdir/sccs \
-Magdir/sendmail \
-Magdir/sequent \
-Magdir/sgi \
-Magdir/sgml \
-Magdir/sharc \
-Magdir/sinclair \
-Magdir/sketch \
-Magdir/smalltalk \
-Magdir/sniffer \
-Magdir/dyadic \
-Magdir/scientific \
-Magdir/softquad \
-Magdir/spectrum \
-Magdir/sql \
-Magdir/sun \
-Magdir/sysex \
-Magdir/teapot \
-Magdir/terminfo \
-Magdir/tex \
-Magdir/tgif \
-Magdir/ti-8x \
-Magdir/timezone \
-Magdir/troff \
-Magdir/tuxedo \
-Magdir/typeset \
-Magdir/unknown \
-Magdir/unicode \
-Magdir/uuencode \
-Magdir/varied.out \
-Magdir/varied.script \
-Magdir/vax \
-Magdir/vicar \
-Magdir/virtutech \
-Magdir/visx \
-Magdir/vms \
-Magdir/vmware \
-Magdir/vorbis \
-Magdir/vxl \
-Magdir/wordprocessors \
-Magdir/xdelta \
-Magdir/xenix \
-Magdir/xo65 \
-Magdir/xwindows \
-Magdir/zilog \
-Magdir/zyxel
+# FIXME: Build file natively as well so that it can be used to compile
+# the target's magic file
+@IS_CROSS_COMPILE_TRUE@FILE_COMPILE = file
+@IS_CROSS_COMPILE_FALSE@FILE_COMPILE_DEP = $(FILE_COMPILE)
+@IS_CROSS_COMPILE_TRUE@FILE_COMPILE_DEP =
all: all-am
.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -385,9 +417,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
@@ -546,22 +578,9 @@ uninstall-am: uninstall-pkgdataDATA
uninstall uninstall-am uninstall-pkgdataDATA
-magic: Header Localstuff $(magic_FRAGMENTS)
- cat $(srcdir)/Header $(srcdir)/Localstuff > $@
- for frag in $(magic_FRAGMENTS); do \
- if test -f $(srcdir)/$$frag; then \
- f=$(srcdir)/$$frag; \
- else \
- f=$$frag; \
- fi; \
- cat $$f; \
- done >> $@
-
-magic.mgc: magic
- $(FILE_COMPILE) -C -m magic
-
-magic.mime.mgc: magic.mime
- $(FILE_COMPILE) -C -m $(srcdir)/magic.mime
+${MAGIC}: $(EXTRA_DIST) $(FILE_COMPILE_DEP)
+ $(FILE_COMPILE) -C -m $(MAGIC_FRAGMENT_DIR)
+ @mv $(MAGIC_FRAGMENT_BASE).mgc $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/contrib/file/Makefile.std b/contrib/file/Makefile.std
deleted file mode 100644
index ff2a9b5..0000000
--- a/contrib/file/Makefile.std
+++ /dev/null
@@ -1,167 +0,0 @@
-# Makefile for file(1) cmd.
-# Copyright (c) Ian F. Darwin 86/09/01 - see LEGAL.NOTICE.
-# @(#)$Id: Makefile.std,v 1.17 2003/02/27 20:47:45 christos Exp $
-#
-# This software is not subject to any license of the American Telephone
-# and Telegraph Company or of the Regents of the University of California.
-#
-# Permission is granted to anyone to use this software for any purpose on
-# any computer system, and to alter it and 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 flaws in it.
-#
-# 2. The origin of this software must not be misrepresented, either by
-# explicit claim or by omission. Since few users ever read sources,
-# credits must appear in the documentation.
-#
-# 3. Altered versions must be plainly marked as such, and must not be
-# misrepresented as being the original software. Since few users
-# ever read sources, credits must appear in the documentation.
-#
-# 4. This notice may not be removed or altered.
-#
-VERSION = 3.41
-SHELL = /bin/sh
-#MAGIC = /etc/magic
-MAGIC = /usr/local/etc/magic
-DEFS = -DMAGIC='"$(MAGIC)"' -DBUILTIN_ELF # -Dvoid=int
-CC = cc
-COPTS = -O -g # newer compilers allow both; else drop -O
-# For truly antique environments, use this for (dummy) include files:
-COPTS = -O # -Ilocalinc
-CFLAGS = $(COPTS) $(DEFS)
-LDFLAGS = $(COPTS) # -Bstatic # older gdb couldn't handle shared libs
-SHAR = bundle
-OFILE = /usr/bin/file # old or distributed version, for comparison
-# Where new binary lives; typically /usr/local (BSD), /usr/lbin (USG).
-BINDIR = /usr/local/bin
-# For installing our man pages;
-# MANCxxx is manual section for Commands, MANFxxx is section for file formats.
-# MANxDIR is directory names; MANxEXT is the filename extention. Usual values:
-# Variable V7 4BSD Sys V
-# MANCDIR /usr/man/man1 /usr/man/man1 /usr/man/u_man/man1
-# MANFDIR /usr/man/man5 /usr/man/man5 /usr/man/u_man/man4
-# MANCEXT 1 1 1
-# MANFEXT 5 5 4
-# --- possible alternative for 4BSD ---
-# MANCDIR /usr/local/man/man1
-# MANCEXT 1
-# or
-# MANCDIR /usr/man/manl
-# MANCEXT l
-# --- possible alternative for USG ---
-# MANCDIR /usr/man/local/man1
-# MANCEXT 1
-
-MANCDIR = /usr/local/man/man1
-MANCEXT = 1
-MANFDIR = /usr/local/man/man4
-MANFEXT = 4
-
-# There are no system-dependant configuration options (except maybe CFLAGS).
-# Uncomment any of these that is missing from your "standard" library.
-LOCALSRCS = # localsrc/getopt.c localsrc/strtol.c \
-# localsrc/strtok.c localsrc/strchr.c
-LOCALOBJS = # localsrc/getopt.o localsrc/strtol.o \
-# localsrc/strtok.o localsrc/strchr.o
-# These are not compiled in unless you use -Ilocalinc, but
-# are not commented out as "make dist" &c use them.
-LOCALINC = # localinc/*.h localinc/sys/*.h
-
-SRCS = file.c apprentice.c fsmagic.c softmagic.c ascmagic.c \
- compress.c is_tar.c readelf.c \
- print.c $(LOCALSRCS) $(LOCALINC)
-OBJS = file.o apprentice.o fsmagic.o softmagic.o ascmagic.o \
- compress.o is_tar.o readelf.o \
- print.o $(LOCALOBJS)
-HDRS = file.h names.h patchlevel.h readelf.h tar.h
-
-AUTOSRC=configure configure.in install-sh config.h.in Makefile.in
-ALLSRC = LEGAL.NOTICE README MAINT PORTING $(SRCS) $(HDRS) \
- Makefile.std file.man magic.man magic2mime $(AUTOSRC) \
- Localstuff Header
-ALLMAGIC = Magdir/[a-z]*
-
-all: file magic file.${MANCEXT} magic.${MANFEXT}
-
-TESTFILES = * tst/*
-try: all $(OFILE)
- cd tst; $(MAKE)
- time $(OFILE) $(TESTFILES) >/tmp/t1 # can't use ./magic
- time ./file -m ./magic $(TESTFILES) >/tmp/t2
- -diff -b /tmp/t[12]
- what ./file >lastnocore
-
-file: $(OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
-lint: $(SRCS)
- lint -ha $(DEFS) $(SRCS) | tee $@
-magic: Localstuff Header Magdir
- cat Header Localstuff Magdir/[a-z] > $@
-
-ascmagic.o: names.h
-
-compress.o apprentice.o ascmagic.o file.o fsmagic.o print.o softmagic.o: file.h
-
-install: file magic
- cp file $(BINDIR)/file
- cp magic $(MAGIC)
-
-install.man: file.${MANCEXT} magic.${MANFEXT}
- cp file.${MANCEXT} $(MANCDIR)/file.$(MANCEXT)
- cp magic.${MANFEXT} $(MANFDIR)/magic.$(MANFEXT)
-
-clean:
- rm -f *.o core file magic lint dist.* MANIFEST \
- magic.${MANFEXT} file.${MANCEXT} \
- config.h config.status config.cache config.log
-clobber:
- cd tst; $(MAKE) clean
-
-
-magic.${MANFEXT} : Makefile magic.man
- @rm -f $@
- sed -e s@__CSECTION__@${MANCEXT}@g \
- -e s@__FSECTION__@${MANFEXT}@g \
- -e s@__VERSION__@${VERSION}@g \
- -e s@__MAGIC__@${MAGIC}@g magic.man > $@
-
-file.${MANCEXT} : Makefile file.man
- @rm -f $@
- sed -e s@__CSECTION__@${MANCEXT}@g \
- -e s@__FSECTION__@${MANFEXT}@g \
- -e s@__VERSION__@${VERSION}@g \
- -e s@__MAGIC__@${MAGIC}@g file.man > $@
-
-send: dist
- ftp ftp.cs
-
-dist: dist.src dist.magic
- @echo Now check this patchlevel!
- ident patchlevel.h
-
-dist.src: $(ALLSRC) MANIFEST
-# Some versions of shar can't handle a single file from
-# a subdirectory, so we manually insert mkdir as needed.
-# The point is to exclude all the generable targets in tst.
- (echo mkdir localinc localinc/sys localsrc tst; \
- $(SHAR) $(ALLSRC) MANIFEST) > $@
-
-rcsdiff: $(ALLSRC)
- rcsdiff -q RCS/*
-
-MANIFEST: $(ALLSRC)
- ident $(ALLSRC) > MANIFEST
-dist.magic: Magdir
-# As above, but to exclude Magdir/RCS from being shipped.
- (echo mkdir Magdir; $(SHAR) $(ALLMAGIC)) >$@
-
-tar: $(ALLSRC) $(ALLMAGIC)
- -rm -fr file-${VERSION}
- -mkdir file-${VERSION} file-${VERSION}/Magdir
- ln $(ALLSRC) file-${VERSION}
- ln ${ALLMAGIC} file-${VERSION}/Magdir
- tar cvf file-${VERSION}.tar file-${VERSION}
- -rm -fr file-${VERSION}
diff --git a/contrib/file/NEWS b/contrib/file/NEWS
new file mode 100644
index 0000000..939a279
--- /dev/null
+++ b/contrib/file/NEWS
@@ -0,0 +1 @@
+See ChangeLog. \ No newline at end of file
diff --git a/contrib/file/PORTING b/contrib/file/PORTING
deleted file mode 100644
index e69de29..0000000
--- a/contrib/file/PORTING
+++ /dev/null
diff --git a/contrib/file/README b/contrib/file/README
index b7e9d55..30b9fa8 100644
--- a/contrib/file/README
+++ b/contrib/file/README
@@ -1,5 +1,10 @@
** README for file(1) Command **
-@(#) $File: README,v 1.34 2006/05/03 18:48:33 christos Exp $
+@(#) $File: README,v 1.40 2008/04/23 03:45:20 christos Exp $
+
+E-mail: christos@astron.com
+Mailing List: file@mx.gw.com
+
+Phone: Do not even think of telephoning me about this program. Send cash first!
This is Release 4.x of Ian Darwin's (copyright but distributable)
file(1) command. This version is the standard "file" command for Linux,
@@ -41,7 +46,7 @@ magic numbers assigned to all sorts of data files that
are in reasonable circulation. Send your magic numbers,
in magic(5) format please, to the maintainer, Christos Zoulas.
-LEGAL.NOTICE - read this first.
+COPYING - read this first.
README - read this second (you are currently reading this file).
PORTING - read this only if the program won't compile.
Makefile - read this next, adapt it as needed (particularly
@@ -71,6 +76,31 @@ readelf.[ch] - Stand-alone elf parsing code.
compress.c - on-the-fly decompression.
print.c - print results, errors, warnings.
+------------------------------------------------------------------------------
+
+If you submit a new magic entry please make sure you read the following
+guidelines:
+
+- Initial match is preferably at least 32 bits long, and is a _unique_ match
+- If this is not feasible, use additional check
+- Match of <= 16 bits are not accepted
+- Delay printing string as much as possible, don't print output too early
+- Avoid printf arbitrary byte as string, which can be a source of
+ crash and buffer overflow
+
+- Provide complete information with entry:
+ * One line short summary
+ * Optional long description
+ * File extension, if applicable
+ * Full name and contact method (for discussion when entry has problem)
+ * Further reference, such as documentation of format
+
+------------------------------------------------------------------------------
+
+You can download the latest version of file from:
+
+ ftp://ftp.astron.com/pub/file/
+
If your gzip sometimes fails to decompress things complaining about a short
file, apply this patch [which is going to be in the next version of gzip]:
*** - Tue Oct 29 02:06:35 1996
@@ -85,10 +115,6 @@ file, apply this patch [which is going to be in the next version of gzip]:
}
bytes_in += (ulg)insize;
-E-mail: christos@astron.com
-
-Phone: Do not even think of telephoning me about this program. Send cash first!
-
Parts of this software were developed at SoftQuad Inc., developers
of SGML/HTML/XML publishing software, in Toronto, Canada.
SoftQuad was swallowed up by Corel in 2002
diff --git a/contrib/file/TODO b/contrib/file/TODO
new file mode 100644
index 0000000..50fd87f
--- /dev/null
+++ b/contrib/file/TODO
@@ -0,0 +1,9 @@
+Continue to squash all magic bugs. See Debian BTS for a good source.
+
+Store arbitrarily long strings, for example for %s patterns, so that
+they can be printed out. Fixes Debian bug #271672.
+
+Add syntax for other sorts of counted string (Debian bug #466032). Use
+to fix bug #283760.
+
+Add syntax for relative offsets after current level (Debian bug #466037).
diff --git a/contrib/file/acinclude.m4 b/contrib/file/acinclude.m4
index f92a2d1..31677b1 100644
--- a/contrib/file/acinclude.m4
+++ b/contrib/file/acinclude.m4
@@ -1,19 +1,3 @@
-dnl cloned from autoconf 2.13 acspecific.m4
-AC_DEFUN([AC_C_LONG_LONG],
-[AC_CACHE_CHECK(for long long, ac_cv_c_long_long,
-[if test "$GCC" = yes; then
- ac_cv_c_long_long=yes
-else
-AC_TRY_RUN([int main() {
-long long foo = 0;
-exit(sizeof(long long) < sizeof(long)); }],
-ac_cv_c_long_long=yes, ac_cv_c_long_long=no)
-fi])
-if test $ac_cv_c_long_long = yes; then
- AC_DEFINE(HAVE_LONG_LONG)
-fi
-])
-
dnl from autoconf 2.13 acspecific.m4, with changes to check for daylight
AC_DEFUN([AC_STRUCT_TIMEZONE_DAYLIGHT],
@@ -43,7 +27,7 @@ AC_CACHE_CHECK([for tm_isdst in struct tm], ac_cv_struct_tm_isdst,
#include <$ac_cv_struct_tm>], [struct tm tm; tm.tm_isdst;],
ac_cv_struct_tm_isdst=yes, ac_cv_struct_tm_isdst=no)])
if test "$ac_cv_struct_tm_isdst" = yes; then
- AC_DEFINE(HAVE_TM_ISDST)
+ AC_DEFINE(HAVE_TM_ISDST,1,[HAVE_TM_ISDST])
fi
AC_CACHE_CHECK(for daylight, ac_cv_var_daylight,
[AC_TRY_LINK(
@@ -55,226 +39,6 @@ extern int daylight;
changequote([, ])dnl
[atoi(daylight);], ac_cv_var_daylight=yes, ac_cv_var_daylight=no)])
if test $ac_cv_var_daylight = yes; then
- AC_DEFINE(HAVE_DAYLIGHT)
+ AC_DEFINE(HAVE_DAYLIGHT,1,[HAVE_DAYLIGHT])
fi
])
-
-dnl from autoconf 2.13 acgeneral.m4, with patch:
-dnl Date: Fri, 15 Jan 1999 05:52:41 -0800
-dnl Message-ID: <199901151352.FAA18237@shade.twinsun.com>
-dnl From: eggert@twinsun.com (Paul Eggert)
-dnl Subject: autoconf 2.13 AC_CHECK_TYPE doesn't allow shell vars
-dnl Newsgroups: gnu.utils.bug
-dnl
-dnl now include <stdint.h> if available
-
-dnl AC_CHECK_TYPE2_STDC(TYPE, DEFAULT)
-AC_DEFUN([AC_CHECK_TYPE2_STDC],
-[AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_REQUIRE([AC_HEADER_STDINT])dnl
-AC_MSG_CHECKING(for $1)
-AC_CACHE_VAL(ac_cv_type_$1,
-[AC_EGREP_CPP(dnl
-[(^|[^a-zA-Z_0-9])$1[^a-zA-Z_0-9]],
-[#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif], eval "ac_cv_type_$1=yes", eval "ac_cv_type_$1=no")])dnl
-if eval "test \"`echo '$ac_cv_type_'$1`\" = yes"; then
- AC_MSG_RESULT(yes)
-else
- AC_MSG_RESULT(no)
- AC_DEFINE_UNQUOTED($1, $2)
-fi
-])
-
-dnl from autoconf 2.13 acgeneral.m4, with additional third argument
-dnl AC_CHECK_SIZEOF_INCLUDES(TYPE [, CROSS-SIZE [, INCLUDES]])
-AC_DEFUN([AC_CHECK_SIZEOF_INCLUDES],
-[dnl The name to #define.
-define([AC_TYPE_NAME], translit(sizeof_$1, [[[a-z *]]], [[[A-Z_P]]]))dnl
-dnl The cache variable name.
-define([AC_CV_NAME], translit(ac_cv_sizeof_$1, [[[ *]]], [[[_p]]]))dnl
-AC_MSG_CHECKING(size of $1)
-AC_CACHE_VAL(AC_CV_NAME,
-[AC_TRY_RUN([$3
-#include <stdio.h>
-main()
-{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof($1));
- exit(0);
-}], AC_CV_NAME=`cat conftestval`, AC_CV_NAME=0, ifelse([$2], , , AC_CV_NAME=$2))])dnl
-AC_MSG_RESULT($AC_CV_NAME)
-AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME)
-undefine([AC_TYPE_NAME])dnl
-undefine([AC_CV_NAME])dnl
-])
-
-dnl AC_CHECK_SIZEOF_STDC_HEADERS(TYPE [, CROSS_SIZE])
-AC_DEFUN([AC_CHECK_SIZEOF_STDC_HEADERS],
-[AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_REQUIRE([AC_HEADER_STDINT])dnl
-AC_CHECK_SIZEOF_INCLUDES($1, $2,
-[#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-])
-
-
-dnl AC_CHECK_TYPE_STDC(TYPE, DEFAULT)
-AC_DEFUN([AC_CHECK_TYPE_STDC],
-[AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_REQUIRE([AC_HEADER_STDINT])dnl
-AC_MSG_CHECKING(for $1)
-AC_CACHE_VAL(ac_cv_type_$1,
-[AC_EGREP_CPP(dnl
-[(^|[^a-zA-Z_0-9])$1[^a-zA-Z_0-9]],
-[#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif], ac_cv_type_$1=yes, ac_cv_type_$1=no)])dnl
-AC_MSG_RESULT($ac_cv_type_$1)
-if test $ac_cv_type_$1 = no; then
- AC_DEFINE($1, $2)
-fi
-])
-
-dnl AC_HEADER_STDINT
-AC_DEFUN([AC_HEADER_STDINT], [AC_CHECK_HEADERS(stdint.h)])
-
-dnl By default, many hosts won't let programs access large files;
-dnl one must use special compiler options to get large-file access to work.
-dnl For more details about this brain damage please see:
-dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
-
-dnl Written by Paul Eggert <eggert@twinsun.com>.
-
-dnl Internal subroutine of AC_SYS_LARGEFILE.
-dnl AC_SYS_LARGEFILE_TEST_INCLUDES
-AC_DEFUN([AC_SYS_LARGEFILE_TEST_INCLUDES],
- [[#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
- ]])
-
-dnl Internal subroutine of AC_SYS_LARGEFILE.
-dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLU=
-DES, FUNCTION-BODY)
-AC_DEFUN([AC_SYS_LARGEFILE_MACRO_VALUE],
- [AC_CACHE_CHECK([for $1 value needed for large files], $3,
- [$3=no
- AC_TRY_COMPILE([$5],
- [$6],
- ,
- [AC_TRY_COMPILE([#define $1 $2]
-[$5]
- ,
- [$6],
- [$3=$2])])])
- if test "[$]$3" != no; then
- AC_DEFINE_UNQUOTED([$1], [$]$3, [$4])
- fi])
-
-AC_DEFUN([AC_SYS_LARGEFILE],
- [AC_REQUIRE([AC_PROG_CC])
- AC_ARG_ENABLE(largefile,
- [ --disable-largefile omit support for large files])
- if test "$enable_largefile" != no; then
-
- AC_CACHE_CHECK([for special C compiler options needed for large files=
-],
- ac_cv_sys_largefile_CC,
- [ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, , ,
- [ac_save_CC="$CC"
- CC="$CC -n32"
- AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, ,
- ac_cv_sys_largefile_CC=' -n32')
- CC="$ac_save_CC"])
- fi])
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC="$CC$ac_cv_sys_largefile_CC"
- fi
-
- AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
- ac_cv_sys_file_offset_bits,
- [Number of bits in a file offset, on hosts where this is settable.],
- AC_SYS_LARGEFILE_TEST_INCLUDES)
- AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
- ac_cv_sys_large_files,
- [Define for large files, on AIX-style hosts.],
- AC_SYS_LARGEFILE_TEST_INCLUDES)
- fi
- ])
-
-AC_DEFUN([AC_FUNC_FSEEKO],
- [AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
- ac_cv_sys_largefile_source,
- [Define to make fseeko visible on some hosts (e.g. glibc 2.2).],
- [#include <stdio.h>], [return !fseeko;])
- # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
- # in glibc 2.1.3, but that breaks too many other things.
- # If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
-
- AC_CACHE_CHECK([for fseeko], ac_cv_func_fseeko,
- [ac_cv_func_fseeko=no
- AC_TRY_LINK([#include <stdio.h>],
- [return fseeko && fseeko (stdin, 0, 0);],
- [ac_cv_func_fseeko=yes])])
- if test $ac_cv_func_fseeko != no; then
- AC_DEFINE(HAVE_FSEEKO, 1,
- [Define if fseeko (and presumably ftello) exists and is declared.])
- fi])
-
-# From Paul Eggert.
-
-# BeOS 5 has <wchar.h> but does not define mbstate_t,
-# so you can't declare an object of that type.
-# Check for this incompatibility with Standard C.
-
-# Include stdlib.h first, because otherwise this test would fail on Linux
-# (at least glibc-2.1.3) because the "_XOPEN_SOURCE 500" definition elicits
-# a syntax error in wchar.h due to the use of undefined __int32_t.
-AC_DEFUN([AC_MBSTATE_T],
- [
- AC_CHECK_HEADERS(stdlib.h)
-
- AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t,
- [AC_TRY_COMPILE([
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#include <wchar.h>],
- [mbstate_t x; return sizeof x;],
- ac_cv_type_mbstate_t=yes,
- ac_cv_type_mbstate_t=no)])
- if test $ac_cv_type_mbstate_t = no; then
- AC_DEFINE(mbstate_t, int,
- [Define to a type if <wchar.h> does not define.])
- fi])
-
-
diff --git a/contrib/file/aclocal.m4 b/contrib/file/aclocal.m4
index c46c041..593d2e9 100644
--- a/contrib/file/aclocal.m4
+++ b/contrib/file/aclocal.m4
@@ -6685,35 +6685,6 @@ fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
-# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
-# From Jim Meyering
-
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-AC_DEFUN([AM_MAINTAINER_MODE],
-[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
- dnl maintainer-mode is disabled by default
- AC_ARG_ENABLE(maintainer-mode,
-[ --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- USE_MAINTAINER_MODE=$enableval,
- USE_MAINTAINER_MODE=no)
- AC_MSG_RESULT([$USE_MAINTAINER_MODE])
- AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST(MAINT)dnl
-]
-)
-
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
@@ -6766,6 +6737,40 @@ AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
diff --git a/contrib/file/apprentice.c b/contrib/file/apprentice.c
index 162acfe..714c86c 100644
--- a/contrib/file/apprentice.c
+++ b/contrib/file/apprentice.c
@@ -45,9 +45,11 @@
#ifdef QUICK
#include <sys/mman.h>
#endif
+#include <sys/types.h>
+#include <dirent.h>
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.109 2007/12/27 20:52:36 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.140 2008/07/20 04:02:15 christos Exp $")
#endif /* lint */
#define EATAB {while (isascii((unsigned char) *l) && \
@@ -97,14 +99,14 @@ private void eatsize(const char **);
private int apprentice_1(struct magic_set *, const char *, int, struct mlist *);
private size_t apprentice_magic_strength(const struct magic *);
private int apprentice_sort(const void *, const void *);
-private int apprentice_file(struct magic_set *, struct magic **, uint32_t *,
+private int apprentice_load(struct magic_set *, struct magic **, uint32_t *,
const char *, int);
private void byteswap(struct magic *, uint32_t);
private void bs1(struct magic *);
private uint16_t swap2(uint16_t);
private uint32_t swap4(uint32_t);
private uint64_t swap8(uint64_t);
-private char *mkdbname(const char *, char *, size_t, int);
+private void mkdbname(const char *, char **, int);
private int apprentice_map(struct magic_set *, struct magic **, uint32_t *,
const char *);
private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *,
@@ -112,10 +114,27 @@ private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *,
private int check_format_type(const char *, int);
private int check_format(struct magic_set *, struct magic *);
private int get_op(char);
+private int parse_mime(struct magic_set *, struct magic_entry *, const char *);
+private int parse_strength(struct magic_set *, struct magic_entry *,
+ const char *);
+
private size_t maxmagic = 0;
private size_t magicsize = sizeof(struct magic);
+private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
+
+private struct {
+ const char *name;
+ size_t len;
+ int (*fun)(struct magic_set *, struct magic_entry *, const char *);
+} bang[] = {
+#define DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
+ DECLARE_FIELD(mime),
+ DECLARE_FIELD(strength),
+#undef DECLARE_FIELD
+ { NULL, 0, NULL }
+};
#ifdef COMPILE_ONLY
@@ -151,13 +170,13 @@ main(int argc, char *argv[])
#endif /* COMPILE_ONLY */
static const struct type_tbl_s {
- const char *name;
+ const char name[16];
const size_t len;
const int type;
const int format;
} type_tbl[] = {
# define XX(s) s, (sizeof(s) - 1)
-# define XX_NULL NULL, 0
+# define XX_NULL "", 0
{ XX("byte"), FILE_BYTE, FILE_FMT_NUM },
{ XX("short"), FILE_SHORT, FILE_FMT_NUM },
{ XX("default"), FILE_DEFAULT, FILE_FMT_STR },
@@ -206,7 +225,7 @@ get_type(const char *l, const char **t)
{
const struct type_tbl_s *p;
- for (p = type_tbl; p->name; p++) {
+ for (p = type_tbl; p->len; p++) {
if (strncmp(l, p->name, p->len) == 0) {
if (t)
*t = l + p->len;
@@ -226,7 +245,7 @@ init_file_tables(void)
return;
done++;
- for (p = type_tbl; p->name; p++) {
+ for (p = type_tbl; p->len; p++) {
assert(p->type < FILE_NAMES_SIZE);
file_names[p->type] = p->name;
file_formats[p->type] = p->format;
@@ -234,7 +253,7 @@ init_file_tables(void)
}
/*
- * Handle one file.
+ * Handle one file or directory.
*/
private int
apprentice_1(struct magic_set *ms, const char *fn, int action,
@@ -254,7 +273,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action,
}
if (action == FILE_COMPILE) {
- rv = apprentice_file(ms, &magic, &nmagic, fn, action);
+ rv = apprentice_load(ms, &magic, &nmagic, fn, action);
if (rv != 0)
return -1;
rv = apprentice_compile(ms, &magic, &nmagic, fn);
@@ -266,19 +285,19 @@ apprentice_1(struct magic_set *ms, const char *fn, int action,
if ((rv = apprentice_map(ms, &magic, &nmagic, fn)) == -1) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "using regular magic file `%s'", fn);
- rv = apprentice_file(ms, &magic, &nmagic, fn, action);
+ rv = apprentice_load(ms, &magic, &nmagic, fn, action);
if (rv != 0)
return -1;
}
mapped = rv;
- if (magic == NULL || nmagic == 0) {
+ if (magic == NULL) {
file_delmagic(magic, mapped, nmagic);
return -1;
}
- if ((ml = malloc(sizeof(*ml))) == NULL) {
+ if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) {
file_delmagic(magic, mapped, nmagic);
file_oomem(ms, sizeof(*ml));
return -1;
@@ -320,14 +339,13 @@ file_delmagic(struct magic *p, int type, size_t entries)
}
}
-/* const char *fn: list of magic files */
+/* const char *fn: list of magic files and directories */
protected struct mlist *
file_apprentice(struct magic_set *ms, const char *fn, int action)
{
- char *p, *mfn, *afn = NULL;
+ char *p, *mfn;
int file_err, errs = -1;
struct mlist *mlist;
- static const char mime[] = ".mime";
init_file_tables();
@@ -342,7 +360,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
}
fn = mfn;
- if ((mlist = malloc(sizeof(*mlist))) == NULL) {
+ if ((mlist = CAST(struct mlist *, malloc(sizeof(*mlist)))) == NULL) {
free(mfn);
file_oomem(ms, sizeof(*mlist));
return NULL;
@@ -355,25 +373,8 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
*p++ = '\0';
if (*fn == '\0')
break;
- if (ms->flags & MAGIC_MIME) {
- size_t len = strlen(fn) + sizeof(mime);
- if ((afn = malloc(len)) == NULL) {
- free(mfn);
- free(mlist);
- file_oomem(ms, len);
- return NULL;
- }
- (void)strcpy(afn, fn);
- (void)strcat(afn, mime);
- fn = afn;
- }
file_err = apprentice_1(ms, fn, action, mlist);
- if (file_err > errs)
- errs = file_err;
- if (afn) {
- free(afn);
- afn = NULL;
- }
+ errs = MAX(errs, file_err);
fn = p;
}
if (errs == -1) {
@@ -398,6 +399,8 @@ apprentice_magic_strength(const struct magic *m)
switch (m->type) {
case FILE_DEFAULT: /* make sure this sorts last */
+ if (m->factor_op != FILE_FACTOR_OP_NONE)
+ abort();
return 0;
case FILE_BYTE:
@@ -429,7 +432,7 @@ apprentice_magic_strength(const struct magic *m)
case FILE_SEARCH:
case FILE_REGEX:
- val += m->vallen;
+ val += m->vallen * MAX(MULT / m->vallen, 1);
break;
case FILE_DATE:
@@ -469,10 +472,10 @@ apprentice_magic_strength(const struct magic *m)
switch (m->reln) {
case 'x': /* matches anything penalize */
+ case '!': /* matches almost anything penalize */
val = 0;
break;
- case '!':
case '=': /* Exact match, prefer */
val += MULT;
break;
@@ -495,6 +498,31 @@ apprentice_magic_strength(const struct magic *m)
if (val == 0) /* ensure we only return 0 for FILE_DEFAULT */
val = 1;
+ switch (m->factor_op) {
+ case FILE_FACTOR_OP_NONE:
+ break;
+ case FILE_FACTOR_OP_PLUS:
+ val += m->factor;
+ break;
+ case FILE_FACTOR_OP_MINUS:
+ val -= m->factor;
+ break;
+ case FILE_FACTOR_OP_TIMES:
+ val *= m->factor;
+ break;
+ case FILE_FACTOR_OP_DIV:
+ val /= m->factor;
+ break;
+ default:
+ abort();
+ }
+
+ /*
+ * Magic entries with no description get a bonus because they depend
+ * on subsequent magic entries to print something.
+ */
+ if (m->desc[0] == '\0')
+ val++;
return val;
}
@@ -504,8 +532,8 @@ apprentice_magic_strength(const struct magic *m)
private int
apprentice_sort(const void *a, const void *b)
{
- const struct magic_entry *ma = a;
- const struct magic_entry *mb = b;
+ const struct magic_entry *ma = CAST(const struct magic_entry *, a);
+ const struct magic_entry *mb = CAST(const struct magic_entry *, b);
size_t sa = apprentice_magic_strength(ma->mp);
size_t sb = apprentice_magic_strength(mb->mp);
if (sa == sb)
@@ -516,36 +544,158 @@ apprentice_sort(const void *a, const void *b)
return 1;
}
+private void
+set_test_type(struct magic *mstart, struct magic *m)
+{
+ switch (m->type) {
+ case FILE_BYTE:
+ case FILE_SHORT:
+ case FILE_LONG:
+ case FILE_DATE:
+ case FILE_BESHORT:
+ case FILE_BELONG:
+ case FILE_BEDATE:
+ case FILE_LESHORT:
+ case FILE_LELONG:
+ case FILE_LEDATE:
+ case FILE_LDATE:
+ case FILE_BELDATE:
+ case FILE_LELDATE:
+ case FILE_MEDATE:
+ case FILE_MELDATE:
+ case FILE_MELONG:
+ case FILE_QUAD:
+ case FILE_LEQUAD:
+ case FILE_BEQUAD:
+ case FILE_QDATE:
+ case FILE_LEQDATE:
+ case FILE_BEQDATE:
+ case FILE_QLDATE:
+ case FILE_LEQLDATE:
+ case FILE_BEQLDATE:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ case FILE_STRING:
+ case FILE_PSTRING:
+ case FILE_BESTRING16:
+ case FILE_LESTRING16:
+ /* binary test, set flag */
+ mstart->flag |= BINTEST;
+ break;
+ case FILE_REGEX:
+ case FILE_SEARCH:
+#ifndef COMPILE_ONLY
+ /* binary test if pattern is not text */
+ if (file_looks_utf8(m->value.us, m->vallen, NULL, NULL) <= 0)
+ mstart->flag |= BINTEST;
+#endif
+ break;
+ case FILE_DEFAULT:
+ /* can't deduce anything; we shouldn't see this at the
+ top level anyway */
+ break;
+ case FILE_INVALID:
+ default:
+ /* invalid search type, but no need to complain here */
+ break;
+ }
+}
+
/*
- * parse from a file
- * const char *fn: name of magic file
+ * Load and parse one file.
*/
-private int
-apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
- const char *fn, int action)
+private void
+load_1(struct magic_set *ms, int action, const char *fn, int *errs,
+ struct magic_entry **marray, uint32_t *marraycount)
{
- private const char hdr[] =
- "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
- FILE *f;
char line[BUFSIZ];
- int errs = 0;
- struct magic_entry *marray;
- uint32_t marraycount, i, mentrycount = 0;
size_t lineno = 0;
-
- ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
-
- f = fopen(ms->file = fn, "r");
+ FILE *f = fopen(ms->file = fn, "r");
if (f == NULL) {
if (errno != ENOENT)
file_error(ms, errno, "cannot read magic file `%s'",
- fn);
- return -1;
+ fn);
+ (*errs)++;
+ } else {
+ /* read and parse this file */
+ for (ms->line = 1; fgets(line, sizeof(line), f) != NULL; ms->line++) {
+ size_t len;
+ len = strlen(line);
+ if (len == 0) /* null line, garbage, etc */
+ continue;
+ if (line[len - 1] == '\n') {
+ lineno++;
+ line[len - 1] = '\0'; /* delete newline */
+ }
+ if (line[0] == '\0') /* empty, do not parse */
+ continue;
+ if (line[0] == '#') /* comment, do not parse */
+ continue;
+ if (line[0] == '!' && line[1] == ':') {
+ size_t i;
+
+ for (i = 0; bang[i].name != NULL; i++) {
+ if (len - 2 > bang[i].len &&
+ memcmp(bang[i].name, line + 2,
+ bang[i].len) == 0)
+ break;
+ }
+ if (bang[i].name == NULL) {
+ file_error(ms, 0,
+ "Unknown !: entry `%s'", line);
+ (*errs)++;
+ continue;
+ }
+ if (*marraycount == 0) {
+ file_error(ms, 0,
+ "No current entry for :!%s type",
+ bang[i].name);
+ (*errs)++;
+ continue;
+ }
+ if ((*bang[i].fun)(ms,
+ &(*marray)[*marraycount - 1],
+ line + bang[i].len + 2) != 0) {
+ (*errs)++;
+ continue;
+ }
+ continue;
+ }
+ if (parse(ms, marray, marraycount, line, lineno,
+ action) != 0)
+ (*errs)++;
+ }
+
+ (void)fclose(f);
}
+}
+
+/*
+ * parse a file or directory of files
+ * const char *fn: name of magic file or directory
+ */
+private int
+apprentice_load(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
+ const char *fn, int action)
+{
+ int errs = 0;
+ struct magic_entry *marray;
+ uint32_t marraycount, i, mentrycount = 0, starttest;
+ size_t slen;
+ char subfn[MAXPATHLEN];
+ struct stat st;
+ DIR *dir;
+ struct dirent *d;
+
+ ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
maxmagic = MAXMAGIS;
- if ((marray = calloc(maxmagic, sizeof(*marray))) == NULL) {
- (void)fclose(f);
+ if ((marray = CAST(struct magic_entry *, calloc(maxmagic,
+ sizeof(*marray)))) == NULL) {
file_oomem(ms, maxmagic * sizeof(*marray));
return -1;
}
@@ -553,32 +703,65 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
/* print silly verbose header for USG compat. */
if (action == FILE_CHECK)
- (void)fprintf(stderr, "%s\n", hdr);
+ (void)fprintf(stderr, "%s\n", usg_hdr);
+
+ /* load directory or file */
+ if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
+ dir = opendir(fn);
+ if (dir) {
+ while ((d = readdir(dir)) != NULL) {
+ snprintf(subfn, sizeof(subfn), "%s/%s",
+ fn, d->d_name);
+ if (stat(subfn, &st) == 0 &&
+ S_ISREG(st.st_mode)) {
+ load_1(ms, action, subfn, &errs,
+ &marray, &marraycount);
+ }
+ }
+ closedir(dir);
+ } else
+ errs++;
+ } else
+ load_1(ms, action, fn, &errs, &marray, &marraycount);
+ if (errs)
+ goto out;
- /* read and parse this file */
- for (ms->line = 1; fgets(line, sizeof(line), f) != NULL; ms->line++) {
- size_t len;
- len = strlen(line);
- if (len == 0) /* null line, garbage, etc */
+ /* Set types of tests */
+ for (i = 0; i < marraycount; ) {
+ if (marray[i].mp->cont_level != 0) {
+ i++;
continue;
- if (line[len - 1] == '\n') {
- lineno++;
- line[len - 1] = '\0'; /* delete newline */
}
- if (line[0] == '\0') /* empty, do not parse */
- continue;
- if (line[0] == '#') /* comment, do not parse */
- continue;
- if (parse(ms, &marray, &marraycount, line, lineno, action) != 0)
- errs++;
- }
- (void)fclose(f);
- if (errs)
- goto out;
+ starttest = i;
+ do {
+ static const char text[] = "text";
+ static const char binary[] = "binary";
+ static const size_t len = sizeof(text);
+ set_test_type(marray[starttest].mp, marray[i].mp);
+ if ((ms->flags & MAGIC_DEBUG) == 0)
+ continue;
+ (void)fprintf(stderr, "%s%s%s: %s\n",
+ marray[i].mp->mimetype,
+ marray[i].mp->mimetype[0] == '\0' ? "" : "; ",
+ marray[i].mp->desc[0] ? marray[i].mp->desc :
+ "(no description)",
+ marray[i].mp->flag & BINTEST ? binary : text);
+ if (marray[i].mp->flag & BINTEST) {
+ char *p = strstr(marray[i].mp->desc, text);
+ if (p && (p == marray[i].mp->desc ||
+ isspace((unsigned char)p[-1])) &&
+ (p + len - marray[i].mp->desc ==
+ MAXstring || (p[len] == '\0' ||
+ isspace((unsigned char)p[len]))))
+ (void)fprintf(stderr, "*** Possible "
+ "binary test for text type\n");
+ }
+ } while (++i < marraycount && marray[i].mp->cont_level != 0);
+ }
-#ifndef NOORDER
qsort(marray, marraycount, sizeof(*marray), apprentice_sort);
+
/*
* Make sure that any level 0 "default" line is last (if one exists).
*/
@@ -596,13 +779,13 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
break;
}
}
-#endif
for (i = 0; i < marraycount; i++)
mentrycount += marray[i].cont_count;
- if ((*magicp = malloc(sizeof(**magicp) * mentrycount)) == NULL) {
- file_oomem(ms, sizeof(**magicp) * mentrycount);
+ slen = sizeof(**magicp) * mentrycount;
+ if ((*magicp = CAST(struct magic *, malloc(slen))) == NULL) {
+ file_oomem(ms, slen);
errs++;
goto out;
}
@@ -699,7 +882,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
}
private int
-string_modifier_check(struct magic_set *ms, struct magic const *m)
+string_modifier_check(struct magic_set *ms, struct magic *m)
{
if ((ms->flags & MAGIC_CHECK) == 0)
return 0;
@@ -708,19 +891,28 @@ string_modifier_check(struct magic_set *ms, struct magic const *m)
case FILE_BESTRING16:
case FILE_LESTRING16:
if (m->str_flags != 0) {
- file_magwarn(ms, "no modifiers allowed for 16-bit strings\n");
+ file_magwarn(ms,
+ "no modifiers allowed for 16-bit strings\n");
return -1;
}
break;
case FILE_STRING:
case FILE_PSTRING:
if ((m->str_flags & REGEX_OFFSET_START) != 0) {
- file_magwarn(ms, "'/%c' only allowed on regex and search\n",
+ file_magwarn(ms,
+ "'/%c' only allowed on regex and search\n",
CHAR_REGEX_OFFSET_START);
return -1;
}
break;
case FILE_SEARCH:
+ if (m->str_range == 0) {
+ file_magwarn(ms,
+ "missing range; defaulting to %d\n",
+ STRING_DEFAULT_RANGE);
+ m->str_range = STRING_DEFAULT_RANGE;
+ return -1;
+ }
break;
case FILE_REGEX:
if ((m->str_flags & STRING_COMPACT_BLANK) != 0) {
@@ -771,19 +963,19 @@ get_op(char c)
private int
get_cond(const char *l, const char **t)
{
- static struct cond_tbl_s {
- const char *name;
- const size_t len;
- const int cond;
+ static const struct cond_tbl_s {
+ char name[8];
+ size_t len;
+ int cond;
} cond_tbl[] = {
{ "if", 2, COND_IF },
{ "elif", 4, COND_ELIF },
{ "else", 4, COND_ELSE },
- { NULL, 0, COND_NONE },
+ { "", 0, COND_NONE },
};
- struct cond_tbl_s *p;
+ const struct cond_tbl_s *p;
- for (p = cond_tbl; p->name; p++) {
+ for (p = cond_tbl; p->len; p++) {
if (strncmp(l, p->name, p->len) == 0 &&
isspace((unsigned char)l[p->len])) {
if (t)
@@ -881,7 +1073,8 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
if (me->cont_count == me->max_count) {
struct magic *nm;
size_t cnt = me->max_count + ALLOC_CHUNK;
- if ((nm = realloc(me->mp, sizeof(*nm) * cnt)) == NULL) {
+ if ((nm = CAST(struct magic *, realloc(me->mp,
+ sizeof(*nm) * cnt))) == NULL) {
file_oomem(ms, sizeof(*nm) * cnt);
return -1;
}
@@ -896,7 +1089,8 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
struct magic_entry *mp;
maxmagic += ALLOC_INCR;
- if ((mp = realloc(*mentryp, sizeof(*mp) * maxmagic)) ==
+ if ((mp = CAST(struct magic_entry *,
+ realloc(*mentryp, sizeof(*mp) * maxmagic))) ==
NULL) {
file_oomem(ms, sizeof(*mp) * maxmagic);
return -1;
@@ -907,8 +1101,9 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
}
me = &(*mentryp)[*nmentryp];
if (me->mp == NULL) {
- if ((m = malloc(sizeof(*m) * ALLOC_CHUNK)) == NULL) {
- file_oomem(ms, sizeof(*m) * ALLOC_CHUNK);
+ size_t len = sizeof(*m) * ALLOC_CHUNK;
+ if ((m = CAST(struct magic *, malloc(len))) == NULL) {
+ file_oomem(ms, len);
return -1;
}
me->mp = m;
@@ -916,6 +1111,7 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
} else
m = me->mp;
(void)memset(m, 0, sizeof(*m));
+ m->factor_op = FILE_FACTOR_OP_NONE;
m->cont_level = 0;
me->cont_count = 1;
}
@@ -1060,7 +1256,7 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
file_magwarn(ms, "'~' invalid for string types");
++l;
}
- m->str_count = 0;
+ m->str_range = 0;
m->str_flags = 0;
m->num_mask = 0;
if ((op = get_op(*l)) != -1) {
@@ -1074,22 +1270,24 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
eatsize(&l);
}
else if (op == FILE_OPDIVIDE) {
- int have_count = 0;
+ int have_range = 0;
while (!isspace((unsigned char)*++l)) {
switch (*l) {
- /* for portability avoid "case '0' ... '9':" */
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
- case '9': {
- if (have_count && ms->flags & MAGIC_CHECK)
+ case '9':
+ if (have_range &&
+ (ms->flags & MAGIC_CHECK))
+ file_magwarn(ms,
+ "multiple ranges");
+ have_range = 1;
+ m->str_range = strtoul(l, &t, 0);
+ if (m->str_range == 0)
file_magwarn(ms,
- "multiple counts");
- have_count = 1;
- m->str_count = strtoul(l, &t, 0);
+ "zero range");
l = t - 1;
break;
- }
case CHAR_COMPACT_BLANK:
m->str_flags |= STRING_COMPACT_BLANK;
break;
@@ -1114,7 +1312,8 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
return -1;
}
/* allow multiple '/' for readability */
- if (l[1] == '/' && !isspace((unsigned char)l[2]))
+ if (l[1] == '/' &&
+ !isspace((unsigned char)l[2]))
l++;
}
if (string_modifier_check(ms, m) == -1)
@@ -1135,6 +1334,17 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
switch (*l) {
case '>':
case '<':
+ m->reln = *l;
+ ++l;
+ if (*l == '=') {
+ if (ms->flags & MAGIC_CHECK) {
+ file_magwarn(ms, "%c= not supported",
+ m->reln);
+ return -1;
+ }
+ ++l;
+ }
+ break;
/* Old-style anding: "0 byte &0x80 dynamically linked" */
case '&':
case '^':
@@ -1177,13 +1387,12 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
EATAB;
if (l[0] == '\b') {
++l;
- m->nospflag = 1;
+ m->flag |= NOSPACE;
} else if ((l[0] == '\\') && (l[1] == 'b')) {
++l;
++l;
- m->nospflag = 1;
- } else
- m->nospflag = 0;
+ m->flag |= NOSPACE;
+ }
for (i = 0; (m->desc[i++] = *l++) != '\0' && i < sizeof(m->desc); )
continue;
if (i == sizeof(m->desc)) {
@@ -1205,11 +1414,103 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
file_mdump(m);
}
#endif
+ m->mimetype[0] = '\0'; /* initialise MIME type to none */
if (m->cont_level == 0)
++(*nmentryp); /* make room for next */
return 0;
}
+/*
+ * parse a STRENGTH annotation line from magic file, put into magic[index - 1]
+ * if valid
+ */
+private int
+parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+ const char *l = line;
+ char *el;
+ unsigned long factor;
+ struct magic *m = &me->mp[0];
+
+ if (m->factor_op != FILE_FACTOR_OP_NONE) {
+ file_magwarn(ms,
+ "Current entry already has a strength type: %c %d",
+ m->factor_op, m->factor);
+ return -1;
+ }
+ EATAB;
+ switch (*l) {
+ case FILE_FACTOR_OP_NONE:
+ case FILE_FACTOR_OP_PLUS:
+ case FILE_FACTOR_OP_MINUS:
+ case FILE_FACTOR_OP_TIMES:
+ case FILE_FACTOR_OP_DIV:
+ m->factor_op = *l++;
+ break;
+ default:
+ file_magwarn(ms, "Unknown factor op `%c'", *l);
+ return -1;
+ }
+ EATAB;
+ factor = strtoul(l, &el, 0);
+ if (factor > 255) {
+ file_magwarn(ms, "Too large factor `%lu'", factor);
+ goto out;
+ }
+ if (*el && !isspace((unsigned char)*el)) {
+ file_magwarn(ms, "Bad factor `%s'", l);
+ goto out;
+ }
+ m->factor = (uint8_t)factor;
+ if (m->factor == 0 && m->factor_op == FILE_FACTOR_OP_DIV) {
+ file_magwarn(ms, "Cannot have factor op `%c' and factor %u",
+ m->factor_op, m->factor);
+ goto out;
+ }
+ return 0;
+out:
+ m->factor_op = FILE_FACTOR_OP_NONE;
+ m->factor = 0;
+ return -1;
+}
+
+/*
+ * parse a MIME annotation line from magic file, put into magic[index - 1]
+ * if valid
+ */
+private int
+parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+ size_t i;
+ const char *l = line;
+ struct magic *m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1];
+
+ if (m->mimetype[0] != '\0') {
+ file_magwarn(ms, "Current entry already has a MIME type `%s',"
+ " new type `%s'", m->mimetype, l);
+ return -1;
+ }
+
+ EATAB;
+ for (i = 0;
+ *l && ((isascii((unsigned char)*l) && isalnum((unsigned char)*l))
+ || strchr("-+/.", *l)) && i < sizeof(m->mimetype);
+ m->mimetype[i++] = *l++)
+ continue;
+ if (i == sizeof(m->mimetype)) {
+ m->desc[sizeof(m->mimetype) - 1] = '\0';
+ if (ms->flags & MAGIC_CHECK)
+ file_magwarn(ms, "MIME type `%s' truncated %zu",
+ m->mimetype, i);
+ } else
+ m->mimetype[i] = '\0';
+
+ if (i > 0)
+ return 0;
+ else
+ return -1;
+}
+
private int
check_format_type(const char *ptr, int type)
{
@@ -1354,12 +1655,12 @@ check_format(struct magic_set *ms, struct magic *m)
assert(file_nformats == file_nnames);
if (m->type >= file_nformats) {
- file_error(ms, 0, "Internal error inconsistency between "
+ file_magwarn(ms, "Internal error inconsistency between "
"m->type and format strings");
return -1;
}
if (file_formats[m->type] == FILE_FMT_NONE) {
- file_error(ms, 0, "No format string for `%s' with description "
+ file_magwarn(ms, "No format string for `%s' with description "
"`%s'", m->desc, file_names[m->type]);
return -1;
}
@@ -1370,15 +1671,16 @@ check_format(struct magic_set *ms, struct magic *m)
* TODO: this error message is unhelpful if the format
* string is not one character long
*/
- file_error(ms, 0, "Printf format `%c' is not valid for type "
- " `%s' in description `%s'", *ptr,
+ file_magwarn(ms, "Printf format `%c' is not valid for type "
+ "`%s' in description `%s'",
+ ptr && *ptr ? *ptr : '?',
file_names[m->type], m->desc);
return -1;
}
for (; *ptr; ptr++) {
if (*ptr == '%') {
- file_error(ms, 0,
+ file_magwarn(ms,
"Too many format strings (should have at most one) "
"for `%s' with description `%s'",
file_names[m->type], m->desc);
@@ -1413,6 +1715,8 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
return -1;
}
m->vallen = slen;
+ if (m->type == FILE_PSTRING)
+ m->vallen++;
return 0;
case FILE_FLOAT:
case FILE_BEFLOAT:
@@ -1709,51 +2013,51 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
uint32_t *ptr;
uint32_t version;
int needsbyteswap;
- char buf[MAXPATHLEN];
- char *dbname = mkdbname(fn, buf, sizeof(buf), 0);
+ char *dbname = NULL;
void *mm = NULL;
+ mkdbname(fn, &dbname, 0);
if (dbname == NULL)
- return -1;
+ goto error2;
if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
- return -1;
+ goto error2;
if (fstat(fd, &st) == -1) {
file_error(ms, errno, "cannot stat `%s'", dbname);
- goto error;
+ goto error1;
}
- if (st.st_size < 16) {
+ if (st.st_size < 8) {
file_error(ms, 0, "file `%s' is too small", dbname);
- goto error;
+ goto error1;
}
#ifdef QUICK
if ((mm = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
file_error(ms, errno, "cannot map `%s'", dbname);
- goto error;
+ goto error1;
}
#define RET 2
#else
- if ((mm = malloc((size_t)st.st_size)) == NULL) {
+ if ((mm = CAST(void *, malloc((size_t)st.st_size))) == NULL) {
file_oomem(ms, (size_t)st.st_size);
- goto error;
+ goto error1;
}
if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) {
file_badread(ms);
- goto error;
+ goto error1;
}
#define RET 1
#endif
- *magicp = mm;
+ *magicp = CAST(struct magic *, mm);
(void)close(fd);
fd = -1;
ptr = (uint32_t *)(void *)*magicp;
if (*ptr != MAGICNO) {
if (swap4(*ptr) != MAGICNO) {
- file_error(ms, 0, "bad magic in `%s'");
- goto error;
+ file_error(ms, 0, "bad magic in `%s'", dbname);
+ goto error1;
}
needsbyteswap = 1;
} else
@@ -1766,15 +2070,18 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
file_error(ms, 0, "File %d.%d supports only %d version magic "
"files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
VERSIONNO, dbname, version);
- goto error;
+ goto error1;
}
- *nmagicp = (uint32_t)(st.st_size / sizeof(struct magic)) - 1;
+ *nmagicp = (uint32_t)(st.st_size / sizeof(struct magic));
+ if (*nmagicp > 0)
+ (*nmagicp)--;
(*magicp)++;
if (needsbyteswap)
byteswap(*magicp, *nmagicp);
+ free(dbname);
return RET;
-error:
+error1:
if (fd != -1)
(void)close(fd);
if (mm) {
@@ -1787,6 +2094,8 @@ error:
*magicp = NULL;
*nmagicp = 0;
}
+error2:
+ free(dbname);
return -1;
}
@@ -1801,53 +2110,65 @@ apprentice_compile(struct magic_set *ms, struct magic **magicp,
uint32_t *nmagicp, const char *fn)
{
int fd;
- char buf[MAXPATHLEN];
- char *dbname = mkdbname(fn, buf, sizeof(buf), 1);
+ char *dbname;
+ int rv = -1;
+
+ mkdbname(fn, &dbname, 1);
if (dbname == NULL)
- return -1;
+ goto out;
if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) {
file_error(ms, errno, "cannot open `%s'", dbname);
- return -1;
+ goto out;
}
if (write(fd, ar, sizeof(ar)) != (ssize_t)sizeof(ar)) {
file_error(ms, errno, "error writing `%s'", dbname);
- return -1;
+ goto out;
}
if (lseek(fd, (off_t)sizeof(struct magic), SEEK_SET)
!= sizeof(struct magic)) {
file_error(ms, errno, "error seeking `%s'", dbname);
- return -1;
+ goto out;
}
if (write(fd, *magicp, (sizeof(struct magic) * *nmagicp))
!= (ssize_t)(sizeof(struct magic) * *nmagicp)) {
file_error(ms, errno, "error writing `%s'", dbname);
- return -1;
+ goto out;
}
(void)close(fd);
- return 0;
+ rv = 0;
+out:
+ free(dbname);
+ return rv;
}
private const char ext[] = ".mgc";
/*
* make a dbname
*/
-private char *
-mkdbname(const char *fn, char *buf, size_t bufsiz, int strip)
+private void
+mkdbname(const char *fn, char **buf, int strip)
{
+ const char *p;
if (strip) {
- const char *p;
if ((p = strrchr(fn, '/')) != NULL)
fn = ++p;
}
- (void)snprintf(buf, bufsiz, "%s%s", fn, ext);
- return buf;
+ if ((p = strstr(fn, ext)) != NULL && p[sizeof(ext) - 1] == '\0')
+ *buf = strdup(fn);
+ else
+ (void)asprintf(buf, "%s%s", fn, ext);
+
+ if (buf && *buf && strlen(*buf) > MAXPATHLEN) {
+ free(*buf);
+ *buf = NULL;
+ }
}
/*
@@ -1897,9 +2218,10 @@ swap4(uint32_t sv)
private uint64_t
swap8(uint64_t sv)
{
- uint32_t rv;
+ uint64_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
+#if 0
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
@@ -1908,6 +2230,16 @@ swap8(uint64_t sv)
d[5] = s[6];
d[6] = s[5];
d[7] = s[4];
+#else
+ d[0] = s[7];
+ d[1] = s[6];
+ d[2] = s[5];
+ d[3] = s[4];
+ d[4] = s[3];
+ d[5] = s[2];
+ d[6] = s[1];
+ d[7] = s[0];
+#endif
return rv;
}
@@ -1922,7 +2254,7 @@ bs1(struct magic *m)
m->in_offset = swap4((uint32_t)m->in_offset);
m->lineno = swap4((uint32_t)m->lineno);
if (IS_STRING(m->type)) {
- m->str_count = swap4(m->str_count);
+ m->str_range = swap4(m->str_range);
m->str_flags = swap4(m->str_flags);
}
else {
diff --git a/contrib/file/ascmagic.c b/contrib/file/ascmagic.c
index 8d2d9a7..c374e02 100644
--- a/contrib/file/ascmagic.c
+++ b/contrib/file/ascmagic.c
@@ -49,32 +49,32 @@
#include "names.h"
#ifndef lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.53 2007/10/29 00:54:08 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.64 2008/07/16 18:00:57 christos Exp $")
#endif /* lint */
-typedef unsigned long unichar;
-
#define MAXLINELEN 300 /* longest sane line length */
#define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' \
|| (x) == 0x85 || (x) == '\f')
private int looks_ascii(const unsigned char *, size_t, unichar *, size_t *);
-private int looks_utf8(const unsigned char *, size_t, unichar *, size_t *);
-private int looks_unicode(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *,
+ size_t *);
+private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *);
private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *);
private int looks_extended(const unsigned char *, size_t, unichar *, size_t *);
private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
private int ascmatch(const unsigned char *, const unichar *, size_t);
+private unsigned char *encode_utf8(unsigned char *, size_t, unichar *, size_t);
protected int
file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
{
size_t i;
- unsigned char *nbuf = NULL;
+ unsigned char *nbuf = NULL, *utf8_buf = NULL, *utf8_end;
unichar *ubuf = NULL;
- size_t ulen;
- struct names *p;
+ size_t ulen, mlen;
+ const struct names *p;
int rv = -1;
int mime = ms->flags & MAGIC_MIME;
@@ -103,9 +103,11 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
while (nbytes > 1 && buf[nbytes - 1] == '\0')
nbytes--;
- if ((nbuf = calloc(1, (nbytes + 1) * sizeof(nbuf[0]))) == NULL)
+ if ((nbuf = CAST(unsigned char *, calloc((size_t)1,
+ (nbytes + 1) * sizeof(nbuf[0])))) == NULL)
goto done;
- if ((ubuf = calloc(1, (nbytes + 1) * sizeof(ubuf[0]))) == NULL)
+ if ((ubuf = CAST(unichar *, calloc((size_t)1,
+ (nbytes + 1) * sizeof(ubuf[0])))) == NULL)
goto done;
/*
@@ -118,11 +120,15 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
code = "ASCII";
code_mime = "us-ascii";
type = "text";
- } else if (looks_utf8(buf, nbytes, ubuf, &ulen)) {
+ } else if (looks_utf8_with_BOM(buf, nbytes, ubuf, &ulen) > 0) {
+ code = "UTF-8 Unicode (with BOM)";
+ code_mime = "utf-8";
+ type = "text";
+ } else if (file_looks_utf8(buf, nbytes, ubuf, &ulen) > 1) {
code = "UTF-8 Unicode";
code_mime = "utf-8";
type = "text";
- } else if ((i = looks_unicode(buf, nbytes, ubuf, &ulen)) != 0) {
+ } else if ((i = looks_ucs16(buf, nbytes, ubuf, &ulen)) != 0) {
if (i == 1)
code = "Little-endian UTF-16 Unicode";
else
@@ -160,33 +166,25 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
goto done;
}
- /*
- * for troff, look for . + letter + letter or .\";
- * this must be done to disambiguate tar archives' ./file
- * and other trash from real troff input.
- *
- * I believe Plan 9 troff allows non-ASCII characters in the names
- * of macros, so this test might possibly fail on such a file.
- */
- if ((ms->flags & MAGIC_NO_CHECK_TROFF) == 0 && *ubuf == '.') {
- unichar *tp = ubuf + 1;
-
- while (ISSPC(*tp))
- ++tp; /* skip leading whitespace */
- if ((tp[0] == '\\' && tp[1] == '\"') ||
- (isascii((unsigned char)tp[0]) &&
- isalnum((unsigned char)tp[0]) &&
- isascii((unsigned char)tp[1]) &&
- isalnum((unsigned char)tp[1]) &&
- ISSPC(tp[2]))) {
- subtype_mime = "text/troff";
- subtype = "troff or preprocessor input";
- goto subtype_identified;
- }
+ /* Convert ubuf to UTF-8 and try text soft magic */
+ /* If original was ASCII or UTF-8, could use nbuf instead of
+ re-converting. */
+ /* malloc size is a conservative overestimate; could be
+ re-converting improved, or at least realloced after
+ re-converting conversion. */
+ mlen = ulen * 6;
+ if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
+ file_oomem(ms, mlen);
+ goto done;
+ }
+ if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen)) == NULL)
+ goto done;
+ if (file_softmagic(ms, utf8_buf, utf8_end - utf8_buf, TEXTTEST) != 0) {
+ rv = 1;
+ goto done;
}
/* look for tokens from names.h - this is expensive! */
-
if ((ms->flags & MAGIC_NO_CHECK_TOKENS) != 0)
goto subtype_identified;
@@ -194,24 +192,18 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
while (i < ulen) {
size_t end;
- /*
- * skip past any leading space
- */
+ /* skip past any leading space */
while (i < ulen && ISSPC(ubuf[i]))
i++;
if (i >= ulen)
break;
- /*
- * find the next whitespace
- */
+ /* find the next whitespace */
for (end = i + 1; end < nbytes; end++)
if (ISSPC(ubuf[end]))
break;
- /*
- * compare the word thus isolated against the token list
- */
+ /* compare the word thus isolated against the token list */
for (p = names; p < names + NNAMES; p++) {
if (ascmatch((const unsigned char *)p->name, ubuf + i,
end - i)) {
@@ -226,9 +218,7 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
subtype_identified:
- /*
- * Now try to discover other details about the file.
- */
+ /* Now try to discover other details about the file. */
for (i = 0; i < ulen; i++) {
if (ubuf[i] == '\n') {
if (seen_cr)
@@ -362,6 +352,8 @@ done:
free(nbuf);
if (ubuf)
free(ubuf);
+ if (utf8_buf)
+ free(utf8_buf);
return rv;
}
@@ -520,15 +512,84 @@ looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
return 1;
}
-private int
-looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
+/*
+ * Encode Unicode string as UTF-8, returning pointer to character
+ * after end of string, or NULL if an invalid character is found.
+ */
+private unsigned char *
+encode_utf8(unsigned char *buf, size_t len, unichar *ubuf, size_t ulen)
+{
+ size_t i;
+ unsigned char *end = buf + len;
+
+ for (i = 0; i < ulen; i++) {
+ if (ubuf[i] <= 0x7f) {
+ if (end - buf < 1)
+ return NULL;
+ *buf++ = (unsigned char)ubuf[i];
+ } else if (ubuf[i] <= 0x7ff) {
+ if (end - buf < 2)
+ return NULL;
+ *buf++ = (unsigned char)((ubuf[i] >> 6) + 0xc0);
+ *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ } else if (ubuf[i] <= 0xffff) {
+ if (end - buf < 3)
+ return NULL;
+ *buf++ = (unsigned char)((ubuf[i] >> 12) + 0xe0);
+ *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ } else if (ubuf[i] <= 0x1fffff) {
+ if (end - buf < 4)
+ return NULL;
+ *buf++ = (unsigned char)((ubuf[i] >> 18) + 0xf0);
+ *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ } else if (ubuf[i] <= 0x3ffffff) {
+ if (end - buf < 5)
+ return NULL;
+ *buf++ = (unsigned char)((ubuf[i] >> 24) + 0xf8);
+ *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ } else if (ubuf[i] <= 0x7fffffff) {
+ if (end - buf < 6)
+ return NULL;
+ *buf++ = (unsigned char)((ubuf[i] >> 30) + 0xfc);
+ *buf++ = (unsigned char)(((ubuf[i] >> 24) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ } else /* Invalid character */
+ return NULL;
+ }
+
+ return buf;
+}
+
+/*
+ * Decide whether some text looks like UTF-8. Returns:
+ *
+ * -1: invalid UTF-8
+ * 0: uses odd control characters, so doesn't look like text
+ * 1: 7-bit text
+ * 2: definitely UTF-8 text (valid high-bit set bytes)
+ *
+ * If ubuf is non-NULL on entry, text is decoded into ubuf, *ulen;
+ * ubuf must be big enough!
+ */
+protected int
+file_looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
{
size_t i;
int n;
unichar c;
- int gotone = 0;
+ int gotone = 0, ctrl = 0;
- *ulen = 0;
+ if (ubuf)
+ *ulen = 0;
for (i = 0; i < nbytes; i++) {
if ((buf[i] & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */
@@ -538,11 +599,12 @@ looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
*/
if (text_chars[buf[i]] != T)
- return 0;
+ ctrl = 1;
- ubuf[(*ulen)++] = buf[i];
+ if (ubuf)
+ ubuf[(*ulen)++] = buf[i];
} else if ((buf[i] & 0x40) == 0) { /* 10xxxxxx never 1st byte */
- return 0;
+ return -1;
} else { /* 11xxxxxx begins UTF-8 */
int following;
@@ -562,7 +624,7 @@ looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
c = buf[i] & 0x01;
following = 5;
} else
- return 0;
+ return -1;
for (n = 0; n < following; n++) {
i++;
@@ -570,21 +632,37 @@ looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
goto done;
if ((buf[i] & 0x80) == 0 || (buf[i] & 0x40))
- return 0;
+ return -1;
c = (c << 6) + (buf[i] & 0x3f);
}
- ubuf[(*ulen)++] = c;
+ if (ubuf)
+ ubuf[(*ulen)++] = c;
gotone = 1;
}
}
done:
- return gotone; /* don't claim it's UTF-8 if it's all 7-bit */
+ return ctrl ? 0 : (gotone ? 2 : 1);
+}
+
+/*
+ * Decide whether some text looks like UTF-8 with BOM. If there is no
+ * BOM, return -1; otherwise return the result of looks_utf8 on the
+ * rest of the text.
+ */
+private int
+looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+ size_t *ulen)
+{
+ if (nbytes > 3 && buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
+ return file_looks_utf8(buf + 3, nbytes - 3, ubuf, ulen);
+ else
+ return -1;
}
private int
-looks_unicode(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
size_t *ulen)
{
int bigend;
diff --git a/contrib/file/test.c b/contrib/file/asprintf.c
index 55b78d3..c103cf1 100644
--- a/contrib/file/test.c
+++ b/contrib/file/asprintf.c
@@ -1,6 +1,7 @@
/*
- * Copyright (c) Christos Zoulas 2003.
- * All Rights Reserved.
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,36 +25,19 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <stdio.h>
-#include "magic.h"
-int
-main(int argc, char **argv)
-{
- struct magic_set *ms;
- const char *m;
- int i;
+#include <stdarg.h>
- if(argc < 2)
- return 1;
+int vasprintf(char **ptr, const char *format_string, va_list vargs);
- ms = magic_open(MAGIC_NONE);
- if (ms == NULL) {
- (void) printf("ERROR: out of memory\n");
- return 1;
- }
- if (magic_load(ms, NULL) == -1) {
- (void) printf("ERROR: %s\n", magic_error(ms));
- return 1;
- }
+int asprintf(char **ptr, const char *fmt, ...)
+{
+ va_list vargs;
+ int retval;
- for (i = 1; i < argc; i++) {
- if ((m = magic_file(ms, argv[i])) == NULL)
- (void) printf("ERROR: %s\n", magic_error(ms));
- else
- (void) printf("%s: %s\n", argv[i], m);
- }
+ va_start(vargs, fmt);
+ retval = vasprintf(ptr, fmt, vargs);
+ va_end(vargs);
- magic_close(ms);
- return 0;
+ return retval;
}
diff --git a/contrib/file/compile b/contrib/file/compile
new file mode 100755
index 0000000..1b1d232
--- /dev/null
+++ b/contrib/file/compile
@@ -0,0 +1,142 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2005-05-14.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as `compile cc -o foo foo.c'.
+ # So we strip `-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no `-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # `.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/contrib/file/compress.c b/contrib/file/compress.c
index 487b1b7..5867ac9 100644
--- a/contrib/file/compress.c
+++ b/contrib/file/compress.c
@@ -56,13 +56,13 @@
#ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.54 2007/12/02 00:28:10 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.57 2008/07/16 18:00:57 christos Exp $")
#endif
-private struct {
- const char *magic;
+private const struct {
+ const char magic[8];
size_t maglen;
- const char *const argv[3];
+ const char *argv[3];
int silent;
} compr[] = {
{ "\037\235", 2, { "gzip", "-cdq", NULL }, 1 }, /* compressed */
@@ -330,7 +330,7 @@ uncompressgzipped(struct magic_set *ms, const unsigned char *old,
if (data_start >= n)
return 0;
- if ((*newch = (unsigned char *)malloc(HOWMANY + 1)) == NULL) {
+ if ((*newch = CAST(unsigned char *, malloc(HOWMANY + 1))) == NULL) {
return 0;
}
@@ -374,6 +374,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
int r;
#ifdef BUILTIN_DECOMPRESS
+ /* FIXME: This doesn't cope with bzip2 */
if (method == 2)
return uncompressgzipped(ms, old, newch, n);
#endif
diff --git a/contrib/file/config.guess b/contrib/file/config.guess
new file mode 100755
index 0000000..3d427f0
--- /dev/null
+++ b/contrib/file/config.guess
@@ -0,0 +1,1504 @@
+#! /bin/sh
+#
+# $NetBSD: config.guess,v 1.9 2006/10/29 23:50:54 wiz Exp $
+#
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+# Inc.
+
+timestamp='2006-07-02'
+
+# 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
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# 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.
+#
+# 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.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+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
+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."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" 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
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ 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:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ x86:Interix*:[3456]*)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T:Interix*:[3456]*)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-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
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #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
+ }'`"
+ 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
+ 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}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-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 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ 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
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ 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
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ 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; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/contrib/file/config.h.in b/contrib/file/config.h.in
index 281a4e4..26585d8 100644
--- a/contrib/file/config.h.in
+++ b/contrib/file/config.h.in
@@ -1,26 +1,41 @@
-/* config.h.in. Generated from configure.in by autoheader. */
+/* config.h.in. Generated from configure.ac by autoheader. */
-/* Use the builtin ELF recognition code */
+/* Define in built-in ELF support is used */
#undef BUILTIN_ELF
-/* Recognize ELF core files */
+/* Define for ELF core file support */
#undef ELFCORE
-/* */
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* HAVE_DAYLIGHT */
#undef HAVE_DAYLIGHT
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the `getopt_long' function. */
#undef HAVE_GETOPT_LONG
+/* Define to 1 if the system has the type `int32_t'. */
+#undef HAVE_INT32_T
+
+/* Define to 1 if the system has the type `int64_t'. */
+#undef HAVE_INT64_T
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -33,9 +48,6 @@
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
-/* */
-#undef HAVE_LONG_LONG
-
/* Define to 1 if you have the `mbrtowc' function. */
#undef HAVE_MBRTOWC
@@ -51,9 +63,6 @@
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
-
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -81,10 +90,6 @@
/* Define to 1 if `st_rdev' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV
-/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
- `HAVE_STRUCT_STAT_ST_RDEV' instead. */
-#undef HAVE_ST_RDEV
-
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
@@ -103,7 +108,7 @@
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
-/* */
+/* HAVE_TM_ISDST */
#undef HAVE_TM_ISDST
/* HAVE_TM_ZONE */
@@ -112,6 +117,18 @@
/* HAVE_TZNAME */
#undef HAVE_TZNAME
+/* Define to 1 if the system has the type `uint16_t'. */
+#undef HAVE_UINT16_T
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#undef HAVE_UINT32_T
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#undef HAVE_UINT8_T
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
@@ -124,8 +141,8 @@
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
-/* Define to 1 if you have the `vsnprintf' function. */
-#undef HAVE_VSNPRINTF
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
@@ -147,6 +164,9 @@
<sysmacros.h>. */
#undef MAJOR_IN_SYSMACROS
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
/* Name of package */
#undef PACKAGE
@@ -165,20 +185,8 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* */
-#undef SIZEOF_INT64_T
-
-/* */
-#undef SIZEOF_UINT16_T
-
-/* */
-#undef SIZEOF_UINT32_T
-
-/* */
-#undef SIZEOF_UINT64_T
-
-/* */
-#undef SIZEOF_UINT8_T
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
@@ -197,18 +205,15 @@
# undef _GNU_SOURCE
#endif
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
-/* */
-#undef int32_t
-
-/* */
-#undef int64_t
-
/* Define to a type if <wchar.h> does not define. */
#undef mbstate_t
@@ -218,14 +223,31 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
-/* */
-#undef uint16_t
-
-/* */
-#undef uint32_t
-/* */
-#undef uint64_t
+#ifndef HAVE_UINT8_T
+typedef unsigned char uint8_t;
+#endif
+#ifndef HAVE_UINT16_T
+typedef unsigned short uint16_t;
+#endif
+#ifndef HAVE_UINT32_T
+typedef unsigned int uint32_t;
+#endif
+#ifndef HAVE_INT32_T
+typedef int int32_t;
+#endif
+#ifndef HAVE_UINT64_T
+#if SIZEOF_LONG_LONG == 8
+typedef unsigned long long uint64_t;
+#else
+typedef unsigned long uint64_t;
+#endif
+#endif
+#ifndef HAVE_INT64_T
+#if SIZEOF_LONG_LONG == 8
+typedef long long int64_t;
+#else
+typedef long int64_t;
+#endif
+#endif
-/* */
-#undef uint8_t
diff --git a/contrib/file/config.sub b/contrib/file/config.sub
new file mode 100755
index 0000000..5b2ab48
--- /dev/null
+++ b/contrib/file/config.sub
@@ -0,0 +1,1622 @@
+#! /bin/sh
+#
+# $NetBSD: config.sub,v 1.8 2006/10/29 23:52:55 wiz Exp $
+#
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+# Inc.
+
+timestamp='2006-09-20'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# 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
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+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."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | mt \
+ | msp430 \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/contrib/file/configure b/contrib/file/configure
index a81d93d..bf5ba589 100755
--- a/contrib/file/configure
+++ b/contrib/file/configure
@@ -1,6 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61.
+# Generated by GNU Autoconf 2.61 for file 4.26.
+#
+# Report bugs to <christos@astron.com>.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -724,13 +726,12 @@ MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
+PACKAGE_NAME='file'
+PACKAGE_TARNAME='file'
+PACKAGE_VERSION='4.26'
+PACKAGE_STRING='file 4.26'
+PACKAGE_BUGREPORT='christos@astron.com'
-ac_unique_file="src/file.c"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
@@ -826,12 +827,10 @@ am__leading_dot
AMTAR
am__tar
am__untar
-MAINTAINER_MODE_TRUE
-MAINTAINER_MODE_FALSE
-MAINT
fsect
FSECT5_TRUE
FSECT5_FALSE
+WARNINGS
CC
CFLAGS
LDFLAGS
@@ -874,9 +873,9 @@ F77
FFLAGS
ac_ct_F77
LIBTOOL
+LIBOBJS
IS_CROSS_COMPILE_TRUE
IS_CROSS_COMPILE_FALSE
-LIBOBJS
LTLIBOBJS'
ac_subst_files=''
ac_precious_vars='build_alias
@@ -932,7 +931,7 @@ sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
@@ -1396,7 +1395,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures file 4.26 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1444,7 +1443,7 @@ Fine tuning of the installation directories:
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/file]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1465,14 +1464,14 @@ _ACEOF
fi
if test -n "$ac_init_help"; then
-
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of file 4.26:";;
+ esac
cat <<\_ACEOF
Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer
--disable-elf disable builtin ELF support
--disable-elf-core disable ELF core file support
--enable-fsect-man5 enable file formats in man section 5
@@ -1484,6 +1483,7 @@ Optional Features:
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--disable-largefile omit support for large files
+ --disable-warnings disable compiler warnings
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1511,6 +1511,7 @@ Some influential environment variables:
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
+Report bugs to <christos@astron.com>.
_ACEOF
ac_status=$?
fi
@@ -1571,7 +1572,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-configure
+file configure 4.26
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1585,7 +1586,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by $as_me, which was
+It was created by file $as_me 4.26, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -1923,6 +1924,14 @@ fi
+
+
+
+
+
+
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -1930,7 +1939,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
am__api_version='1.10'
ac_aux_dir=
@@ -2267,8 +2275,8 @@ fi
# Define the identity of the package.
- PACKAGE=file
- VERSION=4.23
+ PACKAGE='file'
+ VERSION='4.26'
cat >>confdefs.h <<_ACEOF
@@ -2416,28 +2424,6 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
ac_config_headers="$ac_config_headers config.h"
-{ echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
-echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; }
- # Check whether --enable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then
- enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
-else
- USE_MAINTAINER_MODE=no
-fi
-
- { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
-echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; }
- if test $USE_MAINTAINER_MODE = yes; then
- MAINTAINER_MODE_TRUE=
- MAINTAINER_MODE_FALSE='#'
-else
- MAINTAINER_MODE_TRUE='#'
- MAINTAINER_MODE_FALSE=
-fi
-
- MAINT=$MAINTAINER_MODE_TRUE
-
-
{ echo "$as_me:$LINENO: checking for builtin ELF support" >&5
echo $ECHO_N "checking for builtin ELF support... $ECHO_C" >&6; }
@@ -2446,7 +2432,8 @@ if test "${enable_elf+set}" = set; then
enableval=$enable_elf; if test "${enableval}" = yes; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
- cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define BUILTIN_ELF 1
_ACEOF
@@ -2459,7 +2446,8 @@ else
# enable by default
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
- cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define BUILTIN_ELF 1
_ACEOF
@@ -2474,7 +2462,8 @@ if test "${enable_elf_core+set}" = set; then
enableval=$enable_elf_core; if test "${enableval}" = yes; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
- cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define ELFCORE 1
_ACEOF
@@ -2487,7 +2476,8 @@ else
# enable by default
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
- cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define ELFCORE 1
_ACEOF
@@ -2518,6 +2508,7 @@ echo "${ECHO_T}no" >&6; }
fi
+
if test x$fsect = x5; then
FSECT5_TRUE=
FSECT5_FALSE='#'
@@ -2527,6 +2518,8 @@ else
fi
+
+
cat >>confdefs.h <<\_ACEOF
#define _GNU_SOURCE 1
_ACEOF
@@ -3622,6 +3615,132 @@ else
fi
+if test "x$CC" != xcc; then
+ { echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5
+echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6; }
+else
+ { echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5
+echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6; }
+fi
+set dummy $CC; ac_cc=`echo $2 |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ test -f conftest2.$ac_objext && { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&5'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ test -f conftest2.$ac_objext && { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_MINUS_C_MINUS_O 1
+_ACEOF
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
+
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
@@ -4484,7 +4603,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4487 "configure"' > conftest.$ac_ext
+ echo '#line 4606 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -5233,7 +5352,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -7225,11 +7349,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7228: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7352: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7232: \$? = $ac_status" >&5
+ echo "$as_me:7356: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7487,11 +7611,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7490: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7614: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7494: \$? = $ac_status" >&5
+ echo "$as_me:7618: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7549,11 +7673,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7552: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7676: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7556: \$? = $ac_status" >&5
+ echo "$as_me:7680: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -9752,7 +9876,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9755 "configure"
+#line 9879 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9850,7 +9974,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9853 "configure"
+#line 9977 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12094,11 +12218,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12097: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12221: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:12101: \$? = $ac_status" >&5
+ echo "$as_me:12225: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -12156,11 +12280,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12159: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12283: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:12163: \$? = $ac_status" >&5
+ echo "$as_me:12287: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -13492,7 +13616,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 13495 "configure"
+#line 13619 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13590,7 +13714,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 13593 "configure"
+#line 13717 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -14475,11 +14599,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14478: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14602: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:14482: \$? = $ac_status" >&5
+ echo "$as_me:14606: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -14537,11 +14661,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14540: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14664: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:14544: \$? = $ac_status" >&5
+ echo "$as_me:14668: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -16654,11 +16778,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16657: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16781: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16661: \$? = $ac_status" >&5
+ echo "$as_me:16785: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16916,11 +17040,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16919: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17043: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16923: \$? = $ac_status" >&5
+ echo "$as_me:17047: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16978,11 +17102,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16981: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17105: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:16985: \$? = $ac_status" >&5
+ echo "$as_me:17109: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -19181,7 +19305,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 19184 "configure"
+#line 19308 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -19279,7 +19403,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 19282 "configure"
+#line 19406 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -20329,39 +20453,6 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
if test "${ac_cv_header_stdc+set}" = set; then
@@ -20701,7 +20792,12 @@ echo "$as_me: WARNING: sys/mkdev.h: section \"Present But Cannot Be Compiled
echo "$as_me: WARNING: sys/mkdev.h: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: sys/mkdev.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: sys/mkdev.h: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for sys/mkdev.h" >&5
@@ -20837,7 +20933,12 @@ echo "$as_me: WARNING: sys/sysmacros.h: section \"Present But Cannot Be Comp
echo "$as_me: WARNING: sys/sysmacros.h: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: sys/sysmacros.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: sys/sysmacros.h: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for sys/sysmacros.h" >&5
@@ -20931,7 +21032,12 @@ _ACEOF
fi
-for ac_header in stdint.h
+
+
+
+
+
+for ac_header in stdint.h fcntl.h locale.h stdint.h inttypes.h unistd.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -21046,7 +21152,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -21074,9 +21185,7 @@ done
-
-
-for ac_header in fcntl.h locale.h stdint.h inttypes.h unistd.h getopt.h
+for ac_header in utime.h wchar.h wctype.h limits.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -21191,7 +21300,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -21217,9 +21331,7 @@ done
-
-
-for ac_header in utime.h wchar.h wctype.h limits.h
+for ac_header in getopt.h err.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -21334,7 +21446,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -21478,7 +21595,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -21618,7 +21740,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## ---------------------------------- ##
+## Report this to christos@astron.com ##
+## ---------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -21875,7 +22002,6 @@ _ACEOF
fi
-
{ echo "$as_me:$LINENO: checking for struct stat.st_rdev" >&5
echo $ECHO_N "checking for struct stat.st_rdev... $ECHO_C" >&6; }
if test "${ac_cv_member_struct_stat_st_rdev+set}" = set; then
@@ -21976,10 +22102,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ST_RDEV 1
-_ACEOF
-
fi
@@ -22214,7 +22336,8 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm_isdst" >&5
echo "${ECHO_T}$ac_cv_struct_tm_isdst" >&6; }
if test "$ac_cv_struct_tm_isdst" = yes; then
- cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_TM_ISDST 1
_ACEOF
@@ -22274,47 +22397,46 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_var_daylight" >&5
echo "${ECHO_T}$ac_cv_var_daylight" >&6; }
if test $ac_cv_var_daylight = yes; then
- cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DAYLIGHT 1
_ACEOF
fi
-
- # Check whether --enable-largefile was given.
+# Check whether --enable-largefile was given.
if test "${enable_largefile+set}" = set; then
enableval=$enable_largefile;
fi
- if test "$enable_largefile" != no; then
+if test "$enable_largefile" != no; then
- { echo "$as_me:$LINENO: checking for special C compiler options needed for large files=
-" >&5
-echo $ECHO_N "checking for special C compiler options needed for large files=
-... $ECHO_C" >&6; }
+ { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
if test "${ac_cv_sys_largefile_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- cat >conftest.$ac_ext <<_ACEOF
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
main ()
{
@@ -22323,7 +22445,7 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
+ rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -22340,38 +22462,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
- :
+ break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- ac_save_CC="$CC"
- CC="$CC -n32"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
+fi
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -22388,7 +22489,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
- ac_cv_sys_largefile_CC=' -n32'
+ ac_cv_sys_largefile_CC=' -n32'; break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
@@ -22396,41 +22497,40 @@ sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CC="$ac_save_CC"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
fi
{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC="$CC$ac_cv_sys_largefile_CC"
- fi
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
- { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+ { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
if test "${ac_cv_sys_file_offset_bits+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_cv_sys_file_offset_bits=no
- cat >conftest.$ac_ext <<_ACEOF
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
main ()
{
@@ -22456,12 +22556,16 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
- :
+ ac_cv_sys_file_offset_bits=no; break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- cat >conftest.$ac_ext <<_ACEOF
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -22469,16 +22573,14 @@ cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#define _FILE_OFFSET_BITS 64
#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
main ()
{
@@ -22504,7 +22606,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
- ac_cv_sys_file_offset_bits=64
+ ac_cv_sys_file_offset_bits=64; break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
@@ -22513,41 +22615,43 @@ sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
fi
{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
- if test "$ac_cv_sys_file_offset_bits" != no; then
-
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
cat >>confdefs.h <<_ACEOF
#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
_ACEOF
-
- fi
- { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+;;
+esac
+rm -f conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
if test "${ac_cv_sys_large_files+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_cv_sys_large_files=no
- cat >conftest.$ac_ext <<_ACEOF
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
main ()
{
@@ -22573,12 +22677,16 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
- :
+ ac_cv_sys_large_files=no; break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- cat >conftest.$ac_ext <<_ACEOF
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -22586,16 +22694,14 @@ cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#define _LARGE_FILES 1
#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply "#define LARGE_OFF_T 9223372036854775807",
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
main ()
{
@@ -22621,7 +22727,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
- ac_cv_sys_large_files=1
+ ac_cv_sys_large_files=1; break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
@@ -22630,20 +22736,143 @@ sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
fi
{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
- if test "$ac_cv_sys_large_files" != no; then
-
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
cat >>confdefs.h <<_ACEOF
#define _LARGE_FILES $ac_cv_sys_large_files
_ACEOF
+;;
+esac
+rm -f conftest*
+ fi
+fi
- fi
- fi
+{ echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_largefile_source+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_sys_largefile_source=no; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE 1
+#include <stdio.h>
+int
+main ()
+{
+return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_sys_largefile_source=1; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_cv_sys_largefile_source=unknown
+ break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
+esac
+rm -f conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FSEEKO 1
+_ACEOF
+
+fi
{ echo "$as_me:$LINENO: checking for mbstate_t" >&5
echo $ECHO_N "checking for mbstate_t... $ECHO_C" >&6; }
@@ -22720,33 +22949,56 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
+$ac_includes_default
+typedef uint8_t ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])uint8_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
ac_cv_type_uint8_t=yes
else
- ac_cv_type_uint8_t=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_uint8_t=no
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5
echo "${ECHO_T}$ac_cv_type_uint8_t" >&6; }
-if test $ac_cv_type_uint8_t = no; then
- cat >>confdefs.h <<\_ACEOF
-#define uint8_t unsigned char
+if test $ac_cv_type_uint8_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT8_T 1
_ACEOF
-fi
+fi
{ echo "$as_me:$LINENO: checking for uint16_t" >&5
echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6; }
if test "${ac_cv_type_uint16_t+set}" = set; then
@@ -22758,33 +23010,56 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
+$ac_includes_default
+typedef uint16_t ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])uint16_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
ac_cv_type_uint16_t=yes
else
- ac_cv_type_uint16_t=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_uint16_t=no
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
echo "${ECHO_T}$ac_cv_type_uint16_t" >&6; }
-if test $ac_cv_type_uint16_t = no; then
- cat >>confdefs.h <<\_ACEOF
-#define uint16_t unsigned short
+if test $ac_cv_type_uint16_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT16_T 1
_ACEOF
-fi
+fi
{ echo "$as_me:$LINENO: checking for uint32_t" >&5
echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6; }
if test "${ac_cv_type_uint32_t+set}" = set; then
@@ -22796,33 +23071,56 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
+$ac_includes_default
+typedef uint32_t ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])uint32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
ac_cv_type_uint32_t=yes
else
- ac_cv_type_uint32_t=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_uint32_t=no
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
echo "${ECHO_T}$ac_cv_type_uint32_t" >&6; }
-if test $ac_cv_type_uint32_t = no; then
- cat >>confdefs.h <<\_ACEOF
-#define uint32_t unsigned int
+if test $ac_cv_type_uint32_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT32_T 1
_ACEOF
-fi
+fi
{ echo "$as_me:$LINENO: checking for int32_t" >&5
echo $ECHO_N "checking for int32_t... $ECHO_C" >&6; }
if test "${ac_cv_type_int32_t+set}" = set; then
@@ -22834,112 +23132,120 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
+$ac_includes_default
+typedef int32_t ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])int32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
ac_cv_type_int32_t=yes
else
- ac_cv_type_int32_t=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_int32_t=no
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5
echo "${ECHO_T}$ac_cv_type_int32_t" >&6; }
-if test $ac_cv_type_int32_t = no; then
- cat >>confdefs.h <<\_ACEOF
-#define int32_t int
+if test $ac_cv_type_int32_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INT32_T 1
_ACEOF
-fi
-{ echo "$as_me:$LINENO: checking for long long" >&5
-echo $ECHO_N "checking for long long... $ECHO_C" >&6; }
-if test "${ac_cv_c_long_long+set}" = set; then
+fi
+{ echo "$as_me:$LINENO: checking for uint64_t" >&5
+echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_uint64_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$GCC" = yes; then
- ac_cv_c_long_long=yes
-else
-if test "$cross_compiling" = yes; then
- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-int main() {
-long long foo = 0;
-exit(sizeof(long long) < sizeof(long)); }
+$ac_includes_default
+typedef uint64_t ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
+ (eval "$ac_compile") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_long_long=yes
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_type_uint64_t=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-ac_cv_c_long_long=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ ac_cv_type_uint64_t=no
fi
-
-fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_long_long" >&5
-echo "${ECHO_T}$ac_cv_c_long_long" >&6; }
-if test $ac_cv_c_long_long = yes; then
- cat >>confdefs.h <<\_ACEOF
-#define HAVE_LONG_LONG 1
+{ echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint64_t" >&6; }
+if test $ac_cv_type_uint64_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT64_T 1
_ACEOF
-fi
-if test $ac_cv_c_long_long = yes; then
- ulong64='unsigned long long';
- long64='long long';
-else
- ulong64='unsigned long';
- long64='long';
fi
-{ echo "$as_me:$LINENO: checking for uint64_t" >&5
-echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_uint64_t+set}" = set; then
+{ echo "$as_me:$LINENO: checking for int64_t" >&5
+echo $ECHO_N "checking for int64_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_int64_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
@@ -22948,39 +23254,60 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
+$ac_includes_default
+typedef int64_t ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])uint64_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- eval "ac_cv_type_uint64_t=yes"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_type_int64_t=yes
else
- eval "ac_cv_type_uint64_t=no"
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_int64_t=no
fi
-rm -f conftest*
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-if eval "test \"`echo '$ac_cv_type_'uint64_t`\" = yes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- cat >>confdefs.h <<_ACEOF
-#define uint64_t $ulong64
+{ echo "$as_me:$LINENO: result: $ac_cv_type_int64_t" >&5
+echo "${ECHO_T}$ac_cv_type_int64_t" >&6; }
+if test $ac_cv_type_int64_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INT64_T 1
_ACEOF
+
fi
-{ echo "$as_me:$LINENO: checking for int64_t" >&5
-echo $ECHO_N "checking for int64_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_int64_t+set}" = set; then
+{ echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6; }
+if test "${ac_cv_type_long_long+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
@@ -22989,263 +23316,309 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
+$ac_includes_default
+typedef long long ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+ return 0;
+if (sizeof (ac__type_new_))
+ return 0;
+ ;
+ return 0;
+}
_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])int64_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- eval "ac_cv_type_int64_t=yes"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_type_long_long=yes
else
- eval "ac_cv_type_int64_t=no"
-fi
-rm -f conftest*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ ac_cv_type_long_long=no
fi
-if eval "test \"`echo '$ac_cv_type_'int64_t`\" = yes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- cat >>confdefs.h <<_ACEOF
-#define int64_t $long64
-_ACEOF
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6; }
-
-{ echo "$as_me:$LINENO: checking size of uint8_t" >&5
-echo $ECHO_N "checking size of uint8_t... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_uint8_t+set}" = set; then
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ echo "$as_me:$LINENO: checking size of long long" >&5
+echo $ECHO_N "checking size of long long... $ECHO_C" >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test "$cross_compiling" = yes; then
- ac_cv_sizeof_uint8_t=0
-else
- cat >conftest.$ac_ext <<_ACEOF
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-#include <stdio.h>
-main()
+$ac_includes_default
+ typedef long long ac__type_sizeof_;
+int
+main ()
{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(uint8_t));
- exit(0);
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
+ (eval "$ac_compile") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+ typedef long long ac__type_sizeof_;
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
+ (eval "$ac_compile") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sizeof_uint8_t=`cat conftestval`
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_hi=$ac_mid; break
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-ac_cv_sizeof_uint8_t=0
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_uint8_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_uint8_t" >&6; }
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_UINT8_T $ac_cv_sizeof_uint8_t
-_ACEOF
-
-
-
-{ echo "$as_me:$LINENO: checking size of uint16_t" >&5
-echo $ECHO_N "checking size of uint16_t... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_uint16_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_sizeof_uint16_t=0
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
else
- cat >conftest.$ac_ext <<_ACEOF
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-#include <stdio.h>
-main()
+$ac_includes_default
+ typedef long long ac__type_sizeof_;
+int
+main ()
{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(uint16_t));
- exit(0);
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
+ (eval "$ac_compile") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+ typedef long long ac__type_sizeof_;
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
+ (eval "$ac_compile") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sizeof_uint16_t=`cat conftestval`
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_lo=$ac_mid; break
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-ac_cv_sizeof_uint16_t=0
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ ac_lo= ac_hi=
fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_uint16_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_uint16_t" >&6; }
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_UINT16_T $ac_cv_sizeof_uint16_t
-_ACEOF
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
-{ echo "$as_me:$LINENO: checking size of uint32_t" >&5
-echo $ECHO_N "checking size of uint32_t... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_uint32_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_sizeof_uint32_t=0
-else
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-#include <stdio.h>
-main()
+$ac_includes_default
+ typedef long long ac__type_sizeof_;
+int
+main ()
{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(uint32_t));
- exit(0);
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
+ (eval "$ac_compile") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sizeof_uint32_t=`cat conftestval`
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_hi=$ac_mid
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-ac_cv_sizeof_uint32_t=0
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
+ ac_lo=`expr '(' $ac_mid ')' + 1`
fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_uint32_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_uint32_t" >&6; }
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_UINT32_T $ac_cv_sizeof_uint32_t
-_ACEOF
-
-
-{ echo "$as_me:$LINENO: checking size of int64_t" >&5
-echo $ECHO_N "checking size of int64_t... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_int64_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_sizeof_int64_t=0
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long_long=$ac_lo;;
+'') if test "$ac_cv_type_long_long" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long)
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long)
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi ;;
+esac
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -23253,21 +23626,37 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
+$ac_includes_default
+ typedef long long ac__type_sizeof_;
+static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
+static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
#include <stdio.h>
-main()
+#include <stdlib.h>
+int
+main ()
{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(int64_t));
- exit(0);
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (((long int) (sizeof (ac__type_sizeof_))) < 0)
+ {
+ long int i = longval ();
+ if (i != ((long int) (sizeof (ac__type_sizeof_))))
+ return 1;
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ((long int) (sizeof (ac__type_sizeof_))))
+ return 1;
+ fprintf (f, "%lu\n", i);
+ }
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
}
_ACEOF
rm -f conftest$ac_exeext
@@ -23290,35 +23679,90 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_sizeof_int64_t=`cat conftestval`
+ ac_cv_sizeof_long_long=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-ac_cv_sizeof_int64_t=0
+if test "$ac_cv_type_long_long" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long)
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long)
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
+rm -f conftest.val
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6; }
+
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int64_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_int64_t" >&6; }
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT64_T $ac_cv_sizeof_int64_t
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
_ACEOF
-{ echo "$as_me:$LINENO: checking size of uint64_t" >&5
-echo $ECHO_N "checking size of uint64_t... $ECHO_C" >&6; }
-if test "${ac_cv_sizeof_uint64_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+
+
+{ echo "$as_me:$LINENO: checking for gcc compiler warnings" >&5
+echo $ECHO_N "checking for gcc compiler warnings... $ECHO_C" >&6; }
+# Check whether --enable-warnings was given.
+if test "${enable_warnings+set}" = set; then
+ enableval=$enable_warnings; if test "${enableval}" = no -o $GCC = no; then
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ WARNINGS=
else
- if test "$cross_compiling" = yes; then
- ac_cv_sizeof_uint64_t=0
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+ -Wmissing-declarations -Wredundant-decls -Wnested-externs \
+ -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
+ -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter"
+fi
+else
+
+if test $GCC = no; then
+ WARNINGS=
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+else
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+ -Wmissing-declarations -Wredundant-decls -Wnested-externs \
+ -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
+ -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter"
+fi
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in mmap strerror strndup strtoul mbrtowc mkstemp utimes utime wcwidth strtof
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -23326,80 +23770,90 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#if HAVE_STDINT_H
-#include <stdint.h>
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
#endif
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
#endif
-#include <stdio.h>
-main()
+int
+main ()
{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(uint64_t));
- exit(0);
+return $ac_func ();
+ ;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
+ (eval "$ac_link") 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sizeof_uint64_t=`cat conftestval`
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ eval "$as_ac_var=yes"
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-ac_cv_sizeof_uint64_t=0
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ eval "$as_ac_var=no"
fi
-
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_uint64_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_uint64_t" >&6; }
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_UINT64_T $ac_cv_sizeof_uint64_t
+ac_res=`eval echo '${'$as_ac_var'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
+fi
+done
-
-
-
-
-
-
-
-
-
-
-
-for ac_func in mmap strerror strndup strtoul mbrtowc mkstemp getopt_long utimes utime wcwidth snprintf vsnprintf strtof
+for ac_func in getopt_long asprintf vasprintf
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -23489,11 +23943,19 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
+else
+ case " $LIBOBJS " in
+ *" $ac_func.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+ ;;
+esac
+
fi
done
+
{ echo "$as_me:$LINENO: checking for gzopen in -lz" >&5
echo $ECHO_N "checking for gzopen in -lz... $ECHO_C" >&6; }
if test "${ac_cv_lib_z_gzopen+set}" = set; then
@@ -23574,7 +24036,7 @@ else
fi
-ac_config_files="$ac_config_files Makefile src/Makefile magic/Makefile doc/Makefile python/Makefile"
+ac_config_files="$ac_config_files Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -23672,13 +24134,6 @@ LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
-if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
if test -z "${FSECT5_TRUE}" && test -z "${FSECT5_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"FSECT5\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -24014,7 +24469,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by $as_me, which was
+This file was extended by file $as_me 4.26, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -24067,7 +24522,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-config.status
+file config.status 4.26
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -24186,6 +24641,7 @@ do
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"magic/Makefile") CONFIG_FILES="$CONFIG_FILES magic/Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;;
@@ -24309,12 +24765,10 @@ am__leading_dot!$am__leading_dot$ac_delim
AMTAR!$AMTAR$ac_delim
am__tar!$am__tar$ac_delim
am__untar!$am__untar$ac_delim
-MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim
-MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim
-MAINT!$MAINT$ac_delim
fsect!$fsect$ac_delim
FSECT5_TRUE!$FSECT5_TRUE$ac_delim
FSECT5_FALSE!$FSECT5_FALSE$ac_delim
+WARNINGS!$WARNINGS$ac_delim
CC!$CC$ac_delim
CFLAGS!$CFLAGS$ac_delim
LDFLAGS!$LDFLAGS$ac_delim
@@ -24347,6 +24801,8 @@ AR!$AR$ac_delim
RANLIB!$RANLIB$ac_delim
CPP!$CPP$ac_delim
CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -24388,8 +24844,6 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
-CXXFLAGS!$CXXFLAGS$ac_delim
-ac_ct_CXX!$ac_ct_CXX$ac_delim
CXXDEPMODE!$CXXDEPMODE$ac_delim
am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim
am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim
@@ -24398,13 +24852,13 @@ F77!$F77$ac_delim
FFLAGS!$FFLAGS$ac_delim
ac_ct_F77!$ac_ct_F77$ac_delim
LIBTOOL!$LIBTOOL$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
IS_CROSS_COMPILE_TRUE!$IS_CROSS_COMPILE_TRUE$ac_delim
IS_CROSS_COMPILE_FALSE!$IS_CROSS_COMPILE_FALSE$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 14; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 12; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/contrib/file/configure.ac b/contrib/file/configure.ac
new file mode 100644
index 0000000..ae674ff
--- /dev/null
+++ b/contrib/file/configure.ac
@@ -0,0 +1,151 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(file, 4.26, christos@astron.com)
+AM_INIT_AUTOMAKE
+AM_CONFIG_HEADER(config.h)
+
+AC_MSG_CHECKING(for builtin ELF support)
+AC_ARG_ENABLE(elf,
+[ --disable-elf disable builtin ELF support],
+[if test "${enableval}" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([BUILTIN_ELF], 1, [Define if built-in ELF support is used])
+else
+ AC_MSG_RESULT(no)
+fi], [
+ # enable by default
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([BUILTIN_ELF], 1, [Define in built-in ELF support is used])
+])
+
+AC_MSG_CHECKING(for ELF core file support)
+AC_ARG_ENABLE(elf-core,
+[ --disable-elf-core disable ELF core file support],
+[if test "${enableval}" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([ELFCORE], 1, [Define for ELF core file support])
+else
+ AC_MSG_RESULT(no)
+fi], [
+ # enable by default
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([ELFCORE], 1, [Define for ELF core file support])
+])
+
+AC_MSG_CHECKING(for file formats in man section 5)
+AC_ARG_ENABLE(fsect-man5,
+[ --enable-fsect-man5 enable file formats in man section 5],
+[if test "${enableval}" = yes; then
+ AC_MSG_RESULT(yes)
+ fsect=5
+else
+ AC_MSG_RESULT(no)
+ fsect=4
+fi], [
+ # disable by default
+ AC_MSG_RESULT(no)
+ fsect=4
+])
+
+AC_SUBST(fsect)
+AM_CONDITIONAL(FSECT5, test x$fsect = x5)
+
+AC_SUBST(WARNINGS)
+AC_GNU_SOURCE
+
+dnl Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_LIBTOOL
+
+dnl Checks for headers
+AC_HEADER_STDC
+AC_HEADER_MAJOR
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(stdint.h fcntl.h locale.h stdint.h inttypes.h unistd.h)
+AC_CHECK_HEADERS(utime.h wchar.h wctype.h limits.h)
+AC_CHECK_HEADERS(getopt.h err.h)
+AC_CHECK_HEADERS(sys/mman.h sys/stat.h sys/types.h sys/utime.h sys/time.h)
+AC_CHECK_HEADERS(zlib.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_CHECK_MEMBERS([struct stat.st_rdev])
+
+AC_STRUCT_TIMEZONE_DAYLIGHT
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+AC_TYPE_MBSTATE_T
+
+AC_CHECK_TYPES([uint8_t, uint16_t, uint32_t, int32_t, uint64_t, int64_t])
+AC_CHECK_SIZEOF(long long)
+AH_BOTTOM([
+#ifndef HAVE_UINT8_T
+typedef unsigned char uint8_t;
+#endif
+#ifndef HAVE_UINT16_T
+typedef unsigned short uint16_t;
+#endif
+#ifndef HAVE_UINT32_T
+typedef unsigned int uint32_t;
+#endif
+#ifndef HAVE_INT32_T
+typedef int int32_t;
+#endif
+#ifndef HAVE_UINT64_T
+#if SIZEOF_LONG_LONG == 8
+typedef unsigned long long uint64_t;
+#else
+typedef unsigned long uint64_t;
+#endif
+#endif
+#ifndef HAVE_INT64_T
+#if SIZEOF_LONG_LONG == 8
+typedef long long int64_t;
+#else
+typedef long int64_t;
+#endif
+#endif
+])
+
+AC_MSG_CHECKING(for gcc compiler warnings)
+AC_ARG_ENABLE(warnings,
+[ --disable-warnings disable compiler warnings],
+[if test "${enableval}" = no -o $GCC = no; then
+ AC_MSG_RESULT(no)
+ WARNINGS=
+else
+ AC_MSG_RESULT(yes)
+ WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+ -Wmissing-declarations -Wredundant-decls -Wnested-externs \
+ -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
+ -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter"
+fi], [
+if test $GCC = no; then
+ WARNINGS=
+ AC_MSG_RESULT(no)
+else
+ AC_MSG_RESULT(yes)
+ WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+ -Wmissing-declarations -Wredundant-decls -Wnested-externs \
+ -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
+ -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter"
+fi])
+
+dnl Checks for functions
+AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp utimes utime wcwidth strtof)
+
+dnl Provide implementation of some required functions if necessary
+AC_REPLACE_FUNCS(getopt_long asprintf vasprintf)
+
+dnl Checks for libraries
+AC_CHECK_LIB(z,gzopen)
+
+dnl See if we are cross-compiling
+AM_CONDITIONAL(IS_CROSS_COMPILE, test "$cross_compiling" = yes)
+
+AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile])
+AC_OUTPUT
diff --git a/contrib/file/configure.in b/contrib/file/configure.in
deleted file mode 100644
index ee509e2..0000000
--- a/contrib/file/configure.in
+++ /dev/null
@@ -1,139 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT
-AC_CONFIG_SRCDIR([src/file.c])
-AM_INIT_AUTOMAKE(file, 4.23)
-AM_CONFIG_HEADER([config.h])
-AM_MAINTAINER_MODE
-
-AC_MSG_CHECKING(for builtin ELF support)
-AC_ARG_ENABLE(elf,
-[ --disable-elf disable builtin ELF support],
-[if test "${enableval}" = yes; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(BUILTIN_ELF)
-else
- AC_MSG_RESULT(no)
-fi], [
- # enable by default
- AC_MSG_RESULT(yes)
- AC_DEFINE(BUILTIN_ELF)
-])
-
-AC_MSG_CHECKING(for ELF core file support)
-AC_ARG_ENABLE(elf-core,
-[ --disable-elf-core disable ELF core file support],
-[if test "${enableval}" = yes; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(ELFCORE)
-else
- AC_MSG_RESULT(no)
-fi], [
- # enable by default
- AC_MSG_RESULT(yes)
- AC_DEFINE(ELFCORE)
-])
-
-AC_MSG_CHECKING(for file formats in man section 5)
-AC_ARG_ENABLE(fsect-man5,
-[ --enable-fsect-man5 enable file formats in man section 5],
-[if test "${enableval}" = yes; then
- AC_MSG_RESULT(yes)
- fsect=5
-else
- AC_MSG_RESULT(no)
- fsect=4
-fi], [
- # disable by default
- AC_MSG_RESULT(no)
- fsect=4
-])
-AC_SUBST(fsect)
-AM_CONDITIONAL(FSECT5, test x$fsect = x5)
-AC_GNU_SOURCE
-
-dnl Checks for programs.
-AC_PROG_CC
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_LIBTOOL
-
-dnl Templates for autoheader
-AH_TEMPLATE([BUILTIN_ELF],
- [Use the builtin ELF recognition code])
-AH_TEMPLATE([ELFCORE],
- [Recognize ELF core files])
-AH_TEMPLATE([HAVE_DAYLIGHT], [])
-AH_TEMPLATE([HAVE_LONG_LONG], [])
-AH_TEMPLATE([HAVE_TM_ISDST], [])
-AH_TEMPLATE([SIZEOF_UINT16_T], [])
-AH_TEMPLATE([SIZEOF_UINT32_T], [])
-AH_TEMPLATE([SIZEOF_INT64_T], [])
-AH_TEMPLATE([SIZEOF_UINT64_T], [])
-AH_TEMPLATE([SIZEOF_UINT8_T], [])
-AH_TEMPLATE([int32_t], [])
-AH_TEMPLATE([uint16_t], [])
-AH_TEMPLATE([uint32_t], [])
-AH_TEMPLATE([int64_t], [])
-AH_TEMPLATE([uint64_t], [])
-AH_TEMPLATE([uint8_t], [])
-
-dnl Checks for headers
-AC_HEADER_STDC
-AC_HEADER_MAJOR
-AC_HEADER_SYS_WAIT
-AC_HEADER_STDINT
-AC_CHECK_HEADERS(fcntl.h locale.h stdint.h inttypes.h unistd.h getopt.h)
-AC_CHECK_HEADERS(utime.h wchar.h wctype.h limits.h)
-AC_CHECK_HEADERS(sys/mman.h sys/stat.h sys/types.h sys/utime.h sys/time.h)
-AC_CHECK_HEADERS(zlib.h)
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_TYPE_OFF_T
-AC_TYPE_SIZE_T
-AC_DIAGNOSE([obsolete],[AC_STRUCT_ST_RDEV:
- your code should no longer depend upon `HAVE_ST_RDEV', but
- `HAVE_STRUCT_STAT_ST_RDEV'. Remove this warning and
- the `AC_DEFINE' when you adjust the code.])
-AC_CHECK_MEMBERS([struct stat.st_rdev],[AC_DEFINE(HAVE_ST_RDEV, 1,
- [Define to 1 if your `struct stat' has `st_rdev'.
- Deprecated, use `HAVE_STRUCT_STAT_ST_RDEV'
- instead.])])
-
-AC_STRUCT_TIMEZONE_DAYLIGHT
-AC_SYS_LARGEFILE
-AC_TYPE_MBSTATE_T
-
-AC_CHECK_TYPE_STDC(uint8_t, unsigned char)
-AC_CHECK_TYPE_STDC(uint16_t, unsigned short)
-AC_CHECK_TYPE_STDC(uint32_t, unsigned int)
-AC_CHECK_TYPE_STDC(int32_t, int)
-AC_C_LONG_LONG
-if test $ac_cv_c_long_long = yes; then
- ulong64='unsigned long long';
- long64='long long';
-else
- ulong64='unsigned long';
- long64='long';
-fi
-dnl This needs a patch to autoconf 2.13 acgeneral.m4
-AC_CHECK_TYPE2_STDC(uint64_t, $ulong64)
-AC_CHECK_TYPE2_STDC(int64_t, $long64)
-
-AC_CHECK_SIZEOF_STDC_HEADERS(uint8_t, 0)
-AC_CHECK_SIZEOF_STDC_HEADERS(uint16_t, 0)
-AC_CHECK_SIZEOF_STDC_HEADERS(uint32_t, 0)
-AC_CHECK_SIZEOF_STDC_HEADERS(int64_t, 0)
-AC_CHECK_SIZEOF_STDC_HEADERS(uint64_t, 0)
-
-dnl Checks for functions
-AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp getopt_long utimes utime wcwidth snprintf vsnprintf strtof)
-
-dnl Checks for libraries
-AC_CHECK_LIB(z,gzopen)
-
-dnl See if we are cross-compiling
-AM_CONDITIONAL(IS_CROSS_COMPILE, test "$cross_compiling" = yes)
-
-AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile doc/Makefile python/Makefile])
-AC_OUTPUT
diff --git a/contrib/file/elfclass.h b/contrib/file/elfclass.h
new file mode 100644
index 0000000..27817d0
--- /dev/null
+++ b/contrib/file/elfclass.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) Christos Zoulas 2008.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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.
+ */
+ if (nbytes <= sizeof(elfhdr))
+ return 0;
+
+ u.l = 1;
+ (void)memcpy(&elfhdr, buf, sizeof elfhdr);
+ swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
+
+ type = elf_getu16(swap, elfhdr.e_type);
+ switch (type) {
+#ifdef ELFCORE
+ case ET_CORE:
+ if (dophn_core(ms, clazz, swap, fd,
+ (off_t)elf_getu(swap, elfhdr.e_phoff),
+ elf_getu16(swap, elfhdr.e_phnum),
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ fsize, &flags) == -1)
+ return -1;
+ break;
+#endif
+ case ET_EXEC:
+ case ET_DYN:
+ if (dophn_exec(ms, clazz, swap, fd,
+ (off_t)elf_getu(swap, elfhdr.e_phoff),
+ elf_getu16(swap, elfhdr.e_phnum),
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
+ == -1)
+ return -1;
+ /*FALLTHROUGH*/
+ case ET_REL:
+ if (doshn(ms, clazz, swap, fd,
+ (off_t)elf_getu(swap, elfhdr.e_shoff),
+ elf_getu16(swap, elfhdr.e_shnum),
+ (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+ &flags,
+ elf_getu16(swap, elfhdr.e_machine)) == -1)
+ return -1;
+ break;
+
+ default:
+ break;
+ }
+ return 1;
diff --git a/contrib/file/file.c b/contrib/file/file.c
index 575b951..2f518da 100644
--- a/contrib/file/file.c
+++ b/contrib/file/file.c
@@ -61,9 +61,12 @@
#endif
#ifdef HAVE_GETOPT_H
-#include <getopt.h> /* for long options (is this portable?)*/
+#include <getopt.h>
#else
-#undef HAVE_GETOPT_LONG
+#include "mygetopt.h"
+#endif
+#ifndef HAVE_GETOPT_LONG
+int getopt_long(int argc, char * const *argv, const char *optstring, const struct option *longopts, int *longindex);
#endif
#include <netinet/in.h> /* for byte swapping */
@@ -71,7 +74,7 @@
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$File: file.c,v 1.117 2007/12/27 16:35:58 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.121 2008/07/03 15:48:18 christos Exp $")
#endif /* lint */
@@ -103,13 +106,7 @@ private struct magic_set *magic;
private void unwrap(char *);
private void usage(void);
-#ifdef HAVE_GETOPT_LONG
private void help(void);
-#endif
-#if 0
-private int byteconv4(int, int, int);
-private short byteconv2(int, int, int);
-#endif
int main(int, char *[]);
private void process(const char *, int);
@@ -130,7 +127,6 @@ main(int argc, char *argv[])
struct stat sb;
static const char hmagic[] = "/.magic";
#define OPTSTRING "bcCde:f:F:hikLm:nNprsvz0"
-#ifdef HAVE_GETOPT_LONG
int longindex;
static const struct option long_options[] =
{
@@ -143,7 +139,6 @@ main(int argc, char *argv[])
#undef OPT_LONGONLY
{0, 0, NULL, 0}
};
-#endif
static const struct {
const char *name;
@@ -156,13 +151,10 @@ main(int argc, char *argv[])
{ "soft", MAGIC_NO_CHECK_SOFT },
{ "tar", MAGIC_NO_CHECK_TAR },
{ "tokens", MAGIC_NO_CHECK_TOKENS },
- { "troff", MAGIC_NO_CHECK_TROFF },
};
-#ifdef LC_CTYPE
/* makes islower etc work for other langs */
(void)setlocale(LC_CTYPE, "");
-#endif
#ifdef __EMX__
/* sh-like wildcard expansion! Shouldn't hurt at least ... */
@@ -193,14 +185,9 @@ main(int argc, char *argv[])
#ifdef S_IFLNK
flags |= getenv("POSIXLY_CORRECT") ? MAGIC_SYMLINK : 0;
#endif
-#ifndef HAVE_GETOPT_LONG
- while ((c = getopt(argc, argv, OPTSTRING)) != -1)
-#else
while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
&longindex)) != -1)
-#endif
switch (c) {
-#ifdef HAVE_GETOPT_LONG
case 0 :
switch (longindex) {
case 0:
@@ -214,7 +201,6 @@ main(int argc, char *argv[])
break;
}
break;
-#endif
case '0':
nulsep = 1;
break;
@@ -349,8 +335,9 @@ main(int argc, char *argv[])
process(argv[optind], wid);
}
+ c = magic->haderr ? 1 : 0;
magic_close(magic);
- return 0;
+ return c;
}
@@ -392,7 +379,7 @@ unwrap(char *fn)
exit(1);
}
- while (fgets(buf, MAXPATHLEN, f) != NULL) {
+ while (fgets(buf, sizeof(buf), f) != NULL) {
buf[strcspn(buf, "\n")] = '\0';
cwid = file_mbswidth(buf);
if (cwid > wid)
@@ -438,64 +425,6 @@ process(const char *inname, int wid)
(void)printf("%s\n", type);
}
-
-#if 0
-/*
- * byteconv4
- * Input:
- * from 4 byte quantity to convert
- * same whether to perform byte swapping
- * big_endian whether we are a big endian host
- */
-private int
-byteconv4(int from, int same, int big_endian)
-{
- if (same)
- return from;
- else if (big_endian) { /* lsb -> msb conversion on msb */
- union {
- int i;
- char c[4];
- } retval, tmpval;
-
- tmpval.i = from;
- retval.c[0] = tmpval.c[3];
- retval.c[1] = tmpval.c[2];
- retval.c[2] = tmpval.c[1];
- retval.c[3] = tmpval.c[0];
-
- return retval.i;
- }
- else
- return ntohl(from); /* msb -> lsb conversion on lsb */
-}
-
-/*
- * byteconv2
- * Same as byteconv4, but for shorts
- */
-private short
-byteconv2(int from, int same, int big_endian)
-{
- if (same)
- return from;
- else if (big_endian) { /* lsb -> msb conversion on msb */
- union {
- short s;
- char c[2];
- } retval, tmpval;
-
- tmpval.s = (short) from;
- retval.c[0] = tmpval.c[1];
- retval.c[1] = tmpval.c[0];
-
- return retval.s;
- }
- else
- return ntohs(from); /* msb -> lsb conversion on lsb */
-}
-#endif
-
size_t
file_mbswidth(const char *s)
{
@@ -534,13 +463,10 @@ private void
usage(void)
{
(void)fprintf(stderr, USAGE, progname, progname);
-#ifdef HAVE_GETOPT_LONG
(void)fputs("Try `file --help' for more information.\n", stderr);
-#endif
exit(1);
}
-#ifdef HAVE_GETOPT_LONG
private void
help(void)
{
@@ -557,4 +483,3 @@ help(void)
#undef OPT_LONGONLY
exit(0);
}
-#endif
diff --git a/contrib/file/file.h b/contrib/file/file.h
index ce0f4e2..aab1137 100644
--- a/contrib/file/file.h
+++ b/contrib/file/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.92 2007/11/08 00:31:37 christos Exp $
+ * @(#)$File: file.h,v 1.108 2008/07/16 18:00:57 christos Exp $
*/
#ifndef __file_h__
@@ -50,6 +50,7 @@
#include <sys/types.h>
/* Do this here and now, because struct stat gets re-defined on solaris */
#include <sys/stat.h>
+#include <stdarg.h>
#define ENABLE_CONDITIONALS
@@ -79,40 +80,70 @@
#endif
#endif
+#ifndef __GNUC__
+#ifndef __attribute__
+#define __attribute__(a)
+#endif
+#endif
+
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
#ifndef HOWMANY
# define HOWMANY (256 * 1024) /* how much of the file to look at */
#endif
-#define MAXMAGIS 8192 /* max entries in /etc/magic */
-#define MAXDESC 64 /* max leng of text description */
+#define MAXMAGIS 8192 /* max entries in any one magic file
+ or directory */
+#define MAXDESC 64 /* max leng of text description/MIME type */
#define MAXstring 32 /* max leng of "string" types */
#define MAGICNO 0xF11E041C
-#define VERSIONNO 4
-#define FILE_MAGICSIZE (32 * 4)
+#define VERSIONNO 6
+#define FILE_MAGICSIZE (32 * 6)
#define FILE_LOAD 0
#define FILE_CHECK 1
#define FILE_COMPILE 2
+union VALUETYPE {
+ uint8_t b;
+ uint16_t h;
+ uint32_t l;
+ uint64_t q;
+ uint8_t hs[2]; /* 2 bytes of a fixed-endian "short" */
+ uint8_t hl[4]; /* 4 bytes of a fixed-endian "long" */
+ uint8_t hq[8]; /* 8 bytes of a fixed-endian "quad" */
+ char s[MAXstring]; /* the search string or regex pattern */
+ unsigned char us[MAXstring];
+ float f;
+ double d;
+};
+
struct magic {
/* Word 1 */
uint16_t cont_level; /* level of ">" */
- uint8_t nospflag; /* supress space character */
uint8_t flag;
-#define INDIR 1 /* if '(...)' appears */
-#define OFFADD 2 /* if '>&' or '>...(&' appears */
-#define INDIROFFADD 4 /* if '>&(' appears */
-#define UNSIGNED 8 /* comparison is unsigned */
+#define INDIR 0x01 /* if '(...)' appears */
+#define OFFADD 0x02 /* if '>&' or '>...(&' appears */
+#define INDIROFFADD 0x04 /* if '>&(' appears */
+#define UNSIGNED 0x08 /* comparison is unsigned */
+#define NOSPACE 0x10 /* suppress space character before output */
+#define BINTEST 0x20 /* test is for a binary type (set only
+ for top-level tests) */
+#define TEXTTEST 0 /* for passing to file_softmagic */
+
+ uint8_t factor;
/* Word 2 */
uint8_t reln; /* relation (0=eq, '>'=gt, etc) */
uint8_t vallen; /* length of string value, if any */
- uint8_t type; /* int, short, long or string. */
- uint8_t in_type; /* type of indirrection */
+ uint8_t type; /* comparison type (FILE_*) */
+ uint8_t in_type; /* type of indirection */
#define FILE_INVALID 0
#define FILE_BYTE 1
#define FILE_SHORT 2
@@ -175,11 +206,15 @@ struct magic {
uint8_t mask_op; /* operator for mask */
#ifdef ENABLE_CONDITIONALS
uint8_t cond; /* conditional type */
- uint8_t dummy1;
#else
- uint8_t dummy1;
- uint8_t dummy2;
+ uint8_t dummy;
#endif
+ uint8_t factor_op;
+#define FILE_FACTOR_OP_PLUS '+'
+#define FILE_FACTOR_OP_MINUS '-'
+#define FILE_FACTOR_OP_TIMES '*'
+#define FILE_FACTOR_OP_DIV '/'
+#define FILE_FACTOR_OP_NONE '\0'
#define FILE_OPS "&|^+-*/%"
#define FILE_OPAND 0
@@ -219,24 +254,14 @@ struct magic {
} _s; /* for use with string types */
} _u;
#define num_mask _u._mask
-#define str_count _u._s._count
+#define str_range _u._s._count
#define str_flags _u._s._flags
-
/* Words 9-16 */
- union VALUETYPE {
- uint8_t b;
- uint16_t h;
- uint32_t l;
- uint64_t q;
- uint8_t hs[2]; /* 2 bytes of a fixed-endian "short" */
- uint8_t hl[4]; /* 4 bytes of a fixed-endian "long" */
- uint8_t hq[8]; /* 8 bytes of a fixed-endian "quad" */
- char s[MAXstring]; /* the search string or regex pattern */
- float f;
- double d;
- } value; /* either number or string */
+ union VALUETYPE value; /* either number or string */
/* Words 17..31 */
char desc[MAXDESC]; /* description */
+ /* Words 32..47 */
+ char mimetype[MAXDESC]; /* MIME type */
};
#define BIT(A) (1 << (A))
@@ -251,6 +276,7 @@ struct magic {
#define CHAR_IGNORE_UPPERCASE 'C'
#define CHAR_REGEX_OFFSET_START 's'
#define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
+#define STRING_DEFAULT_RANGE 100
/* list of magic entries */
@@ -263,28 +289,29 @@ struct mlist {
struct mlist *next, *prev;
};
+#ifdef __cplusplus
+#define CAST(T, b) static_cast<T>(b)
+#else
+#define CAST(T, b) (b)
+#endif
+
+struct level_info {
+ int32_t off;
+ int got_match;
+#ifdef ENABLE_CONDITIONALS
+ int last_match;
+ int last_cond; /* used for error checking by parse() */
+#endif
+} *li;
struct magic_set {
struct mlist *mlist;
struct cont {
size_t len;
- struct level_info {
- int32_t off;
- int got_match;
-#ifdef ENABLE_CONDITIONALS
- int last_match;
- int last_cond; /* used for error checking by parse() */
-#endif
- } *li;
+ struct level_info *li;
} c;
struct out {
- /* Accumulation buffer */
- char *buf;
- char *ptr;
- size_t left;
- size_t size;
- /* Printable buffer */
- char *pbuf;
- size_t psize;
+ char *buf; /* Accumulation buffer */
+ char *pbuf; /* Printable buffer */
} o;
uint32_t offset;
int error;
@@ -301,16 +328,23 @@ struct magic_set {
size_t rm_len; /* match length */
} search;
+ /* FIXME: Make the string dynamically allocated so that e.g.
+ strings matched in files can be longer than MAXstring */
union VALUETYPE ms_value; /* either number or string */
};
+/* Type for Unicode characters */
+typedef unsigned long unichar;
+
struct stat;
protected const char *file_fmttime(uint32_t, int);
protected int file_buffer(struct magic_set *, int, const char *, const void *,
size_t);
protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
-protected int file_printf(struct magic_set *, const char *, ...);
+protected int file_vprintf(struct magic_set *, const char *, va_list);
+protected int file_printf(struct magic_set *, const char *, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
protected int file_reset(struct magic_set *);
protected int file_tryelf(struct magic_set *, int, const unsigned char *,
size_t);
@@ -318,7 +352,7 @@ protected int file_zmagic(struct magic_set *, int, const char *,
const unsigned char *, size_t);
protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t);
protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
-protected int file_softmagic(struct magic_set *, const unsigned char *, size_t);
+protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, int);
protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
protected uint64_t file_signextend(struct magic_set *, struct magic *,
uint64_t);
@@ -326,15 +360,19 @@ protected void file_delmagic(struct magic *, int type, size_t entries);
protected void file_badread(struct magic_set *);
protected void file_badseek(struct magic_set *);
protected void file_oomem(struct magic_set *, size_t);
-protected void file_error(struct magic_set *, int, const char *, ...);
-protected void file_magerror(struct magic_set *, const char *, ...);
-protected void file_magwarn(struct magic_set *, const char *, ...);
+protected void file_error(struct magic_set *, int, const char *, ...)
+ __attribute__((__format__(__printf__, 3, 4)));
+protected void file_magerror(struct magic_set *, const char *, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+protected void file_magwarn(struct magic_set *, const char *, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
protected void file_mdump(struct magic *);
protected void file_showstr(FILE *, const char *, size_t);
protected size_t file_mbswidth(const char *);
protected const char *file_getbuffer(struct magic_set *);
protected ssize_t sread(int, void *, size_t, int);
protected int file_check_mem(struct magic_set *, unsigned int);
+protected int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *);
#ifndef COMPILE_ONLY
extern const char *file_names[];
@@ -352,8 +390,11 @@ extern char *sys_errlist[];
#define strtoul(a, b, c) strtol(a, b, c)
#endif
-#ifndef HAVE_SNPRINTF
-int snprintf(char *, size_t, const char *, ...);
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **, const char *, va_list);
+#endif
+#ifndef HAVE_ASPRINTF
+int asprintf(char **ptr, const char *format_string, ...);
#endif
#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
@@ -364,9 +405,16 @@ int snprintf(char *, size_t, const char *, ...);
#define O_BINARY 0
#endif
+#ifndef __cplusplus
+#ifdef __GNUC__
+static const char *rcsid(const char *) __attribute__((__used__));
+#endif
#define FILE_RCSID(id) \
static const char *rcsid(const char *p) { \
return rcsid(p = id); \
}
+#else
+#define FILE_RCSID(id)
+#endif
#endif /* __file_h__ */
diff --git a/contrib/file/file.man b/contrib/file/file.man
index 05bf9e7..197700f 100644
--- a/contrib/file/file.man
+++ b/contrib/file/file.man
@@ -1,5 +1,5 @@
-.\" $File: file.man,v 1.66 2007/10/23 19:58:59 christos Exp $
-.Dd January 8, 2007
+.\" $File: file.man,v 1.73 2008/02/19 17:58:00 rrt Exp $
+.Dd February 19, 2008
.Dt FILE __CSECTION__
.Os
.Sh NAME
@@ -8,8 +8,8 @@
.Sh SYNOPSIS
.Nm
.Op Fl bchikLnNprsvz
-.Op Fl mime-type
-.Op Fl mime-encoding
+.Op Fl -mime-type
+.Op Fl -mime-encoding
.Op Fl f Ar namefile
.Op Fl F Ar separator
.Op Fl m Ar magicfiles
@@ -17,6 +17,8 @@
.Nm
.Fl C
.Op Fl m Ar magicfile
+.Nm
+.Op Fl -help
.Sh DESCRIPTION
This manual page documents version __VERSION__ of the
.Nm
@@ -25,7 +27,7 @@ command.
.Nm
tests each argument in an attempt to classify it.
There are three sets of tests, performed in this order:
-filesystem tests, magic number tests, and language tests.
+filesystem tests, magic tests, and language tests.
The
.Em first
test that succeeds causes the file type to be printed.
@@ -49,11 +51,9 @@ meaning anything else (data is usually
or non-printable).
Exceptions are well-known file formats (core files, tar archives)
that are known to contain binary data.
-When modifying the file
-.Pa __MAGIC__
-or the program itself, make sure to
+When modifying magic files or the program itself, make sure to
.Em "preserve these keywords" .
-People depend on knowing that all the readable files in a directory
+Users depend on knowing that all the readable files in a directory
have the word
.Dq text
printed.
@@ -61,12 +61,6 @@ Don't do as Berkeley did and change
.Dq shell commands text
to
.Dq shell script .
-Note that the file
-.Pa __MAGIC__
-is built mechanically from a large number of small files in
-the subdirectory
-.Pa Magdir
-in the source distribution of this program.
.Pp
The filesystem tests are based on examining the return from a
.Xr stat 2
@@ -80,7 +74,7 @@ are intuited if they are defined in
the system header file
.In sys/stat.h .
.Pp
-The magic number tests are used to check for files with data in
+The magic tests are used to check for files with data in
particular fixed formats.
The canonical example of this is a binary executable (compiled program)
.Dv a.out
@@ -97,22 +91,20 @@ near the beginning of the file that tells the
.Dv UNIX operating system
that the file is a binary executable, and which of several types thereof.
The concept of a
-.Sq "magic number"
+.Sq "magic"
has been applied by extension to data files.
Any file with some invariant identifier at a small fixed
offset into the file can usually be described in this way.
The information identifying these files is read from the compiled
magic file
.Pa __MAGIC__.mgc ,
-or
+or the files in the directory
.Pa __MAGIC__
-if the compile file does not exist. In addition
-.Nm
-will look in
-.Pa $HOME/.magic.mgc ,
+if the compiled file does not exist. In addition, if
+.Pa $HOME/.magic.mgc
or
.Pa $HOME/.magic
-for magic entries.
+exists, it will be used in preference to the system magic files.
.Pp
If a file does not match any of the entries in the magic file,
it is examined to see if it seems to be a text file.
@@ -145,9 +137,9 @@ Once
has determined the character set used in a text-type file,
it will
attempt to determine in what language the file is written.
-The language tests look for particular strings (cf
+The language tests look for particular strings (cf.
.In names.h
-that can appear anywhere in the first few blocks of a file.
+) that can appear anywhere in the first few blocks of a file.
For example, the keyword
.Em .br
indicates that the file is most likely a
@@ -163,7 +155,8 @@ The language test routines also test for some miscellany
archives).
.Pp
Any file that cannot be identified as having been written
-in any of the character sets listed above is simply said to be ``data''.
+in any of the character sets listed above is simply said to be
+.Dq data .
.Sh OPTIONS
.Bl -tag -width indent
.It Fl b , -brief
@@ -176,7 +169,7 @@ flag to debug a new magic file before installing it.
.It Fl C , -compile
Write a
.Pa magic.mgc
-output file that contains a pre-parsed version of the magic file.
+output file that contains a pre-parsed version of the magic file or directory.
.It Fl e , -exclude Ar testname
Exclude the test named in
.Ar testname
@@ -239,12 +232,18 @@ file.
(See
.Dq FILES
section, below).
-.It Fl -mime-type , -mime-encoding
+.It Fl -mime-type , -mime-encoding
Like
.Fl i ,
but print only the specified element(s).
.It Fl k , -keep-going
-Don't stop at the first match, keep going.
+Don't stop at the first match, keep going. Subsequent matches will be
+have the string
+.Dq "\[rs]012\- "
+prepended.
+(If you want a newline, see the
+.Dq "\-r"
+option.)
.It Fl L , -dereference
option causes symlinks to be followed, as the like-named option in
.Xr ls 1
@@ -253,16 +252,9 @@ This is the default if the environment variable
.Dv POSIXLY_CORRECT
is defined.
.It Fl m , -magic-file Ar list
-Specify an alternate list of files containing magic numbers.
-This can be a single file, or a colon-separated list of files.
-If a compiled magic file is found alongside, it will be used instead.
-With the
-.Fl i
-or
-.Fl "mime"
-option, the program adds
-.Dq .mime
-to each file name.
+Specify an alternate list of files and directories containing magic.
+This can be a single item, or a colon-separated list.
+If a compiled magic file is found alongside a file or directory, it will be used instead.
.It Fl n , -no-buffer
Force stdout to be flushed after checking each file.
This is only useful if checking a list of files.
@@ -316,38 +308,27 @@ the output. This does not affect the separator which is still printed.
Print a help message and exit.
.El
.Sh FILES
-.Bl -tag -width __MAGIC__.mime.mgc -compact
+.Bl -tag -width __MAGIC__.mgc -compact
.It Pa __MAGIC__.mgc
-Default compiled list of magic numbers
+Default compiled list of magic.
.It Pa __MAGIC__
-Default list of magic numbers
-.It Pa __MAGIC__.mime.mgc
-Default compiled list of magic numbers, used to output mime types when
-the
-.Fl i
-option is specified.
-.It Pa __MAGIC__.mime
-Default list of magic numbers, used to output mime types when the
-.Fl i
-option is specified.
+Directory containing default magic files.
.El
.Sh ENVIRONMENT
The environment variable
.Dv MAGIC
-can be used to set the default magic number file name.
+can be used to set the default magic file name.
If that variable is set, then
.Nm
will not attempt to open
.Pa $HOME/.magic .
.Nm
adds
-.Dq .mime
-and/or
.Dq .mgc
to the value of this variable as appropriate.
The environment variable
.Dv POSIXLY_CORRECT
-controls (on systems that support symbolic links), if
+controls (on systems that support symbolic links), whether
.Nm
will attempt to follow symlinks or not. If set, then
.Nm
@@ -361,7 +342,8 @@ options.
.Xr magic __FSECTION__ ,
.Xr strings 1 ,
.Xr od 1 ,
-.Xr hexdump 1
+.Xr hexdump 1,
+.Xr file 1posix
.Sh STANDARDS CONFORMANCE
This program is believed to exceed the System V Interface Definition
of FILE(CMD), as near as one can determine from the vague language
@@ -465,7 +447,7 @@ command in every
.Dv UNIX since at least Research Version 4
(man page dated November, 1973).
The System V version introduced one significant major change:
-the external list of magic number types.
+the external list of magic types.
This slowed the program down slightly but made it a lot more flexible.
.Pp
This program, based on the System V version,
@@ -486,17 +468,23 @@ Christos Zoulas (christos@astron.com).
Altered by Chris Lowth, chris@lowth.com, 2000:
Handle the
.Fl i
-option to output mime type strings and using an alternative
+option to output mime type strings, using an alternative
magic file and internal logic.
.Pp
Altered by Eric Fischer (enf@pobox.com), July, 2000,
to identify character codes and attempt to identify the languages
of non-ASCII files.
.Pp
-The list of contributors to the "Magdir" directory (source for the
-.Pa __MAGIC__
-file) is too long to include here.
+Altered by Reuben Thomas (rrt@sc3d.org), 2007 to 2008, to improve MIME
+support and merge MIME and non-MIME magic, support directories as well
+as files of magic, apply many bug fixes and improve the build system.
+.Pp
+The list of contributors to the
+.Dq magic
+directory (magic files)
+is too long to include here.
You know who you are; thank you.
+Many contributors are listed in the source files.
.Sh LEGAL NOTICE
Copyright (c) Ian F. Darwin, Toronto, Canada, 1986-1999.
Covered by the standard Berkeley Software Distribution copyright; see the file
@@ -510,17 +498,10 @@ were written by John Gilmore from his public-domain
.Xr tar 1
program, and are not covered by the above license.
.Sh BUGS
+.Pp
There must be a better way to automate the construction of the Magic
file from all the glop in Magdir.
What is it?
-.\" Compilation support has been done
-.\" Better yet, the magic file should be compiled into binary (say,
-.\" .Xr ndbm 3
-.\" or, better yet, fixed-length
-.\" .Dv ASCII
-.\" strings for use in heterogenous network environments) for faster startup.
-.\" Then the program would run as fast as the Version 7 program of the same
-.\" name, with the flexibility of the System V version.
.Pp
.Nm
uses several algorithms that favor speed over accuracy,
@@ -530,31 +511,6 @@ files.
.Pp
The support for text files (primarily for programming languages)
is simplistic, inefficient and requires recompilation to update.
-.\" Else support has been done
-.\" There should be an
-.\" .Dv else
-.\" clause to follow a series of continuation lines.
-.\" .Pp
-.\" Regular expression support has been done
-.\" The magic file and keywords should have regular expression support.
-Their use of
-.Dv ASCII TAB
-as a field delimiter is ugly and makes
-it hard to edit the files, but is entrenched.
-.Pp
-It might be advisable to allow upper-case letters in keywords
-for e.g.,
-.Xr troff 1
-commands vs man page macros.
-Regular expression support would make this easy.
-.Pp
-The program doesn't grok
-.Dv FORTRAN .
-It should be able to figure
-.Dv FORTRAN
-by seeing some keywords which
-appear indented at the start of line.
-Regular expression support would make this easy.
.Pp
The list of keywords in
.Dv ascmagic
@@ -563,11 +519,6 @@ This could be done by using some keyword like
.Sq *
for the offset value.
.Pp
-.\" Sorting has been done.
-.\" Another optimization would be to sort
-.\" the magic file so that we can just run down all the
-.\" tests for the first byte, first word, first long, etc, once we
-.\" have fetched it.
Complain about conflicts in the magic file entries.
Make a rule that the magic entries sort based on file offset rather
than position within the magic file?
@@ -587,10 +538,10 @@ versus
Still, if the others don't pan out, it should be possible to use the
first guess.
.Pp
-This program is slower than some vendors' file commands.
-The new support for multiple character codes makes it even slower.
-.Pp
This manual page, and particularly this section, is too long.
+.Sh RETURN CODE
+.Nm
+returns 0 on success, and non-zero on error.
.Sh AVAILABILITY
You can obtain the original author's latest version by anonymous FTP
on
diff --git a/contrib/file/fsmagic.c b/contrib/file/fsmagic.c
index e04f598..f3b2372 100644
--- a/contrib/file/fsmagic.c
+++ b/contrib/file/fsmagic.c
@@ -57,9 +57,33 @@
#undef HAVE_MAJOR
#ifndef lint
-FILE_RCSID("@(#)$File: fsmagic.c,v 1.48 2007/10/17 19:33:31 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.52 2008/07/25 23:59:01 rrt Exp $")
#endif /* lint */
+private int
+bad_link(struct magic_set *ms, int err, char *buf)
+{
+ const char *errfmt;
+ int mime = ms->flags & MAGIC_MIME;
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-symlink")
+ == -1)
+ return -1;
+ else if (!mime) {
+ if (err == ELOOP)
+ errfmt = "symbolic link in a loop";
+ else
+ errfmt = "broken symbolic link to `%s'";
+ if (ms->flags & MAGIC_ERROR) {
+ file_error(ms, err, errfmt, buf);
+ return -1;
+ }
+ if (file_printf(ms, errfmt, buf) == -1)
+ return -1;
+ }
+ return 1;
+}
+
protected int
file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
{
@@ -96,16 +120,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
return 1;
}
- if (mime) {
- if ((sb->st_mode & S_IFMT) != S_IFREG) {
- if ((mime & MAGIC_MIME_TYPE) &&
- file_printf(ms, "application/x-not-regular-file")
- == -1)
- return -1;
- return 1;
- }
- }
- else {
+ if (!mime) {
#ifdef S_ISUID
if (sb->st_mode & S_ISUID)
if (file_printf(ms, "setuid ") == -1)
@@ -125,7 +140,11 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
switch (sb->st_mode & S_IFMT) {
case S_IFDIR:
- if (file_printf(ms, "directory") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-directory")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "directory") == -1)
return -1;
return 1;
#ifdef S_IFCHR
@@ -137,21 +156,27 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
*/
if ((ms->flags & MAGIC_DEVICES) != 0)
break;
-#ifdef HAVE_ST_RDEV
-# ifdef dv_unit
- if (file_printf(ms, "character special (%d/%d/%d)",
- major(sb->st_rdev), dv_unit(sb->st_rdev),
- dv_subunit(sb->st_rdev)) == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-character-device")
+ == -1)
return -1;
+ if (!mime) {
+#ifdef HAVE_STAT_ST_RDEV
+# ifdef dv_unit
+ if (file_printf(ms, "character special (%d/%d/%d)",
+ major(sb->st_rdev), dv_unit(sb->st_rdev),
+ dv_subunit(sb->st_rdev)) == -1)
+ return -1;
# else
- if (file_printf(ms, "character special (%ld/%ld)",
- (long) major(sb->st_rdev), (long) minor(sb->st_rdev)) == -1)
- return -1;
+ if (file_printf(ms, "character special (%ld/%ld)",
+ (long) major(sb->st_rdev), (long) minor(sb->st_rdev)) == -1)
+ return -1;
# endif
#else
- if (file_printf(ms, "character special") == -1)
- return -1;
+ if (file_printf(ms, "character special") == -1)
+ return -1;
#endif
+ }
return 1;
#endif
#ifdef S_IFBLK
@@ -163,21 +188,27 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
*/
if ((ms->flags & MAGIC_DEVICES) != 0)
break;
-#ifdef HAVE_ST_RDEV
-# ifdef dv_unit
- if (file_printf(ms, "block special (%d/%d/%d)",
- major(sb->st_rdev), dv_unit(sb->st_rdev),
- dv_subunit(sb->st_rdev)) == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-block-device")
+ == -1)
return -1;
+ if (!mime) {
+#ifdef HAVE_STAT_ST_RDEV
+# ifdef dv_unit
+ if (file_printf(ms, "block special (%d/%d/%d)",
+ major(sb->st_rdev), dv_unit(sb->st_rdev),
+ dv_subunit(sb->st_rdev)) == -1)
+ return -1;
# else
- if (file_printf(ms, "block special (%ld/%ld)",
- (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1)
- return -1;
+ if (file_printf(ms, "block special (%ld/%ld)",
+ (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1)
+ return -1;
# endif
#else
- if (file_printf(ms, "block special") == -1)
- return -1;
+ if (file_printf(ms, "block special") == -1)
+ return -1;
#endif
+ }
return 1;
#endif
/* TODO add code to handle V7 MUX and Blit MUX files */
@@ -185,13 +216,21 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
case S_IFIFO:
if((ms->flags & MAGIC_DEVICES) != 0)
break;
- if (file_printf(ms, "fifo (named pipe)") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-fifo")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "fifo (named pipe)") == -1)
return -1;
return 1;
#endif
#ifdef S_IFDOOR
case S_IFDOOR:
- if (file_printf(ms, "door") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-door")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "door") == -1)
return -1;
return 1;
#endif
@@ -203,29 +242,23 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
fn);
return -1;
}
- if (file_printf(ms,
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-symlink")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms,
"unreadable symlink `%s' (%s)", fn,
strerror(errno)) == -1)
return -1;
return 1;
}
- buf[nch] = '\0'; /* readlink(2) forgets this */
+ buf[nch] = '\0'; /* readlink(2) does not do this */
/* If broken symlink, say so and quit early. */
if (*buf == '/') {
- if (stat(buf, &tstatbuf) < 0) {
- if (ms->flags & MAGIC_ERROR) {
- file_error(ms, errno,
- "broken symbolic link to `%s'", buf);
- return -1;
- }
- if (file_printf(ms, "broken symbolic link to `%s'",
- buf) == -1)
- return -1;
- return 1;
- }
- }
- else {
+ if (stat(buf, &tstatbuf) < 0)
+ return bad_link(ms, errno, buf);
+ } else {
char *tmp;
char buf2[BUFSIZ+BUFSIZ+4];
@@ -238,7 +271,11 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
"path too long: `%s'", buf);
return -1;
}
- if (file_printf(ms,
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-path-too-long")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms,
"path too long: `%s'", fn) == -1)
return -1;
return 1;
@@ -248,18 +285,8 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
(void)strcat(buf2, buf); /* plus (rel) link */
tmp = buf2;
}
- if (stat(tmp, &tstatbuf) < 0) {
- if (ms->flags & MAGIC_ERROR) {
- file_error(ms, errno,
- "broken symbolic link to `%s'",
- buf);
- return -1;
- }
- if (file_printf(ms,
- "broken symbolic link to `%s'", buf) == -1)
- return -1;
- return 1;
- }
+ if (stat(tmp, &tstatbuf) < 0)
+ return bad_link(ms, errno, buf);
}
/* Otherwise, handle it. */
@@ -270,16 +297,24 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
ms->flags |= MAGIC_SYMLINK;
return p != NULL ? 1 : -1;
} else { /* just print what it points to */
- if (file_printf(ms, "symbolic link to `%s'",
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-symlink")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "symbolic link to `%s'",
buf) == -1)
return -1;
}
- return 1;
+ return 1;
#endif
#ifdef S_IFSOCK
#ifndef __COHERENT__
case S_IFSOCK:
- if (file_printf(ms, "socket") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-socket")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "socket") == -1)
return -1;
return 1;
#endif
diff --git a/contrib/file/funcs.c b/contrib/file/funcs.c
index 5cf1181..af98605 100644
--- a/contrib/file/funcs.c
+++ b/contrib/file/funcs.c
@@ -39,67 +39,55 @@
#if defined(HAVE_LIMITS_H)
#include <limits.h>
#endif
-#ifndef SIZE_T_MAX
-#ifdef __LP64__
-#define SIZE_T_MAX (size_t)0xffffffffffffffffU
-#else
-#define SIZE_T_MAX (size_t)0xffffffffU
-#endif
-#endif
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.35 2007/12/27 16:35:59 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.44 2008/07/16 18:00:57 christos Exp $")
#endif /* lint */
-#ifndef HAVE_VSNPRINTF
-int vsnprintf(char *, size_t, const char *, va_list);
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)~0)
#endif
/*
- * Like printf, only we print to a buffer and advance it.
+ * Like printf, only we append to a buffer.
*/
protected int
-file_printf(struct magic_set *ms, const char *fmt, ...)
+file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
{
- va_list ap;
- size_t size;
- ssize_t len;
- char *buf;
-
- va_start(ap, fmt);
+ int len;
+ char *buf, *newstr;
- len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap);
- if (len == -1)
+ len = vasprintf(&buf, fmt, ap);
+ if (len < 0)
goto out;
- if (len >= (ssize_t)ms->o.left) {
- long diff; /* XXX: really ptrdiff_t */
- va_end(ap);
- size = (ms->o.size - ms->o.left) + len + 1024;
- if ((buf = realloc(ms->o.buf, size)) == NULL) {
- file_oomem(ms, size);
- return -1;
- }
- diff = ms->o.ptr - ms->o.buf;
- ms->o.ptr = buf + diff;
- ms->o.buf = buf;
- ms->o.left = size - diff;
- ms->o.size = size;
-
- va_start(ap, fmt);
- len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap);
- if (len == -1)
+ if (ms->o.buf != NULL) {
+ len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
+ free(buf);
+ if (len < 0)
goto out;
+ free(ms->o.buf);
+ buf = newstr;
}
- va_end(ap);
- ms->o.ptr += len;
- ms->o.left -= len;
+ ms->o.buf = buf;
return 0;
out:
- file_error(ms, errno, "vsnprintf failed");
+ file_error(ms, errno, "vasprintf failed");
return -1;
}
+protected int
+file_printf(struct magic_set *ms, const char *fmt, ...)
+{
+ int rv;
+ va_list ap;
+
+ va_start(ap, fmt);
+ rv = file_vprintf(ms, fmt, ap);
+ va_end(ap);
+ return rv;
+}
+
/*
* error - print best error message possible
*/
@@ -108,21 +96,17 @@ private void
file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
uint32_t lineno)
{
- size_t len;
/* Only the first error is ok */
if (ms->haderr)
return;
- len = 0;
if (lineno != 0) {
- (void)snprintf(ms->o.buf, ms->o.size, "line %u: ", lineno);
- len = strlen(ms->o.buf);
- }
- (void)vsnprintf(ms->o.buf + len, ms->o.size - len, f, va);
- if (error > 0) {
- len = strlen(ms->o.buf);
- (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
- strerror(error));
+ free(ms->o.buf);
+ ms->o.buf = NULL;
+ file_printf(ms, "line %u: ", lineno);
}
+ file_vprintf(ms, f, va);
+ if (error > 0)
+ file_printf(ms, " (%s)", strerror(error));
ms->haderr++;
ms->error = error;
}
@@ -175,6 +159,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
{
int m;
int mime = ms->flags & MAGIC_MIME;
+ const unsigned char *ubuf = CAST(const unsigned char *, buf);
if (nb == 0) {
if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
@@ -184,7 +169,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
return 1;
} else if (nb == 1) {
if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
- file_printf(ms, mime ? "application/octet-stream" :
+ file_printf(ms, mime ? "application/octet-stream" :
"very short file (no magic)") == -1)
return -1;
return 1;
@@ -205,19 +190,19 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
/* try compression stuff */
if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
- (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
+ (m = file_zmagic(ms, fd, inname, ubuf, nb)) == 0) {
/* Check if we have a tar file */
if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
- (m = file_is_tar(ms, buf, nb)) == 0) {
+ (m = file_is_tar(ms, ubuf, nb)) == 0) {
/* try tests in /etc/magic (or surrogate magic file) */
if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
- (m = file_softmagic(ms, buf, nb)) == 0) {
+ (m = file_softmagic(ms, ubuf, nb, BINTEST)) == 0) {
/* try known keywords, check whether it is ASCII */
if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
- (m = file_ascmagic(ms, buf, nb)) == 0) {
+ (m = file_ascmagic(ms, ubuf, nb)) == 0) {
/* abandon hope, all ye who remain here */
if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
- file_printf(ms, mime ? "application/octet-stream" :
+ file_printf(ms, mime ? "application/octet-stream" :
"data") == -1)
return -1;
m = 1;
@@ -236,7 +221,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
* information from the ELF headers that cannot easily
* be extracted with rules in the magic file.
*/
- (void)file_tryelf(ms, fd, buf, nb);
+ (void)file_tryelf(ms, fd, ubuf, nb);
}
#endif
return m;
@@ -250,8 +235,7 @@ file_reset(struct magic_set *ms)
file_error(ms, 0, "no magic files loaded");
return -1;
}
- ms->o.ptr = ms->o.buf;
- ms->o.left = ms->o.size;
+ ms->o.buf = NULL;
ms->haderr = 0;
ms->error = -1;
return 0;
@@ -277,21 +261,18 @@ file_getbuffer(struct magic_set *ms)
if (ms->flags & MAGIC_RAW)
return ms->o.buf;
- len = ms->o.size - ms->o.left;
/* * 4 is for octal representation, + 1 is for NUL */
- if (len > (SIZE_T_MAX - 1) / 4) {
+ len = strlen(ms->o.buf);
+ if (len > (SIZE_MAX - 1) / 4) {
file_oomem(ms, len);
return NULL;
}
psize = len * 4 + 1;
- if (ms->o.psize < psize) {
- if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) {
- file_oomem(ms, psize);
- return NULL;
- }
- ms->o.psize = psize;
- ms->o.pbuf = pbuf;
+ if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
+ file_oomem(ms, psize);
+ return NULL;
}
+ ms->o.pbuf = pbuf;
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
{
@@ -304,7 +285,7 @@ file_getbuffer(struct magic_set *ms)
np = ms->o.pbuf;
op = ms->o.buf;
- eop = op + strlen(ms->o.buf);
+ eop = op + len;
while (op < eop) {
bytesconsumed = mbrtowc(&nextchar, op,
@@ -350,8 +331,9 @@ file_check_mem(struct magic_set *ms, unsigned int level)
if (level >= ms->c.len) {
len = (ms->c.len += 20) * sizeof(*ms->c.li);
- ms->c.li = (ms->c.li == NULL) ? malloc(len) :
- realloc(ms->c.li, len);
+ ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
+ malloc(len) :
+ realloc(ms->c.li, len));
if (ms->c.li == NULL) {
file_oomem(ms, len);
return -1;
@@ -364,28 +346,3 @@ file_check_mem(struct magic_set *ms, unsigned int level)
#endif /* ENABLE_CONDITIONALS */
return 0;
}
-/*
- * Yes these wrappers suffer from buffer overflows, but if your OS does not
- * have the real functions, maybe you should consider replacing your OS?
- */
-#ifndef HAVE_VSNPRINTF
-int
-vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
-{
- return vsprintf(buf, fmt, ap);
-}
-#endif
-
-#ifndef HAVE_SNPRINTF
-/*ARGSUSED*/
-int
-snprintf(char *buf, size_t len, const char *fmt, ...)
-{
- int rv;
- va_list ap;
- va_start(ap, fmt);
- rv = vsprintf(buf, fmt, ap);
- va_end(ap);
- return rv;
-}
-#endif
diff --git a/contrib/file/getopt_long.c b/contrib/file/getopt_long.c
new file mode 100644
index 0000000..5b9c20b
--- /dev/null
+++ b/contrib/file/getopt_long.c
@@ -0,0 +1,496 @@
+/* $NetBSD: getopt_long.c,v 1.21.4.1 2008/01/09 01:34:14 matt Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <assert.h>
+#ifdef HAVE_ERR_H
+#include <err.h>
+#else
+#include <stdio.h>
+#define warnx printf
+#endif
+#include <errno.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#include "mygetopt.h"
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#define REPLACE_GETOPT
+
+#ifndef _DIAGASSERT
+#define _DIAGASSERT assert
+#endif
+
+#ifdef REPLACE_GETOPT
+#ifdef __weak_alias
+__weak_alias(getopt,_getopt)
+#endif
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+int optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+#elif HAVE_NBTOOL_CONFIG_H && !HAVE_DECL_OPTRESET
+static int optreset;
+#endif
+
+#ifdef __weak_alias
+__weak_alias(getopt_long,_getopt_long)
+#endif
+
+#define IGNORE_FIRST (*options == '-' || *options == '+')
+#define PRINT_ERROR ((opterr) && ((*options != ':') \
+ || (IGNORE_FIRST && options[1] != ':')))
+#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
+#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
+/* XXX: GNU ignores PC if *options == '-' */
+#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-')
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((IGNORE_FIRST && options[1] == ':') \
+ || (*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define EMSG ""
+
+static int getopt_internal(int, char **, const char *);
+static int gcd(int, int);
+static void permute_args(int, int, int, char **);
+
+static const char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(a, b)
+ int a;
+ int b;
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return b;
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(panonopt_start, panonopt_end, opt_end, nargv)
+ int panonopt_start;
+ int panonopt_end;
+ int opt_end;
+ char **nargv;
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ _DIAGASSERT(nargv != NULL);
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end+i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ nargv[pos] = nargv[cstart];
+ nargv[cstart] = swap;
+ }
+ }
+}
+
+/*
+ * getopt_internal --
+ * Parse argc/argv argument vector. Called by user level routines.
+ * Returns -2 if -- is found (can be long option or end of options marker).
+ */
+static int
+getopt_internal(nargc, nargv, options)
+ int nargc;
+ char **nargv;
+ const char *options;
+{
+ char *oli; /* option letter list index */
+ int optchar;
+
+ _DIAGASSERT(nargv != NULL);
+ _DIAGASSERT(options != NULL);
+
+ optarg = NULL;
+
+ /*
+ * XXX Some programs (like rsyncd) expect to be able to
+ * XXX re-initialize optind to 0 and have getopt_long(3)
+ * XXX properly function again. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = 1;
+
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return -1;
+ }
+ if ((*(place = nargv[optind]) != '-')
+ || (place[1] == '\0')) { /* found non-option */
+ place = EMSG;
+ if (IN_ORDER) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return INORDER;
+ }
+ if (!PERMUTE) {
+ /*
+ * if no permutation wanted, stop parsing
+ * at first non-option
+ */
+ return -1;
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+ if (place[1] && *++place == '-') { /* found "--" */
+ place++;
+ return -2;
+ }
+ }
+ if ((optchar = (int)*place++) == (int)':' ||
+ (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
+ /* option letter unknown or ':' */
+ if (!*place)
+ ++optind;
+ if (PRINT_ERROR)
+ warnx(illoptchar, optchar);
+ optopt = optchar;
+ return BADCH;
+ }
+ if (optchar == 'W' && oli[1] == ';') { /* -W long-option */
+ /* XXX: what if no long options provided (called by getopt)? */
+ if (*place)
+ return -2;
+
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return BADARG;
+ } else /* white space */
+ place = nargv[optind];
+ /*
+ * Handle -W arg the same as --arg (which causes getopt to
+ * stop parsing).
+ */
+ return -2;
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ } else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = (char *)place;
+ /* XXX: disable test for :: if PC? (GNU doesn't) */
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return BADARG;
+ } else
+ optarg = nargv[optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return optchar;
+}
+
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the real getopt]
+ */
+int
+getopt(nargc, nargv, options)
+ int nargc;
+ char * const *nargv;
+ const char *options;
+{
+ int retval;
+
+ _DIAGASSERT(nargv != NULL);
+ _DIAGASSERT(options != NULL);
+
+ retval = getopt_internal(nargc, (char **)nargv, options);
+ if (retval == -2) {
+ ++optind;
+ /*
+ * We found an option (--), so if we skipped non-options,
+ * we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end, optind,
+ (char **)nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ retval = -1;
+ }
+ return retval;
+}
+#endif
+
+/*
+ * getopt_long --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long(nargc, nargv, options, long_options, idx)
+ int nargc;
+ char * const *nargv;
+ const char *options;
+ const struct option *long_options;
+ int *idx;
+{
+ int retval;
+
+#define IDENTICAL_INTERPRETATION(_x, _y) \
+ (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
+ long_options[(_x)].flag == long_options[(_y)].flag && \
+ long_options[(_x)].val == long_options[(_y)].val)
+
+ _DIAGASSERT(nargv != NULL);
+ _DIAGASSERT(options != NULL);
+ _DIAGASSERT(long_options != NULL);
+ /* idx may be NULL */
+
+ retval = getopt_internal(nargc, (char **)nargv, options);
+ if (retval == -2) {
+ char *current_argv, *has_equal;
+ size_t current_argv_len;
+ int i, ambiguous, match;
+
+ current_argv = (char *)place;
+ match = -1;
+ ambiguous = 0;
+
+ optind++;
+ place = EMSG;
+
+ if (*current_argv == '\0') { /* found "--" */
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, (char **)nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return -1;
+ }
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ } else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) ==
+ (unsigned)current_argv_len) {
+ /* exact match */
+ match = i;
+ ambiguous = 0;
+ break;
+ }
+ if (match == -1) /* partial match */
+ match = i;
+ else if (!IDENTICAL_INTERPRETATION(i, match))
+ ambiguous = 1;
+ }
+ if (ambiguous) {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ warnx(ambig, (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return BADCH;
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+ if (PRINT_ERROR)
+ warnx(noarg, (int)current_argv_len,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of
+ * flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ return BADARG;
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use
+ * next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':'
+ * indicates no error should be generated
+ */
+ if (PRINT_ERROR)
+ warnx(recargstring, current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless
+ * of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return BADARG;
+ }
+ } else { /* unknown option */
+ if (PRINT_ERROR)
+ warnx(illoptstring, current_argv);
+ optopt = 0;
+ return BADCH;
+ }
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ retval = 0;
+ } else
+ retval = long_options[match].val;
+ if (idx)
+ *idx = match;
+ }
+ return retval;
+#undef IDENTICAL_INTERPRETATION
+}
diff --git a/contrib/file/is_tar.c b/contrib/file/is_tar.c
index 142b487..a931111 100644
--- a/contrib/file/is_tar.c
+++ b/contrib/file/is_tar.c
@@ -45,7 +45,7 @@
#include "tar.h"
#ifndef lint
-FILE_RCSID("@(#)$File: is_tar.c,v 1.29 2007/10/17 19:33:31 christos Exp $")
+FILE_RCSID("@(#)$File: is_tar.c,v 1.31 2008/02/04 20:51:17 christos Exp $")
#endif
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
@@ -53,7 +53,7 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.29 2007/10/17 19:33:31 christos Exp $")
private int is_tar(const unsigned char *, size_t);
private int from_oct(int, const char *); /* Decode octal number */
-static const char *tartype[] = {
+static const char tartype[][32] = {
"tar archive",
"POSIX tar archive",
"POSIX tar archive (GNU)",
@@ -85,7 +85,8 @@ file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
* Return
* 0 if the checksum is bad (i.e., probably not a tar archive),
* 1 for old UNIX tar file,
- * 2 for Unix Std (POSIX) tar file.
+ * 2 for Unix Std (POSIX) tar file,
+ * 3 for GNU tar file.
*/
private int
is_tar(const unsigned char *buf, size_t nbytes)
diff --git a/contrib/file/libmagic.man b/contrib/file/libmagic.man
index 61e8f27..d7082c9 100644
--- a/contrib/file/libmagic.man
+++ b/contrib/file/libmagic.man
@@ -1,3 +1,4 @@
+.\" $File: libmagic.man,v 1.18 2008/02/28 22:24:46 rrt Exp $
.\"
.\" Copyright (c) Christos Zoulas 2003.
.\" All Rights Reserved.
@@ -164,7 +165,7 @@ bytes size.
.Pp
The
.Fn magic_setflags
-function, sets the
+function sets the
.Ar flags
described above. Note that using both MIME flags together can also
return extra information on the charset.
@@ -185,7 +186,9 @@ separated list of database files passed in as
or NULL for the default database. It returns 0 on success and -1 on
failure. The compiled files created are named from the
.Xr basename 1
-of each file argument with ".mgc" appended to it.
+of each file argument with
+.Dq .mgc
+appended to it.
.Pp
The
.Fn magic_load
@@ -199,7 +202,11 @@ The default database file is named by the MAGIC environment variable. If
that variable is not set, the default database file name is __MAGIC__.
.Pp
.Fn magic_load
-adds ".mime" and/or ".mgc" to the database filename as appropriate.
+adds
+.Dq .mime
+and/or
+.Dq .mgc
+to the database filename as appropriate.
.Sh RETURN VALUES
The function
.Fn magic_open
diff --git a/contrib/file/magic.c b/contrib/file/magic.c
index 8fba30b..55dfee1 100644
--- a/contrib/file/magic.c
+++ b/contrib/file/magic.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2003.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must 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
@@ -38,7 +38,9 @@
#ifdef QUICK
#include <sys/mman.h>
#endif
+#ifdef HAVE_LIMITS_H
#include <limits.h> /* for PIPE_BUF */
+#endif
#if defined(HAVE_UTIMES)
# include <sys/time.h>
@@ -63,9 +65,18 @@
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$File: magic.c,v 1.45 2007/12/27 16:35:59 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.54 2008/07/25 23:30:32 rrt Exp $")
#endif /* lint */
+#ifndef PIPE_BUF
+/* Get the PIPE_BUF from pathconf */
+#ifdef _PC_PIPE_BUF
+#define PIPE_BUF pathconf(".", _PC_PIPE_BUF)
+#else
+#define PIPE_BUF 512
+#endif
+#endif
+
#ifdef __EMX__
private char *apptypeName = NULL;
protected int file_os2_apptype(struct magic_set *ms, const char *fn,
@@ -75,7 +86,7 @@ protected int file_os2_apptype(struct magic_set *ms, const char *fn,
private void free_mlist(struct mlist *);
private void close_and_restore(const struct magic_set *, const char *, int,
const struct stat *);
-private int info_from_stat(struct magic_set *, mode_t);
+private int unreadable_info(struct magic_set *, mode_t, const char *);
#ifndef COMPILE_ONLY
private const char *file_or_fd(struct magic_set *, const char *, int);
#endif
@@ -88,38 +99,30 @@ public struct magic_set *
magic_open(int flags)
{
struct magic_set *ms;
+ size_t len;
- if ((ms = calloc((size_t)1, sizeof(struct magic_set))) == NULL)
+ if ((ms = CAST(magic_set *, calloc((size_t)1,
+ sizeof(struct magic_set)))) == NULL)
return NULL;
if (magic_setflags(ms, flags) == -1) {
errno = EINVAL;
- goto free1;
+ goto free;
}
- ms->o.ptr = ms->o.buf = malloc(ms->o.left = ms->o.size = 1024);
- if (ms->o.buf == NULL)
- goto free1;
+ ms->o.buf = ms->o.pbuf = NULL;
+ len = (ms->c.len = 10) * sizeof(*ms->c.li);
- ms->o.pbuf = malloc(ms->o.psize = 1024);
- if (ms->o.pbuf == NULL)
- goto free2;
+ if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
+ goto free;
- ms->c.li = malloc((ms->c.len = 10) * sizeof(*ms->c.li));
- if (ms->c.li == NULL)
- goto free3;
-
ms->haderr = 0;
ms->error = -1;
ms->mlist = NULL;
ms->file = "unknown";
ms->line = 0;
return ms;
-free3:
- free(ms->o.pbuf);
-free2:
- free(ms->o.buf);
-free1:
+free:
free(ms);
return NULL;
}
@@ -143,13 +146,13 @@ free_mlist(struct mlist *mlist)
}
private int
-info_from_stat(struct magic_set *ms, mode_t md)
+unreadable_info(struct magic_set *ms, mode_t md, const char *file)
{
/* We cannot open it, but we were able to stat it. */
- if (md & 0222)
+ if (access(file, W_OK) == 0)
if (file_printf(ms, "writable, ") == -1)
return -1;
- if (md & 0111)
+ if (access(file, X_OK) == 0)
if (file_printf(ms, "executable, ") == -1)
return -1;
if (S_ISREG(md))
@@ -218,7 +221,7 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd,
*/
#ifdef HAVE_UTIMES
struct timeval utsbuf[2];
- memset(utsbuf, 0, sizeof(struct timeval) * 2);
+ (void)memset(utsbuf, 0, sizeof(utsbuf));
utsbuf[0].tv_sec = sb->st_atime;
utsbuf[1].tv_sec = sb->st_mtime;
@@ -226,7 +229,7 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd,
#elif defined(HAVE_UTIME_H) || defined(HAVE_SYS_UTIME_H)
struct utimbuf utbuf;
- memset(&utbuf, 0, sizeof(struct utimbuf));
+ (void)memset(utbuf, 0, sizeof(utbuf));
utbuf.actime = sb->st_atime;
utbuf.modtime = sb->st_mtime;
(void) utime(name, &utbuf); /* don't care if loses */
@@ -268,7 +271,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
* some overlapping space for matches near EOF
*/
#define SLOP (1 + sizeof(union VALUETYPE))
- if ((buf = malloc(HOWMANY + SLOP)) == NULL)
+ if ((buf = CAST(unsigned char *, malloc(HOWMANY + SLOP))) == NULL)
return NULL;
if (file_reset(ms) == -1)
@@ -298,11 +301,18 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
errno = 0;
if ((fd = open(inname, flags)) < 0) {
#ifdef __CYGWIN__
+ /* FIXME: Do this with EXEEXT from autotools */
char *tmp = alloca(strlen(inname) + 5);
(void)strcat(strcpy(tmp, inname), ".exe");
if ((fd = open(tmp, flags)) < 0) {
#endif
- if (info_from_stat(ms, sb.st_mode) == -1)
+ if (unreadable_info(ms, sb.st_mode,
+#ifdef __CYGWIN
+ tmp
+#else
+ inname
+#endif
+ ) == -1)
goto done;
rv = 0;
goto done;
@@ -332,7 +342,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
if (nbytes == 0) {
/* We can not read it, but we were able to stat it. */
- if (info_from_stat(ms, sb.st_mode) == -1)
+ if (unreadable_info(ms, sb.st_mode, inname) == -1)
goto done;
rv = 0;
goto done;
@@ -363,7 +373,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
return NULL;
/*
* The main work is done here!
- * We have the file name and/or the data buffer to be identified.
+ * We have the file name and/or the data buffer to be identified.
*/
if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
return NULL;
diff --git a/contrib/file/magic.h b/contrib/file/magic.h
index 6041f54..ecdd53c 100644
--- a/contrib/file/magic.h
+++ b/contrib/file/magic.h
@@ -48,11 +48,12 @@
#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
#define MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */
#define MAGIC_NO_CHECK_ASCII 0x020000 /* Don't check for ascii files */
-#define MAGIC_NO_CHECK_TROFF 0x040000 /* Don't check ascii/troff */
#define MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check ascii/tokens */
-/* Defined for backwards compatibility; does nothing */
+/* Defined for backwards compatibility; do nothing */
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
+#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
+
#ifdef __cplusplus
extern "C" {
diff --git a/contrib/file/magic.man b/contrib/file/magic.man
index 3842b64..314a014 100644
--- a/contrib/file/magic.man
+++ b/contrib/file/magic.man
@@ -1,11 +1,11 @@
-.\" $File: magic.man,v 1.39 2007/11/08 00:31:37 christos Exp $
-.Dd January 10, 2007
+.\" $File: magic.man,v 1.57 2008/08/30 09:50:20 christos Exp $
+.Dd August 30, 2008
.Dt MAGIC __FSECTION__
.Os
-.\" install as magic.4 on USG, magic.5 on V7 or Berkeley systems.
+.\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems.
.Sh NAME
.Nm magic
-.Nd file command's magic number file
+.Nd file command's magic pattern file
.Sh DESCRIPTION
This manual page documents the format of the magic file as
used by the
@@ -15,18 +15,17 @@ The
.Xr file __CSECTION__
command identifies the type of a file using,
among other tests,
-a test for whether the file begins with a certain
-.Dq "magic number" .
+a test for whether the file contains certain
+.Dq "magic patterns" .
The file
.Pa __MAGIC__
-specifies what magic numbers are to be tested for,
-what message to print if a particular magic number is found,
+specifies what patterns are to be tested for, what message or
+MIME type to print if a particular pattern is found,
and additional information to extract from the file.
.Pp
Each line of the file specifies a test to be performed.
A test compares the data starting at a particular offset
-in the file with a 1-byte, 2-byte, or 4-byte numeric value or
-a string.
+in the file with a byte value, a string or a numeric value.
If the test succeeds, a message is printed.
The line consists of the following fields:
.Bl -tag -width ".Dv message"
@@ -40,15 +39,15 @@ The possible values are:
.It Dv byte
A one-byte value.
.It Dv short
-A two-byte value (on most systems) in this machine's native byte order.
+A two-byte value in this machine's native byte order.
.It Dv long
-A four-byte value (on most systems) in this machine's native byte order.
+A four-byte value in this machine's native byte order.
.It Dv quad
-An eight-byte value (on most systems) in this machine's native byte order.
+An eight-byte value in this machine's native byte order.
.It Dv float
-A 32-bit (on most systems) single precision IEEE floating point number in this machine's native byte order.
+A 32-bit single precision IEEE floating point number in this machine's native byte order.
.It Dv double
-A 64-bit (on most systems) double precision IEEE floating point number in this machine's native byte order.
+A 64-bit double precision IEEE floating point number in this machine's native byte order.
.It Dv string
A string of bytes.
The string type specification can be optionally followed
@@ -69,10 +68,10 @@ Finally the
.Dq c
flag, specifies case insensitive matching: lowercase
characters in the magic match both lower and upper case characters in the
-targer, whereas upper case characters in the magic, only much uppercase
+target, whereas upper case characters in the magic only match uppercase
characters in the target.
.It Dv pstring
-A pascal style string where the first byte is interpreted as the an
+A Pascal-style string where the first byte is interpreted as the an
unsigned length.
The string is not NUL terminated.
.It Dv date
@@ -86,106 +85,119 @@ local time rather than UTC.
An eight-byte value interpreted as a UNIX-style date, but interpreted as
local time rather than UTC.
.It Dv beshort
-A two-byte value (on most systems) in big-endian byte order.
+A two-byte value in big-endian byte order.
.It Dv belong
-A four-byte value (on most systems) in big-endian byte order.
+A four-byte value in big-endian byte order.
.It Dv bequad
-An eight-byte value (on most systems) in big-endian byte order.
+An eight-byte value in big-endian byte order.
.It Dv befloat
-A 32-bit (on most systems) single precision IEEE floating point number in big-endian byte order.
+A 32-bit single precision IEEE floating point number in big-endian byte order.
.It Dv bedouble
-A 64-bit (on most systems) double precision IEEE floating point number in big-endian byte order.
+A 64-bit double precision IEEE floating point number in big-endian byte order.
.It Dv bedate
-A four-byte value (on most systems) in big-endian byte order,
+A four-byte value in big-endian byte order,
interpreted as a Unix date.
.It Dv beqdate
-An eight-byte value (on most systems) in big-endian byte order,
+An eight-byte value in big-endian byte order,
interpreted as a Unix date.
.It Dv beldate
-A four-byte value (on most systems) in big-endian byte order,
+A four-byte value in big-endian byte order,
interpreted as a UNIX-style date, but interpreted as local time rather
than UTC.
.It Dv beqldate
-An eight-byte value (on most systems) in big-endian byte order,
+An eight-byte value in big-endian byte order,
interpreted as a UNIX-style date, but interpreted as local time rather
than UTC.
.It Dv bestring16
A two-byte unicode (UCS16) string in big-endian byte order.
.It Dv leshort
-A two-byte value (on most systems) in little-endian byte order.
+A two-byte value in little-endian byte order.
.It Dv lelong
-A four-byte value (on most systems) in little-endian byte order.
+A four-byte value in little-endian byte order.
.It Dv lequad
-An eight-byte value (on most systems) in little-endian byte order.
+An eight-byte value in little-endian byte order.
.It Dv lefloat
-A 32-bit (on most systems) single precision IEEE floating point number in little-endian byte order.
+A 32-bit single precision IEEE floating point number in little-endian byte order.
.It Dv ledouble
-A 64-bit (on most systems) double precision IEEE floating point number in little-endian byte order.
+A 64-bit double precision IEEE floating point number in little-endian byte order.
.It Dv ledate
-A four-byte value (on most systems) in little-endian byte order,
+A four-byte value in little-endian byte order,
interpreted as a UNIX date.
.It Dv leqdate
-An eight-byte value (on most systems) in little-endian byte order,
+An eight-byte value in little-endian byte order,
interpreted as a UNIX date.
.It Dv leldate
-A four-byte value (on most systems) in little-endian byte order,
+A four-byte value in little-endian byte order,
interpreted as a UNIX-style date, but interpreted as local time rather
than UTC.
.It Dv leqldate
-An eight-byte value (on most systems) in little-endian byte order,
+An eight-byte value in little-endian byte order,
interpreted as a UNIX-style date, but interpreted as local time rather
than UTC.
.It Dv lestring16
A two-byte unicode (UCS16) string in little-endian byte order.
.It Dv melong
-A four-byte value (on most systems) in middle-endian (PDP-11) byte order.
+A four-byte value in middle-endian (PDP-11) byte order.
.It Dv medate
-A four-byte value (on most systems) in middle-endian (PDP-11) byte order,
+A four-byte value in middle-endian (PDP-11) byte order,
interpreted as a UNIX date.
.It Dv meldate
-A four-byte value (on most systems) in middle-endian (PDP-11) byte order,
+A four-byte value in middle-endian (PDP-11) byte order,
interpreted as a UNIX-style date, but interpreted as local time rather
than UTC.
.It Dv regex
A regular expression match in extended POSIX regular expression syntax
-(much like egrep).
-The type specification can be optionally followed by /[cse]*.
+(like egrep). Regular expressions can take exponential time to
+process, and their performance is hard to predict, so their use is
+discouraged. When used in production environments, their performance
+should be carefully checked. The type specification can be optionally
+followed by
+.Dv /[c][s] .
The
.Dq c
flag makes the match case insensitive, while the
.Dq s
-or
-.Dq e
-flags update the offset to the starting or ending offsets of the
-match (only one should be used).
-By default, regex does not update the offset.
-The regular expression is always tested against the first
-.Dv N
-lines, where
+flag update the offset to the start offset of the match, rather than the end.
+The regular expression is tested against line
+.Dv N + 1
+onwards, where
.Dv N
-is the given offset, thus it
-is only useful for (single-byte encoded) text.
+is the given offset.
+Line endings are assumed to be in the machine's native format.
.Dv ^
and
.Dv $
-will match the beginning and end of individual lines, respectively,
+match the beginning and end of individual lines, respectively,
not beginning and end of file.
.It Dv search
-A literal string search starting at the given offset.
-It must be followed by
-.Dv \*[Lt]number\*[Gt]
-which specifies how many matches shall be attempted (the range).
-This is suitable for searching larger binary expressions with variable
-offsets, using
+A literal string search starting at the given offset. The same
+modifier flags can be used as for string patterns. The modifier flags
+(if any) must be followed by
+.Dv /number
+the range, that is, the number of positions at which the match will be
+attempted, starting from the start offset. This is suitable for
+searching larger binary expressions with variable offsets, using
.Dv \e
-escapes for special characters.
+escapes for special characters. The offset works as for regex.
.It Dv default
-This is intended to be used with the text
-.Dv x
+This is intended to be used with the test
+.Em x
(which is always true) and a message that is to be used if there are
no other matches.
.El
-.El
+.Pp
+Each top-level magic pattern (see below for an explanation of levels)
+is classified as text or binary according to the types used. Types
+.Dq regex
+and
+.Dq search
+are classified as text tests, unless non-printable characters are used
+in the pattern. All other tests are classified as binary. A top-level
+pattern is considered to be a test text when all its patterns are text
+patterns; otherwise, it is considered to be a binary pattern. When
+matching a file, binary patterns are tried first; if no match is
+found, and the file looks like text, then its encoding is determined
+and the text patterns are tried.
.Pp
The numeric types may optionally be followed by
.Dv \*[Am]
@@ -195,7 +207,6 @@ numeric value before any comparisons are done.
Prepending a
.Dv u
to the type indicates that ordered comparisons should be unsigned.
-.Bl -tag -width ".Dv message"
.It Dv test
The value to be compared with the value from the file.
If the type is
@@ -232,12 +243,8 @@ Operators
and
.Dv ~
don't work with floats and doubles.
-For all tests except
-.Em string
-and
-.Em regex ,
-operation
-.Dv !
+The operator
+.Dv !\&
specifies that the line matches if the test does
.Em not
succeed.
@@ -250,8 +257,8 @@ is octal, and
.Dv 0x13
is hexadecimal.
.Pp
-For string values, the byte string from the
-file must match the specified byte string.
+For string values, the string from the
+file must match the specified string.
The operators
.Dv = ,
.Dv \*[Lt]
@@ -262,10 +269,10 @@ and
can be applied to strings.
The length used for matching is that of the string argument
in the magic file.
-This means that a line can match any string, and
-then presumably print that string, by doing
+This means that a line can match any non-empty string (usually used to
+then print the string), with
.Em \*[Gt]\e0
-(because all strings are greater than the null string).
+(because all non-empty strings are greater than the empty string).
.Pp
The special test
.Em x
@@ -276,11 +283,44 @@ If the string contains a
.Xr printf 3
format specification, the value from the file (with any specified masking
performed) is printed using the message as the format string.
-If the string begins with ``\\b'', the message printed is the
-remainder of the string with no whitespace added before it: multiple
-matches are normally separated by a single space.
+If the string begins with
+.Dq \eb ,
+the message printed is the remainder of the string with no whitespace
+added before it: multiple matches are normally separated by a single
+space.
.El
.Pp
+A MIME type is given on a separate line, which must be the next
+non-blank or comment line after the magic line that identifies the
+file type, and has the following format:
+.Bd -literal -offset indent
+!:mime MIMETYPE
+.Ed
+.Pp
+i.e. the literal string
+.Dq !:mime
+followed by the MIME type.
+.Pp
+An optional strength can be supplied on a separate line which refers to
+the current magic description using the following format:
+.Bd -literal -offset indent
+!:strength OP VALUE
+.Ed
+.Pp
+The operand
+.Dv OP
+can be:
+.Dv + ,
+.Dv - ,
+.Dv * ,
+or
+.Dv /
+and
+.Dv VALUE
+is a constant between 0 and 255.
+This constant is applied using the specified operand
+to the currently computed default magic strength.
+.Pp
Some file formats contain additional information which is to be printed
along with the file type or need additional tests to determine the true
file type.
@@ -350,13 +390,13 @@ That way variable length structures can be examined:
\*[Gt]\*[Gt](0x3c.l) string LX\e0\e0 LX executable (OS/2)
.Ed
.Pp
-This strategy of examining has one drawback: You must make sure that
+This strategy of examining has a drawback: You must make sure that
you eventually print something, or users may get empty output (like, when
there is neither PE\e0\e0 nor LE\e0\e0 in the above example)
.Pp
-If this indirect offset cannot be used as-is, there are simple calculations
+If this indirect offset cannot be used directly, simple calculations are
possible: appending
-.Em [+-*/%\*[Am]|^]\*[Lt]number\*[Gt]
+.Em [+-*/%\*[Am]|^]number
inside parentheses allows one to modify
the value read from the file before it is used as an offset:
.Bd -literal -offset indent
@@ -468,4 +508,3 @@ a system on which the lengths are invariant.
.\" the changes I posted to the S5R2 version.
.\"
.\" Modified for Ian Darwin's version of the file command.
-.\" @(#)$Id: magic.man,v 1.39 2007/11/08 00:31:37 christos Exp $
diff --git a/contrib/file/magic.mime b/contrib/file/magic.mime
deleted file mode 100644
index dfa62de..0000000
--- a/contrib/file/magic.mime
+++ /dev/null
@@ -1,991 +0,0 @@
-# Magic data for KMimeMagic (originally for file(1) command)
-#
-# Note on adding additional MIME types:
-#
-# [RFC2045,RFC2046] specifies that Content Types, Content Subtypes, Character
-# Sets, Access Types, and conversion values for MIME mail will be assigned and
-# listed by the IANA.
-# http://www.iana.org/assignments/media-types/
-#
-# Any unregistered file type should be listed with a preceding x-, as in
-# application/x-foo (RFC2045 5.1), or a x., as in application/x.foo (RFC4288
-# 4.3). Any non x-prefixed type should be registered with IANA and listed at
-# the above address. Any other behavior is a MIME standards violation!
-#
-# It is preferred that when a registered MIME type exists, that
-# the registered Content-Type and Subtype be used to refer to a file of
-# that type, so don't use application/x-zip when application/zip is
-# registered.
-#
-# If an active RFC suggests that a MIME registration for a new type is in
-# progress, make a note of it pointing to that RFC.
-#
-# The format is 4-5 columns:
-# Column #1: byte number to begin checking from, ">" indicates continuation
-# Column #2: type of data to match
-# Column #3: contents of data to match
-# Column #4: MIME type of result
-# Column #5: MIME encoding of result (optional)
-
-#------------------------------------------------------------------------------
-# Localstuff: file(1) magic for locally observed files
-# Add any locally observed files here.
-
-# Real Audio (Magic .ra\0375)
-0 belong 0x2e7261fd audio/x-pn-realaudio
-0 string .RMF application/vnd.rn-realmedia
-
-#video/x-pn-realvideo
-#video/vnd.rn-realvideo
-#application/vnd.rn-realmedia
-# sigh, there are many mimes for that but the above are the most common.
-
-# Taken from magic, converted to magic.mime
-# mime types according to http://www.geocities.com/nevilo/mod.htm:
-# audio/it .it
-# audio/x-zipped-it .itz
-# audio/xm fasttracker modules
-# audio/x-s3m screamtracker modules
-# audio/s3m screamtracker modules
-# audio/x-zipped-mod mdz
-# audio/mod mod
-# audio/x-mod All modules (mod, s3m, 669, mtm, med, xm, it, mdz, stm, itz, xmz, s3z)
-
-# Taken from loader code from mikmod version 2.14
-# by Steve McIntyre (stevem@chiark.greenend.org.uk)
-# <doj@cubic.org> added title printing on 2003-06-24
-0 string MAS_UTrack_V00
->14 string >/0 audio/x-mod
-#audio/x-tracker-module
-
-#0 string UN05 MikMod UNI format module sound data
-
-0 string Extended\ Module: audio/x-mod
-#audio/x-tracker-module
-##>17 string >\0 Title: "%s"
-
-21 string/c \!SCREAM! audio/x-mod
-#audio/x-screamtracker-module
-21 string BMOD2STM audio/x-mod
-#audio/x-screamtracker-module
-1080 string M.K. audio/x-mod
-#audio/x-protracker-module
-#>0 string >\0 Title: "%s"
-1080 string M!K! audio/x-mod
-#audio/x-protracker-module
-#>0 string >\0 Title: "%s"
-1080 string FLT4 audio/x-mod
-#audio/x-startracker-module
-#>0 string >\0 Title: "%s"
-1080 string FLT8 audio/x-mod
-#audio/x-startracker-module
-#>0 string >\0 Title: "%s"
-1080 string 4CHN audio/x-mod
-#audio/x-fasttracker-module
-#>0 string >\0 Title: "%s"
-1080 string 6CHN audio/x-mod
-#audio/x-fasttracker-module
-#>0 string >\0 Title: "%s"
-1080 string 8CHN audio/x-mod
-#audio/x-fasttracker-module
-#>0 string >\0 Title: "%s"
-1080 string CD81 audio/x-mod
-#audio/x-oktalyzer-tracker-module
-#>0 string >\0 Title: "%s"
-1080 string OKTA audio/x-mod
-#audio/x-oktalyzer-tracker-module
-#>0 string >\0 Title: "%s"
-# Not good enough.
-#1082 string CH
-#>1080 string >/0 %.2s-channel Fasttracker "oktalyzer" module sound data
-1080 string 16CN audio/x-mod
-#audio/x-taketracker-module
-#>0 string >\0 Title: "%s"
-1080 string 32CN audio/x-mod
-#audio/x-taketracker-module
-#>0 string >\0 Title: "%s"
-
-# Impuse tracker module (it)
-0 string IMPM audio/x-mod
-#>4 string >\0 "%s"
-#>40 leshort !0 compatible w/ITv%x
-#>42 leshort !0 created w/ITv%x
-
-#------------------------------------------------------------------------------
-# end local stuff
-#------------------------------------------------------------------------------
-
-# xml based formats!
-
-# svg
-
-38 string \<\!DOCTYPE\040svg image/svg+xml
-
-0 belong 0xfeedfeed application/x-java-keystore
-
-0 belong 0xcececece application/x-java-jce-keystore
-
-
-# xml
-0 string \<?xml text/xml
-
-
-#------------------------------------------------------------------------------
-# Java
-
-0 beshort 0xcafe
->2 beshort 0xbabe application/x-java-applet
->2 beshort 0xd00d application/x-java-pack200
-
-#------------------------------------------------------------------------------
-# audio: file(1) magic for sound formats
-#
-# from Jan Nicolai Langfeldt <janl@ifi.uio.no>,
-#
-
-# Sun/NeXT audio data
-0 string .snd
->12 belong 1 audio/basic
->12 belong 2 audio/basic
->12 belong 3 audio/basic
->12 belong 4 audio/basic
->12 belong 5 audio/basic
->12 belong 6 audio/basic
->12 belong 7 audio/basic
-
->12 belong 23 audio/x-adpcm
-
-# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
-# that uses little-endian encoding and has a different magic number
-# (0x0064732E in little-endian encoding).
-0 lelong 0x0064732E
->12 lelong 1 audio/x-dec-basic
->12 lelong 2 audio/x-dec-basic
->12 lelong 3 audio/x-dec-basic
->12 lelong 4 audio/x-dec-basic
->12 lelong 5 audio/x-dec-basic
->12 lelong 6 audio/x-dec-basic
->12 lelong 7 audio/x-dec-basic
-# compressed (G.721 ADPCM)
->12 lelong 23 audio/x-dec-adpcm
-
-# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM"
-# AIFF audio data
-8 string AIFF audio/x-aiff
-# AIFF-C audio data
-8 string AIFC audio/x-aiff
-# IFF/8SVX audio data
-8 string 8SVX audio/x-aiff
-
-
-
-# Creative Labs AUDIO stuff
-# Standard MIDI data
-0 string MThd audio/x-midi
-#>9 byte >0 (format %d)
-#>11 byte >1 using %d channels
-# Creative Music (CMF) data
-0 string CTMF audio/x-unknown
-# SoundBlaster instrument data
-0 string SBI audio/x-unknown
-# Creative Labs voice data
-0 string Creative\ Voice\ File audio/x-unknown
-## is this next line right? it came this way...
-#>19 byte 0x1A
-#>23 byte >0 - version %d
-#>22 byte >0 \b.%d
-
-# [GRR 950115: is this also Creative Labs? Guessing that first line
-# should be string instead of unknown-endian long...]
-#0 long 0x4e54524b MultiTrack sound data
-#0 string NTRK MultiTrack sound data
-#>4 long x - version %ld
-
-# Microsoft WAVE format (*.wav)
-# [GRR 950115: probably all of the shorts and longs should be leshort/lelong]
-# Microsoft RIFF
-0 string RIFF
-# - WAVE format
->8 string WAVE audio/x-wav
->8 string/B AVI video/x-msvideo
-#
->8 string CDRA image/x-coreldraw
-
-# AAC (aka MPEG-2 NBC)
-0 beshort&0xfff6 0xfff0 audio/X-HX-AAC-ADTS
-0 string ADIF audio/X-HX-AAC-ADIF
-0 beshort&0xffe0 0x56e0 audio/MP4A-LATM
-0 beshort 0x4De1 audio/MP4A-LATM
-
-# MPEG Layer 3 sound files
-# modified by Joerg Jenderek
-# GRR the original test are too common for many DOS files
-# so test 1 <= kbits nibble <= E
-0 beshort &0xffe0
->2 ubyte&0xF0 >0x0F
->>2 ubyte&0xF0 <0xE1 audio/mpeg
-#MP3 with ID3 tag
-0 string ID3 audio/mpeg
-# Ogg/Vorbis
-0 string OggS application/ogg
-
-#------------------------------------------------------------------------------
-# c-lang: file(1) magic for C programs or various scripts
-#
-
-# XPM icons (Greg Roelofs, newt@uchicago.edu)
-# ideally should go into "images", but entries below would tag XPM as C source
-0 string /*\ XPM image/x-xpmi
-
-# 3DS (3d Studio files) Conflicts with diff output 0x3d '='
-#16 beshort 0x3d3d image/x-3ds
-
-# this first will upset you if you're a PL/1 shop... (are there any left?)
-# in which case rm it; ascmagic will catch real C programs
-# C or REXX program text
-#0 string /* text/x-c
-# C++ program text
-#0 string // text/x-c++
-
-#------------------------------------------------------------------------------
-# commands: file(1) magic for various shells and interpreters
-#
-#0 string :\ shell archive or commands for antique kernel text
-0 string #!/bin/sh application/x-shellscript
-0 string #!\ /bin/sh application/x-shellscript
-0 string #!/bin/csh application/x-shellscript
-0 string #!\ /bin/csh application/x-shellscript
-# korn shell magic, sent by George Wu, gwu@clyde.att.com
-0 string #!/bin/ksh application/x-shellscript
-0 string #!\ /bin/ksh application/x-shellscript
-0 string #!/bin/tcsh application/x-shellscript
-0 string #!\ /bin/tcsh application/x-shellscript
-0 string #!/usr/local/tcsh application/x-shellscript
-0 string #!\ /usr/local/tcsh application/x-shellscript
-0 string #!/usr/local/bin/tcsh application/x-shellscript
-0 string #!\ /usr/local/bin/tcsh application/x-shellscript
-# bash shell magic, from Peter Tobias (tobias@server.et-inf.fho-emden.de)
-0 string #!/bin/bash application/x-shellscript
-0 string #!\ /bin/bash application/x-shellscript
-0 string #!/usr/local/bin/bash application/x-shellscript
-0 string #!\ /usr/local/bin/bash application/x-shellscript
-
-#
-# zsh/ash/ae/nawk/gawk magic from cameron@cs.unsw.oz.au (Cameron Simpson)
-0 string #!/bin/zsh application/x-shellscript
-0 string #!/usr/bin/zsh application/x-shellscript
-0 string #!/usr/local/bin/zsh application/x-shellscript
-0 string #!\ /usr/local/bin/zsh application/x-shellscript
-0 string #!/usr/local/bin/ash application/x-shellscript
-0 string #!\ /usr/local/bin/ash application/x-shellscript
-#0 string #!/usr/local/bin/ae Neil Brown's ae
-#0 string #!\ /usr/local/bin/ae Neil Brown's ae
-0 string #!/bin/nawk application/x-nawk
-0 string #!\ /bin/nawk application/x-nawk
-0 string #!/usr/bin/nawk application/x-nawk
-0 string #!\ /usr/bin/nawk application/x-nawk
-0 string #!/usr/local/bin/nawk application/x-nawk
-0 string #!\ /usr/local/bin/nawk application/x-nawk
-0 string #!/bin/gawk application/x-gawk
-0 string #!\ /bin/gawk application/x-gawk
-0 string #!/usr/bin/gawk application/x-gawk
-0 string #!\ /usr/bin/gawk application/x-gawk
-0 string #!/usr/local/bin/gawk application/x-gawk
-0 string #!\ /usr/local/bin/gawk application/x-gawk
-#
-0 string #!/bin/awk application/x-awk
-0 string #!\ /bin/awk application/x-awk
-0 string #!/usr/bin/awk application/x-awk
-0 string #!\ /usr/bin/awk application/x-awk
-# update to distinguish from *.vcf files by Joerg Jenderek: joerg dot jenderek at web dot de
-# Too general, \EBEGIN matches in postscript
-#0 regex BEGIN[[:space:]]*[{] application/x-awk
-
-# For Larry Wall's perl language. The ``eval'' line recognizes an
-# outrageously clever hack for USG systems.
-# Keith Waclena <keith@cerberus.uchicago.edu>
-0 string #!/bin/perl application/x-perl
-0 string #!\ /bin/perl application/x-perl
-0 string eval\ "exec\ /bin/perl application/x-perl
-0 string #!/usr/bin/perl application/x-perl
-0 string #!\ /usr/bin/perl application/x-perl
-0 string eval\ "exec\ /usr/bin/perl application/x-perl
-0 string #!/usr/local/bin/perl application/x-perl
-0 string #!\ /usr/local/bin/perl application/x-perl
-0 string eval\ "exec\ /usr/local/bin/perl application/x-perl
-
-#------------------------------------------------------------------------------
-# compress: file(1) magic for pure-compression formats (no archives)
-#
-# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc.
-#
-# Formats for various forms of compressed data
-# Formats for "compress" proper have been moved into "compress.c",
-# because it tries to uncompress it to figure out what's inside.
-
-# standard unix compress
-0 string \037\235 application/x-compress
-
-# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver)
-0 string \037\213 application/x-gzip
-
-0 string PK\003\004 application/zip
-
-# RAR archiver (Greg Roelofs, newt@uchicago.edu)
-0 string Rar! application/x-rar
-
-# According to gzip.h, this is the correct byte order for packed data.
-0 string \037\036 application/octet-stream
-#
-# This magic number is byte-order-independent.
-#
-0 short 017437 application/octet-stream
-
-# XXX - why *two* entries for "compacted data", one of which is
-# byte-order independent, and one of which is byte-order dependent?
-#
-# compacted data
-0 short 0x1fff application/octet-stream
-0 string \377\037 application/octet-stream
-# huf output
-0 short 0145405 application/octet-stream
-
-# Squeeze and Crunch...
-# These numbers were gleaned from the Unix versions of the programs to
-# handle these formats. Note that I can only uncrunch, not crunch, and
-# I didn't have a crunched file handy, so the crunch number is untested.
-# Keith Waclena <keith@cerberus.uchicago.edu>
-#0 leshort 0x76FF squeezed data (CP/M, DOS)
-#0 leshort 0x76FE crunched data (CP/M, DOS)
-
-# Freeze
-#0 string \037\237 Frozen file 2.1
-#0 string \037\236 Frozen file 1.0 (or gzip 0.5)
-
-# lzh?
-#0 string \037\240 LZH compressed data
-
-257 string ustar\0 application/x-tar posix
-257 string ustar\040\040\0 application/x-tar gnu
-
-0 short 070707 application/x-cpio
-0 short 0143561 application/x-cpio swapped
-
-0 string =<ar> application/x-archive
-0 string \!<arch> application/x-archive
->8 string debian application/x-debian-package
-
-#------------------------------------------------------------------------------
-#
-# RPM: file(1) magic for Red Hat Packages Erik Troan (ewt@redhat.com)
-#
-0 beshort 0xedab
->2 beshort 0xeedb application/x-rpm
-
-0 lelong&0x8080ffff 0x0000081a application/x-arc lzw
-0 lelong&0x8080ffff 0x0000091a application/x-arc squashed
-0 lelong&0x8080ffff 0x0000021a application/x-arc uncompressed
-0 lelong&0x8080ffff 0x0000031a application/x-arc packed
-0 lelong&0x8080ffff 0x0000041a application/x-arc squeezed
-0 lelong&0x8080ffff 0x0000061a application/x-arc crunched
-
-0 leshort 0xea60 application/x-arj
-
-# LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu)
-2 string -lh0- application/x-lharc lh0
-2 string -lh1- application/x-lharc lh1
-2 string -lz4- application/x-lharc lz4
-2 string -lz5- application/x-lharc lz5
-# [never seen any but the last; -lh4- reported in comp.compression:]
-2 string -lzs- application/x-lha lzs
-2 string -lh\ - application/x-lha lh
-2 string -lhd- application/x-lha lhd
-2 string -lh2- application/x-lha lh2
-2 string -lh3- application/x-lha lh3
-2 string -lh4- application/x-lha lh4
-2 string -lh5- application/x-lha lh5
-2 string -lh6- application/x-lha lh6
-2 string -lh7- application/x-lha lh7
-# Shell archives
-10 string #\ This\ is\ a\ shell\ archive application/octet-stream x-shell
-
-#------------------------------------------------------------------------------
-# frame: file(1) magic for FrameMaker files
-#
-# This stuff came on a FrameMaker demo tape, most of which is
-# copyright, but this file is "published" as witness the following:
-#
-# Note that this is the Framemaker Maker Interchange Format, not the
-# Normal format which would be application/vnd.framemaker.
-#
-0 string \<MakerFile application/x-mif
-0 string \<MIFFile application/x-mif
-0 string \<MakerDictionary application/x-mif
-0 string \<MakerScreenFon application/x-mif
-0 string \<MML application/x-mif
-0 string \<Book application/x-mif
-0 string \<Maker application/x-mif
-
-#------------------------------------------------------------------------------
-# html: file(1) magic for HTML (HyperText Markup Language) docs
-#
-# from Daniel Quinlan <quinlan@yggdrasil.com>
-#
-0 string \<HEAD text/html
-0 string \<head text/html
-0 string \<TITLE text/html
-0 string \<title text/html
-0 string \<html text/html
-0 string \<HTML text/html
-0 string \<!-- text/html
-0 string \<h1 text/html
-0 string \<H1 text/html
-0 string/c \<!doctype\ html text/html
-
-#------------------------------------------------------------------------------
-# images: file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
-#
-# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
-# additions by janl@ifi.uio.no as well as others. Jan also suggested
-# merging several one- and two-line files into here.
-#
-# XXX - byte order for GIF and TIFF fields?
-# [GRR: TIFF allows both byte orders; GIF is probably little-endian]
-#
-
-# [GRR: what the hell is this doing in here?]
-#0 string xbtoa btoa'd file
-
-# PBMPLUS
-# PBM file
-0 string P1 image/x-portable-bitmap
-# PGM file
-0 string P2 image/x-portable-greymap
-# PPM file
-0 string P3 image/x-portable-pixmap
-# PBM "rawbits" file
-0 string P4 image/x-portable-bitmap
-# PGM "rawbits" file
-0 string P5 image/x-portable-greymap
-# PPM "rawbits" file
-0 string P6 image/x-portable-pixmap
-
-# NIFF (Navy Interchange File Format, a modification of TIFF)
-# [GRR: this *must* go before TIFF]
-0 string IIN1 image/x-niff
-
-# TIFF and friends
-# TIFF file, big-endian
-0 string MM image/tiff
-# TIFF file, little-endian
-0 string II image/tiff
-
-# possible GIF replacements; none yet released!
-# (Greg Roelofs, newt@uchicago.edu)
-#
-# GRR 950115: this was mine ("Zip GIF"):
-# ZIF image (GIF+deflate alpha)
-0 string GIF94z image/x-unknown
-#
-# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better):
-# FGF image (GIF+deflate beta)
-0 string FGF95a image/x-unknown
-#
-# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal
-# (best; not yet implemented):
-# PBF image (deflate compression)
-0 string PBF image/x-unknown
-
-# GIF
-0 string GIF image/gif
-
-# JPEG images
-0 beshort 0xffd8 image/jpeg
-
-# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
-0 string BM image/bmp
-#>14 byte 12 (OS/2 1.x format)
-#>14 byte 64 (OS/2 2.x format)
-#>14 byte 40 (Windows 3.x format)
-#0 string IC icon
-#0 string PI pointer
-#0 string CI color icon
-#0 string CP color pointer
-#0 string BA bitmap array
-
-# CDROM Filesystems
-32769 string CD001 application/x-iso9660-image
-
-# Newer StuffIt archives (grant@netbsd.org)
-0 string StuffIt application/x-stuffit
-#>162 string >0 : %s
-
-# BinHex is the Macintosh ASCII-encoded file format (see also "apple")
-# Daniel Quinlan, quinlan@yggdrasil.com
-11 string must\ be\ converted\ with\ BinHex\ 4 application/mac-binhex40
-##>41 string x \b, version %.3s
-
-
-#------------------------------------------------------------------------------
-# lisp: file(1) magic for lisp programs
-#
-# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
-0 string ;; text/plain
-# Emacs 18 - this is always correct, but not very magical.
-0 string \012( application/x-elc
-# Emacs 19
-0 string ;ELC\023\000\000\000 application/x-elc
-
-#------------------------------------------------------------------------------
-# mail.news: file(1) magic for mail and news
-#
-# There are tests to ascmagic.c to cope with mail and news.
-0 string Relay-Version: message/rfc822
-0 string #!\ rnews message/rfc822
-0 string N#!\ rnews message/rfc822
-0 string Forward\ to message/rfc822
-0 string Pipe\ to message/rfc822
-0 string Return-Path: message/rfc822
-0 string Received: message/rfc822
-0 string Path: message/news
-0 string Xref: message/news
-0 string From: message/rfc822
-0 string Article message/news
-#------------------------------------------------------------------------------
-# msword: file(1) magic for MS Word files
-#
-# Contributor claims:
-# Reversed-engineered MS Word magic numbers
-#
-
-0 string \376\067\0\043 application/msword
-# disable this one because it applies also to other
-# Office/OLE documents for which msword is not correct. See PR#2608.
-# from magic file of the apache
-#0 string \320\317\021\340\241\261 application/msword
-512 string \354\245\301 application/msword
-0 string \333\245-\0\0\0 application/msword
-
-
-
-#------------------------------------------------------------------------------
-# printer: file(1) magic for printer-formatted files
-#
-
-# PostScript
-0 string %! application/postscript
-0 string \004%! application/postscript
-
-# Acrobat
-# (due to clamen@cs.cmu.edu)
-0 string %PDF- application/pdf
-
-#------------------------------------------------------------------------------
-# sc: file(1) magic for "sc" spreadsheet
-#
-38 string Spreadsheet application/x-sc
-
-#------------------------------------------------------------------------------
-# tex: file(1) magic for TeX files
-#
-# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
-#
-# From <conklin@talisman.kaleida.com>
-
-# Although we may know the offset of certain text fields in TeX DVI
-# and font files, we can't use them reliably because they are not
-# zero terminated. [but we do anyway, christos]
-0 string \367\002 application/x-dvi
-#0 string \367\203 TeX generic font data
-#0 string \367\131 TeX packed font data
-#0 string \367\312 TeX virtual font data
-#0 string This\ is\ TeX, TeX transcript text
-#0 string This\ is\ METAFONT, METAFONT transcript text
-
-# There is no way to detect TeX Font Metric (*.tfm) files without
-# breaking them apart and reading the data. The following patterns
-# match most *.tfm files generated by METAFONT or afm2tfm.
-2 string \000\021 application/x-tex-tfm
-2 string \000\022 application/x-tex-tfm
-#>34 string >\0 (%s)
-
-# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
-0 string \\input\ texinfo text/x-texinfo
-0 string This\ is\ Info\ file text/x-info
-
-# correct TeX magic for Linux (and maybe more)
-# from Peter Tobias (tobias@server.et-inf.fho-emden.de)
-#
-0 leshort 0x02f7 application/x-dvi
-
-# RTF - Rich Text Format
-0 string {\\rtf text/rtf
-
-# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
-0 search/400 \\input text/x-tex
-0 search/400 \\section text/x-tex
-0 search/400 \\setlength text/x-tex
-0 search/400 \\documentstyle text/x-tex
-0 search/400 \\chapter text/x-tex
-0 search/400 \\documentclass text/x-tex
-
-#------------------------------------------------------------------------------
-# animation: file(1) magic for animation/movie formats
-#
-# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8)
-# MPEG file
-# MPEG sequences
-0 belong 0x000001BA
->4 byte &0x40 video/mp2p
->4 byte ^0x40 video/mpeg
-0 belong 0x000001BB video/mpeg
-0 belong 0x000001B0 video/mp4v-es
-0 belong 0x000001B5 video/mp4v-es
-0 belong 0x000001B3 video/mpv
-0 belong&0xFF5FFF1F 0x47400010 video/mp2t
-0 belong 0x00000001
->4 byte&0x1F 0x07 video/h264
-
-# FLI animation format
-0 leshort 0xAF11 video/x-fli
-# FLC animation format
-0 leshort 0xAF12 video/x-flc
-#
-# SGI and Apple formats
-# Added ISO mimes
-0 string MOVI video/x-sgi-movie
-4 string moov video/quicktime
-4 string mdat video/quicktime
-4 string wide video/quicktime
-4 string skip video/quicktime
-4 string free video/quicktime
-4 string idsc image/x-quicktime
-4 string idat image/x-quicktime
-4 string pckg application/x-quicktime-player
-4 string/B jP image/jp2
-4 string ftyp
->8 string isom video/mp4
->8 string mp41 video/mp4
->8 string mp42 video/mp4
->8 string/B jp2 image/jp2
->8 string 3gp video/3gpp
->8 string avc1 video/3gpp
->8 string mmp4 video/mp4
->8 string/B M4A audio/mp4
->8 string/B qt video/quicktime
-# The contributor claims:
-# I couldn't find a real magic number for these, however, this
-# -appears- to work. Note that it might catch other files, too,
-# so BE CAREFUL!
-#
-# Note that title and author appear in the two 20-byte chunks
-# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
-# 255 (hex FF)! DL format SUCKS BIG ROCKS.
-#
-# DL file version 1 , medium format (160x100, 4 images/screen)
-0 byte 1 video/x-unknown
-0 byte 2 video/x-unknown
-#
-# Databases
-#
-# GDBM magic numbers
-# Will be maintained as part of the GDBM distribution in the future.
-# <downsj@teeny.org>
-0 belong 0x13579ace application/x-gdbm
-0 lelong 0x13579ace application/x-gdbm
-0 string GDBM application/x-gdbm
-#
-0 belong 0x061561 application/x-dbm
-#
-# Executables
-#
-0 string \177ELF
->16 leshort 0 application/octet-stream
->16 leshort 1 application/x-object
->16 leshort 2 application/x-executable
->16 leshort 3 application/x-sharedlib
->16 leshort 4 application/x-coredump
->16 beshort 0 application/octet-stream
->16 beshort 1 application/x-object
->16 beshort 2 application/x-executable
->16 beshort 3 application/x-sharedlib
->16 beshort 4 application/x-coredump
-#
-# DOS
-0 string MZ application/x-dosexec
-#
-# KDE
-0 string [KDE\ Desktop\ Entry] application/x-kdelnk
-0 string #\ KDE\ Config\ File application/x-kdelnk
-# xmcd database file for kscd
-0 string #\ xmcd text/x-xmcd
-
-#------------------------------------------------------------------------------
-# pkgadd: file(1) magic for SysV R4 PKG Datastreams
-#
-0 string #\ PaCkAgE\ DaTaStReAm application/x-svr4-package
-
-#PNG Image Format
-0 string \x89PNG image/png
-
-# MNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/>
-0 string \x8aMNG video/x-mng
-0 string \x8aJNG video/x-jng
-
-#------------------------------------------------------------------------------
-# Hierarchical Data Format, used to facilitate scientific data exchange
-# specifications at http://hdf.ncsa.uiuc.edu/
-0 belong 0x0e031301 Hierarchical Data Format (version 4) data
-0 string \211HDF\r\n\032 Hierarchical Data Format (version 5) data
-
-# Adobe Photoshop
-0 string 8BPS image/vnd.adobe.photoshop
-
-# Felix von Leitner <felix-file@fefe.de>
-0 string d8:announce application/x-bittorrent
-
-
-# lotus 1-2-3 document
-0 belong 0x00001a00 application/x-123
-0 belong 0x00000200 application/x-123
-
-# MS Access database
-4 string Standard\ Jet\ DB application/x-msaccess
-
-## magic for XBase files
-#0 byte 0x02
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x03
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x04
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x05
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x30
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x43
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x7b
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x83
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x8b
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0x8e
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0xb3
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 byte 0xf5
-#>8 leshort >0
-#>>12 leshort 0 application/x-dbf
-#
-#0 leshort 0x0006 application/x-dbt
-
-# Debian has entries for the old PGP formats:
-# pgp: file(1) magic for Pretty Good Privacy
-# see http://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html
-0 beshort 0x9900 application/x-pgp-keyring
-0 beshort 0x9501 application/x-pgp-keyring
-0 beshort 0x9500 application/x-pgp-keyring
-0 beshort 0xa600 application/pgp-encrypted
-0 string -----BEGIN\040PGP text/PGP armored data
->15 string PUBLIC\040KEY\040BLOCK- public key block
->15 string MESSAGE- message
->15 string SIGNED\040MESSAGE- signed message
->15 string PGP\040SIGNATURE- signature
-0 beshort 0x8501 data
-#
-# GnuPG Magic:
-#
-0 beshort 0x9901 application/x-gnupg-keyring
-0 beshort 0x8501 text/OpenPGP data
-
-# flash: file(1) magic for Macromedia Flash file format
-#
-# See
-#
-# http://www.macromedia.com/software/flash/open/
-#
-0 string FWS
->3 byte x application/x-shockwave-flash
-# Flash Video
-0 string FLV video/x-flv
-
-
-# The following paramaters are created for Namazu.
-# <http://www.namazu.org/>
-#
-# 1999/08/13
-#0 string \<!--\ MHonArc text/html; x-type=mhonarc
-0 string BZh application/x-bzip2
-
-# 1999/09/09
-# VRML (suggested by Masao Takaku)
-0 string #VRML\ V1.0\ ascii model/vrml
-0 string #VRML\ V2.0\ utf8 model/vrml
-
-#------------------------------------------------------------------------------
-# ichitaro456: file(1) magic for Just System Word Processor Ichitaro
-#
-# Contributor kenzo-:
-# Reversed-engineered JS Ichitaro magic numbers
-#
-
-0 string DOC
->43 byte 0x14 application/x-ichitaro4
->144 string JDASH application/x-ichitaro4
-
-0 string DOC
->43 byte 0x15 application/x-ichitaro5
-
-0 string DOC
->43 byte 0x16 application/x-ichitaro6
-
-#------------------------------------------------------------------------------
-# office97: file(1) magic for MicroSoft Office files
-#
-# Contributor kenzo-:
-# Reversed-engineered MS Office magic numbers
-#
-
-#0 string \320\317\021\340\241\261\032\341
-#>48 byte 0x1B application/excel
-
-2080 string Microsoft\ Excel\ 5.0\ Worksheet application/vnd.ms-excel
-2114 string Biff5 application/vnd.ms-excel
-
-0 string \224\246\056 application/msword
-
-0 belong 0x31be0000 application/msword
-
-0 string PO^Q` application/msword
-
-0 string \320\317\021\340\241\261\032\341
->546 string bjbj application/msword
->546 string jbjb application/msword
-
-512 string R\0o\0o\0t\0\ \0E\0n\0t\0r\0y application/msword
-
-2080 string Microsoft\ Word\ 6.0\ Document application/msword
-2080 string Documento\ Microsoft\ Word\ 6 application/msword
-2112 string MSWordDoc application/msword
-
-#0 string \320\317\021\340\241\261\032\341 application/powerpoint
-0 string \320\317\021\340\241\261\032\341 application/msword
-
-0 string #\ PaCkAgE\ DaTaStReAm application/x-svr4-package
-
-
-# WinNT/WinCE PE files (Warner Losh, imp@village.org)
-#
-128 string PE\000\000 application/octet-stream
-0 string PE\000\000 application/octet-stream
-
-# miscellaneous formats
-0 string LZ application/octet-stream
-
-# DOS device drivers by Joerg Jenderek
-0 belong 0xffffffff application/octet-stream
-
-# .EXE formats (Greg Roelofs, newt@uchicago.edu)
-#
-0 string MZ
->24 string @ application/octet-stream
-
-0 string MZ
->30 string Copyright\ 1989-1990\ PKWARE\ Inc. application/zip
-
-0 string MZ
->30 string PKLITE\ Copr. application/zip
-
-0 string MZ
->36 string LHa's\ SFX application/x-lha
-
-0 string MZ application/octet-stream
-
-# LHA archiver
-2 string -lh
->6 string - application/x-lha
-
-
-# Zoo archiver
-20 lelong 0xfdc4a7dc application/x-zoo
-
-# ARC archiver
-0 lelong&0x8080ffff 0x0000081a application/x-arc
-0 lelong&0x8080ffff 0x0000091a application/x-arc
-0 lelong&0x8080ffff 0x0000021a application/x-arc
-0 lelong&0x8080ffff 0x0000031a application/x-arc
-0 lelong&0x8080ffff 0x0000041a application/x-arc
-0 lelong&0x8080ffff 0x0000061a application/x-arc
-
-# Microsoft Outlook's Transport Neutral Encapsulation Format (TNEF)
-0 lelong 0x223e9f78 application/vnd.ms-tnef
-
-# From: stephane.loeuillet@tiscali.f
-# http://www.djvuzone.org/
-0 string AT&TFORM image/vnd.djvu
-
-# Danny Milosavljevic <danny.milo@gmx.net>
-# this are adrift (adventure game standard) game files, extension .taf
-# depending on version magic continues with 0x93453E6139FA (V 4.0)
-# 0x9445376139FA (V 3.90)
-# 0x9445366139FA (V 3.80)
-# this is from source (http://www.adrift.org.uk/) and I have some taf
-# files, and checked them.
-#0 belong 0x3C423FC9
-#>4 belong 0x6A87C2CF application/x-adrift
-#0 string \000\000\001\000 image/x-ico
-
-# Quark Xpress 3 Files:
-# (made the mimetype up)
-0 string \0\0MMXPR3\0 application/x-quark-xpress-3
-
-# EET archive
-# From: Tilman Sauerbeck <tilman@code-monkey.de>
-0 belong 0x1ee7ff00 application/x-eet
-
-# From: Denis Knauf, via gentoo.
-0 string fLaC audio/x-flac
-0 string CWS application/x-shockwave-flash
-
-# Hangul Document Files:
-# Reversed-engineered HWP magic numbers
-# From: Won-Kyu Park <wkpark@kldp.org>
-512 string R\0o\0o\0t\0 application/x-hwp
-
-0 string/c BEGIN:VCARD text/x-vcard
-0 string WordPro\0 application/vnd.lotus-wordpro
-0 string WordPro\r\373 application/vnd.lotus-wordpro
-0 string CPC\262 image/x-cpi
-
-#
-128 string DICM application/dicom
-
-# Symbian installation files
-8 lelong 0x10000419 application/vnd.symbian.install
-0 lelong 0x10201A7A x-epoc/x-sisx-app
-# FORTRAN source
-0 string/c c\ text/x-fortran
diff --git a/contrib/file/magic2mime b/contrib/file/magic2mime
index 26f84d28..26f84d28 100755..100644
--- a/contrib/file/magic2mime
+++ b/contrib/file/magic2mime
diff --git a/contrib/file/mkinstalldirs b/contrib/file/mkinstalldirs
deleted file mode 100644
index ef7e16f..0000000
--- a/contrib/file/mkinstalldirs
+++ /dev/null
@@ -1,161 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-
-scriptversion=2006-05-11.19
-
-# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain.
-#
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-nl='
-'
-IFS=" "" $nl"
-errstatus=0
-dirmode=
-
-usage="\
-Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
-
-Create each directory DIR (with mode MODE, if specified), including all
-leading file name components.
-
-Report bugs to <bug-automake@gnu.org>."
-
-# process command line arguments
-while test $# -gt 0 ; do
- case $1 in
- -h | --help | --h*) # -h for help
- echo "$usage"
- exit $?
- ;;
- -m) # -m PERM arg
- shift
- test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
- dirmode=$1
- shift
- ;;
- --version)
- echo "$0 $scriptversion"
- exit $?
- ;;
- --) # stop option processing
- shift
- break
- ;;
- -*) # unknown option
- echo "$usage" 1>&2
- exit 1
- ;;
- *) # first non-opt arg
- break
- ;;
- esac
-done
-
-for file
-do
- if test -d "$file"; then
- shift
- else
- break
- fi
-done
-
-case $# in
- 0) exit 0 ;;
-esac
-
-# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
-# mkdir -p a/c at the same time, both will detect that a is missing,
-# one will create a, then the other will try to create a and die with
-# a "File exists" error. This is a problem when calling mkinstalldirs
-# from a parallel make. We use --version in the probe to restrict
-# ourselves to GNU mkdir, which is thread-safe.
-case $dirmode in
- '')
- if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
- echo "mkdir -p -- $*"
- exec mkdir -p -- "$@"
- else
- # On NextStep and OpenStep, the `mkdir' command does not
- # recognize any option. It will interpret all options as
- # directories to create, and then abort because `.' already
- # exists.
- test -d ./-p && rmdir ./-p
- test -d ./--version && rmdir ./--version
- fi
- ;;
- *)
- if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
- test ! -d ./--version; then
- echo "mkdir -m $dirmode -p -- $*"
- exec mkdir -m "$dirmode" -p -- "$@"
- else
- # Clean up after NextStep and OpenStep mkdir.
- for d in ./-m ./-p ./--version "./$dirmode";
- do
- test -d $d && rmdir $d
- done
- fi
- ;;
-esac
-
-for file
-do
- case $file in
- /*) pathcomp=/ ;;
- *) pathcomp= ;;
- esac
- oIFS=$IFS
- IFS=/
- set fnord $file
- shift
- IFS=$oIFS
-
- for d
- do
- test "x$d" = x && continue
-
- pathcomp=$pathcomp$d
- case $pathcomp in
- -*) pathcomp=./$pathcomp ;;
- esac
-
- if test ! -d "$pathcomp"; then
- echo "mkdir $pathcomp"
-
- mkdir "$pathcomp" || lasterr=$?
-
- if test ! -d "$pathcomp"; then
- errstatus=$lasterr
- else
- if test ! -z "$dirmode"; then
- echo "chmod $dirmode $pathcomp"
- lasterr=
- chmod "$dirmode" "$pathcomp" || lasterr=$?
-
- if test ! -z "$lasterr"; then
- errstatus=$lasterr
- fi
- fi
- fi
- fi
-
- pathcomp=$pathcomp/
- done
-done
-
-exit $errstatus
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/contrib/file/mygetopt.h b/contrib/file/mygetopt.h
new file mode 100644
index 0000000..ef87525
--- /dev/null
+++ b/contrib/file/mygetopt.h
@@ -0,0 +1,68 @@
+/* $NetBSD: getopt.h,v 1.8 2007/11/06 19:21:18 christos Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * 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 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
+ * 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.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#include <unistd.h>
+
+/*
+ * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions
+ */
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+struct option {
+ /* name of long option */
+ const char *name;
+ /*
+ * one of no_argument, required_argument, and optional_argument:
+ * whether option takes an argument
+ */
+ int has_arg;
+ /* if not NULL, set *flag to val when option found */
+ int *flag;
+ /* if flag not NULL, value to set *flag to; else return value */
+ int val;
+};
+
+int getopt_long(int, char * const *, const char *,
+ const struct option *, int *);
+
+#endif /* !_GETOPT_H_ */
diff --git a/contrib/file/names.h b/contrib/file/names.h
index 509d2a2..2682edc 100644
--- a/contrib/file/names.h
+++ b/contrib/file/names.h
@@ -32,7 +32,7 @@
* appear at fixed offsets into the file. Don't make HOWMANY
* too high unless you have a very fast CPU.
*
- * $File: names.h,v 1.29 2007/12/27 20:30:35 christos Exp $
+ * $File: names.h,v 1.32 2008/02/11 00:19:29 rrt Exp $
*/
/*
@@ -57,8 +57,8 @@
#define L_PO 13 /* PO */
static const struct {
- const char *human;
- const char *mime;
+ char human[48];
+ char mime[16];
} types[] = {
{ "C program", "text/x-c", },
{ "C++ program", "text/x-c++" },
@@ -74,8 +74,7 @@ static const struct {
{ "BCPL program", "text/x-bcpl" },
{ "M4 macro language pre-processor", "text/x-m4" },
{ "PO (gettext message catalogue)", "text/x-po" },
- { "cannot happen error on names.h/types", "error/x-error" },
- { 0, 0}
+ { "cannot happen error on names.h/types", "error/x-error" }
};
/*
@@ -114,8 +113,8 @@ static const struct {
* as Java, as it comes after "the" and "The". Perhaps we need a fancier
* heuristic to identify Java?
*/
-static struct names {
- const char *name;
+static const struct names {
+ char name[14];
short type;
} names[] = {
/* These must be sorted by eye for optimal hit rate */
@@ -145,18 +144,6 @@ static struct names {
{"LDFLAGS", L_MAKE},
{"all:", L_MAKE},
{".PRECIOUS", L_MAKE},
-/* Too many files of text have these words in them. Find another way
- * to recognize Fortrash.
- */
-#ifdef NOTDEF
- {"subroutine", L_FORT},
- {"function", L_FORT},
- {"block", L_FORT},
- {"common", L_FORT},
- {"dimension", L_FORT},
- {"integer", L_FORT},
- {"data", L_FORT},
-#endif /*NOTDEF*/
{".ascii", L_MACH},
{".asciiz", L_MACH},
{".byte", L_MACH},
@@ -181,6 +168,6 @@ static struct names {
{"<BODY", L_HTML},
{"<html", L_HTML},
{"<HTML", L_HTML},
- {NULL, 0}
+ {"<!--", L_HTML},
};
-#define NNAMES ((sizeof(names)/sizeof(struct names)) - 1)
+#define NNAMES (sizeof(names)/sizeof(struct names))
diff --git a/contrib/file/patchlevel.h b/contrib/file/patchlevel.h
index 10a506b..db6858b 100644
--- a/contrib/file/patchlevel.h
+++ b/contrib/file/patchlevel.h
@@ -1,11 +1,20 @@
#define FILE_VERSION_MAJOR 4
-#define patchlevel 23
+#define patchlevel 26
/*
* Patchlevel file for Ian Darwin's MAGIC command.
- * $File: patchlevel.h,v 1.67 2007/12/28 20:08:40 christos Exp $
+ * $File: patchlevel.h,v 1.70 2008/08/30 10:01:01 christos Exp $
*
* $Log: patchlevel.h,v $
+ * Revision 1.70 2008/08/30 10:01:01 christos
+ * file 4.26
+ *
+ * Revision 1.69 2008/07/02 15:27:05 christos
+ * welcome to 4.25
+ *
+ * Revision 1.68 2008/03/22 21:39:43 christos
+ * file 4.24
+ *
* Revision 1.67 2007/12/28 20:08:40 christos
* welcome to 4.23.
*
diff --git a/contrib/file/print.c b/contrib/file/print.c
index c28ee2e..c41e71e 100644
--- a/contrib/file/print.c
+++ b/contrib/file/print.c
@@ -41,7 +41,7 @@
#include <time.h>
#ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.61 2007/12/27 16:35:59 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.63 2008/02/17 19:28:54 rrt Exp $")
#endif /* lint */
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
@@ -89,8 +89,8 @@ file_mdump(struct magic *m)
if (m->str_flags & REGEX_OFFSET_START)
(void) fputc(CHAR_REGEX_OFFSET_START, stderr);
}
- if (m->str_count)
- (void) fprintf(stderr, "/%u", m->str_count);
+ if (m->str_range)
+ (void) fprintf(stderr, "/%u", m->str_range);
}
else {
if ((m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
@@ -184,13 +184,15 @@ protected void
file_magwarn(struct magic_set *ms, const char *f, ...)
{
va_list va;
- va_start(va, f);
/* cuz we use stdout for most, stderr here */
(void) fflush(stdout);
- (void) fprintf(stderr, "%s, %lu: Warning ", ms->file,
- (unsigned long)ms->line);
+ if (ms->file)
+ (void) fprintf(stderr, "%s, %lu: ", ms->file,
+ (unsigned long)ms->line);
+ (void) fprintf(stderr, "Warning: ");
+ va_start(va, f);
(void) vfprintf(stderr, f, va);
va_end(va);
(void) fputc('\n', stderr);
diff --git a/contrib/file/readelf.c b/contrib/file/readelf.c
index 3c7472b..9dcaf09 100644
--- a/contrib/file/readelf.c
+++ b/contrib/file/readelf.c
@@ -35,9 +35,10 @@
#endif
#include "readelf.h"
+#include "magic.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.68 2007/12/27 16:13:26 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.76 2008/07/16 18:00:57 christos Exp $")
#endif
#ifdef ELFCORE
@@ -45,9 +46,10 @@ private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
off_t, int *);
#endif
private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *);
-private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, int *);
-private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int,
+ off_t, int *, int);
+private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, int *,
+ int);
+private size_t donote(struct magic_set *, void *, size_t, size_t, int,
int, size_t, int *);
#define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
@@ -123,90 +125,124 @@ getu64(int swap, uint64_t value)
return value;
}
+#define elf_getu16(swap, value) getu16(swap, value)
+#define elf_getu32(swap, value) getu32(swap, value)
#ifdef USE_ARRAY_FOR_64BIT_TYPES
# define elf_getu64(swap, array) \
- ((swap ? ((uint64_t)getu32(swap, array[0])) << 32 : getu32(swap, array[0])) + \
- (swap ? getu32(swap, array[1]) : ((uint64_t)getu32(swap, array[1]) << 32)))
+ ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
+ (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
#else
# define elf_getu64(swap, value) getu64(swap, value)
#endif
-#define xsh_addr (class == ELFCLASS32 \
- ? (void *) &sh32 \
+#define xsh_addr (clazz == ELFCLASS32 \
+ ? (void *) &sh32 \
: (void *) &sh64)
-#define xsh_sizeof (class == ELFCLASS32 \
- ? sizeof sh32 \
+#define xsh_sizeof (clazz == ELFCLASS32 \
+ ? sizeof sh32 \
: sizeof sh64)
-#define xsh_size (class == ELFCLASS32 \
- ? getu32(swap, sh32.sh_size) \
- : getu64(swap, sh64.sh_size))
-#define xsh_offset (class == ELFCLASS32 \
- ? getu32(swap, sh32.sh_offset) \
- : getu64(swap, sh64.sh_offset))
-#define xsh_type (class == ELFCLASS32 \
- ? getu32(swap, sh32.sh_type) \
- : getu32(swap, sh64.sh_type))
-#define xph_addr (class == ELFCLASS32 \
- ? (void *) &ph32 \
+#define xsh_size (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, sh32.sh_size) \
+ : elf_getu64(swap, sh64.sh_size))
+#define xsh_offset (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, sh32.sh_offset) \
+ : elf_getu64(swap, sh64.sh_offset))
+#define xsh_type (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, sh32.sh_type) \
+ : elf_getu32(swap, sh64.sh_type))
+#define xph_addr (clazz == ELFCLASS32 \
+ ? (void *) &ph32 \
: (void *) &ph64)
-#define xph_sizeof (class == ELFCLASS32 \
- ? sizeof ph32 \
+#define xph_sizeof (clazz == ELFCLASS32 \
+ ? sizeof ph32 \
: sizeof ph64)
-#define xph_type (class == ELFCLASS32 \
- ? getu32(swap, ph32.p_type) \
- : getu32(swap, ph64.p_type))
-#define xph_offset (off_t)(class == ELFCLASS32 \
- ? getu32(swap, ph32.p_offset) \
- : getu64(swap, ph64.p_offset))
-#define xph_align (size_t)((class == ELFCLASS32 \
- ? (off_t) (ph32.p_align ? \
- getu32(swap, ph32.p_align) : 4) \
- : (off_t) (ph64.p_align ? \
- getu64(swap, ph64.p_align) : 4)))
-#define xph_filesz (size_t)((class == ELFCLASS32 \
- ? getu32(swap, ph32.p_filesz) \
- : getu64(swap, ph64.p_filesz)))
-#define xnh_addr (class == ELFCLASS32 \
- ? (void *) &nh32 \
+#define xph_type (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, ph32.p_type) \
+ : elf_getu32(swap, ph64.p_type))
+#define xph_offset (off_t)(clazz == ELFCLASS32 \
+ ? elf_getu32(swap, ph32.p_offset) \
+ : elf_getu64(swap, ph64.p_offset))
+#define xph_align (size_t)((clazz == ELFCLASS32 \
+ ? (off_t) (ph32.p_align ? \
+ elf_getu32(swap, ph32.p_align) : 4) \
+ : (off_t) (ph64.p_align ? \
+ elf_getu64(swap, ph64.p_align) : 4)))
+#define xph_filesz (size_t)((clazz == ELFCLASS32 \
+ ? elf_getu32(swap, ph32.p_filesz) \
+ : elf_getu64(swap, ph64.p_filesz)))
+#define xnh_addr (clazz == ELFCLASS32 \
+ ? (void *) &nh32 \
: (void *) &nh64)
-#define xph_memsz (size_t)((class == ELFCLASS32 \
- ? getu32(swap, ph32.p_memsz) \
- : getu64(swap, ph64.p_memsz)))
-#define xnh_sizeof (class == ELFCLASS32 \
- ? sizeof nh32 \
+#define xph_memsz (size_t)((clazz == ELFCLASS32 \
+ ? elf_getu32(swap, ph32.p_memsz) \
+ : elf_getu64(swap, ph64.p_memsz)))
+#define xnh_sizeof (clazz == ELFCLASS32 \
+ ? sizeof nh32 \
: sizeof nh64)
-#define xnh_type (class == ELFCLASS32 \
- ? getu32(swap, nh32.n_type) \
- : getu32(swap, nh64.n_type))
-#define xnh_namesz (class == ELFCLASS32 \
- ? getu32(swap, nh32.n_namesz) \
- : getu32(swap, nh64.n_namesz))
-#define xnh_descsz (class == ELFCLASS32 \
- ? getu32(swap, nh32.n_descsz) \
- : getu32(swap, nh64.n_descsz))
-#define prpsoffsets(i) (class == ELFCLASS32 \
- ? prpsoffsets32[i] \
+#define xnh_type (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, nh32.n_type) \
+ : elf_getu32(swap, nh64.n_type))
+#define xnh_namesz (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, nh32.n_namesz) \
+ : elf_getu32(swap, nh64.n_namesz))
+#define xnh_descsz (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, nh32.n_descsz) \
+ : elf_getu32(swap, nh64.n_descsz))
+#define prpsoffsets(i) (clazz == ELFCLASS32 \
+ ? prpsoffsets32[i] \
: prpsoffsets64[i])
+#define xcap_addr (clazz == ELFCLASS32 \
+ ? (void *) &cap32 \
+ : (void *) &cap64)
+#define xcap_sizeof (clazz == ELFCLASS32 \
+ ? sizeof cap32 \
+ : sizeof cap64)
+#define xcap_tag (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, cap32.c_tag) \
+ : elf_getu64(swap, cap64.c_tag))
+#define xcap_val (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, cap32.c_un.c_val) \
+ : elf_getu64(swap, cap64.c_un.c_val))
#ifdef ELFCORE
-size_t prpsoffsets32[] = {
- 8, /* FreeBSD */
- 44, /* Linux (path name) */
+/*
+ * Try larger offsets first to avoid false matches
+ * from earlier data that happen to look like strings.
+ */
+static const size_t prpsoffsets32[] = {
+#ifdef USE_NT_PSINFO
+ 104, /* SunOS 5.x (command line) */
+ 88, /* SunOS 5.x (short name) */
+#endif /* USE_NT_PSINFO */
+
+ 100, /* SunOS 5.x (command line) */
+ 84, /* SunOS 5.x (short name) */
+
+ 44, /* Linux (command line) */
28, /* Linux 2.0.36 (short name) */
- 84, /* SunOS 5.x */
+
+ 8, /* FreeBSD */
};
-size_t prpsoffsets64[] = {
- 16, /* FreeBSD, 64-bit */
- 56, /* Linux (path name) */
+static const size_t prpsoffsets64[] = {
+#ifdef USE_NT_PSINFO
+ 152, /* SunOS 5.x (command line) */
+ 136, /* SunOS 5.x (short name) */
+#endif /* USE_NT_PSINFO */
+
+ 136, /* SunOS 5.x, 64-bit (command line) */
+ 120, /* SunOS 5.x, 64-bit (short name) */
+
+ 56, /* Linux (command line) */
40, /* Linux (tested on core from 2.4.x, short name) */
- 120, /* SunOS 5.x, 64-bit */
+
+ 16, /* FreeBSD, 64-bit */
};
#define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
#define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
-#define NOFFSETS (class == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
+#define NOFFSETS (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
/*
* Look through the program headers of an executable image, searching
@@ -220,6 +256,14 @@ size_t prpsoffsets64[] = {
* SVR4-flavored systems, and Linux) containing the start of the
* command line for that program.
*
+ * SunOS 5.x core files contain two PT_NOTE sections, with the types
+ * NT_PRPSINFO (old) and NT_PSINFO (new). These structs contain the
+ * same info about the command name and command line, so it probably
+ * isn't worthwhile to look for NT_PSINFO, but the offsets are provided
+ * above (see USE_NT_PSINFO), in case we ever decide to do so. The
+ * NT_PRPSINFO and NT_PSINFO sections are always in order and adjacent;
+ * the SunOS 5.x file command relies on this (and prefers the latter).
+ *
* The signal number probably appears in a section of type NT_PRSTATUS,
* but that's also rather OS-dependent, in ways that are harder to
* dissect with heuristics, so I'm not bothering with the signal number.
@@ -233,7 +277,7 @@ size_t prpsoffsets64[] = {
#define OS_STYLE_FREEBSD 1
#define OS_STYLE_NETBSD 2
-private const char *os_style_names[] = {
+private const char os_style_names[][8] = {
"SVR4",
"FreeBSD",
"NetBSD",
@@ -244,7 +288,7 @@ private const char *os_style_names[] = {
#define FLAGS_DID_CORE_STYLE 4
private int
-dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off,
+dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
int num, size_t size, off_t fsize, int *flags)
{
Elf32_Phdr ph32;
@@ -309,7 +353,7 @@ dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off,
if (offset >= (size_t)bufsize)
break;
offset = donote(ms, nbuf, offset, (size_t)bufsize,
- class, swap, 4, flags);
+ clazz, swap, 4, flags);
if (offset == 0)
break;
@@ -320,8 +364,8 @@ dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off,
#endif
private size_t
-donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
- int class, int swap, size_t align, int *flags)
+donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
+ int clazz, int swap, size_t align, int *flags)
{
Elf32_Nhdr nh32;
Elf64_Nhdr nh64;
@@ -330,6 +374,7 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
int os_style = -1;
#endif
uint32_t namesz, descsz;
+ unsigned char *nbuf = CAST(unsigned char *, vbuf);
(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
offset += xnh_sizeof;
@@ -384,7 +429,7 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
if (file_printf(ms, ", for GNU/") == -1)
return size;
- switch (getu32(swap, desc[0])) {
+ switch (elf_getu32(swap, desc[0])) {
case GNU_OS_LINUX:
if (file_printf(ms, "Linux") == -1)
return size;
@@ -397,12 +442,20 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
if (file_printf(ms, "Solaris") == -1)
return size;
break;
+ case GNU_OS_KFREEBSD:
+ if (file_printf(ms, "kFreeBSD") == -1)
+ return size;
+ break;
+ case GNU_OS_KNETBSD:
+ if (file_printf(ms, "kNetBSD") == -1)
+ return size;
+ break;
default:
if (file_printf(ms, "<unknown>") == -1)
return size;
}
- if (file_printf(ms, " %d.%d.%d", getu32(swap, desc[1]),
- getu32(swap, desc[2]), getu32(swap, desc[3])) == -1)
+ if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
+ elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
return size;
*flags |= FLAGS_DID_NOTE;
return size;
@@ -412,7 +465,7 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
xnh_type == NT_NETBSD_VERSION && descsz == 4) {
uint32_t desc;
(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = getu32(swap, desc);
+ desc = elf_getu32(swap, desc);
if (file_printf(ms, ", for NetBSD") == -1)
return size;
@@ -458,7 +511,7 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
uint32_t desc;
(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = getu32(swap, desc);
+ desc = elf_getu32(swap, desc);
if (file_printf(ms, ", for FreeBSD") == -1)
return size;
@@ -547,7 +600,7 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
if (file_printf(ms, ", for DragonFly") == -1)
return size;
(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = getu32(swap, desc);
+ desc = elf_getu32(swap, desc);
if (file_printf(ms, " %d.%d.%d", desc / 100000,
desc / 10000 % 10, desc % 10000) == -1)
return size;
@@ -615,7 +668,7 @@ core:
(void)memcpy(&signo, &nbuf[doff + 0x08],
sizeof(signo));
if (file_printf(ms, " (signal %u)",
- getu32(swap, signo)) == -1)
+ elf_getu32(swap, signo)) == -1)
return size;
*flags |= FLAGS_DID_CORE;
return size;
@@ -689,7 +742,11 @@ core:
&nbuf[doff + prpsoffsets(i)];
for (cp = cname; *cp && isprint(*cp); cp++)
continue;
- if (cp > cname)
+ /*
+ * Linux apparently appends a space at the end
+ * of the command line: remove it.
+ */
+ while (cp > cname && isspace(cp[-1]))
cp--;
if (file_printf(ms, ", from '%.*s'",
(int)(cp - cname), cname) == -1)
@@ -707,15 +764,67 @@ core:
return offset;
}
+/* SunOS 5.x hardware capability descriptions */
+typedef struct cap_desc {
+ uint64_t cd_mask;
+ const char *cd_name;
+} cap_desc_t;
+
+static const cap_desc_t cap_desc_sparc[] = {
+ { AV_SPARC_MUL32, "MUL32" },
+ { AV_SPARC_DIV32, "DIV32" },
+ { AV_SPARC_FSMULD, "FSMULD" },
+ { AV_SPARC_V8PLUS, "V8PLUS" },
+ { AV_SPARC_POPC, "POPC" },
+ { AV_SPARC_VIS, "VIS" },
+ { AV_SPARC_VIS2, "VIS2" },
+ { AV_SPARC_ASI_BLK_INIT, "ASI_BLK_INIT" },
+ { AV_SPARC_FMAF, "FMAF" },
+ { AV_SPARC_FJFMAU, "FJFMAU" },
+ { AV_SPARC_IMA, "IMA" },
+ { 0, NULL }
+};
+
+static const cap_desc_t cap_desc_386[] = {
+ { AV_386_FPU, "FPU" },
+ { AV_386_TSC, "TSC" },
+ { AV_386_CX8, "CX8" },
+ { AV_386_SEP, "SEP" },
+ { AV_386_AMD_SYSC, "AMD_SYSC" },
+ { AV_386_CMOV, "CMOV" },
+ { AV_386_MMX, "MMX" },
+ { AV_386_AMD_MMX, "AMD_MMX" },
+ { AV_386_AMD_3DNow, "AMD_3DNow" },
+ { AV_386_AMD_3DNowx, "AMD_3DNowx" },
+ { AV_386_FXSR, "FXSR" },
+ { AV_386_SSE, "SSE" },
+ { AV_386_SSE2, "SSE2" },
+ { AV_386_PAUSE, "PAUSE" },
+ { AV_386_SSE3, "SSE3" },
+ { AV_386_MON, "MON" },
+ { AV_386_CX16, "CX16" },
+ { AV_386_AHF, "AHF" },
+ { AV_386_TSCP, "TSCP" },
+ { AV_386_AMD_SSE4A, "AMD_SSE4A" },
+ { AV_386_POPCNT, "POPCNT" },
+ { AV_386_AMD_LZCNT, "AMD_LZCNT" },
+ { AV_386_SSSE3, "SSSE3" },
+ { AV_386_SSE4_1, "SSE4.1" },
+ { AV_386_SSE4_2, "SSE4.2" },
+ { 0, NULL }
+};
+
private int
-doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num,
- size_t size, int *flags)
+doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
+ size_t size, int *flags, int mach)
{
Elf32_Shdr sh32;
Elf64_Shdr sh64;
int stripped = 1;
void *nbuf;
off_t noff;
+ uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
+ uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
if (size != xsh_sizeof) {
if (file_printf(ms, ", corrupted section header size") == -1)
@@ -769,7 +878,7 @@ doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num,
if (noff >= (size_t)xsh_size)
break;
noff = donote(ms, nbuf, (size_t)noff,
- (size_t)xsh_size, class, swap, 4,
+ (size_t)xsh_size, clazz, swap, 4,
flags);
if (noff == 0)
break;
@@ -781,10 +890,115 @@ doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num,
}
free(nbuf);
break;
+ case SHT_SUNW_cap:
+ {
+ off_t coff;
+ if ((off = lseek(fd, (off_t)0, SEEK_CUR)) ==
+ (off_t)-1) {
+ file_badread(ms);
+ return -1;
+ }
+ if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
+ (off_t)-1) {
+ file_badread(ms);
+ return -1;
+ }
+ coff = 0;
+ for (;;) {
+ Elf32_Cap cap32;
+ Elf64_Cap cap64;
+ char cbuf[MAX(sizeof cap32, sizeof cap64)];
+ if ((coff += xcap_sizeof) >= (size_t)xsh_size)
+ break;
+ if (read(fd, cbuf, (size_t)xcap_sizeof) !=
+ (ssize_t)xcap_sizeof) {
+ file_badread(ms);
+ return -1;
+ }
+ (void)memcpy(xcap_addr, cbuf, xcap_sizeof);
+ switch (xcap_tag) {
+ case CA_SUNW_NULL:
+ break;
+ case CA_SUNW_HW_1:
+ cap_hw1 |= xcap_val;
+ break;
+ case CA_SUNW_SF_1:
+ cap_sf1 |= xcap_val;
+ break;
+ default:
+ if (file_printf(ms,
+ ", with unknown capability "
+ "0x%llx = 0x%llx",
+ xcap_tag, xcap_val) == -1)
+ return -1;
+ break;
+ }
+ }
+ if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
+ file_badread(ms);
+ return -1;
+ }
+ break;
+ }
}
}
if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
return -1;
+ if (cap_hw1) {
+ const cap_desc_t *cdp;
+ switch (mach) {
+ case EM_SPARC:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ cdp = cap_desc_sparc;
+ break;
+ case EM_386:
+ case EM_IA_64:
+ case EM_AMD64:
+ cdp = cap_desc_386;
+ break;
+ default:
+ cdp = NULL;
+ break;
+ }
+ if (file_printf(ms, ", uses") == -1)
+ return -1;
+ if (cdp) {
+ while (cdp->cd_name) {
+ if (cap_hw1 & cdp->cd_mask) {
+ if (file_printf(ms,
+ " %s", cdp->cd_name) == -1)
+ return -1;
+ cap_hw1 &= ~cdp->cd_mask;
+ }
+ ++cdp;
+ }
+ if (cap_hw1)
+ if (file_printf(ms,
+ " unknown hardware capability 0x%llx",
+ cap_hw1) == -1)
+ return -1;
+ } else {
+ if (file_printf(ms,
+ " hardware capability 0x%llx", cap_hw1) == -1)
+ return -1;
+ }
+ }
+ if (cap_sf1) {
+ if (cap_sf1 & SF1_SUNW_FPUSED) {
+ if (file_printf(ms,
+ (cap_sf1 & SF1_SUNW_FPKNWN)
+ ? ", uses frame pointer"
+ : ", not known to use frame pointer") == -1)
+ return -1;
+ }
+ cap_sf1 &= ~SF1_SUNW_MASK;
+ if (cap_sf1)
+ if (file_printf(ms,
+ ", with unknown software capability 0x%llx",
+ cap_sf1) == -1)
+ return -1;
+ }
return 0;
}
@@ -794,8 +1008,8 @@ doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num,
* otherwise it's statically linked.
*/
private int
-dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
- int num, size_t size, off_t fsize, int *flags)
+dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
+ int num, size_t size, off_t fsize, int *flags, int sh_num)
{
Elf32_Phdr ph32;
Elf64_Phdr ph64;
@@ -814,7 +1028,7 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
if (size != xph_sizeof) {
if (file_printf(ms, ", corrupted program header size") == -1)
- return -1;
+ return -1;
return 0;
}
@@ -864,6 +1078,8 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
return -1;
align = 4;
}
+ if (sh_num)
+ break;
/*
* This is a PT_NOTE section; loop through all the notes
* in the section.
@@ -884,7 +1100,7 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
if (offset >= (size_t)bufsize)
break;
offset = donote(ms, nbuf, offset,
- (size_t)bufsize, class, swap, align,
+ (size_t)bufsize, clazz, swap, align,
flags);
if (offset == 0)
break;
@@ -913,122 +1129,60 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
int32_t l;
char c[sizeof (int32_t)];
} u;
- int class;
+ int clazz;
int swap;
struct stat st;
off_t fsize;
int flags = 0;
+ Elf32_Ehdr elf32hdr;
+ Elf64_Ehdr elf64hdr;
+ uint16_t type;
- /*
- * If we cannot seek, it must be a pipe, socket or fifo.
- */
- if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
- fd = file_pipe2file(ms, fd, buf, nbytes);
-
- if (fstat(fd, &st) == -1) {
- file_badread(ms);
- return -1;
- }
- fsize = st.st_size;
-
+ if (ms->flags & MAGIC_MIME)
+ return 0;
/*
* ELF executables have multiple section headers in arbitrary
* file locations and thus file(1) cannot determine it from easily.
* Instead we traverse thru all section headers until a symbol table
* one is found or else the binary is stripped.
+ * Return immediately if it's not ELF (so we avoid pipe2file unless needed).
*/
if (buf[EI_MAG0] != ELFMAG0
|| (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
|| buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
- return 0;
-
-
- class = buf[EI_CLASS];
-
- if (class == ELFCLASS32) {
- Elf32_Ehdr elfhdr;
- uint16_t type;
-
- if (nbytes <= sizeof (Elf32_Ehdr))
- return 0;
-
-
- u.l = 1;
- (void) memcpy(&elfhdr, buf, sizeof elfhdr);
- swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
+ return 0;
- type = getu16(swap, elfhdr.e_type);
- switch (type) {
-#ifdef ELFCORE
- case ET_CORE:
- if (dophn_core(ms, class, swap, fd,
- (off_t)getu32(swap, elfhdr.e_phoff),
- getu16(swap, elfhdr.e_phnum),
- (size_t)getu16(swap, elfhdr.e_phentsize),
- fsize, &flags) == -1)
- return -1;
- break;
-#endif
- case ET_EXEC:
- case ET_DYN:
- if (dophn_exec(ms, class, swap,
- fd, (off_t)getu32(swap, elfhdr.e_phoff),
- getu16(swap, elfhdr.e_phnum),
- (size_t)getu16(swap, elfhdr.e_phentsize),
- fsize, &flags) == -1)
- return -1;
- if (doshn(ms, class, swap, fd,
- (off_t)getu32(swap, elfhdr.e_shoff),
- getu16(swap, elfhdr.e_shnum),
- (size_t)getu16(swap, elfhdr.e_shentsize),
- &flags) == -1)
- return -1;
- break;
+ /*
+ * If we cannot seek, it must be a pipe, socket or fifo.
+ */
+ if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
+ fd = file_pipe2file(ms, fd, buf, nbytes);
- default:
- break;
- }
- return 1;
+ if (fstat(fd, &st) == -1) {
+ file_badread(ms);
+ return -1;
}
+ fsize = st.st_size;
- if (class == ELFCLASS64) {
- Elf64_Ehdr elfhdr;
- if (nbytes <= sizeof (Elf64_Ehdr))
- return 0;
-
-
- u.l = 1;
- (void) memcpy(&elfhdr, buf, sizeof elfhdr);
- swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
-
- if (getu16(swap, elfhdr.e_type) == ET_CORE) {
-#ifdef ELFCORE
- if (dophn_core(ms, class, swap, fd,
- (off_t)elf_getu64(swap, elfhdr.e_phoff),
- getu16(swap, elfhdr.e_phnum),
- (size_t)getu16(swap, elfhdr.e_phentsize),
- fsize, &flags) == -1)
- return -1;
-#else
- ;
-#endif
- } else {
- if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
- if (dophn_exec(ms, class, swap, fd,
- (off_t)elf_getu64(swap, elfhdr.e_phoff),
- getu16(swap, elfhdr.e_phnum),
- (size_t)getu16(swap, elfhdr.e_phentsize),
- fsize, &flags) == -1)
- return -1;
- }
- if (doshn(ms, class, swap, fd,
- (off_t)elf_getu64(swap, elfhdr.e_shoff),
- getu16(swap, elfhdr.e_shnum),
- (size_t)getu16(swap, elfhdr.e_shentsize), &flags)
- == -1)
- return -1;
- }
- return 1;
+ clazz = buf[EI_CLASS];
+
+ switch (clazz) {
+ case ELFCLASS32:
+#undef elf_getu
+#define elf_getu(a, b) elf_getu32(a, b)
+#undef elfhdr
+#define elfhdr elf32hdr
+#include "elfclass.h"
+ case ELFCLASS64:
+#undef elf_getu
+#define elf_getu(a, b) elf_getu64(a, b)
+#undef elfhdr
+#define elfhdr elf64hdr
+#include "elfclass.h"
+ default:
+ if (file_printf(ms, ", unknown class %d", clazz) == -1)
+ return -1;
+ break;
}
return 0;
}
diff --git a/contrib/file/readelf.h b/contrib/file/readelf.h
index 610c310..ab4b5d1 100644
--- a/contrib/file/readelf.h
+++ b/contrib/file/readelf.h
@@ -44,7 +44,7 @@ typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Word;
typedef uint8_t Elf32_Char;
-#if SIZEOF_UINT64_T != 8
+#if SIZEOF_LONG_LONG != 8
#define USE_ARRAY_FOR_64BIT_TYPES
typedef uint32_t Elf64_Addr[2];
typedef uint32_t Elf64_Off[2];
@@ -96,14 +96,24 @@ typedef struct {
} Elf64_Ehdr;
/* e_type */
+#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
+/* e_machine (used only for SunOS 5.x hardware capabilities) */
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_SPARC32PLUS 18
+#define EM_SPARCV9 43
+#define EM_IA_64 50
+#define EM_AMD64 62
+
/* sh_type */
#define SHT_SYMTAB 2
#define SHT_NOTE 7
#define SHT_DYNSYM 11
+#define SHT_SUNW_cap 0x6ffffff5 /* SunOS 5.x hw/sw capabilites */
/* elf type */
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
@@ -229,5 +239,74 @@ typedef struct {
#define GNU_OS_LINUX 0
#define GNU_OS_HURD 1
#define GNU_OS_SOLARIS 2
+#define GNU_OS_KFREEBSD 3
+#define GNU_OS_KNETBSD 4
+
+/* SunOS 5.x hardware/software capabilities */
+typedef struct {
+ Elf32_Word c_tag;
+ union {
+ Elf32_Word c_val;
+ Elf32_Addr c_ptr;
+ } c_un;
+} Elf32_Cap;
+
+typedef struct {
+ Elf64_Xword c_tag;
+ union {
+ Elf64_Xword c_val;
+ Elf64_Addr c_ptr;
+ } c_un;
+} Elf64_Cap;
+
+/* SunOS 5.x hardware/software capability tags */
+#define CA_SUNW_NULL 0
+#define CA_SUNW_HW_1 1
+#define CA_SUNW_SF_1 2
+
+/* SunOS 5.x software capabilities */
+#define SF1_SUNW_FPKNWN 0x01
+#define SF1_SUNW_FPUSED 0x02
+#define SF1_SUNW_MASK 0x03
+
+/* SunOS 5.x hardware capabilities: sparc */
+#define AV_SPARC_MUL32 0x0001
+#define AV_SPARC_DIV32 0x0002
+#define AV_SPARC_FSMULD 0x0004
+#define AV_SPARC_V8PLUS 0x0008
+#define AV_SPARC_POPC 0x0010
+#define AV_SPARC_VIS 0x0020
+#define AV_SPARC_VIS2 0x0040
+#define AV_SPARC_ASI_BLK_INIT 0x0080
+#define AV_SPARC_FMAF 0x0100
+#define AV_SPARC_FJFMAU 0x4000
+#define AV_SPARC_IMA 0x8000
+
+/* SunOS 5.x hardware capabilities: 386 */
+#define AV_386_FPU 0x00000001
+#define AV_386_TSC 0x00000002
+#define AV_386_CX8 0x00000004
+#define AV_386_SEP 0x00000008
+#define AV_386_AMD_SYSC 0x00000010
+#define AV_386_CMOV 0x00000020
+#define AV_386_MMX 0x00000040
+#define AV_386_AMD_MMX 0x00000080
+#define AV_386_AMD_3DNow 0x00000100
+#define AV_386_AMD_3DNowx 0x00000200
+#define AV_386_FXSR 0x00000400
+#define AV_386_SSE 0x00000800
+#define AV_386_SSE2 0x00001000
+#define AV_386_PAUSE 0x00002000
+#define AV_386_SSE3 0x00004000
+#define AV_386_MON 0x00008000
+#define AV_386_CX16 0x00010000
+#define AV_386_AHF 0x00020000
+#define AV_386_TSCP 0x00040000
+#define AV_386_AMD_SSE4A 0x00080000
+#define AV_386_POPCNT 0x00100000
+#define AV_386_AMD_LZCNT 0x00200000
+#define AV_386_SSSE3 0x00400000
+#define AV_386_SSE4_1 0x00800000
+#define AV_386_SSE4_2 0x01000000
#endif
diff --git a/contrib/file/softmagic.c b/contrib/file/softmagic.c
index 21a0148..39a7fc8 100644
--- a/contrib/file/softmagic.c
+++ b/contrib/file/softmagic.c
@@ -38,11 +38,11 @@
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.103 2007/12/27 16:35:59 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.120 2008/07/28 17:25:21 christos Exp $")
#endif /* lint */
private int match(struct magic_set *, struct magic *, uint32_t,
- const unsigned char *, size_t);
+ const unsigned char *, size_t, int);
private int mget(struct magic_set *, const unsigned char *,
struct magic *, size_t, unsigned int);
private int magiccheck(struct magic_set *, struct magic *);
@@ -58,17 +58,23 @@ private void cvt_32(union VALUETYPE *, const struct magic *);
private void cvt_64(union VALUETYPE *, const struct magic *);
/*
+ * Macro to give description string according to whether we want plain
+ * text or MIME type
+ */
+#define MAGIC_DESC ((ms->flags & MAGIC_MIME) ? m->mimetype : m->desc)
+
+/*
* softmagic - lookup one file in parsed, in-memory copy of database
* Passed the name and FILE * of one file to be typed.
*/
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
protected int
-file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
+file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, int mode)
{
struct mlist *ml;
int rv;
for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
- if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes)) != 0)
+ if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode)) != 0)
return rv;
return 0;
@@ -103,7 +109,7 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
*/
private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
- const unsigned char *s, size_t nbytes)
+ const unsigned char *s, size_t nbytes, int mode)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
@@ -117,17 +123,26 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
for (magindex = 0; magindex < nmagic; magindex++) {
int flush;
+ struct magic *m = &magic[magindex];
- ms->offset = magic[magindex].offset;
- ms->line = magic[magindex].lineno;
+ if ((m->flag & BINTEST) != mode) {
+ /* Skip sub-tests */
+ while (magic[magindex + 1].cont_level != 0 &&
+ ++magindex < nmagic)
+ continue;
+ continue; /* Skip to next top-level test*/
+ }
+
+ ms->offset = m->offset;
+ ms->line = m->lineno;
/* if main entry matches, print it... */
- flush = !mget(ms, s, &magic[magindex], nbytes, cont_level);
+ flush = !mget(ms, s, m, nbytes, cont_level);
if (flush) {
- if (magic[magindex].reln == '!')
+ if (m->reln == '!')
flush = 0;
} else {
- switch (magiccheck(ms, &magic[magindex])) {
+ switch (magiccheck(ms, m)) {
case -1:
return -1;
case 0:
@@ -152,15 +167,14 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* If we are going to print something, we'll need to print
* a blank before we print something else.
*/
- if (magic[magindex].desc[0]) {
+ if (*MAGIC_DESC) {
need_separator = 1;
printed_something = 1;
if (print_sep(ms, firstline) == -1)
return -1;
}
- if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex]))
- == -1)
+ if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1)
return -1;
/* and any continuations that match */
@@ -169,36 +183,36 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
while (magic[magindex+1].cont_level != 0 &&
++magindex < nmagic) {
- ms->line = magic[magindex].lineno; /* for messages */
+ m = &magic[magindex];
+ ms->line = m->lineno; /* for messages */
- if (cont_level < magic[magindex].cont_level)
+ if (cont_level < m->cont_level)
continue;
- if (cont_level > magic[magindex].cont_level) {
+ if (cont_level > m->cont_level) {
/*
* We're at the end of the level
* "cont_level" continuations.
*/
- cont_level = magic[magindex].cont_level;
+ cont_level = m->cont_level;
}
- ms->offset = magic[magindex].offset;
- if (magic[magindex].flag & OFFADD) {
+ ms->offset = m->offset;
+ if (m->flag & OFFADD) {
ms->offset +=
ms->c.li[cont_level - 1].off;
}
#ifdef ENABLE_CONDITIONALS
- if (magic[magindex].cond == COND_ELSE ||
- magic[magindex].cond == COND_ELIF) {
+ if (m->cond == COND_ELSE ||
+ m->cond == COND_ELIF) {
if (ms->c.li[cont_level].last_match == 1)
continue;
}
#endif
- flush = !mget(ms, s, &magic[magindex], nbytes,
- cont_level);
- if (flush && magic[magindex].reln != '!')
+ flush = !mget(ms, s, m, nbytes, cont_level);
+ if (flush && m->reln != '!')
continue;
- switch (flush ? 1 : magiccheck(ms, &magic[magindex])) {
+ switch (flush ? 1 : magiccheck(ms, m)) {
case -1:
return -1;
case 0:
@@ -210,7 +224,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
#ifdef ENABLE_CONDITIONALS
ms->c.li[cont_level].last_match = 1;
#endif
- if (magic[magindex].type != FILE_DEFAULT)
+ if (m->type != FILE_DEFAULT)
ms->c.li[cont_level].got_match = 1;
else if (ms->c.li[cont_level].got_match) {
ms->c.li[cont_level].got_match = 0;
@@ -220,7 +234,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* If we are going to print something,
* make sure that we have a separator first.
*/
- if (magic[magindex].desc[0]) {
+ if (*MAGIC_DESC) {
printed_something = 1;
if (print_sep(ms, firstline) == -1)
return -1;
@@ -233,15 +247,15 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
*/
/* space if previous printed */
if (need_separator
- && (magic[magindex].nospflag == 0)
- && (magic[magindex].desc[0] != '\0')) {
+ && ((m->flag & NOSPACE) == 0)
+ && *MAGIC_DESC) {
if (file_printf(ms, " ") == -1)
return -1;
need_separator = 0;
}
- if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) == -1)
+ if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1)
return -1;
- if (magic[magindex].desc[0])
+ if (*MAGIC_DESC)
need_separator = 1;
/*
@@ -271,7 +285,7 @@ check_fmt(struct magic_set *ms, struct magic *m)
regex_t rx;
int rc;
- if (strchr(m->desc, '%') == NULL)
+ if (strchr(MAGIC_DESC, '%') == NULL)
return 0;
rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
@@ -281,7 +295,7 @@ check_fmt(struct magic_set *ms, struct magic *m)
file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
return -1;
} else {
- rc = regexec(&rx, m->desc, 0, 0, 0);
+ rc = regexec(&rx, MAGIC_DESC, 0, 0, 0);
regfree(&rx);
return !rc;
}
@@ -314,7 +328,7 @@ mprint(struct magic_set *ms, struct magic *m)
float vf;
double vd;
int64_t t = 0;
- char buf[512];
+ char *buf;
union VALUETYPE *p = &ms->ms_value;
switch (m->type) {
@@ -324,14 +338,13 @@ mprint(struct magic_set *ms, struct magic *m)
case -1:
return -1;
case 1:
- if (snprintf(buf, sizeof(buf), "%c",
- (unsigned char)v) < 0)
+ if (asprintf(&buf, "%c", (unsigned char)v) < 0)
return -1;
- if (file_printf(ms, m->desc, buf) == -1)
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, m->desc, (unsigned char) v) == -1)
+ if (file_printf(ms, MAGIC_DESC, (unsigned char) v) == -1)
return -1;
break;
}
@@ -346,14 +359,13 @@ mprint(struct magic_set *ms, struct magic *m)
case -1:
return -1;
case 1:
- if (snprintf(buf, sizeof(buf), "%hu",
- (unsigned short)v) < 0)
+ if (asprintf(&buf, "%hu", (unsigned short)v) < 0)
return -1;
- if (file_printf(ms, m->desc, buf) == -1)
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, m->desc, (unsigned short) v) == -1)
+ if (file_printf(ms, MAGIC_DESC, (unsigned short) v) == -1)
return -1;
break;
}
@@ -369,13 +381,13 @@ mprint(struct magic_set *ms, struct magic *m)
case -1:
return -1;
case 1:
- if (snprintf(buf, sizeof(buf), "%u", (uint32_t)v) < 0)
+ if (asprintf(&buf, "%u", (uint32_t)v) < 0)
return -1;
- if (file_printf(ms, m->desc, buf) == -1)
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, m->desc, (uint32_t) v) == -1)
+ if (file_printf(ms, MAGIC_DESC, (uint32_t) v) == -1)
return -1;
break;
}
@@ -386,7 +398,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQUAD:
case FILE_LEQUAD:
v = file_signextend(ms, m, p->q);
- if (file_printf(ms, m->desc, (uint64_t) v) == -1)
+ if (file_printf(ms, MAGIC_DESC, (uint64_t) v) == -1)
return -1;
t = ms->offset + sizeof(int64_t);
break;
@@ -396,16 +408,18 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BESTRING16:
case FILE_LESTRING16:
if (m->reln == '=' || m->reln == '!') {
- if (file_printf(ms, m->desc, m->value.s) == -1)
+ if (file_printf(ms, MAGIC_DESC, m->value.s) == -1)
return -1;
t = ms->offset + m->vallen;
}
else {
if (*m->value.s == '\0')
p->s[strcspn(p->s, "\n")] = '\0';
- if (file_printf(ms, m->desc, p->s) == -1)
+ if (file_printf(ms, MAGIC_DESC, p->s) == -1)
return -1;
t = ms->offset + strlen(p->s);
+ if (m->type == FILE_PSTRING)
+ t++;
}
break;
@@ -413,7 +427,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEDATE:
case FILE_LEDATE:
case FILE_MEDATE:
- if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1)
+ if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 1)) == -1)
return -1;
t = ms->offset + sizeof(time_t);
break;
@@ -422,7 +436,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BELDATE:
case FILE_LELDATE:
case FILE_MELDATE:
- if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1)
+ if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 0)) == -1)
return -1;
t = ms->offset + sizeof(time_t);
break;
@@ -430,7 +444,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_QDATE:
case FILE_BEQDATE:
case FILE_LEQDATE:
- if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 1))
+ if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 1))
== -1)
return -1;
t = ms->offset + sizeof(uint64_t);
@@ -439,7 +453,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_QLDATE:
case FILE_BEQLDATE:
case FILE_LEQLDATE:
- if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 0))
+ if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 0))
== -1)
return -1;
t = ms->offset + sizeof(uint64_t);
@@ -453,13 +467,13 @@ mprint(struct magic_set *ms, struct magic *m)
case -1:
return -1;
case 1:
- if (snprintf(buf, sizeof(buf), "%g", vf) < 0)
+ if (asprintf(&buf, "%g", vf) < 0)
return -1;
- if (file_printf(ms, m->desc, buf) == -1)
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, m->desc, vf) == -1)
+ if (file_printf(ms, MAGIC_DESC, vf) == -1)
return -1;
break;
}
@@ -474,13 +488,13 @@ mprint(struct magic_set *ms, struct magic *m)
case -1:
return -1;
case 1:
- if (snprintf(buf, sizeof(buf), "%g", vd) < 0)
+ if (asprintf(&buf, "%g", vd) < 0)
return -1;
- if (file_printf(ms, m->desc, buf) == -1)
+ if (file_printf(ms, MAGIC_DESC, buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, m->desc, vd) == -1)
+ if (file_printf(ms, MAGIC_DESC, vd) == -1)
return -1;
break;
}
@@ -496,7 +510,7 @@ mprint(struct magic_set *ms, struct magic *m)
file_oomem(ms, ms->search.rm_len);
return -1;
}
- rval = file_printf(ms, m->desc, cp);
+ rval = file_printf(ms, MAGIC_DESC, cp);
free(cp);
if (rval == -1)
@@ -510,7 +524,7 @@ mprint(struct magic_set *ms, struct magic *m)
}
case FILE_SEARCH:
- if (file_printf(ms, m->desc, m->value.s) == -1)
+ if (file_printf(ms, MAGIC_DESC, m->value.s) == -1)
return -1;
if ((m->str_flags & REGEX_OFFSET_START))
t = ms->search.offset;
@@ -519,7 +533,7 @@ mprint(struct magic_set *ms, struct magic *m)
break;
case FILE_DEFAULT:
- if (file_printf(ms, m->desc, m->value.s) == -1)
+ if (file_printf(ms, MAGIC_DESC, m->value.s) == -1)
return -1;
t = ms->offset;
break;
@@ -646,13 +660,14 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_STRING:
case FILE_BESTRING16:
case FILE_LESTRING16: {
- size_t len;
-
/* Null terminate and eat *trailing* return */
p->s[sizeof(p->s) - 1] = '\0';
+#if 0
+ /* Why? breaks magic numbers that end with \xa */
len = strlen(p->s);
if (len-- && p->s[len] == '\n')
p->s[len] = '\0';
+#endif
return 1;
}
case FILE_PSTRING: {
@@ -663,9 +678,12 @@ mconvert(struct magic_set *ms, struct magic *m)
while (len--)
*ptr1++ = *ptr2++;
*ptr1 = '\0';
+#if 0
+ /* Why? breaks magic numbers that end with \xa */
len = strlen(p->s);
if (len-- && p->s[len] == '\n')
p->s[len] = '\0';
+#endif
return 1;
}
case FILE_BESHORT:
@@ -682,10 +700,11 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_BEQUAD:
case FILE_BEQDATE:
case FILE_BEQLDATE:
- p->q = (int64_t)
- (((int64_t)p->hq[0]<<56)|((int64_t)p->hq[1]<<48)|
- ((int64_t)p->hq[2]<<40)|((int64_t)p->hq[3]<<32)|
- (p->hq[4]<<24)|(p->hq[5]<<16)|(p->hq[6]<<8)|(p->hq[7]));
+ p->q = (uint64_t)
+ (((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
+ ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
+ ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
+ ((uint64_t)p->hq[6]<<8)|((uint64_t)p->hq[7]));
cvt_64(p, m);
return 1;
case FILE_LESHORT:
@@ -702,10 +721,11 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_LEQUAD:
case FILE_LEQDATE:
case FILE_LEQLDATE:
- p->q = (int64_t)
- (((int64_t)p->hq[7]<<56)|((int64_t)p->hq[6]<<48)|
- ((int64_t)p->hq[5]<<40)|((int64_t)p->hq[4]<<32)|
- (p->hq[3]<<24)|(p->hq[2]<<16)|(p->hq[1]<<8)|(p->hq[0]));
+ p->q = (uint64_t)
+ (((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
+ ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
+ ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
+ ((uint64_t)p->hq[1]<<8)|((uint64_t)p->hq[0]));
cvt_64(p, m);
return 1;
case FILE_MELONG:
@@ -778,13 +798,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
case FILE_SEARCH:
ms->search.s = (const char *)s + offset;
ms->search.s_len = nbytes - offset;
+ ms->search.offset = offset;
return 0;
case FILE_REGEX: {
- /*
- * offset is interpreted as last line to search,
- * (starting at 1), not as bytes-from start-of-file
- */
const char *b;
const char *c;
const char *last; /* end of search region */
@@ -879,7 +896,7 @@ mget(struct magic_set *ms, const unsigned char *s,
struct magic *m, size_t nbytes, unsigned int cont_level)
{
uint32_t offset = ms->offset;
- uint32_t count = m->str_count;
+ uint32_t count = m->str_range;
union VALUETYPE *p = &ms->ms_value;
if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
@@ -893,8 +910,8 @@ mget(struct magic_set *ms, const unsigned char *s,
if (m->flag & INDIR) {
int off = m->in_offset;
if (m->in_op & FILE_OPINDIRECT) {
- const union VALUETYPE *q =
- ((const void *)(s + offset + off));
+ const union VALUETYPE *q = CAST(const union VALUETYPE *,
+ ((const void *)(s + offset + off)));
switch (m->in_type) {
case FILE_BYTE:
off = q->b;
@@ -1340,13 +1357,6 @@ mget(struct magic_set *ms, const unsigned char *s,
case FILE_OPMODULO:
offset = p->l % off;
break;
- /* case TOOMANYSWITCHBLOCKS:
- * ugh = p->eye % m->strain;
- * rub;
- * case BEER:
- * off = p->tab & m->in_gest;
- * sleep;
- */
}
} else
offset = p->l;
@@ -1443,10 +1453,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
uint64_t v;
/*
- * What we want here is:
- * v = strncmp(m->value.s, p->s, m->vallen);
- * but ignoring any nulls. bcmp doesn't give -/+/0
- * and isn't universally available anyway.
+ * What we want here is v = strncmp(s1, s2, len),
+ * but ignoring any nulls.
*/
v = 0;
if (0L == flags) { /* normal string: do it fast */
@@ -1646,15 +1654,14 @@ magiccheck(struct magic_set *ms, struct magic *m)
slen = MIN(m->vallen, sizeof(m->value.s));
l = 0;
v = 0;
- ms->search.offset = m->offset;
- for (idx = 0; m->str_count == 0 || idx < m->str_count; idx++) {
+ for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
if (slen + idx > ms->search.s_len)
break;
v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags);
if (v == 0) { /* found match */
- ms->search.offset = m->offset + idx;
+ ms->search.offset += idx;
break;
}
}
diff --git a/contrib/file/tar.h b/contrib/file/tar.h
index 30d386b..fa2390a 100644
--- a/contrib/file/tar.h
+++ b/contrib/file/tar.h
@@ -32,20 +32,10 @@
*
* Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
*
- * $File: tar.h,v 1.11 2007/01/16 14:56:45 ljt Exp $ # checkin only
+ * $File: tar.h,v 1.12 2008/02/07 00:58:52 christos Exp $ # checkin only
*/
/*
- * Kludge for handling systems that cannot cope with multiple
- * external definitions of a variable. In ONE routine (tar.c),
- * we #define TAR_EXTERN to null; here, we set it to "extern" if
- * it is not already set.
- */
-#ifndef TAR_EXTERN
-#define TAR_EXTERN extern
-#endif
-
-/*
* Header block on tape.
*
* I'm going to use traditional DP naming conventions here.
@@ -78,58 +68,6 @@ union record {
} header;
};
-/* The checksum field is filled with this while the checksum is computed. */
-#define CHKBLANKS " " /* 8 blanks, no null */
-
/* The magic field is filled with this if uname and gname are valid. */
#define TMAGIC "ustar" /* 5 chars and a null */
#define GNUTMAGIC "ustar " /* 7 chars and a null */
-
-/* The linkflag defines the type of file */
-#define LF_OLDNORMAL '\0' /* Normal disk file, Unix compat */
-#define LF_NORMAL '0' /* Normal disk file */
-#define LF_LINK '1' /* Link to previously dumped file */
-#define LF_SYMLINK '2' /* Symbolic link */
-#define LF_CHR '3' /* Character special file */
-#define LF_BLK '4' /* Block special file */
-#define LF_DIR '5' /* Directory */
-#define LF_FIFO '6' /* FIFO special file */
-#define LF_CONTIG '7' /* Contiguous file */
-/* Further link types may be defined later. */
-
-/*
- * Exit codes from the "tar" program
- */
-#define EX_SUCCESS 0 /* success! */
-#define EX_ARGSBAD 1 /* invalid args */
-#define EX_BADFILE 2 /* invalid filename */
-#define EX_BADARCH 3 /* bad archive */
-#define EX_SYSTEM 4 /* system gave unexpected error */
-
-/*
- * Structure for keeping track of filenames and lists thereof.
- */
-struct name {
- struct name *next;
- short length;
- char found;
- char name[NAMSIZ+1];
-};
-
-/*
- *
- * Due to the next struct declaration, each routine that includes
- * "tar.h" must also include <sys/types.h>. I tried to make it automatic,
- * but System V has no defines in <sys/types.h>, so there is no way of
- * knowing when it has been included. In addition, it cannot be included
- * twice, but must be included exactly once. Argghh!
- *
- * Thanks, typedef. Thanks, USG.
- */
-struct link {
- struct link *next;
- dev_t dev;
- ino_t ino;
- short linkcount;
- char name[NAMSIZ+1];
-};
diff --git a/contrib/file/tests/Makefile.am b/contrib/file/tests/Makefile.am
new file mode 100644
index 0000000..3e0a2e6
--- /dev/null
+++ b/contrib/file/tests/Makefile.am
@@ -0,0 +1,11 @@
+check_PROGRAMS = test
+test_LDADD = $(top_builddir)/src/libmagic.la
+test_CPPFLAGS = -I$(top_builddir)/src
+
+EXTRA_DIST = \
+ gedcom.magic gedcom.testfile gedcom.result
+
+T = $(top_srcdir)/tests
+check-local:
+ MAGIC=$(top_builddir)/magic/magic ./test
+ for i in $T/*.testfile; do MAGIC=$T/$${i%%.testfile}.magic $(top_builddir)/tests/test $T/$$i $T/$${i%%.testfile}.result; done
diff --git a/contrib/file/tests/Makefile.in b/contrib/file/tests/Makefile.in
new file mode 100644
index 0000000..5d9de02
--- /dev/null
+++ b/contrib/file/tests/Makefile.in
@@ -0,0 +1,455 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program 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.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = test$(EXEEXT)
+subdir = tests
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+test_SOURCES = test.c
+test_OBJECTS = test-test.$(OBJEXT)
+test_DEPENDENCIES = $(top_builddir)/src/libmagic.la
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = test.c
+DIST_SOURCES = test.c
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WARNINGS = @WARNINGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fsect = @fsect@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+test_LDADD = $(top_builddir)/src/libmagic.la
+test_CPPFLAGS = -I$(top_builddir)/src
+EXTRA_DIST = \
+ gedcom.magic gedcom.testfile gedcom.result
+
+T = $(top_srcdir)/tests
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES)
+ @rm -f test$(EXEEXT)
+ $(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+test-test.o: test.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF $(DEPDIR)/test-test.Tpo -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test-test.Tpo $(DEPDIR)/test-test.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c
+
+test-test.obj: test.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF $(DEPDIR)/test-test.Tpo -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test-test.Tpo $(DEPDIR)/test-test.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+check-local:
+ MAGIC=$(top_builddir)/magic/magic ./test
+ for i in $T/*.testfile; do MAGIC=$T/$${i%%.testfile}.magic $(top_builddir)/tests/test $T/$$i $T/$${i%%.testfile}.result; done
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/file/tests/README b/contrib/file/tests/README
new file mode 100644
index 0000000..31f9b14
--- /dev/null
+++ b/contrib/file/tests/README
@@ -0,0 +1,17 @@
+file tests
+==========
+
+This directory contains tests for file. It is highly encouraged to add
+one each time a bug is found, and each time new magic is added. Each
+test consists of three files:
+
+ TEST.magic
+ TEST.testfile
+ TEST.result
+
+where TEST is the base name of the test, TEST.magic contains the magic
+used, TEST.testfile is the input, and TEST.result is the desired
+output from file.
+
+It suffices to add a triplet of test files to the directory to have
+them included in "make check".
diff --git a/contrib/file/tests/gedcom.magic b/contrib/file/tests/gedcom.magic
new file mode 100644
index 0000000..616fd56
--- /dev/null
+++ b/contrib/file/tests/gedcom.magic
@@ -0,0 +1,6 @@
+# GEDCOM Genealogy file
+
+0 string/c 0\ HEAD GEDCOM genealogy data
+>&0 search 1\ GEDC
+>>&0 search 2\ VERS version
+>>>&1 string >\0 %s
diff --git a/contrib/file/tests/gedcom.result b/contrib/file/tests/gedcom.result
new file mode 100644
index 0000000..bbb0eb8
--- /dev/null
+++ b/contrib/file/tests/gedcom.result
@@ -0,0 +1 @@
+GEDCOM genealogy data version 5.5 \ No newline at end of file
diff --git a/contrib/file/tests/gedcom.testfile b/contrib/file/tests/gedcom.testfile
new file mode 100644
index 0000000..3d9607e
--- /dev/null
+++ b/contrib/file/tests/gedcom.testfile
@@ -0,0 +1,8 @@
+0 HEAD
+1 SOUR GENJ
+2 VERS 2.x
+1 GEDC
+2 VERS 5.5
+2 FORM Lineage-Linked
+1 CHAR UNICODE
+1 LANG Italian
diff --git a/contrib/file/tests/test.c b/contrib/file/tests/test.c
new file mode 100644
index 0000000..db91c62
--- /dev/null
+++ b/contrib/file/tests/test.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * 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 immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "magic.h"
+
+static void *
+xrealloc(void *p, size_t n)
+{
+ p = realloc(p, n);
+ if (p == NULL) {
+ (void)fprintf(stderr, "ERROR slurping file: out of memory\n");
+ exit(10);
+ }
+ return p;
+}
+
+static char *
+slurp(FILE *fp, size_t *final_len)
+{
+ size_t len = 256;
+ int c;
+ char *l = (char *)xrealloc(NULL, len), *s = l;
+
+ for (c = getc(fp); c != EOF; c = getc(fp)) {
+ if (s == l + len) {
+ l = (char *)xrealloc(l, len * 2);
+ len *= 2;
+ }
+ *s++ = c;
+ }
+ if (s == l + len)
+ l = (char *)xrealloc(l, len + 1);
+ *s++ = '\0';
+
+ *final_len = s - l;
+ l = (char *)xrealloc(l, s - l);
+ return l;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct magic_set *ms;
+ const char *result;
+ char *desired;
+ size_t desired_len;
+ int i;
+ FILE *fp;
+
+ ms = magic_open(MAGIC_NONE);
+ if (ms == NULL) {
+ (void)fprintf(stderr, "ERROR opening MAGIC_NONE: out of memory\n");
+ return 10;
+ }
+ if (magic_load(ms, NULL) == -1) {
+ (void)fprintf(stderr, "ERROR loading with NULL file: %s\n", magic_error(ms));
+ return 11;
+ }
+
+ if (argc > 1) {
+ if (argc != 3) {
+ (void)fprintf(stderr, "Usage: test TEST-FILE RESULT\n");
+ } else {
+ if ((result = magic_file(ms, argv[1])) == NULL) {
+ (void)fprintf(stderr, "ERROR loading file %s: %s\n", argv[1], magic_error(ms));
+ return 12;
+ } else {
+ fp = fopen(argv[2], "r");
+ if (fp == NULL) {
+ (void)fprintf(stderr, "ERROR opening `%s': ", argv[2]);
+ perror(NULL);
+ return 13;
+ }
+ desired = slurp(fp, &desired_len);
+ fclose(fp);
+ (void)printf("%s: %s\n", argv[1], result);
+ if (strcmp(result, desired) != 0) {
+ (void)fprintf(stderr, "Error: result was\n%s\nexpected:\n%s\n", result, desired);
+ return 1;
+ }
+ }
+ }
+ }
+
+ magic_close(ms);
+ return 0;
+}
diff --git a/contrib/file/vasprintf.c b/contrib/file/vasprintf.c
new file mode 100644
index 0000000..0289c0d
--- /dev/null
+++ b/contrib/file/vasprintf.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * 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 immediately at the beginning of the file, without modification,
+ * 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.
+ */
+/*###########################################################################
+ # #
+ # vasprintf #
+ # #
+ # Copyright (c) 2002-2005 David TAILLANDIER #
+ # #
+ ###########################################################################*/
+
+/*
+
+This software is distributed under the "modified BSD licence".
+
+This software is also released with GNU license (GPL) in another file (same
+source-code, only license differ).
+
+
+
+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. 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.
+
+====================
+
+Hacked from xnprintf version of 26th February 2005 to provide only
+vasprintf by Reuben Thomas <rrt@sc3d.org>.
+
+====================
+
+
+'printf' function family use the following format string:
+
+%[flag][width][.prec][modifier]type
+
+%% is the escape sequence to print a '%'
+% followed by an unknown format will print the characters without
+trying to do any interpretation
+
+flag: none + - # (blank)
+width: n 0n *
+prec: none .0 .n .*
+modifier: F N L h l ll ('F' and 'N' are ms-dos/16-bit specific)
+type: d i o u x X f e g E G c s p n
+
+
+The function needs to allocate memory to store the full text before to
+actually writting it. i.e if you want to fnprintf() 1000 characters, the
+functions will allocate 1000 bytes.
+This behaviour can be modified: you have to customise the code to flush the
+internal buffer (writing to screen or file) when it reach a given size. Then
+the buffer can have a shorter length. But what? If you really need to write
+HUGE string, don't use printf!
+During the process, some other memory is allocated (1024 bytes minimum)
+to handle the output of partial sprintf() calls. If you have only 10000 bytes
+free in memory, you *may* not be able to nprintf() a 8000 bytes-long text.
+
+note: if a buffer overflow occurs, exit() is called. This situation should
+never appear ... but if you want to be *really* sure, you have to modify the
+code to handle those situations (only one place to modify).
+A buffer overflow can only occur if your sprintf() do strange things or when
+you use strange formats.
+
+*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#define ALLOC_CHUNK 2048
+#define ALLOC_SECURITY_MARGIN 1024 /* big value because some platforms have very big 'G' exponent */
+#if ALLOC_CHUNK < ALLOC_SECURITY_MARGIN
+# error !!! ALLOC_CHUNK < ALLOC_SECURITY_MARGIN !!!
+#endif
+/* note: to have some interest, ALLOC_CHUNK should be much greater than ALLOC_SECURITY_MARGIN */
+
+/*
+ * To save a lot of push/pop, every variable are stored into this
+ * structure, which is passed among nearly every sub-functions.
+ */
+typedef struct {
+ const char * src_string; /* current position into intput string */
+ char * buffer_base; /* output buffer */
+ char * dest_string; /* current position into output string */
+ size_t buffer_len; /* length of output buffer */
+ size_t real_len; /* real current length of output text */
+ size_t pseudo_len; /* total length of output text if it were not limited in size */
+ size_t maxlen;
+ va_list vargs; /* pointer to current position into vargs */
+ char * sprintf_string;
+ FILE * fprintf_file;
+} xprintf_struct;
+
+/*
+ * Realloc buffer if needed
+ * Return value: 0 = ok
+ * EOF = not enought memory
+ */
+static int realloc_buff(xprintf_struct *s, size_t len)
+{
+ char * ptr;
+
+ if (len + ALLOC_SECURITY_MARGIN + s->real_len > s->buffer_len) {
+ len += s->real_len + ALLOC_CHUNK;
+ ptr = (char *)realloc((void *)(s->buffer_base), len);
+ if (ptr == NULL) {
+ s->buffer_base = NULL;
+ return EOF;
+ }
+
+ s->dest_string = ptr + (size_t)(s->dest_string - s->buffer_base);
+ s->buffer_base = ptr;
+ s->buffer_len = len;
+
+ (s->buffer_base)[s->buffer_len - 1] = 1; /* overflow marker */
+ }
+
+ return 0;
+}
+
+/*
+ * Prints 'usual' characters up to next '%'
+ * or up to end of text
+ */
+static int usual_char(xprintf_struct * s)
+{
+ size_t len;
+
+ len = strcspn(s->src_string, "%"); /* reachs the next '%' or end of input string */
+ /* note: 'len' is never 0 because the presence of '%' */
+ /* or end-of-line is checked in the calling function */
+
+ if (realloc_buff(s,len) == EOF)
+ return EOF;
+
+ memcpy(s->dest_string, s->src_string, len);
+ s->src_string += len;
+ s->dest_string += len;
+ s->real_len += len;
+ s->pseudo_len += len;
+
+ return 0;
+}
+
+/*
+ * Return value: 0 = ok
+ * EOF = error
+ */
+static int print_it(xprintf_struct *s, size_t approx_len,
+ const char *format_string, ...)
+{
+ va_list varg;
+ int vsprintf_len;
+ size_t len;
+
+ if (realloc_buff(s,approx_len) == EOF)
+ return EOF;
+
+ va_start(varg, format_string);
+ vsprintf_len = vsprintf(s->dest_string, format_string, varg);
+ va_end(varg);
+
+ /* Check for overflow */
+ assert((s->buffer_base)[s->buffer_len - 1] == 1);
+
+ if (vsprintf_len == EOF) /* must be done *after* overflow-check */
+ return EOF;
+
+ s->pseudo_len += vsprintf_len;
+ len = strlen(s->dest_string);
+ s->real_len += len;
+ s->dest_string += len;
+
+ return 0;
+}
+
+/*
+ * Prints a string (%s)
+ * We need special handling because:
+ * a: the length of the string is unknown
+ * b: when .prec is used, we must not access any extra byte of the
+ * string (of course, if the original sprintf() does... what the
+ * hell, not my problem)
+ *
+ * Return value: 0 = ok
+ * EOF = error
+ */
+static int type_s(xprintf_struct *s, int width, int prec,
+ const char *format_string, const char *arg_string)
+{
+ size_t string_len;
+
+ if (arg_string == NULL)
+ return print_it(s, (size_t)6, "(null)", 0);
+
+ /* hand-made strlen() whitch stops when 'prec' is reached. */
+ /* if 'prec' is -1 then it is never reached. */
+ string_len = 0;
+ while (arg_string[string_len] != 0 && (size_t)prec != string_len)
+ string_len++;
+
+ if (width != -1 && string_len < (size_t)width)
+ string_len = (size_t)width;
+
+ return print_it(s, string_len, format_string, arg_string);
+}
+
+/*
+ * Read a serie of digits. Stop when non-digit is found.
+ * Return value: the value read (between 0 and 32767).
+ * Note: no checks are made against overflow. If the string contain a big
+ * number, then the return value won't be what we want (but, in this case,
+ * the programmer don't know whatr he wants, then no problem).
+ */
+static int getint(const char **string)
+{
+ int i = 0;
+
+ while (isdigit((unsigned char)**string) != 0) {
+ i = i * 10 + (**string - '0');
+ (*string)++;
+ }
+
+ if (i < 0 || i > 32767)
+ i = 32767; /* if we have i==-10 this is not because the number is */
+ /* negative; this is because the number is big */
+ return i;
+}
+
+/*
+ * Read a part of the format string. A part is 'usual characters' (ie "blabla")
+ * or '%%' escape sequence (to print a single '%') or any combination of
+ * format specifier (ie "%i" or "%10.2d").
+ * After the current part is managed, the function returns to caller with
+ * everything ready to manage the following part.
+ * The caller must ensure than the string is not empty, i.e. the first byte
+ * is not zero.
+ *
+ * Return value: 0 = ok
+ * EOF = error
+ */
+static int dispatch(xprintf_struct *s)
+{
+ const char *initial_ptr;
+ char format_string[24]; /* max length may be something like "% +-#032768.32768Ld" */
+ char *format_ptr;
+ int flag_plus, flag_minus, flag_space, flag_sharp, flag_zero;
+ int width, prec, modifier, approx_width;
+ char type;
+ /* most of those variables are here to rewrite the format string */
+
+#define SRCTXT (s->src_string)
+#define DESTTXT (s->dest_string)
+
+ /* incoherent format string. Characters after the '%' will be printed with the next call */
+#define INCOHERENT() do {SRCTXT=initial_ptr; return 0;} while (0) /* do/while to avoid */
+#define INCOHERENT_TEST() do {if(*SRCTXT==0) INCOHERENT();} while (0) /* a null statement */
+
+ /* 'normal' text */
+ if (*SRCTXT != '%')
+ return usual_char(s);
+
+ /* we then have a '%' */
+ SRCTXT++;
+ /* don't check for end-of-string ; this is done later */
+
+ /* '%%' escape sequence */
+ if (*SRCTXT == '%') {
+ if (realloc_buff(s, (size_t)1) == EOF) /* because we can have "%%%%%%%%..." */
+ return EOF;
+ *DESTTXT = '%';
+ DESTTXT++;
+ SRCTXT++;
+ (s->real_len)++;
+ (s->pseudo_len)++;
+ return 0;
+ }
+
+ /* '%' managing */
+ initial_ptr = SRCTXT; /* save current pointer in case of incorrect */
+ /* 'decoding'. Points just after the '%' so the '%' */
+ /* won't be printed in any case, as required. */
+
+ /* flag */
+ flag_plus = flag_minus = flag_space = flag_sharp = flag_zero = 0;
+
+ for (;; SRCTXT++) {
+ if (*SRCTXT == ' ')
+ flag_space = 1;
+ else if (*SRCTXT == '+')
+ flag_plus = 1;
+ else if (*SRCTXT == '-')
+ flag_minus = 1;
+ else if (*SRCTXT == '#')
+ flag_sharp = 1;
+ else if (*SRCTXT == '0')
+ flag_zero = 1;
+ else
+ break;
+ }
+
+ INCOHERENT_TEST(); /* here is the first test for end of string */
+
+ /* width */
+ if (*SRCTXT == '*') { /* width given by next argument */
+ SRCTXT++;
+ width = va_arg(s->vargs, int);
+ if ((size_t)width > 0x3fffU) /* 'size_t' to check against negative values too */
+ width = 0x3fff;
+ } else if (isdigit((unsigned char)*SRCTXT)) /* width given as ASCII number */
+ width = getint(&SRCTXT);
+ else
+ width = -1; /* no width specified */
+
+ INCOHERENT_TEST();
+
+ /* .prec */
+ if (*SRCTXT == '.') {
+ SRCTXT++;
+ if (*SRCTXT == '*') { /* .prec given by next argument */
+ SRCTXT++;
+ prec = va_arg(s->vargs, int);
+ if ((size_t)prec >= 0x3fffU) /* 'size_t' to check against negative values too */
+ prec = 0x3fff;
+ } else { /* .prec given as ASCII number */
+ if (isdigit((unsigned char)*SRCTXT) == 0)
+ INCOHERENT();
+ prec = getint(&SRCTXT);
+ }
+ INCOHERENT_TEST();
+ } else
+ prec = -1; /* no .prec specified */
+
+ /* modifier */
+ if (*SRCTXT == 'L' || *SRCTXT == 'h' || *SRCTXT == 'l') {
+ modifier = *SRCTXT;
+ SRCTXT++;
+ if (modifier=='l' && *SRCTXT=='l') {
+ SRCTXT++;
+ modifier = 'L'; /* 'll' == 'L' long long == long double */
+ } /* only for compatibility ; not portable */
+ INCOHERENT_TEST();
+ } else
+ modifier = -1; /* no modifier specified */
+
+ /* type */
+ type = *SRCTXT;
+ if (strchr("diouxXfegEGcspn",type) == NULL)
+ INCOHERENT(); /* unknown type */
+ SRCTXT++;
+
+ /* rewrite format-string */
+ format_string[0] = '%';
+ format_ptr = &(format_string[1]);
+
+ if (flag_plus) {
+ *format_ptr = '+';
+ format_ptr++;
+ }
+ if (flag_minus) {
+ *format_ptr = '-';
+ format_ptr++;
+ }
+ if (flag_space) {
+ *format_ptr = ' ';
+ format_ptr++;
+ }
+ if (flag_sharp) {
+ *format_ptr = '#';
+ format_ptr++;
+ }
+ if (flag_zero) {
+ *format_ptr = '0';
+ format_ptr++;
+ } /* '0' *must* be the last one */
+
+ if (width != -1) {
+ sprintf(format_ptr, "%i", width);
+ format_ptr += strlen(format_ptr);
+ }
+
+ if (prec != -1) {
+ *format_ptr = '.';
+ format_ptr++;
+ sprintf(format_ptr, "%i", prec);
+ format_ptr += strlen(format_ptr);
+ }
+
+ if (modifier != -1) {
+ if (modifier == 'L' && strchr("diouxX",type) != NULL) {
+ *format_ptr = 'l';
+ format_ptr++;
+ *format_ptr = 'l';
+ format_ptr++;
+ } else {
+ *format_ptr = modifier;
+ format_ptr++;
+ }
+ }
+
+ *format_ptr = type;
+ format_ptr++;
+ *format_ptr = 0;
+
+ /* vague approximation of minimal length if width or prec are specified */
+ approx_width = width + prec;
+ if (approx_width < 0) /* because width == -1 and/or prec == -1 */
+ approx_width = 0;
+
+ switch (type) {
+ /* int */
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ switch (modifier) {
+ case -1 :
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
+ case 'L':
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long long int));
+ case 'l':
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long int));
+ case 'h':
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
+ /* 'int' instead of 'short int' because default promotion is 'int' */
+ default:
+ INCOHERENT();
+ }
+
+ /* char */
+ case 'c':
+ if (modifier != -1)
+ INCOHERENT();
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
+ /* 'int' instead of 'char' because default promotion is 'int' */
+
+ /* math */
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'E':
+ case 'G':
+ switch (modifier) {
+ case -1 : /* because of default promotion, no modifier means 'l' */
+ case 'l':
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, double));
+ case 'L':
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long double));
+ default:
+ INCOHERENT();
+ }
+
+ /* string */
+ case 's':
+ return type_s(s, width, prec, format_string, va_arg(s->vargs, const char*));
+
+ /* pointer */
+ case 'p':
+ if (modifier == -1)
+ return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, void *));
+ INCOHERENT();
+
+ /* store */
+ case 'n':
+ if (modifier == -1) {
+ int * p;
+ p = va_arg(s->vargs, int *);
+ if (p != NULL) {
+ *p = s->pseudo_len;
+ return 0;
+ }
+ return EOF;
+ }
+ INCOHERENT();
+
+ } /* switch */
+
+ INCOHERENT(); /* unknown type */
+
+#undef INCOHERENT
+#undef INCOHERENT_TEST
+#undef SRCTXT
+#undef DESTTXT
+}
+
+/*
+ * Return value: number of *virtually* written characters
+ * EOF = error
+ */
+static int core(xprintf_struct *s)
+{
+ size_t len, save_len;
+ char *dummy_base;
+
+ /* basic checks */
+ if ((int)(s->maxlen) <= 0) /* 'int' to check against some conversion */
+ return EOF; /* error for example if value is (int)-10 */
+ s->maxlen--; /* because initial maxlen counts final 0 */
+ /* note: now 'maxlen' _can_ be zero */
+
+ if (s->src_string == NULL)
+ s->src_string = "(null)";
+
+ /* struct init and memory allocation */
+ s->buffer_base = NULL;
+ s->buffer_len = 0;
+ s->real_len = 0;
+ s->pseudo_len = 0;
+ if (realloc_buff(s, (size_t)0) == EOF)
+ return EOF;
+ s->dest_string = s->buffer_base;
+
+ /* process source string */
+ for (;;) {
+ /* up to end of source string */
+ if (*(s->src_string) == 0) {
+ *(s->dest_string) = 0; /* final 0 */
+ len = s->real_len + 1;
+ break;
+ }
+
+ if (dispatch(s) == EOF)
+ goto free_EOF;
+
+ /* up to end of dest string */
+ if (s->real_len >= s->maxlen) {
+ (s->buffer_base)[s->maxlen] = 0; /* final 0 */
+ len = s->maxlen + 1;
+ break;
+ }
+ }
+
+ /* for (v)asnprintf */
+ dummy_base = s->buffer_base;
+ save_len = 0; /* just to avoid a compiler warning */
+
+ dummy_base = s->buffer_base + s->real_len;
+ save_len = s->real_len;
+
+ /* process the remaining of source string to compute 'pseudo_len'. We
+ * overwrite again and again, starting at 'dummy_base' because we don't
+ * need the text, only char count. */
+ while(*(s->src_string) != 0) { /* up to end of source string */
+ s->real_len = 0;
+ s->dest_string = dummy_base;
+ if (dispatch(s) == EOF)
+ goto free_EOF;
+ }
+
+ s->buffer_base = (char *)realloc((void *)(s->buffer_base), save_len + 1);
+ if (s->buffer_base == NULL)
+ return EOF; /* should rarely happen because we shrink the buffer */
+ return s->pseudo_len;
+
+ free_EOF:
+ if (s->buffer_base != NULL)
+ free(s->buffer_base);
+ return EOF;
+}
+
+int vasprintf(char **ptr, const char *format_string, va_list vargs)
+{
+ xprintf_struct s;
+ int retval;
+
+ s.src_string = format_string;
+#ifdef va_copy
+ va_copy (s.vargs, vargs);
+#else
+#ifdef __va_copy
+ __va_copy (s.vargs, vargs);
+#else
+ memcpy (&s.vargs, vargs, sizeof (va_list));
+#endif /* __va_copy */
+#endif /* va_copy */
+ s.maxlen = (size_t)INT_MAX;
+
+ retval = core(&s);
+ va_end(s.vargs);
+ if (retval == EOF) {
+ *ptr = NULL;
+ return EOF;
+ }
+
+ *ptr = s.buffer_base;
+ return retval;
+}
diff --git a/contrib/gdtoa/README b/contrib/gdtoa/README
index 95a40aa..ce8be55 100644
--- a/contrib/gdtoa/README
+++ b/contrib/gdtoa/README
@@ -56,7 +56,9 @@ two letters:
whose sum is the desired value
For decimal -> binary conversions, there are three families of
-helper routines: one for round-nearest:
+helper routines: one for round-nearest (or the current rounding
+mode on IEEE-arithmetic systems that provide the C99 fegetround()
+function, if compiled with -DHonor_FLT_ROUNDS):
strtof
strtod
@@ -191,6 +193,9 @@ in the buffer, if the buffer was long enough, or 0. Other forms of
conversion are easily done with the help of gdtoa(), such as %e or %f
style and conversions with direction of rounding specified (so that, if
desired, the decimal value is either >= or <= the binary value).
+On IEEE-arithmetic systems that provide the C99 fegetround() function,
+if compiled with -DHonor_FLT_ROUNDS, these routines honor the current
+rounding mode.
For an example of more general conversions based on dtoa(), see
netlib's "printf.c from ampl/solvers".
@@ -342,5 +347,11 @@ standard says it should -- when Honor_FLT_ROUNDS is #defined, the
current rounding mode is obtained from fegetround() rather than from
FLT_ROUNDS, unless Trust_FLT_ROUNDS is also #defined.
+Compile with -DUSE_LOCALE to use the current locale; otherwise
+decimal points are assumed to be '.'. With -DUSE_LOCALE, unless
+you also compile with -DNO_LOCALE_CACHE, the details about the
+current "decimal point" character string are cached and assumed not
+to change during the program's execution.
+
Please send comments to David M. Gay (dmg at acm dot org, with " at "
changed at "@" and " dot " changed to ".").
diff --git a/contrib/gdtoa/g_Qfmt.c b/contrib/gdtoa/g_Qfmt.c
index 2b9b367..15d1bdd 100644
--- a/contrib/gdtoa/g_Qfmt.c
+++ b/contrib/gdtoa/g_Qfmt.c
@@ -51,15 +51,20 @@ THIS SOFTWARE.
char*
#ifdef KR_headers
-g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
+g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
#else
-g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize)
+g_Qfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
- static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
+ static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
char *b, *s, *se;
ULong bits[4], *L, sign;
int decpt, ex, i, mode;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
if (ndig < 0)
ndig = 0;
@@ -109,6 +114,6 @@ g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize)
return 0;
mode = 0;
}
- s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
- return g__fmt(buf, s, se, decpt, sign);
+ s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign, bufsize);
}
diff --git a/contrib/gdtoa/g__fmt.c b/contrib/gdtoa/g__fmt.c
index 021ecfb..fbccb7d 100644
--- a/contrib/gdtoa/g__fmt.c
+++ b/contrib/gdtoa/g__fmt.c
@@ -37,24 +37,51 @@ THIS SOFTWARE.
char *
#ifdef KR_headers
-g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign;
+g__fmt(b, s, se, decpt, sign, blen) char *b; char *s; char *se; int decpt; ULong sign; size_t blen;
#else
-g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
+g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
#endif
{
int i, j, k;
- char *s0 = s;
+ char *be, *s0;
+ size_t len;
#ifdef USE_LOCALE
- char decimalpoint = *localeconv()->decimal_point;
+#ifdef NO_LOCALE_CACHE
+ char *decimalpoint = localeconv()->decimal_point;
+ size_t dlen = strlen(decimalpoint);
#else
-#define decimalpoint '.'
+ char *decimalpoint;
+ static char *decimalpoint_cache;
+ static size_t dlen;
+ if (!(s0 = decimalpoint_cache)) {
+ s0 = localeconv()->decimal_point;
+ dlen = strlen(s0);
+ if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ strcpy(decimalpoint_cache, s0);
+ s0 = decimalpoint_cache;
+ }
+ }
+ decimalpoint = s0;
+#endif
+#else
+#define dlen 0
#endif
+ s0 = s;
+ len = (se-s) + dlen + 6; /* 6 = sign + e+dd + trailing null */
+ if (blen < len)
+ goto ret0;
+ be = b + blen - 1;
if (sign)
*b++ = '-';
if (decpt <= -4 || decpt > se - s + 5) {
*b++ = *s++;
if (*s) {
- *b++ = decimalpoint;
+#ifdef USE_LOCALE
+ while((*b = *decimalpoint++))
+ ++b;
+#else
+ *b++ = '.';
+#endif
while((*b = *s++) !=0)
b++;
}
@@ -69,6 +96,8 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){}
for(;;) {
i = decpt / k;
+ if (b >= be)
+ goto ret0;
*b++ = i + '0';
if (--j <= 0)
break;
@@ -78,22 +107,41 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
*b = 0;
}
else if (decpt <= 0) {
- *b++ = decimalpoint;
+#ifdef USE_LOCALE
+ while((*b = *decimalpoint++))
+ ++b;
+#else
+ *b++ = '.';
+#endif
+ if (be < b - decpt + (se - s))
+ goto ret0;
for(; decpt < 0; decpt++)
*b++ = '0';
- while((*b = *s++) !=0)
+ while((*b = *s++) != 0)
b++;
}
else {
- while((*b = *s++) !=0) {
+ while((*b = *s++) != 0) {
b++;
- if (--decpt == 0 && *s)
- *b++ = decimalpoint;
+ if (--decpt == 0 && *s) {
+#ifdef USE_LOCALE
+ while(*b = *decimalpoint++)
+ ++b;
+#else
+ *b++ = '.';
+#endif
+ }
+ }
+ if (b + decpt > be) {
+ ret0:
+ b = 0;
+ goto ret;
}
for(; decpt > 0; decpt--)
*b++ = '0';
*b = 0;
}
+ ret:
freedtoa(s0);
return b;
}
diff --git a/contrib/gdtoa/g_ddfmt.c b/contrib/gdtoa/g_ddfmt.c
index 7fc3057..b65d39d 100644
--- a/contrib/gdtoa/g_ddfmt.c
+++ b/contrib/gdtoa/g_ddfmt.c
@@ -33,9 +33,9 @@ THIS SOFTWARE.
char *
#ifdef KR_headers
-g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize;
+g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; size_t bufsize;
#else
-g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize)
+g_ddfmt(char *buf, double *dd, int ndig, size_t bufsize)
#endif
{
FPI fpi;
@@ -44,6 +44,21 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize)
int bx, by, decpt, ex, ey, i, j, mode;
Bigint *x, *y, *z;
double ddx[2];
+#ifdef Honor_FLT_ROUNDS /*{{*/
+ int Rounding;
+#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
+ Rounding = Flt_Rounds;
+#else /*}{*/
+ Rounding = 1;
+ switch(fegetround()) {
+ case FE_TOWARDZERO: Rounding = 0; break;
+ case FE_UPWARD: Rounding = 2; break;
+ case FE_DOWNWARD: Rounding = 3;
+ }
+#endif /*}}*/
+#else /*}{*/
+#define Rounding FPI_Round_near
+#endif /*}}*/
if (bufsize < 10 || bufsize < ndig + 8)
return 0;
@@ -144,11 +159,11 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize)
}
fpi.emin = 1-1023-53+1;
fpi.emax = 2046-1023-106+1;
- fpi.rounding = FPI_Round_near;
+ fpi.rounding = Rounding;
fpi.sudden_underflow = 0;
i = STRTOG_Normal;
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
- b = g__fmt(buf, s, se, decpt, z->sign);
+ b = g__fmt(buf, s, se, decpt, z->sign, bufsize);
Bfree(z);
return b;
}
diff --git a/contrib/gdtoa/g_dfmt.c b/contrib/gdtoa/g_dfmt.c
index db2636f..23d8b24 100644
--- a/contrib/gdtoa/g_dfmt.c
+++ b/contrib/gdtoa/g_dfmt.c
@@ -33,15 +33,20 @@ THIS SOFTWARE.
char*
#ifdef KR_headers
-g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize;
+g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; size_t bufsize;
#else
-g_dfmt(char *buf, double *d, int ndig, unsigned bufsize)
+g_dfmt(char *buf, double *d, int ndig, size_t bufsize)
#endif
{
- static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
+ static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
char *b, *s, *se;
ULong bits[2], *L, sign;
int decpt, ex, i, mode;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
if (ndig < 0)
ndig = 0;
@@ -52,6 +57,8 @@ g_dfmt(char *buf, double *d, int ndig, unsigned bufsize)
sign = L[_0] & 0x80000000L;
if ((L[_0] & 0x7ff00000) == 0x7ff00000) {
/* Infinity or NaN */
+ if (bufsize < 10)
+ return 0;
if (L[_0] & 0xfffff || L[_1]) {
return strcp(buf, "NaN");
}
@@ -78,12 +85,9 @@ g_dfmt(char *buf, double *d, int ndig, unsigned bufsize)
ex = 1;
ex -= 0x3ff + 52;
mode = 2;
- if (ndig <= 0) {
- if (bufsize < 25)
- return 0;
+ if (ndig <= 0)
mode = 0;
- }
i = STRTOG_Normal;
- s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
- return g__fmt(buf, s, se, decpt, sign);
+ s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign, bufsize);
}
diff --git a/contrib/gdtoa/g_ffmt.c b/contrib/gdtoa/g_ffmt.c
index 612adfa..1c27c60 100644
--- a/contrib/gdtoa/g_ffmt.c
+++ b/contrib/gdtoa/g_ffmt.c
@@ -33,15 +33,20 @@ THIS SOFTWARE.
char*
#ifdef KR_headers
-g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize;
+g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; size_t bufsize;
#else
-g_ffmt(char *buf, float *f, int ndig, unsigned bufsize)
+g_ffmt(char *buf, float *f, int ndig, size_t bufsize)
#endif
{
- static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
+ static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
char *b, *s, *se;
ULong bits[1], *L, sign;
int decpt, ex, i, mode;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
if (ndig < 0)
ndig = 0;
@@ -83,6 +88,6 @@ g_ffmt(char *buf, float *f, int ndig, unsigned bufsize)
mode = 0;
}
i = STRTOG_Normal;
- s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
- return g__fmt(buf, s, se, decpt, sign);
+ s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign, bufsize);
}
diff --git a/contrib/gdtoa/g_xLfmt.c b/contrib/gdtoa/g_xLfmt.c
index 1bbc6e2..6fa1de2 100644
--- a/contrib/gdtoa/g_xLfmt.c
+++ b/contrib/gdtoa/g_xLfmt.c
@@ -49,15 +49,20 @@ THIS SOFTWARE.
char*
#ifdef KR_headers
-g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
+g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
#else
-g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize)
+g_xLfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
- static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
char *b, *s, *se;
ULong bits[2], *L, sign;
int decpt, ex, i, mode;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
if (ndig < 0)
ndig = 0;
@@ -103,6 +108,6 @@ g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize)
return 0;
mode = 0;
}
- s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
- return g__fmt(buf, s, se, decpt, sign);
+ s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign, bufsize);
}
diff --git a/contrib/gdtoa/g_xfmt.c b/contrib/gdtoa/g_xfmt.c
index 47a862d..495c7b4 100644
--- a/contrib/gdtoa/g_xfmt.c
+++ b/contrib/gdtoa/g_xfmt.c
@@ -53,16 +53,21 @@ THIS SOFTWARE.
char*
#ifdef KR_headers
-g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
+g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
#else
-g_xfmt(char *buf, void *V, int ndig, unsigned bufsize)
+g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
- static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
char *b, *s, *se;
ULong bits[2], sign;
UShort *L;
int decpt, ex, i, mode;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
if (ndig < 0)
ndig = 0;
@@ -109,6 +114,6 @@ g_xfmt(char *buf, void *V, int ndig, unsigned bufsize)
return 0;
mode = 0;
}
- s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
- return g__fmt(buf, s, se, decpt, sign);
+ s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
+ return g__fmt(buf, s, se, decpt, sign, bufsize);
}
diff --git a/contrib/gdtoa/gdtoa.c b/contrib/gdtoa/gdtoa.c
index 8ff8cc5..3b64250 100644
--- a/contrib/gdtoa/gdtoa.c
+++ b/contrib/gdtoa/gdtoa.c
@@ -417,11 +417,9 @@ gdtoa
if (dval(d) > ds + dval(eps))
goto bump_up;
else if (dval(d) < ds - dval(eps)) {
- while(*--s == '0'){}
- s++;
if (dval(d))
inex = STRTOG_Inexlo;
- goto ret1;
+ goto clear_trailing0;
}
break;
}
@@ -479,8 +477,12 @@ gdtoa
}
++*s++;
}
- else
+ else {
inex = STRTOG_Inexlo;
+ clear_trailing0:
+ while(*--s == '0'){}
+ ++s;
+ }
break;
}
}
@@ -738,7 +740,7 @@ gdtoa
if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo;
while(*--s == '0'){}
- s++;
+ ++s;
}
ret:
Bfree(S);
diff --git a/contrib/gdtoa/gdtoa.h b/contrib/gdtoa/gdtoa.h
index ed0e020..e59ebf6 100644
--- a/contrib/gdtoa/gdtoa.h
+++ b/contrib/gdtoa/gdtoa.h
@@ -33,6 +33,7 @@ THIS SOFTWARE.
#define GDTOA_H_INCLUDED
#include "arith.h"
+#include <stddef.h> /* for size_t */
#ifndef Long
#define Long long
@@ -111,12 +112,12 @@ extern float strtof ANSI((CONST char *, char **));
extern double strtod ANSI((CONST char *, char **));
extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
-extern char* g_ddfmt ANSI((char*, double*, int, unsigned));
-extern char* g_dfmt ANSI((char*, double*, int, unsigned));
-extern char* g_ffmt ANSI((char*, float*, int, unsigned));
-extern char* g_Qfmt ANSI((char*, void*, int, unsigned));
-extern char* g_xfmt ANSI((char*, void*, int, unsigned));
-extern char* g_xLfmt ANSI((char*, void*, int, unsigned));
+extern char* g_ddfmt ANSI((char*, double*, int, size_t));
+extern char* g_dfmt ANSI((char*, double*, int, size_t));
+extern char* g_ffmt ANSI((char*, float*, int, size_t));
+extern char* g_Qfmt ANSI((char*, void*, int, size_t));
+extern char* g_xfmt ANSI((char*, void*, int, size_t));
+extern char* g_xLfmt ANSI((char*, void*, int, size_t));
extern int strtoId ANSI((CONST char*, char**, double*, double*));
extern int strtoIdd ANSI((CONST char*, char**, double*, double*));
diff --git a/contrib/gdtoa/gdtoa_fltrnds.h b/contrib/gdtoa/gdtoa_fltrnds.h
new file mode 100644
index 0000000..33e5f9e
--- /dev/null
+++ b/contrib/gdtoa/gdtoa_fltrnds.h
@@ -0,0 +1,18 @@
+ FPI *fpi, fpi1;
+ int Rounding;
+#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
+ Rounding = Flt_Rounds;
+#else /*}{*/
+ Rounding = 1;
+ switch(fegetround()) {
+ case FE_TOWARDZERO: Rounding = 0; break;
+ case FE_UPWARD: Rounding = 2; break;
+ case FE_DOWNWARD: Rounding = 3;
+ }
+#endif /*}}*/
+ fpi = &fpi0;
+ if (Rounding != 1) {
+ fpi1 = fpi0;
+ fpi = &fpi1;
+ fpi1.rounding = Rounding;
+ }
diff --git a/contrib/gdtoa/gdtoaimp.h b/contrib/gdtoa/gdtoaimp.h
index 916e156..c550ada 100644
--- a/contrib/gdtoa/gdtoaimp.h
+++ b/contrib/gdtoa/gdtoaimp.h
@@ -128,8 +128,10 @@ THIS SOFTWARE.
* conversions of IEEE doubles in single-threaded executions with
* 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with
* 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate.
- * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
- * Infinity and NaN (case insensitively).
+ * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK
+ * #defined automatically on IEEE systems. On such systems,
+ * when INFNAN_CHECK is #defined, strtod checks
+ * for Infinity and NaN (case insensitively).
* When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
* strtodg also accepts (case insensitively) strings of the form
* NaN(x), where x is a string of hexadecimal digits (optionally
@@ -177,6 +179,9 @@ THIS SOFTWARE.
#include "gdtoa.h"
#include "gd_qnan.h"
+#ifdef Honor_FLT_ROUNDS
+#include <fenv.h>
+#endif
#ifdef DEBUG
#include "stdio.h"
@@ -206,6 +211,7 @@ extern Char *MALLOC ANSI((size_t));
#define INFNAN_CHECK
#define USE_LOCALE
+#define NO_LOCALE_CACHE
#define Honor_FLT_ROUNDS
#define Trust_FLT_ROUNDS
@@ -608,7 +614,7 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t));
extern void freedtoa ANSI((char*));
extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp,
int mode, int ndigits, int *decpt, char **rve));
- extern char *g__fmt ANSI((char*, char*, char*, int, ULong));
+ extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t));
extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
extern void hexdig_init_D2A(Void);
extern int hexnan ANSI((CONST char**, FPI*, ULong*));
@@ -626,7 +632,7 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t));
extern double ratio ANSI((Bigint*, Bigint*));
extern void rshift ANSI((Bigint*, int));
extern char *rv_alloc ANSI((int));
- extern Bigint *s2b ANSI((CONST char*, int, int, ULong));
+ extern Bigint *s2b ANSI((CONST char*, int, int, ULong, int));
extern Bigint *set_ones ANSI((Bigint*, int));
extern char *strcp ANSI((char*, const char*));
extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
@@ -668,6 +674,10 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t));
* (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
*/
#ifdef IEEE_Arith
+#ifndef NO_INFNAN_CHECK
+#undef INFNAN_CHECK
+#define INFNAN_CHECK
+#endif
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
diff --git a/contrib/gdtoa/gethex.c b/contrib/gdtoa/gethex.c
index b3f7c50..c8ac8ba 100644
--- a/contrib/gdtoa/gethex.c
+++ b/contrib/gdtoa/gethex.c
@@ -49,9 +49,21 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
ULong L, lostbits, *x;
Long e, e1;
#ifdef USE_LOCALE
- unsigned char decimalpoint = *localeconv()->decimal_point;
+ int i;
+#ifdef NO_LOCALE_CACHE
+ const unsigned char *decimalpoint = (unsigned char*)localeconv()->decimal_point;
#else
-#define decimalpoint '.'
+ const unsigned char *decimalpoint;
+ static unsigned char *decimalpoint_cache;
+ if (!(s0 = decimalpoint_cache)) {
+ s0 = (unsigned char*)localeconv()->decimal_point;
+ if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ strcpy(decimalpoint_cache, s0);
+ s0 = decimalpoint_cache;
+ }
+ }
+ decimalpoint = s0;
+#endif
#endif
if (!hexdig['0'])
@@ -66,11 +78,21 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
decpt = 0;
zret = 0;
e = 0;
- if (!hexdig[*s]) {
+ if (hexdig[*s])
+ havedig++;
+ else {
zret = 1;
- if (*s != decimalpoint)
+#ifdef USE_LOCALE
+ for(i = 0; decimalpoint[i]; ++i) {
+ if (s[i] != decimalpoint[i])
+ goto pcheck;
+ }
+ decpt = s += i;
+#else
+ if (*s != '.')
goto pcheck;
decpt = ++s;
+#endif
if (!hexdig[*s])
goto pcheck;
while(*s == '0')
@@ -82,11 +104,20 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
}
while(hexdig[*s])
s++;
- if (*s == decimalpoint && !decpt) {
+#ifdef USE_LOCALE
+ if (*s == *decimalpoint && !decpt) {
+ for(i = 1; decimalpoint[i]; ++i) {
+ if (s[i] != decimalpoint[i])
+ goto pcheck;
+ }
+ decpt = s += i;
+#else
+ if (*s == '.' && !decpt) {
decpt = ++s;
+#endif
while(hexdig[*s])
s++;
- }
+ }/*}*/
if (decpt)
e = -(((Long)(s-decpt)) << 2);
pcheck:
@@ -118,7 +149,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
}
*sp = (char*)s;
if (!havedig)
- *sp = s0 - 1;
+ *sp = (char*)s0 - 1;
if (zret)
return STRTOG_Zero;
if (big) {
@@ -168,16 +199,26 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
return STRTOG_Normal | STRTOG_Inexlo;
}
n = s1 - s0 - 1;
- for(k = 0; n > 7; n >>= 1)
+ for(k = 0; n > (1 << kshift-2) - 1; n >>= 1)
k++;
b = Balloc(k);
x = b->x;
n = 0;
L = 0;
+#ifdef USE_LOCALE
+ for(i = 0; decimalpoint[i+1]; ++i);
+#endif
while(s1 > s0) {
- if (*--s1 == decimalpoint)
+#ifdef USE_LOCALE
+ if (*--s1 == decimalpoint[i]) {
+ s1 -= i;
continue;
- if (n == 32) {
+ }
+#else
+ if (*--s1 == '.')
+ continue;
+#endif
+ if (n == ULbits) {
*x++ = L;
L = 0;
n = 0;
@@ -187,7 +228,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
}
*x++ = L;
b->wds = n = x - b->x;
- n = 32*n - hi0bits(L);
+ n = ULbits*n - hi0bits(L);
nbits = fpi->nbits;
lostbits = 0;
x = b->x;
diff --git a/contrib/gdtoa/makefile b/contrib/gdtoa/makefile
index 209fefc..367eb9c 100644
--- a/contrib/gdtoa/makefile
+++ b/contrib/gdtoa/makefile
@@ -25,7 +25,7 @@
.SUFFIXES: .c .o
CC = cc
-CFLAGS = -g -DINFNAN_CHECK
+CFLAGS = -g
.c.o:
$(CC) -c $(CFLAGS) $*.c
@@ -55,9 +55,9 @@ gdtoa.a: dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c\
# If your system lacks ranlib, you do not need it.
xs0 = README arithchk.c dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c\
- g_ffmt.c g_xLfmt.c g_xfmt.c gdtoa.c gdtoa.h gdtoaimp.h gethex.c\
- gmisc.c hd_init.c hexnan.c makefile misc.c qnan.c smisc.c strtoIQ.c\
- strtoId.c strtoIdd.c strtoIf.c strtoIg.c strtoIx.c strtoIxL.c\
+ g_ffmt.c g_xLfmt.c g_xfmt.c gdtoa.c gdtoa.h gdtoa_fltrnds.h gdtoaimp.h\
+ gethex.c gmisc.c hd_init.c hexnan.c makefile misc.c qnan.c smisc.c\
+ strtoIQ.c strtoId.c strtoIdd.c strtoIf.c strtoIg.c strtoIx.c strtoIxL.c\
strtod.c strtodI.c strtodg.c strtodnrp.c strtof.c strtopQ.c strtopd.c\
strtopdd.c strtopf.c strtopx.c strtopxL.c strtorQ.c strtord.c strtordd.c\
strtorf.c strtorx.c strtorxL.c sum.c ulp.c
diff --git a/contrib/gdtoa/smisc.c b/contrib/gdtoa/smisc.c
index 163011e..50431fc 100644
--- a/contrib/gdtoa/smisc.c
+++ b/contrib/gdtoa/smisc.c
@@ -34,9 +34,9 @@ THIS SOFTWARE.
Bigint *
s2b
#ifdef KR_headers
- (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+ (s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
#else
- (CONST char *s, int nd0, int nd, ULong y9)
+ (CONST char *s, int nd0, int nd, ULong y9, int dplen)
#endif
{
Bigint *b;
@@ -60,10 +60,10 @@ s2b
s += 9;
do b = multadd(b, 10, *s++ - '0');
while(++i < nd0);
- s++;
+ s += dplen;
}
else
- s += 10;
+ s += dplen + 9;
for(; i < nd; i++)
b = multadd(b, 10, *s++ - '0');
return b;
diff --git a/contrib/gdtoa/strtod.c b/contrib/gdtoa/strtod.c
index 69567f5..5550853 100644
--- a/contrib/gdtoa/strtod.c
+++ b/contrib/gdtoa/strtod.c
@@ -80,6 +80,28 @@ strtod
#ifdef SET_INEXACT
int inexact, oldinexact;
#endif
+#ifdef USE_LOCALE /*{{*/
+#ifdef NO_LOCALE_CACHE
+ char *decimalpoint = localeconv()->decimal_point;
+ int dplen = strlen(decimalpoint);
+#else
+ char *decimalpoint;
+ static char *decimalpoint_cache;
+ static int dplen;
+ if (!(s0 = decimalpoint_cache)) {
+ s0 = localeconv()->decimal_point;
+ if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ strcpy(decimalpoint_cache, s0);
+ s0 = decimalpoint_cache;
+ }
+ dplen = strlen(s0);
+ }
+ decimalpoint = (char*)s0;
+#endif /*NO_LOCALE_CACHE*/
+#else /*USE_LOCALE}{*/
+#define dplen 1
+#endif /*USE_LOCALE}}*/
+
#ifdef Honor_FLT_ROUNDS /*{*/
int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
@@ -118,7 +140,7 @@ strtod
}
break2:
if (*s == '0') {
-#ifndef NO_HEX_FP /*{{*/
+#ifndef NO_HEX_FP /*{*/
{
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
Long exp;
@@ -157,7 +179,7 @@ strtod
goto ret;
}
}
-#endif
+#endif /*}*/
nz0 = 1;
while(*++s == '0') ;
if (!*s)
@@ -172,13 +194,17 @@ strtod
z = 10*z + c - '0';
nd0 = nd;
#ifdef USE_LOCALE
- if (c == *localeconv()->decimal_point)
+ if (c == *decimalpoint) {
+ for(i = 1; decimalpoint[i]; ++i)
+ if (s[i] != decimalpoint[i])
+ goto dig_done;
+ s += i;
+ c = *s;
#else
- if (c == '.')
+ if (c == '.') {
+ c = *++s;
#endif
- {
decpt = 1;
- c = *++s;
if (!nd) {
for(; c == '0'; c = *++s)
nz++;
@@ -207,7 +233,7 @@ strtod
nz = 0;
}
}
- }
+ }/*}*/
dig_done:
e = 0;
if (c == 'e' || c == 'E') {
@@ -527,7 +553,7 @@ strtod
/* Put digits into bd: true value = bd * 10^e */
- bd0 = s2b(s0, nd0, nd, y);
+ bd0 = s2b(s0, nd0, nd, y, dplen);
for(;;) {
bd = Balloc(bd0->k);
@@ -974,7 +1000,11 @@ strtod
dval(rv) *= dval(rv0);
#ifndef NO_ERRNO
/* try to avoid the bug of testing an 8087 register value */
+#ifdef IEEE_Arith
+ if (!(word0(rv) & Exp_mask))
+#else
if (word0(rv) == 0 && word1(rv) == 0)
+#endif
errno = ERANGE;
#endif
}
diff --git a/contrib/gdtoa/strtodg.c b/contrib/gdtoa/strtodg.c
index 9b73d95..a69ce30 100644
--- a/contrib/gdtoa/strtodg.c
+++ b/contrib/gdtoa/strtodg.c
@@ -331,6 +331,27 @@ strtodg
Long L;
ULong *b, *be, y, z;
Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
+#ifdef USE_LOCALE /*{{*/
+#ifdef NO_LOCALE_CACHE
+ char *decimalpoint = localeconv()->decimal_point;
+ int dplen = strlen(decimalpoint);
+#else
+ char *decimalpoint;
+ static char *decimalpoint_cache;
+ static int dplen;
+ if (!(s0 = decimalpoint_cache)) {
+ s0 = localeconv()->decimal_point;
+ if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ strcpy(decimalpoint_cache, s0);
+ s0 = decimalpoint_cache;
+ }
+ dplen = strlen(s0);
+ }
+ decimalpoint = (char*)s0;
+#endif /*NO_LOCALE_CACHE*/
+#else /*USE_LOCALE}{*/
+#define dplen 1
+#endif /*USE_LOCALE}}*/
irv = STRTOG_Zero;
denorm = sign = nz0 = nz = 0;
@@ -389,13 +410,17 @@ strtodg
z = 10*z + c - '0';
nd0 = nd;
#ifdef USE_LOCALE
- if (c == *localeconv()->decimal_point)
+ if (c == *decimalpoint) {
+ for(i = 1; decimalpoint[i]; ++i)
+ if (s[i] != decimalpoint[i])
+ goto dig_done;
+ s += i;
+ c = *s;
#else
- if (c == '.')
+ if (c == '.') {
+ c = *++s;
#endif
- {
decpt = 1;
- c = *++s;
if (!nd) {
for(; c == '0'; c = *++s)
nz++;
@@ -424,7 +449,7 @@ strtodg
nz = 0;
}
}
- }
+ }/*}*/
dig_done:
e = 0;
if (c == 'e' || c == 'E') {
@@ -683,7 +708,7 @@ strtodg
/* Put digits into bd: true value = bd * 10^e */
- bd0 = s2b(s0, nd0, nd, y);
+ bd0 = s2b(s0, nd0, nd, y, dplen);
for(;;) {
bd = Balloc(bd0->k);
@@ -992,7 +1017,7 @@ strtodg
irv = STRTOG_Normal | STRTOG_Inexlo;
*exp = fpi->emax;
b = bits;
- be = b + (fpi->nbits >> 5) + 1;
+ be = b + ((fpi->nbits + 31) >> 5);
while(b < be)
*b++ = -1;
if ((j = fpi->nbits & 0x1f))
diff --git a/contrib/gdtoa/strtof.c b/contrib/gdtoa/strtof.c
index 727a3fa..df9a75a 100644
--- a/contrib/gdtoa/strtof.c
+++ b/contrib/gdtoa/strtof.c
@@ -41,19 +41,16 @@ strtof(CONST char *s, char **sp)
#endif
{
static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
- FPI *fpi, fpi1;
ULong bits[1];
Long exp;
int k;
- int Rounding = Flt_Rounds;
union { ULong L[1]; float f; } u;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- fpi = &fpi0;
- if (Rounding != FPI_Round_near) {
- fpi1 = fpi0;
- fpi1.rounding = Rounding;
- fpi = &fpi1;
- }
k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
diff --git a/contrib/gdtoa/strtopQ.c b/contrib/gdtoa/strtopQ.c
index dd5dab8..77f3190 100644
--- a/contrib/gdtoa/strtopQ.c
+++ b/contrib/gdtoa/strtopQ.c
@@ -56,13 +56,18 @@ strtopQ(s, sp, V) CONST char *s; char **sp; void *V;
strtopQ(CONST char *s, char **sp, void *V)
#endif
{
- static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI };
+ static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI };
ULong bits[4];
Long exp;
int k;
ULong *L = (ULong*)V;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- k = strtodg(s, sp, &fpi, &exp, bits);
+ k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
diff --git a/contrib/gdtoa/strtopd.c b/contrib/gdtoa/strtopd.c
index 42c57fc..0fb35da 100644
--- a/contrib/gdtoa/strtopd.c
+++ b/contrib/gdtoa/strtopd.c
@@ -42,8 +42,13 @@ strtopd(CONST char *s, char **sp, double *d)
ULong bits[2];
Long exp;
int k;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- k = strtodg(s, sp, &fpi0, &exp, bits);
+ k = strtodg(s, sp, fpi, &exp, bits);
ULtod((ULong*)d, bits, exp, k);
return k;
}
diff --git a/contrib/gdtoa/strtopdd.c b/contrib/gdtoa/strtopdd.c
index 9b788ee..c665976 100644
--- a/contrib/gdtoa/strtopdd.c
+++ b/contrib/gdtoa/strtopdd.c
@@ -39,9 +39,9 @@ strtopdd(CONST char *s, char **sp, double *dd)
#endif
{
#ifdef Sudden_Underflow
- static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
+ static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
#else
- static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
+ static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
#endif
ULong bits[4];
Long exp;
@@ -51,8 +51,13 @@ strtopdd(CONST char *s, char **sp, double *dd)
ULong L[4];
} U;
U *u;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- rv = strtodg(s, sp, &fpi, &exp, bits);
+ rv = strtodg(s, sp, fpi, &exp, bits);
u = (U*)dd;
switch(rv & STRTOG_Retmask) {
case STRTOG_NoNumber:
diff --git a/contrib/gdtoa/strtopf.c b/contrib/gdtoa/strtopf.c
index cc7c970..74694a0 100644
--- a/contrib/gdtoa/strtopf.c
+++ b/contrib/gdtoa/strtopf.c
@@ -38,12 +38,17 @@ strtopf(s, sp, f) CONST char *s; char **sp; float *f;
strtopf(CONST char *s, char **sp, float *f)
#endif
{
- static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
ULong bits[1], *L;
Long exp;
int k;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- k = strtodg(s, sp, &fpi, &exp, bits);
+ k = strtodg(s, sp, fpi, &exp, bits);
L = (ULong*)f;
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
diff --git a/contrib/gdtoa/strtopx.c b/contrib/gdtoa/strtopx.c
index 4dcb06a..07d0458 100644
--- a/contrib/gdtoa/strtopx.c
+++ b/contrib/gdtoa/strtopx.c
@@ -58,13 +58,18 @@ strtopx(s, sp, V) CONST char *s; char **sp; void *V;
strtopx(CONST char *s, char **sp, void *V)
#endif
{
- static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
ULong bits[2];
Long exp;
int k;
UShort *L = (UShort*)V;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- k = strtodg(s, sp, &fpi, &exp, bits);
+ k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
diff --git a/contrib/gdtoa/strtopxL.c b/contrib/gdtoa/strtopxL.c
index 68c83d2..b0f5cdd 100644
--- a/contrib/gdtoa/strtopxL.c
+++ b/contrib/gdtoa/strtopxL.c
@@ -54,13 +54,18 @@ strtopxL(s, sp, V) CONST char *s; char **sp; void *V;
strtopxL(CONST char *s, char **sp, void *V)
#endif
{
- static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
ULong bits[2];
Long exp;
int k;
ULong *L = (ULong*)V;
+#ifdef Honor_FLT_ROUNDS
+#include "gdtoa_fltrnds.h"
+#else
+#define fpi &fpi0
+#endif
- k = strtodg(s, sp, &fpi, &exp, bits);
+ k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
diff --git a/contrib/gdtoa/test/README b/contrib/gdtoa/test/README
index 685fe13..1076205 100644
--- a/contrib/gdtoa/test/README
+++ b/contrib/gdtoa/test/README
@@ -60,6 +60,15 @@ must be set to 53 bits. This can be done, e.g., by invoking
fpinit_ASL(), whose source appears in
http://www.netlib.org/ampl/solvers/fpinit.c .
+The obad directory shows results expected on (at least some) Intel x86
+Linux systems and may not be relevant to other systems.
+
+You can optionally compile getround.c with -DHonor_FLT_ROUNDS
+to manually test strtof, strtod, etc., using fegetround().
+You can also or alternatively compile getround.c with
+-DUSE_MY_LOCALE (when ../gdtoa.a is compiled with -DUSE_LOCALE)
+to test multi-byte decimal points.
+
These are simple test programs, not meant for exhaustive testing,
but for manually testing "interesting" cases. Paxson's testbase
is good for more exhaustive testing, in part with random inputs.
diff --git a/contrib/gdtoa/test/getround.c b/contrib/gdtoa/test/getround.c
index 786bcc3..e67e14f 100644
--- a/contrib/gdtoa/test/getround.c
+++ b/contrib/gdtoa/test/getround.c
@@ -35,6 +35,11 @@ THIS SOFTWARE.
static char *dir[4] = { "toward zero", "nearest", "toward +Infinity",
"toward -Infinity" };
+#ifdef Honor_FLT_ROUNDS
+#include <fenv.h>
+static int fe_conv[4] = {FE_TOWARDZERO, FE_TONEAREST, FE_UPWARD, FE_DOWNWARD };
+#endif
+
int
#ifdef KR_headers
getround(r, s) int r; char *s;
@@ -59,6 +64,9 @@ getround(int r, char *s)
else
printf("changed from %d (%s) to %d (%s)\n",
r, dir[r], i, dir[i]);
+#ifdef Honor_FLT_ROUNDS
+ fesetround(fe_conv[i]);
+#endif
return i;
}
printf("Bad rounding direction %d: choose among\n", i);
@@ -67,3 +75,16 @@ getround(int r, char *s)
printf("Leaving rounding mode for strtor... at %d (%s)\n", r, dir[r]);
return r;
}
+
+#ifdef USE_MY_LOCALE
+#include <locale.h>
+
+ struct lconv *
+localeconv(void)
+{
+ static struct lconv mylocale;
+ mylocale.decimal_point = "<Pt>";
+ return &mylocale;
+ }
+#endif
+
diff --git a/contrib/gdtoa/test/makefile b/contrib/gdtoa/test/makefile
index 156eae2..243b5a6 100644
--- a/contrib/gdtoa/test/makefile
+++ b/contrib/gdtoa/test/makefile
@@ -28,6 +28,8 @@ CC = cc
CFLAGS = -g -I..
A = ../gdtoa.a
L = -lm
+L1 =
+#use "L1=-lm" when compiled with -DHonor_FLTP_ROUNDS or -DUSE_LOCALE
INFFIX = | sed 's/[Ii][Nn][Ff][intyINTY]*/Infinity/g'
.c.o:
@@ -41,7 +43,7 @@ dt: $(dt)
dItest = dItest.o getround.o $A
dItest: $(dItest)
- $(CC) -o dItest $(dItest)
+ $(CC) -o dItest $(dItest) $(L1)
ddtest = ddtest.o getround.o $A
ddtest: $(ddtest)
@@ -53,19 +55,19 @@ dtest: $(dtest)
ftest = ftest.o getround.o $A
ftest: $(ftest)
- $(CC) -o ftest $(ftest)
+ $(CC) -o ftest $(ftest) $(L1)
Qtest = Qtest.o getround.o $A
Qtest: $(Qtest)
- $(CC) -o Qtest $(Qtest)
+ $(CC) -o Qtest $(Qtest) $(L1)
xtest = xtest.o getround.o $A
xtest: $(xtest)
- $(CC) -o xtest $(xtest)
+ $(CC) -o xtest $(xtest) $(L1)
xLtest = xLtest.o getround.o $A
xLtest: $(xLtest)
- $(CC) -o xLtest $(xLtest)
+ $(CC) -o xLtest $(xLtest) $(L1)
strtopddSI.o: strtopddSI.c ../strtopdd.c
@@ -83,7 +85,7 @@ ddtestsi: $(ddtestsi)
dItestsi = dItest.o strtodISI.o strtoIdSI.o getround.o $A
dItestsi: $(dItestsi)
- $(CC) -o dItestsi $(dItestsi)
+ $(CC) -o dItestsi $(dItestsi) $(L1)
strtodt = strtodt.o $A
strtodt: $(strtodt)
@@ -132,7 +134,8 @@ tests: Q.out x.out xL.out dt dItest ddtest dtest ftest Qtest xLtest xtest ddtest
cat bad/strtodt.out
./strtodtnrp testnos3 >bad/strtodtnrp.out && rm bad/strtodtnrp.out || \
cat bad/strtodtnrp.out
- rmdir bad
+ rmdir bad 2>/dev/null || \
+ (cd bad; for i in *; do cmp -s $$i ../obad/$$i && rm $$i;done; cd ..; rmdir bad)
touch tests
xs0 = README Qtest.c dItest.c ddtest.c dtest.c dt.c ftest.c getround.c \
diff --git a/contrib/gdtoa/test/obad/strtodt.out b/contrib/gdtoa/test/obad/strtodt.out
new file mode 100644
index 0000000..79516bf
--- /dev/null
+++ b/contrib/gdtoa/test/obad/strtodt.out
@@ -0,0 +1,6 @@
+Line 31 of testnos3: got 4585747a b143e354; expected 4585747a b143e353
+Line 46 of testnos3: got 64fdcf7d f8f573b8; expected 64fdcf7d f8f573b7
+Line 47 of testnos3: got 650dcf7d f8f573b8; expected 650dcf7d f8f573b7
+Line 72 of testnos3: got 3cc70385 6844bdbe; expected 3cc70385 6844bdbf
+Line 73 of testnos3: got 3cb70385 6844bdbe; expected 3cb70385 6844bdbf
+5 bad conversions
diff --git a/contrib/gdtoa/test/obad/xL.out b/contrib/gdtoa/test/obad/xL.out
new file mode 100644
index 0000000..19a7fd1
--- /dev/null
+++ b/contrib/gdtoa/test/obad/xL.out
@@ -0,0 +1,1460 @@
+
+Input: 1.23
+
+strtoxL consumes 4 bytes and returns 33
+with bits = #3fff0000 9d70a3d7 a3d70a4
+printf("%.21Lg") gives 7.73283722915781506499e-4933
+g_xLfmt(0) gives 4 bytes: "1.23"
+
+strtoIxL returns 33, consuming 4 bytes.
+fI[0] = #3fff0000 9d70a3d7 a3d70a3
+= 7.73283722915781506134e-4933
+fI[1] = #3fff0000 9d70a3d7 a3d70a4
+= 7.73283722915781506499e-4933
+fI[1] == strtoxL
+
+
+Input: 1.23e+20
+
+strtoxL consumes 8 bytes and returns 1
+with bits = #40410000 d55ef90a 2da18000
+printf("%.21Lg") gives 2.24239113715721119512e-4932
+g_xLfmt(0) gives 8 bytes: "1.23e+20"
+
+strtoIxL returns 1, consuming 8 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1.23e-20
+
+strtoxL consumes 8 bytes and returns 17
+with bits = #3fbc0000 e857267b b3a984f2
+printf("%.21Lg") gives 2.74065070995958800375e-4932
+g_xLfmt(0) gives 8 bytes: "1.23e-20"
+
+strtoIxL returns 17, consuming 8 bytes.
+fI[0] = #3fbc0000 e857267b b3a984f2
+= 2.74065070995958800375e-4932
+fI[1] = #3fbc0000 e857267b b3a984f3
+= 2.74065070995958800411e-4932
+fI[0] == strtoxL
+
+
+Input: 1.23456789
+
+strtoxL consumes 10 bytes and returns 33
+with bits = #3fff0000 9e065214 1ef0dbf6
+printf("%.21Lg") gives 7.88641440242171807354e-4933
+g_xLfmt(0) gives 10 bytes: "1.23456789"
+
+strtoIxL returns 33, consuming 10 bytes.
+fI[0] = #3fff0000 9e065214 1ef0dbf5
+= 7.8864144024217180699e-4933
+fI[1] = #3fff0000 9e065214 1ef0dbf6
+= 7.88641440242171807354e-4933
+fI[1] == strtoxL
+
+
+Input: 1.23456589e+20
+
+strtoxL consumes 14 bytes and returns 1
+with bits = #40410000 d629bd33 5ccba00
+printf("%.21Lg") gives 2.26319561227049478508e-4932
+g_xLfmt(0) gives 14 bytes: "1.23456589e+20"
+
+strtoIxL returns 1, consuming 14 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1.23e+30
+
+strtoxL consumes 8 bytes and returns 17
+with bits = #40620000 f8658274 7dbc824a
+printf("%.21Lg") gives 3.16238691003557160385e-4932
+g_xLfmt(0) gives 8 bytes: "1.23e+30"
+
+strtoIxL returns 17, consuming 8 bytes.
+fI[0] = #40620000 f8658274 7dbc824a
+= 3.16238691003557160385e-4932
+fI[1] = #40620000 f8658274 7dbc824b
+= 3.16238691003557160421e-4932
+fI[0] == strtoxL
+
+
+Input: 1.23e-30
+
+strtoxL consumes 8 bytes and returns 17
+with bits = #3f9b0000 c794337a 808554eb
+printf("%.21Lg") gives 1.88012249978407873966e-4932
+g_xLfmt(0) gives 8 bytes: "1.23e-30"
+
+strtoIxL returns 17, consuming 8 bytes.
+fI[0] = #3f9b0000 c794337a 808554eb
+= 1.88012249978407873966e-4932
+fI[1] = #3f9b0000 c794337a 808554ec
+= 1.88012249978407874003e-4932
+fI[0] == strtoxL
+
+
+Input: 1.23456789e-20
+
+strtoxL consumes 14 bytes and returns 17
+with bits = #3fbc0000 e9340a38 f3d6d352
+printf("%.21Lg") gives 2.76331470044569174626e-4932
+g_xLfmt(0) gives 14 bytes: "1.23456789e-20"
+
+strtoIxL returns 17, consuming 14 bytes.
+fI[0] = #3fbc0000 e9340a38 f3d6d352
+= 2.76331470044569174626e-4932
+fI[1] = #3fbc0000 e9340a38 f3d6d353
+= 2.76331470044569174663e-4932
+fI[0] == strtoxL
+
+
+Input: 1.23456789e-30
+
+strtoxL consumes 14 bytes and returns 17
+with bits = #3f9b0000 c851f19d decca8fc
+printf("%.21Lg") gives 1.89959071937101288293e-4932
+g_xLfmt(0) gives 14 bytes: "1.23456789e-30"
+
+strtoIxL returns 17, consuming 14 bytes.
+fI[0] = #3f9b0000 c851f19d decca8fc
+= 1.89959071937101288293e-4932
+fI[1] = #3f9b0000 c851f19d decca8fd
+= 1.89959071937101288329e-4932
+fI[0] == strtoxL
+
+
+Input: 1.234567890123456789
+
+strtoxL consumes 20 bytes and returns 17
+with bits = #3fff0000 9e065214 62cfdb8d
+printf("%.21Lg") gives 7.88641440657246265535e-4933
+g_xLfmt(0) gives 20 bytes: "1.234567890123456789"
+
+strtoIxL returns 17, consuming 20 bytes.
+fI[0] = #3fff0000 9e065214 62cfdb8d
+= 7.88641440657246265535e-4933
+fI[1] = #3fff0000 9e065214 62cfdb8e
+= 7.886414406572462659e-4933
+fI[0] == strtoxL
+
+
+Input: 1.23456789012345678901234567890123456789
+
+strtoxL consumes 40 bytes and returns 17
+with bits = #3fff0000 9e065214 62cfdb8d
+printf("%.21Lg") gives 7.88641440657246265535e-4933
+g_xLfmt(0) gives 20 bytes: "1.234567890123456789"
+
+strtoIxL returns 17, consuming 40 bytes.
+fI[0] = #3fff0000 9e065214 62cfdb8d
+= 7.88641440657246265535e-4933
+fI[1] = #3fff0000 9e065214 62cfdb8e
+= 7.886414406572462659e-4933
+fI[0] == strtoxL
+
+
+Input: 1.23e306
+
+strtoxL consumes 8 bytes and returns 17
+with bits = #43f70000 e033b668 e30fa6d5
+printf("%.21Lg") gives 2.52688323155200052759e-4932
+g_xLfmt(0) gives 9 bytes: "1.23e+306"
+
+strtoIxL returns 17, consuming 8 bytes.
+fI[0] = #43f70000 e033b668 e30fa6d5
+= 2.52688323155200052759e-4932
+fI[1] = #43f70000 e033b668 e30fa6d6
+= 2.52688323155200052796e-4932
+fI[0] == strtoxL
+
+
+Input: 1.23e-306
+
+strtoxL consumes 9 bytes and returns 33
+with bits = #3c060000 dd1dc2ed 1cb73f25
+printf("%.21Lg") gives 2.44583168427704605801e-4932
+g_xLfmt(0) gives 9 bytes: "1.23e-306"
+
+strtoIxL returns 33, consuming 9 bytes.
+fI[0] = #3c060000 dd1dc2ed 1cb73f24
+= 2.44583168427704605765e-4932
+fI[1] = #3c060000 dd1dc2ed 1cb73f25
+= 2.44583168427704605801e-4932
+fI[1] == strtoxL
+
+
+Input: 1.23e-320
+
+strtoxL consumes 9 bytes and returns 33
+with bits = #3bd80000 9b98c371 844c3f1a
+printf("%.21Lg") gives 7.24867657578821329238e-4933
+g_xLfmt(0) gives 9 bytes: "1.23e-320"
+
+strtoIxL returns 33, consuming 9 bytes.
+fI[0] = #3bd80000 9b98c371 844c3f19
+= 7.24867657578821328874e-4933
+fI[1] = #3bd80000 9b98c371 844c3f1a
+= 7.24867657578821329238e-4933
+fI[1] == strtoxL
+
+
+Input: 1.23e-20
+
+strtoxL consumes 8 bytes and returns 17
+with bits = #3fbc0000 e857267b b3a984f2
+printf("%.21Lg") gives 2.74065070995958800375e-4932
+g_xLfmt(0) gives 8 bytes: "1.23e-20"
+
+strtoIxL returns 17, consuming 8 bytes.
+fI[0] = #3fbc0000 e857267b b3a984f2
+= 2.74065070995958800375e-4932
+fI[1] = #3fbc0000 e857267b b3a984f3
+= 2.74065070995958800411e-4932
+fI[0] == strtoxL
+
+
+Input: 1.23456789e307
+
+strtoxL consumes 14 bytes and returns 17
+with bits = #43fb0000 8ca58a5e d766de75
+printf("%.21Lg") gives 3.32182163192682931854e-4933
+g_xLfmt(0) gives 15 bytes: "1.23456789e+307"
+
+strtoIxL returns 17, consuming 14 bytes.
+fI[0] = #43fb0000 8ca58a5e d766de75
+= 3.32182163192682931854e-4933
+fI[1] = #43fb0000 8ca58a5e d766de76
+= 3.32182163192682932219e-4933
+fI[0] == strtoxL
+
+
+Input: 1.23456589e-307
+
+strtoxL consumes 15 bytes and returns 17
+with bits = #3c030000 b18cb5dc c22fd369
+printf("%.21Lg") gives 1.30149245314004923345e-4932
+g_xLfmt(0) gives 15 bytes: "1.23456589e-307"
+
+strtoIxL returns 17, consuming 15 bytes.
+fI[0] = #3c030000 b18cb5dc c22fd369
+= 1.30149245314004923345e-4932
+fI[1] = #3c030000 b18cb5dc c22fd36a
+= 1.30149245314004923382e-4932
+fI[0] == strtoxL
+
+
+Input: 1.234567890123456789
+
+strtoxL consumes 20 bytes and returns 17
+with bits = #3fff0000 9e065214 62cfdb8d
+printf("%.21Lg") gives 7.88641440657246265535e-4933
+g_xLfmt(0) gives 20 bytes: "1.234567890123456789"
+
+strtoIxL returns 17, consuming 20 bytes.
+fI[0] = #3fff0000 9e065214 62cfdb8d
+= 7.88641440657246265535e-4933
+fI[1] = #3fff0000 9e065214 62cfdb8e
+= 7.886414406572462659e-4933
+fI[0] == strtoxL
+
+
+Input: 1.234567890123456789e301
+
+strtoxL consumes 24 bytes and returns 33
+with bits = #43e70000 937a8baf ab20980c
+printf("%.21Lg") gives 5.11635766619117643114e-4933
+g_xLfmt(0) gives 25 bytes: "1.234567890123456789e+301"
+
+strtoIxL returns 33, consuming 24 bytes.
+fI[0] = #43e70000 937a8baf ab20980b
+= 5.1163576661911764275e-4933
+fI[1] = #43e70000 937a8baf ab20980c
+= 5.11635766619117643114e-4933
+fI[1] == strtoxL
+
+
+Input: 1.234567890123456789e-301
+
+strtoxL consumes 25 bytes and returns 33
+with bits = #3c170000 a953271a 5d069ad9
+printf("%.21Lg") gives 1.08545540462853463561e-4932
+g_xLfmt(0) gives 25 bytes: "1.234567890123456789e-301"
+
+strtoIxL returns 33, consuming 25 bytes.
+fI[0] = #3c170000 a953271a 5d069ad8
+= 1.08545540462853463524e-4932
+fI[1] = #3c170000 a953271a 5d069ad9
+= 1.08545540462853463561e-4932
+fI[1] == strtoxL
+
+
+Input: 1.234567890123456789e-321
+
+strtoxL consumes 25 bytes and returns 33
+with bits = #3bd40000 f9e11b4c ea6dcce9
+printf("%.21Lg") gives 3.20133479952876185942e-4932
+g_xLfmt(0) gives 25 bytes: "1.234567890123456789e-321"
+
+strtoIxL returns 33, consuming 25 bytes.
+fI[0] = #3bd40000 f9e11b4c ea6dcce8
+= 3.20133479952876185905e-4932
+fI[1] = #3bd40000 f9e11b4c ea6dcce9
+= 3.20133479952876185942e-4932
+fI[1] == strtoxL
+
+
+Input: 1e23
+
+strtoxL consumes 4 bytes and returns 1
+with bits = #404b0000 a968163f a57b400
+printf("%.21Lg") gives 1.08760331670538037378e-4932
+g_xLfmt(0) gives 5 bytes: "1e+23"
+
+strtoIxL returns 1, consuming 4 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1e310
+
+strtoxL consumes 5 bytes and returns 33
+with bits = #44040000 de81e40a 34bcf50
+printf("%.21Lg") gives 2.48237171106260601618e-4932
+g_xLfmt(0) gives 6 bytes: "1e+310"
+
+strtoIxL returns 33, consuming 5 bytes.
+fI[0] = #44040000 de81e40a 34bcf4f
+= 2.48237171106260601582e-4932
+fI[1] = #44040000 de81e40a 34bcf50
+= 2.48237171106260601618e-4932
+fI[1] == strtoxL
+
+
+Input: 9.0259718793241475e-277
+
+strtoxL consumes 23 bytes and returns 33
+with bits = #3c690000 ffffffff fffffcf7
+printf("%.21Lg") gives 3.36210314311209322303e-4932
+g_xLfmt(0) gives 23 bytes: "9.0259718793241475e-277"
+
+strtoIxL returns 33, consuming 23 bytes.
+fI[0] = #3c690000 ffffffff fffffcf6
+= 3.36210314311209322267e-4932
+fI[1] = #3c690000 ffffffff fffffcf7
+= 3.36210314311209322303e-4932
+fI[1] == strtoxL
+
+
+Input: 9.025971879324147880346310405869e-277
+
+strtoxL consumes 37 bytes and returns 17
+with bits = #3c6a0000 80000000 0
+printf("%.21Lg") gives 3.36210314311209350626e-4932
+g_xLfmt(0) gives 26 bytes: "9.0259718793241478803e-277"
+
+strtoIxL returns 17, consuming 37 bytes.
+fI[0] = #3c6a0000 80000000 0
+= 3.36210314311209350626e-4932
+fI[1] = #3c6a0000 80000000 1
+= 3.64519953188247460253e-4951
+fI[0] == strtoxL
+
+
+Input: 9.025971879324147880346310405868e-277
+
+strtoxL consumes 37 bytes and returns 33
+with bits = #3c6a0000 80000000 0
+printf("%.21Lg") gives 3.36210314311209350626e-4932
+g_xLfmt(0) gives 26 bytes: "9.0259718793241478803e-277"
+
+strtoIxL returns 33, consuming 37 bytes.
+fI[0] = #3c690000 ffffffff ffffffff
+= 3.3621031431120935059e-4932
+fI[1] = #3c6a0000 80000000 0
+= 3.36210314311209350626e-4932
+fI[1] == strtoxL
+
+
+Input: 2.2250738585072014e-308
+
+strtoxL consumes 23 bytes and returns 17
+with bits = #3c010000 80000000 46
+printf("%.21Lg") gives 2.55163967231773222177e-4949
+g_xLfmt(0) gives 23 bytes: "2.2250738585072014e-308"
+
+strtoIxL returns 17, consuming 23 bytes.
+fI[0] = #3c010000 80000000 46
+= 2.55163967231773222177e-4949
+fI[1] = #3c010000 80000000 47
+= 2.5880916676365569678e-4949
+fI[0] == strtoxL
+
+
+Input: 2.2250738585072013e-308
+
+strtoxL consumes 23 bytes and returns 17
+with bits = #3c000000 ffffffff fffffd4f
+printf("%.21Lg") gives 3.36210314311209325511e-4932
+g_xLfmt(0) gives 23 bytes: "2.2250738585072013e-308"
+
+strtoIxL returns 17, consuming 23 bytes.
+fI[0] = #3c000000 ffffffff fffffd4f
+= 3.36210314311209325511e-4932
+fI[1] = #3c000000 ffffffff fffffd50
+= 3.36210314311209325547e-4932
+fI[0] == strtoxL
+
+Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero)
+
+Input: 1.1
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 8ccccccc cccccccc
+printf("%.21Lg") gives 3.36210314311209350335e-4933
+g_xLfmt(0) gives 21 bytes: "1.0999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[1] = #3fff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[0] == strtoxL
+
+
+Input: -1.1
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 8ccccccc cccccccc
+printf("%.21Lg") gives 3.36210314311209350335e-4933
+g_xLfmt(0) gives 22 bytes: "-1.0999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[1] = #bfff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[1] == strtoxL
+
+
+Input: 1.2
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 99999999 99999999
+printf("%.21Lg") gives 6.72420628622418701034e-4933
+g_xLfmt(0) gives 21 bytes: "1.1999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[1] = #3fff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[0] == strtoxL
+
+
+Input: -1.2
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 99999999 99999999
+printf("%.21Lg") gives 6.72420628622418701034e-4933
+g_xLfmt(0) gives 22 bytes: "-1.1999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[1] = #bfff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[1] == strtoxL
+
+
+Input: 1.3
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 a6666666 66666666
+printf("%.21Lg") gives 1.00863094293362805173e-4932
+g_xLfmt(0) gives 3 bytes: "1.3"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] = #3fff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[0] == strtoxL
+
+
+Input: -1.3
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 a6666666 66666666
+printf("%.21Lg") gives 1.00863094293362805173e-4932
+g_xLfmt(0) gives 4 bytes: "-1.3"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[1] = #bfff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] == strtoxL
+
+
+Input: 1.4
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 b3333333 33333333
+printf("%.21Lg") gives 1.34484125724483740243e-4932
+g_xLfmt(0) gives 3 bytes: "1.4"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] = #3fff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[0] == strtoxL
+
+
+Input: -1.4
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 b3333333 33333333
+printf("%.21Lg") gives 1.34484125724483740243e-4932
+g_xLfmt(0) gives 4 bytes: "-1.4"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[1] = #bfff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] == strtoxL
+
+
+Input: 1.5
+
+strtoxL consumes 3 bytes and returns 1
+with bits = #3fff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 3 bytes: "1.5"
+
+strtoIxL returns 1, consuming 3 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: -1.5
+
+strtoxL consumes 4 bytes and returns 9
+with bits = #bfff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 4 bytes: "-1.5"
+
+strtoIxL returns 9, consuming 4 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1.6
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 cccccccc cccccccc
+printf("%.21Lg") gives 2.01726188586725610347e-4932
+g_xLfmt(0) gives 21 bytes: "1.5999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[1] = #3fff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[0] == strtoxL
+
+
+Input: -1.6
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 cccccccc cccccccc
+printf("%.21Lg") gives 2.01726188586725610347e-4932
+g_xLfmt(0) gives 22 bytes: "-1.5999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[1] = #bfff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[1] == strtoxL
+
+
+Input: 1.7
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 d9999999 99999999
+printf("%.21Lg") gives 2.35347220017846545417e-4932
+g_xLfmt(0) gives 21 bytes: "1.6999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[1] = #3fff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[0] == strtoxL
+
+
+Input: -1.7
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 d9999999 99999999
+printf("%.21Lg") gives 2.35347220017846545417e-4932
+g_xLfmt(0) gives 22 bytes: "-1.6999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[1] = #bfff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[1] == strtoxL
+
+
+Input: 1.8
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 e6666666 66666666
+printf("%.21Lg") gives 2.68968251448967480486e-4932
+g_xLfmt(0) gives 3 bytes: "1.8"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] = #3fff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[0] == strtoxL
+
+
+Input: -1.8
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 e6666666 66666666
+printf("%.21Lg") gives 2.68968251448967480486e-4932
+g_xLfmt(0) gives 4 bytes: "-1.8"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[1] = #bfff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] == strtoxL
+
+
+Input: 1.9
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 f3333333 33333333
+printf("%.21Lg") gives 3.02589282880088415556e-4932
+g_xLfmt(0) gives 3 bytes: "1.9"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] = #3fff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[0] == strtoxL
+
+
+Input: -1.9
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 f3333333 33333333
+printf("%.21Lg") gives 3.02589282880088415556e-4932
+g_xLfmt(0) gives 4 bytes: "-1.9"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[1] = #bfff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] == strtoxL
+
+Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest)
+
+Input: 1.1
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 8ccccccc cccccccd
+printf("%.21Lg") gives 3.36210314311209350699e-4933
+g_xLfmt(0) gives 3 bytes: "1.1"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[1] = #3fff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[1] == strtoxL
+
+
+Input: -1.1
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 8ccccccc cccccccd
+printf("%.21Lg") gives 3.36210314311209350699e-4933
+g_xLfmt(0) gives 4 bytes: "-1.1"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[1] = #bfff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[0] == strtoxL
+
+
+Input: 1.2
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 99999999 9999999a
+printf("%.21Lg") gives 6.72420628622418701398e-4933
+g_xLfmt(0) gives 3 bytes: "1.2"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[1] = #3fff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[1] == strtoxL
+
+
+Input: -1.2
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 99999999 9999999a
+printf("%.21Lg") gives 6.72420628622418701398e-4933
+g_xLfmt(0) gives 4 bytes: "-1.2"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[1] = #bfff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[0] == strtoxL
+
+
+Input: 1.3
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 a6666666 66666666
+printf("%.21Lg") gives 1.00863094293362805173e-4932
+g_xLfmt(0) gives 3 bytes: "1.3"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] = #3fff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[0] == strtoxL
+
+
+Input: -1.3
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 a6666666 66666666
+printf("%.21Lg") gives 1.00863094293362805173e-4932
+g_xLfmt(0) gives 4 bytes: "-1.3"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[1] = #bfff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] == strtoxL
+
+
+Input: 1.4
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 b3333333 33333333
+printf("%.21Lg") gives 1.34484125724483740243e-4932
+g_xLfmt(0) gives 3 bytes: "1.4"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] = #3fff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[0] == strtoxL
+
+
+Input: -1.4
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 b3333333 33333333
+printf("%.21Lg") gives 1.34484125724483740243e-4932
+g_xLfmt(0) gives 4 bytes: "-1.4"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[1] = #bfff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] == strtoxL
+
+
+Input: 1.5
+
+strtoxL consumes 3 bytes and returns 1
+with bits = #3fff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 3 bytes: "1.5"
+
+strtoIxL returns 1, consuming 3 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: -1.5
+
+strtoxL consumes 4 bytes and returns 9
+with bits = #bfff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 4 bytes: "-1.5"
+
+strtoIxL returns 9, consuming 4 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1.6
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 cccccccc cccccccd
+printf("%.21Lg") gives 2.01726188586725610383e-4932
+g_xLfmt(0) gives 3 bytes: "1.6"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[1] = #3fff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[1] == strtoxL
+
+
+Input: -1.6
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 cccccccc cccccccd
+printf("%.21Lg") gives 2.01726188586725610383e-4932
+g_xLfmt(0) gives 4 bytes: "-1.6"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[1] = #bfff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[0] == strtoxL
+
+
+Input: 1.7
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 d9999999 9999999a
+printf("%.21Lg") gives 2.35347220017846545453e-4932
+g_xLfmt(0) gives 3 bytes: "1.7"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[1] = #3fff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[1] == strtoxL
+
+
+Input: -1.7
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 d9999999 9999999a
+printf("%.21Lg") gives 2.35347220017846545453e-4932
+g_xLfmt(0) gives 4 bytes: "-1.7"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[1] = #bfff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[0] == strtoxL
+
+
+Input: 1.8
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 e6666666 66666666
+printf("%.21Lg") gives 2.68968251448967480486e-4932
+g_xLfmt(0) gives 3 bytes: "1.8"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] = #3fff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[0] == strtoxL
+
+
+Input: -1.8
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 e6666666 66666666
+printf("%.21Lg") gives 2.68968251448967480486e-4932
+g_xLfmt(0) gives 4 bytes: "-1.8"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[1] = #bfff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] == strtoxL
+
+
+Input: 1.9
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 f3333333 33333333
+printf("%.21Lg") gives 3.02589282880088415556e-4932
+g_xLfmt(0) gives 3 bytes: "1.9"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] = #3fff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[0] == strtoxL
+
+
+Input: -1.9
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 f3333333 33333333
+printf("%.21Lg") gives 3.02589282880088415556e-4932
+g_xLfmt(0) gives 4 bytes: "-1.9"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[1] = #bfff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] == strtoxL
+
+Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity)
+
+Input: 1.1
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 8ccccccc cccccccd
+printf("%.21Lg") gives 3.36210314311209350699e-4933
+g_xLfmt(0) gives 3 bytes: "1.1"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[1] = #3fff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[1] == strtoxL
+
+
+Input: -1.1
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 8ccccccc cccccccc
+printf("%.21Lg") gives 3.36210314311209350335e-4933
+g_xLfmt(0) gives 22 bytes: "-1.0999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[1] = #bfff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[1] == strtoxL
+
+
+Input: 1.2
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 99999999 9999999a
+printf("%.21Lg") gives 6.72420628622418701398e-4933
+g_xLfmt(0) gives 3 bytes: "1.2"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[1] = #3fff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[1] == strtoxL
+
+
+Input: -1.2
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 99999999 99999999
+printf("%.21Lg") gives 6.72420628622418701034e-4933
+g_xLfmt(0) gives 22 bytes: "-1.1999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[1] = #bfff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[1] == strtoxL
+
+
+Input: 1.3
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 a6666666 66666667
+printf("%.21Lg") gives 1.0086309429336280521e-4932
+g_xLfmt(0) gives 21 bytes: "1.3000000000000000001"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] = #3fff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[1] == strtoxL
+
+
+Input: -1.3
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 a6666666 66666666
+printf("%.21Lg") gives 1.00863094293362805173e-4932
+g_xLfmt(0) gives 4 bytes: "-1.3"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[1] = #bfff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] == strtoxL
+
+
+Input: 1.4
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 b3333333 33333334
+printf("%.21Lg") gives 1.3448412572448374028e-4932
+g_xLfmt(0) gives 21 bytes: "1.4000000000000000001"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] = #3fff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[1] == strtoxL
+
+
+Input: -1.4
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 b3333333 33333333
+printf("%.21Lg") gives 1.34484125724483740243e-4932
+g_xLfmt(0) gives 4 bytes: "-1.4"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[1] = #bfff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] == strtoxL
+
+
+Input: 1.5
+
+strtoxL consumes 3 bytes and returns 1
+with bits = #3fff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 3 bytes: "1.5"
+
+strtoIxL returns 1, consuming 3 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: -1.5
+
+strtoxL consumes 4 bytes and returns 9
+with bits = #bfff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 4 bytes: "-1.5"
+
+strtoIxL returns 9, consuming 4 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1.6
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 cccccccc cccccccd
+printf("%.21Lg") gives 2.01726188586725610383e-4932
+g_xLfmt(0) gives 3 bytes: "1.6"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[1] = #3fff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[1] == strtoxL
+
+
+Input: -1.6
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 cccccccc cccccccc
+printf("%.21Lg") gives 2.01726188586725610347e-4932
+g_xLfmt(0) gives 22 bytes: "-1.5999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[1] = #bfff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[1] == strtoxL
+
+
+Input: 1.7
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 d9999999 9999999a
+printf("%.21Lg") gives 2.35347220017846545453e-4932
+g_xLfmt(0) gives 3 bytes: "1.7"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[1] = #3fff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[1] == strtoxL
+
+
+Input: -1.7
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 d9999999 99999999
+printf("%.21Lg") gives 2.35347220017846545417e-4932
+g_xLfmt(0) gives 22 bytes: "-1.6999999999999999999"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[1] = #bfff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[1] == strtoxL
+
+
+Input: 1.8
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 e6666666 66666667
+printf("%.21Lg") gives 2.68968251448967480523e-4932
+g_xLfmt(0) gives 21 bytes: "1.8000000000000000001"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] = #3fff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[1] == strtoxL
+
+
+Input: -1.8
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 e6666666 66666666
+printf("%.21Lg") gives 2.68968251448967480486e-4932
+g_xLfmt(0) gives 4 bytes: "-1.8"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[1] = #bfff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] == strtoxL
+
+
+Input: 1.9
+
+strtoxL consumes 3 bytes and returns 33
+with bits = #3fff0000 f3333333 33333334
+printf("%.21Lg") gives 3.02589282880088415593e-4932
+g_xLfmt(0) gives 21 bytes: "1.9000000000000000001"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] = #3fff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[1] == strtoxL
+
+
+Input: -1.9
+
+strtoxL consumes 4 bytes and returns 25
+with bits = #bfff0000 f3333333 33333333
+printf("%.21Lg") gives 3.02589282880088415556e-4932
+g_xLfmt(0) gives 4 bytes: "-1.9"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[1] = #bfff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] == strtoxL
+
+Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity)
+
+Input: 1.1
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 8ccccccc cccccccc
+printf("%.21Lg") gives 3.36210314311209350335e-4933
+g_xLfmt(0) gives 21 bytes: "1.0999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[1] = #3fff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[0] == strtoxL
+
+
+Input: -1.1
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 8ccccccc cccccccd
+printf("%.21Lg") gives 3.36210314311209350699e-4933
+g_xLfmt(0) gives 4 bytes: "-1.1"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 8ccccccc cccccccd
+= 3.36210314311209350699e-4933
+fI[1] = #bfff0000 8ccccccc cccccccc
+= 3.36210314311209350335e-4933
+fI[0] == strtoxL
+
+
+Input: 1.2
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 99999999 99999999
+printf("%.21Lg") gives 6.72420628622418701034e-4933
+g_xLfmt(0) gives 21 bytes: "1.1999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[1] = #3fff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[0] == strtoxL
+
+
+Input: -1.2
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 99999999 9999999a
+printf("%.21Lg") gives 6.72420628622418701398e-4933
+g_xLfmt(0) gives 4 bytes: "-1.2"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 99999999 9999999a
+= 6.72420628622418701398e-4933
+fI[1] = #bfff0000 99999999 99999999
+= 6.72420628622418701034e-4933
+fI[0] == strtoxL
+
+
+Input: 1.3
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 a6666666 66666666
+printf("%.21Lg") gives 1.00863094293362805173e-4932
+g_xLfmt(0) gives 3 bytes: "1.3"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[1] = #3fff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[0] == strtoxL
+
+
+Input: -1.3
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 a6666666 66666667
+printf("%.21Lg") gives 1.0086309429336280521e-4932
+g_xLfmt(0) gives 22 bytes: "-1.3000000000000000001"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 a6666666 66666667
+= 1.0086309429336280521e-4932
+fI[1] = #bfff0000 a6666666 66666666
+= 1.00863094293362805173e-4932
+fI[0] == strtoxL
+
+
+Input: 1.4
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 b3333333 33333333
+printf("%.21Lg") gives 1.34484125724483740243e-4932
+g_xLfmt(0) gives 3 bytes: "1.4"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[1] = #3fff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[0] == strtoxL
+
+
+Input: -1.4
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 b3333333 33333334
+printf("%.21Lg") gives 1.3448412572448374028e-4932
+g_xLfmt(0) gives 22 bytes: "-1.4000000000000000001"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 b3333333 33333334
+= 1.3448412572448374028e-4932
+fI[1] = #bfff0000 b3333333 33333333
+= 1.34484125724483740243e-4932
+fI[0] == strtoxL
+
+
+Input: 1.5
+
+strtoxL consumes 3 bytes and returns 1
+with bits = #3fff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 3 bytes: "1.5"
+
+strtoIxL returns 1, consuming 3 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: -1.5
+
+strtoxL consumes 4 bytes and returns 9
+with bits = #bfff0000 c0000000 0
+printf("%.21Lg") gives 1.68105157155604675313e-4932
+g_xLfmt(0) gives 4 bytes: "-1.5"
+
+strtoIxL returns 9, consuming 4 bytes.
+fI[0] == fI[1] == strtoxL
+
+
+Input: 1.6
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 cccccccc cccccccc
+printf("%.21Lg") gives 2.01726188586725610347e-4932
+g_xLfmt(0) gives 21 bytes: "1.5999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[1] = #3fff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[0] == strtoxL
+
+
+Input: -1.6
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 cccccccc cccccccd
+printf("%.21Lg") gives 2.01726188586725610383e-4932
+g_xLfmt(0) gives 4 bytes: "-1.6"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 cccccccc cccccccd
+= 2.01726188586725610383e-4932
+fI[1] = #bfff0000 cccccccc cccccccc
+= 2.01726188586725610347e-4932
+fI[0] == strtoxL
+
+
+Input: 1.7
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 d9999999 99999999
+printf("%.21Lg") gives 2.35347220017846545417e-4932
+g_xLfmt(0) gives 21 bytes: "1.6999999999999999999"
+
+strtoIxL returns 33, consuming 3 bytes.
+fI[0] = #3fff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[1] = #3fff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[0] == strtoxL
+
+
+Input: -1.7
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 d9999999 9999999a
+printf("%.21Lg") gives 2.35347220017846545453e-4932
+g_xLfmt(0) gives 4 bytes: "-1.7"
+
+strtoIxL returns 41, consuming 4 bytes.
+fI[0] = #bfff0000 d9999999 9999999a
+= 2.35347220017846545453e-4932
+fI[1] = #bfff0000 d9999999 99999999
+= 2.35347220017846545417e-4932
+fI[0] == strtoxL
+
+
+Input: 1.8
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 e6666666 66666666
+printf("%.21Lg") gives 2.68968251448967480486e-4932
+g_xLfmt(0) gives 3 bytes: "1.8"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[1] = #3fff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[0] == strtoxL
+
+
+Input: -1.8
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 e6666666 66666667
+printf("%.21Lg") gives 2.68968251448967480523e-4932
+g_xLfmt(0) gives 22 bytes: "-1.8000000000000000001"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 e6666666 66666667
+= 2.68968251448967480523e-4932
+fI[1] = #bfff0000 e6666666 66666666
+= 2.68968251448967480486e-4932
+fI[0] == strtoxL
+
+
+Input: 1.9
+
+strtoxL consumes 3 bytes and returns 17
+with bits = #3fff0000 f3333333 33333333
+printf("%.21Lg") gives 3.02589282880088415556e-4932
+g_xLfmt(0) gives 3 bytes: "1.9"
+
+strtoIxL returns 17, consuming 3 bytes.
+fI[0] = #3fff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[1] = #3fff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[0] == strtoxL
+
+
+Input: -1.9
+
+strtoxL consumes 4 bytes and returns 41
+with bits = #bfff0000 f3333333 33333334
+printf("%.21Lg") gives 3.02589282880088415593e-4932
+g_xLfmt(0) gives 22 bytes: "-1.9000000000000000001"
+
+strtoIxL returns 25, consuming 4 bytes.
+fI[0] = #bfff0000 f3333333 33333334
+= 3.02589282880088415593e-4932
+fI[1] = #bfff0000 f3333333 33333333
+= 3.02589282880088415556e-4932
+fI[0] == strtoxL
+
diff --git a/contrib/gdtoa/test/xsum0.out b/contrib/gdtoa/test/xsum0.out
index 9837ac8..3081e0a 100644
--- a/contrib/gdtoa/test/xsum0.out
+++ b/contrib/gdtoa/test/xsum0.out
@@ -1,11 +1,11 @@
-README e86e9133 2692
+README e3adb571 3095
Qtest.c e8353ffc 5046
dItest.c e33800ce 2371
ddtest.c f9d06e7b 4984
dtest.c ee533ac3 4078
dt.c 7eeda57 6384
ftest.c ec8a6654 3999
-getround.c 161043dd 2143
+getround.c fe659fe7 2503
strtoIdSI.c 7bfb88b 49
strtoIddSI.c 72e8852 50
strtodISI.c ed08b740 49
@@ -32,4 +32,4 @@ x.ou1 f1af5a00 34581
xL.ou1 e349e5c 37165
Q.ou0 e4592b85 28742
Q.ou1 ea0b344d 39572
-makefile b77232c 4939
+makefile 13d36c85 5148
diff --git a/contrib/gdtoa/xsum0.out b/contrib/gdtoa/xsum0.out
index 5fc30d9..2034c71 100644
--- a/contrib/gdtoa/xsum0.out
+++ b/contrib/gdtoa/xsum0.out
@@ -1,25 +1,26 @@
-README 1d9fab5a 14790
+README ee32ce1c 15386
arithchk.c ebbe5bc7 4075
dmisc.c c8daa18 4682
dtoa.c 14f5b9e1 17138
-g_Qfmt.c f791d807 2839
-g__fmt.c 14dca85 2504
-g_ddfmt.c 10eae12a 3695
-g_dfmt.c f36c1014 2503
-g_ffmt.c fb83cfb5 2429
-g_xLfmt.c f216a096 2686
-g_xfmt.c ed824bf3 2775
-gdtoa.c e29409a6 16988
-gdtoa.h fd46e927 4920
-gdtoaimp.h e753264b 19648
-gethex.c f42e6bdf 6247
+g_Qfmt.c f6aad16c 2926
+g__fmt.c 1b8e8cd8 3401
+g_ddfmt.c eb4d0889 4090
+g_dfmt.c 10d694eb 2584
+g_ffmt.c 197652f1 2516
+g_xLfmt.c 3fd29c5 2773
+g_xfmt.c f6a580a 2862
+gdtoa.c eabc1bc5 17024
+gdtoa.h f3c171cc 4945
+gdtoa_fltrnds.h 1aaf5112 421
+gdtoaimp.h 490a372 19893
+gethex.c e7327648 7106
gmisc.c 1859d016 2084
hd_init.c efdbe921 1797
hexnan.c 13f362b7 3462
-makefile f890b12 2932
+makefile 3cd7ae 2933
misc.c 1757f7fc 14252
qnan.c efd33d64 3417
-smisc.c e282e715 3655
+smisc.c 1064c213 3694
strtoIQ.c 1809dfcf 1939
strtoId.c f41ddac2 1931
strtoIdd.c f13e3bc3 2105
@@ -27,17 +28,17 @@ strtoIf.c f12c6af4 1875
strtoIg.c fd8c1bcf 3589
strtoIx.c e50f716d 1960
strtoIxL.c ea0b821b 1931
-strtod.c f6943e52 21001
+strtod.c e7e4addc 21731
strtodI.c 1c2440ce 3915
-strtodg.c 1c1bb220 20499
+strtodg.c f74828cc 21164
strtodnrp.c af895e9 2538
-strtof.c 1c5192d3 2073
-strtopQ.c f116d4f0 2563
-strtopd.c f7681c7a 1671
-strtopdd.c 9864fba 4497
-strtopf.c eb15b627 2067
-strtopx.c 1cafe482 2618
-strtopxL.c 1e4b77e9 2373
+strtof.c 1db524d 2155
+strtopQ.c f244b012 2645
+strtopd.c 1c3c9ce 1751
+strtopdd.c 125d6c19 4580
+strtopf.c 1939f590 2149
+strtopx.c f78a816e 2700
+strtopxL.c b77b701 2455
strtorQ.c 9360a0b 2885
strtord.c af5c50e 2491
strtordd.c 1b266865 4936
diff --git a/contrib/lukemftpd/src/extern.h b/contrib/lukemftpd/src/extern.h
index 2d02106..771fbb8 100644
--- a/contrib/lukemftpd/src/extern.h
+++ b/contrib/lukemftpd/src/extern.h
@@ -139,7 +139,7 @@ void feat(void);
void format_path(char *, const char *);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(char *[], const char *, int);
-char *getline(char *, int, FILE *);
+int getline(char *, int, FILE *);
void init_curclass(void);
void logxfer(const char *, off_t, const char *, const char *,
const struct timeval *, const char *);
diff --git a/contrib/lukemftpd/src/ftpcmd.y b/contrib/lukemftpd/src/ftpcmd.y
index 804a26b..3f3e950 100644
--- a/contrib/lukemftpd/src/ftpcmd.y
+++ b/contrib/lukemftpd/src/ftpcmd.y
@@ -1363,8 +1363,12 @@ lookup(struct tab *p, const char *cmd)
/*
* getline - a hacked up version of fgets to ignore TELNET escape codes.
+ * `s' is the buffer to read into.
+ * `n' is the 1 less than the size of the buffer, to allow trailing NUL
+ * `iop' is the FILE to read from.
+ * Returns 0 on success, -1 on EOF, -2 if the command was too long.
*/
-char *
+int
getline(char *s, int n, FILE *iop)
{
int c;
@@ -1379,7 +1383,7 @@ getline(char *s, int n, FILE *iop)
if (ftpd_debug)
syslog(LOG_DEBUG, "command: %s", s);
tmpline[0] = '\0';
- return(s);
+ return(0);
}
if (c == 0)
tmpline[0] = '\0';
@@ -1418,11 +1422,25 @@ getline(char *s, int n, FILE *iop)
}
}
*cs++ = c;
- if (--n <= 0 || c == '\n')
+ if (--n <= 0) {
+ /*
+ * If command doesn't fit into buffer, discard the
+ * rest of the command and indicate truncation.
+ * This prevents the command to be split up into
+ * multiple commands.
+ */
+ if (ftpd_debug)
+ syslog(LOG_DEBUG,
+ "command too long, last char: %d", c);
+ while (c != '\n' && (c = getc(iop)) != EOF)
+ continue;
+ return (-2);
+ }
+ if (c == '\n')
break;
}
if (c == EOF && cs == s)
- return (NULL);
+ return (-1);
*cs++ = '\0';
if (ftpd_debug) {
if ((curclass.type != CLASS_GUEST &&
@@ -1444,7 +1462,7 @@ getline(char *s, int n, FILE *iop)
syslog(LOG_DEBUG, "command: %.*s", len, s);
}
}
- return (s);
+ return (0);
}
void
@@ -1458,15 +1476,20 @@ ftp_handle_line(char *cp)
void
ftp_loop(void)
{
+ int ret;
while (1) {
(void) alarm(curclass.timeout);
- if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
+ ret = getline(cbuf, sizeof(cbuf)-1, stdin);
+ (void) alarm(0);
+ if (ret == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (ret == -2) {
+ reply(500, "Command too long.");
+ } else {
+ ftp_handle_line(cbuf);
}
- (void) alarm(0);
- ftp_handle_line(cbuf);
}
/*NOTREACHED*/
}
diff --git a/contrib/lukemftpd/src/ftpd.c b/contrib/lukemftpd/src/ftpd.c
index 50a8854..afdd517 100644
--- a/contrib/lukemftpd/src/ftpd.c
+++ b/contrib/lukemftpd/src/ftpd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ftpd.c,v 1.176 2006/05/09 20:18:06 mrg Exp $ */
+/* $NetBSD: ftpd.c,v 1.187 2008/09/13 03:30:35 lukem Exp $ */
/*
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@@ -2896,6 +2896,7 @@ static int
handleoobcmd()
{
char *cp;
+ int ret;
if (!urgflag)
return (0);
@@ -2904,9 +2905,14 @@ handleoobcmd()
if (!transflag)
return (0);
cp = tmpline;
- if (getline(cp, sizeof(tmpline), stdin) == NULL) {
+ ret = getline(cp, sizeof(tmpline)-1, stdin);
+ if (ret == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (ret == -2) {
+ /* Ignore truncated command */
+ /* XXX: abort xfer with "500 command too long", & return 1 ? */
+ return 0;
}
/*
* Manually parse OOB commands, because we can't
diff --git a/contrib/ntp/ntpd/ntp_crypto.c b/contrib/ntp/ntpd/ntp_crypto.c
index 84adbdd..82afe69 100644
--- a/contrib/ntp/ntpd/ntp_crypto.c
+++ b/contrib/ntp/ntpd/ntp_crypto.c
@@ -1612,7 +1612,7 @@ crypto_verify(
*/
EVP_VerifyInit(&ctx, peer->digest);
EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12);
- if (!EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey))
+ if (EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey) <= 0)
return (XEVNT_SIG);
if (peer->crypto & CRYPTO_FLAG_VRFY) {
diff --git a/contrib/openbsm/INSTALL b/contrib/openbsm/INSTALL
index 7afd1f9..c2eac44 100644
--- a/contrib/openbsm/INSTALL
+++ b/contrib/openbsm/INSTALL
@@ -9,6 +9,12 @@ support are built conditionally. Typically, build will be performed using:
./configure
make
+If doing development work on OpenBSM with gcc, the following invocation of
+configure may be preferred in order to generate full compiler warnings and
+force the compile to fail if a warning is found:
+
+ CFLAGS="-Wall -Werror" ./configure
+
To install, use:
make install
diff --git a/contrib/openbsm/Makefile.am b/contrib/openbsm/Makefile.am
index 60fbea9..55849cc 100644
--- a/contrib/openbsm/Makefile.am
+++ b/contrib/openbsm/Makefile.am
@@ -1,15 +1,23 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/Makefile.am#3 $
+# $P4: //depot/projects/trustedbsd/openbsm/Makefile.am#4 $
#
SUBDIRS = \
- bsm \
+ bsm
+
+if HAVE_AUDIT_SYSCALLS
+SUBDIRS += \
+ libauditd
+endif
+
+SUBDIRS += \
libbsm \
bin \
man \
modules \
sys
+
EXTRA_DIST = \
CHANGELOG \
LICENSE \
diff --git a/contrib/openbsm/Makefile.in b/contrib/openbsm/Makefile.in
index 9068b4c..0cc9095 100644
--- a/contrib/openbsm/Makefile.in
+++ b/contrib/openbsm/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/Makefile.in#9 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
@@ -35,6 +35,9 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@HAVE_AUDIT_SYSCALLS_TRUE@am__append_1 = \
+@HAVE_AUDIT_SYSCALLS_TRUE@ libauditd
+
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/config/config.h.in \
@@ -63,7 +66,7 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = bsm libauditd libbsm bin man modules sys
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -183,14 +186,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-SUBDIRS = \
- bsm \
- libbsm \
- bin \
- man \
- modules \
- sys
-
+SUBDIRS = bsm $(am__append_1) libbsm bin man modules sys
EXTRA_DIST = \
CHANGELOG \
LICENSE \
diff --git a/contrib/openbsm/NEWS b/contrib/openbsm/NEWS
index 7bfe756..aeafc8c 100644
--- a/contrib/openbsm/NEWS
+++ b/contrib/openbsm/NEWS
@@ -1,5 +1,69 @@
OpenBSM Version History
+OpenBSM 1.1 alpha 5
+
+- Stub libauditd(3) man page added.
+- All BSM error number constants with BSM_ERRNO_.
+- Interfaces to convert between local and BSM socket types and protocol
+ families have been added: au_bsm_to_domain(3), au_bsm_to_socket_type(3),
+ au_domain_to_bsm(3), and au_socket_type_to_bsm(3), along with definitions
+ of constants in audit_domain.h and audit_socket_type.h. This improves
+ interoperability by converting local constant spaces, which vary by OS, to
+ and from Solaris constants (where available) or OpenBSM constants for
+ protocol domains not present in Solaris (a fair number). These routines
+ should be used when generating and interpreting extended socket tokens.
+- Fix build warnings with full gcc warnings enabled on most supported
+ platforms.
+- Don't compile error strings into bsm_errno.c when building it in the kernel
+ environment.
+- When started by launchd, use the label com.apple.auditd rather than
+ org.trustedbsd.auditd.
+
+OpenBSM 1.1 alpha 4
+
+- With the addition of BSM error number mapping, we also need to map the
+ local error number passed to audit_submit(3) to a BSM error number, rather
+ than have the caller perform that conversion.
+- Reallocate user audit events to avoid collisions with Solaris; adopt a more
+ formal allocation scheme, and add some events allocated in Solaris that
+ will be of immediate use on other platforms.
+- Add an event for Calife.
+- Add au_strerror(3), which allows generating strings for BSM errors
+ directly, rather than requiring applications to map to the local error
+ space, which might not be able to entirely represent the BSM error number
+ space.
+- Major auditd rewrite for launchd(8) support. Add libauditd library that is
+ shared between launchd and auditd.
+- Add AUDIT_TRIGGER_INITIALIZE trigger (sent via 'audit -i') for (re)starting
+ auditing under launchd(8) on Mac OS X.
+- Add 'current' symlink to active audit trail.
+- Add crash recovery of previous audit trail file when detected on audit
+ startup that it has not been properly terminated.
+- Add the event AUE_audit_recovery to indicated when an audit trail file has
+ been recovered from not being properly terminated. This event is stored
+ in the new audit trail file and includes the path of recovered audit trail
+ file.
+- Mac OS X and FreeBSD dependent code in auditd.c is separated into
+ auditd_darwin.c and auditd_fbsd.c files.
+- Add an event for the posix_spawn(2) and fsgetpath(2) Mac OS X system calls.
+- For Mac OS X, we use ASL(3) instead of syslog(3) for logging.
+- Add support for NOTICE level logging.
+
+OpenBSM 1.1 alpha 3
+
+- Add two new functions, au_bsm_to_errno() and au_errno_to_bsm(), to map
+ between BSM error numbers (largely the Solaris definitions) and local
+ errno(2) values for 32-bit and 64-bit return tokens. This is required as
+ operating systems don't agree on some of the values of more recent error
+ numbers.
+- Fix a bug how au_to_exec_args(3) and au_to_exec_env(3) calculates the total
+ size for the token. This bug resulted in "unknown" tokens being printed
+ after the exec args/env tokens.
+- Support for AUT_SOCKET_EX extended socket tokens, which describe a socket
+ using a pair of IPv4/IPv6 and port tuples.
+- OpenBSM BSM file header version bumped for 1.1 release.
+- Deprecated Darwin constants, such as TRAILER_PAD_MAGIC, removed.
+
OpenBSM 1.1 alpha 2
- Include files in OpenBSM are now broken out into two parts: library builds
@@ -348,4 +412,4 @@ OpenBSM 1.0 alpha 1
to support reloading of kernel event table.
- Allow comments in /etc/security configuration files.
-$P4: //depot/projects/trustedbsd/openbsm/NEWS#9 $
+$P4: //depot/projects/trustedbsd/openbsm/NEWS#27 $
diff --git a/contrib/openbsm/README b/contrib/openbsm/README
index 1ded5cd..25e5dca 100644
--- a/contrib/openbsm/README
+++ b/contrib/openbsm/README
@@ -1,4 +1,4 @@
-OpenBSM 1.1 alpha 1
+OpenBSM 1.1 alpha 4
Introduction
@@ -19,6 +19,7 @@ OpenBSM consists of several directories:
bsm/ Library include files for BSM
compat/ Compatibility code to build on various OS's
etc/ Sample /etc/security configuration files
+ libauditd Common audit management functions for auditd and launchd
libbsm/ Implementation of BSM library interfaces and man pages
man/ System call and configuration file man pages
modules/ Directory for auditfilterd module source
@@ -55,4 +56,4 @@ Information on TrustedBSD may be found on the TrustedBSD home page:
http://www.TrustedBSD.org/
-$P4: //depot/projects/trustedbsd/openbsm/README#32 $
+$P4: //depot/projects/trustedbsd/openbsm/README#34 $
diff --git a/contrib/openbsm/TODO b/contrib/openbsm/TODO
index 03cd9e1..855eaa6 100644
--- a/contrib/openbsm/TODO
+++ b/contrib/openbsm/TODO
@@ -20,5 +20,7 @@ OpenBSM TODO
- Document audit_warn event arguments.
- Allow the path /etc/security to be configured at configure-time so that
alternative locations can be used.
+- NLS support for au_strerror(3), which provides error strings for BSM errors
+ not available on the local OS platform.
-$P4: //depot/projects/trustedbsd/openbsm/TODO#11 $
+$P4: //depot/projects/trustedbsd/openbsm/TODO#12 $
diff --git a/contrib/openbsm/VERSION b/contrib/openbsm/VERSION
index 7f2f71c..eb86d90 100644
--- a/contrib/openbsm/VERSION
+++ b/contrib/openbsm/VERSION
@@ -1 +1 @@
-OPENBSM_1_1_ALPHA_2
+OPENBSM_1_1_ALPHA_5
diff --git a/contrib/openbsm/bin/Makefile.in b/contrib/openbsm/bin/Makefile.in
index ddace58..06ef9a7 100644
--- a/contrib/openbsm/bin/Makefile.in
+++ b/contrib/openbsm/bin/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.in#10 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
diff --git a/contrib/openbsm/bin/audit/Makefile.am b/contrib/openbsm/bin/audit/Makefile.am
index ed62929..1b5d554 100644
--- a/contrib/openbsm/bin/audit/Makefile.am
+++ b/contrib/openbsm/bin/audit/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.am#4 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.am#6 $
#
if USE_NATIVE_INCLUDES
@@ -13,11 +13,11 @@ audit_LDADD = $(top_builddir)/libbsm/libbsm.la
man8_MANS = audit.8
if USE_MACH_IPC
-audit_SOURCES = auditd_control_user.c audit.c
-CLEANFILES = auditd_control_user.c auditd_control_user.h
+audit_SOURCES = auditd_controlUser.c audit.c
+CLEANFILES = auditd_controlUser.c auditd_control.h
-auditd_control_user.c: $(top_srcdir)/bin/auditd/auditd_control.defs
- $(MIG) -user auditd_control_user.c -header auditd_control_user.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
+auditd_controlUser.c auditd_control.h: $(top_srcdir)/bin/auditd/auditd_control.defs
+ $(MIG) -user auditd_controlUser.c -header auditd_control.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
else
audit_SOURCES = audit.c
endif
diff --git a/contrib/openbsm/bin/audit/Makefile.in b/contrib/openbsm/bin/audit/Makefile.in
index edaf018..ae2dd6e 100644
--- a/contrib/openbsm/bin/audit/Makefile.in
+++ b/contrib/openbsm/bin/audit/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.in#9 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.in#11 $
#
VPATH = @srcdir@
@@ -49,9 +49,9 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
-am__audit_SOURCES_DIST = audit.c auditd_control_user.c
+am__audit_SOURCES_DIST = audit.c auditd_controlUser.c
@USE_MACH_IPC_FALSE@am_audit_OBJECTS = audit.$(OBJEXT)
-@USE_MACH_IPC_TRUE@am_audit_OBJECTS = auditd_control_user.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@am_audit_OBJECTS = auditd_controlUser.$(OBJEXT) \
@USE_MACH_IPC_TRUE@ audit.$(OBJEXT)
audit_OBJECTS = $(am_audit_OBJECTS)
audit_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la
@@ -188,8 +188,8 @@ top_srcdir = @top_srcdir@
audit_LDADD = $(top_builddir)/libbsm/libbsm.la
man8_MANS = audit.8
@USE_MACH_IPC_FALSE@audit_SOURCES = audit.c
-@USE_MACH_IPC_TRUE@audit_SOURCES = auditd_control_user.c audit.c
-@USE_MACH_IPC_TRUE@CLEANFILES = auditd_control_user.c auditd_control_user.h
+@USE_MACH_IPC_TRUE@audit_SOURCES = auditd_controlUser.c audit.c
+@USE_MACH_IPC_TRUE@CLEANFILES = auditd_controlUser.c auditd_control.h
all: all-am
.SUFFIXES:
@@ -262,7 +262,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_control_user.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_controlUser.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -521,8 +521,8 @@ uninstall-man: uninstall-man8
uninstall-sbinPROGRAMS
-@USE_MACH_IPC_TRUE@auditd_control_user.c: $(top_srcdir)/bin/auditd/auditd_control.defs
-@USE_MACH_IPC_TRUE@ $(MIG) -user auditd_control_user.c -header auditd_control_user.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
+@USE_MACH_IPC_TRUE@auditd_controlUser.c auditd_control.h: $(top_srcdir)/bin/auditd/auditd_control.defs
+@USE_MACH_IPC_TRUE@ $(MIG) -user auditd_controlUser.c -header auditd_control.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/contrib/openbsm/bin/audit/audit.8 b/contrib/openbsm/bin/audit/audit.8
index 4aaa494..b0276d4 100644
--- a/contrib/openbsm/bin/audit/audit.8
+++ b/contrib/openbsm/bin/audit/audit.8
@@ -25,9 +25,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.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#11 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#13 $
.\"
-.Dd October 2, 2006
+.Dd December 11, 2008
.Dt AUDIT 8
.Os
.Sh NAME
@@ -35,7 +35,7 @@
.Nd audit management utility
.Sh SYNOPSIS
.Nm
-.Fl n | s | t
+.Fl i | n | s | t
.Sh DESCRIPTION
The
.Nm
@@ -43,6 +43,13 @@ utility controls the state of the audit system.
One of the following flags is required as an argument to
.Nm :
.Bl -tag -width indent
+.It Fl i
+Initializes and starts auditing.
+This option is currently for Mac OS X only
+and requires
+.Xr auditd 8
+to be configured to run under
+.Xr launchd 8 .
.It Fl n
Forces the audit system to close the existing audit log file and rotate to
a new log file in a location specified in the audit control file.
@@ -59,6 +66,13 @@ and renamed to indicate the time of the shutdown.
The
.Xr auditd 8
daemon must already be running.
+Optionally, it can be configured to be started
+on-demand by
+.Xr launchd 8
+(Mac OS X only).
+The
+.Nm
+utility requires audit administrator privileges for successful operation.
.Sh FILES
.Bl -tag -width ".Pa /etc/security/audit_control" -compact
.It Pa /etc/security/audit_control
@@ -67,7 +81,8 @@ Audit policy file used to configure the auditing system.
.Sh SEE ALSO
.Xr audit 4 ,
.Xr audit_control 5 ,
-.Xr auditd 8
+.Xr auditd 8 ,
+.Xr launchd 8
.Sh HISTORY
The OpenBSM implementation was created by McAfee Research, the security
division of McAfee Inc., under contract to Apple Computer Inc.\& in 2004.
diff --git a/contrib/openbsm/bin/audit/audit.c b/contrib/openbsm/bin/audit/audit.c
index b1415a6..3a07aa7 100644
--- a/contrib/openbsm/bin/audit/audit.c
+++ b/contrib/openbsm/bin/audit/audit.c
@@ -26,7 +26,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.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#11 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#13 $
*/
/*
* Program to trigger the audit daemon with a message that is either:
@@ -47,6 +47,7 @@
#include <bsm/libbsm.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -64,7 +65,15 @@ static int send_trigger(unsigned int);
#include <mach/host_special_ports.h>
#include <servers/bootstrap.h>
-#include "auditd_control_user.h"
+#include "auditd_control.h"
+
+/*
+ * XXX the following is temporary until this can be added to the kernel
+ * audit.h header.
+ */
+#ifndef AUDIT_TRIGGER_INITIALIZE
+#define AUDIT_TRIGGER_INITIALIZE 7
+#endif
static int
send_trigger(unsigned int trigger)
@@ -74,7 +83,12 @@ send_trigger(unsigned int trigger)
error = host_get_audit_control_port(mach_host_self(), &serverPort);
if (error != KERN_SUCCESS) {
- mach_error("Cannot get auditd_control Mach port: ", error);
+ if (geteuid() != 0) {
+ errno = EPERM;
+ perror("audit requires root privileges");
+ } else
+ mach_error("Cannot get auditd_control Mach port:",
+ error);
return (-1);
}
@@ -96,7 +110,10 @@ send_trigger(unsigned int trigger)
error = auditon(A_SENDTRIGGER, &trigger, sizeof(trigger));
if (error != 0) {
- perror("Error sending trigger");
+ if (error == EPERM)
+ perror("audit requires root privileges");
+ else
+ perror("Error sending trigger");
return (-1);
}
@@ -108,7 +125,7 @@ static void
usage(void)
{
- (void)fprintf(stderr, "Usage: audit -n | -s | -t \n");
+ (void)fprintf(stderr, "Usage: audit -i | -n | -s | -t \n");
exit(-1);
}
@@ -124,9 +141,13 @@ main(int argc, char **argv)
if (argc != 2)
usage();
- while ((ch = getopt(argc, argv, "nst")) != -1) {
+ while ((ch = getopt(argc, argv, "inst")) != -1) {
switch(ch) {
+ case 'i':
+ trigger = AUDIT_TRIGGER_INITIALIZE;
+ break;
+
case 'n':
trigger = AUDIT_TRIGGER_ROTATE_USER;
break;
diff --git a/contrib/openbsm/bin/auditd/Makefile.am b/contrib/openbsm/bin/auditd/Makefile.am
index f65b155..2372fa6 100644
--- a/contrib/openbsm/bin/auditd/Makefile.am
+++ b/contrib/openbsm/bin/auditd/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.am#4 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.am#5 $
#
if USE_NATIVE_INCLUDES
@@ -9,18 +9,18 @@ INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
endif
sbin_PROGRAMS = auditd
-auditd_LDADD = $(top_builddir)/libbsm/libbsm.la
+auditd_LDADD = $(top_builddir)/libbsm/libbsm.la $(top_builddir)/libauditd/libauditd.la
man8_MANS = auditd.8
if USE_MACH_IPC
-auditd_SOURCES = auditd_control_server.c audit_triggers_server.c audit_warn.c auditd.c
-CLEANFILES = auditd_control_server.c auditd_control_server.h audit_triggers_server.c audit_triggers_server.h
+auditd_SOURCES = auditd_controlServer.c audit_triggersServer.c audit_warn.c auditd.c auditd_darwin.c
+CLEANFILES = auditd_control_server.c auditd_controlServer.h audit_triggersServer.c audit_triggersServer.h
-auditd_control_server.c: auditd_control.defs
- $(MIG) -user /dev/null -header /dev/null -server auditd_control_server.c -sheader auditd_control_server.h $(top_srcdir)/bin/auditd/auditd_control.defs
+auditd_controlServer.c auditd_controlServer.h: auditd_control.defs
+ $(MIG) -user /dev/null -header /dev/null -server auditd_controlServer.c -sheader auditd_controlServer.h $(top_srcdir)/bin/auditd/auditd_control.defs
-audit_triggers_server.c: audit_triggers.defs
- $(MIG) -user /dev/null -header /dev/null -server audit_triggers_server.c -sheader audit_triggers_server.h $(top_srcdir)/bin/auditd/audit_triggers.defs
+audit_triggersServer.c audit_triggersServer.h: audit_triggers.defs
+ $(MIG) -user /dev/null -header /dev/null -server audit_triggersServer.c -sheader audit_triggersServer.h $(top_srcdir)/bin/auditd/audit_triggers.defs
else
-auditd_SOURCES = audit_warn.c auditd.c
+auditd_SOURCES = audit_warn.c auditd.c auditd_fbsd.c
endif
diff --git a/contrib/openbsm/bin/auditd/Makefile.in b/contrib/openbsm/bin/auditd/Makefile.in
index 731607c..44240d6 100644
--- a/contrib/openbsm/bin/auditd/Makefile.in
+++ b/contrib/openbsm/bin/auditd/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.in#9 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.in#10 $
#
VPATH = @srcdir@
@@ -49,16 +49,17 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
-am__auditd_SOURCES_DIST = audit_warn.c auditd.c \
- auditd_control_server.c audit_triggers_server.c
+am__auditd_SOURCES_DIST = audit_warn.c auditd.c auditd_fbsd.c \
+ auditd_controlServer.c audit_triggersServer.c auditd_darwin.c
@USE_MACH_IPC_FALSE@am_auditd_OBJECTS = audit_warn.$(OBJEXT) \
-@USE_MACH_IPC_FALSE@ auditd.$(OBJEXT)
-@USE_MACH_IPC_TRUE@am_auditd_OBJECTS = \
-@USE_MACH_IPC_TRUE@ auditd_control_server.$(OBJEXT) \
-@USE_MACH_IPC_TRUE@ audit_triggers_server.$(OBJEXT) \
-@USE_MACH_IPC_TRUE@ audit_warn.$(OBJEXT) auditd.$(OBJEXT)
+@USE_MACH_IPC_FALSE@ auditd.$(OBJEXT) auditd_fbsd.$(OBJEXT)
+@USE_MACH_IPC_TRUE@am_auditd_OBJECTS = auditd_controlServer.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@ audit_triggersServer.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@ audit_warn.$(OBJEXT) auditd.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@ auditd_darwin.$(OBJEXT)
auditd_OBJECTS = $(am_auditd_OBJECTS)
-auditd_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la
+auditd_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la \
+ $(top_builddir)/libauditd/libauditd.la
DEFAULT_INCLUDES = -I. -I$(top_builddir)/config@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
@@ -189,11 +190,11 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@USE_NATIVE_INCLUDES_FALSE@INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
@USE_NATIVE_INCLUDES_TRUE@INCLUDES = -I$(top_builddir) -I$(top_srcdir)
-auditd_LDADD = $(top_builddir)/libbsm/libbsm.la
+auditd_LDADD = $(top_builddir)/libbsm/libbsm.la $(top_builddir)/libauditd/libauditd.la
man8_MANS = auditd.8
-@USE_MACH_IPC_FALSE@auditd_SOURCES = audit_warn.c auditd.c
-@USE_MACH_IPC_TRUE@auditd_SOURCES = auditd_control_server.c audit_triggers_server.c audit_warn.c auditd.c
-@USE_MACH_IPC_TRUE@CLEANFILES = auditd_control_server.c auditd_control_server.h audit_triggers_server.c audit_triggers_server.h
+@USE_MACH_IPC_FALSE@auditd_SOURCES = audit_warn.c auditd.c auditd_fbsd.c
+@USE_MACH_IPC_TRUE@auditd_SOURCES = auditd_controlServer.c audit_triggersServer.c audit_warn.c auditd.c auditd_darwin.c
+@USE_MACH_IPC_TRUE@CLEANFILES = auditd_control_server.c auditd_controlServer.h audit_triggersServer.c audit_triggersServer.h
all: all-am
.SUFFIXES:
@@ -265,10 +266,12 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_triggers_server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_triggersServer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_warn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_control_server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_controlServer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_darwin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_fbsd.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -527,11 +530,11 @@ uninstall-man: uninstall-man8
uninstall-sbinPROGRAMS
-@USE_MACH_IPC_TRUE@auditd_control_server.c: auditd_control.defs
-@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server auditd_control_server.c -sheader auditd_control_server.h $(top_srcdir)/bin/auditd/auditd_control.defs
+@USE_MACH_IPC_TRUE@auditd_controlServer.c auditd_controlServer.h: auditd_control.defs
+@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server auditd_controlServer.c -sheader auditd_controlServer.h $(top_srcdir)/bin/auditd/auditd_control.defs
-@USE_MACH_IPC_TRUE@audit_triggers_server.c: audit_triggers.defs
-@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server audit_triggers_server.c -sheader audit_triggers_server.h $(top_srcdir)/bin/auditd/audit_triggers.defs
+@USE_MACH_IPC_TRUE@audit_triggersServer.c audit_triggersServer.h: audit_triggers.defs
+@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server audit_triggersServer.c -sheader audit_triggersServer.h $(top_srcdir)/bin/auditd/audit_triggers.defs
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/contrib/openbsm/bin/auditd/audit_warn.c b/contrib/openbsm/bin/auditd/audit_warn.c
index 7bc7a14..6dfb3bd 100644
--- a/contrib/openbsm/bin/auditd/audit_warn.c
+++ b/contrib/openbsm/bin/auditd/audit_warn.c
@@ -26,7 +26,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.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#9 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#10 $
*/
#include <sys/types.h>
@@ -71,20 +71,15 @@ auditwarnlog(char *args[])
}
/*
- * Indicates that the hard limit for all filesystems has been exceeded count
- * times.
+ * Indicates that the hard limit for all filesystems has been exceeded.
*/
int
-audit_warn_allhard(int count)
+audit_warn_allhard(void)
{
- char intstr[12];
- char *args[3];
-
- snprintf(intstr, 12, "%d", count);
+ char *args[2];
args[0] = HARDLIM_ALL_WARN;
- args[1] = intstr;
- args[2] = NULL;
+ args[1] = NULL;
return (auditwarnlog(args));
}
diff --git a/contrib/openbsm/bin/auditd/auditd.8 b/contrib/openbsm/bin/auditd/auditd.8
index 199b9cc..d680edd 100644
--- a/contrib/openbsm/bin/auditd/auditd.8
+++ b/contrib/openbsm/bin/auditd/auditd.8
@@ -25,9 +25,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.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.8#14 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.8#17 $
.\"
-.Dd October 2, 2006
+.Dd December 11, 2008
.Dt AUDITD 8
.Os
.Sh NAME
@@ -35,7 +35,7 @@
.Nd audit log management daemon
.Sh SYNOPSIS
.Nm
-.Op Fl d
+.Op Fl d | l
.Sh DESCRIPTION
The
.Nm
@@ -50,7 +50,16 @@ The options are as follows:
.Bl -tag -width indent
.It Fl d
Starts the daemon in debug mode \[em] it will not daemonize.
+.It Fl l
+This option is for when
+.Nm
+is configured to start on-demand using
+.Xr launchd 8 .
.El
+.Pp
+Optionally, the audit review group "audit" may be created.
+Non-privileged
+users that are members of this group may read the audit trail log files.
.Sh NOTE
To assure uninterrupted audit support, the
.Nm
@@ -63,20 +72,33 @@ the
.Pa audit_control
file.
.Pp
-.\" Sending a
-.\" .Dv SIGHUP
-.\" to a running
-.\" .Nm
-.\" daemon will force it to exit.
-Sending a
-.Dv SIGTERM
-to a running
+If
+.Nm
+is started on-demand by
+.Xr launchd 8
+then auditing should only be started and stopped with
+.Xr audit 8 .
+.Pp
+On Mac OS X,
.Nm
-daemon will force it to exit.
+uses the
+.Xr asl 3
+API for writing system log messages.
+Therefore, only the audit administrator
+and members of the audit review group will be able to read the
+system log entries.
.Sh FILES
-.Bl -tag -width ".Pa /var/audit" -compact
+.Bl -tag -width ".Pa /etc/security" -compact
.It Pa /var/audit
Default directory for storing audit log files.
+.Pp
+.It Pa /etc/security
+The directory containing the auditing configuration files
+.Xr audit_class 5 ,
+.Xr audit_control 5 ,
+.Xr audit_event 5 ,
+and
+.Xr audit_warn 5 .
.El
.Sh COMPATIBILITY
The historical
@@ -92,9 +114,15 @@ and
and are no longer available as arguments to
.Nm .
.Sh SEE ALSO
+.Xr asl 3 ,
+.Xr libauditd 3 ,
.Xr audit 4 ,
+.Xr audit_class 5 ,
.Xr audit_control 5 ,
-.Xr audit 8
+.Xr audit_event 5 ,
+.Xr audit_warn 5 ,
+.Xr audit 8 ,
+.Xr launchd 8
.Sh HISTORY
The OpenBSM implementation was created by McAfee Research, the security
division of McAfee Inc., under contract to Apple Computer Inc.\& in 2004.
diff --git a/contrib/openbsm/bin/auditd/auditd.c b/contrib/openbsm/bin/auditd/auditd.c
index e0c03d0..20300c1 100644
--- a/contrib/openbsm/bin/auditd/auditd.c
+++ b/contrib/openbsm/bin/auditd/auditd.c
@@ -26,30 +26,29 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#39 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#41 $
*/
-#include <sys/param.h>
+#include <sys/types.h>
#include <config/config.h>
#include <sys/dirent.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
#ifdef HAVE_FULL_QUEUE_H
#include <sys/queue.h>
#else /* !HAVE_FULL_QUEUE_H */
#include <compat/queue.h>
#endif /* !HAVE_FULL_QUEUE_H */
+#include <sys/mman.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <bsm/audit.h>
#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
#include <bsm/libbsm.h>
-#include <netinet/in.h>
-
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -60,115 +59,88 @@
#include <unistd.h>
#include <signal.h>
#include <string.h>
-#include <syslog.h>
-#include <netdb.h>
#include "auditd.h"
-#ifdef USE_MACH_IPC
-#include <notify.h>
-#include <mach/port.h>
-#include <mach/mach_error.h>
-#include <mach/mach_traps.h>
-#include <mach/mach.h>
-#include <mach/host_special_ports.h>
-
-#include "auditd_control_server.h"
-#include "audit_triggers_server.h"
-#endif /* USE_MACH_IPC */
#ifndef HAVE_STRLCPY
#include <compat/strlcpy.h>
#endif
-#define NA_EVENT_STR_SIZE 25
-#define POL_STR_SIZE 128
-static int ret, minval;
-static char *lastfile = NULL;
-static int allhardcount = 0;
-static int sigchlds, sigchlds_handled;
-static int sighups, sighups_handled;
-#ifndef USE_MACH_IPC
-static int sigterms, sigterms_handled;
-static int triggerfd = 0;
-
-#else /* USE_MACH_IPC */
-
-static mach_port_t control_port = MACH_PORT_NULL;
-static mach_port_t signal_port = MACH_PORT_NULL;
-static mach_port_t port_set = MACH_PORT_NULL;
-
-#ifndef __BSM_INTERNAL_NOTIFY_KEY
-#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
-#endif /* __BSM_INTERNAL_NOTIFY_KEY */
-#endif /* USE_MACH_IPC */
-
-static TAILQ_HEAD(, dir_ent) dir_q;
-
-static int config_audit_controls(void);
-
/*
- * Error starting auditd
+ * XXX the following is temporary until this can be added to the kernel
+ * audit.h header.
*/
-static void
-fail_exit(void)
-{
+#ifndef AUDIT_TRIGGER_INITIALIZE
+#define AUDIT_TRIGGER_INITIALIZE 7
+#endif
- audit_warn_nostart();
- exit(1);
-}
+/*
+ * LaunchD flag (Mac OS X and, maybe, FreeBSD only.) See launchd(8) and
+ * http://wiki.freebsd.org/launchd for more information.
+ *
+ * In order for auditd to work "on demand" with launchd(8) it can't:
+ * call daemon(3)
+ * call fork and having the parent process exit
+ * change uids or gids.
+ * set up the current working directory or chroot.
+ * set the session id
+ * change stdio to /dev/null.
+ * call setrusage(2)
+ * call setpriority(2)
+ * Ignore SIGTERM.
+ * auditd (in 'launchd mode') is launched on demand so it must catch
+ * SIGTERM to exit cleanly.
+ */
+static int launchd_flag = 0;
/*
- * Free our local list of directory names.
+ * The GID of the audit review group (if used). The audit trail files and
+ * system logs (Mac OS X only) can only be reviewed by members of this group
+ * or the audit administrator (aka. "root").
*/
-static void
-free_dir_q(void)
-{
- struct dir_ent *dirent;
+static gid_t audit_review_gid = -1;
- while ((dirent = TAILQ_FIRST(&dir_q))) {
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- free(dirent->dirname);
- free(dirent);
- }
-}
+/*
+ * The path and file name of the last audit trail file.
+ */
+static char *lastfile = NULL;
/*
- * Generate the timestamp string.
+ * Error starting auditd. Run warn script and exit.
*/
-static int
-getTSstr(char *buf, int len)
+static void
+fail_exit(void)
{
- struct timeval ts;
- struct timezone tzp;
- time_t tt;
- if (gettimeofday(&ts, &tzp) != 0)
- return (-1);
- tt = (time_t)ts.tv_sec;
- if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
- return (-1);
- return (0);
+ audit_warn_nostart();
+ exit(1);
}
/*
- * Concat the directory name to the given file name.
- * XXX We should affix the hostname also
+ * Follow the 'current' symlink to get the active trail file name.
*/
static char *
-affixdir(char *name, struct dir_ent *dirent)
+get_curfile(void)
{
- char *fn = NULL;
+ char *cf;
+ int len;
- syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
- /*
- * Sanity check on file name.
- */
- if (strlen(name) != (FILENAME_LEN - 1)) {
- syslog(LOG_ERR, "Invalid file name: %s", name);
+ cf = malloc(MAXPATHLEN);
+ if (cf == NULL) {
+ auditd_log_err("malloc failed: %m");
+ return (NULL);
+ }
+
+ len = readlink(AUDIT_CURRENT_LINK, cf, MAXPATHLEN - 1);
+ if (len < 0) {
+ free(cf);
return (NULL);
}
- asprintf(&fn, "%s/%s", dirent->dirname, name);
- return (fn);
+
+ /* readlink() doesn't terminate string. */
+ cf[len] = '\0';
+
+ return (cf);
}
/*
@@ -181,6 +153,10 @@ close_lastfile(char *TS)
char *oldname;
size_t len;
+ /* If lastfile is NULL try to get it from the 'current' link. */
+ if (lastfile == NULL)
+ lastfile = get_curfile();
+
if (lastfile != NULL) {
len = strlen(lastfile) + 1;
oldname = (char *)malloc(len);
@@ -192,16 +168,21 @@ close_lastfile(char *TS)
if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
strlcpy(ptr, TS, TIMESTAMP_LEN);
if (rename(oldname, lastfile) != 0)
- syslog(LOG_ERR,
+ auditd_log_err(
"Could not rename %s to %s: %m", oldname,
lastfile);
else {
- syslog(LOG_INFO, "renamed %s to %s",
+ /*
+ * Remove the 'current' symlink since the link
+ * is now invalid.
+ */
+ (void) unlink(AUDIT_CURRENT_LINK);
+ auditd_log_notice( "renamed %s to %s",
oldname, lastfile);
audit_warn_closefile(lastfile);
}
} else
- syslog(LOG_ERR, "Could not rename %s to %s", oldname,
+ auditd_log_err( "Could not rename %s to %s", oldname,
lastfile);
free(lastfile);
free(oldname);
@@ -211,168 +192,81 @@ close_lastfile(char *TS)
}
/*
- * Create the new audit file with appropriate permissions and ownership. Try
- * to clean up if something goes wrong.
- */
-static int
-#ifdef AUDIT_REVIEW_GROUP
-open_trail(const char *fname, uid_t uid, gid_t gid)
-#else
-open_trail(const char *fname)
-#endif
-{
- int error, fd;
-
- fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
- if (fd < 0)
- return (-1);
-#ifdef AUDIT_REVIEW_GROUP
- if (fchown(fd, uid, gid) < 0) {
- error = errno;
- close(fd);
- (void)unlink(fname);
- errno = error;
- return (-1);
- }
-#endif
- return (fd);
-}
-
-/*
* Create the new file name, swap with existing audit file.
*/
static int
swap_audit_file(void)
{
- char timestr[FILENAME_LEN];
- char *fn;
+ int err;
+ char *newfile;
char TS[TIMESTAMP_LEN];
- struct dir_ent *dirent;
-#ifdef AUDIT_REVIEW_GROUP
- struct group *grp;
- gid_t gid;
- uid_t uid;
-#endif
- int error, fd;
+ time_t tt;
- if (getTSstr(TS, TIMESTAMP_LEN) != 0)
+ if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0)
return (-1);
+ err = auditd_swap_trail(TS, &newfile, audit_review_gid,
+ audit_warn_getacdir);
+ if (err != ADE_NOERR) {
+ auditd_log_err( "%s: %m", auditd_strerror(err));
+ if (err != ADE_ACTL)
+ return (-1);
+ }
- snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED);
-
-#ifdef AUDIT_REVIEW_GROUP
/*
- * XXXRW: Currently, this code falls back to the daemon gid, which is
- * likely the wheel group. Is there a better way to deal with this?
+ * Only close the last file if were in an auditing state before
+ * calling swap_audit_file(). We may need to recover from a crash.
*/
- grp = getgrnam(AUDIT_REVIEW_GROUP);
- if (grp == NULL) {
- syslog(LOG_INFO,
- "Audit review group '%s' not available, using daemon gid",
- AUDIT_REVIEW_GROUP);
- gid = -1;
- } else
- gid = grp->gr_gid;
- uid = getuid();
-#endif
+ if (auditd_get_state() == AUD_STATE_ENABLED)
+ close_lastfile(TS);
- /* Try until we succeed. */
- while ((dirent = TAILQ_FIRST(&dir_q))) {
- if ((fn = affixdir(timestr, dirent)) == NULL) {
- syslog(LOG_INFO, "Failed to swap log at time %s",
- timestr);
- return (-1);
- }
- /*
- * Create and open the file; then close and pass to the
- * kernel if all went well.
- */
- syslog(LOG_INFO, "New audit file is %s", fn);
-#ifdef AUDIT_REVIEW_GROUP
- fd = open_trail(fn, uid, gid);
-#else
- fd = open_trail(fn);
-#endif
- if (fd < 0)
- warn("open(%s)", fn);
- if (fd >= 0) {
- error = auditctl(fn);
- if (error) {
- syslog(LOG_ERR,
- "auditctl failed setting log file! : %s",
- strerror(errno));
- close(fd);
- } else {
- /* Success. */
-#ifdef USE_MACH_IPC
- /*
- * auditctl() potentially changes the audit
- * state so post that the audit config (may
- * have) changed.
- */
- notify_post(__BSM_INTERNAL_NOTIFY_KEY);
-#endif
- close_lastfile(TS);
- lastfile = fn;
- close(fd);
- return (0);
- }
- }
+ /*
+ * auditd_swap_trail() potentially enables auditing (if not already
+ * enabled) so updated the cached state as well.
+ */
+ auditd_set_state(AUD_STATE_ENABLED);
+
+ /*
+ * Create 'current' symlink. Recover from crash, if needed.
+ */
+ if (auditd_new_curlink(newfile) != 0)
+ auditd_log_err("auditd_new_curlink(\"%s\") failed: %s: %m",
+ newfile, auditd_strerror(err));
- /*
- * Tell the administrator about lack of permissions for dir.
- */
- audit_warn_getacdir(dirent->dirname);
+ lastfile = newfile;
+ auditd_log_notice("New audit file is %s", newfile);
- /* Try again with a different directory. */
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- free(dirent->dirname);
- free(dirent);
- }
- syslog(LOG_ERR, "Log directories exhausted");
- return (-1);
+ return (0);
}
/*
- * Read the audit_control file contents.
+ * Create a new audit log trail file and swap with the current one, if any.
*/
static int
-read_control_file(void)
+do_trail_file(void)
{
- char cur_dir[MAXNAMLEN];
- struct dir_ent *dirent;
- au_qctrl_t qctrl;
+ int err;
/*
- * Clear old values. Force a re-read of the file the next time.
+ * First, refresh the list of audit log directories.
*/
- free_dir_q();
- endac();
-
- /*
- * Read the list of directories into a local linked list.
- *
- * XXX We should use the reentrant interfaces once they are
- * available.
- */
- while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
- dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
- if (dirent == NULL)
- return (-1);
- dirent->softlim = 0;
- dirent->dirname = (char *) malloc(MAXNAMLEN);
- if (dirent->dirname == NULL) {
- free(dirent);
+ err = auditd_read_dirs(audit_warn_soft, audit_warn_hard);
+ if (err) {
+ auditd_log_err("auditd_read_dirs(): %s",
+ auditd_strerror(err));
+ if (err == ADE_HARDLIM)
+ audit_warn_allhard();
+ if (err != ADE_SOFTLIM)
return (-1);
- }
- strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
- TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
+ else
+ audit_warn_allsoft();
+ /* continue on with soft limit error */
}
- allhardcount = 0;
+ /*
+ * Create a new file and swap with the one being used in kernel.
+ */
if (swap_audit_file() == -1) {
- syslog(LOG_ERR, "Could not swap audit file");
/*
* XXX Faulty directory listing? - user should be given
* XXX an opportunity to change the audit_control file
@@ -381,26 +275,54 @@ read_control_file(void)
return (-1);
}
- /*
- * XXX There are synchronization problems here
- * XXX what should we do if a trigger for the earlier limit
- * XXX is generated here?
- */
- if (0 == (ret = getacmin(&minval))) {
- syslog(LOG_DEBUG, "min free = %d", minval);
- if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
- syslog(LOG_ERR,
- "could not get audit queue settings");
- return (-1);
- }
- qctrl.aq_minfree = minval;
- if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
- syslog(LOG_ERR,
- "could not set audit queue settings");
- return (-1);
- }
+ return (0);
+}
+
+/*
+ * Start up auditing.
+ */
+static void
+audit_setup(void)
+{
+ int err;
+
+ if (do_trail_file() == -1) {
+ auditd_log_err("Error creating audit trail file");
+ fail_exit();
}
+ /* Generate an audit record. */
+ err = auditd_gen_record(AUE_audit_startup, NULL);
+ if (err)
+ auditd_log_err("auditd_gen_record(AUE_audit_startup) %s: %m",
+ auditd_strerror(err));
+
+ if (auditd_config_controls() == 0)
+ auditd_log_info("Audit controls init successful");
+ else
+ auditd_log_err("Audit controls init failed");
+
+}
+
+
+/*
+ * Close auditd pid file and trigger mechanism.
+ */
+static int
+close_misc(void)
+{
+
+ auditd_close_dirs();
+ if (unlink(AUDITD_PIDFILE) == -1 && errno != ENOENT) {
+ auditd_log_err("Couldn't remove %s: %m", AUDITD_PIDFILE);
+ return (1);
+ }
+ endac();
+
+ if (auditd_close_trigger() != 0) {
+ auditd_log_err("Error closing trigger messaging mechanism");
+ return (1);
+ }
return (0);
}
@@ -410,107 +332,48 @@ read_control_file(void)
static int
close_all(void)
{
- struct auditinfo ai;
int err_ret = 0;
char TS[TIMESTAMP_LEN];
- int aufd;
- token_t *tok;
+ int err;
long cond;
+ time_t tt;
- /* Generate an audit record. */
- if ((aufd = au_open()) == -1)
- syslog(LOG_ERR, "Could not create audit shutdown event.");
- else {
- if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
- au_write(aufd, tok);
- /*
- * XXX we need to implement extended subject tokens so we can
- * effectively represent terminal lines with this token type.
- */
- bzero(&ai, sizeof(ai));
- if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
- getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
- != NULL)
- au_write(aufd, tok);
- if ((tok = au_to_return32(0, 0)) != NULL)
- au_write(aufd, tok);
- if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
- syslog(LOG_ERR,
- "Could not close audit shutdown event.");
- }
+ err = auditd_gen_record(AUE_audit_shutdown, NULL);
+ if (err)
+ auditd_log_err("auditd_gen_record(AUE_audit_shutdown) %s: %m",
+ auditd_strerror(err));
/* Flush contents. */
cond = AUC_DISABLED;
err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
if (err_ret != 0) {
- syslog(LOG_ERR, "Disabling audit failed! : %s",
- strerror(errno));
+ auditd_log_err("Disabling audit failed! : %s", strerror(errno));
err_ret = 1;
}
-#ifdef USE_MACH_IPC
- /*
- * Post a notification that the audit config changed.
+
+ /*
+ * Updated the cached state that auditing has been disabled.
*/
- notify_post(__BSM_INTERNAL_NOTIFY_KEY);
-#endif
- if (getTSstr(TS, TIMESTAMP_LEN) == 0)
+ auditd_set_state(AUD_STATE_DISABLED);
+
+ if (getTSstr(tt, TS, TIMESTAMP_LEN) == 0)
close_lastfile(TS);
if (lastfile != NULL)
free(lastfile);
- free_dir_q();
- if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
- syslog(LOG_ERR, "Could not unregister");
+ err_ret += close_misc();
+
+ if (err_ret) {
+ auditd_log_err("Could not unregister");
audit_warn_postsigterm();
- return (1);
}
- endac();
-#ifndef USE_MACH_IPC
- if (close(triggerfd) != 0)
- syslog(LOG_ERR, "Error closing control file");
-#endif
- syslog(LOG_INFO, "Finished");
- return (0);
+ auditd_log_info("Finished");
+ return (err_ret);
}
/*
- * When we get a signal, we are often not at a clean point. So, little can
- * be done in the signal handler itself. Instead, we send a message to the
- * main servicing loop to do proper handling from a non-signal-handler
- * context.
- */
-#ifdef USE_MACH_IPC
-static void
-relay_signal(int signal)
-{
- mach_msg_empty_send_t msg;
-
- msg.header.msgh_id = signal;
- msg.header.msgh_remote_port = signal_port;
- msg.header.msgh_local_port = MACH_PORT_NULL;
- msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
- mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
- 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-}
-
-#else /* ! USE_MACH_IPC */
-
-static void
-relay_signal(int signal)
-{
-
- if (signal == SIGHUP)
- sighups++;
- if (signal == SIGTERM)
- sigterms++;
- if (signal == SIGCHLD)
- sigchlds++;
-}
-#endif /* ! USE_MACH_IPC */
-
-/*
- * Registering the daemon.
+ * Register the daemon with the signal handler and the auditd pid file.
*/
static int
register_daemon(void)
@@ -520,24 +383,29 @@ register_daemon(void)
pid_t pid;
/* Set up the signal hander. */
- if (signal(SIGTERM, relay_signal) == SIG_ERR) {
- syslog(LOG_ERR,
+ if (signal(SIGTERM, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
"Could not set signal handler for SIGTERM");
fail_exit();
}
- if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
- syslog(LOG_ERR,
+ if (signal(SIGCHLD, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
"Could not set signal handler for SIGCHLD");
fail_exit();
}
- if (signal(SIGHUP, relay_signal) == SIG_ERR) {
- syslog(LOG_ERR,
+ if (signal(SIGHUP, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
"Could not set signal handler for SIGHUP");
fail_exit();
}
+ if (signal(SIGALRM, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
+ "Could not set signal handler for SIGALRM");
+ fail_exit();
+ }
if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
- syslog(LOG_ERR, "Could not open PID file");
+ auditd_log_err("Could not open PID file");
audit_warn_tmpfile();
return (-1);
}
@@ -545,7 +413,7 @@ register_daemon(void)
/* Attempt to lock the pid file; if a lock is present, exit. */
fd = fileno(pidfile);
if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
- syslog(LOG_ERR,
+ auditd_log_err(
"PID file is locked (is another auditd running?).");
audit_warn_ebusy();
return (-1);
@@ -562,48 +430,6 @@ register_daemon(void)
return (0);
}
-#ifdef USE_MACH_IPC
-/*
- * Implementation of the auditd_control() MIG simpleroutine.
- *
- * React to input from the audit(1) tool.
- */
-
-/* ARGSUSED */
-kern_return_t
-auditd_control(mach_port_t __unused auditd_port, int trigger)
-{
- int err_ret = 0;
-
- switch (trigger) {
-
- case AUDIT_TRIGGER_ROTATE_USER:
- /*
- * Create a new file and swap with the one
- * being used in kernel.
- */
- if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
- break;
-
- case AUDIT_TRIGGER_READ_FILE:
- if (read_control_file() == -1)
- syslog(LOG_ERR, "Error in audit control file");
- break;
-
- case AUDIT_TRIGGER_CLOSE_AND_DIE:
- err_ret = close_all();
- exit (err_ret);
- break;
-
- default:
- break;
- }
-
- return (KERN_SUCCESS);
-}
-#endif /* USE_MACH_IPC */
-
/*
* Handle the audit trigger event.
*
@@ -615,25 +441,16 @@ auditd_control(mach_port_t __unused auditd_port, int trigger)
* not be retransmitted, and the log file will grow in an unbounded fashion.
*/
#define DUPLICATE_INTERVAL 30
-#ifdef USE_MACH_IPC
-#define AT_SUCCESS KERN_SUCCESS
-
-/* ARGSUSED */
-kern_return_t
-audit_triggers(mach_port_t __unused audit_port, int trigger)
-#else
-#define AT_SUCCESS 0
-
-static int
-handle_audit_trigger(int trigger)
-#endif
+void
+auditd_handle_trigger(int trigger)
{
static int last_trigger, last_warning;
static time_t last_time;
- struct dir_ent *dirent;
struct timeval ts;
struct timezone tzp;
time_t tt;
+ int au_state;
+ int err = 0;
/*
* Suppress duplicate messages from the kernel within the specified
@@ -652,10 +469,10 @@ handle_audit_trigger(int trigger)
if ((trigger == last_trigger) &&
(tt < (last_time + DUPLICATE_INTERVAL))) {
if (tt >= (last_warning + DUPLICATE_INTERVAL))
- syslog(LOG_INFO,
+ auditd_log_info(
"Suppressing duplicate trigger %d",
trigger);
- return (AT_SUCCESS);
+ return;
}
last_warning = tt;
break;
@@ -663,6 +480,8 @@ handle_audit_trigger(int trigger)
case AUDIT_TRIGGER_ROTATE_KERNEL:
case AUDIT_TRIGGER_ROTATE_USER:
case AUDIT_TRIGGER_READ_FILE:
+ case AUDIT_TRIGGER_CLOSE_AND_DIE:
+ case AUDIT_TRIGGER_INITIALIZE:
/*
* Triggers that we cannot suppress.
*/
@@ -678,166 +497,70 @@ handle_audit_trigger(int trigger)
last_time = tt;
}
+ au_state = auditd_get_state();
+
/*
* Message processing is done here.
*/
- dirent = TAILQ_FIRST(&dir_q);
switch(trigger) {
case AUDIT_TRIGGER_LOW_SPACE:
- syslog(LOG_INFO, "Got low space trigger");
- if (dirent && (dirent->softlim != 1)) {
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- /* Add this node to the end of the list. */
- TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
- audit_warn_soft(dirent->dirname);
- dirent->softlim = 1;
-
- if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
- swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
-
- /*
- * Check if the next dir has already reached its soft
- * limit.
- */
- dirent = TAILQ_FIRST(&dir_q);
- if (dirent->softlim == 1) {
- /* All dirs have reached their soft limit. */
- audit_warn_allsoft();
- }
- } else {
- /*
- * Continue auditing to the current file. Also
- * generate an allsoft warning.
- *
- * XXX do we want to do this ?
- */
- audit_warn_allsoft();
- }
+ auditd_log_notice("Got low space trigger");
+ if (do_trail_file() == -1)
+ auditd_log_err("Error swapping audit file");
break;
case AUDIT_TRIGGER_NO_SPACE:
- syslog(LOG_INFO, "Got no space trigger");
-
- /* Delete current dir, go on to next. */
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- audit_warn_hard(dirent->dirname);
- free(dirent->dirname);
- free(dirent);
-
- if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
-
- /* We are out of log directories. */
- audit_warn_allhard(++allhardcount);
+ auditd_log_notice("Got no space trigger");
+ if (do_trail_file() == -1)
+ auditd_log_err("Error swapping audit file");
break;
case AUDIT_TRIGGER_ROTATE_KERNEL:
case AUDIT_TRIGGER_ROTATE_USER:
- /*
- * Create a new file and swap with the one being used in
- * kernel
- */
- syslog(LOG_INFO, "Got open new trigger from %s", trigger ==
+ auditd_log_info("Got open new trigger from %s", trigger ==
AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
- if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
+ if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1)
+ auditd_log_err("Error swapping audit file");
break;
case AUDIT_TRIGGER_READ_FILE:
- syslog(LOG_INFO, "Got read file trigger");
- if (read_control_file() == -1)
- syslog(LOG_ERR, "Error in audit control file");
- if (config_audit_controls() == -1)
- syslog(LOG_ERR, "Error setting audit controls");
- break;
-
- default:
- syslog(LOG_ERR, "Got unknown trigger %d", trigger);
+ auditd_log_info("Got read file trigger");
+ if (au_state == AUD_STATE_ENABLED &&
+ auditd_config_controls() == -1)
+ auditd_log_err("Error setting audit controls");
break;
- }
-
- return (AT_SUCCESS);
-}
-#undef AT_SUCCESS
-
-static void
-handle_sighup(void)
-{
-
- sighups_handled = sighups;
- config_audit_controls();
-}
-
-static int
-config_audit_host(void)
-{
- char hoststr[MAXHOSTNAMELEN];
- struct sockaddr_in6 *sin6;
- struct sockaddr_in *sin;
- struct addrinfo *res;
- struct auditinfo_addr aia;
- int error;
-
- if (getachost(hoststr, MAXHOSTNAMELEN) != 0) {
- syslog(LOG_WARNING,
- "warning: failed to read 'host' param in control file");
+ case AUDIT_TRIGGER_CLOSE_AND_DIE:
+ auditd_log_info("Got close and die trigger");
+ if (au_state == AUD_STATE_ENABLED)
+ err = close_all();
/*
- * To maintain reverse compatability with older audit_control
- * files, simply drop a warning if the host parameter has not
- * been set. However, we will explicitly disable the
- * generation of extended audit header by passing in a zeroed
- * termid structure.
+ * Running under launchd don't exit. Wait for launchd to
+ * send SIGTERM.
*/
- bzero(&aia, sizeof(aia));
- aia.ai_termid.at_type = AU_IPv4;
- error = auditon(A_SETKAUDIT, &aia, sizeof(aia));
- if (error < 0 && errno == ENOSYS)
- return (0);
- else if (error < 0) {
- syslog(LOG_ERR,
- "Failed to set audit host info");
- return (-1);
+ if (!launchd_flag) {
+ auditd_log_info("auditd exiting.");
+ exit (err);
}
- return (0);
- }
- error = getaddrinfo(hoststr, NULL, NULL, &res);
- if (error) {
- syslog(LOG_ERR, "Failed to lookup hostname: %s", hoststr);
- return (-1);
- }
- switch (res->ai_family) {
- case PF_INET6:
- sin6 = (struct sockaddr_in6 *) res->ai_addr;
- bcopy(&sin6->sin6_addr.s6_addr,
- &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
- aia.ai_termid.at_type = AU_IPv6;
break;
- case PF_INET:
- sin = (struct sockaddr_in *) res->ai_addr;
- bcopy(&sin->sin_addr.s_addr,
- &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
- aia.ai_termid.at_type = AU_IPv4;
+
+ case AUDIT_TRIGGER_INITIALIZE:
+ auditd_log_info("Got audit initialize trigger");
+ if (au_state == AUD_STATE_DISABLED)
+ audit_setup();
break;
+
default:
- syslog(LOG_ERR,
- "Un-supported address family in host parameter");
- return (-1);
- }
- if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0) {
- syslog(LOG_ERR,
- "auditon: failed to set audit host information");
- return (-1);
+ auditd_log_err("Got unknown trigger %d", trigger);
+ break;
}
- return (0);
}
/*
* Reap our children.
*/
-static void
-reap_children(void)
+void
+auditd_reap_children(void)
{
pid_t child;
int wstatus;
@@ -845,7 +568,7 @@ reap_children(void)
while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
if (!wstatus)
continue;
- syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
+ auditd_log_info("warn process [pid=%d] %s %d.", child,
((WIFEXITED(wstatus)) ? "exited with non-zero status" :
"exited as a result of signal"),
((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
@@ -853,287 +576,121 @@ reap_children(void)
}
}
-static void
-handle_sigchld(void)
-{
-
- sigchlds_handled = sigchlds;
- reap_children();
-}
-
/*
- * Read the control file for triggers/signals and handle appropriately.
+ * Reap any children and terminate. If under launchd don't shutdown auditing
+ * but just the other stuff.
*/
-#ifdef USE_MACH_IPC
-#define MAX_MSG_SIZE 4096
-
-static boolean_t
-auditd_combined_server(mach_msg_header_t *InHeadP,
- mach_msg_header_t *OutHeadP)
-{
- mach_port_t local_port = InHeadP->msgh_local_port;
-
- if (local_port == signal_port) {
- int signo = InHeadP->msgh_id;
- int ret;
-
- switch(signo) {
- case SIGTERM:
- ret = close_all();
- exit(ret);
-
- case SIGCHLD:
- handle_sigchld();
- return (TRUE);
-
- case SIGHUP:
- handle_sighup();
- return (TRUE);
-
- default:
- syslog(LOG_INFO, "Received signal %d", signo);
- return (TRUE);
- }
- } else if (local_port == control_port) {
- boolean_t result;
-
- result = audit_triggers_server(InHeadP, OutHeadP);
- if (!result)
- result = auditd_control_server(InHeadP, OutHeadP);
- return (result);
- }
- syslog(LOG_INFO, "Recevied msg on bad port 0x%x.", local_port);
- return (FALSE);
-}
-
-static int
-wait_for_events(void)
+void
+auditd_terminate(void)
{
- kern_return_t result;
-
- result = mach_msg_server(auditd_combined_server, MAX_MSG_SIZE,
- port_set, MACH_MSG_OPTION_NONE);
- syslog(LOG_ERR, "abnormal exit\n");
- return (close_all());
-}
-
-#else /* ! USE_MACH_IPC */
+ int ret;
-static int
-wait_for_events(void)
-{
- int num;
- unsigned int trigger;
+ auditd_reap_children();
+
+ if (launchd_flag)
+ ret = close_misc();
+ else
+ ret = close_all();
- for (;;) {
- num = read(triggerfd, &trigger, sizeof(trigger));
- if ((num == -1) && (errno != EINTR)) {
- syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
- return (-1);
- }
- if (sigterms != sigterms_handled) {
- syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
- break;
- }
- if (sigchlds != sigchlds_handled)
- handle_sigchld();
- if (sighups != sighups_handled) {
- syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
- handle_sighup();
- }
- if ((num == -1) && (errno == EINTR))
- continue;
- if (num == 0) {
- syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
- return (-1);
- }
- if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
- break;
- else
- (void)handle_audit_trigger(trigger);
- }
- return (close_all());
+ exit(ret);
}
-#endif /* ! USE_MACH_IPC */
/*
* Configure the audit controls in the kernel: the event to class mapping,
* kernel preselection mask, etc.
*/
-static int
-config_audit_controls(void)
+int
+auditd_config_controls(void)
{
- au_event_ent_t ev, *evp;
- au_evclass_map_t evc_map;
- au_mask_t aumask;
- int ctr = 0;
- char naeventstr[NA_EVENT_STR_SIZE];
- char polstr[POL_STR_SIZE];
- long policy;
- au_fstat_t au_fstat;
- size_t filesz;
-
- /*
- * Process the audit event file, obtaining a class mapping for each
- * event, and send that mapping into the kernel.
- *
- * XXX There's a risk here that the BSM library will return NULL
- * for an event when it can't properly map it to a class. In that
- * case, we will not process any events beyond the one that failed,
- * but should. We need a way to get a count of the events.
- */
- ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
- ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
- if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
- if (ev.ae_name != NULL)
- free(ev.ae_name);
- syslog(LOG_ERR,
- "Memory allocation error when configuring audit controls.");
- return (-1);
- }
+ int cnt, err;
+ int ret = 0;
/*
- * XXXRW: Currently we have no way to remove mappings from the kernel
- * when they are removed from the file-based mappings.
- */
- evp = &ev;
- setauevent();
- while ((evp = getauevent_r(evp)) != NULL) {
- evc_map.ec_number = evp->ae_number;
- evc_map.ec_class = evp->ae_class;
- if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
- != 0)
- syslog(LOG_ERR,
- "Failed to register class mapping for event %s",
- evp->ae_name);
- else
- ctr++;
- }
- endauevent();
- free(ev.ae_name);
- free(ev.ae_desc);
- if (ctr == 0)
- syslog(LOG_ERR, "No events to class mappings registered.");
- else
- syslog(LOG_DEBUG, "Registered %d event to class mappings.",
- ctr);
-
- /*
- * Get the non-attributable event string and set the kernel mask from
- * that.
- */
- if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
- (getauditflagsbin(naeventstr, &aumask) == 0)) {
- if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
- syslog(LOG_ERR,
- "Failed to register non-attributable event mask.");
- else
- syslog(LOG_DEBUG,
- "Registered non-attributable event mask.");
+ * Configure event to class mappings in kernel.
+ */
+ cnt = auditd_set_evcmap();
+ if (cnt < 0) {
+ auditd_log_err("auditd_set_evcmap() failed: %m");
+ ret = -1;
+ } else if (cnt == 0) {
+ auditd_log_err("No events to class mappings registered.");
+ ret = -1;
} else
- syslog(LOG_ERR,
- "Failed to obtain non-attributable event mask.");
+ auditd_log_debug("Registered %d event to class mappings.", cnt);
/*
- * If a policy is configured in audit_control(5), implement the
- * policy. However, if one isn't defined, set AUDIT_CNT to avoid
- * leaving the system in a fragile state.
+ * Configure non-attributable event mask in kernel.
*/
- if ((getacpol(polstr, POL_STR_SIZE) == 0) &&
- (au_strtopol(polstr, &policy) == 0)) {
- if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
- syslog(LOG_ERR, "Failed to set audit policy: %m");
- } else {
- syslog(LOG_ERR, "Failed to obtain policy flags: %m");
- policy = AUDIT_CNT;
- if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
- syslog(LOG_ERR,
- "Failed to set default audit policy: %m");
- }
+ err = auditd_set_namask();
+ if (err) {
+ auditd_log_err("auditd_set_namask() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
+ } else
+ auditd_log_debug("Registered non-attributable event mask.");
/*
- * Set trail rotation size.
+ * Configure audit policy in kernel.
*/
- if (getacfilesz(&filesz) == 0) {
- bzero(&au_fstat, sizeof(au_fstat));
- au_fstat.af_filesz = filesz;
- if (auditon(A_SETFSIZE, &au_fstat, sizeof(au_fstat)) < 0)
- syslog(LOG_ERR, "Failed to set filesz: %m");
+ err = auditd_set_policy();
+ if (err) {
+ auditd_log_err("auditd_set_policy() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
} else
- syslog(LOG_ERR, "Failed to obtain filesz: %m");
-
- return (config_audit_host());
-}
-
-#ifdef USE_MACH_IPC
-static void
-mach_setup(void)
-{
- mach_msg_type_name_t poly;
-
+ auditd_log_debug("Set audit policy in kernel.");
+
/*
- * Allocate a port set
+ * Configure audit trail log size in kernel.
*/
- if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET,
- &port_set) != KERN_SUCCESS) {
- syslog(LOG_ERR, "Allocation of port set failed");
- fail_exit();
- }
-
+ err = auditd_set_fsize();
+ if (err) {
+ auditd_log_err("audit_set_fsize() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
+ } else
+ auditd_log_debug("Set audit trail size in kernel.");
+
/*
- * Allocate a signal reflection port
+ * Configure audit trail volume minimum free percentage of blocks in
+ * kernel.
*/
- if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
- &signal_port) != KERN_SUCCESS ||
- mach_port_move_member(mach_task_self(), signal_port, port_set) !=
- KERN_SUCCESS) {
- syslog(LOG_ERR, "Allocation of signal port failed");
- fail_exit();
- }
+ err = auditd_set_minfree();
+ if (err) {
+ auditd_log_err("auditd_set_minfree() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
+ } else
+ auditd_log_debug(
+ "Set audit trail min free percent in kernel.");
/*
- * Allocate a trigger port
- */
- if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
- &control_port) != KERN_SUCCESS ||
- mach_port_move_member(mach_task_self(), control_port, port_set)
- != KERN_SUCCESS)
- syslog(LOG_ERR, "Allocation of trigger port failed");
-
- /*
- * Create a send right on our trigger port.
- */
- mach_port_extract_right(mach_task_self(), control_port,
- MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
-
- /*
- * Register the trigger port with the kernel.
+ * Configure host address in the audit kernel information.
*/
- if (host_set_audit_control_port(mach_host_self(), control_port) !=
- KERN_SUCCESS) {
- syslog(LOG_ERR, "Cannot set Mach control port");
- fail_exit();
+ err = auditd_set_host();
+ if (err) {
+ auditd_log_err("auditd_set_host() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
} else
- syslog(LOG_DEBUG, "Mach control port registered");
+ auditd_log_debug(
+ "Set audit host address information in kernel.");
+
+ return (ret);
}
-#endif /* USE_MACH_IPC */
+/*
+ * Setup and initialize auditd.
+ */
static void
setup(void)
{
- struct auditinfo ai;
- auditinfo_t auinfo;
- int aufd;
- token_t *tok;
-
-#ifdef USE_MACH_IPC
- mach_setup();
-#else
- if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
- syslog(LOG_ERR, "Error opening trigger file");
+ int err;
+
+ if (auditd_open_trigger(launchd_flag) < 0) {
+ auditd_log_err("Error opening trigger messaging mechanism");
fail_exit();
}
-#endif
/*
* To prevent event feedback cycles and avoid auditd becoming
@@ -1142,49 +699,25 @@ setup(void)
* mask fields to be implicitly set to zero, but do set the pid. We
* run this after opening the trigger device to avoid configuring
* audit state without audit present in the system.
- *
- * XXXRW: Is there more to it than this?
*/
- bzero(&auinfo, sizeof(auinfo));
- auinfo.ai_asid = getpid();
- if (setaudit(&auinfo) == -1) {
- syslog(LOG_ERR, "Error setting audit stat");
+ err = auditd_prevent_audit();
+ if (err) {
+ auditd_log_err("auditd_prevent_audit() %s: %m",
+ auditd_strerror(err));
fail_exit();
}
- TAILQ_INIT(&dir_q);
- if (read_control_file() == -1) {
- syslog(LOG_ERR, "Error reading control file");
- fail_exit();
- }
-
- /* Generate an audit record. */
- if ((aufd = au_open()) == -1)
- syslog(LOG_ERR, "Could not create audit startup event.");
- else {
- /*
- * XXXCSJP Perhaps we want more robust audit records for
- * audit start up and shutdown. This might include capturing
- * failures to initialize the audit subsystem?
- */
- bzero(&ai, sizeof(ai));
- if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
- getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
- != NULL)
- au_write(aufd, tok);
- if ((tok = au_to_text("auditd::Audit startup")) != NULL)
- au_write(aufd, tok);
- if ((tok = au_to_return32(0, 0)) != NULL)
- au_write(aufd, tok);
- if (au_close(aufd, 1, AUE_audit_startup) == -1)
- syslog(LOG_ERR,
- "Could not close audit startup event.");
- }
+ /*
+ * Make sure auditd auditing state is correct.
+ */
+ auditd_set_state(AUD_STATE_INIT);
- if (config_audit_controls() == 0)
- syslog(LOG_INFO, "Audit controls init successful");
- else
- syslog(LOG_ERR, "Audit controls init failed");
+ /*
+ * If under launchd, don't start auditing. Wait for a trigger to
+ * do so.
+ */
+ if (!launchd_flag)
+ audit_setup();
}
int
@@ -1192,48 +725,73 @@ main(int argc, char **argv)
{
int ch;
int debug = 0;
- int rc, logopts;
+#ifdef AUDIT_REVIEW_GROUP
+ struct group *grp;
+#endif
- while ((ch = getopt(argc, argv, "d")) != -1) {
+ while ((ch = getopt(argc, argv, "dl")) != -1) {
switch(ch) {
case 'd':
/* Debug option. */
debug = 1;
break;
+ case 'l':
+ /* Be launchd friendly. */
+ launchd_flag = 1;
+ break;
+
case '?':
default:
(void)fprintf(stderr,
- "usage: auditd [-d] \n");
+ "usage: auditd [-d] [-l]\n");
exit(1);
}
}
- logopts = LOG_CONS | LOG_PID;
- if (debug != 0)
- logopts |= LOG_PERROR;
+ audit_review_gid = getgid();
-#ifdef LOG_SECURITY
- openlog("auditd", logopts, LOG_SECURITY);
-#else
- openlog("auditd", logopts, LOG_AUTH);
+#ifdef AUDIT_REVIEW_GROUP
+ /*
+ * XXXRW: Currently, this code falls back to the daemon gid, which is
+ * likely the wheel group. Is there a better way to deal with this?
+ */
+ grp = getgrnam(AUDIT_REVIEW_GROUP);
+ if (grp != NULL)
+ audit_review_gid = grp->gr_gid;
#endif
- syslog(LOG_INFO, "starting...");
- if (debug == 0 && daemon(0, 0) == -1) {
- syslog(LOG_ERR, "Failed to daemonize");
+ auditd_openlog(debug, audit_review_gid);
+
+ if (launchd_flag)
+ auditd_log_info("started by launchd...");
+ else
+ auditd_log_info("starting...");
+
+#ifdef AUDIT_REVIEW_GROUP
+ if (grp == NULL)
+ auditd_log_info(
+ "Audit review group '%s' not available, using daemon gid (%d)",
+ AUDIT_REVIEW_GROUP, audit_review_gid);
+#endif
+ if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) {
+ auditd_log_err("Failed to daemonize");
exit(1);
}
if (register_daemon() == -1) {
- syslog(LOG_ERR, "Could not register as daemon");
+ auditd_log_err("Could not register as daemon");
exit(1);
}
setup();
- rc = wait_for_events();
- syslog(LOG_INFO, "auditd exiting.");
+ /*
+ * auditd_wait_for_events() shouldn't return unless something is wrong.
+ */
+ auditd_wait_for_events();
- exit(rc);
+ auditd_log_err("abnormal exit.");
+ close_all();
+ exit(-1);
}
diff --git a/contrib/openbsm/bin/auditd/auditd.h b/contrib/openbsm/bin/auditd/auditd.h
index 688aea3..0351a0e 100644
--- a/contrib/openbsm/bin/auditd/auditd.h
+++ b/contrib/openbsm/bin/auditd/auditd.h
@@ -26,7 +26,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.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#11 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#12 $
*/
#ifndef _AUDITD_H_
@@ -46,17 +46,6 @@
*/
#define AUDIT_REVIEW_GROUP "audit"
-#define NOT_TERMINATED "not_terminated"
-#define POSTFIX_LEN (sizeof("YYYYMMDDhhmmss") - 1)
-#define FILENAME_LEN ((2 * POSTFIX_LEN) + 2)
-#define TIMESTAMP_LEN (POSTFIX_LEN + 1)
-
-struct dir_ent {
- char *dirname;
- char softlim;
- TAILQ_ENTRY(dir_ent) dirs;
-};
-
#define HARDLIM_ALL_WARN "allhard"
#define SOFTLIM_ALL_WARN "allsoft"
#define AUDITOFF_WARN "auditoff"
@@ -72,7 +61,11 @@ struct dir_ent {
#define AUDITWARN_SCRIPT "/etc/security/audit_warn"
#define AUDITD_PIDFILE "/var/run/auditd.pid"
-int audit_warn_allhard(int count);
+#define AUD_STATE_INIT -1
+#define AUD_STATE_DISABLED 0
+#define AUD_STATE_ENABLED 1
+
+int audit_warn_allhard(void);
int audit_warn_allsoft(void);
int audit_warn_auditoff(void);
int audit_warn_closefile(char *filename);
@@ -84,4 +77,24 @@ int audit_warn_postsigterm(void);
int audit_warn_soft(char *filename);
int audit_warn_tmpfile(void);
+void auditd_openlog(int debug, gid_t gid);
+void auditd_log_err(const char *fmt, ...);
+void auditd_log_debug(const char *fmt, ...);
+void auditd_log_info(const char *fmt, ...);
+void auditd_log_notice(const char *fmt, ...);
+
+void auditd_set_state(int state);
+int auditd_get_state(void);
+
+int auditd_open_trigger(int launchd_flag);
+int auditd_close_trigger(void);
+void auditd_handle_trigger(int trigger);
+
+void auditd_wait_for_events(void);
+void auditd_relay_signal(int signal);
+void auditd_terminate(void);
+int auditd_config_controls(void);
+void auditd_reap_children(void);
+
+
#endif /* !_AUDITD_H_ */
diff --git a/contrib/openbsm/bin/auditd/auditd_darwin.c b/contrib/openbsm/bin/auditd/auditd_darwin.c
new file mode 100644
index 0000000..fbf99d8
--- /dev/null
+++ b/contrib/openbsm/bin/auditd/auditd_darwin.c
@@ -0,0 +1,484 @@
+/*-
+ * Copyright (c) 2004-2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd_darwin.c#3 $
+ */
+
+#include <sys/types.h>
+
+#include <config/config.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
+#include <bsm/libbsm.h>
+
+#include <asl.h>
+#include <launch.h>
+#include <notify.h>
+#include <mach/port.h>
+#include <mach/mach_error.h>
+#include <mach/mach_traps.h>
+#include <mach/mach.h>
+#include <mach/host_special_ports.h>
+
+#include "auditd.h"
+
+#include "auditd_controlServer.h"
+#include "audit_triggersServer.h"
+
+/*
+ * Apple System Logger Handles.
+ */
+static aslmsg au_aslmsg = NULL;
+static aslclient au_aslclient = NULL;
+
+static mach_port_t control_port = MACH_PORT_NULL;
+static mach_port_t signal_port = MACH_PORT_NULL;
+static mach_port_t port_set = MACH_PORT_NULL;
+
+/*
+ * Current auditing state (cache).
+ */
+static int auditing_state = AUD_STATE_INIT;
+
+/*
+ * Maximum idle time before auditd terminates under launchd.
+ * If it is zero then auditd does not timeout while idle.
+ */
+static int max_idletime = 0;
+
+#ifndef __BSM_INTERNAL_NOTIFY_KEY
+#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
+#endif /* __BSM_INTERNAL_NOTIFY_KEY */
+
+#ifndef __AUDIT_LAUNCHD_LABEL
+#define __AUDIT_LAUNCHD_LABEL "com.apple.auditd"
+#endif /* __AUDIT_LAUNCHD_LABEL */
+
+#define MAX_MSG_SIZE 4096
+
+/*
+ * Open and set up system logging.
+ */
+void
+auditd_openlog(int debug, gid_t gid)
+{
+ uint32_t opt = 0;
+ char *cp = NULL;
+
+ if (debug)
+ opt = ASL_OPT_STDERR;
+
+ au_aslclient = asl_open("auditd", "com.apple.auditd", opt);
+ au_aslmsg = asl_new(ASL_TYPE_MSG);
+
+#ifdef ASL_KEY_READ_UID
+ /*
+ * Make it only so the audit administrator and members of the audit
+ * review group (if used) have access to the auditd system log messages.
+ */
+ asl_set(au_aslmsg, ASL_KEY_READ_UID, "0");
+ asprintf(&cp, "%u", gid);
+ if (cp != NULL) {
+#ifdef ASL_KEY_READ_GID
+ asl_set(au_aslmsg, ASL_KEY_READ_GID, cp);
+#endif
+ free(cp);
+ }
+#endif
+
+ /*
+ * Set the client-side system log filtering.
+ */
+ if (debug)
+ asl_set_filter(au_aslclient,
+ ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
+ else
+ asl_set_filter(au_aslclient,
+ ASL_FILTER_MASK_UPTO(ASL_LEVEL_INFO));
+}
+
+/*
+ * Log messages at different priority levels.
+ */
+void
+auditd_log_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_ERR, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_notice(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_NOTICE, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_info(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_INFO, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_debug(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_DEBUG, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Get the auditing state from the kernel and cache it.
+ */
+static void
+init_audit_state(void)
+{
+ long au_cond;
+
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ if (errno != ENOSYS) {
+ auditd_log_err("Audit status check failed (%s)",
+ strerror(errno));
+ }
+ auditing_state = AUD_STATE_DISABLED;
+ } else
+ if (au_cond == AUC_NOAUDIT || au_cond == AUC_DISABLED)
+ auditing_state = AUD_STATE_DISABLED;
+ else
+ auditing_state = AUD_STATE_ENABLED;
+}
+
+/*
+ * Update the cached auditing state. Let other tasks that may be caching it
+ * as well to update their state via notify(3).
+ */
+void
+auditd_set_state(int state)
+{
+ int old_auditing_state = auditing_state;
+
+ if (state == AUD_STATE_INIT)
+ init_audit_state();
+ else
+ auditing_state = state;
+
+ if (auditing_state != old_auditing_state) {
+ notify_post(__BSM_INTERNAL_NOTIFY_KEY);
+
+ if (auditing_state == AUD_STATE_ENABLED)
+ auditd_log_notice("Auditing enabled");
+ if (auditing_state == AUD_STATE_DISABLED)
+ auditd_log_notice("Auditing disabled");
+ }
+}
+
+/*
+ * Get the cached auditing state.
+ */
+int
+auditd_get_state(void)
+{
+
+ if (auditing_state == AUD_STATE_INIT) {
+ init_audit_state();
+ notify_post(__BSM_INTERNAL_NOTIFY_KEY);
+ }
+
+ return (auditing_state);
+}
+
+/*
+ * Lookup the audit mach port in the launchd dictionary.
+ */
+static mach_port_t
+lookup_machport(const char *label)
+{
+ launch_data_t msg, msd, ld, cdict, to;
+ mach_port_t mp = MACH_PORT_NULL;
+
+ msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
+
+ cdict = launch_msg(msg);
+ if (cdict == NULL) {
+ auditd_log_err("launch_msg(\"" LAUNCH_KEY_CHECKIN
+ "\") IPC failure: %m");
+ return (MACH_PORT_NULL);
+ }
+
+ if (launch_data_get_type(cdict) == LAUNCH_DATA_ERRNO) {
+ errno = launch_data_get_errno(cdict);
+ auditd_log_err("launch_data_get_type() can't get dict: %m");
+ return (MACH_PORT_NULL);
+ }
+
+ to = launch_data_dict_lookup(cdict, LAUNCH_JOBKEY_TIMEOUT);
+ if (to) {
+ max_idletime = launch_data_get_integer(to);
+ auditd_log_debug("launchd timeout set to %d", max_idletime);
+ } else {
+ auditd_log_debug("launchd timeout not set, setting to 60");
+ max_idletime = 60;
+ }
+
+ msd = launch_data_dict_lookup(cdict, LAUNCH_JOBKEY_MACHSERVICES);
+ if (msd == NULL) {
+ auditd_log_err(
+ "launch_data_dict_lookup() can't get mach services");
+ return (MACH_PORT_NULL);
+ }
+
+ ld = launch_data_dict_lookup(msd, label);
+ if (ld == NULL) {
+ auditd_log_err("launch_data_dict_lookup can't find %s", label);
+ return (MACH_PORT_NULL);
+ }
+
+ mp = launch_data_get_machport(ld);
+
+ return (mp);
+}
+
+static int
+mach_setup(int launchd_flag)
+{
+ mach_msg_type_name_t poly;
+
+ /*
+ * Allocate a port set.
+ */
+ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET,
+ &port_set) != KERN_SUCCESS) {
+ auditd_log_err("Allocation of port set failed");
+ return (-1);
+ }
+
+
+ /*
+ * Allocate a signal reflection port.
+ */
+ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
+ &signal_port) != KERN_SUCCESS ||
+ mach_port_move_member(mach_task_self(), signal_port, port_set) !=
+ KERN_SUCCESS) {
+ auditd_log_err("Allocation of signal port failed");
+ return (-1);
+ }
+
+ /*
+ * Allocate a trigger port.
+ */
+ if (launchd_flag) {
+ /*
+ * If started under launchd, lookup port in launchd dictionary.
+ */
+ if ((control_port = lookup_machport(__AUDIT_LAUNCHD_LABEL)) ==
+ MACH_PORT_NULL || mach_port_move_member(mach_task_self(),
+ control_port, port_set) != KERN_SUCCESS) {
+ auditd_log_err("Cannot get Mach control port"
+ " via launchd");
+ return (-1);
+ } else
+ auditd_log_debug("Mach control port registered"
+ " via launchd");
+ } else {
+ /*
+ * If not started under launchd, allocate port and register.
+ */
+ if (mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_RECEIVE, &control_port) != KERN_SUCCESS ||
+ mach_port_move_member(mach_task_self(), control_port,
+ port_set) != KERN_SUCCESS)
+ auditd_log_err("Allocation of trigger port failed");
+
+ /*
+ * Create a send right on our trigger port.
+ */
+ mach_port_extract_right(mach_task_self(), control_port,
+ MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
+
+ /*
+ * Register the trigger port with the kernel.
+ */
+ if (host_set_audit_control_port(mach_host_self(),
+ control_port) != KERN_SUCCESS) {
+ auditd_log_err("Cannot set Mach control port");
+ return (-1);
+ } else
+ auditd_log_debug("Mach control port registered");
+ }
+
+ return (0);
+}
+
+/*
+ * Open the trigger messaging mechanism.
+ */
+int
+auditd_open_trigger(int launchd_flag)
+{
+
+ return (mach_setup(launchd_flag));
+}
+
+/*
+ * Close the trigger messaging mechanism.
+ */
+int
+auditd_close_trigger(void)
+{
+
+ return (0);
+}
+
+/*
+ * Combined server handler. Called by the mach message loop when there is
+ * a trigger or signal message.
+ */
+static boolean_t
+auditd_combined_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+ mach_port_t local_port = InHeadP->msgh_local_port;
+
+ /* Reset the idle time alarm, if used. */
+ if (max_idletime)
+ alarm(max_idletime);
+
+ if (local_port == signal_port) {
+ int signo = InHeadP->msgh_id;
+
+ switch(signo) {
+ case SIGTERM:
+ case SIGALRM:
+ auditd_terminate();
+ /* Not reached. */
+
+ case SIGCHLD:
+ auditd_reap_children();
+ return (TRUE);
+
+ case SIGHUP:
+ auditd_config_controls();
+ return (TRUE);
+
+ default:
+ auditd_log_info("Received signal %d", signo);
+ return (TRUE);
+ }
+ } else if (local_port == control_port) {
+ boolean_t result;
+
+ result = audit_triggers_server(InHeadP, OutHeadP);
+ if (!result)
+ result = auditd_control_server(InHeadP, OutHeadP);
+ return (result);
+ }
+ auditd_log_info("Recevied msg on bad port 0x%x.", local_port);
+ return (FALSE);
+}
+
+/*
+ * The main event loop. Wait for trigger messages or signals and handle them.
+ * It should not return unless there is a problem.
+ */
+void
+auditd_wait_for_events(void)
+{
+ kern_return_t result;
+
+ /*
+ * Call the mach messaging server loop.
+ */
+ result = mach_msg_server(auditd_combined_server, MAX_MSG_SIZE,
+ port_set, MACH_MSG_OPTION_NONE);
+}
+
+/*
+ * Implementation of the audit_triggers() MIG simpleroutine. Simply a
+ * wrapper function. This handles input from the kernel on the host
+ * special mach port.
+ */
+kern_return_t
+audit_triggers(mach_port_t __unused audit_port, int trigger)
+{
+
+ auditd_handle_trigger(trigger);
+
+ return (KERN_SUCCESS);
+}
+
+/*
+ * Implementation of the auditd_control() MIG simpleroutine. Simply a
+ * wrapper function. This handles input from the audit(1) tool.
+ */
+kern_return_t
+auditd_control(mach_port_t __unused auditd_port, int trigger)
+{
+
+ auditd_handle_trigger(trigger);
+
+ return (KERN_SUCCESS);
+}
+
+/*
+ * When we get a signal, we are often not at a clean point. So, little can
+ * be done in the signal handler itself. Instead, we send a message to the
+ * main servicing loop to do proper handling from a non-signal-handler
+ * context.
+ */
+void
+auditd_relay_signal(int signal)
+{
+ mach_msg_empty_send_t msg;
+
+ msg.header.msgh_id = signal;
+ msg.header.msgh_remote_port = signal_port;
+ msg.header.msgh_local_port = MACH_PORT_NULL;
+ msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+ mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
+ 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+}
diff --git a/contrib/openbsm/bin/auditd/auditd_fbsd.c b/contrib/openbsm/bin/auditd/auditd_fbsd.c
new file mode 100644
index 0000000..ea2a090
--- /dev/null
+++ b/contrib/openbsm/bin/auditd/auditd_fbsd.c
@@ -0,0 +1,274 @@
+/*-
+ * Copyright (c) 2004-2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd_fbsd.c#2 $
+ */
+
+#include <sys/types.h>
+
+#include <config/config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
+#include <bsm/libbsm.h>
+
+#include "auditd.h"
+
+/*
+ * Current auditing state (cache).
+ */
+static int auditing_state = AUD_STATE_INIT;
+
+/*
+ * Maximum idle time before auditd terminates under launchd.
+ * If it is zero then auditd does not timeout while idle.
+ */
+static int max_idletime = 0;
+
+static int sigchlds, sigchlds_handled;
+static int sighups, sighups_handled;
+static int sigterms, sigterms_handled;
+static int sigalrms, sigalrms_handled;
+
+static int triggerfd = 0;
+
+/*
+ * Open and set up system logging.
+ */
+void
+auditd_openlog(int debug, gid_t __unused gid)
+{
+ int logopts = LOG_CONS | LOG_PID;
+
+ if (debug)
+ logopts |= LOG_PERROR;
+
+#ifdef LOG_SECURITY
+ openlog("auditd", logopts, LOG_SECURITY);
+#else
+ openlog("auditd", logopts, LOG_AUTH);
+#endif
+}
+
+/*
+ * Log messages at different priority levels.
+ */
+void
+auditd_log_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_notice(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_NOTICE, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_info(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_INFO, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_debug(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_DEBUG, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Get the auditing state from the kernel and cache it.
+ */
+static void
+init_audit_state(void)
+{
+ long au_cond;
+
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ if (errno != ENOSYS) {
+ auditd_log_err("Audit status check failed (%s)",
+ strerror(errno));
+ }
+ auditing_state = AUD_STATE_DISABLED;
+ } else
+ if (au_cond == AUC_NOAUDIT || au_cond == AUC_DISABLED)
+ auditing_state = AUD_STATE_DISABLED;
+ else
+ auditing_state = AUD_STATE_ENABLED;
+}
+
+/*
+ * Update the cached auditing state.
+ */
+void
+auditd_set_state(int state)
+{
+ int old_auditing_state = auditing_state;
+
+ if (state == AUD_STATE_INIT)
+ init_audit_state();
+ else
+ auditing_state = state;
+
+ if (auditing_state != old_auditing_state) {
+ if (auditing_state == AUD_STATE_ENABLED)
+ auditd_log_notice("Auditing enabled");
+ if (auditing_state == AUD_STATE_DISABLED)
+ auditd_log_notice("Auditing disabled");
+ }
+}
+
+/*
+ * Get the cached auditing state.
+ */
+int
+auditd_get_state(void)
+{
+
+ if (auditing_state == AUD_STATE_INIT)
+ init_audit_state();
+
+ return (auditing_state);
+}
+
+/*
+ * Open the trigger messaging mechanism.
+ */
+int
+auditd_open_trigger(int __unused launchd_flag)
+{
+
+ return ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)));
+}
+
+/*
+ * Close the trigger messaging mechanism.
+ */
+int
+auditd_close_trigger(void)
+{
+
+ return (close(triggerfd));
+}
+
+/*
+ * The main event loop. Wait for trigger messages or signals and handle them.
+ * It should not return unless there is a problem.
+ */
+void
+auditd_wait_for_events(void)
+{
+ int num;
+ unsigned int trigger;
+
+ for (;;) {
+ num = read(triggerfd, &trigger, sizeof(trigger));
+ if ((num == -1) && (errno != EINTR)) {
+ auditd_log_err("%s: error %d", __FUNCTION__, errno);
+ return;
+ }
+
+ /* Reset the idle time alarm, if used. */
+ if (max_idletime)
+ alarm(max_idletime);
+
+ if (sigterms != sigterms_handled) {
+ auditd_log_debug("%s: SIGTERM", __FUNCTION__);
+ auditd_terminate();
+ /* not reached */
+ }
+ if (sigalrms != sigalrms_handled) {
+ auditd_log_debug("%s: SIGALRM", __FUNCTION__);
+ auditd_terminate();
+ /* not reached */
+ }
+ if (sigchlds != sigchlds_handled) {
+ sigchlds_handled = sigchlds;
+ auditd_reap_children();
+ }
+ if (sighups != sighups_handled) {
+ auditd_log_debug("%s: SIGHUP", __FUNCTION__);
+ sighups_handled = sighups;
+ auditd_config_controls();
+ }
+
+ if ((num == -1) && (errno == EINTR))
+ continue;
+ if (num == 0) {
+ auditd_log_err("%s: read EOF", __FUNCTION__);
+ return;
+ }
+ auditd_handle_trigger(trigger);
+ }
+}
+
+/*
+ * When we get a signal, we are often not at a clean point. So, little can
+ * be done in the signal handler itself. Instead, we send a message to the
+ * main servicing loop to do proper handling from a non-signal-handler
+ * context.
+ */
+void
+auditd_relay_signal(int signal)
+{
+ if (signal == SIGHUP)
+ sighups++;
+ if (signal == SIGTERM)
+ sigterms++;
+ if (signal == SIGCHLD)
+ sigchlds++;
+ if (signal == SIGALRM)
+ sigalrms++;
+}
+
diff --git a/contrib/openbsm/bin/auditfilterd/Makefile.in b/contrib/openbsm/bin/auditfilterd/Makefile.in
index 874e106..07926da 100644
--- a/contrib/openbsm/bin/auditfilterd/Makefile.in
+++ b/contrib/openbsm/bin/auditfilterd/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/Makefile.in#6 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/Makefile.in#7 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/bin/auditreduce/Makefile.in b/contrib/openbsm/bin/auditreduce/Makefile.in
index b18513f..1030a83 100644
--- a/contrib/openbsm/bin/auditreduce/Makefile.in
+++ b/contrib/openbsm/bin/auditreduce/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/Makefile.in#9 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/bin/auditreduce/auditreduce.c b/contrib/openbsm/bin/auditreduce/auditreduce.c
index f22f454..0faadda 100644
--- a/contrib/openbsm/bin/auditreduce/auditreduce.c
+++ b/contrib/openbsm/bin/auditreduce/auditreduce.c
@@ -26,7 +26,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/auditreduce.c#28 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/auditreduce.c#31 $
*/
/*
@@ -41,6 +41,9 @@
*/
#include <config/config.h>
+
+#define _GNU_SOURCE /* Required for strptime() on glibc2. */
+
#ifdef HAVE_FULL_QUEUE_H
#include <sys/queue.h>
#else
@@ -567,7 +570,7 @@ select_records(FILE *fp)
* The -o option has the form object_type=object_value. Identify the object
* components.
*/
-void
+static void
parse_object_type(char *name, char *val)
{
if (val == NULL)
diff --git a/contrib/openbsm/bin/praudit/Makefile.in b/contrib/openbsm/bin/praudit/Makefile.in
index 4472757..025b48f 100644
--- a/contrib/openbsm/bin/praudit/Makefile.in
+++ b/contrib/openbsm/bin/praudit/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/praudit/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/praudit/Makefile.in#9 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/bsm/Makefile.am b/contrib/openbsm/bsm/Makefile.am
index cad4115..b92f9cd 100644
--- a/contrib/openbsm/bsm/Makefile.am
+++ b/contrib/openbsm/bsm/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.am#3 $
+# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.am#4 $
#
openbsmdir = $(includedir)/bsm
@@ -7,5 +7,6 @@ openbsmdir = $(includedir)/bsm
openbsm_HEADERS = \
audit_filter.h \
audit_uevents.h \
+ auditd_lib.h \
libbsm.h
diff --git a/contrib/openbsm/bsm/Makefile.in b/contrib/openbsm/bsm/Makefile.in
index ed82a3b..5ea5ee2 100644
--- a/contrib/openbsm/bsm/Makefile.in
+++ b/contrib/openbsm/bsm/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.in#9 $
#
VPATH = @srcdir@
@@ -172,6 +172,7 @@ openbsmdir = $(includedir)/bsm
openbsm_HEADERS = \
audit_filter.h \
audit_uevents.h \
+ auditd_lib.h \
libbsm.h
all: all-am
diff --git a/contrib/openbsm/bsm/audit_uevents.h b/contrib/openbsm/bsm/audit_uevents.h
index 03d0f9b..53c5616 100644
--- a/contrib/openbsm/bsm/audit_uevents.h
+++ b/contrib/openbsm/bsm/audit_uevents.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Apple Inc.
+ * Copyright (c) 2004-2008 Apple Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,22 +26,14 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit_uevents.h#8 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit_uevents.h#10 $
*/
#ifndef _BSM_AUDIT_UEVENTS_H_
#define _BSM_AUDIT_UEVENTS_H_
-/*-
- * User level audit event numbers
- *
- * Range of audit event numbers:
- * 0 Reserved, invalid
- * 1 - 2047 Reserved for kernel events
- * 2048 - 32767 Defined by BSM for user events
- * 32768 - 36864 Reserved for Mac OS-X applications
- * 36865 - 65535 Reserved for applications
- *
+/*
+ * Solaris userspace events.
*/
#define AUE_at_create 6144
#define AUE_at_delete 6145
@@ -70,8 +62,13 @@
#define AUE_shutdown 6168
#define AUE_poweroff 6169
#define AUE_crontab_mod 6170
-#define AUE_audit_startup 6171
-#define AUE_audit_shutdown 6172
+#define AUE_ftpd_logout 6171
+#define AUE_ssh 6172
+#define AUE_role_login 6173
+#define AUE_prof_cmd 6180
+#define AUE_filesystem_add 6181
+#define AUE_filesystem_delete 6182
+#define AUE_filesystem_modify 6183
#define AUE_allocate_succ 6200
#define AUE_allocate_fail 6201
#define AUE_deallocate_succ 6202
@@ -83,20 +80,63 @@
#define AUE_delete_user 6209
#define AUE_disable_user 6210
#define AUE_enable_user 6211
-#define AUE_sudo 6300
-#define AUE_modify_password 6501 /* Not assigned by Sun. */
-#define AUE_create_group 6511 /* Not assigned by Sun. */
-#define AUE_delete_group 6512 /* Not assigned by Sun. */
-#define AUE_modify_group 6513 /* Not assigned by Sun. */
-#define AUE_add_to_group 6514 /* Not assigned by Sun. */
-#define AUE_remove_from_group 6515 /* Not assigned by Sun. */
-#define AUE_revoke_obj 6521 /* Not assigned by Sun; not used. */
-#define AUE_lw_login 6600 /* Not assigned by Sun; tentative. */
-#define AUE_lw_logout 6601 /* Not assigned by Sun; tentative. */
-#define AUE_auth_user 7000 /* Not assigned by Sun. */
-#define AUE_ssconn 7001 /* Not assigned by Sun. */
-#define AUE_ssauthorize 7002 /* Not assigned by Sun. */
-#define AUE_ssauthint 7003 /* Not assigned by Sun. */
+#define AUE_newgrp_login 6212
+#define AUE_admin_authentication 6213
+#define AUE_kadmind_auth 6214
+#define AUE_kadmind_unauth 6215
+#define AUE_krb5kdc_as_req 6216
+#define AUE_krb5kdc_tgs_req 6217
+#define AUE_krb5kdc_tgs_req_2ndtktmm 6218
+#define AUE_krb5kdc_tgs_req_alt_tgt 6219
+
+/*
+ * Historic Darwin use of the low event numbering space, which collided with
+ * the Solaris event space. Now obsoleted and new, higher, event numbers
+ * assigned to make it easier to interpret Solaris events using the OpenBSM
+ * tools.
+ */
+#define AUE_DARWIN_audit_startup 6171
+#define AUE_DARWIN_audit_shutdown 6172
+#define AUE_DARWIN_sudo 6300
+#define AUE_DARWIN_modify_password 6501
+#define AUE_DARWIN_create_group 6511
+#define AUE_DARWIN_delete_group 6512
+#define AUE_DARWIN_modify_group 6513
+#define AUE_DARWIN_add_to_group 6514
+#define AUE_DARWIN_remove_from_group 6515
+#define AUE_DARWIN_revoke_obj 6521
+#define AUE_DARWIN_lw_login 6600
+#define AUE_DARWIN_lw_logout 6601
+#define AUE_DARWIN_auth_user 7000
+#define AUE_DARWIN_ssconn 7001
+#define AUE_DARWIN_ssauthorize 7002
+#define AUE_DARWIN_ssauthint 7003
+
+/*
+ * Historic/third-party appliation allocations of event idenfiers.
+ */
#define AUE_openssh 32800
+/*
+ * OpenBSM-managed application event space.
+ */
+#define AUE_audit_startup 45000 /* Darwin-specific. */
+#define AUE_audit_shutdown 45001 /* Darwin-specific. */
+#define AUE_modify_password 45014 /* Darwin-specific. */
+#define AUE_create_group 45015 /* Darwin-specific. */
+#define AUE_delete_group 45016 /* Darwin-specific. */
+#define AUE_modify_group 45017 /* Darwin-specific. */
+#define AUE_add_to_group 45018 /* Darwin-specific. */
+#define AUE_remove_from_group 45019 /* Darwin-specific. */
+#define AUE_revoke_obj 45020 /* Darwin-specific. */
+#define AUE_lw_login 45021 /* Darwin-specific. */
+#define AUE_lw_logout 45022 /* Darwin-specific. */
+#define AUE_auth_user 45023 /* Darwin-specific. */
+#define AUE_ssconn 45024 /* Darwin-specific. */
+#define AUE_ssauthorize 45025 /* Darwin-specific. */
+#define AUE_ssauthint 45026 /* Darwin-specific. */
+#define AUE_calife 45027 /* OpenBSM-allocated. */
+#define AUE_sudo 45028 /* OpenBSM-allocated. */
+#define AUE_audit_recovery 45029 /* OpenBSM-allocated. */
+
#endif /* !_BSM_AUDIT_UEVENTS_H_ */
diff --git a/contrib/openbsm/bsm/auditd_lib.h b/contrib/openbsm/bsm/auditd_lib.h
new file mode 100644
index 0000000..7c6ab40
--- /dev/null
+++ b/contrib/openbsm/bsm/auditd_lib.h
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/bsm/auditd_lib.h#3 $
+ */
+
+#ifndef _BSM_AUDITD_LIB_H_
+#define _BSM_AUDITD_LIB_H_
+
+/*
+ * Lengths for audit trail file components.
+ */
+#define NOT_TERMINATED "not_terminated"
+#define CRASH_RECOVERY "crash_recovery"
+#define POSTFIX_LEN (sizeof("YYYYMMDDhhmmss") - 1)
+#define FILENAME_LEN ((2 * POSTFIX_LEN) + 2)
+#define TIMESTAMP_LEN (POSTFIX_LEN + 1)
+
+/*
+ * Macro to generate the timestamp string for trail file.
+ */
+#define getTSstr(t, b, l) \
+ ( (((t) = time(0)) == (time_t)-1 ) || \
+ !strftime((b), (l), "%Y%m%d%H%M%S", gmtime(&(t)) ) ) ? -1 : 0
+
+/*
+ * The symbolic link to the currently active audit trail file.
+ */
+#define AUDIT_CURRENT_LINK "/var/audit/current"
+
+/*
+ * Path of auditd plist file for launchd.
+ */
+#define AUDITD_PLIST_FILE \
+ "/System/Library/LaunchDaemons/com.apple.auditd.plist"
+
+/*
+ * Error return codes for auditd_lib functions.
+ */
+#define ADE_NOERR 0 /* No Error or Success. */
+#define ADE_PARSE -1 /* Error parsing audit_control(5). */
+#define ADE_AUDITON -2 /* auditon(2) call failed. */
+#define ADE_NOMEM -3 /* Error allocating memory. */
+#define ADE_SOFTLIM -4 /* All audit log directories over soft limit. */
+#define ADE_HARDLIM -5 /* All audit log directories over hard limit. */
+#define ADE_STRERR -6 /* Error creating file name string. */
+#define ADE_AU_OPEN -7 /* au_open(3) failed. */
+#define ADE_AU_CLOSE -8 /* au_close(3) failed. */
+#define ADE_SETAUDIT -9 /* setaudit(2) or setaudit_addr(2) failed. */
+#define ADE_ACTL -10 /* "Soft" error with auditctl(2). */
+#define ADE_ACTLERR -11 /* "Hard" error with auditctl(2). */
+#define ADE_SWAPERR -12 /* The audit trail file could not be swap. */
+#define ADE_RENAME -13 /* Error renaming crash recovery file. */
+#define ADE_READLINK -14 /* Error reading 'current' link. */
+#define ADE_SYMLINK -15 /* Error creating 'current' link. */
+#define ADE_INVAL -16 /* Invalid argument. */
+#define ADE_GETADDR -17 /* Error resolving address from hostname. */
+#define ADE_ADDRFAM -18 /* Address family not supported. */
+
+/*
+ * auditd_lib functions.
+ */
+const char *auditd_strerror(int errcode);
+int auditd_set_minfree(void);
+int auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *));
+void auditd_close_dirs(void);
+int auditd_set_evcmap(void);
+int auditd_set_namask(void);
+int auditd_set_policy(void);
+int auditd_set_fsize(void);
+int auditd_set_host(void);
+int auditd_swap_trail(char *TS, char **newfile, gid_t gid,
+ int (*warn_getacdir)(char *));
+int auditd_prevent_audit(void);
+int auditd_gen_record(int event, char *path);
+int auditd_new_curlink(char *curfile);
+int audit_quick_start(void);
+int audit_quick_stop(void);
+
+#endif /* !_BSM_AUDITD_LIB_H_ */
diff --git a/contrib/openbsm/bsm/libbsm.h b/contrib/openbsm/bsm/libbsm.h
index 97b9530..4e74f57 100644
--- a/contrib/openbsm/bsm/libbsm.h
+++ b/contrib/openbsm/bsm/libbsm.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Apple Inc.
+ * Copyright (c) 2004-2008 Apple Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#35 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#41 $
*/
#ifndef _LIBBSM_H_
@@ -547,13 +547,13 @@ typedef struct {
* remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
*/
typedef struct {
+ u_int16_t domain;
u_int16_t type;
+ u_int16_t atype;
u_int16_t l_port;
- u_int32_t l_ad_type;
- u_int32_t l_addr;
+ u_int32_t l_addr[4];
u_int32_t r_port;
- u_int32_t r_ad_type;
- u_int32_t r_addr;
+ u_int32_t r_addr[4];
} au_socket_ex32_t;
/*
@@ -821,6 +821,21 @@ void au_print_tok_xml(FILE *outfp, tokenstr_t *tok,
*/
void au_print_xml_header(FILE *outfp);
void au_print_xml_footer(FILE *outfp);
+
+/*
+ * BSM library routines for converting between local and BSM constant spaces.
+ * (Note: some of these are replicated in audit_record.h for the benefit of
+ * the FreeBSD and Mac OS X kernels)
+ */
+int au_bsm_to_domain(u_short bsm_domain, int *local_domainp);
+int au_bsm_to_errno(u_char bsm_error, int *errorp);
+int au_bsm_to_socket_type(u_short bsm_socket_type,
+ int *local_socket_typep);
+u_short au_domain_to_bsm(int local_domain);
+u_char au_errno_to_bsm(int local_errno);
+u_short au_socket_type_to_bsm(int local_socket_type);
+
+const char *au_strerror(u_char bsm_error);
__END_DECLS
/*
@@ -930,6 +945,19 @@ void au_free_token(token_t *tok);
* XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE.
*/
int au_get_state(void);
+
+/*
+ * Initialize the audit notification. If it has not already been initialized
+ * it will automatically on the first call of au_get_state().
+ */
+uint32_t au_notify_initialize(void);
+
+/*
+ * Cancel audit notification and free the resources associated with it.
+ * Responsible code that no longer needs to use au_get_state() should call
+ * this.
+ */
+int au_notify_terminate(void);
__END_DECLS
/* OpenSSH compatibility */
diff --git a/contrib/openbsm/compat/endian.h b/contrib/openbsm/compat/endian.h
index 83762e4..6ef1d15 100644
--- a/contrib/openbsm/compat/endian.h
+++ b/contrib/openbsm/compat/endian.h
@@ -25,7 +25,7 @@
* SUCH DAMAGE.
*
* Derived from FreeBSD src/sys/sys/endian.h:1.6.
- * $P4: //depot/projects/trustedbsd/openbsm/compat/endian.h#7 $
+ * $P4: //depot/projects/trustedbsd/openbsm/compat/endian.h#8 $
*/
#ifndef _COMPAT_ENDIAN_H_
@@ -35,7 +35,9 @@
* Some systems will have the uint/int types defined here already, others
* will need stdint.h.
*/
+#ifdef HAVE_STDINT_H
#include <stdint.h>
+#endif
/*
* Some operating systems do not yet have the more recent endian APIs that
diff --git a/contrib/openbsm/config/config.h b/contrib/openbsm/config/config.h
index b750910..0a052cd 100644
--- a/contrib/openbsm/config/config.h
+++ b/contrib/openbsm/config/config.h
@@ -8,6 +8,9 @@
/* Define if audit system calls present */
#define HAVE_AUDIT_SYSCALLS
+/* Define if be32enc is present */
+#define HAVE_BE32ENC
+
/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1
@@ -69,6 +72,9 @@
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
+/* Define to 1 if you have the `pthread_mutex_lock' function. */
+#define HAVE_PTHREAD_MUTEX_LOCK 1
+
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
@@ -159,13 +165,13 @@
#define PACKAGE_NAME "OpenBSM"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "OpenBSM 1.1alpha2"
+#define PACKAGE_STRING "OpenBSM 1.1alpha4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "openbsm"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.1alpha2"
+#define PACKAGE_VERSION "1.1alpha4"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
@@ -186,7 +192,7 @@
#define USE_NATIVE_INCLUDES
/* Version number of package */
-#define VERSION "1.1alpha2"
+#define VERSION "1.1alpha4"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
diff --git a/contrib/openbsm/config/config.h.in b/contrib/openbsm/config/config.h.in
index 5ac71ab..bc30aaa 100644
--- a/contrib/openbsm/config/config.h.in
+++ b/contrib/openbsm/config/config.h.in
@@ -6,6 +6,9 @@
/* Define if audit system calls present */
#undef HAVE_AUDIT_SYSCALLS
+/* Define if be32enc is present */
+#undef HAVE_BE32ENC
+
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
@@ -67,6 +70,9 @@
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
+/* Define to 1 if you have the `pthread_mutex_lock' function. */
+#undef HAVE_PTHREAD_MUTEX_LOCK
+
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
diff --git a/contrib/openbsm/configure b/contrib/openbsm/configure
index e6cb1ce..073b507 100755
--- a/contrib/openbsm/configure
+++ b/contrib/openbsm/configure
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.ac P4: //depot/projects/trustedbsd/openbsm/configure.ac#41 .
+# From configure.ac P4: //depot/projects/trustedbsd/openbsm/configure.ac#49 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for OpenBSM 1.1alpha2.
+# Generated by GNU Autoconf 2.61 for OpenBSM 1.1alpha5.
#
# Report bugs to <trustedbsd-audit@TrustesdBSD.org>.
#
@@ -729,8 +729,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='OpenBSM'
PACKAGE_TARNAME='openbsm'
-PACKAGE_VERSION='1.1alpha2'
-PACKAGE_STRING='OpenBSM 1.1alpha2'
+PACKAGE_VERSION='1.1alpha5'
+PACKAGE_STRING='OpenBSM 1.1alpha5'
PACKAGE_BUGREPORT='trustedbsd-audit@TrustesdBSD.org'
ac_unique_file="bin/auditreduce/auditreduce.c"
@@ -1404,7 +1404,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures OpenBSM 1.1alpha2 to adapt to many kinds of systems.
+\`configure' configures OpenBSM 1.1alpha5 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1474,7 +1474,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of OpenBSM 1.1alpha2:";;
+ short | recursive ) echo "Configuration of OpenBSM 1.1alpha5:";;
esac
cat <<\_ACEOF
@@ -1580,7 +1580,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-OpenBSM configure 1.1alpha2
+OpenBSM configure 1.1alpha5
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1594,7 +1594,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by OpenBSM $as_me 1.1alpha2, which was
+It was created by OpenBSM $as_me 1.1alpha5, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -19076,7 +19076,7 @@ fi
# Define the identity of the package.
PACKAGE=OpenBSM
- VERSION=1.1alpha2
+ VERSION=1.1alpha5
cat >>confdefs.h <<_ACEOF
@@ -19852,7 +19852,8 @@ fi
-for ac_header in endian.h mach/mach.h machine/endian.h sys/endian.h
+
+for ac_header in endian.h mach/mach.h machine/endian.h sys/endian.h stdint.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -22802,7 +22803,8 @@ done
-for ac_func in bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul
+
+for ac_func in bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul pthread_mutex_lock
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -22969,7 +22971,7 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
- #include <stdlib.h>
+ #include <stddef.h>
extern int auditon(int, void *, int);
@@ -23031,6 +23033,66 @@ else
fi
+#
+# There are a wide variety of endian macros and functions in the wild; we try
+# to use the native support if it defines be32enc(), but otherwise have to
+# use our own.
+#
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+ #include <sys/endian.h>
+ #include <stdlib.h>
+
+int
+main ()
+{
+
+ be32enc(NULL, 1);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BE32ENC
+_ACEOF
+
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
# Check to see if Mach IPC is used for trigger messages. If so, use Mach IPC
# instead of the default for sending trigger messages to the audit components.
{ echo "$as_me:$LINENO: checking for /usr/include/mach/audit_triggers.defs" >&5
@@ -23074,7 +23136,7 @@ else
fi
-ac_config_files="$ac_config_files Makefile bin/Makefile bin/audit/Makefile bin/auditd/Makefile bin/auditfilterd/Makefile bin/auditreduce/Makefile bin/praudit/Makefile bsm/Makefile libbsm/Makefile modules/Makefile modules/auditfilter_noop/Makefile man/Makefile sys/Makefile sys/bsm/Makefile test/Makefile test/bsm/Makefile tools/Makefile"
+ac_config_files="$ac_config_files Makefile bin/Makefile bin/audit/Makefile bin/auditd/Makefile bin/auditfilterd/Makefile bin/auditreduce/Makefile bin/praudit/Makefile bsm/Makefile libauditd/Makefile libbsm/Makefile modules/Makefile modules/auditfilter_noop/Makefile man/Makefile sys/Makefile sys/bsm/Makefile test/Makefile test/bsm/Makefile tools/Makefile"
cat >confcache <<\_ACEOF
@@ -23522,7 +23584,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by OpenBSM $as_me 1.1alpha2, which was
+This file was extended by OpenBSM $as_me 1.1alpha5, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -23575,7 +23637,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-OpenBSM config.status 1.1alpha2
+OpenBSM config.status 1.1alpha5
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -23699,6 +23761,7 @@ do
"bin/auditreduce/Makefile") CONFIG_FILES="$CONFIG_FILES bin/auditreduce/Makefile" ;;
"bin/praudit/Makefile") CONFIG_FILES="$CONFIG_FILES bin/praudit/Makefile" ;;
"bsm/Makefile") CONFIG_FILES="$CONFIG_FILES bsm/Makefile" ;;
+ "libauditd/Makefile") CONFIG_FILES="$CONFIG_FILES libauditd/Makefile" ;;
"libbsm/Makefile") CONFIG_FILES="$CONFIG_FILES libbsm/Makefile" ;;
"modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;;
"modules/auditfilter_noop/Makefile") CONFIG_FILES="$CONFIG_FILES modules/auditfilter_noop/Makefile" ;;
diff --git a/contrib/openbsm/configure.ac b/contrib/openbsm/configure.ac
index 1da42cd..8ec6558 100644
--- a/contrib/openbsm/configure.ac
+++ b/contrib/openbsm/configure.ac
@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
-AC_INIT([OpenBSM], [1.1alpha2], [trustedbsd-audit@TrustesdBSD.org],[openbsm])
-AC_REVISION([$P4: //depot/projects/trustedbsd/openbsm/configure.ac#42 $])
+AC_INIT([OpenBSM], [1.1alpha5], [trustedbsd-audit@TrustesdBSD.org],[openbsm])
+AC_REVISION([$P4: //depot/projects/trustedbsd/openbsm/configure.ac#49 $])
AC_CONFIG_SRCDIR([bin/auditreduce/auditreduce.c])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_HEADER([config/config.h])
@@ -35,7 +35,7 @@ AC_SEARCH_LIBS(clock_gettime, rt)
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([endian.h mach/mach.h machine/endian.h sys/endian.h])
+AC_CHECK_HEADERS([endian.h mach/mach.h machine/endian.h sys/endian.h stdint.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -83,7 +83,7 @@ AC_FUNC_MKTIME
AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_FUNC_STRFTIME
-AC_CHECK_FUNCS([bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul])
+AC_CHECK_FUNCS([bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul pthread_mutex_lock])
# sys/queue.h exists on most systems, but its capabilities vary a great deal.
# test for LIST_FIRST and TAILQ_FOREACH_SAFE, which appears to not exist in
@@ -106,7 +106,7 @@ AC_DEFINE(HAVE_FULL_QUEUE_H,, Define if queue.h includes LIST_FIRST)
# depend on them or it will generate link-time or run-time errors. Test for
# just one.
AC_TRY_LINK([
- #include <stdlib.h>
+ #include <stddef.h>
extern int auditon(int, void *, int);
], [
@@ -121,6 +121,20 @@ have_audit_syscalls=false
])
AM_CONDITIONAL(HAVE_AUDIT_SYSCALLS, $have_audit_syscalls)
+#
+# There are a wide variety of endian macros and functions in the wild; we try
+# to use the native support if it defines be32enc(), but otherwise have to
+# use our own.
+#
+AC_TRY_LINK([
+ #include <sys/endian.h>
+ #include <stdlib.h>
+], [
+ be32enc(NULL, 1);
+], [
+AC_DEFINE(HAVE_BE32ENC,, Define if be32enc is present)
+])
+
# Check to see if Mach IPC is used for trigger messages. If so, use Mach IPC
# instead of the default for sending trigger messages to the audit components.
AC_CHECK_FILE([/usr/include/mach/audit_triggers.defs], [
@@ -139,6 +153,7 @@ AC_CONFIG_FILES([Makefile
bin/auditreduce/Makefile
bin/praudit/Makefile
bsm/Makefile
+ libauditd/Makefile
libbsm/Makefile
modules/Makefile
modules/auditfilter_noop/Makefile
diff --git a/contrib/openbsm/etc/audit_event b/contrib/openbsm/etc/audit_event
index 20e585c..a734020 100644
--- a/contrib/openbsm/etc/audit_event
+++ b/contrib/openbsm/etc/audit_event
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_event#30 $
+# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_event#34 $
# $FreeBSD$
#
# The mapping between event identifiers and values is also hard-coded in
@@ -8,6 +8,20 @@
# those changes. It is advisable not to change the numbering or naming of
# kernel audit events.
#
+# Allocation of BSM event identifier ranges:
+#
+# 0 Reserved and invalid
+# 1 - 2047 Reserved for Solaris kernel events
+# 2048 - 5999 Reserved and unallocated
+# 6000 - 9999 Reserved for Solaris user events
+# 10000 - 32767 Reserved and unallocated
+# 32768 - 65535 Available for third party applications
+#
+# Of the third party range, OpenBSM allocates from the following ranges:
+#
+# 43000 - 44999 Reserved for OpenBSM kernel events
+# 45000 - 46999 Reserved for OpenBSM application events
+#
0:AUE_NULL:indir system call:no
1:AUE_EXIT:exit(2):pc
2:AUE_FORK:fork(2):pc
@@ -186,6 +200,7 @@
205:AUE_SETGID:setgid(2):pc
206:AUE_READL:readl(2):no
207:AUE_READVL:readvl(2):no
+208:AUE_FSTAT:fstat(2):fa
209:AUE_DUP2:dup2(2):no
210:AUE_MMAP:mmap(2):no
211:AUE_AUDIT:audit(2):ot
@@ -535,33 +550,107 @@
43187:AUE_CAP_GETRIGHTS:cap_getrights(2):fm
43188:AUE_CAP_ENTER:cap_enter(2):pc
43189:AUE_CAP_GETMODE:cap_getmode(2):pc
+43190:AUE_POSIX_SPAWN:posix_spawn(2):pc
+43191:AUE_FSGETPATH:fsgetpath(2):ot
#
-# User space system events.
+# Solaris userspace events.
#
+6144:AUE_at_create:at-create atjob:ad
+6145:AUE_at_delete:at-delete atjob (at or atrm):ad
+6146:AUE_at_perm:at-permission:no
+6147:AUE_cron_invoke:cron-invoke:ad
+6148:AUE_crontab_create:crontab-crontab created:ad
+6149:AUE_crontab_delete:crontab-crontab deleted:ad
+6150:AUE_crontab_perm:crontab-permission:no
+6151:AUE_inetd_connect:inetd connection:na
6152:AUE_login:login - local:lo
6153:AUE_logout:logout - local:lo
+6154:AUE_telnet:login - telnet:lo
+6155:AUE_rlogin:login - rlogin:lo
+6156:AUE_mountd_mount:mount:na
+6157:AUE_mountd_umount:unmount:na
+6158:AUE_rshd:rsh access:lo
6159:AUE_su:su(1):lo
6160:AUE_halt:system halt:ad
+6161:AUE_reboot:system reboot:ad
+6162:AUE_rexecd:rexecd:lo
+6163:AUE_passwd:passwd:lo
+6164:AUE_rexd:rexd:lo
+6165:AUE_ftpd:ftp access:lo
+6166:AUE_init:init:lo
+6167:AUE_uadmin:uadmin:no
6168:AUE_shutdown:system shutdown:ad
-6171:AUE_audit_startup:audit startup:ad
-6172:AUE_audit_shutdown:audit shutdown:ad
+6168:AUE_poweroff:system poweroff:ad
+6170:AUE_crontab_mod:crontab-modify:ad
+6171:AUE_ftpd_logout:ftp logout:lo
+6172:AUE_ssh:login - ssh:lo
+6173:AUE_role_login:role login:lo
+6180:AUE_prof_cmd: profile command:ad
+6181:AUE_filesystem_add:add filesystem:ad
+6182:AUE_filesystem_delete:delete filesystem:ad
+6183:AUE_filesystem_modify:modify filesystem:ad
+6200:AUE_allocate_succ:allocate-device success:ot
+6201:AUE_allocate_fail:allocate-device failure:ot
+6202:AUE_deallocate_succ:deallocate-device success:ot
+6203:AUE_deallocate_fail:deallocate-device failure:ot
+6204:AUE_listdevice_succ:allocate-list devices success:ot
+6205:AUE_listdevice_fail:allocate-list devices failure:ot
6207:AUE_create_user:create user:ad
6208:AUE_modify_user:modify user:ad
6209:AUE_delete_user:delete user:ad
6210:AUE_disable_user:disable user:ad
-6211:AUE_enable_user::ad
-6300:AUE_sudo:sudo(1):ad
-6501:AUE_modify_password:modify password:ad
-6511:AUE_create_group:create group:ad
-6512:AUE_delete_group:delete group:ad
-6513:AUE_modify_group:modify group:ad
-6514:AUE_add_to_group:add to group:ad
-6515:AUE_remove_from_group:remove from group:ad
-6521:AUE_revoke_obj:revoke object priv:fm
-6600:AUE_lw_login:loginwindow login:lo
-6601:AUE_lw_logout:loginwindow logout:lo
-7000:AUE_auth_user:user authentication:ad
-7001:AUE_ssconn:SecSrvr connection setup:ad
-7002:AUE_ssauthorize:SecSrvr AuthEngine:ad
-7003:AUE_ssauthint:SecSrvr authinternal mech:ad
+6211:AUE_enable_user:enable users:ad
+6212:AUE_newgrp_login:newgrp login:lo
+6213:AUE_admin_authenticate:admin login:lo
+6214:AUE_kadmind_auth:authenticated kadmind request:ua
+6215:AUE_kadmind_unauth:unauthenticated kadmind req:ua
+6216:AUE_krb5kdc_as_req:kdc authentication svc request:ap
+6217:AUE_krb5kdc_tgs_req:kdc tkt-grant svc request:ap
+6218:AUE_krb5kdc_tgs_req_2ndtktmm:kdc tgs 2ndtkt mismtch:ap
+6219:AUE_krb5kdc_tgs_req_alt_tgt:kdc tgs issue alt tgt:ap
+#
+# Historic Darwin use of low event numbering space, which collided with the
+# Solaris event space. Now obsoleted and new, higher, event numbers assigned
+# to make it easier to interpret Solaris events using the OpenBSM tools.
+#
+6171:AUE_DARWIN_audit_startup:audit startup:ad
+6172:AUE_DARWIN_audit_shutdown:audit shutdown:ad
+6300:AUE_DARWIN_sudo:sudo(1):ad
+6501:AUE_DARWIN_modify_password:modify password:ad
+6511:AUE_DARWIN_create_group:create group:ad
+6512:AUE_DARWIN_delete_group:delete group:ad
+6513:AUE_DARWIN_modify_group:modify group:ad
+6514:AUE_DARWIN_add_to_group:add to group:ad
+6515:AUE_DARWIN_remove_from_group:remove from group:ad
+6521:AUE_DARWIN_revoke_obj:revoke object priv:fm
+6600:AUE_DARWIN_lw_login:loginwindow login:lo
+6601:AUE_DARWIN_lw_logout:loginwindow logout:lo
+7000:AUE_DARWIN_auth_user:user authentication:ad
+7001:AUE_DARWIN_ssconn:SecSrvr connection setup:ad
+7002:AUE_DARWIN_ssauthorize:SecSrvr AuthEngine:ad
+7003:AUE_DARWIN_ssauthint:SecSrvr authinternal mech:ad
+#
+# Historic/third-party application allocations of event identifiers.
+#
32800:AUE_openssh:OpenSSH login:lo
+#
+# OpenBSM-managed application event space.
+#
+45000:AUE_audit_startup:audit startup:ad
+45001:AUE_audit_shutdown:audit shutdown:ad
+45014:AUE_modify_password:modify password:ad
+45015:AUE_create_group:create group:ad
+45016:AUE_delete_group:delete group:ad
+45017:AUE_modify_group:modify group:ad
+45018:AUE_add_to_group:add to group:ad
+45019:AUE_remove_from_group:remove from group:ad
+45020:AUE_revoke_obj:revoke object priv:fm
+45021:AUE_lw_login:loginwindow login:lo
+45022:AUE_lw_logout:loginwindow logout:lo
+45023:AUE_auth_user:user authentication:ad
+45024:AUE_ssconn:SecSrvr connection setup:ad
+45025:AUE_ssauthorize:SecSrvr AuthEngine:ad
+45026:AUE_ssauthint:SecSrvr authinternal mech:ad
+45027:AUE_calife:Calife:ad
+45028:AUE_sudo:sudo(1):ad
+45029:AUE_audit_recovery:audit crash recovery:ad
diff --git a/contrib/openbsm/libauditd/Makefile.am b/contrib/openbsm/libauditd/Makefile.am
new file mode 100644
index 0000000..2459cdf
--- /dev/null
+++ b/contrib/openbsm/libauditd/Makefile.am
@@ -0,0 +1,17 @@
+#
+# $P4: //depot/projects/trustedbsd/openbsm/libauditd/Makefile.am#2 $
+#
+
+if USE_NATIVE_INCLUDES
+INCLUDES = -I$(top_builddir) -I$(top_srcdir)
+else
+INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
+endif
+
+lib_LTLIBRARIES = libauditd.la
+
+libauditd_la_SOURCES = \
+ auditd_lib.c
+
+man3_MANS = \
+ libauditd.3
diff --git a/contrib/openbsm/libauditd/Makefile.in b/contrib/openbsm/libauditd/Makefile.in
new file mode 100644
index 0000000..0881e22
--- /dev/null
+++ b/contrib/openbsm/libauditd/Makefile.in
@@ -0,0 +1,525 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program 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.
+
+@SET_MAKE@
+
+#
+# $P4: //depot/projects/trustedbsd/openbsm/libauditd/Makefile.in#2 $
+#
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = libauditd
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libauditd_la_LIBADD =
+am_libauditd_la_OBJECTS = auditd_lib.lo
+libauditd_la_OBJECTS = $(am_libauditd_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)/config@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libauditd_la_SOURCES)
+DIST_SOURCES = $(libauditd_la_SOURCES)
+man3dir = $(mandir)/man3
+NROFF = nroff
+MANS = $(man3_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MIG = @MIG@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+@USE_NATIVE_INCLUDES_FALSE@INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
+@USE_NATIVE_INCLUDES_TRUE@INCLUDES = -I$(top_builddir) -I$(top_srcdir)
+lib_LTLIBRARIES = libauditd.la
+libauditd_la_SOURCES = \
+ auditd_lib.c
+
+man3_MANS = \
+ libauditd.3
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libauditd/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign libauditd/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libauditd.la: $(libauditd_la_OBJECTS) $(libauditd_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libauditd_la_OBJECTS) $(libauditd_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_lib.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man3: $(man3_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
+ @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 3*) ;; \
+ *) ext='3' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
+ done
+uninstall-man3:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 3*) ;; \
+ *) ext='3' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man: install-man3
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES uninstall-man
+
+uninstall-man: uninstall-man3
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-man3 install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-libLTLIBRARIES \
+ uninstall-man uninstall-man3
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/openbsm/libauditd/auditd_lib.c b/contrib/openbsm/libauditd/auditd_lib.c
new file mode 100644
index 0000000..d19d174
--- /dev/null
+++ b/contrib/openbsm/libauditd/auditd_lib.c
@@ -0,0 +1,867 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#2 $
+ */
+
+#include <sys/param.h>
+
+#include <config/config.h>
+
+#include <sys/dirent.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#ifdef HAVE_FULL_QUEUE_H
+#include <sys/queue.h>
+#else /* !HAVE_FULL_QUEUE_H */
+#include <compat/queue.h>
+#endif /* !HAVE_FULL_QUEUE_H */
+
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
+#include <bsm/libbsm.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#ifdef __APPLE__
+#include <notify.h>
+#ifndef __BSM_INTERNAL_NOTIFY_KEY
+#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
+#endif /* __BSM_INTERNAL_NOTIFY_KEY */
+#endif /* __APPLE__ */
+
+/*
+ * XXX This is temporary until this is moved to <bsm/audit.h> and shared with
+ * the kernel.
+ */
+#ifndef AUDIT_HARD_LIMIT_FREE_BLOCKS
+#define AUDIT_HARD_LIMIT_FREE_BLOCKS 4
+#endif
+
+struct dir_ent {
+ char *dirname;
+ uint8_t softlim;
+ uint8_t hardlim;
+ TAILQ_ENTRY(dir_ent) dirs;
+};
+
+static TAILQ_HEAD(, dir_ent) dir_q;
+static int minval = -1;
+
+static char *auditd_errmsg[] = {
+ "no error", /* ADE_NOERR ( 0) */
+ "could not parse audit_control(5) file", /* ADE_PARSE ( 1) */
+ "auditon(2) failed", /* ADE_AUDITON ( 2) */
+ "malloc(3) failed", /* ADE_NOMEM ( 3) */
+ "all audit log directories over soft limit", /* ADE_SOFTLIM ( 4) */
+ "all audit log directories over hard limit", /* ADE_HARDLIM ( 5) */
+ "could not create file name string", /* ADE_STRERR ( 6) */
+ "could not open audit record", /* ADE_AU_OPEN ( 7) */
+ "could not close audit record", /* ADE_AU_CLOSE ( 8) */
+ "could not set active audit session state", /* ADE_SETAUDIT ( 9) */
+ "auditctl(2) failed (trail still swapped)", /* ADE_ACTL (10) */
+ "auditctl(2) failed (trail not swapped)", /* ADE_ACTLERR (11) */
+ "could not swap audit trail file", /* ADE_SWAPERR (12) */
+ "could not rename crash recovery file", /* ADE_RENAME (13) */
+ "could not read 'current' link file", /* ADE_READLINK (14) */
+ "could not create 'current' link file", /* ADE_SYMLINK (15) */
+ "invalid argument", /* ADE_INVAL (16) */
+ "could not resolve hostname to address", /* ADE_GETADDR (17) */
+ "address family not supported", /* ADE_ADDRFAM (18) */
+};
+
+#define MAXERRCODE (sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0]))
+
+#define NA_EVENT_STR_SIZE 25
+#define POL_STR_SIZE 128
+
+
+/*
+ * Look up and return the error string for the given audit error code.
+ */
+const char *
+auditd_strerror(int errcode)
+{
+ int idx = -errcode;
+
+ if (idx < 0 || idx > (int)MAXERRCODE)
+ return ("Invalid auditd error code");
+
+ return (auditd_errmsg[idx]);
+}
+
+
+/*
+ * Free our local list of directory names and init list
+ */
+static void
+free_dir_q(void)
+{
+ struct dir_ent *d1, *d2;
+
+ d1 = TAILQ_FIRST(&dir_q);
+ while (d1 != NULL) {
+ d2 = TAILQ_NEXT(d1, dirs);
+ free(d1->dirname);
+ free(d1);
+ d1 = d2;
+ }
+ TAILQ_INIT(&dir_q);
+}
+
+/*
+ * Concat the directory name to the given file name.
+ * XXX We should affix the hostname also
+ */
+static char *
+affixdir(char *name, struct dir_ent *dirent)
+{
+ char *fn = NULL;
+
+ /*
+ * Sanity check on file name.
+ */
+ if (strlen(name) != (FILENAME_LEN - 1)) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ asprintf(&fn, "%s/%s", dirent->dirname, name);
+ return (fn);
+}
+
+/*
+ * Insert the directory entry in the list by the way they are ordered in
+ * audit_control(5). Move the entries that are over the soft and hard limits
+ * toward the tail.
+ */
+static void
+insert_orderly(struct dir_ent *denew)
+{
+ struct dir_ent *dep;
+
+ TAILQ_FOREACH(dep, &dir_q, dirs) {
+ if (dep->softlim == 1 && denew->softlim == 0) {
+ TAILQ_INSERT_BEFORE(dep, denew, dirs);
+ return;
+ }
+ if (dep->hardlim == 1 && denew->hardlim == 0) {
+ TAILQ_INSERT_BEFORE(dep, denew, dirs);
+ return;
+ }
+ }
+ TAILQ_INSERT_TAIL(&dir_q, denew, dirs);
+}
+
+/*
+ * Get the host from audit_control(5) and set it in the audit kernel
+ * information. Return:
+ * ADE_NOERR on success.
+ * ADE_PARSE error parsing audit_control(5).
+ * ADE_AUDITON error getting/setting auditon(2) value.
+ * ADE_GETADDR error getting address info for host.
+ * ADE_ADDRFAM un-supported address family.
+ */
+int
+auditd_set_host(void)
+{
+ char hoststr[MAXHOSTNAMELEN];
+ struct sockaddr_in6 *sin6;
+ struct sockaddr_in *sin;
+ struct addrinfo *res;
+ struct auditinfo_addr aia;
+ int error, ret = ADE_NOERR;
+
+ if (getachost(hoststr, MAXHOSTNAMELEN) != 0) {
+
+ ret = ADE_PARSE;
+
+ /*
+ * To maintain reverse compatability with older audit_control
+ * files, simply drop a warning if the host parameter has not
+ * been set. However, we will explicitly disable the
+ * generation of extended audit header by passing in a zeroed
+ * termid structure.
+ */
+ bzero(&aia, sizeof(aia));
+ aia.ai_termid.at_type = AU_IPv4;
+ error = auditon(A_SETKAUDIT, &aia, sizeof(aia));
+ if (error < 0 && errno != ENOSYS)
+ ret = ADE_AUDITON;
+ return (ret);
+ }
+ error = getaddrinfo(hoststr, NULL, NULL, &res);
+ if (error)
+ return (ADE_GETADDR);
+ switch (res->ai_family) {
+ case PF_INET6:
+ sin6 = (struct sockaddr_in6 *) res->ai_addr;
+ bcopy(&sin6->sin6_addr.s6_addr,
+ &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
+ aia.ai_termid.at_type = AU_IPv6;
+ break;
+
+ case PF_INET:
+ sin = (struct sockaddr_in *) res->ai_addr;
+ bcopy(&sin->sin_addr.s_addr,
+ &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
+ aia.ai_termid.at_type = AU_IPv4;
+ break;
+
+ default:
+ /* Un-supported address family in host parameter. */
+ errno = EAFNOSUPPORT;
+ return (ADE_ADDRFAM);
+ }
+
+ if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0)
+ ret = ADE_AUDITON;
+
+ return (ret);
+}
+
+/*
+ * Get the min percentage of free blocks from audit_control(5) and that
+ * value in the kernel. Return:
+ * ADE_NOERR on success,
+ * ADE_PARSE error parsing audit_control(5),
+ * ADE_AUDITON error getting/setting auditon(2) value.
+ */
+int
+auditd_set_minfree(void)
+{
+ au_qctrl_t qctrl;
+
+ if (getacmin(&minval) != 0)
+ return (ADE_PARSE);
+
+ if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0)
+ return (ADE_AUDITON);
+
+ if (qctrl.aq_minfree != minval) {
+ qctrl.aq_minfree = minval;
+ if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0)
+ return (ADE_AUDITON);
+ }
+
+ return (0);
+}
+
+/*
+ * Parses the "dir" entry in audit_control(5) into an ordered list. Also, will
+ * set the minfree value if not already set. Arguments include function
+ * pointers to audit_warn functions for soft and hard limits. Returns:
+ * ADE_NOERR on success,
+ * ADE_PARSE error parsing audit_control(5),
+ * ADE_AUDITON error getting/setting auditon(2) value,
+ * ADE_NOMEM error allocating memory,
+ * ADE_SOFTLIM if all the directories are over the soft limit,
+ * ADE_HARDLIM if all the directories are over the hard limit,
+ */
+int
+auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *))
+{
+ char cur_dir[MAXNAMLEN];
+ struct dir_ent *dirent;
+ struct statfs sfs;
+ int err;
+ char soft, hard;
+ int tcnt = 0;
+ int scnt = 0;
+ int hcnt = 0;
+
+ if (minval == -1 && (err = auditd_set_minfree()) != 0)
+ return (err);
+
+ /*
+ * Init directory q. Force a re-read of the file the next time.
+ */
+ free_dir_q();
+ endac();
+
+ /*
+ * Read the list of directories into an ordered linked list
+ * admin's preference, then those over soft limit and, finally,
+ * those over the hard limit.
+ *
+ * XXX We should use the reentrant interfaces once they are
+ * available.
+ */
+ while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
+ if (statfs(cur_dir, &sfs) < 0)
+ continue; /* XXX should warn */
+ soft = (sfs.f_bfree < (sfs.f_blocks / (100 / minval))) ? 1 : 0;
+ hard = (sfs.f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) ? 1 : 0;
+ if (soft) {
+ if (warn_soft)
+ (*warn_soft)(cur_dir);
+ scnt++;
+ }
+ if (hard) {
+ if (warn_hard)
+ (*warn_hard)(cur_dir);
+ hcnt++;
+ }
+ dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
+ if (dirent == NULL)
+ return (ADE_NOMEM);
+ dirent->softlim = soft;
+ dirent->hardlim = hard;
+ dirent->dirname = (char *) malloc(MAXNAMLEN);
+ if (dirent->dirname == NULL) {
+ free(dirent);
+ return (ADE_NOMEM);
+ }
+ strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
+ insert_orderly(dirent);
+ tcnt++;
+ }
+
+ if (hcnt == tcnt)
+ return (ADE_HARDLIM);
+ if (scnt == tcnt)
+ return (ADE_SOFTLIM);
+ return (0);
+}
+
+void
+auditd_close_dirs(void)
+{
+ free_dir_q();
+ minval = -1;
+}
+
+
+/*
+ * Process the audit event file, obtaining a class mapping for each event, and
+ * set that mapping into the kernel. Return:
+ * n number of event mappings that were successfully processed,
+ * ADE_NOMEM if there was an error allocating memory.
+ */
+int
+auditd_set_evcmap(void)
+{
+ au_event_ent_t ev, *evp;
+ au_evclass_map_t evc_map;
+ int ctr = 0;
+
+
+ /*
+ * XXX There's a risk here that the BSM library will return NULL
+ * for an event when it can't properly map it to a class. In that
+ * case, we will not process any events beyond the one that failed,
+ * but should. We need a way to get a count of the events.
+ */
+ ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
+ ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
+ if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
+ if (ev.ae_name != NULL)
+ free(ev.ae_name);
+ return (ADE_NOMEM);
+ }
+
+ /*
+ * XXXRW: Currently we have no way to remove mappings from the kernel
+ * when they are removed from the file-based mappings.
+ */
+ evp = &ev;
+ setauevent();
+ while ((evp = getauevent_r(evp)) != NULL) {
+ evc_map.ec_number = evp->ae_number;
+ evc_map.ec_class = evp->ae_class;
+ if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
+ == 0)
+ ctr++;
+ }
+ endauevent();
+ free(ev.ae_name);
+ free(ev.ae_desc);
+
+ return (ctr);
+}
+
+/*
+ * Get the non-attributable event string and set the kernel mask. Return:
+ * ADE_NOERR on success,
+ * ADE_PARSE error parsing audit_control(5),
+ * ADE_AUDITON error setting the mask using auditon(2).
+ */
+int
+auditd_set_namask(void)
+{
+ au_mask_t aumask;
+ char naeventstr[NA_EVENT_STR_SIZE];
+
+ if ((getacna(naeventstr, NA_EVENT_STR_SIZE) != 0) ||
+ (getauditflagsbin(naeventstr, &aumask) != 0))
+ return (ADE_PARSE);
+
+ if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
+ return (ADE_AUDITON);
+
+ return (ADE_NOERR);
+}
+
+/*
+ * Set the audit control policy if a policy is configured in audit_control(5),
+ * implement the policy. However, if one isn't defined or if there is an error
+ * parsing the control file, set AUDIT_CNT to avoid leaving the system in a
+ * fragile state. Return:
+ * ADE_NOERR on success,
+ * ADE_PARSE error parsing audit_control(5),
+ * ADE_AUDITON error setting policy using auditon(2).
+ */
+int
+auditd_set_policy(void)
+{
+ long policy;
+ char polstr[POL_STR_SIZE];
+
+ if ((getacpol(polstr, POL_STR_SIZE) != 0) ||
+ (au_strtopol(polstr, &policy) != 0)) {
+ policy = AUDIT_CNT;
+ if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
+ return (ADE_AUDITON);
+ return (ADE_PARSE);
+ }
+
+ if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
+ return (ADE_AUDITON);
+
+ return (ADE_NOERR);
+}
+
+/*
+ * Set trail rotation size. Return:
+ * ADE_NOERR on success,
+ * ADE_PARSE error parsing audit_control(5),
+ * ADE_AUDITON error setting file size using auditon(2).
+ */
+int
+auditd_set_fsize(void)
+{
+ size_t filesz;
+ au_fstat_t au_fstat;
+
+ /*
+ * Set trail rotation size.
+ */
+ if (getacfilesz(&filesz) != 0)
+ return (ADE_PARSE);
+
+ bzero(&au_fstat, sizeof(au_fstat));
+ au_fstat.af_filesz = filesz;
+ if (auditon(A_SETFSIZE, &au_fstat, sizeof(au_fstat)) < 0)
+ return (ADE_AUDITON);
+
+ return (ADE_NOERR);
+}
+
+/*
+ * Create the new audit file with appropriate permissions and ownership. Try
+ * to clean up if something goes wrong.
+ */
+static int
+open_trail(char *fname, gid_t gid)
+{
+ int error, fd;
+
+ fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
+ if (fd < 0)
+ return (-1);
+ if (fchown(fd, -1, gid) < 0) {
+ error = errno;
+ close(fd);
+ (void)unlink(fname);
+ errno = error;
+ return (-1);
+ }
+ return (fd);
+}
+
+/*
+ * Create the new audit trail file, swap with existing audit file. Arguments
+ * include timestamp for the filename, a pointer to a string for returning the
+ * new file name, GID for trail file, and audit_warn function pointer for
+ * 'getacdir()' errors. Returns:
+ * ADE_NOERR on success,
+ * ADE_STRERR if the file name string could not be created,
+ * ADE_SWAPERR if the audit trail file could not be swapped,
+ * ADE_ACTL if the auditctl(2) call failed but file swap still
+ * successful.
+ * ADE_ACTLERR if the auditctl(2) call failed and file swap failed.
+ * ADE_SYMLINK if symlink(2) failed updating the current link.
+ */
+int
+auditd_swap_trail(char *TS, char **newfile, gid_t gid,
+ int (*warn_getacdir)(char *))
+{
+ char timestr[FILENAME_LEN];
+ char *fn;
+ struct dir_ent *dirent;
+ int fd;
+ int error;
+ int saverrno = 0;
+
+ if (strlen(TS) != (TIMESTAMP_LEN - 1) ||
+ snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED) < 0) {
+ errno = EINVAL;
+ return (ADE_STRERR);
+ }
+
+ /* Try until we succeed. */
+ while ((dirent = TAILQ_FIRST(&dir_q))) {
+ if (dirent->hardlim)
+ continue;
+ if ((fn = affixdir(timestr, dirent)) == NULL)
+ return (ADE_STRERR);
+
+ /*
+ * Create and open the file; then close and pass to the
+ * kernel if all went well.
+ */
+ fd = open_trail(fn, gid);
+ if (fd >= 0) {
+ error = auditctl(fn);
+ if (error) {
+ /*
+ * auditctl failed setting log file.
+ * Try again.
+ */
+ saverrno = errno;
+ close(fd);
+ } else {
+ /* Success. */
+ *newfile = fn;
+ close(fd);
+ if (error)
+ return (error);
+ if (saverrno) {
+ /*
+ * auditctl() failed but still
+ * successful. Return errno and "soft"
+ * error.
+ */
+ errno = saverrno;
+ return (ADE_ACTL);
+ }
+ return (ADE_NOERR);
+ }
+ }
+
+ /*
+ * Tell the administrator about lack of permissions for dir.
+ */
+ if (warn_getacdir != NULL)
+ (*warn_getacdir)(dirent->dirname);
+ }
+ if (saverrno) {
+ errno = saverrno;
+ return (ADE_ACTLERR);
+ } else
+ return (ADE_SWAPERR);
+}
+
+/*
+ * Mask calling process from being audited. Returns:
+ * ADE_NOERR on success,
+ * ADE_SETAUDIT if setaudit(2) fails.
+ */
+int
+auditd_prevent_audit(void)
+{
+ auditinfo_t ai;
+
+ /*
+ * To prevent event feedback cycles and avoid audit becoming stalled if
+ * auditing is suspended we mask this processes events from being
+ * audited. We allow the uid, tid, and mask fields to be implicitly
+ * set to zero, but do set the audit session ID to the PID.
+ *
+ * XXXRW: Is there more to it than this?
+ */
+ bzero(&ai, sizeof(ai));
+ ai.ai_asid = getpid();
+ if (setaudit(&ai) != 0)
+ return (ADE_SETAUDIT);
+ return (ADE_NOERR);
+}
+
+/*
+ * Generate and submit audit record for audit startup or shutdown. The event
+ * argument can be AUE_audit_recovery, AUE_audit_startup or
+ * AUE_audit_shutdown. The path argument will add a path token, if not NULL.
+ * Returns:
+ * AUE_NOERR on success,
+ * ADE_NOMEM if memory allocation fails,
+ * ADE_AU_OPEN if au_open(3) fails,
+ * ADE_AU_CLOSE if au_close(3) fails.
+ */
+int
+auditd_gen_record(int event, char *path)
+{
+ int aufd;
+ uid_t uid;
+ pid_t pid;
+ char *autext = NULL;
+ token_t *tok;
+ struct auditinfo_addr aia;
+
+ if (event == AUE_audit_startup)
+ asprintf(&autext, "%s::Audit startup", getprogname());
+ else if (event == AUE_audit_shutdown)
+ asprintf(&autext, "%s::Audit shutdown", getprogname());
+ else if (event == AUE_audit_recovery)
+ asprintf(&autext, "%s::Audit recovery", getprogname());
+ else
+ return (ADE_INVAL);
+ if (autext == NULL)
+ return (ADE_NOMEM);
+
+ if ((aufd = au_open()) == -1) {
+ free(autext);
+ return (ADE_AU_OPEN);
+ }
+ bzero(&aia, sizeof(aia));
+ uid = getuid(); pid = getpid();
+ if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, getgid(),
+ pid, pid, &aia.ai_termid)) != NULL)
+ au_write(aufd, tok);
+ if ((tok = au_to_text(autext)) != NULL)
+ au_write(aufd, tok);
+ free(autext);
+ if (path != NULL && (tok = au_to_path(path)) != NULL)
+ au_write(aufd, tok);
+ if ((tok = au_to_return32(0, 0)) != NULL)
+ au_write(aufd, tok);
+ if (au_close(aufd, 1, event) == -1)
+ return (ADE_AU_CLOSE);
+
+ return (ADE_NOERR);
+}
+
+/*
+ * Check for a 'current' symlink and do crash recovery, if needed. Create a new
+ * 'current' symlink. The argument 'curfile' is the file the 'current' symlink
+ * should point to. Returns:
+ * ADE_NOERR on success,
+ * ADE_AU_OPEN if au_open(3) fails,
+ * ADE_AU_CLOSE if au_close(3) fails.
+ * ADE_RENAME if error renaming audit trail file,
+ * ADE_READLINK if error reading the 'current' link,
+ * ADE_SYMLINK if error creating 'current' link.
+ */
+int
+auditd_new_curlink(char *curfile)
+{
+ int len, err;
+ char *ptr;
+ char *path = NULL;
+ struct stat sb;
+ char recoveredname[MAXPATHLEN];
+ char newname[MAXPATHLEN];
+
+ /*
+ * Check to see if audit was shutdown properly. If not, clean up,
+ * recover previous audit trail file, and generate audit record.
+ */
+ len = readlink(AUDIT_CURRENT_LINK, recoveredname, MAXPATHLEN - 1);
+ if (len > 0) {
+ /* 'current' exist but is it pointing at a valid file? */
+ recoveredname[len++] = '\0';
+ if (stat(recoveredname, &sb) == 0) {
+ /* Yes, rename it to a crash recovery file. */
+ strlcpy(newname, recoveredname, MAXPATHLEN);
+
+ if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
+ strlcpy(ptr, CRASH_RECOVERY, TIMESTAMP_LEN);
+ if (rename(recoveredname, newname) != 0)
+ return (ADE_RENAME);
+ } else
+ return (ADE_STRERR);
+
+ path = newname;
+ }
+
+ /* 'current' symlink is (now) invalid so remove it. */
+ (void) unlink(AUDIT_CURRENT_LINK);
+
+ /* Note the crash recovery in current audit trail */
+ err = auditd_gen_record(AUE_audit_recovery, path);
+ if (err)
+ return (err);
+ }
+
+ if (len < 0 && errno != ENOENT)
+ return (ADE_READLINK);
+
+ if (symlink(curfile, AUDIT_CURRENT_LINK) != 0)
+ return (ADE_SYMLINK);
+
+ return (0);
+}
+
+/*
+ * Do just what we need to quickly start auditing. Assume no system logging or
+ * notify. Return:
+ * 0 on success,
+ * -1 on failure.
+ */
+int
+audit_quick_start(void)
+{
+ int err;
+ char *newfile;
+ time_t tt;
+ char TS[TIMESTAMP_LEN];
+
+ /*
+ * Mask auditing of this process.
+ */
+ if (auditd_prevent_audit() != 0)
+ return (-1);
+
+ /*
+ * Read audit_control and get log directories.
+ */
+ err = auditd_read_dirs(NULL, NULL);
+ if (err != ADE_NOERR && err != ADE_SOFTLIM)
+ return (-1);
+
+ /*
+ * Create a new audit trail log.
+ */
+ if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0)
+ return (-1);
+ err = auditd_swap_trail(TS, &newfile, getgid(), NULL);
+ if (err != ADE_NOERR && err != ADE_ACTL)
+ return (-1);
+
+ /*
+ * Add the current symlink and recover from crash, if needed.
+ */
+ if (auditd_new_curlink(newfile) != 0)
+ return(-1);
+
+ /*
+ * At this point auditing has started so generate audit start-up record.
+ */
+ if (auditd_gen_record(AUE_audit_startup, NULL) != 0)
+ return (-1);
+
+ /*
+ * Configure the audit controls.
+ */
+ (void) auditd_set_evcmap();
+ (void) auditd_set_namask();
+ (void) auditd_set_policy();
+ (void) auditd_set_fsize();
+ (void) auditd_set_minfree();
+ (void) auditd_set_host();
+
+ return (0);
+}
+
+/*
+ * Shut down auditing quickly. Assumes that is only called on system shutdown.
+ * Returns:
+ * 0 on success,
+ * -1 on failure.
+ */
+int
+audit_quick_stop(void)
+{
+ int len;
+ long cond;
+ char *ptr;
+ time_t tt;
+ char oldname[MAXPATHLEN];
+ char newname[MAXPATHLEN];
+ char TS[TIMESTAMP_LEN];
+
+ /*
+ * Auditing already disabled?
+ */
+ if (auditon(A_GETCOND, &cond, sizeof(cond)) < 0)
+ return (-1);
+ if (cond == AUC_NOAUDIT)
+ return (0);
+
+ /*
+ * Generate audit shutdown record.
+ */
+ (void) auditd_gen_record(AUE_audit_shutdown, NULL);
+
+ /*
+ * Shutdown auditing in the kernel.
+ */
+ cond = AUC_DISABLED;
+ if (auditon(A_SETCOND, &cond, sizeof(cond)) != 0)
+ return (-1);
+#ifdef __BSM_INTERNAL_NOTIFY_KEY
+ notify_post(__BSM_INTERNAL_NOTIFY_KEY);
+#endif
+
+ /*
+ * Rename last audit trail and remove 'current' link.
+ */
+ len = readlink(AUDIT_CURRENT_LINK, oldname, MAXPATHLEN - 1);
+ if (len < 0)
+ return (-1);
+ oldname[len++] = '\0';
+
+ if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0)
+ return (-1);
+
+ strlcpy(newname, oldname, len);
+
+ if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
+ strlcpy(ptr, TS, TIMESTAMP_LEN);
+ if (rename(oldname, newname) != 0)
+ return (-1);
+ } else
+ return (-1);
+
+ (void) unlink(AUDIT_CURRENT_LINK);
+
+ return (0);
+}
diff --git a/contrib/openbsm/libauditd/libauditd.3 b/contrib/openbsm/libauditd/libauditd.3
new file mode 100644
index 0000000..0fece29
--- /dev/null
+++ b/contrib/openbsm/libauditd/libauditd.3
@@ -0,0 +1,60 @@
+.\"-
+.\" Copyright (c) 2008 Apple Inc.
+.\" 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+.\"
+.\" $P4: //depot/projects/trustedbsd/openbsm/libauditd/libauditd.3#1 $
+.\"
+.Dd December 27, 2008
+.Dt LIBAUDITD 3
+.Os
+.Sh NAME
+.Nm libauditd
+.Nd "auditd support library"
+.Sh LIBRARY
+.Lb libauditd
+.Sh DESCRIPTION
+The
+.Nm
+library provides the internal implementation of
+.Xr auditd 8 .
+.Sh INTERFACES
+There are no public interfaces in
+.Nm .
+.Sh SEE ALSO
+.Xr auditd 8 .
+.Sh HISTORY
+The OpenBSM implementation was created by McAfee Research, the security
+division of McAfee Inc., under contract to Apple Computer, Inc., in 2004.
+It was subsequently adopted by the TrustedBSD Project as the foundation for
+the OpenBSM distribution.
+.Sh AUTHORS
+.An -nosplit
+This software was created by
+.An Stacey Son .
+.Pp
+The Basic Security Module (BSM) interface to audit records and audit event
+stream format were defined by Sun Microsystems.
diff --git a/contrib/openbsm/libbsm/Makefile.am b/contrib/openbsm/libbsm/Makefile.am
index d4e31fe..d7e0652 100644
--- a/contrib/openbsm/libbsm/Makefile.am
+++ b/contrib/openbsm/libbsm/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.am#5 $
+# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.am#8 $
#
if USE_NATIVE_INCLUDES
@@ -14,10 +14,13 @@ libbsm_la_SOURCES = \
bsm_audit.c \
bsm_class.c \
bsm_control.c \
+ bsm_domain.c \
+ bsm_errno.c \
bsm_event.c \
bsm_flags.c \
bsm_io.c \
bsm_mask.c \
+ bsm_socket_type.c \
bsm_token.c \
bsm_user.c
@@ -30,11 +33,14 @@ endif
man3_MANS = \
au_class.3 \
au_control.3 \
+ au_domain.3 \
+ au_errno.3 \
au_event.3 \
au_free_token.3 \
au_io.3 \
au_mask.3 \
au_open.3 \
+ au_socket_type.3 \
au_token.3 \
au_user.3 \
libbsm.3
diff --git a/contrib/openbsm/libbsm/Makefile.in b/contrib/openbsm/libbsm/Makefile.in
index dd09ce0..4d6c847 100644
--- a/contrib/openbsm/libbsm/Makefile.in
+++ b/contrib/openbsm/libbsm/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.in#9 $
+# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.in#13 $
#
VPATH = @srcdir@
@@ -60,13 +60,15 @@ libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libbsm_la_LIBADD =
am__libbsm_la_SOURCES_DIST = bsm_audit.c bsm_class.c bsm_control.c \
- bsm_event.c bsm_flags.c bsm_io.c bsm_mask.c bsm_token.c \
- bsm_user.c bsm_notify.c bsm_wrappers.c
+ bsm_domain.c bsm_errno.c bsm_event.c bsm_flags.c bsm_io.c \
+ bsm_mask.c bsm_socket_type.c bsm_token.c bsm_user.c \
+ bsm_notify.c bsm_wrappers.c
@HAVE_AUDIT_SYSCALLS_TRUE@am__objects_1 = bsm_notify.lo \
@HAVE_AUDIT_SYSCALLS_TRUE@ bsm_wrappers.lo
am_libbsm_la_OBJECTS = bsm_audit.lo bsm_class.lo bsm_control.lo \
- bsm_event.lo bsm_flags.lo bsm_io.lo bsm_mask.lo bsm_token.lo \
- bsm_user.lo $(am__objects_1)
+ bsm_domain.lo bsm_errno.lo bsm_event.lo bsm_flags.lo bsm_io.lo \
+ bsm_mask.lo bsm_socket_type.lo bsm_token.lo bsm_user.lo \
+ $(am__objects_1)
libbsm_la_OBJECTS = $(am_libbsm_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(top_builddir)/config@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
@@ -199,17 +201,20 @@ top_srcdir = @top_srcdir@
@USE_NATIVE_INCLUDES_FALSE@INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
@USE_NATIVE_INCLUDES_TRUE@INCLUDES = -I$(top_builddir) -I$(top_srcdir)
lib_LTLIBRARIES = libbsm.la
-libbsm_la_SOURCES = bsm_audit.c bsm_class.c bsm_control.c bsm_event.c \
- bsm_flags.c bsm_io.c bsm_mask.c bsm_token.c bsm_user.c \
- $(am__append_1)
+libbsm_la_SOURCES = bsm_audit.c bsm_class.c bsm_control.c bsm_domain.c \
+ bsm_errno.c bsm_event.c bsm_flags.c bsm_io.c bsm_mask.c \
+ bsm_socket_type.c bsm_token.c bsm_user.c $(am__append_1)
man3_MANS = \
au_class.3 \
au_control.3 \
+ au_domain.3 \
+ au_errno.3 \
au_event.3 \
au_free_token.3 \
au_io.3 \
au_mask.3 \
au_open.3 \
+ au_socket_type.3 \
au_token.3 \
au_user.3 \
libbsm.3
@@ -286,11 +291,14 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_audit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_class.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_control.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_domain.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_errno.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_event.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_flags.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_io.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_mask.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_notify.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_socket_type.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_token.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_user.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_wrappers.Plo@am__quote@
diff --git a/contrib/openbsm/libbsm/au_domain.3 b/contrib/openbsm/libbsm/au_domain.3
new file mode 100644
index 0000000..14ac45a
--- /dev/null
+++ b/contrib/openbsm/libbsm/au_domain.3
@@ -0,0 +1,87 @@
+.\"-
+.\" Copyright (c) 2008 Apple Inc.
+.\" 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+.\"
+.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_domain.3#1 $
+.\"
+.Dd December 28, 2008
+.Dt AU_BSM_TO_DOMAIN 3
+.Os
+.Sh NAME
+.Nm au_bsm_to_domain ,
+.Nm au_domain_to_bsm
+.Nd "convert between BSM and local protocol domains"
+.Sh LIBRARY
+.Lb libbsm
+.Sh SYNOPSIS
+.In bsm/libbsm.h
+.Ft int
+.Fn au_bsm_to_domain "u_short bsm_domain" "int *local_domainp"
+.Ft u_short
+.Fn au_domain_to_bsm "int local_domain"
+.Sh DESCRIPTION
+These interfaces may be used to convert between the local and BSM protocol
+domains.
+The
+.Fn au_bsm_to_domain
+function accepts a BSM domain,
+.Fa bsm_domain ,
+and converts it to a local domain, such as those passed to
+.Xr socket 2 ,
+that will be stored in the integer pointed to by
+.Fa local_domainp
+if successful.
+This call will fail if the BSM domain cannot be mapped into a local domain,
+which may occur if the socket token was generated on another operating
+system.
+.Pp
+.Fn au_domain_to_bsm
+function accepts a local domain, and returns the BSM domain for it.
+This call cannot fail, and instead returns a BSM domain indicating to a later
+decoder that the domain could not be encoded.
+.Sh RETURN VALULES
+On success,
+.Fn au_bsm_to_domain
+returns 0 and a converted domain; on failure, it returns -1 but does not set
+.Xr errno 2 .
+.Sh SEE ALSO
+.Xr au_bsm_to_socket_type 3 ,
+.Xr au_socket_type_to_bsm 3 ,
+.Xr au_to_socket_ex 3 ,
+.Xr libbsm 3
+.Sh HISTORY
+.Fn au_bsm_to_domain
+and
+.Fn au_domain_to_bsm
+were introduced in OpenBSM 1.1.
+.Sh AUTHORS
+These functions were implemented by
+.An Robert Watson
+under contract to Apple Inc.
+.Pp
+The Basic Security Module (BSM) interface to audit records and audit event
+stream format were defined by Sun Microsystems.
diff --git a/contrib/openbsm/libbsm/au_errno.3 b/contrib/openbsm/libbsm/au_errno.3
new file mode 100644
index 0000000..f7ff8a0
--- /dev/null
+++ b/contrib/openbsm/libbsm/au_errno.3
@@ -0,0 +1,111 @@
+.\"-
+.\" Copyright (c) 2008 Apple Inc.
+.\" 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+.\"
+.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_errno.3#3 $
+.\"
+.Dd December 8, 2008
+.Dt AU_BSM_TO_ERRNO 3
+.Os
+.Sh NAME
+.Nm au_bsm_to_errno ,
+.Nm au_errno_to_bsm ,
+.Nm au_strerror
+.Nd "convert between BSM and local error numbers"
+.Sh LIBRARY
+.Lb libbsm
+.Sh SYNOPSIS
+.In bsm/libbsm.h
+.Ft int
+.Fn au_bsm_to_errno "u_char bsm_error" "int *errorp"
+.Ft u_char
+.Fn au_errno_to_bsm "int error"
+.Ft const char *
+.Fn au_strerror "int bsm_error"
+.Sh DESCRIPTION
+These interfaces may be used to convert between the local (
+.Xr errno 2 )
+and BSM error number spaces found in BSM return tokens.
+.Pp
+The
+.Fn au_bsm_to_errno
+function accepts a BSM error value,
+.Fa bsm_error,
+and converts it to an
+.Xr errno 2
+that will be stored in the integer pointed to by
+.Fa errorp
+if successful.
+This call will fail if the BSM error cannot be mapped into a local error
+number, which may occur if the return token was generated on another
+operating system.
+.Pp
+.Fn au_errno_to_bsm
+function accepts a local
+.Xr errno 2
+value, and returns the BSM error number for it.
+This call cannot fail, and instead returns a BSM error number indicating to
+a later decoder that the error could not be encoded.
+.Pp
+The
+.Fn au_strerror
+converts a BSM error value to a string, generally by converting first to a
+local error number and using the local
+.Xr strerror 3
+function, but will also work for errors that are not locally defined.
+.Sh RETURN VALULES
+On success,
+.Fn au_bsm_to_errno
+returns 0 and a converted error value; on failure, it returns -1 but does not
+set
+.Xr errno 2 .
+.Pp
+On success,
+.Fn au_strerror
+returns a pointer to an error string; on failure it will return
+.Dv NULL .
+.Sh SEE ALSO
+.Xr au_to_return 3 ,
+.Xr au_to_return32 3 ,
+.Xr au_to_return64 3 ,
+.Xr libbsm 3
+.Sh HISTORY
+.Fn au_bsm_to_errno
+and
+.Fn au_errno_to_bsm
+were introduced in OpenBSM 1.1.
+.Sh AUTHORS
+These functions were implemented by
+.An Robert Watson
+under contract to Apple Inc.
+.Pp
+The Basic Security Module (BSM) interface to audit records and audit event
+stream format were defined by Sun Microsystems.
+.Sh BUGS
+.Nm au_strerror
+is unable to provide localized strings for errors not available in the local
+operating system.
diff --git a/contrib/openbsm/libbsm/au_socket_type.3 b/contrib/openbsm/libbsm/au_socket_type.3
new file mode 100644
index 0000000..174e5c7
--- /dev/null
+++ b/contrib/openbsm/libbsm/au_socket_type.3
@@ -0,0 +1,93 @@
+.\"-
+.\" Copyright (c) 2008 Apple Inc.
+.\" 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+.\"
+.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_socket_type.3#1 $
+.\"
+.Dd December 28, 2008
+.Dt AU_BSM_TO_SOCKET_TYPE 3
+.Os
+.Sh NAME
+.Nm au_bsm_to_socket_type ,
+.Nm au_socket_type_to_bsm
+.Nd "convert between BSM and local socket types"
+.Sh LIBRARY
+.Lb libbsm
+.Sh SYNOPSIS
+.In bsm/libbsm.h
+.Ft int
+.Fn au_bsm_to_socket_type "u_short bsm_socket_type" "int *local_socket_typep"
+.Ft u_short
+.Fn au_socket_type_to_bsm "int local_socket_type"
+.Sh DESCRIPTION
+These interfaces may be used to convert between the local and BSM socket
+types.
+The
+.Fn au_bsm_to_socket_type
+function accepts a BSM socket type,
+.Fa bsm_socket_type ,
+and converts it to a local socket type, such as those passed to
+.Xr socket 2 ,
+that will be stored in the integer pointed to by
+.Fa local_socket_typep
+if successful.
+This call will fail if the BSM socket type cannot be mapped into a local
+socket type, which may occur if the socket token was generated on another
+operating system.
+.Pp
+.Fn au_socket_type_to_bsm
+function accepts a local socket type, and returns the BSM socket type for it.
+This call cannot fail, and instead returns a BSM socket type indicating to a
+later decoder that the socket type could not be encoded.
+.Sh RETURN VALULES
+On success,
+.Fn au_bsm_to_socket_type
+returns 0 and a converted socket type; on failure, it returns -1 but does not
+set
+.Xr errno 2 .
+.Pp
+On success,
+.Fn au_strerror
+returns a pointer to an error string; on failure it will return
+.Dv NULL .
+.Sh SEE ALSO
+.Xr au_bsm_to_domain 3 ,
+.Xr au_domain_to_bsm 3 ,
+.Xr au_to_socket_ex 3 ,
+.Xr libbsm 3
+.Sh HISTORY
+.Fn au_bsm_to_socket_type
+and
+.Fn au_socket_type_to_bsm
+were introduced in OpenBSM 1.1.
+.Sh AUTHORS
+These functions were implemented by
+.An Robert Watson
+under contract to Apple Inc.
+.Pp
+The Basic Security Module (BSM) interface to audit records and audit event
+stream format were defined by Sun Microsystems.
diff --git a/contrib/openbsm/libbsm/au_token.3 b/contrib/openbsm/libbsm/au_token.3
index cb8ef70..2888729 100644
--- a/contrib/openbsm/libbsm/au_token.3
+++ b/contrib/openbsm/libbsm/au_token.3
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_token.3#15 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_token.3#17 $
.\"
.Dd April 19, 2005
.Dt AU_TOKEN 3
@@ -60,6 +60,7 @@
.Nm au_to_sock_inet32 ,
.Nm au_to_sock_inet128 ,
.Nm au_to_sock_inet ,
+.Nm au_to_socket_ex ,
.Nm au_to_subject32 ,
.Nm au_to_subject64 ,
.Nm au_to_subject ,
@@ -156,6 +157,8 @@
.Ft "token_t *"
.Fn au_to_sock_int "struct sockaddr_in *so"
.Ft "token_t *"
+.Fn au_to_socket_ex "u_short so_domain" "u_short so_type" "struct sockaddr *sa_local" "struct sockaddr *sa_remote"
+.Ft "token_t *"
.Fo au_to_subject32
.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid"
.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_t *tid"
@@ -209,6 +212,15 @@
These interfaces support the allocation of BSM audit tokens, represented by
.Vt token_t ,
for various data types.
+.Pp
+.Xr au_errno_to_bsm 3
+must be used to convert local
+.Xr errno 2
+errors to BSM error numbers before they are passed to
+.Fn au_to_return ,
+.Fn au_to_return32 ,
+and
+.Fn au_to_return64 .
.Sh RETURN VALUES
On success, a pointer to a
.Vt token_t
@@ -221,6 +233,7 @@ On failure,
will be returned, and an error condition returned via
.Va errno .
.Sh SEE ALSO
+.Xr au_errno_to_bsm 3 ,
.Xr libbsm 3
.Sh HISTORY
The OpenBSM implementation was created by McAfee Research, the security
diff --git a/contrib/openbsm/libbsm/audit_submit.3 b/contrib/openbsm/libbsm/audit_submit.3
index 6a61d99..80a2578 100644
--- a/contrib/openbsm/libbsm/audit_submit.3
+++ b/contrib/openbsm/libbsm/audit_submit.3
@@ -27,7 +27,7 @@
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/audit_submit.3#14 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/audit_submit.3#15 $
.\"
.Dd January 18, 2008
.Dt audit_submit 3
@@ -58,7 +58,10 @@ The return token is dependent on the
.Fa status
and
.Fa reterr
-arguments.
+arguments; unlike the argument to
+.Xr au_to_return ,
+.Fa reterr
+should be a local rather than BSM error number.
Optionally, a text token will be created as a part of this record.
.Pp
Text token output is under the control of a
diff --git a/contrib/openbsm/libbsm/bsm_audit.c b/contrib/openbsm/libbsm/bsm_audit.c
index 2fd9466..6537b37 100644
--- a/contrib/openbsm/libbsm/bsm_audit.c
+++ b/contrib/openbsm/libbsm/bsm_audit.c
@@ -30,7 +30,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_audit.c#31 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_audit.c#35 $
*/
#include <sys/types.h>
@@ -48,7 +48,9 @@
#include <netinet/in.h>
#include <errno.h>
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
#include <pthread.h>
+#endif
#include <stdlib.h>
#include <string.h>
@@ -65,7 +67,9 @@ static int audit_rec_count = 0;
*/
static LIST_HEAD(, au_record) audit_free_q;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
/*
* This call frees a token_t and its internal data.
@@ -93,7 +97,9 @@ au_open(void)
{
au_record_t *rec = NULL;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (audit_rec_count == 0)
LIST_INIT(&audit_free_q);
@@ -108,7 +114,9 @@ au_open(void)
LIST_REMOVE(rec, au_rec_q);
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
if (rec == NULL) {
/*
@@ -125,10 +133,14 @@ au_open(void)
return (-1);
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (audit_rec_count == MAX_AUDIT_RECORDS) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
free(rec->data);
free(rec);
@@ -140,7 +152,9 @@ au_open(void)
open_desc_table[audit_rec_count] = rec;
audit_rec_count++;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
@@ -205,13 +219,16 @@ au_write(int d, token_t *tok)
static int
au_assemble(au_record_t *rec, short event)
{
- token_t *header, *tok, *trailer;
- size_t tot_rec_size, hdrsize;
- u_char *dptr;
+#ifdef HAVE_AUDIT_SYSCALLS
struct in6_addr *aptr;
- int error;
struct auditinfo_addr aia;
struct timeval tm;
+ size_t hdrsize;
+#endif /* HAVE_AUDIT_SYSCALLS */
+ token_t *header, *tok, *trailer;
+ size_t tot_rec_size;
+ u_char *dptr;
+ int error;
#ifdef HAVE_AUDIT_SYSCALLS
/*
@@ -221,7 +238,7 @@ au_assemble(au_record_t *rec, short event)
aia.ai_termid.at_type = AU_IPv4;
aia.ai_termid.at_addr[0] = INADDR_ANY;
if (auditon(A_GETKAUDIT, &aia, sizeof(aia)) < 0) {
- if (errno != ENOSYS)
+ if (errno != ENOSYS && errno != EPERM)
return (-1);
#endif /* HAVE_AUDIT_SYSCALLS */
tot_rec_size = rec->len + AUDIT_HEADER_SIZE +
@@ -242,6 +259,8 @@ au_assemble(au_record_t *rec, short event)
(IN6_IS_ADDR_UNSPECIFIED(aptr)) ?
AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&aia);
break;
+ default:
+ return (-1);
}
tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE;
/*
@@ -299,12 +318,16 @@ au_teardown(au_record_t *rec)
rec->used = 0;
rec->len = 0;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
/* Add the record to the freelist tail */
LIST_INSERT_HEAD(&audit_free_q, rec, au_rec_q);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
#ifdef HAVE_AUDIT_SYSCALLS
diff --git a/contrib/openbsm/libbsm/bsm_class.c b/contrib/openbsm/libbsm/bsm_class.c
index 0acfed4..1978e44 100644
--- a/contrib/openbsm/libbsm/bsm_class.c
+++ b/contrib/openbsm/libbsm/bsm_class.c
@@ -27,7 +27,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_class.c#14 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_class.c#15 $
*/
#include <config/config.h>
@@ -35,7 +35,9 @@
#include <bsm/libbsm.h>
#include <string.h>
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
#include <pthread.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -51,7 +53,9 @@ static FILE *fp = NULL;
static char linestr[AU_LINE_MAX];
static const char *classdelim = ":";
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
/*
* Parse a single line from the audit_class file passed in str to the struct
@@ -133,9 +137,13 @@ getauclassent_r(struct au_class_ent *c)
{
struct au_class_ent *cp;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
cp = getauclassent_r_locked(c);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (cp);
}
@@ -152,9 +160,13 @@ getauclassent(void)
c.ac_name = class_ent_name;
c.ac_desc = class_ent_desc;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
cp = getauclassent_r_locked(&c);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (cp);
}
@@ -175,9 +187,13 @@ void
setauclass(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setauclass_locked();
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -191,15 +207,21 @@ getauclassnam_r(struct au_class_ent *c, const char *name)
if (name == NULL)
return (NULL);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setauclass_locked();
while ((cp = getauclassent_r_locked(c)) != NULL) {
if (strcmp(name, cp->ac_name) == 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (cp);
}
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (NULL);
}
@@ -230,13 +252,17 @@ getauclassnum_r(struct au_class_ent *c, au_class_t class_number)
{
struct au_class_ent *cp;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setauclass_locked();
while ((cp = getauclassent_r_locked(c)) != NULL) {
if (class_number == cp->ac_class)
return (cp);
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (NULL);
}
@@ -263,10 +289,14 @@ void
endauclass(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
diff --git a/contrib/openbsm/libbsm/bsm_control.c b/contrib/openbsm/libbsm/bsm_control.c
index 96cbc23..4fed3ff 100644
--- a/contrib/openbsm/libbsm/bsm_control.c
+++ b/contrib/openbsm/libbsm/bsm_control.c
@@ -27,7 +27,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#23 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#24 $
*/
#include <config/config.h>
@@ -36,7 +36,9 @@
#include <errno.h>
#include <string.h>
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
#include <pthread.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -58,7 +60,9 @@ static char *delim = ":";
static char inacdir = 0;
static char ptrmoved = 0;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
/*
* Returns the string value corresponding to the given label from the
@@ -318,9 +322,13 @@ void
setac(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -330,13 +338,17 @@ void
endac(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
ptrmoved = 1;
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -352,7 +364,9 @@ getacdir(char *name, int len)
* Check if another function was called between successive calls to
* getacdir.
*/
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (inacdir && ptrmoved) {
ptrmoved = 0;
if (fp != NULL)
@@ -360,19 +374,27 @@ getacdir(char *name, int len)
ret = 2;
}
if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (dir == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-1);
}
if (strlen(dir) >= (size_t)len) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-3);
}
strlcpy(name, dir, len);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (ret);
}
@@ -384,18 +406,26 @@ getacmin(int *min_val)
{
char *min;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (min == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (1);
}
*min_val = atoi(min);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (0);
}
@@ -408,20 +438,28 @@ getacfilesz(size_t *filesz_val)
char *filesz, *dummy;
long long ll;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &filesz) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (filesz == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
errno = EINVAL;
return (1);
}
ll = strtoll(filesz, &dummy, 10);
if (*dummy != '\0') {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
errno = EINVAL;
return (-1);
}
@@ -430,12 +468,16 @@ getacfilesz(size_t *filesz_val)
* indicates no rotation size.
*/
if (ll < 0 || (ll > 0 && ll < MIN_AUDIT_FILE_SIZE)) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
errno = EINVAL;
return (-1);
}
*filesz_val = ll;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (0);
}
@@ -447,22 +489,32 @@ getacflg(char *auditstr, int len)
{
char *str;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (str == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (1);
}
if (strlen(str) >= (size_t)len) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-3);
}
strlcpy(auditstr, str, len);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (0);
}
@@ -474,22 +526,32 @@ getacna(char *auditstr, int len)
{
char *str;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (str == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (1);
}
if (strlen(str) >= (size_t)len) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-3);
}
strlcpy(auditstr, str, len);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (0);
}
@@ -501,22 +563,32 @@ getacpol(char *auditstr, size_t len)
{
char *str;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
if (getstrfromtype_locked(POLICY_CONTROL_ENTRY, &str) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (str == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-1);
}
if (strlen(str) >= len) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-3);
}
strlcpy(auditstr, str, len);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (0);
}
@@ -525,21 +597,31 @@ getachost(char *auditstr, size_t len)
{
char *str;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setac_locked();
if (getstrfromtype_locked(AUDIT_HOST_CONTROL_ENTRY, &str) < 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-2);
}
if (str == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (1);
}
if (strlen(str) >= len) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-3);
}
strcpy(auditstr, str);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (0);
}
diff --git a/contrib/openbsm/libbsm/bsm_domain.c b/contrib/openbsm/libbsm/bsm_domain.c
new file mode 100644
index 0000000..496235f
--- /dev/null
+++ b/contrib/openbsm/libbsm/bsm_domain.c
@@ -0,0 +1,499 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_domain.c#2 $
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <config/config.h>
+
+#include <bsm/audit_domain.h>
+#include <bsm/libbsm.h>
+
+struct bsm_domain {
+ u_short bd_bsm_domain;
+ int bd_local_domain;
+};
+
+#define PF_NO_LOCAL_MAPPING -600
+
+static const struct bsm_domain bsm_domains[] = {
+ { BSM_PF_UNSPEC, PF_UNSPEC },
+ { BSM_PF_LOCAL, PF_LOCAL },
+ { BSM_PF_INET, PF_INET },
+ { BSM_PF_IMPLINK,
+#ifdef PF_IMPLINK
+ PF_IMPLINK
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PUP,
+#ifdef PF_PUP
+ PF_PUP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CHAOS,
+#ifdef PF_CHAOS
+ PF_CHAOS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NS,
+#ifdef PF_NS
+ PF_NS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NBS,
+#ifdef PF_NBS
+ PF_NBS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ECMA,
+#ifdef PF_ECMA
+ PF_ECMA
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_DATAKIT,
+#ifdef PF_DATAKIT
+ PF_DATAKIT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CCITT,
+#ifdef PF_CCITT
+ PF_CCITT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SNA, PF_SNA },
+ { BSM_PF_DECnet, PF_DECnet },
+ { BSM_PF_DLI,
+#ifdef PF_DLI
+ PF_DLI
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_LAT,
+#ifdef PF_LAT
+ PF_LAT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_HYLINK,
+#ifdef PF_HYLINK
+ PF_HYLINK
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_APPLETALK, PF_APPLETALK },
+ { BSM_PF_NIT,
+#ifdef PF_NIT
+ PF_NIT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_802,
+#ifdef PF_802
+ PF_802
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_OSI,
+#ifdef PF_OSI
+ PF_OSI
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_X25,
+#ifdef PF_X25
+ PF_X25
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_OSINET,
+#ifdef PF_OSINET
+ PF_OSINET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_GOSIP,
+#ifdef PF_GOSIP
+ PF_GOSIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IPX, PF_IPX },
+ { BSM_PF_ROUTE, PF_ROUTE },
+ { BSM_PF_LINK,
+#ifdef PF_LINK
+ PF_LINK
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_INET6, PF_INET6 },
+ { BSM_PF_KEY, PF_KEY },
+ { BSM_PF_NCA,
+#ifdef PF_NCA
+ PF_NCA
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_POLICY,
+#ifdef PF_POLICY
+ PF_POLICY
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_INET_OFFLOAD,
+#ifdef PF_INET_OFFLOAD
+ PF_INET_OFFLOAD
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NETBIOS,
+#ifdef PF_NETBIOS
+ PF_NETBIOS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ISO,
+#ifdef PF_ISO
+ PF_ISO
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_XTP,
+#ifdef PF_XTP
+ PF_XTP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_COIP,
+#ifdef PF_COIP
+ PF_COIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CNT,
+#ifdef PF_CNT
+ PF_CNT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_RTIP,
+#ifdef PF_RTIP
+ PF_RTIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SIP,
+#ifdef PF_SIP
+ PF_SIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PIP,
+#ifdef PF_PIP
+ PF_PIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ISDN,
+#ifdef PF_ISDN
+ PF_ISDN
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_E164,
+#ifdef PF_E164
+ PF_E164
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NATM,
+#ifdef PF_NATM
+ PF_NATM
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ATM,
+#ifdef PF_ATM
+ PF_ATM
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NETGRAPH,
+#ifdef PF_NETGRAPH
+ PF_NETGRAPH
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SLOW,
+#ifdef PF_SLOW
+ PF_SLOW
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SCLUSTER,
+#ifdef PF_SCLUSTER
+ PF_SCLUSTER
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ARP,
+#ifdef PF_ARP
+ PF_ARP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_BLUETOOTH,
+#ifdef PF_BLUETOOTH
+ PF_BLUETOOTH
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IEEE80211,
+#ifdef PF_IEEE80211
+ PF_IEEE80211
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_AX25,
+#ifdef PF_AX25
+ PF_AX25
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ROSE,
+#ifdef PF_ROSE
+ PF_ROSE
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NETBEUI,
+#ifdef PF_NETBEUI
+ PF_NETBEUI
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SECURITY,
+#ifdef PF_SECURITY
+ PF_SECURITY
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PACKET,
+#ifdef PF_PACKET
+ PF_PACKET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ASH,
+#ifdef PF_ASH
+ PF_ASH
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ECONET,
+#ifdef PF_ECONET
+ PF_ECONET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ATMSVC,
+#ifdef PF_ATMSVC
+ PF_ATMSVC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IRDA,
+#ifdef PF_IRDA
+ PF_IRDA
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PPPOX,
+#ifdef PF_PPPOX
+ PF_PPPOX
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_WANPIPE,
+#ifdef PF_WANPIPE
+ PF_WANPIPE
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_LLC,
+#ifdef PF_LLC
+ PF_LLC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CAN,
+#ifdef PF_CAN
+ PF_CAN
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_TIPC,
+#ifdef PF_TIPC
+ PF_TIPC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IUCV,
+#ifdef PF_IUCV
+ PF_IUCV
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_RXRPC,
+#ifdef PF_RXRPC
+ PF_RXRPC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PHONET,
+#ifdef PF_PHONET
+ PF_PHONET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+};
+static const int bsm_domains_count = sizeof(bsm_domains) /
+ sizeof(bsm_domains[0]);
+
+static const struct bsm_domain *
+bsm_lookup_local_domain(int local_domain)
+{
+ int i;
+
+ for (i = 0; i < bsm_domains_count; i++) {
+ if (bsm_domains[i].bd_local_domain == local_domain)
+ return (&bsm_domains[i]);
+ }
+ return (NULL);
+}
+
+u_short
+au_domain_to_bsm(int local_domain)
+{
+ const struct bsm_domain *bstp;
+
+ bstp = bsm_lookup_local_domain(local_domain);
+ if (bstp == NULL)
+ return (BSM_PF_UNKNOWN);
+ return (bstp->bd_bsm_domain);
+}
+
+static const struct bsm_domain *
+bsm_lookup_bsm_domain(u_short bsm_domain)
+{
+ int i;
+
+ for (i = 0; i < bsm_domains_count; i++) {
+ if (bsm_domains[i].bd_bsm_domain == bsm_domain)
+ return (&bsm_domains[i]);
+ }
+ return (NULL);
+}
+
+int
+au_bsm_to_domain(u_short bsm_domain, int *local_domainp)
+{
+ const struct bsm_domain *bstp;
+
+ bstp = bsm_lookup_bsm_domain(bsm_domain);
+ if (bstp == NULL || bstp->bd_local_domain)
+ return (-1);
+ *local_domainp = bstp->bd_local_domain;
+ return (0);
+}
diff --git a/contrib/openbsm/libbsm/bsm_errno.c b/contrib/openbsm/libbsm/bsm_errno.c
new file mode 100644
index 0000000..78aad97
--- /dev/null
+++ b/contrib/openbsm/libbsm/bsm_errno.c
@@ -0,0 +1,661 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_errno.c#16 $
+ */
+
+#include <sys/types.h>
+
+#include <config/config.h>
+
+#include <bsm/audit_errno.h>
+#include <bsm/libbsm.h>
+
+#include <errno.h>
+#include <string.h>
+
+/*
+ * Different operating systems use different numeric constants for different
+ * error numbers, and sometimes error numbers don't exist in more than one
+ * operating system. These routines convert between BSM and local error
+ * number spaces, subject to the above realities. BSM error numbers are
+ * stored in a single 8-bit character, so don't have a byte order.
+ *
+ * Don't include string definitions when this code is compiled into a kernel.
+ */
+struct bsm_errno {
+ int be_bsm_errno;
+ int be_local_errno;
+#if !defined(KERNEL) && !defined(_KERNEL)
+ const char *be_strerror;
+#endif
+};
+
+#define ERRNO_NO_LOCAL_MAPPING -600
+
+#if !defined(KERNEL) && !defined(_KERNEL)
+#define ES(x) x
+#else
+#define ES(x)
+#endif
+
+/*
+ * Mapping table -- please maintain in numeric sorted order with respect to
+ * the BSM constant. Today we do a linear lookup, but could switch to a
+ * binary search if it makes sense. We only ifdef errors that aren't
+ * generally available, but it does make the table a lot more ugly.
+ *
+ * XXXRW: It would be nice to have a similar ordered table mapping to BSM
+ * constant from local constant, but the order of local constants varies by
+ * OS. Really we need to build that table at compile-time but don't do that
+ * yet.
+ *
+ * XXXRW: We currently embed English-language error strings here, but should
+ * support catalogues; these are only used if the OS doesn't have an error
+ * string using strerror(3).
+ */
+static const struct bsm_errno bsm_errnos[] = {
+ { BSM_ERRNO_ESUCCESS, 0, ES("Success") },
+ { BSM_ERRNO_EPERM, EPERM, ES("Operation not permitted") },
+ { BSM_ERRNO_ENOENT, ENOENT, ES("No such file or directory") },
+ { BSM_ERRNO_ESRCH, ESRCH, ES("No such process") },
+ { BSM_ERRNO_EINTR, EINTR, ES("Interrupted system call") },
+ { BSM_ERRNO_EIO, EIO, ES("Input/output error") },
+ { BSM_ERRNO_ENXIO, ENXIO, ES("Device not configured") },
+ { BSM_ERRNO_E2BIG, E2BIG, ES("Argument list too long") },
+ { BSM_ERRNO_ENOEXEC, ENOEXEC, ES("Exec format error") },
+ { BSM_ERRNO_EBADF, EBADF, ES("Bad file descriptor") },
+ { BSM_ERRNO_ECHILD, ECHILD, ES("No child processes") },
+ { BSM_ERRNO_EAGAIN, EAGAIN, ES("Resource temporarily unavailable") },
+ { BSM_ERRNO_ENOMEM, ENOMEM, ES("Cannot allocate memory") },
+ { BSM_ERRNO_EACCES, EACCES, ES("Permission denied") },
+ { BSM_ERRNO_EFAULT, EFAULT, ES("Bad address") },
+ { BSM_ERRNO_ENOTBLK, ENOTBLK, ES("Block device required") },
+ { BSM_ERRNO_EBUSY, EBUSY, ES("Device busy") },
+ { BSM_ERRNO_EEXIST, EEXIST, ES("File exists") },
+ { BSM_ERRNO_EXDEV, EXDEV, ES("Cross-device link") },
+ { BSM_ERRNO_ENODEV, ENODEV, ES("Operation not supported by device") },
+ { BSM_ERRNO_ENOTDIR, ENOTDIR, ES("Not a directory") },
+ { BSM_ERRNO_EISDIR, EISDIR, ES("Is a directory") },
+ { BSM_ERRNO_EINVAL, EINVAL, ES("Invalid argument") },
+ { BSM_ERRNO_ENFILE, ENFILE, ES("Too many open files in system") },
+ { BSM_ERRNO_EMFILE, EMFILE, ES("Too many open files") },
+ { BSM_ERRNO_ENOTTY, ENOTTY, ES("Inappropriate ioctl for device") },
+ { BSM_ERRNO_ETXTBSY, ETXTBSY, ES("Text file busy") },
+ { BSM_ERRNO_EFBIG, EFBIG, ES("File too large") },
+ { BSM_ERRNO_ENOSPC, ENOSPC, ES("No space left on device") },
+ { BSM_ERRNO_ESPIPE, ESPIPE, ES("Illegal seek") },
+ { BSM_ERRNO_EROFS, EROFS, ES("Read-only file system") },
+ { BSM_ERRNO_EMLINK, EMLINK, ES("Too many links") },
+ { BSM_ERRNO_EPIPE, EPIPE, ES("Broken pipe") },
+ { BSM_ERRNO_EDOM, EDOM, ES("Numerical argument out of domain") },
+ { BSM_ERRNO_ERANGE, ERANGE, ES("Result too large") },
+ { BSM_ERRNO_ENOMSG, ENOMSG, ES("No message of desired type") },
+ { BSM_ERRNO_EIDRM, EIDRM, ES("Identifier removed") },
+ { BSM_ERRNO_ECHRNG,
+#ifdef ECHRNG
+ ECHRNG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Channel number out of range") },
+ { BSM_ERRNO_EL2NSYNC,
+#ifdef EL2NSYNC
+ EL2NSYNC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 2 not synchronized") },
+ { BSM_ERRNO_EL3HLT,
+#ifdef EL3HLT
+ EL3HLT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 3 halted") },
+ { BSM_ERRNO_EL3RST,
+#ifdef EL3RST
+ EL3RST,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 3 reset") },
+ { BSM_ERRNO_ELNRNG,
+#ifdef ELNRNG
+ ELNRNG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Link number out of range") },
+ { BSM_ERRNO_EUNATCH,
+#ifdef EUNATCH
+ EUNATCH,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Protocol driver not attached") },
+ { BSM_ERRNO_ENOCSI,
+#ifdef ENOCSI
+ ENOCSI,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No CSI structure available") },
+ { BSM_ERRNO_EL2HLT,
+#ifdef EL2HLT
+ EL2HLT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 2 halted") },
+ { BSM_ERRNO_EDEADLK, EDEADLK, ES("Resource deadlock avoided") },
+ { BSM_ERRNO_ENOLCK, ENOLCK, ES("No locks available") },
+ { BSM_ERRNO_ECANCELED, ECANCELED, ES("Operation canceled") },
+ { BSM_ERRNO_ENOTSUP, ENOTSUP, ES("Operation not supported") },
+ { BSM_ERRNO_EDQUOT, EDQUOT, ES("Disc quota exceeded") },
+ { BSM_ERRNO_EBADE,
+#ifdef EBADE
+ EBADE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid exchange") },
+ { BSM_ERRNO_EBADR,
+#ifdef EBADR
+ EBADR,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid request descriptor") },
+ { BSM_ERRNO_EXFULL,
+#ifdef EXFULL
+ EXFULL,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Exchange full") },
+ { BSM_ERRNO_ENOANO,
+#ifdef ENOANO
+ ENOANO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No anode") },
+ { BSM_ERRNO_EBADRQC,
+#ifdef EBADRQC
+ EBADRQC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid request descriptor") },
+ { BSM_ERRNO_EBADSLT,
+#ifdef EBADSLT
+ EBADSLT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid slot") },
+ { BSM_ERRNO_EDEADLOCK,
+#ifdef EDEADLOCK
+ EDEADLOCK,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Resource deadlock avoided") },
+ { BSM_ERRNO_EBFONT,
+#ifdef EBFONT
+ EBFONT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad font file format") },
+ { BSM_ERRNO_EOWNERDEAD,
+#ifdef EOWNERDEAD
+ EOWNERDEAD,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Process died with the lock") },
+ { BSM_ERRNO_ENOTRECOVERABLE,
+#ifdef ENOTRECOVERABLE
+ ENOTRECOVERABLE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Lock is not recoverable") },
+ { BSM_ERRNO_ENOSTR,
+#ifdef ENOSTR
+ ENOSTR,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Device not a stream") },
+ { BSM_ERRNO_ENONET,
+#ifdef ENONET
+ ENONET,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Machine is not on the network") },
+ { BSM_ERRNO_ENOPKG,
+#ifdef ENOPKG
+ ENOPKG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Package not installed") },
+ { BSM_ERRNO_EREMOTE, EREMOTE,
+ ES("Too many levels of remote in path") },
+ { BSM_ERRNO_ENOLINK,
+#ifdef ENOLINK
+ ENOLINK,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Link has been severed") },
+ { BSM_ERRNO_EADV,
+#ifdef EADV
+ EADV,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Advertise error") },
+ { BSM_ERRNO_ESRMNT,
+#ifdef ESRMNT
+ ESRMNT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("srmount error") },
+ { BSM_ERRNO_ECOMM,
+#ifdef ECOMM
+ ECOMM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Communication error on send") },
+ { BSM_ERRNO_EPROTO,
+#ifdef EPROTO
+ EPROTO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Protocol error") },
+ { BSM_ERRNO_ELOCKUNMAPPED,
+#ifdef ELOCKUNMAPPED
+ ELOCKUNMAPPED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Locked lock was unmapped") },
+ { BSM_ERRNO_ENOTACTIVE,
+#ifdef ENOTACTIVE
+ ENOTACTIVE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Facility is not active") },
+ { BSM_ERRNO_EMULTIHOP,
+#ifdef EMULTIHOP
+ EMULTIHOP,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Multihop attempted") },
+ { BSM_ERRNO_EBADMSG,
+#ifdef EBADMSG
+ EBADMSG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad message") },
+ { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, ES("File name too long") },
+ { BSM_ERRNO_EOVERFLOW, EOVERFLOW,
+ ES("Value too large to be stored in data type") },
+ { BSM_ERRNO_ENOTUNIQ,
+#ifdef ENOTUNIQ
+ ENOTUNIQ,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Given log name not unique") },
+ { BSM_ERRNO_EBADFD,
+#ifdef EBADFD
+ EBADFD,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Given f.d. invalid for this operation") },
+ { BSM_ERRNO_EREMCHG,
+#ifdef EREMCHG
+ EREMCHG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Remote address changed") },
+ { BSM_ERRNO_ELIBACC,
+#ifdef ELIBACC
+ ELIBACC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Can't access a needed shared lib") },
+ { BSM_ERRNO_ELIBBAD,
+#ifdef ELIBBAD
+ ELIBBAD,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Accessing a corrupted shared lib") },
+ { BSM_ERRNO_ELIBSCN,
+#ifdef ELIBSCN
+ ELIBSCN,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES(".lib section in a.out corrupted") },
+ { BSM_ERRNO_ELIBMAX,
+#ifdef ELIBMAX
+ ELIBMAX,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Attempting to link in too many libs") },
+ { BSM_ERRNO_ELIBEXEC,
+#ifdef ELIBEXEC
+ ELIBEXEC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Attempting to exec a shared library") },
+ { BSM_ERRNO_EILSEQ, EILSEQ, ES("Illegal byte sequence") },
+ { BSM_ERRNO_ENOSYS, ENOSYS, ES("Function not implemented") },
+ { BSM_ERRNO_ELOOP, ELOOP, ES("Too many levels of symbolic links") },
+ { BSM_ERRNO_ERESTART,
+#ifdef ERESTART
+ ERESTART,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Restart syscall") },
+ { BSM_ERRNO_ESTRPIPE,
+#ifdef ESTRPIPE
+ ESTRPIPE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("If pipe/FIFO, don't sleep in stream head") },
+ { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, ES("Directory not empty") },
+ { BSM_ERRNO_EUSERS, EUSERS, ES("Too many users") },
+ { BSM_ERRNO_ENOTSOCK, ENOTSOCK,
+ ES("Socket operation on non-socket") },
+ { BSM_ERRNO_EDESTADDRREQ, EDESTADDRREQ,
+ ES("Destination address required") },
+ { BSM_ERRNO_EMSGSIZE, EMSGSIZE, ES("Message too long") },
+ { BSM_ERRNO_EPROTOTYPE, EPROTOTYPE,
+ ES("Protocol wrong type for socket") },
+ { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, ES("Protocol not available") },
+ { BSM_ERRNO_EPROTONOSUPPORT, EPROTONOSUPPORT,
+ ES("Protocol not supported") },
+ { BSM_ERRNO_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT,
+ ES("Socket type not supported") },
+ { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, ES("Operation not supported") },
+ { BSM_ERRNO_EPFNOSUPPORT, EPFNOSUPPORT,
+ ES("Protocol family not supported") },
+ { BSM_ERRNO_EAFNOSUPPORT, EAFNOSUPPORT,
+ ES("Address family not supported by protocol family") },
+ { BSM_ERRNO_EADDRINUSE, EADDRINUSE, ES("Address already in use") },
+ { BSM_ERRNO_EADDRNOTAVAIL, EADDRNOTAVAIL,
+ ES("Can't assign requested address") },
+ { BSM_ERRNO_ENETDOWN, ENETDOWN, ES("Network is down") },
+ { BSM_ERRNO_ENETRESET, ENETRESET,
+ ES("Network dropped connection on reset") },
+ { BSM_ERRNO_ECONNABORTED, ECONNABORTED,
+ ES("Software caused connection abort") },
+ { BSM_ERRNO_ECONNRESET, ECONNRESET, ES("Connection reset by peer") },
+ { BSM_ERRNO_ENOBUFS, ENOBUFS, ES("No buffer space available") },
+ { BSM_ERRNO_EISCONN, EISCONN, ES("Socket is already connected") },
+ { BSM_ERRNO_ENOTCONN, ENOTCONN, ES("Socket is not connected") },
+ { BSM_ERRNO_ESHUTDOWN, ESHUTDOWN,
+ ES("Can't send after socket shutdown") },
+ { BSM_ERRNO_ETOOMANYREFS, ETOOMANYREFS,
+ ES("Too many references: can't splice") },
+ { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, ES("Operation timed out") },
+ { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, ES("Connection refused") },
+ { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, ES("Host is down") },
+ { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, ES("No route to host") },
+ { BSM_ERRNO_EALREADY, EALREADY, ES("Operation already in progress") },
+ { BSM_ERRNO_EINPROGRESS, EINPROGRESS,
+ ES("Operation now in progress") },
+ { BSM_ERRNO_ESTALE, ESTALE, ES("Stale NFS file handle") },
+ { BSM_ERRNO_EPWROFF,
+#ifdef EPWROFF
+ EPWROFF,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Device power is off") },
+ { BSM_ERRNO_EDEVERR,
+#ifdef EDEVERR
+ EDEVERR,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Device error") },
+ { BSM_ERRNO_EBADEXEC,
+#ifdef EBADEXEC
+ EBADEXEC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad executable") },
+ { BSM_ERRNO_EBADARCH,
+#ifdef EBADARCH
+ EBADARCH,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad CPU type in executable") },
+ { BSM_ERRNO_ESHLIBVERS,
+#ifdef ESHLIBVERS
+ ESHLIBVERS,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Shared library version mismatch") },
+ { BSM_ERRNO_EBADMACHO,
+#ifdef EBADMACHO
+ EBADMACHO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Malfored Macho file") },
+ { BSM_ERRNO_EPOLICY,
+#ifdef EPOLICY
+ EPOLICY,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Operation failed by policy") },
+ { BSM_ERRNO_EDOTDOT,
+#ifdef EDOTDOT
+ EDOTDOT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("RFS specific error") },
+ { BSM_ERRNO_EUCLEAN,
+#ifdef EUCLEAN
+ EUCLEAN,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Structure needs cleaning") },
+ { BSM_ERRNO_ENOTNAM,
+#ifdef ENOTNAM
+ ENOTNAM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Not a XENIX named type file") },
+ { BSM_ERRNO_ENAVAIL,
+#ifdef ENAVAIL
+ ENAVAIL,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No XENIX semaphores available") },
+ { BSM_ERRNO_EISNAM,
+#ifdef EISNAM
+ EISNAM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Is a named type file") },
+ { BSM_ERRNO_EREMOTEIO,
+#ifdef EREMOTEIO
+ EREMOTEIO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Remote I/O error") },
+ { BSM_ERRNO_ENOMEDIUM,
+#ifdef ENOMEDIUM
+ ENOMEDIUM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No medium found") },
+ { BSM_ERRNO_EMEDIUMTYPE,
+#ifdef EMEDIUMTYPE
+ EMEDIUMTYPE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Wrong medium type") },
+ { BSM_ERRNO_ENOKEY,
+#ifdef ENOKEY
+ ENOKEY,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Required key not available") },
+ { BSM_ERRNO_EKEYEXPIRED,
+#ifdef EKEEXPIRED
+ EKEYEXPIRED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Key has expired") },
+ { BSM_ERRNO_EKEYREVOKED,
+#ifdef EKEYREVOKED
+ EKEYREVOKED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Key has been revoked") },
+ { BSM_ERRNO_EKEYREJECTED,
+#ifdef EKEREJECTED
+ EKEYREJECTED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Key was rejected by service") },
+};
+static const int bsm_errnos_count = sizeof(bsm_errnos) / sizeof(bsm_errnos[0]);
+
+static const struct bsm_errno *
+bsm_lookup_errno_local(int local_errno)
+{
+ int i;
+
+ for (i = 0; i < bsm_errnos_count; i++) {
+ if (bsm_errnos[i].be_local_errno == local_errno)
+ return (&bsm_errnos[i]);
+ }
+ return (NULL);
+}
+
+/*
+ * Conversion to the BSM errno space isn't allowed to fail; we simply map to
+ * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it.
+ */
+u_char
+au_errno_to_bsm(int local_errno)
+{
+ const struct bsm_errno *bsme;
+
+ bsme = bsm_lookup_errno_local(local_errno);
+ if (bsme == NULL)
+ return (BSM_ERRNO_UNKNOWN);
+ return (bsme->be_bsm_errno);
+}
+
+static const struct bsm_errno *
+bsm_lookup_errno_bsm(u_char bsm_errno)
+{
+ int i;
+
+ for (i = 0; i < bsm_errnos_count; i++) {
+ if (bsm_errnos[i].be_bsm_errno == bsm_errno)
+ return (&bsm_errnos[i]);
+ }
+ return (NULL);
+}
+
+/*
+ * Converstion from a BSM error to a local error number may fail if either
+ * OpenBSM doesn't recognize the error on the wire, or because there is no
+ * appropriate local mapping.
+ */
+int
+au_bsm_to_errno(u_char bsm_errno, int *errorp)
+{
+ const struct bsm_errno *bsme;
+
+ bsme = bsm_lookup_errno_bsm(bsm_errno);
+ if (bsme == NULL || bsme->be_local_errno == ERRNO_NO_LOCAL_MAPPING)
+ return (-1);
+ *errorp = bsme->be_local_errno;
+ return (0);
+}
+
+#if !defined(KERNEL) && !defined(_KERNEL)
+const char *
+au_strerror(u_char bsm_errno)
+{
+ const struct bsm_errno *bsme;
+
+ bsme = bsm_lookup_errno_bsm(bsm_errno);
+ if (bsme == NULL)
+ return ("Unrecognized BSM error");
+ if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING)
+ return (strerror(bsme->be_local_errno));
+ return (bsme->be_strerror);
+}
+#endif
diff --git a/contrib/openbsm/libbsm/bsm_event.c b/contrib/openbsm/libbsm/bsm_event.c
index 695e617c..f3c6601 100644
--- a/contrib/openbsm/libbsm/bsm_event.c
+++ b/contrib/openbsm/libbsm/bsm_event.c
@@ -27,7 +27,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#16 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#17 $
*/
#include <config/config.h>
@@ -35,7 +35,9 @@
#include <bsm/libbsm.h>
#include <string.h>
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
#include <pthread.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -52,7 +54,9 @@ static FILE *fp = NULL;
static char linestr[AU_LINE_MAX];
static const char *eventdelim = ":";
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
/*
* Parse one line from the audit_event file into the au_event_ent structure.
@@ -114,9 +118,13 @@ void
setauevent(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setauevent_locked();
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -126,12 +134,16 @@ void
endauevent(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -171,9 +183,13 @@ getauevent_r(struct au_event_ent *e)
{
struct au_event_ent *ep;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
ep = getauevent_r_locked(e);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (ep);
}
@@ -230,9 +246,13 @@ getauevnam_r(struct au_event_ent *e, const char *name)
{
struct au_event_ent *ep;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
ep = getauevnam_r_locked(e, name);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (ep);
}
@@ -284,9 +304,13 @@ getauevnum_r(struct au_event_ent *e, au_event_t event_number)
{
struct au_event_ent *ep;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
ep = getauevnum_r_locked(e, event_number);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (ep);
}
diff --git a/contrib/openbsm/libbsm/bsm_io.c b/contrib/openbsm/libbsm/bsm_io.c
index 989fd8b..eb56827 100644
--- a/contrib/openbsm/libbsm/bsm_io.c
+++ b/contrib/openbsm/libbsm/bsm_io.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Apple Inc.
+ * Copyright (c) 2004-2008 Apple Inc.
* Copyright (c) 2005 SPARTA, Inc.
* Copyright (c) 2006 Robert N. M. Watson
* Copyright (c) 2006 Martin Voros
@@ -32,15 +32,15 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#55 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#60 $
*/
#include <sys/types.h>
#include <config/config.h>
-#ifdef HAVE_SYS_ENDIAN_H
+#if defined(HAVE_SYS_ENDIAN_H) && defined(HAVE_BE32ENC)
#include <sys/endian.h>
-#else /* !HAVE_SYS_ENDIAN_H */
+#else /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */
#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#else /* !HAVE_MACHINE_ENDIAN_H */
@@ -51,7 +51,7 @@
#endif /* !HAVE_ENDIAN_H */
#endif /* !HAVE_MACHINE_ENDIAN_H */
#include <compat/endian.h>
-#endif /* !HAVE_SYS_ENDIAN_H */
+#endif /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */
#ifdef HAVE_FULL_QUEUE_H
#include <sys/queue.h>
#else /* !HAVE_FULL_QUEUE_H */
@@ -771,13 +771,24 @@ print_ip_ex_address(FILE *fp, u_int32_t type, u_int32_t *ipaddr)
static void
print_retval(FILE *fp, u_char status, char raw)
{
+ int error;
+
if (raw)
fprintf(fp, "%u", status);
else {
- if (status == 0)
- fprintf(fp, "success");
- else
- fprintf(fp, "failure : %s", strerror(status));
+ /*
+ * Convert to a local error number and print the OS's version
+ * of the error string if possible. We may want to provide
+ * an au_strerror(3) in the future so that we can print
+ * strings for non-local errors.
+ */
+ if (au_bsm_to_errno(status, &error) == 0) {
+ if (error == 0)
+ fprintf(fp, "success");
+ else
+ fprintf(fp, "failure : %s", strerror(error));
+ } else
+ fprintf(fp, "failure: Unknown error: %d", status);
}
}
@@ -3742,54 +3753,72 @@ print_text_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
}
/*
+ * socket domain 2 bytes
* socket type 2 bytes
+ * address type 2 bytes
* local port 2 bytes
- * address type/length 4 bytes
- * local Internet address 4 bytes
- * remote port 4 bytes
- * address type/length 4 bytes
- * remote Internet address 4 bytes
+ * local Internet address 4/16 bytes
+ * remote port 2 bytes
+ * remote Internet address 4/16 bytes
*/
static int
fetch_socketex32_tok(tokenstr_t *tok, u_char *buf, int len)
{
int err = 0;
- READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len,
+ READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.domain, tok->len,
err);
if (err)
return (-1);
- READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_port,
- sizeof(uint16_t), tok->len, err);
+ READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len,
+ err);
if (err)
return (-1);
- READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.l_ad_type, tok->len,
+ READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.atype, tok->len,
err);
if (err)
return (-1);
- READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr,
- sizeof(tok->tt.socket_ex32.l_addr), tok->len, err);
- if (err)
+ if (tok->tt.socket_ex32.atype != AU_IPv4 &&
+ tok->tt.socket_ex32.atype != AU_IPv6)
return (-1);
- READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_port,
+ READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_port,
sizeof(uint16_t), tok->len, err);
if (err)
return (-1);
- READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.r_ad_type, tok->len,
- err);
- if (err)
- return (-1);
+ if (tok->tt.socket_ex32.atype == AU_IPv4) {
+ READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr,
+ sizeof(tok->tt.socket_ex32.l_addr[0]), tok->len, err);
+ if (err)
+ return (-1);
+ } else {
+ READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr,
+ sizeof(tok->tt.socket_ex32.l_addr), tok->len, err);
+ if (err)
+ return (-1);
+ }
- READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr,
- sizeof(tok->tt.socket_ex32.r_addr), tok->len, err);
+ READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_port,
+ sizeof(uint16_t), tok->len, err);
if (err)
return (-1);
+ if (tok->tt.socket_ex32.atype == AU_IPv4) {
+ READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr,
+ sizeof(tok->tt.socket_ex32.r_addr[0]), tok->len, err);
+ if (err)
+ return (-1);
+ } else {
+ READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr,
+ sizeof(tok->tt.socket_ex32.r_addr), tok->len, err);
+ if (err)
+ return (-1);
+ }
+
return (0);
}
@@ -3798,8 +3827,17 @@ print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
__unused char sfrm, int xml)
{
+ /*
+ * This print routine prints BSM constant space domains and socket
+ * types rather than converting them. If we add string printers for
+ * these constants in the future, we may want to call conversion
+ * routines.
+ */
print_tok_type(fp, tok->id, "socket", raw, xml);
if (xml) {
+ open_attr(fp, "sock_dom");
+ print_2_bytes(fp, tok->tt.socket_ex32.domain, "%#x");
+ close_attr(fp);
open_attr(fp, "sock_type");
print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x");
close_attr(fp);
@@ -3807,10 +3845,12 @@ print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x");
close_attr(fp);
open_attr(fp, "laddr");
- print_ip_address(fp, tok->tt.socket_ex32.l_addr);
+ print_ip_ex_address(fp, tok->tt.socket_ex32.atype,
+ tok->tt.socket_ex32.l_addr);
close_attr(fp);
open_attr(fp, "faddr");
- print_ip_address(fp, tok->tt.socket_ex32.r_addr);
+ print_ip_ex_address(fp, tok->tt.socket_ex32.atype,
+ tok->tt.socket_ex32.r_addr);
close_attr(fp);
open_attr(fp, "fport");
print_2_bytes(fp, ntohs(tok->tt.socket_ex32.r_port), "%#x");
@@ -3818,15 +3858,19 @@ print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
close_tag(fp, tok->id);
} else {
print_delim(fp, del);
+ print_2_bytes(fp, tok->tt.socket_ex32.domain, "%#x");
+ print_delim(fp, del);
print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x");
print_delim(fp, del);
print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x");
print_delim(fp, del);
- print_ip_address(fp, tok->tt.socket_ex32.l_addr);
+ print_ip_ex_address(fp, tok->tt.socket_ex32.atype,
+ tok->tt.socket_ex32.l_addr);
print_delim(fp, del);
print_4_bytes(fp, ntohs(tok->tt.socket_ex32.r_port), "%#x");
print_delim(fp, del);
- print_ip_address(fp, tok->tt.socket_ex32.r_addr);
+ print_ip_ex_address(fp, tok->tt.socket_ex32.atype,
+ tok->tt.socket_ex32.r_addr);
}
}
diff --git a/contrib/openbsm/libbsm/bsm_mask.c b/contrib/openbsm/libbsm/bsm_mask.c
index 07d3da3..afbed5e 100644
--- a/contrib/openbsm/libbsm/bsm_mask.c
+++ b/contrib/openbsm/libbsm/bsm_mask.c
@@ -27,7 +27,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_mask.c#14 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_mask.c#15 $
*/
#include <sys/types.h>
@@ -41,12 +41,16 @@
#include <bsm/libbsm.h>
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
#include <pthread.h>
+#endif
#include <stdlib.h>
#include <string.h>
/* MT-Safe */
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
static int firsttime = 1;
/*
@@ -162,11 +166,15 @@ au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag)
return (-1);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (firsttime) {
firsttime = 0;
if ( -1 == load_event_table()) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-1);
}
}
@@ -174,7 +182,9 @@ au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag)
case AU_PRS_REREAD:
flush_cache();
if (load_event_table() == -1) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-1);
}
ev = read_from_cache(event);
@@ -186,14 +196,18 @@ au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag)
ev = NULL;
}
if (ev == NULL) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (-1);
}
if (sorf & AU_PRS_SUCCESS)
effmask |= (mask_p->am_success & ev->ae_class);
if (sorf & AU_PRS_FAILURE)
effmask |= (mask_p->am_failure & ev->ae_class);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
if (effmask != 0)
return (1);
return (0);
diff --git a/contrib/openbsm/libbsm/bsm_socket_type.c b/contrib/openbsm/libbsm/bsm_socket_type.c
new file mode 100644
index 0000000..a10b609
--- /dev/null
+++ b/contrib/openbsm/libbsm/bsm_socket_type.c
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_socket_type.c#1 $
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <config/config.h>
+
+#include <bsm/audit_socket_type.h>
+#include <bsm/libbsm.h>
+
+struct bsm_socket_type {
+ u_short bst_bsm_socket_type;
+ int bst_local_socket_type;
+};
+
+#define ST_NO_LOCAL_MAPPING -600
+
+static const struct bsm_socket_type bsm_socket_types[] = {
+ { BSM_SOCK_DGRAM, SOCK_DGRAM },
+ { BSM_SOCK_STREAM, SOCK_STREAM },
+ { BSM_SOCK_RAW, SOCK_RAW },
+ { BSM_SOCK_RDM, SOCK_RDM },
+ { BSM_SOCK_SEQPACKET, SOCK_SEQPACKET },
+};
+static const int bsm_socket_types_count = sizeof(bsm_socket_types) /
+ sizeof(bsm_socket_types[0]);
+
+static const struct bsm_socket_type *
+bsm_lookup_local_socket_type(int local_socket_type)
+{
+ int i;
+
+ for (i = 0; i < bsm_socket_types_count; i++) {
+ if (bsm_socket_types[i].bst_local_socket_type ==
+ local_socket_type)
+ return (&bsm_socket_types[i]);
+ }
+ return (NULL);
+}
+
+u_short
+au_socket_type_to_bsm(int local_socket_type)
+{
+ const struct bsm_socket_type *bstp;
+
+ bstp = bsm_lookup_local_socket_type(local_socket_type);
+ if (bstp == NULL)
+ return (BSM_SOCK_UNKNOWN);
+ return (bstp->bst_bsm_socket_type);
+}
+
+static const struct bsm_socket_type *
+bsm_lookup_bsm_socket_type(u_short bsm_socket_type)
+{
+ int i;
+
+ for (i = 0; i < bsm_socket_types_count; i++) {
+ if (bsm_socket_types[i].bst_bsm_socket_type ==
+ bsm_socket_type)
+ return (&bsm_socket_types[i]);
+ }
+ return (NULL);
+}
+
+int
+au_bsm_to_socket_type(u_short bsm_socket_type, int *local_socket_typep)
+{
+ const struct bsm_socket_type *bstp;
+
+ bstp = bsm_lookup_bsm_socket_type(bsm_socket_type);
+ if (bstp == NULL || bstp->bst_local_socket_type)
+ return (-1);
+ *local_socket_typep = bstp->bst_local_socket_type;
+ return (0);
+}
diff --git a/contrib/openbsm/libbsm/bsm_token.c b/contrib/openbsm/libbsm/bsm_token.c
index f9692d1..430e09b 100644
--- a/contrib/openbsm/libbsm/bsm_token.c
+++ b/contrib/openbsm/libbsm/bsm_token.c
@@ -30,15 +30,15 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#72 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#86 $
*/
#include <sys/types.h>
#include <config/config.h>
-#ifdef HAVE_SYS_ENDIAN_H
+#if defined(HAVE_SYS_ENDIAN_H) && defined(HAVE_BE32ENC)
#include <sys/endian.h>
-#else /* !HAVE_SYS_ENDIAN_H */
+#else /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */
#ifdef HAVE_MACHINE_ENDIAN_H
#include <machine/endian.h>
#else /* !HAVE_MACHINE_ENDIAN_H */
@@ -49,7 +49,7 @@
#endif /* !HAVE_ENDIAN_H */
#endif /* !HAVE_MACHINE_ENDIAN_H */
#include <compat/endian.h>
-#endif /* !HAVE_SYS_ENDIAN_H */
+#endif /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */
#ifdef HAVE_FULL_QUEUE_H
#include <sys/queue.h>
#else /* !HAVE_FULL_QUEUE_H */
@@ -178,8 +178,12 @@ au_to_attr32(struct vnode_au_info *vni)
ADD_U_CHAR(dptr, AUT_ATTR32);
/*
- * Darwin defines the size for the file mode as 2 bytes; BSM defines
- * 4 so pad with 0.
+ * BSD defines the size for the file mode as 2 bytes; BSM defines 4
+ * so pad with 0.
+ *
+ * XXXRW: Possibly should be conditionally compiled.
+ *
+ * XXXRW: Should any conversions take place on the mode?
*/
ADD_U_INT16(dptr, pad0_16);
ADD_U_INT16(dptr, vni->vn_mode);
@@ -223,8 +227,12 @@ au_to_attr64(struct vnode_au_info *vni)
ADD_U_CHAR(dptr, AUT_ATTR64);
/*
- * Darwin defines the size for the file mode as 2 bytes; BSM defines
- * 4 so pad with 0.
+ * BSD defines the size for the file mode as 2 bytes; BSM defines 4
+ * so pad with 0.
+ *
+ * XXXRW: Possibly should be conditionally compiled.
+ *
+ * XXXRW: Should any conversions take place on the mode?
*/
ADD_U_INT16(dptr, pad0_16);
ADD_U_INT16(dptr, vni->vn_mode);
@@ -305,6 +313,10 @@ au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
if (t == NULL)
return (NULL);
+ /*
+ * XXXRW: We should be byte-swapping each data item for multi-byte
+ * types.
+ */
ADD_U_CHAR(dptr, AUT_DATA);
ADD_U_CHAR(dptr, unit_print);
ADD_U_CHAR(dptr, unit_type);
@@ -401,7 +413,7 @@ au_to_in_addr_ex(struct in6_addr *internet_addr)
{
token_t *t;
u_char *dptr = NULL;
- u_int32_t type = AF_INET6;
+ u_int32_t type = AU_IPv6;
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
if (t == NULL)
@@ -482,20 +494,30 @@ au_to_ipc_perm(struct ipc_perm *perm)
ADD_U_CHAR(dptr, AUT_IPC_PERM);
/*
- * Darwin defines the sizes for ipc_perm members as 2 bytes; BSM
- * defines 4 so pad with 0.
+ * Systems vary significantly in what types they use in struct
+ * ipc_perm; at least a few still use 16-bit uid's and gid's, so
+ * allow for that, as BSM define 32-bit values here.
+ * Some systems define the sizes for ipc_perm members as 2 bytes;
+ * BSM defines 4 so pad with 0.
+ *
+ * XXXRW: Possibly shoulid be conditionally compiled, and more cases
+ * need to be handled.
*/
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->uid);
-
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->gid);
-
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->cuid);
-
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->cgid);
+ if (sizeof(perm->uid) != sizeof(u_int32_t)) {
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->uid);
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->gid);
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->cuid);
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->cgid);
+ } else {
+ ADD_U_INT32(dptr, perm->uid);
+ ADD_U_INT32(dptr, perm->gid);
+ ADD_U_INT32(dptr, perm->cuid);
+ ADD_U_INT32(dptr, perm->cgid);
+ }
ADD_U_INT16(dptr, pad0);
ADD_U_INT16(dptr, perm->mode);
@@ -616,6 +638,8 @@ au_to_text(const char *text)
textlen = strlen(text);
textlen += 1;
+ /* XXXRW: Should validate length against token size limit. */
+
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
if (t == NULL)
return (NULL);
@@ -686,6 +710,13 @@ au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
ADD_U_INT32(dptr, pid);
ADD_U_INT32(dptr, sid);
ADD_U_INT32(dptr, tid->port);
+
+ /*
+ * Note: Solaris will write out IPv6 addresses here as a 32-bit
+ * address type and 16 bytes of address, but for IPv4 addresses it
+ * simply writes the 4-byte address directly. We support only IPv4
+ * addresses for process32 tokens.
+ */
ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
return (t);
@@ -712,6 +743,13 @@ au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
ADD_U_INT32(dptr, pid);
ADD_U_INT32(dptr, sid);
ADD_U_INT64(dptr, tid->port);
+
+ /*
+ * Note: Solaris will write out IPv6 addresses here as a 32-bit
+ * address type and 16 bytes of address, but for IPv4 addresses it
+ * simply writes the 4-byte address directly. We support only IPv4
+ * addresses for process64 tokens.
+ */
ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
return (t);
@@ -899,6 +937,63 @@ au_to_seq(long audit_count)
/*
* token ID 1 byte
+ * socket domain 2 bytes
+ * socket type 2 bytes
+ * address type 2 byte
+ * local port 2 bytes
+ * local address 4 bytes/16 bytes (IPv4/IPv6 address)
+ * remote port 2 bytes
+ * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
+ *
+ * Domain and type arguments to this routine are assumed to already have been
+ * converted to the BSM constant space, so we don't do that here.
+ */
+token_t *
+au_to_socket_ex(u_short so_domain, u_short so_type,
+ struct sockaddr *sa_local, struct sockaddr *sa_remote)
+{
+ token_t *t;
+ u_char *dptr = NULL;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ if (so_domain == AF_INET)
+ GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
+ 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
+ else if (so_domain == AF_INET6)
+ GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
+ 5 * sizeof(u_int16_t) + 16 * sizeof(u_int32_t));
+ else {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ ADD_U_CHAR(dptr, AUT_SOCKET_EX);
+ ADD_U_INT16(dptr, so_domain); /* XXXRW: explicitly convert? */
+ ADD_U_INT16(dptr, so_type); /* XXXRW: explicitly convert? */
+ if (so_domain == AF_INET) {
+ ADD_U_INT16(dptr, AU_IPv4);
+ sin = (struct sockaddr_in *)sa_local;
+ ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
+ sin = (struct sockaddr_in *)sa_remote;
+ ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
+ } else {
+ ADD_U_INT16(dptr, AU_IPv6);
+ sin6 = (struct sockaddr_in6 *)sa_local;
+ ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
+ sin6 = (struct sockaddr_in6 *)sa_remote;
+ ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
+ }
+
+ return (t);
+}
+
+/*
+ * token ID 1 byte
* socket family 2 bytes
* path 104 bytes
*/
@@ -971,8 +1066,9 @@ au_to_sock_inet128(struct sockaddr_in6 *so)
ADD_U_CHAR(dptr, AUT_SOCKINET128);
/*
- * In Darwin, sin6_family is one octet, but BSM defines the token
- * to store two. So we copy in a 0 first.
+ * In BSD, sin6_family is one octet, but BSM defines the token to
+ * store two. So we copy in a 0 first. XXXRW: Possibly should be
+ * conditionally compiled.
*/
ADD_U_CHAR(dptr, 0);
ADD_U_CHAR(dptr, so->sin6_family);
@@ -1207,7 +1303,6 @@ au_to_exec_args(char **argv)
nextarg = *(argv + count);
}
- totlen += count * sizeof(char); /* nul terminations. */
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
if (t == NULL)
return (NULL);
@@ -1224,27 +1319,6 @@ au_to_exec_args(char **argv)
}
/*
- * token ID 1 byte
- * zonename length 2 bytes
- * zonename N bytes + 1 terminating NULL byte
- */
-token_t *
-au_to_zonename(const char *zonename)
-{
- u_char *dptr = NULL;
- u_int16_t textlen;
- token_t *t;
-
- textlen = strlen(zonename);
- textlen += 1;
- GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
- ADD_U_CHAR(dptr, AUT_ZONENAME);
- ADD_U_INT16(dptr, textlen);
- ADD_STRING(dptr, zonename, textlen);
- return (t);
-}
-
-/*
* token ID 1 byte
* count 4 bytes
* text count null-terminated strings
@@ -1269,7 +1343,6 @@ au_to_exec_env(char **envp)
nextenv = *(envp + count);
}
- totlen += sizeof(char) * count;
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
if (t == NULL)
return (NULL);
@@ -1287,6 +1360,29 @@ au_to_exec_env(char **envp)
/*
* token ID 1 byte
+ * zonename length 2 bytes
+ * zonename N bytes + 1 terminating NULL byte
+ */
+token_t *
+au_to_zonename(const char *zonename)
+{
+ u_char *dptr = NULL;
+ u_int16_t textlen;
+ token_t *t;
+
+ textlen = strlen(zonename) + 1;
+ GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
+ if (t == NULL)
+ return (NULL);
+
+ ADD_U_CHAR(dptr, AUT_ZONENAME);
+ ADD_U_INT16(dptr, textlen);
+ ADD_STRING(dptr, zonename, textlen);
+ return (t);
+}
+
+/*
+ * token ID 1 byte
* record byte count 4 bytes
* version # 1 byte [2]
* event type 2 bytes
@@ -1338,9 +1434,10 @@ au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
{
token_t *t;
u_char *dptr = NULL;
- u_int32_t timems, hostid;
- au_tid_addr_t *tid = &aia->ai_termid;
+ u_int32_t timems;
+ au_tid_addr_t *tid;
+ tid = &aia->ai_termid;
if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6)
return (NULL);
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
@@ -1462,7 +1559,7 @@ au_to_trailer(int rec_size)
{
token_t *t;
u_char *dptr = NULL;
- u_int16_t magic = TRAILER_PAD_MAGIC;
+ u_int16_t magic = AUT_TRAILER_MAGIC;
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
sizeof(u_int32_t));
diff --git a/contrib/openbsm/libbsm/bsm_user.c b/contrib/openbsm/libbsm/bsm_user.c
index 5266fdf..005698b 100644
--- a/contrib/openbsm/libbsm/bsm_user.c
+++ b/contrib/openbsm/libbsm/bsm_user.c
@@ -27,7 +27,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_user.c#18 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_user.c#19 $
*/
#include <config/config.h>
@@ -35,7 +35,9 @@
#include <bsm/libbsm.h>
#include <string.h>
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
#include <pthread.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -51,7 +53,9 @@ static FILE *fp = NULL;
static char linestr[AU_LINE_MAX];
static const char *user_delim = ":";
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
/*
* Parse one line from the audit_user file into the au_user_ent structure.
@@ -97,9 +101,13 @@ void
setauuser(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setauuser_locked();
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -109,12 +117,16 @@ void
endauuser(void)
{
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
}
/*
@@ -154,9 +166,13 @@ getauuserent_r(struct au_user_ent *u)
{
struct au_user_ent *up;
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
up = getauuserent_r_locked(u);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (up);
}
@@ -184,17 +200,23 @@ getauusernam_r(struct au_user_ent *u, const char *name)
if (name == NULL)
return (NULL);
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_lock(&mutex);
+#endif
setauuser_locked();
while ((up = getauuserent_r_locked(u)) != NULL) {
if (strcmp(name, u->au_name) == 0) {
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (u);
}
}
+#ifdef HAVE_PTHREAD_MUTEX_LOCK
pthread_mutex_unlock(&mutex);
+#endif
return (NULL);
}
diff --git a/contrib/openbsm/libbsm/bsm_wrappers.c b/contrib/openbsm/libbsm/bsm_wrappers.c
index f818f1d..5bcf57c 100644
--- a/contrib/openbsm/libbsm/bsm_wrappers.c
+++ b/contrib/openbsm/libbsm/bsm_wrappers.c
@@ -26,7 +26,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#26 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#28 $
*/
#ifdef __APPLE__
@@ -69,6 +69,7 @@ audit_submit(short au_event, au_id_t auid, char status,
int error, afd, subj_ex;
struct auditinfo ai;
struct auditinfo_addr aia;
+ au_tid_t atid;
if (auditon(A_GETCOND, &acond, sizeof(acond)) < 0) {
/*
@@ -85,7 +86,6 @@ audit_submit(short au_event, au_id_t auid, char status,
}
if (acond == AUC_NOAUDIT)
return (0);
- /* XXXCSJP we should be doing a pre-select here */
afd = au_open();
if (afd < 0) {
error = errno;
@@ -95,30 +95,51 @@ audit_submit(short au_event, au_id_t auid, char status,
return (-1);
}
/*
- * Some operating systems do not have getaudit_addr(2) implemented
- * yet. So we try to use getaudit(2) first, if the subject is
- * using IPv6, then we will have to try getaudit_addr(2). Failing
- * this, we return error.
+ * Try to use getaudit_addr(2) first. If this kernel does not support
+ * it, then fall back on to getaudit(2).
*/
subj_ex = 0;
- error = getaudit(&ai);
- if (error < 0 && errno == E2BIG) {
- error = getaudit_addr(&aia, sizeof(aia));
- if (error == 0)
- subj_ex = 1;
- }
- if (error < 0) {
+ error = getaudit_addr(&aia, sizeof(aia));
+ if (error < 0 && errno == ENOSYS) {
+ error = getaudit(&ai);
+ if (error < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s",
+ strerror(errno));
+ errno = error;
+ return (-1);
+ }
+ /*
+ * Convert this auditinfo_t to an auditinfo_addr_t to make the
+ * following code less complicated wrt to preselection and
+ * subject token generation.
+ */
+ aia.ai_auid = ai.ai_auid;
+ aia.ai_mask = ai.ai_mask;
+ aia.ai_asid = ai.ai_asid;
+ aia.ai_termid.at_type = AU_IPv4;
+ aia.ai_termid.at_addr[0] = ai.ai_termid.machine;
+ aia.ai_termid.at_port = ai.ai_termid.port;
+ } else if (error < 0) {
error = errno;
- syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s",
+ syslog(LOG_AUTH | LOG_ERR, "audit: getaudit_addr failed: %s",
strerror(errno));
errno = error;
return (-1);
}
+ /*
+ * NB: We should be performing pre-selection here now that we have the
+ * masks for this process.
+ */
+ if (aia.ai_termid.at_type == AU_IPv6)
+ subj_ex = 1;
pid = getpid();
- if (subj_ex == 0)
+ if (subj_ex == 0) {
+ atid.port = aia.ai_termid.at_port;
+ atid.machine = aia.ai_termid.at_addr[0];
token = au_to_subject32(auid, geteuid(), getegid(),
- getuid(), getgid(), pid, pid, &ai.ai_termid);
- else
+ getuid(), getgid(), pid, pid, &atid);
+ } else
token = au_to_subject_ex(auid, geteuid(), getegid(),
getuid(), getgid(), pid, pid, &aia.ai_termid);
if (token == NULL) {
@@ -157,7 +178,7 @@ audit_submit(short au_event, au_id_t auid, char status,
return (-1);
}
}
- token = au_to_return32(status, reterr);
+ token = au_to_return32(status, au_errno_to_bsm(reterr));
if (token == NULL) {
syslog(LOG_AUTH | LOG_ERR,
"audit: enable to build return token");
diff --git a/contrib/openbsm/libbsm/libbsm.3 b/contrib/openbsm/libbsm/libbsm.3
index e84ea94..f059e28 100644
--- a/contrib/openbsm/libbsm/libbsm.3
+++ b/contrib/openbsm/libbsm/libbsm.3
@@ -1,5 +1,6 @@
.\"-
.\" Copyright (c) 2005-2007 Robert N. M. Watson
+.\" Copyright (c) 2008 Apple Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -23,9 +24,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/libbsm.3#13 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/libbsm.3#16 $
.\"
-.Dd April 19, 2005
+.Dd November 12, 2008
.Dt LIBBSM 3
.Os
.Sh NAME
@@ -170,6 +171,7 @@ representation:
.Xr au_to_sock_inet 3 ,
.Xr au_to_sock_inet32 3 ,
.Xr au_to_sock_inet128 3 ,
+.Xr au_to_socket_ex 3 ,
.Xr au_to_subject 3 ,
.Xr au_to_subject32 3 ,
.Xr au_to_subject64 3 ,
@@ -191,14 +193,28 @@ database:
.Xr getauusernam 3 ,
.Xr getauusernam_r 3 ,
.Xr getfauditflags 3 .
+.Ss Audit Constant Conversion Interfaces
+These functions convert between BSM and local constants, including the
+.Xr errno 2
+number, socket type, and protocol famil spaces, and must be used to generate
+and interpret BSM return and extended socket tokens:
+.Xr au_bsm_to_domain 3 ,
+.Xr au_bsm_to_errno 3 ,
+.Xr au_bsm_to_socket_type 3 ,
+.Xr au_domain_to_bsm 3 ,
+.Xr au_errno_to_bsm 3 ,
+.Xr au_socket_type_to_bsm 3 .
.Sh SEE ALSO
.Xr au_class 3 ,
-.Xr audit_submit 3 ,
+.Xr au_domain 3 ,
+.Xr au_errno 3 ,
.Xr au_mask 3 ,
.Xr au_notify 3 ,
+.Xr au_socket_type 3 ,
.Xr au_stream 3 ,
.Xr au_token 3 ,
.Xr au_user 3 ,
+.Xr audit_submit 3 ,
.Xr audit_class 5 ,
.Xr audit_control 5
.Sh HISTORY
diff --git a/contrib/openbsm/man/Makefile.in b/contrib/openbsm/man/Makefile.in
index a24804a..2f229f5 100644
--- a/contrib/openbsm/man/Makefile.in
+++ b/contrib/openbsm/man/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/man/Makefile.in#7 $
+# $P4: //depot/projects/trustedbsd/openbsm/man/Makefile.in#8 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
diff --git a/contrib/openbsm/man/audit.log.5 b/contrib/openbsm/man/audit.log.5
index dac0067..143936c 100644
--- a/contrib/openbsm/man/audit.log.5
+++ b/contrib/openbsm/man/audit.log.5
@@ -1,5 +1,6 @@
.\"-
.\" Copyright (c) 2005-2006 Robert N. M. Watson
+.\" Copyright (c) 2008 Apple Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -23,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/man/audit.log.5#19 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/man/audit.log.5#23 $
.\"
.Dd November 5, 2006
.Dt AUDIT.LOG 5
@@ -139,7 +140,7 @@ token can be created using
The
.Dq trailer
terminates a BSM audit record, and contains a magic number,
-.Dv TRAILER_PAD_MAGIC
+.Dv AUT_TRAILER_MAGIC
and length that can be used to validate that the record was read properly.
A
.Dq trailer
@@ -515,7 +516,7 @@ An exec_args token may be created using
.It Sy "Field Bytes Description"
.It "Token ID 1 byte Token ID"
.It Li "Count" Ta "4 bytes" Ta "Number of arguments"
-.It Li "Text" Ta "* bytes" Ta "Count null-terminated strings"
+.It Li "Text" Ta "* bytes" Ta "Count nul-terminated strings"
.El
.Ss exec_env Token
The
@@ -560,25 +561,24 @@ or
.It Li "Local port" Ta "2 bytes" Ta "Local port"
.It Li "Socket address" Ta "4 bytes" Ta "Socket address"
.El
-.Bl -column -offset 3n ".No Terminal Address Type/Length" ".No N bytes + 1 NUL"
-.It Sy "Field Bytes Description"
-.It "Token ID 1 byte Token ID"
-.It Li "Socket domain" Ta "4 bytes" Ta "Socket domain"
-.It Li "Socket family" Ta "2 bytes" Ta "Socket family"
-.It Li "Address type" Ta "1 byte" Ta "Address type (IPv4/IPv6)"
-.It Li "Local port" Ta "2 bytes" Ta "Local port"
-.It Li "Local IP address" Ta "4/16 bytes" Ta "Local IP address"
-.It Li "Remote port" Ta "2 bytes" Ta "Remote port"
-.It Li "Remote IP address" Ta "4/16 bytes" Ta "Remote IP address"
-.El
.Ss Expanded Socket Token
The
.Dq expanded socket
token contains information about IPv4 and IPv6 sockets.
+A
+.Dq expanded socket
+token can be created using
+.Xr au_to_socket_ex 3 .
.Bl -column -offset 3n ".No Terminal Address Type/Length" ".No N bytes + 1 NUL"
.It Sy "Field Bytes Description"
-.It "Token ID 1 byte Token ID"
-.It XXXXX
+.It Li "Token ID" Ta "1 byte" Ta "Token ID"
+.It Li "Socket domain" Ta "2 bytes" Ta "Socket domain"
+.It Li "Socket type" Ta "2 bytes" Ta "Socket type"
+.It Li "Address type" Ta "2 byte" Ta "Address type (IPv4/IPv6)"
+.It Li "Local port" Ta "2 bytes" Ta "Local port"
+.It Li "Local IP address" Ta "4/16 bytes" Ta "Local IP address"
+.It Li "Remote port" Ta "2 bytes" Ta "Remote port"
+.It Li "Remote IP address" Ta "4/16 bytes" Ta "Remote IP address"
.El
.Ss Seq Token
The
diff --git a/contrib/openbsm/man/audit_user.5 b/contrib/openbsm/man/audit_user.5
index 947f5c8..5075f4a 100644
--- a/contrib/openbsm/man/audit_user.5
+++ b/contrib/openbsm/man/audit_user.5
@@ -25,9 +25,9 @@
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $P4: //depot/projects/trustedbsd/openbsm/man/audit_user.5#13 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/man/audit_user.5#14 $
.\"
-.Dd February 5, 2006
+.Dd January 4, 2008
.Dt AUDIT_USER 5
.Os
.Sh NAME
@@ -67,7 +67,7 @@ jdoe:-fc,ad:+fw
.Ed
.Pp
These settings would cause login/logout and administrative events that
-succeed on behalf of user
+are performed on behalf of user
.Dq Li root
to be audited.
No failure events are audited.
diff --git a/contrib/openbsm/modules/Makefile.in b/contrib/openbsm/modules/Makefile.in
index 39b942a..135dcae 100644
--- a/contrib/openbsm/modules/Makefile.in
+++ b/contrib/openbsm/modules/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/modules/Makefile.in#5 $
+# $P4: //depot/projects/trustedbsd/openbsm/modules/Makefile.in#6 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
diff --git a/contrib/openbsm/modules/auditfilter_noop/Makefile.in b/contrib/openbsm/modules/auditfilter_noop/Makefile.in
index 6d39c48..8c764e4 100644
--- a/contrib/openbsm/modules/auditfilter_noop/Makefile.in
+++ b/contrib/openbsm/modules/auditfilter_noop/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/modules/auditfilter_noop/Makefile.in#6 $
+# $P4: //depot/projects/trustedbsd/openbsm/modules/auditfilter_noop/Makefile.in#7 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/sys/Makefile.in b/contrib/openbsm/sys/Makefile.in
index 7c090bd..b61e9fc 100644
--- a/contrib/openbsm/sys/Makefile.in
+++ b/contrib/openbsm/sys/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/sys/Makefile.in#2 $
+# $P4: //depot/projects/trustedbsd/openbsm/sys/Makefile.in#3 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
diff --git a/contrib/openbsm/sys/bsm/Makefile.am b/contrib/openbsm/sys/bsm/Makefile.am
index b3c7805..12ad8e9 100644
--- a/contrib/openbsm/sys/bsm/Makefile.am
+++ b/contrib/openbsm/sys/bsm/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.am#1 $
+# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.am#3 $
#
@@ -8,7 +8,10 @@ openbsmdir = $(includedir)/bsm
openbsm_HEADERS = \
audit.h \
+ audit_domain.h \
+ audit_errno.h \
audit_internal.h \
audit_kevents.h \
- audit_record.h
+ audit_record.h \
+ audit_socket_type.h
endif
diff --git a/contrib/openbsm/sys/bsm/Makefile.in b/contrib/openbsm/sys/bsm/Makefile.in
index 34cb9e6..0b602df 100644
--- a/contrib/openbsm/sys/bsm/Makefile.in
+++ b/contrib/openbsm/sys/bsm/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.in#2 $
+# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.in#5 $
#
VPATH = @srcdir@
@@ -48,8 +48,9 @@ CONFIG_HEADER = $(top_builddir)/config/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
-am__openbsm_HEADERS_DIST = audit.h audit_internal.h audit_kevents.h \
- audit_record.h
+am__openbsm_HEADERS_DIST = audit.h audit_domain.h audit_errno.h \
+ audit_internal.h audit_kevents.h audit_record.h \
+ audit_socket_type.h
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -173,9 +174,12 @@ top_srcdir = @top_srcdir@
@USE_NATIVE_INCLUDES_FALSE@openbsmdir = $(includedir)/bsm
@USE_NATIVE_INCLUDES_FALSE@openbsm_HEADERS = \
@USE_NATIVE_INCLUDES_FALSE@ audit.h \
+@USE_NATIVE_INCLUDES_FALSE@ audit_domain.h \
+@USE_NATIVE_INCLUDES_FALSE@ audit_errno.h \
@USE_NATIVE_INCLUDES_FALSE@ audit_internal.h \
@USE_NATIVE_INCLUDES_FALSE@ audit_kevents.h \
-@USE_NATIVE_INCLUDES_FALSE@ audit_record.h
+@USE_NATIVE_INCLUDES_FALSE@ audit_record.h \
+@USE_NATIVE_INCLUDES_FALSE@ audit_socket_type.h
all: all-am
diff --git a/contrib/openbsm/sys/bsm/audit.h b/contrib/openbsm/sys/bsm/audit.h
index ebb84da..3b22b03 100644
--- a/contrib/openbsm/sys/bsm/audit.h
+++ b/contrib/openbsm/sys/bsm/audit.h
@@ -26,12 +26,21 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#1 $
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#4 $
*/
#ifndef _BSM_AUDIT_H
#define _BSM_AUDIT_H
+#ifdef __APPLE__
+/* Temporary until rdar://problem/6133383 is resolved. */
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/cdefs.h>
+#include <sys/queue.h>
+#endif /* __APPLE__ */
+
#define AUDIT_RECORD_MAGIC 0x828a0f1b
#define MAX_AUDIT_RECORDS 20
#define MAXAUDITDATA (0x8000 - 1)
@@ -39,6 +48,14 @@
#define MIN_AUDIT_FILE_SIZE (512 * 1024)
/*
+ * Minimum noumber of free blocks on the filesystem containing the audit
+ * log necessary to avoid a hard log rotation. DO NOT SET THIS VALUE TO 0
+ * as the kernel does an unsigned compare, plus we want to leave a few blocks
+ * free so userspace can terminate the log, etc.
+ */
+#define AUDIT_HARD_LIMIT_FREE_BLOCKS 4
+
+/*
* Triggers for the audit daemon.
*/
#define AUDIT_TRIGGER_MIN 1
@@ -47,8 +64,9 @@
#define AUDIT_TRIGGER_READ_FILE 3 /* Re-read config file. */
#define AUDIT_TRIGGER_CLOSE_AND_DIE 4 /* Terminate audit. */
#define AUDIT_TRIGGER_NO_SPACE 5 /* Below min free space. */
-#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests roate. */
-#define AUDIT_TRIGGER_MAX 6
+#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests rotate. */
+#define AUDIT_TRIGGER_INITIALIZE 7 /* Initialize audit. */
+#define AUDIT_TRIGGER_MAX 7
/*
* The special device filename (FreeBSD).
@@ -59,7 +77,9 @@
/*
* Pre-defined audit IDs
*/
-#define AU_DEFAUDITID -1
+#define AU_DEFAUDITID (uid_t)(-1)
+#define AU_DEFAUDITSID 0
+#define AU_ASSIGN_ASID -1
/*
* IPC types.
@@ -103,6 +123,7 @@
#define A_GETKAUDIT 29
#define A_SETKAUDIT 30
#define A_SENDTRIGGER 31
+#define A_GETSINFO_ADDR 32
/*
* Audit policy controls.
@@ -183,6 +204,7 @@ struct auditinfo_addr {
au_mask_t ai_mask; /* Audit masks. */
au_tid_addr_t ai_termid; /* Terminal ID. */
au_asid_t ai_asid; /* Audit session ID. */
+ u_int64_t ai_flags; /* Audit session flags. */
};
typedef struct auditinfo_addr auditinfo_addr_t;
@@ -192,6 +214,7 @@ struct auditpinfo {
au_mask_t ap_mask; /* Audit masks. */
au_tid_t ap_termid; /* Terminal ID. */
au_asid_t ap_asid; /* Audit session ID. */
+ u_int64_t ap_flags; /* Audit session flags. */
};
typedef struct auditpinfo auditpinfo_t;
@@ -204,6 +227,16 @@ struct auditpinfo_addr {
};
typedef struct auditpinfo_addr auditpinfo_addr_t;
+struct au_session {
+ auditinfo_addr_t *as_aia_p; /* Ptr to full audit info. */
+#define as_asid as_aia_p->ai_asid
+#define as_auid as_aia_p->ai_auid
+#define as_termid as_aia_p->ai_termid
+
+ au_mask_t as_mask; /* Process Audit Masks. */
+};
+typedef struct au_session au_session_t;
+
/*
* Contents of token_t are opaque outside of libbsm.
*/
@@ -246,8 +279,8 @@ typedef struct audit_stat au_stat_t;
* Structure for the audit file statistics.
*/
struct audit_fstat {
- u_quad_t af_filesz;
- u_quad_t af_currsz;
+ u_int64_t af_filesz;
+ u_int64_t af_currsz;
};
typedef struct audit_fstat au_fstat_t;
diff --git a/contrib/openbsm/sys/bsm/audit_domain.h b/contrib/openbsm/sys/bsm/audit_domain.h
new file mode 100644
index 0000000..9edcb4f
--- /dev/null
+++ b/contrib/openbsm/sys/bsm/audit_domain.h
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_domain.h#1 $
+ */
+
+#ifndef _BSM_AUDIT_DOMAIN_H_
+#define _BSM_AUDIT_DOMAIN_H_
+
+/*
+ * BSM protocol domain constants - protocol domains defined in Solaris.
+ */
+#define BSM_PF_UNSPEC 0
+#define BSM_PF_LOCAL 1
+#define BSM_PF_INET 2
+#define BSM_PF_IMPLINK 3
+#define BSM_PF_PUP 4
+#define BSM_PF_CHAOS 5
+#define BSM_PF_NS 6
+#define BSM_PF_NBS 7 /* Solaris-specific. */
+#define BSM_PF_ECMA 8
+#define BSM_PF_DATAKIT 9
+#define BSM_PF_CCITT 10
+#define BSM_PF_SNA 11
+#define BSM_PF_DECnet 12
+#define BSM_PF_DLI 13
+#define BSM_PF_LAT 14
+#define BSM_PF_HYLINK 15
+#define BSM_PF_APPLETALK 16
+#define BSM_PF_NIT 17 /* Solaris-specific. */
+#define BSM_PF_802 18 /* Solaris-specific. */
+#define BSM_PF_OSI 19
+#define BSM_PF_X25 20 /* Solaris/Linux-specific. */
+#define BSM_PF_OSINET 21 /* Solaris-specific. */
+#define BSM_PF_GOSIP 22 /* Solaris-specific. */
+#define BSM_PF_IPX 23
+#define BSM_PF_ROUTE 24
+#define BSM_PF_LINK 25
+#define BSM_PF_INET6 26
+#define BSM_PF_KEY 27
+#define BSM_PF_NCA 28 /* Solaris-specific. */
+#define BSM_PF_POLICY 29 /* Solaris-specific. */
+#define BSM_PF_INET_OFFLOAD 30 /* Solaris-specific. */
+
+/*
+ * BSM protocol domain constants - protocol domains not defined in Solaris.
+ */
+#define BSM_PF_NETBIOS 500 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_ISO 501 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_XTP 502 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_COIP 503 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_CNT 504 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_RTIP 505 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_SIP 506 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_PIP 507 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_ISDN 508 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_E164 509 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_NATM 510 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_ATM 511 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_NETGRAPH 512 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_SLOW 513 /* FreeBSD-specific. */
+#define BSM_PF_SCLUSTER 514 /* FreeBSD-specific. */
+#define BSM_PF_ARP 515 /* FreeBSD-specific. */
+#define BSM_PF_BLUETOOTH 516 /* FreeBSD-specific. */
+#define BSM_PF_IEEE80211 517 /* FreeBSD-specific. */
+#define BSM_PF_AX25 518 /* Linux-specific. */
+#define BSM_PF_ROSE 519 /* Linux-specific. */
+#define BSM_PF_NETBEUI 520 /* Linux-specific. */
+#define BSM_PF_SECURITY 521 /* Linux-specific. */
+#define BSM_PF_PACKET 522 /* Linux-specific. */
+#define BSM_PF_ASH 523 /* Linux-specific. */
+#define BSM_PF_ECONET 524 /* Linux-specific. */
+#define BSM_PF_ATMSVC 525 /* Linux-specific. */
+#define BSM_PF_IRDA 526 /* Linux-specific. */
+#define BSM_PF_PPPOX 527 /* Linux-specific. */
+#define BSM_PF_WANPIPE 528 /* Linux-specific. */
+#define BSM_PF_LLC 529 /* Linux-specific. */
+#define BSM_PF_CAN 530 /* Linux-specific. */
+#define BSM_PF_TIPC 531 /* Linux-specific. */
+#define BSM_PF_IUCV 532 /* Linux-specific. */
+#define BSM_PF_RXRPC 533 /* Linux-specific. */
+#define BSM_PF_PHONET 534 /* Linux-specific. */
+
+/*
+ * Used when there is no mapping from a local to BSM protocol domain.
+ */
+#define BSM_PF_UNKNOWN 700 /* OpenBSM-specific. */
+
+#endif /* !_BSM_AUDIT_DOMAIN_H_ */
diff --git a/contrib/openbsm/sys/bsm/audit_errno.h b/contrib/openbsm/sys/bsm/audit_errno.h
new file mode 100644
index 0000000..f7dec8d
--- /dev/null
+++ b/contrib/openbsm/sys/bsm/audit_errno.h
@@ -0,0 +1,214 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_errno.h#5 $
+ */
+
+#ifndef _BSM_AUDIT_ERRNO_H_
+#define _BSM_AUDIT_ERRNO_H_
+
+/*
+ * For the purposes of portable encoding, we convert between local error
+ * numbers and Solaris error numbers (as well as some extensions for error
+ * numbers that don't exist in Solaris). Although the first 35 or so
+ * constants are the same across all OS's, we don't handle that in any
+ * special way.
+ *
+ * When adding constants here, also add them to bsm_errno.c.
+ */
+#define BSM_ERRNO_ESUCCESS 0
+#define BSM_ERRNO_EPERM 1
+#define BSM_ERRNO_ENOENT 2
+#define BSM_ERRNO_ESRCH 3
+#define BSM_ERRNO_EINTR 4
+#define BSM_ERRNO_EIO 5
+#define BSM_ERRNO_ENXIO 6
+#define BSM_ERRNO_E2BIG 7
+#define BSM_ERRNO_ENOEXEC 8
+#define BSM_ERRNO_EBADF 9
+#define BSM_ERRNO_ECHILD 10
+#define BSM_ERRNO_EAGAIN 11
+#define BSM_ERRNO_ENOMEM 12
+#define BSM_ERRNO_EACCES 13
+#define BSM_ERRNO_EFAULT 14
+#define BSM_ERRNO_ENOTBLK 15
+#define BSM_ERRNO_EBUSY 16
+#define BSM_ERRNO_EEXIST 17
+#define BSM_ERRNO_EXDEV 18
+#define BSM_ERRNO_ENODEV 19
+#define BSM_ERRNO_ENOTDIR 20
+#define BSM_ERRNO_EISDIR 21
+#define BSM_ERRNO_EINVAL 22
+#define BSM_ERRNO_ENFILE 23
+#define BSM_ERRNO_EMFILE 24
+#define BSM_ERRNO_ENOTTY 25
+#define BSM_ERRNO_ETXTBSY 26
+#define BSM_ERRNO_EFBIG 27
+#define BSM_ERRNO_ENOSPC 28
+#define BSM_ERRNO_ESPIPE 29
+#define BSM_ERRNO_EROFS 30
+#define BSM_ERRNO_EMLINK 31
+#define BSM_ERRNO_EPIPE 32
+#define BSM_ERRNO_EDOM 33
+#define BSM_ERRNO_ERANGE 34
+#define BSM_ERRNO_ENOMSG 35
+#define BSM_ERRNO_EIDRM 36
+#define BSM_ERRNO_ECHRNG 37 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL2NSYNC 38 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL3HLT 39 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL3RST 40 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELNRNG 41 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EUNATCH 42 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOCSI 43 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL2HLT 44 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EDEADLK 45
+#define BSM_ERRNO_ENOLCK 46
+#define BSM_ERRNO_ECANCELED 47
+#define BSM_ERRNO_ENOTSUP 48
+#define BSM_ERRNO_EDQUOT 49
+#define BSM_ERRNO_EBADE 50 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADR 51 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EXFULL 52 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOANO 53 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADRQC 54 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADSLT 55 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EDEADLOCK 56 /* Solaris-specific. */
+#define BSM_ERRNO_EBFONT 57 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EOWNERDEAD 58 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOTRECOVERABLE 59 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOSTR 60 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ENODATA 61 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ETIME 62 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ENOSR 63 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ENONET 64 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOPKG 65 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EREMOTE 66
+#define BSM_ERRNO_ENOLINK 67
+#define BSM_ERRNO_EADV 68 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ESRMNT 69 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ECOMM 70 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EPROTO 71
+#define BSM_ERRNO_ELOCKUNMAPPED 72 /* Solaris-specific. */
+#define BSM_ERRNO_ENOTACTIVE 73 /* Solaris-specific. */
+#define BSM_ERRNO_EMULTIHOP 74
+#define BSM_ERRNO_EBADMSG 77
+#define BSM_ERRNO_ENAMETOOLONG 78
+#define BSM_ERRNO_EOVERFLOW 79
+#define BSM_ERRNO_ENOTUNIQ 80 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADFD 81 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EREMCHG 82 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBACC 83 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBBAD 84 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBSCN 85 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBMAX 86 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBEXEC 87 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EILSEQ 88
+#define BSM_ERRNO_ENOSYS 89
+#define BSM_ERRNO_ELOOP 90
+#define BSM_ERRNO_ERESTART 91
+#define BSM_ERRNO_ESTRPIPE 92 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOTEMPTY 93
+#define BSM_ERRNO_EUSERS 94
+#define BSM_ERRNO_ENOTSOCK 95
+#define BSM_ERRNO_EDESTADDRREQ 96
+#define BSM_ERRNO_EMSGSIZE 97
+#define BSM_ERRNO_EPROTOTYPE 98
+#define BSM_ERRNO_ENOPROTOOPT 99
+#define BSM_ERRNO_EPROTONOSUPPORT 120
+#define BSM_ERRNO_ESOCKTNOSUPPORT 121
+#define BSM_ERRNO_EOPNOTSUPP 122
+#define BSM_ERRNO_EPFNOSUPPORT 123
+#define BSM_ERRNO_EAFNOSUPPORT 124
+#define BSM_ERRNO_EADDRINUSE 125
+#define BSM_ERRNO_EADDRNOTAVAIL 126
+#define BSM_ERRNO_ENETDOWN 127
+#define BSM_ERRNO_ENETUNREACH 128
+#define BSM_ERRNO_ENETRESET 129
+#define BSM_ERRNO_ECONNABORTED 130
+#define BSM_ERRNO_ECONNRESET 131
+#define BSM_ERRNO_ENOBUFS 132
+#define BSM_ERRNO_EISCONN 133
+#define BSM_ERRNO_ENOTCONN 134
+#define BSM_ERRNO_ESHUTDOWN 143
+#define BSM_ERRNO_ETOOMANYREFS 144
+#define BSM_ERRNO_ETIMEDOUT 145
+#define BSM_ERRNO_ECONNREFUSED 146
+#define BSM_ERRNO_EHOSTDOWN 147
+#define BSM_ERRNO_EHOSTUNREACH 148
+#define BSM_ERRNO_EALREADY 149
+#define BSM_ERRNO_EINPROGRESS 150
+#define BSM_ERRNO_ESTALE 151
+
+/*
+ * OpenBSM constants for error numbers not defined in Solaris. In the event
+ * that these errors are added to Solaris, we will deprecate the OpenBSM
+ * numbers in the same way we do for audit event constants.
+ *
+ * ELAST doesn't get a constant in the BSM space.
+ */
+#define BSM_ERRNO_EPROCLIM 190 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EBADRPC 191 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_ERPCMISMATCH 192 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EPROGUNAVAIL 193 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EPROGMISMATCH 194 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EPROCUNAVAIL 195 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EFTYPE 196 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EAUTH 197 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_ENEEDAUTH 198 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_ENOATTR 199 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EDOOFUS 200 /* FreeBSD-specific. */
+#define BSM_ERRNO_EJUSTRETURN 201 /* FreeBSD-specific. */
+#define BSM_ERRNO_ENOIOCTL 202 /* FreeBSD-specific. */
+#define BSM_ERRNO_EDIRIOCTL 203 /* FreeBSD-specific. */
+#define BSM_ERRNO_EPWROFF 204 /* Darwin-specific. */
+#define BSM_ERRNO_EDEVERR 205 /* Darwin-specific. */
+#define BSM_ERRNO_EBADEXEC 206 /* Darwin-specific. */
+#define BSM_ERRNO_EBADARCH 207 /* Darwin-specific. */
+#define BSM_ERRNO_ESHLIBVERS 208 /* Darwin-specific. */
+#define BSM_ERRNO_EBADMACHO 209 /* Darwin-specific. */
+#define BSM_ERRNO_EPOLICY 210 /* Darwin-specific. */
+#define BSM_ERRNO_EDOTDOT 211 /* Linux-specific. */
+#define BSM_ERRNO_EUCLEAN 212 /* Linux-specific. */
+#define BSM_ERRNO_ENOTNAM 213 /* Linux(Xenix?)-specific. */
+#define BSM_ERRNO_ENAVAIL 214 /* Linux(Xenix?)-specific. */
+#define BSM_ERRNO_EISNAM 215 /* Linux(Xenix?)-specific. */
+#define BSM_ERRNO_EREMOTEIO 216 /* Linux-specific. */
+#define BSM_ERRNO_ENOMEDIUM 217 /* Linux-specific. */
+#define BSM_ERRNO_EMEDIUMTYPE 218 /* Linux-specific. */
+#define BSM_ERRNO_ENOKEY 219 /* Linux-specific. */
+#define BSM_ERRNO_EKEYEXPIRED 220 /* Linux-specific. */
+#define BSM_ERRNO_EKEYREVOKED 221 /* Linux-specific. */
+#define BSM_ERRNO_EKEYREJECTED 222 /* Linux-specific. */
+
+/*
+ * In the event that OpenBSM doesn't have a file representation of a local
+ * error number, use this.
+ */
+#define BSM_ERRNO_UNKNOWN 250 /* OpenBSM-specific. */
+
+#endif /* !_BSM_AUDIT_ERRNO_H_ */
diff --git a/contrib/openbsm/sys/bsm/audit_internal.h b/contrib/openbsm/sys/bsm/audit_internal.h
index d3482b3..71a5130 100644
--- a/contrib/openbsm/sys/bsm/audit_internal.h
+++ b/contrib/openbsm/sys/bsm/audit_internal.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Apple Inc.
+ * Copyright (c) 2005-2008 Apple Inc.
* Copyright (c) 2005 SPARTA, Inc.
* All rights reserved.
*
@@ -30,7 +30,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.
*
- * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_internal.h#2 $
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_internal.h#5 $
*/
#ifndef _AUDIT_INTERNAL_H
diff --git a/contrib/openbsm/sys/bsm/audit_kevents.h b/contrib/openbsm/sys/bsm/audit_kevents.h
index 34cf545..57351b5 100644
--- a/contrib/openbsm/sys/bsm/audit_kevents.h
+++ b/contrib/openbsm/sys/bsm/audit_kevents.h
@@ -26,7 +26,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.
*
- * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_kevents.h#3 $
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_kevents.h#4 $
*/
#ifndef _BSM_AUDIT_KEVENTS_H_
@@ -58,7 +58,6 @@
#define AUE_UMOUNT 12
#define AUE_JUNK 13 /* Solaris-specific. */
#define AUE_ACCESS 14
-#define AUE_CHECKUSERACCESS AUE_ACCESS /* Darwin-specific. */
#define AUE_KILL 15
#define AUE_STAT 16
#define AUE_LSTAT 17
@@ -560,7 +559,7 @@
#define AUE_ACCESS_EXTENDED 43162 /* Darwin. */
#define AUE_CHMOD_EXTENDED 43163 /* Darwin. */
#define AUE_FCHMOD_EXTENDED 43164 /* Darwin. */
-#define AUE_FSTAT_EXTENDED 43165 /* Dariwn. */
+#define AUE_FSTAT_EXTENDED 43165 /* Darwin. */
#define AUE_LSTAT_EXTENDED 43166 /* Darwin. */
#define AUE_MKDIR_EXTENDED 43167 /* Darwin. */
#define AUE_MKFIFO_EXTENDED 43168 /* Darwin. */
@@ -585,6 +584,8 @@
#define AUE_CAP_GETRIGHTS 43187 /* TrustedBSD. */
#define AUE_CAP_ENTER 43188 /* TrustedBSD. */
#define AUE_CAP_GETMODE 43189 /* TrustedBSD. */
+#define AUE_POSIX_SPAWN 43190 /* Darwin. */
+#define AUE_FSGETPATH 43191 /* Darwin. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
@@ -656,13 +657,42 @@
/*
* Possible desired future values based on review of BSD/Darwin system calls.
*/
+#define AUE_ACCESSEXTENDED AUE_NULL
+#define AUE_ATGETMSG AUE_NULL
+#define AUE_ATPUTMSG AUE_NULL
+#define AUE_ATSOCKET AUE_NULL
+#define AUE_ATPGETREQ AUE_NULL
+#define AUE_ATPGETRSP AUE_NULL
+#define AUE_ATPSNDREQ AUE_NULL
+#define AUE_ATPSNDRSP AUE_NULL
+#define AUE_BSDTHREADCREATE AUE_NULL
+#define AUE_BSDTHREADTERMINATE AUE_NULL
+#define AUE_BSDTHREADREGISTER AUE_NULL
+#define AUE_CHMODEXTENDED AUE_NULL
+#define AUE_CHUD AUE_NULL
+#define AUE_CSOPS AUE_NULL
#define AUE_DUP AUE_NULL
+#define AUE_FCHMODEXTENDED AUE_NULL
+#define AUE_FDATASYNC AUE_NULL
+#define AUE_FFSCTL AUE_NULL
+#define AUE_FGETATTRLIST AUE_NULL
+#define AUE_FGETXATTR AUE_NULL
+#define AUE_FLISTXATTR AUE_NULL
+#define AUE_FREMOVEXATTR AUE_NULL
#define AUE_FSCTL AUE_NULL
+#define AUE_FSETATTRLIST AUE_NULL
+#define AUE_FSETXATTR AUE_NULL
+#define AUE_FSTATEXTENDED AUE_NULL
+#define AUE_FSTATFS64 AUE_NULL
#define AUE_FSTATV AUE_NULL
+#define AUE_FSTAT64 AUE_NULL
+#define AUE_FSTAT64EXTENDED AUE_NULL
#define AUE_GCCONTROL AUE_NULL
+#define AUE_GETDIRENTRIES64 AUE_NULL
#define AUE_GETDTABLESIZE AUE_NULL
#define AUE_GETEGID AUE_NULL
#define AUE_GETEUID AUE_NULL
+#define AUE_GETFSSTAT64 AUE_NULL
#define AUE_GETGID AUE_NULL
#define AUE_GETGROUPS AUE_NULL
#define AUE_GETITIMER AUE_NULL
@@ -675,24 +705,53 @@
#define AUE_GETPRIORITY AUE_NULL
#define AUE_GETRLIMIT AUE_NULL
#define AUE_GETRUSAGE AUE_NULL
+#define AUE_GETSGROUPS AUE_NULL
#define AUE_GETSID AUE_NULL
#define AUE_GETSOCKNAME AUE_NULL
#define AUE_GETTIMEOFDAY AUE_NULL
+#define AUE_GETTID AUE_NULL
#define AUE_GETUID AUE_NULL
#define AUE_GETSOCKOPT AUE_NULL
-#define AUE_GTSOCKOPT AUE_GETSOCKOPT /* XXX: Typo in Darwin. */
+#define AUE_GETWGROUPS AUE_NULL
+#define AUE_GETXATTR AUE_NULL
+#define AUE_IDENTITYSVC AUE_NULL
+#define AUE_INITGROUPS AUE_NULL
+#define AUE_IOPOLICYSYS AUE_NULL
#define AUE_ISSETUGID AUE_NULL
+#define AUE_LIOLISTIO AUE_NULL
+#define AUE_LISTXATTR AUE_NULL
+#define AUE_LSTATEXTENDED AUE_NULL
#define AUE_LSTATV AUE_NULL
+#define AUE_LSTAT64 AUE_NULL
+#define AUE_LSTAT64EXTENDED AUE_NULL
#define AUE_MADVISE AUE_NULL
#define AUE_MINCORE AUE_NULL
#define AUE_MKCOMPLEX AUE_NULL
+#define AUE_MKDIREXTENDED AUE_NULL
+#define AUE_MKFIFOEXTENDED AUE_NULL
#define AUE_MODWATCH AUE_NULL
#define AUE_MSGCL AUE_NULL
#define AUE_MSYNC AUE_NULL
+#define AUE_OPENEXTENDED AUE_NULL
#define AUE_PREAD AUE_NULL
#define AUE_PWRITE AUE_NULL
#define AUE_PREADV AUE_NULL
+#define AUE_PROCINFO AUE_NULL
+#define AUE_PTHREADCANCELED AUE_NULL
+#define AUE_PTHREADCHDIR AUE_NULL
+#define AUE_PTHREADCONDBROADCAST AUE_NULL
+#define AUE_PTHREADCONDDESTORY AUE_NULL
+#define AUE_PTHREADCONDINIT AUE_NULL
+#define AUE_PTHREADCONDSIGNAL AUE_NULL
+#define AUE_PTHREADCONDWAIT AUE_NULL
+#define AUE_PTHREADFCHDIR AUE_NULL
+#define AUE_PTHREADMARK AUE_NULL
+#define AUE_PTHREADMUTEXDESTROY AUE_NULL
+#define AUE_PTHREADMUTEXINIT AUE_NULL
+#define AUE_PTHREADMUTEXTRYLOCK AUE_NULL
+#define AUE_PTHREADMUTEXUNLOCK AUE_NULL
#define AUE_PWRITEV AUE_NULL
+#define AUE_REMOVEXATTR AUE_NULL
#define AUE_SBRK AUE_NULL
#define AUE_SELECT AUE_NULL
#define AUE_SEMDESTROY AUE_NULL
@@ -701,7 +760,15 @@
#define AUE_SEMPOST AUE_NULL
#define AUE_SEMTRYWAIT AUE_NULL
#define AUE_SEMWAIT AUE_NULL
+#define AUE_SEMWAITSIGNAL AUE_NULL
#define AUE_SETITIMER AUE_NULL
+#define AUE_SETSGROUPS AUE_NULL
+#define AUE_SETTID AUE_NULL
+#define AUE_SETTIDWITHPID AUE_NULL
+#define AUE_SETWGROUPS AUE_NULL
+#define AUE_SETXATTR AUE_NULL
+#define AUE_SHAREDREGIONCHECK AUE_NULL
+#define AUE_SHAREDREGIONMAP AUE_NULL
#define AUE_SIGACTION AUE_NULL
#define AUE_SIGALTSTACK AUE_NULL
#define AUE_SIGPENDING AUE_NULL
@@ -710,11 +777,21 @@
#define AUE_SIGSUSPEND AUE_NULL
#define AUE_SIGWAIT AUE_NULL
#define AUE_SSTK AUE_NULL
+#define AUE_STACKSNAPSHOT AUE_NULL
+#define AUE_STATEXTENDED AUE_NULL
+#define AUE_STATFS64 AUE_NULL
#define AUE_STATV AUE_NULL
+#define AUE_STAT64 AUE_NULL
+#define AUE_STAT64EXTENDED AUE_NULL
#define AUE_SYNC AUE_NULL
#define AUE_SYSCALL AUE_NULL
#define AUE_TABLE AUE_NULL
+#define AUE_UMASKEXTENDED AUE_NULL
+#define AUE_VMPRESSUREMONITOR AUE_NULL
#define AUE_WAITEVENT AUE_NULL
+#define AUE_WAITID AUE_NULL
#define AUE_WATCHEVENT AUE_NULL
+#define AUE_WORKQOPEN AUE_NULL
+#define AUE_WORKQOPS AUE_NULL
#endif /* !_BSM_AUDIT_KEVENTS_H_ */
diff --git a/contrib/openbsm/sys/bsm/audit_record.h b/contrib/openbsm/sys/bsm/audit_record.h
index ccca15b..c8180323 100644
--- a/contrib/openbsm/sys/bsm/audit_record.h
+++ b/contrib/openbsm/sys/bsm/audit_record.h
@@ -26,7 +26,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.
*
- * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_record.h#3 $
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_record.h#9 $
*/
#ifndef _BSM_AUDIT_RECORD_H_
@@ -164,14 +164,11 @@
#define AUDIT_HEADER_VERSION_SOLARIS 2
#define AUDIT_HEADER_VERSION_TSOL25 3
#define AUDIT_HEADER_VERSION_TSOL 4
-#define AUDIT_HEADER_VERSION_OPENBSM 10
+#define AUDIT_HEADER_VERSION_OPENBSM10 10
+#define AUDIT_HEADER_VERSION_OPENBSM11 11
+#define AUDIT_HEADER_VERSION_OPENBSM AUDIT_HEADER_VERSION_OPENBSM11
-/*
- * BSM define is AUT_TRAILER_MAGIC; Apple BSM define is TRAILER_PAD_MAGIC; we
- * split the difference, will remove the Apple define for the next release.
- */
#define AUT_TRAILER_MAGIC 0xb105
-#define TRAILER_PAD_MAGIC AUT_TRAILER_MAGIC
/* BSM library calls */
@@ -182,6 +179,7 @@ struct in6_addr;
struct ip;
struct ipc_perm;
struct kevent;
+struct sockaddr;
struct sockaddr_in;
struct sockaddr_in6;
struct sockaddr_un;
@@ -208,6 +206,7 @@ token_t *au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod);
token_t *au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod);
token_t *au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod);
token_t *au_to_header64(int rec_size, au_event_t e_type, au_emod_t e_mod);
+token_t *au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod);
#endif
token_t *au_to_me(void);
@@ -251,15 +250,8 @@ token_t *au_to_return(char status, uint32_t ret);
token_t *au_to_return32(char status, uint32_t ret);
token_t *au_to_return64(char status, uint64_t ret);
token_t *au_to_seq(long audit_count);
-
-#if defined(_KERNEL) || defined(KERNEL)
-token_t *au_to_socket(struct socket *so);
-token_t *au_to_socket_ex_32(uint16_t lp, uint16_t rp, struct sockaddr *la,
- struct sockaddr *ta);
-token_t *au_to_socket_ex_128(uint16_t lp, uint16_t rp, struct sockaddr *la,
- struct sockaddr *ta);
-#endif
-
+token_t *au_to_socket_ex(u_short so_domain, u_short so_type,
+ struct sockaddr *sa_local, struct sockaddr *sa_remote);
token_t *au_to_sock_inet(struct sockaddr_in *so);
token_t *au_to_sock_inet32(struct sockaddr_in *so);
token_t *au_to_sock_inet128(struct sockaddr_in6 *so);
@@ -277,8 +269,8 @@ token_t *au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
token_t *au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid);
#if defined(_KERNEL) || defined(KERNEL)
-token_t *au_to_exec_args(const char *args, int argc);
-token_t *au_to_exec_env(const char *envs, int envc);
+token_t *au_to_exec_args(char *args, int argc);
+token_t *au_to_exec_env(char *envs, int envc);
#else
token_t *au_to_exec_args(char **argv);
token_t *au_to_exec_env(char **envp);
@@ -288,6 +280,17 @@ token_t *au_to_kevent(struct kevent *kev);
token_t *au_to_trailer(int rec_size);
token_t *au_to_zonename(const char *zonename);
+/*
+ * BSM library routines for converting between local and BSM constant spaces.
+ */
+int au_bsm_to_domain(u_short bsm_domain, int *local_domainp);
+int au_bsm_to_errno(u_char bsm_error, int *errorp);
+int au_bsm_to_socket_type(u_short bsm_socket_type,
+ int *local_socket_typep);
+u_short au_domain_to_bsm(int local_domain);
+u_char au_errno_to_bsm(int local_errno);
+u_short au_socket_type_to_bsm(int local_socket_type);
+
__END_DECLS
#endif /* ! _BSM_AUDIT_RECORD_H_ */
diff --git a/contrib/openbsm/sys/bsm/audit_socket_type.h b/contrib/openbsm/sys/bsm/audit_socket_type.h
new file mode 100644
index 0000000..85f6aef
--- /dev/null
+++ b/contrib/openbsm/sys/bsm/audit_socket_type.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_socket_type.h#1 $
+ */
+
+#ifndef _BSM_AUDIT_SOCKET_TYPE_H_
+#define _BSM_AUDIT_SOCKET_TYPE_H_
+
+/*
+ * BSM socket type constants.
+ */
+#define BSM_SOCK_DGRAM 1
+#define BSM_SOCK_STREAM 2
+#define BSM_SOCK_RAW 4
+#define BSM_SOCK_RDM 5
+#define BSM_SOCK_SEQPACKET 6
+
+#define BSM_SOCK_UNKNOWN 500
+
+#endif /* !_BSM_AUDIT_SOCKET_TYPE_H_ */
diff --git a/contrib/openbsm/test/Makefile.in b/contrib/openbsm/test/Makefile.in
index 9eb97fa..737f3b1e 100644
--- a/contrib/openbsm/test/Makefile.in
+++ b/contrib/openbsm/test/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/test/Makefile.in#6 $
+# $P4: //depot/projects/trustedbsd/openbsm/test/Makefile.in#7 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
diff --git a/contrib/openbsm/test/bsm/Makefile.in b/contrib/openbsm/test/bsm/Makefile.in
index 128b03d..aa06a80 100644
--- a/contrib/openbsm/test/bsm/Makefile.in
+++ b/contrib/openbsm/test/bsm/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/test/bsm/Makefile.in#6 $
+# $P4: //depot/projects/trustedbsd/openbsm/test/bsm/Makefile.in#7 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/test/bsm/generate.c b/contrib/openbsm/test/bsm/generate.c
index d066246..bbc81bb 100644
--- a/contrib/openbsm/test/bsm/generate.c
+++ b/contrib/openbsm/test/bsm/generate.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2006-2007 Robert N. M. Watson
+ * Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/test/bsm/generate.c#9 $
+ * $P4: //depot/projects/trustedbsd/openbsm/test/bsm/generate.c#14 $
*/
/*
@@ -553,7 +554,7 @@ generate_process64ex_record(const char *directory, const char *record_filename,
free(buf);
}
-static char return32_status = 0xd7;
+static char return32_status = EINVAL;
static uint32_t return32_ret = 0x12345678;
static void
@@ -561,7 +562,8 @@ generate_return32_token(const char *directory, const char *token_filename)
{
token_t *return32_token;
- return32_token = au_to_return32(return32_status, return32_ret);
+ return32_token = au_to_return32(au_errno_to_bsm(return32_status),
+ return32_ret);
if (return32_token == NULL)
err(EX_UNAVAILABLE, "au_to_return32");
write_token(directory, token_filename, return32_token);
@@ -572,7 +574,8 @@ generate_return32_record(const char *directory, const char *record_filename)
{
token_t *return32_token;
- return32_token = au_to_return32(return32_status, return32_ret);
+ return32_token = au_to_return32(au_errno_to_bsm(return32_status),
+ return32_ret);
if (return32_token == NULL)
err(EX_UNAVAILABLE, "au_to_return32");
write_record(directory, record_filename, return32_token, AUE_NULL);
@@ -789,6 +792,7 @@ generate_seq_record(const char *directory, const char *record_filename)
write_record(directory, record_filename, seq_token, AUE_NULL);
}
+#if 0
/*
* AUT_ACL
*/
@@ -820,7 +824,9 @@ generate_ipc_perm_record(const char *directory, const char *record_filename)
token_t *ipc_perm_token;
}
+#endif
+#if 0
/*
* AUT_LABEL
*/
@@ -838,6 +844,7 @@ generate_groups_record(const char *directory, const char *record_filename)
token_t *groups_token;
}
+#endif
/*
* AUT_ILABEL
@@ -875,6 +882,7 @@ generate_groups_record(const char *directory, const char *record_filename)
* AUT_EXEC_ENV
*/
+#if 0
static void
generate_attr32_token(const char *directory, const char *token_filename)
{
@@ -888,6 +896,7 @@ generate_attr32_record(const char *directory, const char *record_filename)
token_t *attr32_token;
}
+#endif
static char *zonename_sample = "testzone";
@@ -913,6 +922,126 @@ generate_zonename_record(const char *directory, const char *record_filename)
write_record(directory, record_filename, zonename_token, AUE_NULL);
}
+static u_short socketex_domain = PF_INET;
+static u_short socketex_type = SOCK_STREAM;
+static struct sockaddr_in socketex_laddr, socketex_raddr;
+
+static void
+generate_socketex_token(const char *directory, const char *token_filename)
+{
+ token_t *socketex_token;
+
+ bzero(&socketex_laddr, sizeof(socketex_laddr));
+ socketex_laddr.sin_family = AF_INET;
+ socketex_laddr.sin_len = sizeof(socketex_laddr);
+ socketex_laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ bzero(&socketex_raddr, sizeof(socketex_raddr));
+ socketex_raddr.sin_family = AF_INET;
+ socketex_raddr.sin_len = sizeof(socketex_raddr);
+ socketex_raddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ socketex_token = au_to_socket_ex(au_domain_to_bsm(socketex_domain),
+ au_socket_type_to_bsm(socketex_type),
+ (struct sockaddr *)&socketex_laddr,
+ (struct sockaddr *)&socketex_raddr);
+ if (socketex_token == NULL)
+ err(EX_UNAVAILABLE, "au_to_socket_ex");
+ write_token(directory, token_filename, socketex_token);
+}
+
+static void
+generate_socketex_record(const char *directory, const char *record_filename)
+{
+ token_t *socketex_token;
+
+ bzero(&socketex_laddr, sizeof(socketex_laddr));
+ socketex_laddr.sin_family = AF_INET;
+ socketex_laddr.sin_len = sizeof(socketex_laddr);
+ socketex_laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ bzero(&socketex_raddr, sizeof(socketex_raddr));
+ socketex_raddr.sin_family = AF_INET;
+ socketex_raddr.sin_len = sizeof(socketex_raddr);
+ socketex_raddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ socketex_token = au_to_socket_ex(au_domain_to_bsm(socketex_domain),
+ au_socket_type_to_bsm(socketex_type),
+ (struct sockaddr *)&socketex_laddr,
+ (struct sockaddr *)&socketex_raddr);
+ if (socketex_token == NULL)
+ err(EX_UNAVAILABLE, "au_to_socket_ex");
+ write_record(directory, record_filename, socketex_token, AUE_NULL);
+}
+
+/*
+ * Generate a series of error-number specific return tokens in records.
+ */
+static void
+generate_error_record(const char *directory, const char *filename, int error)
+{
+ char pathname[PATH_MAX];
+ token_t *return32_token;
+
+ return32_token = au_to_return32(au_errno_to_bsm(error), -1);
+ if (return32_token == NULL)
+ err(EX_UNAVAILABLE, "au_to_return32");
+ (void)snprintf(pathname, PATH_MAX, "%s_record", filename);
+ write_record(directory, pathname, return32_token, AUE_NULL);
+}
+
+/*
+ * Not all the error numbers, just a few present on all platforms for now.
+ */
+const struct {
+ int error_number;
+ const char *error_name;
+} error_list[] = {
+ { EPERM, "EPERM" },
+ { ENOENT, "ENOENT" },
+ { ESRCH, "ESRCH" },
+ { EINTR, "EINTR" },
+ { EIO, "EIO" },
+ { ENXIO, "ENXIO" },
+ { E2BIG, "E2BIG" },
+ { ENOEXEC, "ENOEXEC" },
+ { EBADF, "EBADF" },
+ { ECHILD, "ECHILD" },
+ { EDEADLK, "EDEADLK" },
+ { ENOMEM, "ENOMEM" },
+ { EACCES, "EACCES" },
+ { EFAULT, "EFAULT" },
+ { ENOTBLK, "ENOTBLK" },
+ { EBUSY, "EBUSY" },
+ { EEXIST, "EEXIST" },
+ { EXDEV, "EXDEV" },
+ { ENODEV, "ENODEV" },
+ { ENOTDIR, "ENOTDIR" },
+ { EISDIR, "EISDIR" },
+ { EINVAL, "EINVAL" },
+ { ENFILE, "ENFILE" },
+ { EMFILE, "EMFILE" },
+ { ENOTTY, "ENOTTY" },
+ { ETXTBSY, "ETXTBSY" },
+ { EFBIG, "EFBIG" },
+ { ENOSPC, "ENOSPC" },
+ { ESPIPE, "ESPIPE" },
+ { EROFS, "EROFS" },
+ { EMLINK, "EMLINK" },
+ { EPIPE, "EPIPE" }
+};
+const int error_list_count = sizeof(error_list)/sizeof(error_list[0]);
+
+static void
+do_error_records(const char *directory)
+{
+ int i;
+
+ for (i = 0; i < error_list_count; i++)
+ generate_error_record(directory, error_list[i].error_name,
+ error_list[i].error_number);
+}
+
int
main(int argc, char *argv[])
{
@@ -975,11 +1104,14 @@ main(int argc, char *argv[])
generate_iport_token(directory, "iport_token");
generate_arg32_token(directory, "arg32_token");
generate_seq_token(directory, "seq_token");
+#if 0
generate_attr_token(directory, "attr_token");
generate_ipc_perm_token(directory, "ipc_perm_token");
generate_groups_token(directory, "groups_token");
generate_attr32_token(directory, "attr32_token");
+#endif
generate_zonename_token(directory, "zonename_token");
+ generate_socketex_token(directory, "socketex_token");
}
if (do_records) {
@@ -1010,11 +1142,15 @@ main(int argc, char *argv[])
generate_iport_record(directory, "iport_record");
generate_arg32_record(directory, "arg32_record");
generate_seq_record(directory, "seq_record");
+#if 0
generate_attr_record(directory, "attr_record");
generate_ipc_perm_record(directory, "ipc_perm_record");
generate_groups_record(directory, "groups_record");
generate_attr32_record(directory, "attr32_record");
+#endif
generate_zonename_record(directory, "zonename_record");
+ generate_socketex_record(directory, "socketex_record");
+ do_error_records(directory);
}
return (0);
diff --git a/contrib/openbsm/test/reference/E2BIG_record b/contrib/openbsm/test/reference/E2BIG_record
new file mode 100644
index 0000000..8665900
--- /dev/null
+++ b/contrib/openbsm/test/reference/E2BIG_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EACCES_record b/contrib/openbsm/test/reference/EACCES_record
new file mode 100644
index 0000000..7ab3181
--- /dev/null
+++ b/contrib/openbsm/test/reference/EACCES_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EBADF_record b/contrib/openbsm/test/reference/EBADF_record
new file mode 100644
index 0000000..ed80d6a
--- /dev/null
+++ b/contrib/openbsm/test/reference/EBADF_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EBUSY_record b/contrib/openbsm/test/reference/EBUSY_record
new file mode 100644
index 0000000..1ceaf62
--- /dev/null
+++ b/contrib/openbsm/test/reference/EBUSY_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ECHILD_record b/contrib/openbsm/test/reference/ECHILD_record
new file mode 100644
index 0000000..fc1e884
--- /dev/null
+++ b/contrib/openbsm/test/reference/ECHILD_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EDEADLK_record b/contrib/openbsm/test/reference/EDEADLK_record
new file mode 100644
index 0000000..ace3c46
--- /dev/null
+++ b/contrib/openbsm/test/reference/EDEADLK_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EEXIST_record b/contrib/openbsm/test/reference/EEXIST_record
new file mode 100644
index 0000000..f6eae9f
--- /dev/null
+++ b/contrib/openbsm/test/reference/EEXIST_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EFAULT_record b/contrib/openbsm/test/reference/EFAULT_record
new file mode 100644
index 0000000..1b8ed09
--- /dev/null
+++ b/contrib/openbsm/test/reference/EFAULT_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EFBIG_record b/contrib/openbsm/test/reference/EFBIG_record
new file mode 100644
index 0000000..fc4a060
--- /dev/null
+++ b/contrib/openbsm/test/reference/EFBIG_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EINTR_record b/contrib/openbsm/test/reference/EINTR_record
new file mode 100644
index 0000000..2c96d4a
--- /dev/null
+++ b/contrib/openbsm/test/reference/EINTR_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EINVAL_record b/contrib/openbsm/test/reference/EINVAL_record
new file mode 100644
index 0000000..0068cd1
--- /dev/null
+++ b/contrib/openbsm/test/reference/EINVAL_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EIO_record b/contrib/openbsm/test/reference/EIO_record
new file mode 100644
index 0000000..36682c3
--- /dev/null
+++ b/contrib/openbsm/test/reference/EIO_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EISDIR_record b/contrib/openbsm/test/reference/EISDIR_record
new file mode 100644
index 0000000..56ccdf3
--- /dev/null
+++ b/contrib/openbsm/test/reference/EISDIR_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EMFILE_record b/contrib/openbsm/test/reference/EMFILE_record
new file mode 100644
index 0000000..b15e0e5
--- /dev/null
+++ b/contrib/openbsm/test/reference/EMFILE_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EMLINK_record b/contrib/openbsm/test/reference/EMLINK_record
new file mode 100644
index 0000000..27c048c
--- /dev/null
+++ b/contrib/openbsm/test/reference/EMLINK_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENFILE_record b/contrib/openbsm/test/reference/ENFILE_record
new file mode 100644
index 0000000..7dbbb3d
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENFILE_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENODEV_record b/contrib/openbsm/test/reference/ENODEV_record
new file mode 100644
index 0000000..1e745d8
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENODEV_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOENT_record b/contrib/openbsm/test/reference/ENOENT_record
new file mode 100644
index 0000000..33395f8
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOENT_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOEXEC_record b/contrib/openbsm/test/reference/ENOEXEC_record
new file mode 100644
index 0000000..a2e2593
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOEXEC_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOMEM_record b/contrib/openbsm/test/reference/ENOMEM_record
new file mode 100644
index 0000000..f7137e7
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOMEM_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOSPC_record b/contrib/openbsm/test/reference/ENOSPC_record
new file mode 100644
index 0000000..863a9a7
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOSPC_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOTBLK_record b/contrib/openbsm/test/reference/ENOTBLK_record
new file mode 100644
index 0000000..6b14cb1
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOTBLK_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOTDIR_record b/contrib/openbsm/test/reference/ENOTDIR_record
new file mode 100644
index 0000000..9b311c0
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOTDIR_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENOTTY_record b/contrib/openbsm/test/reference/ENOTTY_record
new file mode 100644
index 0000000..31e98ee
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENOTTY_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ENXIO_record b/contrib/openbsm/test/reference/ENXIO_record
new file mode 100644
index 0000000..72bb902
--- /dev/null
+++ b/contrib/openbsm/test/reference/ENXIO_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EPERM_record b/contrib/openbsm/test/reference/EPERM_record
new file mode 100644
index 0000000..b0822e6
--- /dev/null
+++ b/contrib/openbsm/test/reference/EPERM_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EPIPE_record b/contrib/openbsm/test/reference/EPIPE_record
new file mode 100644
index 0000000..c85fa40
--- /dev/null
+++ b/contrib/openbsm/test/reference/EPIPE_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EROFS_record b/contrib/openbsm/test/reference/EROFS_record
new file mode 100644
index 0000000..79468ec
--- /dev/null
+++ b/contrib/openbsm/test/reference/EROFS_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ESPIPE_record b/contrib/openbsm/test/reference/ESPIPE_record
new file mode 100644
index 0000000..196390f
--- /dev/null
+++ b/contrib/openbsm/test/reference/ESPIPE_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ESRCH_record b/contrib/openbsm/test/reference/ESRCH_record
new file mode 100644
index 0000000..1d55e17
--- /dev/null
+++ b/contrib/openbsm/test/reference/ESRCH_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ETXTBSY_record b/contrib/openbsm/test/reference/ETXTBSY_record
new file mode 100644
index 0000000..2a8895d
--- /dev/null
+++ b/contrib/openbsm/test/reference/ETXTBSY_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/EXDEV_record b/contrib/openbsm/test/reference/EXDEV_record
new file mode 100644
index 0000000..ca4a620
--- /dev/null
+++ b/contrib/openbsm/test/reference/EXDEV_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/arg32_record b/contrib/openbsm/test/reference/arg32_record
index 2222ed0..12a545d 100644
--- a/contrib/openbsm/test/reference/arg32_record
+++ b/contrib/openbsm/test/reference/arg32_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/data_record b/contrib/openbsm/test/reference/data_record
index 8088f4e..f237459 100644
--- a/contrib/openbsm/test/reference/data_record
+++ b/contrib/openbsm/test/reference/data_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/data_token b/contrib/openbsm/test/reference/data_token
index e000b8a..83576767 100644
--- a/contrib/openbsm/test/reference/data_token
+++ b/contrib/openbsm/test/reference/data_token
Binary files differ
diff --git a/contrib/openbsm/test/reference/file_record b/contrib/openbsm/test/reference/file_record
index b56d5cc..b5d1406 100644
--- a/contrib/openbsm/test/reference/file_record
+++ b/contrib/openbsm/test/reference/file_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/header32_token b/contrib/openbsm/test/reference/header32_token
index dd72c1c..3386b86 100644
--- a/contrib/openbsm/test/reference/header32_token
+++ b/contrib/openbsm/test/reference/header32_token
Binary files differ
diff --git a/contrib/openbsm/test/reference/in_addr_record b/contrib/openbsm/test/reference/in_addr_record
index 4f308e0..389b743 100644
--- a/contrib/openbsm/test/reference/in_addr_record
+++ b/contrib/openbsm/test/reference/in_addr_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ip_record b/contrib/openbsm/test/reference/ip_record
index aee40a7..5d8b21d 100644
--- a/contrib/openbsm/test/reference/ip_record
+++ b/contrib/openbsm/test/reference/ip_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/ipc_record b/contrib/openbsm/test/reference/ipc_record
index 4510f88..5b51561 100644
--- a/contrib/openbsm/test/reference/ipc_record
+++ b/contrib/openbsm/test/reference/ipc_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/iport_record b/contrib/openbsm/test/reference/iport_record
index 1375efb..bef1c9f 100644
--- a/contrib/openbsm/test/reference/iport_record
+++ b/contrib/openbsm/test/reference/iport_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/opaque_record b/contrib/openbsm/test/reference/opaque_record
index 247d6f2..e13a36b 100644
--- a/contrib/openbsm/test/reference/opaque_record
+++ b/contrib/openbsm/test/reference/opaque_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/path_record b/contrib/openbsm/test/reference/path_record
index 0d32b86..fab532c 100644
--- a/contrib/openbsm/test/reference/path_record
+++ b/contrib/openbsm/test/reference/path_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/process32_record b/contrib/openbsm/test/reference/process32_record
index 9a3f7d9..4f19d37 100644
--- a/contrib/openbsm/test/reference/process32_record
+++ b/contrib/openbsm/test/reference/process32_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/process32ex_record-IPv4 b/contrib/openbsm/test/reference/process32ex_record-IPv4
index 6250b9c..4ff66c0 100644
--- a/contrib/openbsm/test/reference/process32ex_record-IPv4
+++ b/contrib/openbsm/test/reference/process32ex_record-IPv4
Binary files differ
diff --git a/contrib/openbsm/test/reference/process32ex_record-IPv6 b/contrib/openbsm/test/reference/process32ex_record-IPv6
index 22a3249..944510d 100644
--- a/contrib/openbsm/test/reference/process32ex_record-IPv6
+++ b/contrib/openbsm/test/reference/process32ex_record-IPv6
Binary files differ
diff --git a/contrib/openbsm/test/reference/process64_record b/contrib/openbsm/test/reference/process64_record
index d8fca8e..5f831bf 100644
--- a/contrib/openbsm/test/reference/process64_record
+++ b/contrib/openbsm/test/reference/process64_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/process64ex_record-IPv4 b/contrib/openbsm/test/reference/process64ex_record-IPv4
index 3b7a728..1440ac7 100644
--- a/contrib/openbsm/test/reference/process64ex_record-IPv4
+++ b/contrib/openbsm/test/reference/process64ex_record-IPv4
Binary files differ
diff --git a/contrib/openbsm/test/reference/process64ex_record-IPv6 b/contrib/openbsm/test/reference/process64ex_record-IPv6
index 6563e25..da55f6a 100644
--- a/contrib/openbsm/test/reference/process64ex_record-IPv6
+++ b/contrib/openbsm/test/reference/process64ex_record-IPv6
Binary files differ
diff --git a/contrib/openbsm/test/reference/return32_record b/contrib/openbsm/test/reference/return32_record
index e57d26c..7919034 100644
--- a/contrib/openbsm/test/reference/return32_record
+++ b/contrib/openbsm/test/reference/return32_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/return32_token b/contrib/openbsm/test/reference/return32_token
index e7a2098..4c6dc0c 100644
--- a/contrib/openbsm/test/reference/return32_token
+++ b/contrib/openbsm/test/reference/return32_token
@@ -1 +1 @@
-'×4Vx \ No newline at end of file
+'4Vx \ No newline at end of file
diff --git a/contrib/openbsm/test/reference/seq_record b/contrib/openbsm/test/reference/seq_record
index 75cea17..26c6180 100644
--- a/contrib/openbsm/test/reference/seq_record
+++ b/contrib/openbsm/test/reference/seq_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/socketex_record b/contrib/openbsm/test/reference/socketex_record
new file mode 100644
index 0000000..522fb51
--- /dev/null
+++ b/contrib/openbsm/test/reference/socketex_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/socketex_token b/contrib/openbsm/test/reference/socketex_token
new file mode 100644
index 0000000..d107290
--- /dev/null
+++ b/contrib/openbsm/test/reference/socketex_token
Binary files differ
diff --git a/contrib/openbsm/test/reference/subject32_record b/contrib/openbsm/test/reference/subject32_record
index f96d84c..ed91cf0 100644
--- a/contrib/openbsm/test/reference/subject32_record
+++ b/contrib/openbsm/test/reference/subject32_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/subject32ex_record b/contrib/openbsm/test/reference/subject32ex_record
index 1d949a6..5b5575e 100644
--- a/contrib/openbsm/test/reference/subject32ex_record
+++ b/contrib/openbsm/test/reference/subject32ex_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/text_record b/contrib/openbsm/test/reference/text_record
index 2f3fce2..694dc5c 100644
--- a/contrib/openbsm/test/reference/text_record
+++ b/contrib/openbsm/test/reference/text_record
Binary files differ
diff --git a/contrib/openbsm/test/reference/zonename_record b/contrib/openbsm/test/reference/zonename_record
index cfb9e26..1fa8d97 100644
--- a/contrib/openbsm/test/reference/zonename_record
+++ b/contrib/openbsm/test/reference/zonename_record
Binary files differ
diff --git a/contrib/openbsm/tools/Makefile.in b/contrib/openbsm/tools/Makefile.in
index d689761..0931a48 100644
--- a/contrib/openbsm/tools/Makefile.in
+++ b/contrib/openbsm/tools/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/tools/Makefile.in#9 $
+# $P4: //depot/projects/trustedbsd/openbsm/tools/Makefile.in#10 $
#
VPATH = @srcdir@
diff --git a/contrib/opie/opiekey.1 b/contrib/opie/opiekey.1
index 1f6e35e..bc62b94 100644
--- a/contrib/opie/opiekey.1
+++ b/contrib/opie/opiekey.1
@@ -157,8 +157,7 @@ this mistake. Better checks are needed.
.BR opieinfo (1),
.BR opiekeys (5),
.BR opieaccess (5),
-.BR opiegen (1)
-.BR su (1),
+.BR su (1)
.SH AUTHOR
Bellcore's S/Key was written by Phil Karn, Neil M. Haller, and John S. Walden
diff --git a/contrib/smbfs/mount_smbfs/mount_smbfs.8 b/contrib/smbfs/mount_smbfs/mount_smbfs.8
index aec889c..85ee6e3 100644
--- a/contrib/smbfs/mount_smbfs/mount_smbfs.8
+++ b/contrib/smbfs/mount_smbfs/mount_smbfs.8
@@ -1,6 +1,6 @@
.\" $Id: mount_smbfs.8,v 1.10 2002/04/16 02:47:41 bp Exp $
.\" $FreeBSD$
-.Dd March 10, 2000
+.Dd January 21, 2008
.Dt MOUNT_SMBFS 8
.Os
.Sh NAME
@@ -16,6 +16,7 @@
.Op Fl O Ar cowner : Ns Ar cgroup Ns / Ns Ar sowner : Ns Ar sgroup
.Op Fl R Ar retrycount
.Op Fl T Ar timeout
+.Op Fl U Ar username
.Op Fl W Ar workgroup
.Op Fl c Ar case
.Op Fl d Ar mode
@@ -77,6 +78,8 @@ Default is 4.
.It Fl T Ar timeout
Timeout in seconds for each request.
Default is 15.
+.It Fl U Ar username
+Username to authenticate with.
.It Fl W Ar workgroup
This option specifies the workgroup to be used in the authentication request.
.It Fl c Ar case
diff --git a/contrib/smbfs/mount_smbfs/mount_smbfs.c b/contrib/smbfs/mount_smbfs/mount_smbfs.c
index fdcdd1a..3025c79 100644
--- a/contrib/smbfs/mount_smbfs/mount_smbfs.c
+++ b/contrib/smbfs/mount_smbfs/mount_smbfs.c
@@ -295,7 +295,7 @@ usage(void)
"usage: mount_smbfs [-E cs1:cs2] [-I host] [-L locale] [-M crights:srights]",
" [-N] [-O cowner:cgroup/sowner:sgroup] [-R retrycount]",
" [-T timeout] [-W workgroup] [-c case] [-d mode] [-f mode]",
- " [-g gid] [-n opt] [-u uid] //user@server/share node");
+ " [-g gid] [-n opt] [-u uid] [-U username] //user@server/share node");
exit (1);
}
diff --git a/contrib/wpa_supplicant/ChangeLog b/contrib/wpa_supplicant/ChangeLog
index 1ba2e1c..10b1aca 100644
--- a/contrib/wpa_supplicant/ChangeLog
+++ b/contrib/wpa_supplicant/ChangeLog
@@ -1,5 +1,31 @@
ChangeLog for wpa_supplicant
+2008-11-28 - v0.5.11
+ * fixed race condition between disassociation event and group key
+ handshake to avoid getting stuck in incorrect state [Bug 261]
+ * updated D-Bus usage to avoid deprecated functions
+ * silence SIOCSIWAUTH ioctl failure message (these can be ignored in
+ most cases and are now only shown in debug output)
+ * increase timeout for IBSS connection
+ * driver_wext: do not overwrite BSS frequency if channel was already
+ received
+ * driver_wext: set interface down for mode switches, if needed (e.g.,
+ for mac80211)
+ * driver_wext: fixed re-initialization of a removed and re-inserted
+ interface (e.g., USB dongle or on resume if driver was unloaded for
+ suspend)
+ * improve per-SSID scanning for drivers that report background scan
+ results frequently
+ * fixed scanning behavior after a failed initial association
+ * driver_wext: fixed processing of invalid event messages from kernel
+ not to crash wpa_supplicant (this could happen when using 64-bit
+ kernel with 32-bit userspace)
+ * fixed EAP-AKA to use RES Length field in AT_RES as length in bits,
+ not bytes
+ * fixed canceling of PMKSA caching when using drivers that generate
+ RSN IE and refuse to drop PMKIDs that wpa_supplicant does not know
+ about
+
2008-02-19 - v0.5.10
* added support for Makefile builds to include debug-log-to-a-file
functionality (CONFIG_DEBUG_FILE=y and -f<path> on command line)
diff --git a/contrib/wpa_supplicant/Makefile b/contrib/wpa_supplicant/Makefile
index 9bcdd83..74ea2f5 100644
--- a/contrib/wpa_supplicant/Makefile
+++ b/contrib/wpa_supplicant/Makefile
@@ -149,7 +149,10 @@ endif
ifdef CONFIG_DRIVER_NDIS
CFLAGS += -DCONFIG_DRIVER_NDIS
-OBJS_d += driver_ndis.o driver_ndis_.o
+OBJS_d += driver_ndis.o
+ifdef CONFIG_NDIS_EVENTS_INTEGRATED
+OBJS_d += driver_ndis_.o
+endif
ifndef CONFIG_L2_PACKET
CONFIG_L2_PACKET=pcap
endif
diff --git a/contrib/wpa_supplicant/base64.c b/contrib/wpa_supplicant/base64.c
index 0c33e58..8b1da25 100644
--- a/contrib/wpa_supplicant/base64.c
+++ b/contrib/wpa_supplicant/base64.c
@@ -115,7 +115,7 @@ unsigned char * base64_decode(const unsigned char *src, size_t len,
count++;
}
- if (count % 4)
+ if (count == 0 || count % 4)
return NULL;
olen = count / 4 * 3;
diff --git a/contrib/wpa_supplicant/ctrl_iface.c b/contrib/wpa_supplicant/ctrl_iface.c
index c84a9f9..52d5bd9 100644
--- a/contrib/wpa_supplicant/ctrl_iface.c
+++ b/contrib/wpa_supplicant/ctrl_iface.c
@@ -76,6 +76,7 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
}
+#ifdef IEEE8021X_EAPOL
static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
char *addr)
{
@@ -94,6 +95,7 @@ static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
return 0;
}
+#endif /* IEEE8021X_EAPOL */
#ifdef CONFIG_PEERKEY
@@ -1126,9 +1128,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
wpa_s->reassociate = 1;
wpa_supplicant_req_scan(wpa_s, 0, 0);
}
+#ifdef IEEE8021X_EAPOL
} else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
reply_len = -1;
+#endif /* IEEE8021X_EAPOL */
#ifdef CONFIG_PEERKEY
} else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
diff --git a/contrib/wpa_supplicant/ctrl_iface_dbus.c b/contrib/wpa_supplicant/ctrl_iface_dbus.c
index ba78516..7475aa4 100644
--- a/contrib/wpa_supplicant/ctrl_iface_dbus.c
+++ b/contrib/wpa_supplicant/ctrl_iface_dbus.c
@@ -30,10 +30,10 @@
#include "wpa_ctrl.h"
#include "eap.h"
-#define DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR)
+#define _DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR)
#define DBUS_VER(major, minor) ((major) << 8 | (minor))
-#if DBUS_VERSION < DBUS_VER(1,1)
+#if _DBUS_VERSION < DBUS_VER(1,1)
#define dbus_watch_get_unix_fd dbus_watch_get_fd
#endif
diff --git a/contrib/wpa_supplicant/ctrl_iface_unix.c b/contrib/wpa_supplicant/ctrl_iface_unix.c
index 9e4f85f..6c03d46 100644
--- a/contrib/wpa_supplicant/ctrl_iface_unix.c
+++ b/contrib/wpa_supplicant/ctrl_iface_unix.c
@@ -305,7 +305,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
/* Group name not found - try to parse this as gid */
gid = strtol(gid_str, &endp, 10);
if (*gid_str == '\0' || *endp != '\0') {
- wpa_printf(MSG_DEBUG, "CTRL: Invalid group "
+ wpa_printf(MSG_ERROR, "CTRL: Invalid group "
"'%s'", gid_str);
goto fail;
}
diff --git a/contrib/wpa_supplicant/dbus_dict_helpers.c b/contrib/wpa_supplicant/dbus_dict_helpers.c
index 2852ed5..b6ea556 100644
--- a/contrib/wpa_supplicant/dbus_dict_helpers.c
+++ b/contrib/wpa_supplicant/dbus_dict_helpers.c
@@ -629,36 +629,56 @@ dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
}
+#define BYTE_ARRAY_CHUNK_SIZE 34
+#define BYTE_ARRAY_ITEM_SIZE (sizeof (char))
+
static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
- DBusMessageIter *iter, int array_len, int array_type,
+ DBusMessageIter *iter, int array_type,
struct wpa_dbus_dict_entry *entry)
{
- dbus_uint32_t i = 0;
+ dbus_uint32_t count = 0;
dbus_bool_t success = FALSE;
- char byte;
+ char *buffer;
- /* Zero-length arrays are valid. */
- if (array_len == 0) {
- entry->bytearray_value = NULL;
- entry->array_type = DBUS_TYPE_BYTE;
- success = TRUE;
- goto done;
- }
+ entry->bytearray_value = NULL;
+ entry->array_type = DBUS_TYPE_BYTE;
- entry->bytearray_value = wpa_zalloc(array_len * sizeof(char));
- if (!entry->bytearray_value) {
+ buffer = wpa_zalloc(BYTE_ARRAY_ITEM_SIZE * BYTE_ARRAY_CHUNK_SIZE);
+ if (!buffer) {
perror("_wpa_dbus_dict_entry_get_byte_array[dbus]: out of "
"memory");
goto done;
}
- entry->array_type = DBUS_TYPE_BYTE;
- entry->array_len = array_len;
+ entry->bytearray_value = buffer;
+ entry->array_len = 0;
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
+ char byte;
+
+ if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
+ buffer = realloc(buffer, BYTE_ARRAY_ITEM_SIZE *
+ (count + BYTE_ARRAY_CHUNK_SIZE));
+ if (buffer == NULL) {
+ perror("_wpa_dbus_dict_entry_get_byte_array["
+ "dbus] out of memory trying to "
+ "retrieve the string array");
+ goto done;
+ }
+ }
+ entry->bytearray_value = buffer;
+
dbus_message_iter_get_basic(iter, &byte);
- entry->bytearray_value[i++] = byte;
+ entry->bytearray_value[count] = byte;
+ entry->array_len = ++count;
dbus_message_iter_next(iter);
}
+
+ /* Zero-length arrays are valid. */
+ if (entry->array_len == 0) {
+ free(entry->bytearray_value);
+ entry->bytearray_value = NULL;
+ }
+
success = TRUE;
done:
@@ -666,8 +686,11 @@ done:
}
+#define STR_ARRAY_CHUNK_SIZE 8
+#define STR_ARRAY_ITEM_SIZE (sizeof (char *))
+
static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
- DBusMessageIter *iter, int array_len, int array_type,
+ DBusMessageIter *iter, int array_type,
struct wpa_dbus_dict_entry *entry)
{
dbus_uint32_t count = 0;
@@ -677,13 +700,7 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
entry->strarray_value = NULL;
entry->array_type = DBUS_TYPE_STRING;
- /* Zero-length arrays are valid. */
- if (array_len == 0) {
- success = TRUE;
- goto done;
- }
-
- buffer = wpa_zalloc(sizeof (char *) * 8);
+ buffer = wpa_zalloc(STR_ARRAY_ITEM_SIZE * STR_ARRAY_CHUNK_SIZE);
if (buffer == NULL) {
perror("_wpa_dbus_dict_entry_get_string_array[dbus] out of "
"memory trying to retrieve a string array");
@@ -696,18 +713,15 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
const char *value;
char *str;
- if ((count % 8) == 0 && count != 0) {
- char **tmp;
- tmp = realloc(buffer, sizeof(char *) * (count + 8));
- if (tmp == NULL) {
+ if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
+ buffer = realloc(buffer, STR_ARRAY_ITEM_SIZE *
+ (count + STR_ARRAY_CHUNK_SIZE));
+ if (buffer == NULL) {
perror("_wpa_dbus_dict_entry_get_string_array["
"dbus] out of memory trying to "
"retrieve the string array");
- free(buffer);
- buffer = NULL;
goto done;
}
- buffer = tmp;
}
entry->strarray_value = buffer;
@@ -723,6 +737,13 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
entry->array_len = ++count;
dbus_message_iter_next(iter);
}
+
+ /* Zero-length arrays are valid. */
+ if (entry->array_len == 0) {
+ free(entry->strarray_value);
+ entry->strarray_value = NULL;
+ }
+
success = TRUE;
done:
@@ -734,7 +755,6 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_array(
DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
{
int array_type = dbus_message_iter_get_element_type(iter_dict_val);
- int array_len;
dbus_bool_t success = FALSE;
DBusMessageIter iter_array;
@@ -743,20 +763,14 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_array(
dbus_message_iter_recurse(iter_dict_val, &iter_array);
- array_len = dbus_message_iter_get_array_len(&iter_array);
- if (array_len < 0)
- return FALSE;
-
switch (array_type) {
case DBUS_TYPE_BYTE:
success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
- array_len,
array_type,
entry);
break;
case DBUS_TYPE_STRING:
success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
- array_len,
array_type,
entry);
break;
@@ -946,9 +960,17 @@ void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
break;
case DBUS_TYPE_ARRAY:
switch (entry->array_type) {
- case DBUS_TYPE_BYTE:
- free(entry->bytearray_value);
- break;
+ case DBUS_TYPE_BYTE: {
+ free(entry->bytearray_value);
+ break;
+ }
+ case DBUS_TYPE_STRING: {
+ unsigned int i;
+ for (i = 0; i < entry->array_len; i++)
+ free(entry->strarray_value[i]);
+ free(entry->strarray_value);
+ break;
+ }
}
break;
}
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_background.8 b/contrib/wpa_supplicant/doc/docbook/wpa_background.8
index 6244529..c62f5e0 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_background.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_background.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_BACKGROUND" "8" "19 February 2008" "" ""
+.TH "WPA_BACKGROUND" "8" "28 November 2008" "" ""
.SH NAME
wpa_background \- Background information on Wi-Fi Protected Access and IEEE 802.11i
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_cli.8 b/contrib/wpa_supplicant/doc/docbook/wpa_cli.8
index 0865264..43cc43d 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_cli.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_cli.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_CLI" "8" "19 February 2008" "" ""
+.TH "WPA_CLI" "8" "28 November 2008" "" ""
.SH NAME
wpa_cli \- WPA command line client
@@ -57,17 +57,18 @@ current network. <text> is description of the request. In
case of OTP request, it includes the challenge from the
authentication server.
.PP
-The reply to these requests can be given with 'identity',
-'password', and 'otp' commands. <id> needs to be copied from the
-the matching request. 'password' and 'otp' commands can be used
-regardless of whether the request was for PASSWORD or OTP. The
-main difference between these two commands is that values given
-with 'password' are remembered as long as wpa_supplicant is
-running whereas values given with 'otp' are used only once and
-then forgotten, i.e., wpa_supplicant will ask frontend for a new
-value for every use. This can be used to implement
-one-time-password lists and generic token card -based
-authentication.
+The reply to these requests can be given with
+\fBidentity\fR, \fBpassword\fR, and
+\fBotp\fR commands. <id> needs to be copied from
+the matching request. \fBpassword\fR and
+\fBotp\fR commands can be used regardless of whether
+the request was for PASSWORD or OTP. The main difference between these
+two commands is that values given with \fBpassword\fR are
+remembered as long as wpa_supplicant is running whereas values given
+with \fBotp\fR are used only once and then forgotten,
+i.e., wpa_supplicant will ask frontend for a new value for every use.
+This can be used to implement one-time-password lists and generic token
+card -based authentication.
.PP
Example request for password and a matching reply:
.sp
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml b/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml
index 8430599..ade0362 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml
@@ -72,17 +72,18 @@
case of OTP request, it includes the challenge from the
authentication server.</para>
- <para>The reply to these requests can be given with 'identity',
- 'password', and 'otp' commands. &lt;id&gt; needs to be copied from the
- the matching request. 'password' and 'otp' commands can be used
- regardless of whether the request was for PASSWORD or OTP. The
- main difference between these two commands is that values given
- with 'password' are remembered as long as wpa_supplicant is
- running whereas values given with 'otp' are used only once and
- then forgotten, i.e., wpa_supplicant will ask frontend for a new
- value for every use. This can be used to implement
- one-time-password lists and generic token card -based
- authentication.</para>
+ <para>The reply to these requests can be given with
+ <emphasis>identity</emphasis>, <emphasis>password</emphasis>, and
+ <emphasis>otp</emphasis> commands. &lt;id&gt; needs to be copied from
+ the matching request. <emphasis>password</emphasis> and
+ <emphasis>otp</emphasis> commands can be used regardless of whether
+ the request was for PASSWORD or OTP. The main difference between these
+ two commands is that values given with <emphasis>password</emphasis> are
+ remembered as long as wpa_supplicant is running whereas values given
+ with <emphasis>otp</emphasis> are used only once and then forgotten,
+ i.e., wpa_supplicant will ask frontend for a new value for every use.
+ This can be used to implement one-time-password lists and generic token
+ card -based authentication.</para>
<para>Example request for password and a matching reply:</para>
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8 b/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8
index a0f5c70..52faebb 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_PASSPHRASE" "8" "19 February 2008" "" ""
+.TH "WPA_PASSPHRASE" "8" "28 November 2008" "" ""
.SH NAME
wpa_passphrase \- Generate a WPA PSK from an ASCII passphrase for a SSID
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8 b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8
index 1a5697d..e7d8406 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_SUPPLICANT" "8" "19 February 2008" "" ""
+.TH "WPA_SUPPLICANT" "8" "28 November 2008" "" ""
.SH NAME
wpa_supplicant \- Wi-Fi Protected Access client and IEEE 802.1X supplicant
@@ -214,7 +214,11 @@ PMKSA caching
.RE
.SH "AVAILABLE DRIVERS"
.PP
-The available drivers to specify with the -D option are:
+A summary of available driver backends is below. Support for each
+of the driver backends is chosen at wpa_supplicant compile time. For a
+list of supported driver backends that may be used with the -D option on
+your system, refer to the help output of wpa_supplicant
+(\fBwpa_supplicant -h\fR).
.TP
\fBhostap\fR
(default) Host AP driver (Intersil Prism2/2.5/3).
@@ -250,33 +254,47 @@ BSD 802.11 support (Atheros, etc.).
\fBndis\fR
Windows NDIS driver.
.SH "COMMAND LINE OPTIONS"
+.PP
+Most command line options have global scope. Some are given per
+interface, and are only valid if at least one \fB-i\fR option
+is specified, otherwise they're ignored. Option groups for different
+interfaces must be separated by \fB-N\fR option.
+.TP
+\fB-b br_ifname\fR
+Optional bridge interface name. (Per interface)
.TP
\fB-B\fR
Run daemon in the background.
.TP
\fB-i ifname\fR
-Interface to listen on.
+Interface to listen on. Multiple instances of this option can
+be present, one per interface, separated by \fB-N\fR
+option (see below).
.TP
\fB-c filename\fR
-Path to configuration file.
+Path to configuration file. (Per interface)
.TP
\fB-P PID_file\fR
Path to PID file.
.TP
\fB-C ctrl_interface\fR
-Path to ctrl_interface socket (only used if -c is not).
+Path to ctrl_interface socket (Per interface. Only used if
+\fB-c\fR is not).
.TP
\fB-g global ctrl_interface\fR
-Path to global ctrl_interface socket.
+Path to global ctrl_interface socket. If specified, interface
+definitions may be omitted.
.TP
\fB-D driver\fR
-Driver to use. See the available options below.
+Driver to use. (Per interface, see the available options
+below.)
.TP
\fB-f output file\fR
Log output to specified file instead of stdout.
.TP
\fB-d\fR
-Increase debugging verbosity (-dd even more).
+Increase debugging verbosity (\fB-dd\fR even
+more).
.TP
\fB-K\fR
Include keys (passwords, etc.) in debug output.
@@ -296,7 +314,12 @@ Help. Show a usage message.
Show license (GPL and BSD).
.TP
\fB-q\fR
-Decrease debugging verbosity (-qq even less).
+Decrease debugging verbosity (\fB-qq\fR even
+less).
+.TP
+\fB-u\fR
+Enabled DBus control interface. If enabled, interface
+definitions may be omitted.
.TP
\fB-v\fR
Show version.
@@ -367,9 +390,9 @@ with other versions)
.TP
\fBHost AP driver for Prism2/2.5/3 (development snapshot/v0.2.x)\fR
(http://hostap.epitest.fi/) Driver needs to be set in
-Managed mode ('iwconfig wlan0 mode managed'). Please note
-that station firmware version needs to be 1.7.0 or newer to
-work in WPA mode.
+Managed mode (\fBiwconfig wlan0 mode managed\fR).
+Please note that station firmware version needs to be 1.7.0 or
+newer to work in WPA mode.
.TP
\fBLinuxant DriverLoader\fR
(http://www.linuxant.com/driverloader/)
@@ -506,8 +529,8 @@ can be used to enable WPA support:
Add MODE="Managed" and WPA="y" to the network scheme in
\fI/etc/pcmcia/wireless.opts\fR\&.
.PP
-Add the following block to the end of 'start' action handler
-in \fI/etc/pcmcia/wireless\fR:
+Add the following block to the end of \fBstart\fR
+action handler in \fI/etc/pcmcia/wireless\fR:
.sp
.RS
@@ -519,8 +542,8 @@ fi
.fi
.RE
.PP
-Add the following block to the end of 'stop' action handler
-(may need to be separated from other actions) in
+Add the following block to the end of \fBstop\fR
+action handler (may need to be separated from other actions) in
\fI/etc/pcmcia/wireless\fR:
.sp
.RS
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
index efe17cc..494b8a2 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_SUPPLICANT.CONF" "5" "19 February 2008" "" ""
+.TH "WPA_SUPPLICANT.CONF" "5" "28 November 2008" "" ""
.SH NAME
wpa_supplicant.conf \- configuration file for wpa_supplicant
@@ -24,7 +24,7 @@ run in the background.
Changes to configuration file can be reloaded be sending
SIGHUP signal to \fBwpa_supplicant\fR ('killall -HUP
wpa_supplicant'). Similarly, reloading can be triggered with
-the 'wpa_cli reconfigure' command.
+the \fBwpa_cli reconfigure\fR command.
.PP
Configuration file can include one or more network blocks,
e.g., one for each used SSID. wpa_supplicant will automatically
@@ -179,7 +179,7 @@ network={
.TP 3
6.
Authentication for wired Ethernet. This can be used with
-'wired' interface (-Dwired on command line).
+\fBwired\fR interface (-Dwired on command line).
.sp
.RS
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
index 082509c..063e882 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
@@ -26,7 +26,7 @@
<para>Changes to configuration file can be reloaded be sending
SIGHUP signal to <command>wpa_supplicant</command> ('killall -HUP
wpa_supplicant'). Similarly, reloading can be triggered with
- the 'wpa_cli reconfigure' command.</para>
+ the <emphasis>wpa_cli reconfigure</emphasis> command.</para>
<para>Configuration file can include one or more network blocks,
e.g., one for each used SSID. wpa_supplicant will automatically
@@ -179,7 +179,7 @@ network={
<listitem>
<para>Authentication for wired Ethernet. This can be used with
- 'wired' interface (-Dwired on command line).</para>
+ <emphasis>wired</emphasis> interface (-Dwired on command line).</para>
<blockquote><programlisting>
ctrl_interface=/var/run/wpa_supplicant
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index b46d13c..ad570ba 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -241,7 +241,11 @@
<refsect1>
<title>Available Drivers</title>
- <para>The available drivers to specify with the -D option are:</para>
+ <para>A summary of available driver backends is below. Support for each
+ of the driver backends is chosen at wpa_supplicant compile time. For a
+ list of supported driver backends that may be used with the -D option on
+ your system, refer to the help output of wpa_supplicant
+ (<emphasis>wpa_supplicant -h</emphasis>).</para>
<variablelist>
<varlistentry>
@@ -326,8 +330,19 @@
<refsect1>
<title>Command Line Options</title>
+ <para>Most command line options have global scope. Some are given per
+ interface, and are only valid if at least one <option>-i</option> option
+ is specified, otherwise they're ignored. Option groups for different
+ interfaces must be separated by <option>-N</option> option.</para>
<variablelist>
<varlistentry>
+ <term>-b br_ifname</term>
+ <listitem>
+ <para>Optional bridge interface name. (Per interface)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-B</term>
<listitem>
<para>Run daemon in the background.</para>
@@ -337,14 +352,16 @@
<varlistentry>
<term>-i ifname</term>
<listitem>
- <para>Interface to listen on.</para>
+ <para>Interface to listen on. Multiple instances of this option can
+ be present, one per interface, separated by <option>-N</option>
+ option (see below).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-c filename</term>
<listitem>
- <para>Path to configuration file.</para>
+ <para>Path to configuration file. (Per interface)</para>
</listitem>
</varlistentry>
@@ -358,21 +375,24 @@
<varlistentry>
<term>-C ctrl_interface</term>
<listitem>
- <para>Path to ctrl_interface socket (only used if -c is not).</para>
+ <para>Path to ctrl_interface socket (Per interface. Only used if
+ <option>-c</option> is not).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-g global ctrl_interface</term>
<listitem>
- <para>Path to global ctrl_interface socket.</para>
+ <para>Path to global ctrl_interface socket. If specified, interface
+ definitions may be omitted.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-D driver</term>
<listitem>
- <para>Driver to use. See the available options below.</para>
+ <para>Driver to use. (Per interface, see the available options
+ below.)</para>
</listitem>
</varlistentry>
@@ -386,7 +406,8 @@
<varlistentry>
<term>-d</term>
<listitem>
- <para>Increase debugging verbosity (-dd even more).</para>
+ <para>Increase debugging verbosity (<option>-dd</option> even
+ more).</para>
</listitem>
</varlistentry>
@@ -430,9 +451,19 @@
<varlistentry>
<term>-q</term>
<listitem>
- <para>Decrease debugging verbosity (-qq even less).</para>
+ <para>Decrease debugging verbosity (<option>-qq</option> even
+ less).</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>-u</term>
+ <listitem>
+ <para>Enabled DBus control interface. If enabled, interface
+ definitions may be omitted.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>-v</term>
<listitem>
@@ -523,9 +554,9 @@ wpa_supplicant \
snapshot/v0.2.x)</term>
<listitem>
<para> (http://hostap.epitest.fi/) Driver needs to be set in
- Managed mode ('iwconfig wlan0 mode managed'). Please note
- that station firmware version needs to be 1.7.0 or newer to
- work in WPA mode.</para>
+ Managed mode (<emphasis>iwconfig wlan0 mode managed</emphasis>).
+ Please note that station firmware version needs to be 1.7.0 or
+ newer to work in WPA mode.</para>
</listitem>
</varlistentry>
@@ -729,8 +760,8 @@ wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B
<para>Add MODE="Managed" and WPA="y" to the network scheme in
<filename>/etc/pcmcia/wireless.opts</filename>.</para>
- <para>Add the following block to the end of 'start' action handler
- in <filename>/etc/pcmcia/wireless</filename>:</para>
+ <para>Add the following block to the end of <emphasis>start</emphasis>
+ action handler in <filename>/etc/pcmcia/wireless</filename>:</para>
<blockquote><programlisting>
if [ "$WPA" = "y" -a -x /usr/local/bin/wpa_supplicant ]; then
@@ -739,8 +770,8 @@ fi
</programlisting></blockquote>
- <para>Add the following block to the end of 'stop' action handler
- (may need to be separated from other actions) in
+ <para>Add the following block to the end of <emphasis>stop</emphasis>
+ action handler (may need to be separated from other actions) in
<filename>/etc/pcmcia/wireless</filename>:</para>
<blockquote><programlisting>
diff --git a/contrib/wpa_supplicant/driver_ndis.c b/contrib/wpa_supplicant/driver_ndis.c
index 570b4ca..de34306 100644
--- a/contrib/wpa_supplicant/driver_ndis.c
+++ b/contrib/wpa_supplicant/driver_ndis.c
@@ -42,7 +42,9 @@ int close(int fd);
#include "driver_ndis.h"
int wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv);
+#ifdef CONFIG_NDIS_EVENTS_INTEGRATED
void wpa_driver_ndis_event_pipe_cb(void *eloop_data, void *user_data);
+#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */
static void wpa_driver_ndis_deinit(void *priv);
static void wpa_driver_ndis_poll(void *drv);
diff --git a/contrib/wpa_supplicant/eap.c b/contrib/wpa_supplicant/eap.c
index a5cd982..8021e80 100644
--- a/contrib/wpa_supplicant/eap.c
+++ b/contrib/wpa_supplicant/eap.c
@@ -892,7 +892,7 @@ static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
#endif /* PCSC_FUNCS */
-static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
+static int eap_sm_set_scard_pin(struct eap_sm *sm, struct wpa_ssid *ssid)
{
#ifdef PCSC_FUNCS
if (scard_set_pin(sm->scard_ctx, ssid->pin)) {
@@ -907,6 +907,17 @@ static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
eap_sm_request_pin(sm);
return -1;
}
+ return 0;
+#else /* PCSC_FUNCS */
+ return -1;
+#endif /* PCSC_FUNCS */
+}
+
+static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
+{
+#ifdef PCSC_FUNCS
+ if (eap_sm_set_scard_pin(sm, ssid))
+ return -1;
return eap_sm_imsi_identity(sm, ssid);
#else /* PCSC_FUNCS */
@@ -973,6 +984,9 @@ u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
eap_sm_request_identity(sm);
return NULL;
}
+ } else if (config->pcsc) {
+ if (eap_sm_set_scard_pin(sm, config) < 0)
+ return NULL;
}
*len = sizeof(struct eap_hdr) + 1 + identity_len;
diff --git a/contrib/wpa_supplicant/eap_aka.c b/contrib/wpa_supplicant/eap_aka.c
index a8b56ca..daf7722 100644
--- a/contrib/wpa_supplicant/eap_aka.c
+++ b/contrib/wpa_supplicant/eap_aka.c
@@ -292,7 +292,7 @@ static u8 * eap_aka_response_challenge(struct eap_aka_data *data,
msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE);
wpa_printf(MSG_DEBUG, " AT_RES");
- eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len,
+ eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
data->res, data->res_len);
wpa_printf(MSG_DEBUG, " AT_MAC");
eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
diff --git a/contrib/wpa_supplicant/eap_gpsk.c b/contrib/wpa_supplicant/eap_gpsk.c
index 81b03ed..a9af85c 100644
--- a/contrib/wpa_supplicant/eap_gpsk.c
+++ b/contrib/wpa_supplicant/eap_gpsk.c
@@ -240,8 +240,8 @@ const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm,
return NULL;
}
if (*list_len == 0 || (*list_len % sizeof(struct eap_gpsk_csuite))) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %d",
- *list_len);
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %lu",
+ (unsigned long) *list_len);
return NULL;
}
*list = pos;
@@ -460,6 +460,7 @@ const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data,
data->id_server, data->id_server_len);
wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3",
pos, len);
+ return NULL;
}
pos += len;
@@ -537,7 +538,9 @@ const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data,
miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
if (end - pos < (int) miclen) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
- "(left=%d miclen=%d)", end - pos, miclen);
+ "(left=%lu miclen=%lu)",
+ (unsigned long) (end - pos),
+ (unsigned long) miclen);
return NULL;
}
if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
@@ -589,8 +592,9 @@ static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
return NULL;
}
if (pos != end) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %d bytes of extra "
- "data in the end of GPSK-2", end - pos);
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
+ "data in the end of GPSK-2",
+ (unsigned long) (end - pos));
}
req = (const struct eap_hdr *) reqData;
diff --git a/contrib/wpa_supplicant/eap_gpsk_common.c b/contrib/wpa_supplicant/eap_gpsk_common.c
index 7422fa6..ec97a56 100644
--- a/contrib/wpa_supplicant/eap_gpsk_common.c
+++ b/contrib/wpa_supplicant/eap_gpsk_common.c
@@ -376,8 +376,8 @@ static int eap_gpsk_compute_mic_aes(const u8 *sk, size_t sk_len,
const u8 *data, size_t len, u8 *mic)
{
if (sk_len != 16) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid SK length %d for "
- "AES-CMAC MIC", sk_len);
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid SK length %lu for "
+ "AES-CMAC MIC", (unsigned long) sk_len);
return -1;
}
diff --git a/contrib/wpa_supplicant/eap_ttls.c b/contrib/wpa_supplicant/eap_ttls.c
index ca006943..bdffed4 100644
--- a/contrib/wpa_supplicant/eap_ttls.c
+++ b/contrib/wpa_supplicant/eap_ttls.c
@@ -673,7 +673,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
/* MS-CHAP-Challenge */
challenge = eap_ttls_implicit_challenge(
- sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN * 2 + 1);
+ sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
if (challenge == NULL) {
os_free(buf);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
@@ -777,7 +777,8 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
config->identity, config->identity_len);
/* MS-CHAP-Challenge */
- challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
+ challenge = eap_ttls_implicit_challenge(
+ sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
if (challenge == NULL) {
os_free(buf);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
@@ -907,7 +908,8 @@ static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
config->identity, config->identity_len);
/* CHAP-Challenge */
- challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
+ challenge = eap_ttls_implicit_challenge(
+ sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
if (challenge == NULL) {
os_free(buf);
wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
diff --git a/contrib/wpa_supplicant/eloop.c b/contrib/wpa_supplicant/eloop.c
index 232e753..9cac792 100644
--- a/contrib/wpa_supplicant/eloop.c
+++ b/contrib/wpa_supplicant/eloop.c
@@ -232,7 +232,10 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
timeout = os_malloc(sizeof(*timeout));
if (timeout == NULL)
return -1;
- os_get_time(&timeout->time);
+ if (os_get_time(&timeout->time) < 0) {
+ os_free(timeout);
+ return -1;
+ }
timeout->time.sec += secs;
timeout->time.usec += usecs;
while (timeout->time.usec >= 1000000) {
@@ -302,6 +305,25 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
}
+int eloop_is_timeout_registered(eloop_timeout_handler handler,
+ void *eloop_data, void *user_data)
+{
+ struct eloop_timeout *tmp;
+
+ tmp = eloop.timeout;
+ while (tmp != NULL) {
+ if (tmp->handler == handler &&
+ tmp->eloop_data == eloop_data &&
+ tmp->user_data == user_data)
+ return 1;
+
+ tmp = tmp->next;
+ }
+
+ return 0;
+}
+
+
#ifndef CONFIG_NATIVE_WINDOWS
static void eloop_handle_alarm(int sig)
{
diff --git a/contrib/wpa_supplicant/eloop.h b/contrib/wpa_supplicant/eloop.h
index 4dd2871..cf83f38 100644
--- a/contrib/wpa_supplicant/eloop.h
+++ b/contrib/wpa_supplicant/eloop.h
@@ -207,6 +207,19 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
void *eloop_data, void *user_data);
/**
+ * eloop_is_timeout_registered - Check if a timeout is already registered
+ * @handler: Matching callback function
+ * @eloop_data: Matching eloop_data
+ * @user_data: Matching user_data
+ * Returns: 1 if the timeout is registered, 0 if the timeout is not registered
+ *
+ * Determine if a matching <handler,eloop_data,user_data> timeout is registered
+ * with eloop_register_timeout().
+ */
+int eloop_is_timeout_registered(eloop_timeout_handler handler,
+ void *eloop_data, void *user_data);
+
+/**
* eloop_register_signal - Register handler for signals
* @sig: Signal number (e.g., SIGHUP)
* @handler: Callback function to be called when the signal is received
diff --git a/contrib/wpa_supplicant/eloop_none.c b/contrib/wpa_supplicant/eloop_none.c
index 6943109..215030b 100644
--- a/contrib/wpa_supplicant/eloop_none.c
+++ b/contrib/wpa_supplicant/eloop_none.c
@@ -197,6 +197,26 @@ int eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx),
}
+int eloop_is_timeout_registered(void (*handler)(void *eloop_ctx,
+ void *timeout_ctx),
+ void *eloop_data, void *user_data)
+{
+ struct eloop_timeout *tmp;
+
+ tmp = eloop.timeout;
+ while (tmp != NULL) {
+ if (tmp->handler == handler &&
+ tmp->eloop_data == eloop_data &&
+ tmp->user_data == user_data)
+ return 1;
+
+ tmp = tmp->next;
+ }
+
+ return 0;
+}
+
+
/* TODO: replace with suitable signal handler */
#if 0
static void eloop_handle_signal(int sig)
diff --git a/contrib/wpa_supplicant/mlme.c b/contrib/wpa_supplicant/mlme.c
index 92b5959..e618e2a 100644
--- a/contrib/wpa_supplicant/mlme.c
+++ b/contrib/wpa_supplicant/mlme.c
@@ -985,8 +985,6 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
supp_rates[1] = 0;
for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) {
struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i];
- if (!(rate->flags & WPA_RATE_SUPPORTED))
- continue;
if (esupp_rates) {
pos = buf + len;
len++;
@@ -996,6 +994,7 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
esupp_rates[1] = 1;
pos = &esupp_rates[2];
+ len += 3;
} else {
pos = buf + len;
len++;
diff --git a/contrib/wpa_supplicant/os_unix.c b/contrib/wpa_supplicant/os_unix.c
index 69ba25a..7e3ab4a 100644
--- a/contrib/wpa_supplicant/os_unix.c
+++ b/contrib/wpa_supplicant/os_unix.c
@@ -216,7 +216,12 @@ char * os_readfile(const char *name, size_t *len)
return NULL;
}
- fread(buf, 1, *len, f);
+ if (fread(buf, 1, *len, f) != *len) {
+ fclose(f);
+ free(buf);
+ return NULL;
+ }
+
fclose(f);
return buf;
diff --git a/contrib/wpa_supplicant/preauth_test.c b/contrib/wpa_supplicant/preauth_test.c
index bd31d8b..6758d9e 100644
--- a/contrib/wpa_supplicant/preauth_test.c
+++ b/contrib/wpa_supplicant/preauth_test.c
@@ -44,12 +44,6 @@ struct preauth_test_data {
};
-static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
-{
- wpa_supplicant_req_scan(wpa_s, sec, usec);
-}
-
-
static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
{
wpa_supplicant_disassociate(wpa_s, reason_code);
@@ -254,7 +248,6 @@ static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname)
ctx->ctx = wpa_s;
ctx->set_state = _wpa_supplicant_set_state;
ctx->get_state = _wpa_supplicant_get_state;
- ctx->req_scan = _wpa_supplicant_req_scan;
ctx->deauthenticate = _wpa_supplicant_deauthenticate;
ctx->disassociate = _wpa_supplicant_disassociate;
ctx->set_key = wpa_supplicant_set_key;
diff --git a/contrib/wpa_supplicant/radius.c b/contrib/wpa_supplicant/radius.c
index 743f340..afa4f93 100644
--- a/contrib/wpa_supplicant/radius.c
+++ b/contrib/wpa_supplicant/radius.c
@@ -801,6 +801,7 @@ static u8 * decrypt_ms_key(const u8 *key, size_t len,
ppos = plain = os_malloc(plen);
if (plain == NULL)
return NULL;
+ plain[0] = 0;
while (left > 0) {
/* b(1) = MD5(Secret + Request-Authenticator + Salt)
@@ -825,7 +826,7 @@ static u8 * decrypt_ms_key(const u8 *key, size_t len,
left -= MD5_MAC_LEN;
}
- if (plain[0] > plen - 1) {
+ if (plain[0] == 0 || plain[0] > plen - 1) {
printf("Failed to decrypt MPPE key\n");
os_free(plain);
return NULL;
diff --git a/contrib/wpa_supplicant/sha1.c b/contrib/wpa_supplicant/sha1.c
index 194db16..e53c845 100644
--- a/contrib/wpa_supplicant/sha1.c
+++ b/contrib/wpa_supplicant/sha1.c
@@ -265,6 +265,10 @@ int tls_prf(const u8 *secret, size_t secret_len, const char *label,
L_S1 = L_S2 = (secret_len + 1) / 2;
S1 = secret;
S2 = secret + L_S1;
+ if (secret_len & 1) {
+ /* The last byte of S1 will be shared with S2 */
+ S2--;
+ }
hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
diff --git a/contrib/wpa_supplicant/tls_openssl.c b/contrib/wpa_supplicant/tls_openssl.c
index d5aafaa..cb6b974 100644
--- a/contrib/wpa_supplicant/tls_openssl.c
+++ b/contrib/wpa_supplicant/tls_openssl.c
@@ -871,6 +871,7 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
{
SSL_CTX *ssl = ssl_ctx;
struct tls_connection *conn;
+ long options;
conn = os_zalloc(sizeof(*conn));
if (conn == NULL)
@@ -884,9 +885,12 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
}
SSL_set_app_data(conn->ssl, conn);
- SSL_set_options(conn->ssl,
- SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
- SSL_OP_SINGLE_DH_USE);
+ options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
+ SSL_OP_SINGLE_DH_USE;
+#ifdef SSL_OP_NO_COMPRESSION
+ options |= SSL_OP_NO_COMPRESSION;
+#endif /* SSL_OP_NO_COMPRESSION */
+ SSL_set_options(conn->ssl, options);
conn->ssl_in = BIO_new(BIO_s_mem());
if (!conn->ssl_in) {
diff --git a/contrib/wpa_supplicant/version.h b/contrib/wpa_supplicant/version.h
index 364d8ae..fa00fcc 100644
--- a/contrib/wpa_supplicant/version.h
+++ b/contrib/wpa_supplicant/version.h
@@ -1,6 +1,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define VERSION_STR "0.5.10"
+#define VERSION_STR "0.5.11"
#endif /* VERSION_H */
diff --git a/contrib/wpa_supplicant/wpa.c b/contrib/wpa_supplicant/wpa.c
index 5669e6a..7ef746a 100644
--- a/contrib/wpa_supplicant/wpa.c
+++ b/contrib/wpa_supplicant/wpa.c
@@ -65,8 +65,7 @@ static const u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
struct wpa_ie_hdr {
u8 elem_id;
u8 len;
- u8 oui[3];
- u8 oui_type;
+ u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */
u8 version[2];
} STRUCT_PACKED;
@@ -1406,7 +1405,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
"caching attempt");
sm->cur_pmksa = NULL;
abort_cached = 1;
- } else {
+ } else if (!abort_cached) {
return -1;
}
}
@@ -1567,7 +1566,6 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
wpa_cipher_txt(sm->pairwise_cipher),
wpa_cipher_txt(sm->group_cipher));
- eloop_cancel_timeout(sm->ctx->scan, sm->ctx->ctx, NULL);
wpa_sm_cancel_auth_timeout(sm);
wpa_sm_set_state(sm, WPA_COMPLETED);
@@ -1904,7 +1902,6 @@ static void wpa_report_ie_mismatch(struct wpa_sm *sm,
}
wpa_sm_disassociate(sm, REASON_IE_IN_4WAY_DIFFERS);
- wpa_sm_req_scan(sm, 0, 0);
}
@@ -3798,7 +3795,6 @@ static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
os_memset(sm->pmk, 0, sizeof(sm->pmk));
wpa_sm_deauthenticate(sm, REASON_UNSPECIFIED);
- wpa_sm_req_scan(sm, 0, 0);
}
}
diff --git a/contrib/wpa_supplicant/wpa.h b/contrib/wpa_supplicant/wpa.h
index df075c3..8a9ae76 100644
--- a/contrib/wpa_supplicant/wpa.h
+++ b/contrib/wpa_supplicant/wpa.h
@@ -59,7 +59,6 @@ struct wpa_sm_ctx {
void (*set_state)(void *ctx, wpa_states state);
wpa_states (*get_state)(void *ctx);
- void (*req_scan)(void *ctx, int sec, int usec);
void (*deauthenticate)(void * ctx, int reason_code);
void (*disassociate)(void *ctx, int reason_code);
int (*set_key)(void *ctx, wpa_alg alg,
diff --git a/contrib/wpa_supplicant/wpa_cli.c b/contrib/wpa_supplicant/wpa_cli.c
index 7176c95..6c3a881 100644
--- a/contrib/wpa_supplicant/wpa_cli.c
+++ b/contrib/wpa_supplicant/wpa_cli.c
@@ -1081,6 +1081,7 @@ static int wpa_cli_exec(const char *program, const char *arg1,
{
char *cmd;
size_t len;
+ int ret = 0;
len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
cmd = os_malloc(len);
@@ -1089,11 +1090,12 @@ static int wpa_cli_exec(const char *program, const char *arg1,
os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
cmd[len - 1] = '\0';
#ifndef _WIN32_WCE
- system(cmd);
+ if (system(cmd) < 0)
+ ret = -1;
#endif /* _WIN32_WCE */
os_free(cmd);
- return 0;
+ return ret;
}
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp b/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
index 6ea35e0..b8e17ac 100644
--- a/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
+++ b/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
@@ -12,6 +12,7 @@
* See README and COPYING for more details.
*/
+#include <cstdio>
#include <QMessageBox>
#include "networkconfig.h"
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.cpp b/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
index 57cf716..75d1c51 100644
--- a/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
+++ b/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
@@ -14,6 +14,8 @@
#include <QTimer>
+#include <cstdio>
+
#include "scanresults.h"
#include "wpagui.h"
#include "networkconfig.h"
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
index 31cb38c..798786b 100644
--- a/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
+++ b/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
@@ -17,6 +17,7 @@
#include <unistd.h>
#endif
+#include <cstdio>
#include <QMessageBox>
#include "wpagui.h"
diff --git a/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h b/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h
index a3cd733..22afed9 100644
--- a/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h
+++ b/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h
@@ -10,6 +10,7 @@
** destructor.
*****************************************************************************/
+#include <stdlib.h>
enum {
AUTH_NONE = 0,
diff --git a/contrib/wpa_supplicant/wpa_gui/userdatarequest.ui.h b/contrib/wpa_supplicant/wpa_gui/userdatarequest.ui.h
index 4b47ccd..66d4478 100644
--- a/contrib/wpa_supplicant/wpa_gui/userdatarequest.ui.h
+++ b/contrib/wpa_supplicant/wpa_gui/userdatarequest.ui.h
@@ -10,6 +10,8 @@
** destructor.
*****************************************************************************/
+#include <stdlib.h>
+
int UserDataRequest::setParams(WpaGui *_wpagui, const char *reqMsg)
{
char *tmp, *pos, *pos2;
diff --git a/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h b/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h
index 6db8862..3f86c16 100644
--- a/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h
+++ b/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h
@@ -16,6 +16,7 @@
#include <unistd.h>
#endif
+#include <stdlib.h>
void WpaGui::init()
{
diff --git a/contrib/wpa_supplicant/wpa_i.h b/contrib/wpa_supplicant/wpa_i.h
index b5adb5e..d1cab4b 100644
--- a/contrib/wpa_supplicant/wpa_i.h
+++ b/contrib/wpa_supplicant/wpa_i.h
@@ -146,11 +146,6 @@ static inline wpa_states wpa_sm_get_state(struct wpa_sm *sm)
return sm->ctx->get_state(sm->ctx->ctx);
}
-static inline void wpa_sm_req_scan(struct wpa_sm *sm, int sec, int usec)
-{
- sm->ctx->req_scan(sm->ctx->ctx, sec, usec);
-}
-
static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, int reason_code)
{
sm->ctx->deauthenticate(sm->ctx->ctx, reason_code);
diff --git a/contrib/wpa_supplicant/wpa_supplicant.c b/contrib/wpa_supplicant/wpa_supplicant.c
index 95c8b1b..a795e4a 100644
--- a/contrib/wpa_supplicant/wpa_supplicant.c
+++ b/contrib/wpa_supplicant/wpa_supplicant.c
@@ -364,7 +364,6 @@ static void wpa_supplicant_notify_eapol_done(void *ctx)
if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
} else {
- eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
wpa_supplicant_cancel_auth_timeout(wpa_s);
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
}
@@ -492,6 +491,28 @@ void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
*/
void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
{
+ /* If there's at least one network that should be specifically scanned
+ * then don't cancel the scan and reschedule. Some drivers do
+ * background scanning which generates frequent scan results, and that
+ * causes the specific SSID scan to get continually pushed back and
+ * never happen, which causes hidden APs to never get probe-scanned.
+ */
+ if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) &&
+ wpa_s->conf->ap_scan == 1) {
+ struct wpa_ssid *ssid = wpa_s->conf->ssid;
+
+ while (ssid) {
+ if (!ssid->disabled && ssid->scan_ssid)
+ break;
+ ssid = ssid->next;
+ }
+ if (ssid) {
+ wpa_msg(wpa_s, MSG_DEBUG, "Not rescheduling scan to "
+ "ensure that specific SSID scans occur");
+ return;
+ }
+ }
+
wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
sec, usec);
eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
@@ -1051,6 +1072,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1) {
wpa_s->scan_res_tried++;
+ wpa_s->scan_req = scan_req;
wpa_printf(MSG_DEBUG, "Trying to get current scan results "
"first without requesting a new scan to speed up "
"initial association");
@@ -1521,13 +1543,15 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
} else {
/* Timeout for IEEE 802.11 authentication and association */
- int timeout;
- if (assoc_failed)
- timeout = 5;
- else if (wpa_s->conf->ap_scan == 1)
- timeout = 10;
- else
- timeout = 60;
+ int timeout = 60;
+
+ if (assoc_failed) {
+ /* give IBSS a bit more time */
+ timeout = ssid->mode ? 10 : 5;
+ } else if (wpa_s->conf->ap_scan == 1) {
+ /* give IBSS a bit more time */
+ timeout = ssid->mode ? 20 : 10;
+ }
wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
}
@@ -1797,12 +1821,6 @@ static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
}
-static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
-{
- wpa_supplicant_req_scan(wpa_s, sec, usec);
-}
-
-
static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
{
wpa_supplicant_cancel_auth_timeout(wpa_s);
@@ -1824,12 +1842,16 @@ static wpa_states _wpa_supplicant_get_state(void *wpa_s)
static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
{
wpa_supplicant_disassociate(wpa_s, reason_code);
+ /* Schedule a scan to make sure we continue looking for networks */
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
}
static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
{
wpa_supplicant_deauthenticate(wpa_s, reason_code);
+ /* Schedule a scan to make sure we continue looking for networks */
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
}
@@ -2207,7 +2229,6 @@ static int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
ctx->ctx = wpa_s;
ctx->set_state = _wpa_supplicant_set_state;
ctx->get_state = _wpa_supplicant_get_state;
- ctx->req_scan = _wpa_supplicant_req_scan;
ctx->deauthenticate = _wpa_supplicant_deauthenticate;
ctx->disassociate = _wpa_supplicant_disassociate;
ctx->set_key = wpa_supplicant_set_key;
diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c
index 7858aee..4af171d 100644
--- a/crypto/openssl/apps/speed.c
+++ b/crypto/openssl/apps/speed.c
@@ -2038,7 +2038,7 @@ int MAIN(int argc, char **argv)
{
ret=RSA_verify(NID_md5_sha1, buf,36, buf2,
rsa_num, rsa_key[j]);
- if (ret == 0)
+ if (ret <= 0)
{
BIO_printf(bio_err,
"RSA verify failure\n");
diff --git a/crypto/openssl/apps/spkac.c b/crypto/openssl/apps/spkac.c
index 0191d0a..01fe406 100644
--- a/crypto/openssl/apps/spkac.c
+++ b/crypto/openssl/apps/spkac.c
@@ -285,7 +285,7 @@ bad:
pkey = NETSCAPE_SPKI_get_pubkey(spki);
if(verify) {
i = NETSCAPE_SPKI_verify(spki, pkey);
- if(i) BIO_printf(bio_err, "Signature OK\n");
+ if (i > 0) BIO_printf(bio_err, "Signature OK\n");
else {
BIO_printf(bio_err, "Signature Failure\n");
ERR_print_errors(bio_err);
diff --git a/crypto/openssl/apps/verify.c b/crypto/openssl/apps/verify.c
index 9ff32cb..20cc9e3 100644
--- a/crypto/openssl/apps/verify.c
+++ b/crypto/openssl/apps/verify.c
@@ -266,7 +266,7 @@ static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X
ret=0;
end:
- if (i)
+ if (i > 0)
{
fprintf(stdout,"OK\n");
ret=1;
@@ -367,4 +367,3 @@ static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
ERR_clear_error();
return(ok);
}
-
diff --git a/crypto/openssl/apps/x509.c b/crypto/openssl/apps/x509.c
index 5f61eb5..f0fa9d7 100644
--- a/crypto/openssl/apps/x509.c
+++ b/crypto/openssl/apps/x509.c
@@ -1144,7 +1144,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);
- if (!reqfile && !X509_verify_cert(&xsc))
+ if (!reqfile && X509_verify_cert(&xsc) <= 0)
goto end;
if (!X509_check_private_key(xca,pkey))
diff --git a/crypto/openssl/ssl/s2_clnt.c b/crypto/openssl/ssl/s2_clnt.c
index ce60de6..6c7ef68 100644
--- a/crypto/openssl/ssl/s2_clnt.c
+++ b/crypto/openssl/ssl/s2_clnt.c
@@ -1044,7 +1044,7 @@ int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
i=ssl_verify_cert_chain(s,sk);
- if ((s->verify_mode != SSL_VERIFY_NONE) && (!i))
+ if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
{
SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
goto err;
diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c
index 27d71a2..e2cba0b 100644
--- a/crypto/openssl/ssl/s2_srvr.c
+++ b/crypto/openssl/ssl/s2_srvr.c
@@ -1054,7 +1054,7 @@ static int request_certificate(SSL *s)
i=ssl_verify_cert_chain(s,sk);
- if (i) /* we like the packet, now check the chksum */
+ if (i > 0) /* we like the packet, now check the chksum */
{
EVP_MD_CTX ctx;
EVP_PKEY *pkey=NULL;
@@ -1083,7 +1083,7 @@ static int request_certificate(SSL *s)
EVP_PKEY_free(pkey);
EVP_MD_CTX_cleanup(&ctx);
- if (i)
+ if (i > 0)
{
if (s->session->peer != NULL)
X509_free(s->session->peer);
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index 278be82..e52e9ca 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -883,7 +883,7 @@ int ssl3_get_server_certificate(SSL *s)
}
i=ssl_verify_cert_chain(s,sk);
- if ((s->verify_mode != SSL_VERIFY_NONE) && (!i)
+ if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
#ifndef OPENSSL_NO_KRB5
&& (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK))
!= (SSL_aKRB5|SSL_kKRB5)
@@ -1368,7 +1368,7 @@ int ssl3_get_key_exchange(SSL *s)
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
- if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey))
+ if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
{
/* bad signature */
al=SSL_AD_DECRYPT_ERROR;
@@ -1386,7 +1386,7 @@ int ssl3_get_key_exchange(SSL *s)
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
- if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey))
+ if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
{
/* bad signature */
al=SSL_AD_DECRYPT_ERROR;
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index 9414cf0..38ab682 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -2481,7 +2481,7 @@ int ssl3_get_client_certificate(SSL *s)
else
{
i=ssl_verify_cert_chain(s,sk);
- if (!i)
+ if (i <= 0)
{
al=ssl_verify_alarm_type(s->verify_result);
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED);
diff --git a/crypto/openssl/ssl/ssltest.c b/crypto/openssl/ssl/ssltest.c
index 517657c0..41dafbb 100644
--- a/crypto/openssl/ssl/ssltest.c
+++ b/crypto/openssl/ssl/ssltest.c
@@ -2072,7 +2072,7 @@ static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
if (cb_arg->proxy_auth)
{
- if (ok)
+ if (ok > 0)
{
const char *cond_end = NULL;
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 9cd866a..47f1f52 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -101,7 +101,7 @@ nisdomainname="NO" # Set to NIS domain if using NIS (or NO).
dhclient_program="/sbin/dhclient" # Path to dhcp client program.
dhclient_flags="" # Extra flags to pass to dhcp client.
#dhclient_flags_fxp0="" # Extra dhclient flags for fxp0 only
-background_dhclient="NO" # Start dhcp client in the background.
+background_dhclient="YES" # Start dhcp client in the background.
#background_dhclient_fxp0="YES" # Start dhcp client on fxp0 in the background.
synchronous_dhclient="NO" # Start dhclient directly on configured
# interfaces during startup.
@@ -570,7 +570,7 @@ ldconfig_local_dirs="/usr/local/libdata/ldconfig"
ldconfig_local32_dirs="/usr/local/libdata/ldconfig32"
# Local directories with 32-bit compatibility ldconfig
# configuration files.
-kern_securelevel_enable="NO" # kernel security level (see init(8)),
+kern_securelevel_enable="NO" # kernel security level (see security(7))
kern_securelevel="-1" # range: -1..3 ; `-1' is the most insecure
# Note that setting securelevel to 0 will result
# in the system booting with securelevel set to 1, as
@@ -617,24 +617,27 @@ jail_sysvipc_allow="NO" # Allow SystemV IPC use from within a jail
# each jail, specified in jail_list, with the following variables.
# NOTES:
# - replace 'example' with the jail's name.
-# - except rootdir, hostname and ip, all of the following variables may be made
-# global jail variables if you don't specify a jail name (ie. jail_interface).
+# - except rootdir, hostname, ip and the _multi<n> addresses,
+# all of the following variables may be made global jail variables
+# if you don't specify a jail name (ie. jail_interface, jail_devfs_ruleset).
#
#jail_example_rootdir="/usr/jail/default" # Jail's root directory
#jail_example_hostname="default.domain.com" # Jail's hostname
-#jail_example_ip="192.168.0.10" # Jail's IP number
-#jail_example_interface="" # Interface to create the IP alias on
-#jail_example_fib="0" # routing table for setfib(1)
+#jail_example_interface="" # Jail's interface variable to create IP aliases on
+#jail_example_fib="0" # Routing table for setfib(1)
+#jail_example_ip="192.0.2.10,2001:db8::17" # Jail's primary IPv4 and IPv6 address
+#jail_example_ip_multi0="2001:db8::10" # and another IPv6 address
#jail_example_exec_start="/bin/sh /etc/rc" # command to execute in jail for starting
#jail_example_exec_afterstart0="/bin/sh command" # command to execute after the one for
# starting the jail. More than one can be
# specified using a trailing number
#jail_example_exec_stop="/bin/sh /etc/rc.shutdown" # command to execute in jail for stopping
#jail_example_devfs_enable="NO" # mount devfs in the jail
+#jail_example_devfs_ruleset="ruleset_name" # devfs ruleset to apply to jail -
+ # usually you want "devfsrules_jail".
#jail_example_fdescfs_enable="NO" # mount fdescfs in the jail
#jail_example_procfs_enable="NO" # mount procfs in jail
#jail_example_mount_enable="NO" # mount/umount jail's fs
-#jail_example_devfs_ruleset="ruleset_name" # devfs ruleset to apply to jail
#jail_example_fstab="" # fstab(5) for mount/umount
#jail_example_flags="-l -U root" # flags for jail(8)
diff --git a/etc/devd.conf b/etc/devd.conf
index 8dbf34b..f4f04ad 100644
--- a/etc/devd.conf
+++ b/etc/devd.conf
@@ -31,18 +31,17 @@ options {
# Configure the interface on attach. Due to a historical accident, this
# script is called pccard_ether.
#
+# NB: DETACH events are ignored; the kernel should handle all cleanup
+# (routes, arp cache) if you need to do something beware of races
+# against immediate create of a device w/ the same name; e.g.
+# ifconfig bridge0 destroy; ifconfig bridge0 create
+#
notify 0 {
match "system" "IFNET";
match "type" "ATTACH";
action "/etc/pccard_ether $subsystem start";
};
-notify 0 {
- match "system" "IFNET";
- match "type" "DETACH";
- action "/etc/pccard_ether $subsystem stop";
-};
-
#
# Try to start dhclient on Ethernet like interfaces when the link comes
# up. Only devices that are configured to support DHCP will actually
diff --git a/etc/network.subr b/etc/network.subr
index 06ca836..0a64f96 100644
--- a/etc/network.subr
+++ b/etc/network.subr
@@ -515,7 +515,9 @@ childif_create()
i=`ifconfig wlan create ${create_args}`
ifconfig $i name $child && cfg=0
fi
- ifn_start $child
+ if autoif $child; then
+ ifn_start $child
+ fi
done
return ${cfg}
diff --git a/etc/periodic/weekly/Makefile b/etc/periodic/weekly/Makefile
index 463520f..fb8cf72 100644
--- a/etc/periodic/weekly/Makefile
+++ b/etc/periodic/weekly/Makefile
@@ -16,7 +16,7 @@ FILES+= 320.whatis 330.catman
.endif
.if ${MK_PKGTOOLS} != "no"
-FLES+= 400.status-pkg
+FILES+= 400.status-pkg
.endif
.include <bsd.prog.mk>
diff --git a/etc/rc.d/defaultroute b/etc/rc.d/defaultroute
index 536cb42..4eb15dd 100755
--- a/etc/rc.d/defaultroute
+++ b/etc/rc.d/defaultroute
@@ -18,11 +18,21 @@ stop_cmd=":"
defaultroute_start()
{
- # Return without waiting if we don't have dhcp interfaces.
- # Once we can test that the link is actually up, we should
- # remove this test and always wait.
+ local output carrier nocarrier
+
+ # Return without waiting if we don't have dhcp interfaces or
+ # if none of the dhcp interfaces is plugged in.
dhcp_interfaces=`list_net_interfaces dhcp`
- [ -z "`list_net_interfaces dhcp`" ] && return
+ [ -z "${dhcp_interfaces}" ] && return
+ carrier=false
+ for _if in ${dhcp_interfaces}; do
+ output=`/sbin/ifconfig ${_if}`
+ nocarrier=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'`
+ [ -z "${nocarrier}" ] && carrier=true
+ done
+ if ! ${carrier}; then
+ return
+ fi
# Wait for a default route
delay=${if_up_delay}
diff --git a/etc/rc.d/jail b/etc/rc.d/jail
index 851bf3c..52b7944 100755
--- a/etc/rc.d/jail
+++ b/etc/rc.d/jail
@@ -39,7 +39,6 @@ init_variables()
_procdir="${_rootdir}/proc"
eval _hostname=\"\$jail_${_j}_hostname\"
eval _ip=\"\$jail_${_j}_ip\"
- eval _netmask=\"\${jail_${_j}_netmask:-255.255.255.255}\"
eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
eval _exec=\"\$jail_${_j}_exec\"
eval _exec_start=\"\${jail_${_j}_exec_start:-${jail_exec_start}}\"
@@ -94,7 +93,7 @@ init_variables()
debug "$_j mount enable: $_mount"
debug "$_j hostname: $_hostname"
debug "$_j ip: $_ip"
- debug "$_j netmask: $_netmask"
+ jail_show_addresses ${_j}
debug "$_j interface: $_interface"
debug "$_j fib: $_fib"
debug "$_j root: $_rootdir"
@@ -128,10 +127,6 @@ init_variables()
if [ -z "${_rootdir}" ]; then
err 3 "$name: No root directory has been defined for ${_j}"
fi
- if [ -z "${_ip}" ]; then
- err 3 "$name: No IP address has been defined for ${_j}"
- fi
-
}
# set_sysctl rc_knob mib msg
@@ -277,6 +272,208 @@ jail_mount_fstab()
mount -a -F "${_fstab}"
}
+# jail_show_addresses jail
+# Debug print the input for the given _multi aliases
+# for a jail for init_variables().
+#
+jail_show_addresses()
+{
+ local _j _type alias
+ _j="$1"
+ alias=0
+
+ if [ -z "${_j}" ]; then
+ warn "jail_show_addresses: you must specify a jail"
+ return
+ fi
+
+ while : ; do
+ eval _addr=\"\$jail_${_j}_ip_multi${alias}\"
+ if [ -n "${_addr}" ]; then
+ debug "${_j} ip_multi${alias}: $_addr"
+ alias=$((${alias} + 1))
+ else
+ break
+ fi
+ done
+}
+
+# jail_extract_address argument
+# The second argument is the string from one of the _ip
+# or the _multi variables. In case of a comma separated list
+# only one argument must be passed in at a time.
+# The function alters the _type, _iface, _addr and _mask variables.
+#
+jail_extract_address()
+{
+ local _i
+ _i=$1
+
+ if [ -z "${_i}" ]; then
+ warn "jail_extract_address: called without input"
+ return
+ fi
+
+ # Check if we have an interface prefix given and split into
+ # iFace and rest.
+ case "${_i}" in
+ *\|*) # ifN|.. prefix there
+ _iface=${_i%%|*}
+ _r=${_i##*|}
+ ;;
+ *) _iface=""
+ _r=${_i}
+ ;;
+ esac
+
+ # In case the IP has no interface given, check if we have a global one.
+ _iface=${_iface:-${_interface}}
+
+ # Set address, cut off any prefix/netmask/prefixlen.
+ _addr=${_r}
+ _addr=${_addr%%[/ ]*}
+
+ # Theoretically we can return here if interface is not set,
+ # as we only care about the _mask if we call ifconfig.
+ # This is not done because we may want to santize IP addresses
+ # based on _type later, and optionally change the type as well.
+
+ # Extract the prefix/netmask/prefixlen part by cutting off the address.
+ _mask=${_r}
+ _mask=`expr "${_mask}" : "${_addr}\(.*\)"`
+
+ # Identify type {inet,inet6}.
+ case "${_addr}" in
+ *\.*\.*\.*) _type="inet" ;;
+ *:*) _type="inet6" ;;
+ *) warn "jail_extract_address: type not identified"
+ ;;
+ esac
+
+ # Handle the special /netmask instead of /prefix or
+ # "netmask xxx" case for legacy IP.
+ # We do NOT support shortend class-full netmasks.
+ if [ "${_type}" = "inet" ]; then
+ case "${_mask}" in
+ /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;;
+ *) ;;
+ esac
+
+ # In case _mask is still not set use /32.
+ _mask=${_mask:-/32}
+
+ elif [ "${_type}" = "inet6" ]; then
+ # In case _maske is not set for IPv6, use /128.
+ _mask=${_mask:-/128}
+ fi
+}
+
+# jail_handle_ips_option {add,del} input
+# Handle a single argument imput which can be a comma separated
+# list of addresses (theoretically with an option interface and
+# prefix/netmask/prefixlen).
+#
+jail_handle_ips_option()
+{
+ local _x _action _type _i
+ _action=$1
+ _x=$2
+
+ if [ -z "${_x}" ]; then
+ # No IP given. This can happen for the primary address
+ # of each address family.
+ return
+ fi
+
+ # Loop, in case we find a comma separated list, we need to handle
+ # each argument on its own.
+ while [ ${#_x} -gt 0 ]; do
+ case "${_x}" in
+ *,*) # Extract the first argument and strip it off the list.
+ _i=`expr "${_x}" : '^\([^,]*\)'`
+ _x=`expr "${_x}" : "^[^,]*,\(.*\)"`
+ ;;
+ *) _i=${_x}
+ _x=""
+ ;;
+ esac
+
+ _type=""
+ _iface=""
+ _addr=""
+ _mask=""
+ jail_extract_address "${_i}"
+
+ # make sure we got an address.
+ case "${_addr}" in
+ "") continue ;;
+ *) ;;
+ esac
+
+ # Append address to list of addresses for the jail command.
+ case "${_addrl}" in
+ "") _addrl="${_addr}" ;;
+ *) _addrl="${_addrl},${_addr}" ;;
+ esac
+
+ # Configure interface alias if requested by a given interface
+ # and if we could correctly parse everything.
+ case "${_iface}" in
+ "") continue ;;
+ esac
+ case "${_type}" in
+ inet) ;;
+ inet6) ;;
+ *) warn "Could not determine address family. Not going" \
+ "to ${_action} address '${_addr}' for ${_jail}."
+ continue
+ ;;
+ esac
+ case "${_action}" in
+ add) ifconfig ${_iface} ${_type} ${_addr}${_mask} alias
+ ;;
+ del) # When removing the IP, ignore the _mask.
+ ifconfig ${_iface} ${_type} ${_addr} -alias
+ ;;
+ esac
+ done
+}
+
+# jail_ips {add,del}
+# Extract the comma separated list of addresses and return them
+# for the jail command.
+# Handle more than one address via the _multi option as well.
+# If an interface is given also add/remove an alias for the
+# address with an optional netmask.
+#
+jail_ips()
+{
+ local _action
+ _action=$1
+
+ case "${_action}" in
+ add) ;;
+ del) ;;
+ *) warn "jail_ips: invalid action '${_action}'"
+ return
+ ;;
+ esac
+
+ # Handle addresses.
+ jail_handle_ips_option ${_action} "${_ip}"
+ # Handle jail_xxx_ip_multi<N>
+ alias=0
+ while : ; do
+ eval _x=\"\$jail_${_jail}_ip_multi${alias}\"
+ case "${_x}" in
+ "") break ;;
+ *) jail_handle_ips_option ${_action} "${_x}"
+ alias=$((${alias} + 1))
+ ;;
+ esac
+ done
+}
+
jail_start()
{
echo -n 'Configuring jails:'
@@ -298,9 +495,8 @@ jail_start()
echo -n " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]"
continue;
fi
- if [ -n "${_interface}" ]; then
- ifconfig ${_interface} alias ${_ip} netmask ${_netmask}
- fi
+ _addrl=""
+ jail_ips "add"
if [ -n "${_fib}" ]; then
_setfib="setfib -F '${_fib}'"
else
@@ -360,7 +556,7 @@ jail_start()
fi
_tmp_jail=${_tmp_dir}/jail.$$
eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \
- ${_ip} ${_exec_start} > ${_tmp_jail} 2>&1
+ \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1
if [ "$?" -eq 0 ] ; then
_jail_id=$(head -1 ${_tmp_jail})
@@ -381,9 +577,7 @@ jail_start()
echo ${_jail_id} > /var/run/jail_${_jail}.id
else
jail_umount_fs
- if [ -n "${_interface}" ]; then
- ifconfig ${_interface} -alias ${_ip}
- fi
+ jail_ips "del"
echo " cannot start jail \"${_jail}\": "
tail +2 ${_tmp_jail}
fi
@@ -412,9 +606,7 @@ jail_stop()
jail_umount_fs
echo -n " $_hostname"
fi
- if [ -n "${_interface}" ]; then
- ifconfig ${_interface} -alias ${_ip}
- fi
+ jail_ips "del"
rm /var/run/jail_${_jail}.id
else
echo " cannot stop jail ${_jail}. No jail id in /var/run"
diff --git a/etc/rc.d/named b/etc/rc.d/named
index 4aedb04..e40a464 100755
--- a/etc/rc.d/named
+++ b/etc/rc.d/named
@@ -61,10 +61,23 @@ chroot_autoupdate()
# Mount a devfs in the chroot directory if needed
#
- umount ${named_chrootdir}/dev 2>/dev/null
- devfs_domount ${named_chrootdir}/dev devfsrules_hide_all
- devfs -m ${named_chrootdir}/dev rule apply path null unhide
- devfs -m ${named_chrootdir}/dev rule apply path random unhide
+ if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then
+ umount ${named_chrootdir}/dev 2>/dev/null
+ devfs_domount ${named_chrootdir}/dev devfsrules_hide_all
+ devfs -m ${named_chrootdir}/dev rule apply path null unhide
+ devfs -m ${named_chrootdir}/dev rule apply path random unhide
+ else
+ if [ -c ${named_chrootdir}/dev/null -a \
+ -c ${named_chrootdir}/dev/random ]; then
+ info "named chroot: using pre-mounted devfs."
+ else
+ err 1 "named chroot: devfs cannot be mounted from" \
+ "within a jail. Thus a chrooted named cannot" \
+ "be run from within a jail." \
+ "To run named without chrooting it, set" \
+ "named_chrootdir=\"\" in /etc/rc.conf."
+ fi
+ fi
# Copy and/or update key files to the chroot /etc
#
@@ -113,7 +126,12 @@ named_stop()
named_poststop()
{
if [ -n "${named_chrootdir}" -a -c ${named_chrootdir}/dev/null ]; then
- umount ${named_chrootdir}/dev 2>/dev/null || true
+ if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then
+ umount ${named_chrootdir}/dev 2>/dev/null || true
+ else
+ warn "named chroot:" \
+ "cannot unmount devfs from inside jail!"
+ fi
fi
}
diff --git a/etc/rc.shutdown b/etc/rc.shutdown
index ebe79d7..dc1ca13 100644
--- a/etc/rc.shutdown
+++ b/etc/rc.shutdown
@@ -98,7 +98,7 @@ done
# Terminate the background watchdog timer (if it is running)
#
if [ -n "$_rcshutdown_watchdog" ]; then
- kill -TERM $_rcshutdown_watchdog >/dev/null 2>&1
+ pkill -TERM -P $_rcshutdown_watchdog >/dev/null 2>&1
fi
# Insert other shutdown procedures here
diff --git a/etc/regdomain.xml b/etc/regdomain.xml
index 95e83bd..d75d4d7 100644
--- a/etc/regdomain.xml
+++ b/etc/regdomain.xml
@@ -190,6 +190,55 @@
</netband>
</rd>
+<!-- FCC4 is 2.4GHz FCC w/ Public Safety Band (PSB) -->
+
+<rd id="fcc4">
+ <name>FCC4</name>
+ <sku>0x12</sku>
+ <netband mode="11b">
+ <band>
+ <freqband ref="F1_2412_2462"/>
+ <maxpower>30</maxpower>
+ <flags>IEEE80211_CHAN_B</flags>
+ </band>
+ </netband>
+ <netband mode="11g">
+ <band>
+ <freqband ref="F1_2412_2462"/>
+ <maxpower>30</maxpower>
+ <flags>IEEE80211_CHAN_G</flags>
+ </band>
+ </netband>
+ <netband mode="11a">
+ <band>
+ <freqband ref="F1_4950_4980"/>
+ <maxpower>23</maxpower>
+ </band>
+ <band>
+ <freqband ref="F1_4945_4985_10"/>
+ <maxpower>27</maxpower>
+ </band>
+ <band>
+ <freqband ref="F1_4942_4987_5"/>
+ <maxpower>30</maxpower>
+ </band>
+ </netband>
+ <netband mode="11ng">
+ <band>
+ <freqband ref="F1_2412_2462"/>
+ <maxpower>30</maxpower>
+ <flags>IEEE80211_CHAN_G</flags>
+ <flags>IEEE80211_CHAN_HT20</flags>
+ </band>
+ <band>
+ <freqband ref="F1_2412_2462"/>
+ <maxpower>30</maxpower>
+ <flags>IEEE80211_CHAN_G</flags>
+ <flags>IEEE80211_CHAN_HT40</flags>
+ </band>
+ </netband>
+</rd>
+
<rd id="japan">
<name>JAPAN</name>
<sku>0x40</sku>
@@ -1084,7 +1133,6 @@
<rd id="sr9">
<name>SR9</name>
<sku>0x0298</sku>
- <defcc ref="SR9"/>
<netband mode="11g">
<band>
<freqband ref="S1_907_922_5"/>
@@ -1107,20 +1155,19 @@
<rd id="xr9">
<name>XR9</name>
<sku>0x299</sku>
- <defcc ref="XR9"/>
<netband mode="11g">
<band>
- <freqband ref="S2_907_922_5"/>
+ <freqband ref="S1_907_922_5"/>
<maxpower>30</maxpower>
<flags>IEEE80211_CHAN_G</flags>
</band>
<band>
- <freqband ref="S2_907_922_10"/>
+ <freqband ref="S1_907_922_10"/>
<maxpower>30</maxpower>
<flags>IEEE80211_CHAN_G</flags>
</band>
<band>
- <freqband ref="S2_912_917"/>
+ <freqband ref="S1_912_917"/>
<maxpower>30</maxpower>
<flags>IEEE80211_CHAN_G</flags>
</band>
@@ -1130,7 +1177,6 @@
<rd id="gz901">
<name>GZ901</name>
<sku>0x29a</sku>
- <defcc ref="GZ901"/>
<netband mode="11g">
<band>
<freqband ref="S1_908_923_5"/>
@@ -1270,9 +1316,6 @@
<country id="GT">
<isocc>320</isocc> <name>Guatemala</name> <rd ref="none"/>
</country>
-<country id="GZ901">
- <isocc>5002</isocc> <name>ZComax GZ-901</name> <rd ref="gz901"/>
-</country>
<country id="HN">
<isocc>340</isocc> <name>Honduras</name> <rd ref="none"/>
</country>
@@ -1468,12 +1511,6 @@
<country id="TR">
<isocc>792</isocc> <name>Turkey</name> <rd ref="etsi"/>
</country>
-<country id="SR9">
- <isocc>5000</isocc> <name>Ubiquiti SR9</name> <rd ref="sr9"/>
-</country>
-<country id="XR9">
- <isocc>5001</isocc> <name>Ubiquiti XR9</name> <rd ref="xr9"/>
-</country>
<country id="UA">
<isocc>804</isocc> <name>Ukraine</name> <rd ref="none"/>
</country>
@@ -1515,6 +1552,23 @@
NB: keep sorted by starting frequency, legacy before HT
-->
<shared-frequency-bands>
+<freqband id="F1_4942_4987_5">
+ <freqstart>4942</freqstart> <freqend>4987</freqend>
+ <chanwidth>5</chanwidth> <chansep>5</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+ <flags>IEEE80211_CHAN_QUARTER</flags>
+</freqband>
+<freqband id="F1_4945_4985_10">
+ <freqstart>4945</freqstart> <freqend>4985</freqend>
+ <chanwidth>10</chanwidth> <chansep>5</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+ <flags>IEEE80211_CHAN_HALF</flags>
+</freqband>
+<freqband id="F1_4950_4980">
+ <freqstart>4950</freqstart> <freqend>4980</freqend>
+ <chanwidth>20</chanwidth> <chansep>5</chansep>
+ <flags>IEEE80211_CHAN_A</flags>
+</freqband>
<freqband id="F1_5120_5240">
<freqstart>5120</freqstart> <freqend>5240</freqend>
<chanwidth>20</chanwidth> <chansep>20</chansep>
@@ -1659,55 +1713,37 @@
</freqband>
<freqband id="S1_907_922_5">
- <freqstart>2422</freqstart> <freqend>2437</freqend>
+ <freqstart>907</freqstart> <freqend>922</freqend>
<chanwidth>5</chanwidth> <chansep>5</chansep>
<flags>IEEE80211_CHAN_GSM</flags>
<flags>IEEE80211_CHAN_QUARTER</flags>
</freqband>
<freqband id="S1_907_922_10">
- <freqstart>2422</freqstart> <freqend>2437</freqend>
+ <freqstart>907</freqstart> <freqend>922</freqend>
<chanwidth>10</chanwidth> <chansep>5</chansep>
<flags>IEEE80211_CHAN_GSM</flags>
<flags>IEEE80211_CHAN_HALF</flags>
</freqband>
<freqband id="S1_912_917">
- <freqstart>2427</freqstart> <freqend>2432</freqend>
- <chanwidth>20</chanwidth> <chansep>5</chansep>
- <flags>IEEE80211_CHAN_GSM</flags>
-</freqband>
-
-<freqband id="S2_907_922_5">
- <freqstart>2427</freqstart> <freqend>2442</freqend>
- <chanwidth>5</chanwidth> <chansep>5</chansep>
- <flags>IEEE80211_CHAN_GSM</flags>
- <flags>IEEE80211_CHAN_QUARTER</flags>
-</freqband>
-<freqband id="S2_907_922_10">
- <freqstart>2427</freqstart> <freqend>2442</freqend>
- <chanwidth>10</chanwidth> <chansep>5</chansep>
- <flags>IEEE80211_CHAN_GSM</flags>
- <flags>IEEE80211_CHAN_HALF</flags>
-</freqband>
-<freqband id="S2_912_917">
- <freqstart>2432</freqstart> <freqend>2437</freqend>
+ <freqstart>912</freqstart> <freqend>917</freqend>
<chanwidth>20</chanwidth> <chansep>5</chansep>
<flags>IEEE80211_CHAN_GSM</flags>
</freqband>
<freqband id="S1_908_923_5">
- <freqstart>2447</freqstart> <freqend>2467</freqend>
+ <freqstart>908</freqstart> <freqend>923</freqend>
<chanwidth>5</chanwidth> <chansep>5</chansep>
<flags>IEEE80211_CHAN_GSM</flags>
<flags>IEEE80211_CHAN_QUARTER</flags>
</freqband>
<freqband id="S1_913_918_10">
- <freqstart>2457</freqstart> <freqend>2462</freqend>
+ <freqstart>913</freqstart> <freqend>918</freqend>
<chanwidth>10</chanwidth> <chansep>5</chansep>
<flags>IEEE80211_CHAN_GSM</flags>
<flags>IEEE80211_CHAN_HALF</flags>
</freqband>
<freqband id="S1_913_918">
- <freqstart>2457</freqstart> <freqend>2462</freqend>
+ <freqstart>913</freqstart> <freqend>918</freqend>
<chanwidth>20</chanwidth> <chansep>5</chansep>
<flags>IEEE80211_CHAN_GSM</flags>
</freqband>
diff --git a/games/fortune/datfiles/freebsd-tips b/games/fortune/datfiles/freebsd-tips
index 3029df7..c9a2ed6 100644
--- a/games/fortune/datfiles/freebsd-tips
+++ b/games/fortune/datfiles/freebsd-tips
@@ -215,8 +215,8 @@ Over quota? "du -s * | sort -n " will give you a sorted list of your
directory sizes.
-- David Scheidt <dscheidt@tumbolia.com>
%
-ports/net/netcat port is useful not only for redirecting input/output
-to TCP or UDP connections, but also for proxying them with inetd(8).
+nc(1) (or netcat) is useful not only for redirecting input/output to
+TCP or UDP connections, but also for proxying them with inetd(8).
%
sh (the default Bourne shell in FreeBSD) supports command-line editing. Just
``set -o emacs'' or ``set -o vi'' to enable it.
diff --git a/gnu/lib/libstdc++/Makefile b/gnu/lib/libstdc++/Makefile
index da132b7..e2a774e 100644
--- a/gnu/lib/libstdc++/Makefile
+++ b/gnu/lib/libstdc++/Makefile
@@ -75,7 +75,6 @@ MARCHDIR= i486
MARCHDIR= ${MACHINE_ARCH}
.endif
-ATOMICITY_H= atomicity.h
.if exists(${SRCDIR}/config/cpu/${MARCHDIR}/atomicity.h)
ATOMICITY_H= ${SRCDIR}/config/cpu/${MARCHDIR}/atomicity.h
.else
diff --git a/gnu/usr.bin/grep/savedir.c b/gnu/usr.bin/grep/savedir.c
index 9357cad..cfba77c 100644
--- a/gnu/usr.bin/grep/savedir.c
+++ b/gnu/usr.bin/grep/savedir.c
@@ -17,6 +17,9 @@
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#if HAVE_CONFIG_H
# include <config.h>
#endif
@@ -137,10 +140,10 @@ savedir (const char *dir, off_t name_size, struct exclude *included_patterns,
&& !isdir1 (dir, dp->d_name))
{
if (included_patterns
- && !excluded_filename (included_patterns, dp->d_name, 0))
+ && !excluded_filename (included_patterns, path, 0))
continue;
if (excluded_patterns
- && excluded_filename (excluded_patterns, dp->d_name, 0))
+ && excluded_filename (excluded_patterns, path, 0))
continue;
}
diff --git a/gnu/usr.bin/man/manpath/manpath.config b/gnu/usr.bin/man/manpath/manpath.config
index 5134e46..1309746 100644
--- a/gnu/usr.bin/man/manpath/manpath.config
+++ b/gnu/usr.bin/man/manpath/manpath.config
@@ -17,14 +17,12 @@ MANDATORY_MANPATH /usr/share/openssl/man
# check if the directory exists and if it does, add it to MANPATH
#
OPTIONAL_MANPATH /usr/local/man
-OPTIONAL_MANPATH /usr/X11R6/man
#
# set up PATH to MANPATH mapping
#
MANPATH_MAP /bin /usr/share/man
MANPATH_MAP /usr/bin /usr/share/man
MANPATH_MAP /usr/local/bin /usr/local/man
-MANPATH_MAP /usr/X11R6/bin /usr/X11R6/man
#
# set man locales, if needed
#
diff --git a/include/paths.h b/include/paths.h
index 69990a6..a8a68a0 100644
--- a/include/paths.h
+++ b/include/paths.h
@@ -42,11 +42,9 @@
/* Default search path. */
#define _PATH_DEFPATH "/usr/bin:/bin"
/* All standard utilities path. */
-#define _PATH_STDPATH \
- "/usr/bin:/bin:/usr/sbin:/sbin:"
-/* Locate system binaries */
-#define _PATH_SYSPATH \
- "/sbin:/usr/sbin"
+#define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin:"
+/* Locate system binaries. */
+#define _PATH_SYSPATH "/sbin:/usr/sbin"
#define _PATH_AUTHCONF "/etc/auth.conf"
#define _PATH_BSHELL "/bin/sh"
diff --git a/include/stdlib.h b/include/stdlib.h
index 0a83270..91be536 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -88,14 +88,14 @@ int atoi(const char *);
long atol(const char *);
void *bsearch(const void *, const void *, size_t,
size_t, int (*)(const void *, const void *));
-void *calloc(size_t, size_t);
+void *calloc(size_t, size_t) __malloc_like;
div_t div(int, int) __pure2;
void exit(int) __dead2;
void free(void *);
char *getenv(const char *);
long labs(long) __pure2;
ldiv_t ldiv(long, long) __pure2;
-void *malloc(size_t);
+void *malloc(size_t) __malloc_like;
int mblen(const char *, size_t);
size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t);
int mbtowc(wchar_t * __restrict, const char * __restrict, size_t);
diff --git a/include/string.h b/include/string.h
index 32a9ad3..4770d10 100644
--- a/include/string.h
+++ b/include/string.h
@@ -78,7 +78,7 @@ int strcoll(const char *, const char *);
char *strcpy(char * __restrict, const char * __restrict);
size_t strcspn(const char *, const char *) __pure;
#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
-char *strdup(const char *);
+char *strdup(const char *) __malloc_like;
#endif
char *strerror(int);
#if __POSIX_VISIBLE >= 200112
@@ -96,7 +96,7 @@ char *strncat(char * __restrict, const char * __restrict, size_t);
int strncmp(const char *, const char *, size_t) __pure;
char *strncpy(char * __restrict, const char * __restrict, size_t);
#if __BSD_VISIBLE
-char *strndup(const char *, size_t);
+char *strndup(const char *, size_t) __malloc_like;
char *strnstr(const char *, const char *, size_t) __pure;
#endif
char *strpbrk(const char *, const char *) __pure;
diff --git a/include/wchar.h b/include/wchar.h
index 2326b1d..4fc6c8c 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -214,7 +214,7 @@ int wcwidth(wchar_t);
wchar_t *fgetwln(struct __sFILE * __restrict, size_t * __restrict);
size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t,
size_t, mbstate_t * __restrict);
-wchar_t *wcsdup(const wchar_t *);
+wchar_t *wcsdup(const wchar_t *) __malloc_like;
size_t wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t,
size_t, mbstate_t * __restrict);
size_t wcslcat(wchar_t *, const wchar_t *, size_t);
diff --git a/lib/Makefile b/lib/Makefile
index a44335c..06263ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -8,6 +8,7 @@
#
# 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.
# libkvm must be built before libdevstat.
@@ -26,7 +27,8 @@
#
# Otherwise, the SUBDIR list should be in alphabetical order.
-SUBDIR= ${_csu} libc libbsm libcom_err libcrypt libelf libkvm msun libmd \
+SUBDIR= ${_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 \
diff --git a/lib/libarchive/archive_read_support_compression_gzip.c b/lib/libarchive/archive_read_support_compression_gzip.c
index 1e8f818..4669ea4 100644
--- a/lib/libarchive/archive_read_support_compression_gzip.c
+++ b/lib/libarchive/archive_read_support_compression_gzip.c
@@ -428,8 +428,9 @@ gzip_source_read(struct archive_read_source *self, const void **p)
"Failed to clean up gzip decompressor");
return (ARCHIVE_FATAL);
}
- /* Restart header parser with the next block. */
- state->header_state = state->header_done = 0;
+ /* zlib has been torn down */
+ state->header_done = 0;
+ state->eof = 1;
/* FALL THROUGH */
case Z_OK: /* Decompressor made some progress. */
/* If we filled our buffer, update stats and return. */
diff --git a/lib/libarchive/archive_read_support_format_ar.c b/lib/libarchive/archive_read_support_format_ar.c
index fed979d..0201364 100644
--- a/lib/libarchive/archive_read_support_format_ar.c
+++ b/lib/libarchive/archive_read_support_format_ar.c
@@ -511,11 +511,10 @@ ar_parse_gnu_filename_table(struct archive_read *a)
}
}
/*
- * Sanity check, last two chars must be `/\n' or '\n\n',
- * depending on whether the string table is padded by a '\n'
- * (string table produced by GNU ar always has a even size).
+ * GNU ar always pads the table to an even size.
+ * The pad character is either '\n' or '`'.
*/
- if (p != ar->strtab + size && *p != '\n')
+ if (p != ar->strtab + size && *p != '\n' && *p != '`')
goto bad_string_table;
/* Enforce zero termination. */
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c
index e64b6fc..ab96a27 100644
--- a/lib/libarchive/archive_read_support_format_iso9660.c
+++ b/lib/libarchive/archive_read_support_format_iso9660.c
@@ -466,7 +466,10 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
* seek backwards to extract it, so issue a warning. */
if (file->offset < iso9660->current_position) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring out-of-order file");
+ "Ignoring out-of-order file @%x (%s) %jd < %jd",
+ file,
+ iso9660->pathname.s,
+ file->offset, iso9660->current_position);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
release_file(iso9660, file);
@@ -607,7 +610,7 @@ parse_file_info(struct iso9660 *iso9660, struct file_info *parent,
file->parent = parent;
if (parent != NULL)
parent->refcount++;
- file->offset = toi(isodirrec + DR_extent_offset, DR_extent_size)
+ file->offset = (uint64_t)toi(isodirrec + DR_extent_offset, DR_extent_size)
* iso9660->logical_block_size;
file->size = toi(isodirrec + DR_size_offset, DR_size_size);
file->mtime = isodate7(isodirrec + DR_date_offset);
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c
index 68da515..ddac630 100644
--- a/lib/libarchive/archive_write_disk.c
+++ b/lib/libarchive/archive_write_disk.c
@@ -178,6 +178,8 @@ struct archive_write_disk {
int fd;
/* Current offset for writing data to the file. */
off_t offset;
+ /* Last offset actually written to disk. */
+ off_t fd_offset;
/* Maximum size of file, -1 if unknown. */
off_t filesize;
/* Dir we were in before this restore; only for deep paths. */
@@ -187,8 +189,6 @@ struct archive_write_disk {
/* UID/GID to use in restoring this entry. */
uid_t uid;
gid_t gid;
- /* Last offset written to disk. */
- off_t last_offset;
};
/*
@@ -235,7 +235,7 @@ static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
static gid_t trivial_lookup_gid(void *, const char *, gid_t);
static uid_t trivial_lookup_uid(void *, const char *, uid_t);
static ssize_t write_data_block(struct archive_write_disk *,
- const char *, size_t, off_t);
+ const char *, size_t);
static struct archive_vtable *archive_write_disk_vtable(void);
@@ -337,7 +337,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
}
a->entry = archive_entry_clone(entry);
a->fd = -1;
- a->last_offset = 0;
+ a->fd_offset = 0;
a->offset = 0;
a->uid = a->user_uid;
a->mode = archive_entry_mode(a->entry);
@@ -484,7 +484,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
}
/* We've created the object and are ready to pour data into it. */
- if (ret == ARCHIVE_OK)
+ if (ret >= ARCHIVE_WARN)
a->archive.state = ARCHIVE_STATE_DATA;
/*
* If it's not open, tell our client not to try writing.
@@ -513,9 +513,9 @@ archive_write_disk_set_skip_file(struct archive *_a, dev_t d, ino_t i)
}
static ssize_t
-write_data_block(struct archive_write_disk *a,
- const char *buff, size_t size, off_t offset)
+write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
{
+ uint64_t start_size = size;
ssize_t bytes_written = 0;
ssize_t block_size = 0, bytes_to_write;
@@ -538,8 +538,9 @@ write_data_block(struct archive_write_disk *a,
#endif
}
- if (a->filesize >= 0 && (off_t)(offset + size) > a->filesize)
- size = (size_t)(a->filesize - offset);
+ /* If this write would run beyond the file size, truncate it. */
+ if (a->filesize >= 0 && (off_t)(a->offset + size) > a->filesize)
+ start_size = size = (size_t)(a->filesize - a->offset);
/* Write the data. */
while (size > 0) {
@@ -555,7 +556,7 @@ write_data_block(struct archive_write_disk *a,
if (*p != '\0')
break;
}
- offset += p - buff;
+ a->offset += p - buff;
size -= p - buff;
buff = p;
if (size == 0)
@@ -563,22 +564,25 @@ write_data_block(struct archive_write_disk *a,
/* Calculate next block boundary after offset. */
block_end
- = (offset / block_size) * block_size + block_size;
+ = (a->offset / block_size + 1) * block_size;
/* If the adjusted write would cross block boundary,
* truncate it to the block boundary. */
bytes_to_write = size;
- if (offset + bytes_to_write > block_end)
- bytes_to_write = block_end - offset;
+ if (a->offset + bytes_to_write > block_end)
+ bytes_to_write = block_end - a->offset;
}
/* Seek if necessary to the specified offset. */
- if (offset != a->last_offset) {
- if (lseek(a->fd, offset, SEEK_SET) < 0) {
+ if (a->offset != a->fd_offset) {
+ if (lseek(a->fd, a->offset, SEEK_SET) < 0) {
archive_set_error(&a->archive, errno,
"Seek failed");
return (ARCHIVE_FATAL);
}
+ a->fd_offset = a->offset;
+ a->archive.file_position = a->offset;
+ a->archive.raw_position = a->offset;
}
bytes_written = write(a->fd, buff, bytes_to_write);
if (bytes_written < 0) {
@@ -587,12 +591,12 @@ write_data_block(struct archive_write_disk *a,
}
buff += bytes_written;
size -= bytes_written;
- offset += bytes_written;
+ a->offset += bytes_written;
a->archive.file_position += bytes_written;
a->archive.raw_position += bytes_written;
- a->last_offset = a->offset = offset;
+ a->fd_offset = a->offset;
}
- return (bytes_written);
+ return (start_size - size);
}
static ssize_t
@@ -605,9 +609,9 @@ _archive_write_data_block(struct archive *_a,
__archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_disk_block");
- r = write_data_block(a, buff, size, offset);
-
- if (r < 0)
+ a->offset = offset;
+ r = write_data_block(a, buff, size);
+ if (r < ARCHIVE_OK)
return (r);
if ((size_t)r < size) {
archive_set_error(&a->archive, 0,
@@ -625,7 +629,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t size)
__archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
- return (write_data_block(a, buff, size, a->offset));
+ return (write_data_block(a, buff, size));
}
static int
@@ -646,7 +650,7 @@ _archive_write_finish_entry(struct archive *_a)
/* There's no file. */
} else if (a->filesize < 0) {
/* File size is unknown, so we can't set the size. */
- } else if (a->last_offset == a->filesize) {
+ } else if (a->fd_offset == a->filesize) {
/* Last write ended at exactly the filesize; we're done. */
/* Hopefully, this is the common case. */
} else {
@@ -843,7 +847,7 @@ edit_deep_directories(struct archive_write_disk *a)
*tail = '\0'; /* Terminate dir portion */
ret = create_dir(a, a->name);
if (ret == ARCHIVE_OK && chdir(a->name) != 0)
- ret = ARCHIVE_WARN;
+ ret = ARCHIVE_FAILED;
*tail = '/'; /* Restore the / we removed. */
if (ret != ARCHIVE_OK)
return;
@@ -884,7 +888,7 @@ restore_entry(struct archive_write_disk *a)
/* We tried, but couldn't get rid of it. */
archive_set_error(&a->archive, errno,
"Could not unlink");
- return(ARCHIVE_WARN);
+ return(ARCHIVE_FAILED);
}
}
@@ -903,7 +907,7 @@ restore_entry(struct archive_write_disk *a)
&& (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
/* If we're not overwriting, we're done. */
archive_set_error(&a->archive, en, "Already exists");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
/*
@@ -918,7 +922,7 @@ restore_entry(struct archive_write_disk *a)
if (rmdir(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't remove already-existing dir");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
a->pst = NULL;
/* Try again. */
@@ -945,7 +949,7 @@ restore_entry(struct archive_write_disk *a)
if (r != 0) {
archive_set_error(&a->archive, errno,
"Can't stat existing object");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
/*
@@ -974,7 +978,7 @@ restore_entry(struct archive_write_disk *a)
if (unlink(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't unlink already-existing object");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
a->pst = NULL;
/* Try again. */
@@ -984,7 +988,7 @@ restore_entry(struct archive_write_disk *a)
if (rmdir(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't remove already-existing dir");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
/* Try again. */
en = create_filesystem_object(a);
@@ -1007,7 +1011,7 @@ restore_entry(struct archive_write_disk *a)
if (en) {
/* Everything failed; give up here. */
archive_set_error(&a->archive, en, "Can't create '%s'", a->name);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
a->pst = NULL; /* Cached stat data no longer valid. */
@@ -1393,7 +1397,7 @@ check_symlinks(struct archive_write_disk *a)
"Could not remove symlink %s",
a->name);
pn[0] = c;
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
a->pst = NULL;
/*
@@ -1417,7 +1421,7 @@ check_symlinks(struct archive_write_disk *a)
"Cannot remove intervening symlink %s",
a->name);
pn[0] = c;
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
a->pst = NULL;
} else {
@@ -1425,7 +1429,7 @@ check_symlinks(struct archive_write_disk *a)
"Cannot extract through symlink %s",
a->name);
pn[0] = c;
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
}
}
@@ -1551,7 +1555,7 @@ create_parent_dir(struct archive_write_disk *a, char *path)
* Create the specified dir, recursing to create parents as necessary.
*
* Returns ARCHIVE_OK if the path exists when we're done here.
- * Otherwise, returns ARCHIVE_WARN.
+ * Otherwise, returns ARCHIVE_FAILED.
* Assumes path is in mutable storage; path is unchanged on exit.
*/
static int
@@ -1596,18 +1600,18 @@ create_dir(struct archive_write_disk *a, char *path)
if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
archive_set_error(&a->archive, EEXIST,
"Can't create directory '%s'", path);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
if (unlink(path) != 0) {
archive_set_error(&a->archive, errno,
"Can't create directory '%s': "
"Conflicting file cannot be removed");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
} else if (errno != ENOENT && errno != ENOTDIR) {
/* Stat failed? */
archive_set_error(&a->archive, errno, "Can't test directory '%s'", path);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
} else if (slash != NULL) {
*slash = '\0';
r = create_dir(a, path);
@@ -1648,7 +1652,7 @@ create_dir(struct archive_write_disk *a, char *path)
return (ARCHIVE_OK);
archive_set_error(&a->archive, errno, "Failed to create dir '%s'", path);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
/*
diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile
index cb532aa..fc8e3e9 100644
--- a/lib/libarchive/test/Makefile
+++ b/lib/libarchive/test/Makefile
@@ -58,9 +58,11 @@ TESTS= \
test_write_compress.c \
test_write_compress_program.c \
test_write_disk.c \
+ test_write_disk_failures.c \
test_write_disk_hardlink.c \
test_write_disk_perms.c \
test_write_disk_secure.c \
+ test_write_disk_sparse.c \
test_write_disk_times.c \
test_write_format_ar.c \
test_write_format_cpio.c \
diff --git a/lib/libarchive/test/test_write_disk_failures.c b/lib/libarchive/test/test_write_disk_failures.c
new file mode 100644
index 0000000..76c9c3f
--- /dev/null
+++ b/lib/libarchive/test/test_write_disk_failures.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * 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(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 ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) 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 "test.h"
+__FBSDID("$FreeBSD$");
+
+#if ARCHIVE_VERSION_NUMBER >= 1009000
+
+#define UMASK 022
+
+
+#endif
+
+DEFINE_TEST(test_write_disk_failures)
+{
+#if ARCHIVE_VERSION_NUMBER < 1009000
+ skipping("archive_write_disk interface");
+#else
+ struct archive_entry *ae;
+ struct archive *a;
+
+ /* Force the umask to something predictable. */
+ umask(UMASK);
+
+ /* A directory that we can't write to. */
+ assertEqualInt(0, mkdir("dir", 0555));
+
+ /* Try to extract a regular file into the directory above. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "dir/file");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assert((a = archive_write_disk_new()) != NULL);
+ archive_write_disk_set_options(a, ARCHIVE_EXTRACT_TIME);
+ archive_entry_set_mtime(ae, 123456789, 0);
+ assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
+ assertEqualIntA(a, 0, archive_write_finish_entry(a));
+ assertEqualInt(0, archive_write_finish(a));
+ archive_entry_free(ae);
+#endif
+}
diff --git a/lib/libarchive/test/test_write_disk_secure.c b/lib/libarchive/test/test_write_disk_secure.c
index bcb0bf4..b898c97 100644
--- a/lib/libarchive/test/test_write_disk_secure.c
+++ b/lib/libarchive/test/test_write_disk_secure.c
@@ -80,7 +80,7 @@ DEFINE_TEST(test_write_disk_secure)
archive_entry_set_mode(ae, S_IFREG | 0777);
archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS);
failure("Extracting a file through a symlink should fail here.");
- assertEqualInt(ARCHIVE_WARN, archive_write_header(a, ae));
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
archive_entry_free(ae);
assert(0 == archive_write_finish_entry(a));
diff --git a/lib/libarchive/test/test_write_disk_sparse.c b/lib/libarchive/test/test_write_disk_sparse.c
new file mode 100644
index 0000000..6179610
--- /dev/null
+++ b/lib/libarchive/test/test_write_disk_sparse.c
@@ -0,0 +1,278 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * 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(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 ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) 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 "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Write a file using archive_write_data call, read the file
+ * back and verify the contents. The data written includes large
+ * blocks of nulls, so it should exercise the sparsification logic
+ * if ARCHIVE_EXTRACT_SPARSE is enabled.
+ */
+static void
+verify_write_data(struct archive *a, int sparse)
+{
+ static const char data[]="abcdefghijklmnopqrstuvwxyz";
+ struct stat st;
+ struct archive_entry *ae;
+ size_t buff_size = 64 * 1024;
+ char *buff, *p;
+ const char *msg = sparse ? "sparse" : "non-sparse";
+ int fd;
+
+ buff = malloc(buff_size);
+ assert(buff != NULL);
+
+ ae = archive_entry_new();
+ assert(ae != NULL);
+ archive_entry_set_size(ae, 8 * buff_size);
+ archive_entry_set_pathname(ae, "test_write_data");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualIntA(a, 0, archive_write_header(a, ae));
+
+ /* Use archive_write_data() to write three relatively sparse blocks. */
+
+ /* First has non-null data at beginning. */
+ memset(buff, 0, buff_size);
+ memcpy(buff, data, sizeof(data));
+ failure("%s", msg);
+ assertEqualInt(buff_size, archive_write_data(a, buff, buff_size));
+
+ /* Second has non-null data in the middle. */
+ memset(buff, 0, buff_size);
+ memcpy(buff + buff_size / 2 - 3, data, sizeof(data));
+ failure("%s", msg);
+ assertEqualInt(buff_size, archive_write_data(a, buff, buff_size));
+
+ /* Third has non-null data at the end. */
+ memset(buff, 0, buff_size);
+ memcpy(buff + buff_size - sizeof(data), data, sizeof(data));
+ failure("%s", msg);
+ assertEqualInt(buff_size, archive_write_data(a, buff, buff_size));
+
+ failure("%s", msg);
+ assertEqualIntA(a, 0, archive_write_finish_entry(a));
+
+ /* Test the entry on disk. */
+ assert(0 == stat(archive_entry_pathname(ae), &st));
+ assertEqualInt(st.st_size, 8 * buff_size);
+ fd = open(archive_entry_pathname(ae), O_RDONLY);
+ if (!assert(fd >= 0))
+ return;
+
+ /* Check first block. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ failure("%s", msg);
+ assertEqualMem(buff, data, sizeof(data));
+ for (p = buff + sizeof(data); p < buff + buff_size; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check second block. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ for (p = buff; p < buff + buff_size; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (p == buff + buff_size / 2 - 3) {
+ assertEqualMem(p, data, sizeof(data));
+ p += sizeof(data);
+ } else if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check third block. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ for (p = buff; p < buff + buff_size - sizeof(data); ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+ failure("%s", msg);
+ assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data));
+
+ /* XXX more XXX */
+
+ assertEqualInt(0, close(fd));
+ free(buff);
+}
+
+/*
+ * As above, but using the archive_write_data_block() call.
+ */
+static void
+verify_write_data_block(struct archive *a, int sparse)
+{
+ static const char data[]="abcdefghijklmnopqrstuvwxyz";
+ struct stat st;
+ struct archive_entry *ae;
+ size_t buff_size = 64 * 1024;
+ char *buff, *p;
+ const char *msg = sparse ? "sparse" : "non-sparse";
+ int fd;
+
+ buff = malloc(buff_size);
+ assert(buff != NULL);
+
+ ae = archive_entry_new();
+ assert(ae != NULL);
+ archive_entry_set_size(ae, 8 * buff_size);
+ archive_entry_set_pathname(ae, "test_write_data_block");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualIntA(a, 0, archive_write_header(a, ae));
+
+ /* Use archive_write_data_block() to write three
+ relatively sparse blocks. */
+
+ /* First has non-null data at beginning. */
+ memset(buff, 0, buff_size);
+ memcpy(buff, data, sizeof(data));
+ failure("%s", msg);
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_data_block(a, buff, buff_size, 100));
+
+ /* Second has non-null data in the middle. */
+ memset(buff, 0, buff_size);
+ memcpy(buff + buff_size / 2 - 3, data, sizeof(data));
+ failure("%s", msg);
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_data_block(a, buff, buff_size, buff_size + 200));
+
+ /* Third has non-null data at the end. */
+ memset(buff, 0, buff_size);
+ memcpy(buff + buff_size - sizeof(data), data, sizeof(data));
+ failure("%s", msg);
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_data_block(a, buff, buff_size, buff_size * 2 + 300));
+
+ failure("%s", msg);
+ assertEqualIntA(a, 0, archive_write_finish_entry(a));
+
+ /* Test the entry on disk. */
+ assert(0 == stat(archive_entry_pathname(ae), &st));
+ assertEqualInt(st.st_size, 8 * buff_size);
+ fd = open(archive_entry_pathname(ae), O_RDONLY);
+ if (!assert(fd >= 0))
+ return;
+
+ /* Check 100-byte gap at beginning */
+ assertEqualInt(100, read(fd, buff, 100));
+ failure("%s", msg);
+ for (p = buff; p < buff + 100; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check first block. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ failure("%s", msg);
+ assertEqualMem(buff, data, sizeof(data));
+ for (p = buff + sizeof(data); p < buff + buff_size; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check 100-byte gap */
+ assertEqualInt(100, read(fd, buff, 100));
+ failure("%s", msg);
+ for (p = buff; p < buff + 100; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check second block. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ for (p = buff; p < buff + buff_size; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (p == buff + buff_size / 2 - 3) {
+ assertEqualMem(p, data, sizeof(data));
+ p += sizeof(data);
+ } else if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check 100-byte gap */
+ assertEqualInt(100, read(fd, buff, 100));
+ failure("%s", msg);
+ for (p = buff; p < buff + 100; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+
+ /* Check third block. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ for (p = buff; p < buff + buff_size - sizeof(data); ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+ failure("%s", msg);
+ assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data));
+
+ /* Check another block size beyond last we wrote. */
+ assertEqualInt(buff_size, read(fd, buff, buff_size));
+ failure("%s", msg);
+ for (p = buff; p < buff + buff_size; ++p) {
+ failure("offset: %d, %s", (int)(p - buff), msg);
+ if (!assertEqualInt(0, *p))
+ break;
+ }
+
+
+ /* XXX more XXX */
+
+ assertEqualInt(0, close(fd));
+ free(buff);
+}
+
+DEFINE_TEST(test_write_disk_sparse)
+{
+ struct archive *ad;
+
+
+ /*
+ * The return values, etc, of the write data functions
+ * shouldn't change regardless of whether we've requested
+ * sparsification. (The performance and pattern of actual
+ * write calls to the disk should vary, of course, but the
+ * client program shouldn't see any difference.)
+ */
+ assert((ad = archive_write_disk_new()) != NULL);
+ archive_write_disk_set_options(ad, 0);
+ verify_write_data(ad, 0);
+ verify_write_data_block(ad, 0);
+ assertEqualInt(0, archive_write_finish(ad));
+
+ assert((ad = archive_write_disk_new()) != NULL);
+ archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_SPARSE);
+ verify_write_data(ad, 1);
+ verify_write_data_block(ad, 1);
+ assertEqualInt(0, archive_write_finish(ad));
+
+}
diff --git a/lib/libauditd/Makefile b/lib/libauditd/Makefile
new file mode 100644
index 0000000..48ec4b1
--- /dev/null
+++ b/lib/libauditd/Makefile
@@ -0,0 +1,22 @@
+#
+# $FreeBSD$
+#
+
+OPENBSMDIR= ${.CURDIR}/../../contrib/openbsm
+LIBAUDITDDIR= ${OPENBSMDIR}/libauditd
+LIBBSMDIR= ${OPENBSMDIR}/libbsm
+
+LIB= auditd
+
+.PATH: ${LIBAUDITDDIR}
+
+SRCS= auditd_lib.c
+
+#
+# Must use BSM include files from within the contrib area, not the system.
+#
+CFLAGS+= -I${OPENBSMDIR} -I${LIBBSMDIR}
+
+NO_MAN=
+
+.include <bsd.lib.mk>
diff --git a/lib/libbsm/Makefile b/lib/libbsm/Makefile
index 8f3b828..e978b7f 100644
--- a/lib/libbsm/Makefile
+++ b/lib/libbsm/Makefile
@@ -15,11 +15,14 @@ SHLIB_MAJOR= 2
SRCS= bsm_audit.c \
bsm_class.c \
bsm_control.c \
+ bsm_domain.c \
+ bsm_errno.c \
bsm_event.c \
bsm_flags.c \
bsm_io.c \
bsm_mask.c \
bsm_notify.c \
+ bsm_socket_type.c \
bsm_token.c \
bsm_user.c \
bsm_wrappers.c
@@ -35,11 +38,14 @@ INCSDIR= ${INCLUDEDIR}/bsm
MAN= libbsm.3 \
au_class.3 \
au_control.3 \
+ au_domain.3 \
+ au_errno.3 \
au_event.3 \
au_free_token.3 \
au_io.3 \
au_mask.3 \
au_open.3 \
+ au_socket_type.3 \
au_token.3 \
au_user.3 \
audit_submit.3
@@ -79,6 +85,11 @@ MLINKS= libbsm.3 bsm.3 \
au_control.3 getacpol.3 \
au_control.3 au_poltostr.3 \
au_control.3 au_strtopol.3 \
+ au_domain.3 au_bsm_to_domain.3 \
+ au_domain.3 au_domain_to_bsm.3 \
+ au_errno.3 au_bsm_to_errno.3 \
+ au_errno.3 au_errno_to_bsm.3 \
+ au_errno.3 au_strerror.3 \
au_event.3 setauevent.3 \
au_event.3 endauevent.3 \
au_event.3 getauevent.3 \
@@ -99,6 +110,8 @@ MLINKS= libbsm.3 bsm.3 \
au_open.3 au_close_buffer.3 \
au_open.3 au_close_token.3 \
au_open.3 au_write.3 \
+ au_socket_type.3 au_bsm_to_socket_type.3 \
+ au_socket_type.3 au_socket_type_to_bsm.3 \
au_token.3 au_to_arg32.3 \
au_token.3 au_to_arg64.3 \
au_token.3 au_to_arg.3 \
diff --git a/lib/libc/db/man/dbm.3 b/lib/libc/db/man/dbm.3
index 16becc6..fabce8a 100644
--- a/lib/libc/db/man/dbm.3
+++ b/lib/libc/db/man/dbm.3
@@ -15,8 +15,6 @@
.\"
.\" $FreeBSD$
.\"
-.\" Note: The date here should be updated whenever a non-trivial
-.\" change is made to the manual page.
.Dd April 16, 2006
.Dt DBM 3
.Os
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
index bded0d1..75f8668 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 March 27, 2008
+.Dd January 28, 2009
.Dt SYSCTL 3
.Os
.Sh NAME
@@ -440,10 +440,8 @@ attempts to comply.
.It Li KERN_PROC
Return selected information about specific running processes.
.Pp
-For the following names, an array of pairs of
-.Va struct proc
-followed by corresponding
-.Va struct eproc
+For the following names, an array of
+.Va struct kinfo_proc
structures is returned,
whose size depends on the current number of such objects in the system.
.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent
diff --git a/lib/libc/locale/mbstowcs.c b/lib/libc/locale/mbstowcs.c
index ad259d8..194ec2e 100644
--- a/lib/libc/locale/mbstowcs.c
+++ b/lib/libc/locale/mbstowcs.c
@@ -37,7 +37,9 @@ mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
{
static const mbstate_t initial;
mbstate_t mbs;
+ const char *sp;
mbs = initial;
- return (__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs));
+ sp = s;
+ return (__mbsnrtowcs(pwcs, &sp, SIZE_T_MAX, n, &mbs));
}
diff --git a/lib/libc/locale/wcsftime.c b/lib/libc/locale/wcsftime.c
index 7a54fc0..a546dc6 100644
--- a/lib/libc/locale/wcsftime.c
+++ b/lib/libc/locale/wcsftime.c
@@ -52,7 +52,9 @@ wcsftime(wchar_t * __restrict wcs, size_t maxsize,
{
static const mbstate_t initial;
mbstate_t mbs;
- char *dst, *dstp, *sformat;
+ char *dst, *sformat;
+ const char *dstp;
+ const wchar_t *formatp;
size_t n, sflen;
int sverrno;
@@ -63,13 +65,14 @@ wcsftime(wchar_t * __restrict wcs, size_t maxsize,
* for strftime(), which only handles single-byte characters.
*/
mbs = initial;
- sflen = wcsrtombs(NULL, &format, 0, &mbs);
+ formatp = format;
+ sflen = wcsrtombs(NULL, &formatp, 0, &mbs);
if (sflen == (size_t)-1)
goto error;
if ((sformat = malloc(sflen + 1)) == NULL)
goto error;
mbs = initial;
- wcsrtombs(sformat, &format, sflen + 1, &mbs);
+ wcsrtombs(sformat, &formatp, sflen + 1, &mbs);
/*
* Allocate memory for longest multibyte sequence that will fit
@@ -88,7 +91,7 @@ wcsftime(wchar_t * __restrict wcs, size_t maxsize,
goto error;
dstp = dst;
mbs = initial;
- n = mbsrtowcs(wcs, (const char **)&dstp, maxsize, &mbs);
+ n = mbsrtowcs(wcs, &dstp, maxsize, &mbs);
if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL)
goto error;
diff --git a/lib/libc/locale/wcstombs.c b/lib/libc/locale/wcstombs.c
index acd0051..250d2b9 100644
--- a/lib/libc/locale/wcstombs.c
+++ b/lib/libc/locale/wcstombs.c
@@ -37,7 +37,9 @@ wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
{
static const mbstate_t initial;
mbstate_t mbs;
+ const wchar_t *pwcsp;
mbs = initial;
- return (__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs));
+ pwcsp = pwcs;
+ return (__wcsnrtombs(s, &pwcsp, SIZE_T_MAX, n, &mbs));
}
diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3
index 8afdcf9..b09c068 100644
--- a/lib/libc/net/getaddrinfo.3
+++ b/lib/libc/net/getaddrinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 1, 2008
+.Dd January 6, 2009
.Dt GETADDRINFO 3
.Os
.Sh NAME
@@ -126,13 +126,11 @@ field to which the
parameter points shall be set to zero
or be the bitwise-inclusive OR of one or more of the values
.Dv AI_ADDRCONFIG ,
-.Dv AI_ALL ,
.Dv AI_CANONNAME ,
.Dv AI_NUMERICHOST ,
-.Dv AI_NUMERICSERV ,
-.Dv AI_PASSIVE ,
+.Dv AI_NUMERICSERV
and
-.Dv AI_V4MAPPED .
+.Dv AI_PASSIVE .
.Bl -tag -width "AI_CANONNAMEXX"
.It Dv AI_ADDRCONFIG
If the
@@ -141,19 +139,6 @@ bit is set, IPv4 addresses shall be returned only if
an IPv4 address is configured on the local system,
and IPv6 addresses shall be returned only if
an IPv6 address is configured on the local system.
-.It Dv AI_ALL
-If the
-.Dv AI_ALL
-bit is set with the
-.Dv AI_V4MAPPED
-bit, then
-.Fn getaddrinfo
-shall return all matching IPv6 and IPv4 addresses.
-The
-.Dv AI_ALL
-bit without the
-.Dv AI_V4MAPPED
-bit is ignored.
.It Dv AI_CANONNAME
If the
.Dv AI_CANONNAME
@@ -218,30 +203,6 @@ loopback address if
is the null pointer and
.Dv AI_PASSIVE
is not set.
-.It Dv AI_V4MAPPED
-If the
-.Dv AI_V4MAPPED
-flag is specified along with an
-.Fa ai_family
-of
-.Dv AF_INET6 ,
-then
-.Fn getaddrinfo
-shall return IPv4-mapped IPv6 addresses
-on finding no matching IPv6 addresses (
-.Fa ai_addrlen
-shall be 16).
-The
-.Dv AI_V4MAPPED
-flag shall be ignored unless
-.Fa ai_family
-equals
-.Dv AF_INET6 .
-Note: this flag is currently
-.Em not
-supported, see the
-.Sx BUGS
-section.
.El
.El
.Pp
@@ -490,18 +451,6 @@ freeaddrinfo(res0);
.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
.%D June 2000
.Re
-.Sh BUGS
-The
-.Nm
-function as implemented in
-.Fx
-currently does not support
-.Dv AI_ALL
-and
-.Dv AI_V4MAPPED
-flags and returns
-.Dv EAI_BADFLAGS
-if one of them is specified.
.Sh STANDARDS
The
.Fn getaddrinfo
diff --git a/lib/libc/sparc64/sys/__sparc_utrap.c b/lib/libc/sparc64/sys/__sparc_utrap.c
index e556f83..7a5dafa 100644
--- a/lib/libc/sparc64/sys/__sparc_utrap.c
+++ b/lib/libc/sparc64/sys/__sparc_utrap.c
@@ -122,7 +122,7 @@ __utrap_write(const char *str)
}
void
-__utrap_kill_self(sig)
+__utrap_kill_self(int sig)
{
int berrno;
diff --git a/lib/libc/stdio/ferror.3 b/lib/libc/stdio/ferror.3
index d7daef3..043b688 100644
--- a/lib/libc/stdio/ferror.3
+++ b/lib/libc/stdio/ferror.3
@@ -32,7 +32,7 @@
.\" @(#)ferror.3 8.2 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd January 10, 2003
+.Dd January 28, 2009
.Dt FERROR 3
.Os
.Sh NAME
@@ -77,17 +77,16 @@ The function
tests the end-of-file indicator for the stream pointed to by
.Fa stream ,
returning non-zero if it is set.
-The end-of-file indicator can only be cleared by the function
-.Fn clearerr .
+The end-of-file indicator may be cleared by explicitly calling
+.Fn clearerr ,
+or as a side-effect of other operations, e.g.\&
+.Fn fseek .
.Pp
The function
.Fn ferror
tests the error indicator for the stream pointed to by
.Fa stream ,
returning non-zero if it is set.
-The error indicator can only be reset by the
-.Fn clearerr
-function.
.Pp
The function
.Fn fileno
diff --git a/lib/libc/stdio/fputws.c b/lib/libc/stdio/fputws.c
index 7397411..b4462b7 100644
--- a/lib/libc/stdio/fputws.c
+++ b/lib/libc/stdio/fputws.c
@@ -45,6 +45,7 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
char buf[BUFSIZ];
struct __suio uio;
struct __siov iov;
+ const wchar_t *wsp;
FLOCKFILE(fp);
ORIENT(fp, 1);
@@ -54,7 +55,8 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
uio.uio_iovcnt = 1;
iov.iov_base = buf;
do {
- nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf),
+ wsp = ws;
+ nbytes = __wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf),
&fp->_mbstate);
if (nbytes == (size_t)-1)
goto error;
diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
index a126a64..98e26dc 100644
--- a/lib/libc/stdio/printf.3
+++ b/lib/libc/stdio/printf.3
@@ -207,8 +207,7 @@ conversions, this option has no effect.
For
.Cm o
conversions, the precision of the number is increased to force the first
-character of the output string to a zero (except if a zero value is printed
-with an explicit precision of zero).
+character of the output string to a zero.
For
.Cm x
and
diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h
new file mode 100644
index 0000000..39b0003
--- /dev/null
+++ b/lib/libc/stdio/printfcommon.h
@@ -0,0 +1,301 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This file defines common routines used by both printf and wprintf.
+ * You must define CHAR to either char or wchar_t prior to including this.
+ */
+
+
+#ifndef NO_FLOATING_POINT
+
+#define dtoa __dtoa
+#define freedtoa __freedtoa
+
+#include <float.h>
+#include <math.h>
+#include "floatio.h"
+#include "gdtoa.h"
+
+#define DEFPREC 6
+
+static int exponent(CHAR *, int, CHAR);
+
+#endif /* !NO_FLOATING_POINT */
+
+static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *);
+static CHAR *__ultoa(u_long, CHAR *, int, int, const char *);
+
+#define NIOV 8
+struct io_state {
+ FILE *fp;
+ struct __suio uio; /* output information: summary */
+ struct __siov iov[NIOV];/* ... and individual io vectors */
+};
+
+static inline void
+io_init(struct io_state *iop, FILE *fp)
+{
+
+ iop->uio.uio_iov = iop->iov;
+ iop->uio.uio_resid = 0;
+ iop->uio.uio_iovcnt = 0;
+ iop->fp = fp;
+}
+
+/*
+ * WARNING: The buffer passed to io_print() is not copied immediately; it must
+ * remain valid until io_flush() is called.
+ */
+static inline int
+io_print(struct io_state *iop, const CHAR * __restrict ptr, int len)
+{
+
+ iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr;
+ iop->iov[iop->uio.uio_iovcnt].iov_len = len;
+ iop->uio.uio_resid += len;
+ if (++iop->uio.uio_iovcnt >= NIOV)
+ return (__sprint(iop->fp, &iop->uio));
+ else
+ return (0);
+}
+
+/*
+ * Choose PADSIZE to trade efficiency vs. size. If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define PADSIZE 16 /* pad chunk size */
+static const CHAR blanks[PADSIZE] =
+{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+static const CHAR zeroes[PADSIZE] =
+{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+/*
+ * Pad with blanks or zeroes. 'with' should point to either the blanks array
+ * or the zeroes array.
+ */
+static inline int
+io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with)
+{
+ int n;
+
+ while (howmany > 0) {
+ n = (howmany >= PADSIZE) ? PADSIZE : howmany;
+ if (io_print(iop, with, n))
+ return (-1);
+ howmany -= n;
+ }
+ return (0);
+}
+
+/*
+ * Print exactly len characters of the string spanning p to ep, truncating
+ * or padding with 'with' as necessary.
+ */
+static inline int
+io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
+ int len, const CHAR * __restrict with)
+{
+ int p_len;
+
+ p_len = ep - p;
+ if (p_len > len)
+ p_len = len;
+ if (p_len > 0) {
+ if (io_print(iop, p, p_len))
+ return (-1);
+ } else {
+ p_len = 0;
+ }
+ return (io_pad(iop, len - p_len, with));
+}
+
+static inline int
+io_flush(struct io_state *iop)
+{
+
+ return (__sprint(iop->fp, &iop->uio));
+}
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static CHAR *
+__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs)
+{
+ CHAR *cp = endp;
+ long sval;
+
+ /*
+ * Handle the three cases separately, in the hope of getting
+ * better/faster code.
+ */
+ switch (base) {
+ case 10:
+ if (val < 10) { /* many numbers are 1 digit */
+ *--cp = to_char(val);
+ return (cp);
+ }
+ /*
+ * On many machines, unsigned arithmetic is harder than
+ * signed arithmetic, so we do at most one unsigned mod and
+ * divide; this is sufficient to reduce the range of
+ * the incoming value to where signed arithmetic works.
+ */
+ if (val > LONG_MAX) {
+ *--cp = to_char(val % 10);
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ if (octzero && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default: /* oops */
+ abort();
+ }
+ return (cp);
+}
+
+/* Identical to __ultoa, but for intmax_t. */
+static CHAR *
+__ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs)
+{
+ CHAR *cp = endp;
+ intmax_t sval;
+
+ /* quick test for small values; __ultoa is typically much faster */
+ /* (perhaps instead we should run until small, then call __ultoa?) */
+ if (val <= ULONG_MAX)
+ return (__ultoa((u_long)val, endp, base, octzero, xdigs));
+ switch (base) {
+ case 10:
+ if (val < 10) {
+ *--cp = to_char(val % 10);
+ return (cp);
+ }
+ if (val > INTMAX_MAX) {
+ *--cp = to_char(val % 10);
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ if (octzero && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default:
+ abort();
+ }
+ return (cp);
+}
+
+#ifndef NO_FLOATING_POINT
+
+static int
+exponent(CHAR *p0, int exp, CHAR fmtch)
+{
+ CHAR *p, *t;
+ CHAR expbuf[MAXEXPDIG];
+
+ p = p0;
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXPDIG;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
+ }
+ else {
+ /*
+ * Exponents for decimal floating point conversions
+ * (%[eEgG]) must be at least two characters long,
+ * whereas exponents for hexadecimal conversions can
+ * be only one character long.
+ */
+ if (fmtch == 'e' || fmtch == 'E')
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return (p - p0);
+}
+
+#endif /* !NO_FLOATING_POINT */
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index dab331d..e3f95eb 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -65,13 +65,82 @@ __FBSDID("$FreeBSD$");
#include "printflocal.h"
static int __sprint(FILE *, struct __suio *);
-static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
-static char *__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
- const char *);
-static char *__ultoa(u_long, char *, int, int, const char *, int, char,
- const char *);
+static int __sbprintf(FILE *, const char *, va_list) __printflike(2, 0)
+ __noinline;
static char *__wcsconv(wchar_t *, int);
+#define CHAR char
+#include "printfcommon.h"
+
+struct grouping_state {
+ char *thousands_sep; /* locale-specific thousands separator */
+ int thousep_len; /* length of thousands_sep */
+ const char *grouping; /* locale-specific numeric grouping rules */
+ int lead; /* sig figs before decimal or group sep */
+ int nseps; /* number of group separators with ' */
+ int nrepeats; /* number of repeats of the last group */
+};
+
+/*
+ * Initialize the thousands' grouping state in preparation to print a
+ * number with ndigits digits. This routine returns the total number
+ * of bytes that will be needed.
+ */
+static int
+grouping_init(struct grouping_state *gs, int ndigits)
+{
+ struct lconv *locale;
+
+ locale = localeconv();
+ gs->grouping = locale->grouping;
+ gs->thousands_sep = locale->thousands_sep;
+ gs->thousep_len = strlen(gs->thousands_sep);
+
+ gs->nseps = gs->nrepeats = 0;
+ gs->lead = ndigits;
+ while (*gs->grouping != CHAR_MAX) {
+ if (gs->lead <= *gs->grouping)
+ break;
+ gs->lead -= *gs->grouping;
+ if (*(gs->grouping+1)) {
+ gs->nseps++;
+ gs->grouping++;
+ } else
+ gs->nrepeats++;
+ }
+ return ((gs->nseps + gs->nrepeats) * gs->thousep_len);
+}
+
+/*
+ * Print a number with thousands' separators.
+ */
+static int
+grouping_print(struct grouping_state *gs, struct io_state *iop,
+ const CHAR *cp, const CHAR *ep)
+{
+ const CHAR *cp0 = cp;
+
+ if (io_printandpad(iop, cp, ep, gs->lead, zeroes))
+ return (-1);
+ cp += gs->lead;
+ while (gs->nseps > 0 || gs->nrepeats > 0) {
+ if (gs->nrepeats > 0)
+ gs->nrepeats--;
+ else {
+ gs->grouping--;
+ gs->nseps--;
+ }
+ if (io_print(iop, gs->thousands_sep, gs->thousep_len))
+ return (-1);
+ if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes))
+ return (-1);
+ cp += *gs->grouping;
+ }
+ if (cp > ep)
+ cp = ep;
+ return (cp - cp0);
+}
+
/*
* Flush out all the vectors defined by the given uio,
* then reset it so that it can be reused.
@@ -103,6 +172,10 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
FILE fake;
unsigned char buf[BUFSIZ];
+ /* XXX This is probably not needed. */
+ if (prepwrite(fp) != 0)
+ return (EOF);
+
/* copy the important variables */
fake._flags = fp->_flags & ~__SNBF;
fake._file = fp->_file;
@@ -126,160 +199,6 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
}
/*
- * Convert an unsigned long to ASCII for printf purposes, returning
- * a pointer to the first character of the string representation.
- * Octal numbers can be forced to have a leading zero; hex numbers
- * use the given digits.
- */
-static char *
-__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
- int needgrp, char thousep, const char *grp)
-{
- char *cp = endp;
- long sval;
- int ndig;
-
- /*
- * Handle the three cases separately, in the hope of getting
- * better/faster code.
- */
- switch (base) {
- case 10:
- if (val < 10) { /* many numbers are 1 digit */
- *--cp = to_char(val);
- return (cp);
- }
- ndig = 0;
- /*
- * On many machines, unsigned arithmetic is harder than
- * signed arithmetic, so we do at most one unsigned mod and
- * divide; this is sufficient to reduce the range of
- * the incoming value to where signed arithmetic works.
- */
- if (val > LONG_MAX) {
- *--cp = to_char(val % 10);
- ndig++;
- sval = val / 10;
- } else
- sval = val;
- do {
- *--cp = to_char(sval % 10);
- ndig++;
- /*
- * If (*grp == CHAR_MAX) then no more grouping
- * should be performed.
- */
- if (needgrp && ndig == *grp && *grp != CHAR_MAX
- && sval > 9) {
- *--cp = thousep;
- ndig = 0;
- /*
- * If (*(grp+1) == '\0') then we have to
- * use *grp character (last grouping rule)
- * for all next cases
- */
- if (*(grp+1) != '\0')
- grp++;
- }
- sval /= 10;
- } while (sval != 0);
- break;
-
- case 8:
- do {
- *--cp = to_char(val & 7);
- val >>= 3;
- } while (val);
- if (octzero && *cp != '0')
- *--cp = '0';
- break;
-
- case 16:
- do {
- *--cp = xdigs[val & 15];
- val >>= 4;
- } while (val);
- break;
-
- default: /* oops */
- abort();
- }
- return (cp);
-}
-
-/* Identical to __ultoa, but for intmax_t. */
-static char *
-__ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs,
- int needgrp, char thousep, const char *grp)
-{
- char *cp = endp;
- intmax_t sval;
- int ndig;
-
- /* quick test for small values; __ultoa is typically much faster */
- /* (perhaps instead we should run until small, then call __ultoa?) */
- if (val <= ULONG_MAX)
- return (__ultoa((u_long)val, endp, base, octzero, xdigs,
- needgrp, thousep, grp));
- switch (base) {
- case 10:
- if (val < 10) {
- *--cp = to_char(val % 10);
- return (cp);
- }
- ndig = 0;
- if (val > INTMAX_MAX) {
- *--cp = to_char(val % 10);
- ndig++;
- sval = val / 10;
- } else
- sval = val;
- do {
- *--cp = to_char(sval % 10);
- ndig++;
- /*
- * If (*grp == CHAR_MAX) then no more grouping
- * should be performed.
- */
- if (needgrp && *grp != CHAR_MAX && ndig == *grp
- && sval > 9) {
- *--cp = thousep;
- ndig = 0;
- /*
- * If (*(grp+1) == '\0') then we have to
- * use *grp character (last grouping rule)
- * for all next cases
- */
- if (*(grp+1) != '\0')
- grp++;
- }
- sval /= 10;
- } while (sval != 0);
- break;
-
- case 8:
- do {
- *--cp = to_char(val & 7);
- val >>= 3;
- } while (val);
- if (octzero && *cp != '0')
- *--cp = '0';
- break;
-
- case 16:
- do {
- *--cp = xdigs[val & 15];
- val >>= 4;
- } while (val);
- break;
-
- default:
- abort();
- }
- return (cp);
-}
-
-/*
* Convert a wide character string argument for the %ls format to a multibyte
* string representation. If not -1, prec specifies the maximum number of
* bytes to output, and also means that we can't assume that the wide char.
@@ -348,35 +267,26 @@ vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
int ret;
FLOCKFILE(fp);
- ret = __vfprintf(fp, fmt0, ap);
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0)
+ ret = __sbprintf(fp, fmt0, ap);
+ else
+ ret = __vfprintf(fp, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
-#ifndef NO_FLOATING_POINT
-
-#define dtoa __dtoa
-#define freedtoa __freedtoa
-
-#include <float.h>
-#include <math.h>
-#include "floatio.h"
-#include "gdtoa.h"
-
-#define DEFPREC 6
-
-static int exponent(char *, int, int);
-
-#endif /* !NO_FLOATING_POINT */
-
/*
* The size of the buffer we use as scratch space for integer
- * conversions, among other things. Technically, we would need the
- * most space for base 10 conversions with thousands' grouping
- * characters between each pair of digits. 100 bytes is a
- * conservative overestimate even for a 128-bit uintmax_t.
+ * conversions, among other things. We need enough space to
+ * write a uintmax_t in octal (plus one byte).
*/
-#define BUF 100
+#if UINTMAX_MAX <= UINT64_MAX
+#define BUF 32
+#else
+#error "BUF must be large enough to format a uintmax_t"
+#endif
/*
* Non-MT-safe version
@@ -388,14 +298,13 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
int ch; /* character from fmt */
int n, n2; /* handy integer (short term usage) */
char *cp; /* handy char pointer (short term usage) */
- struct __siov *iovp; /* for PRINT macro */
int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format; <0 for N/A */
char sign; /* sign prefix (' ', '+', '-', or \0) */
- char thousands_sep; /* locale specific thousands separator */
- const char *grouping; /* locale specific numeric grouping rules */
+ struct grouping_state gs; /* thousands' grouping info */
+
#ifndef NO_FLOATING_POINT
/*
* We can decompose the printed representation of floating
@@ -412,6 +321,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
* F: at least two digits for decimal, at least one digit for hex
*/
char *decimal_point; /* locale specific decimal point */
+ int decpt_len; /* length of decimal_point */
int signflag; /* true if float is negative */
union { /* floating point arguments %[aAeEfFgG] */
double dbl;
@@ -421,12 +331,9 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
char expchar; /* exponent character: [eEpP\0] */
char *dtoaend; /* pointer to end of converted digits */
int expsize; /* character count for expstr */
- int lead; /* sig figs before decimal or group sep */
int ndig; /* actual number of digits returned by dtoa */
char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
char *dtoaresult; /* buffer allocated by dtoa */
- int nseps; /* number of group separators with ' */
- int nrepeats; /* number of repeats of the last group */
#endif
u_long ulval; /* integer arguments %[diouxX] */
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
@@ -436,9 +343,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
int size; /* size of converted field or string */
int prsize; /* max size of printed field */
const char *xdigs; /* digits for %[xX] conversion */
-#define NIOV 8
- struct __suio uio; /* output information: summary */
- struct __siov iov[NIOV];/* ... and individual io vectors */
+ struct io_state io; /* I/O buffering state */
char buf[BUF]; /* buffer with space for digits of uintmax_t */
char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
union arg *argtable; /* args, built due to positional arg */
@@ -447,56 +352,25 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
va_list orgap; /* original argument pointer */
char *convbuf; /* wide to multibyte conversion result */
- /*
- * Choose PADSIZE to trade efficiency vs. size. If larger printf
- * fields occur frequently, increase PADSIZE and make the initialisers
- * below longer.
- */
-#define PADSIZE 16 /* pad chunk size */
- static char blanks[PADSIZE] =
- {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
- static char zeroes[PADSIZE] =
- {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
static const char xdigs_lower[16] = "0123456789abcdef";
static const char xdigs_upper[16] = "0123456789ABCDEF";
- /*
- * BEWARE, these `goto error' on error, and PAD uses `n'.
- */
+ /* BEWARE, these `goto error' on error. */
#define PRINT(ptr, len) { \
- iovp->iov_base = (ptr); \
- iovp->iov_len = (len); \
- uio.uio_resid += (len); \
- iovp++; \
- if (++uio.uio_iovcnt >= NIOV) { \
- if (__sprint(fp, &uio)) \
- goto error; \
- iovp = iov; \
- } \
+ if (io_print(&io, (ptr), (len))) \
+ goto error; \
}
#define PAD(howmany, with) { \
- if ((n = (howmany)) > 0) { \
- while (n > PADSIZE) { \
- PRINT(with, PADSIZE); \
- n -= PADSIZE; \
- } \
- PRINT(with, n); \
- } \
+ if (io_pad(&io, (howmany), (with))) \
+ goto error; \
+}
+#define PRINTANDPAD(p, ep, len, with) { \
+ if (io_printandpad(&io, (p), (ep), (len), (with))) \
+ goto error; \
}
-#define PRINTANDPAD(p, ep, len, with) do { \
- n2 = (ep) - (p); \
- if (n2 > (len)) \
- n2 = (len); \
- if (n2 > 0) \
- PRINT((p), n2); \
- PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
-} while(0)
#define FLUSH() { \
- if (uio.uio_resid && __sprint(fp, &uio)) \
+ if (io_flush(&io)) \
goto error; \
- uio.uio_iovcnt = 0; \
- iovp = iov; \
}
/*
@@ -571,25 +445,18 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
if (prepwrite(fp) != 0)
return (EOF);
- /* optimise fprintf(stderr) (and other unbuffered Unix files) */
- if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0)
- return (__sbprintf(fp, fmt0, ap));
-
- thousands_sep = '\0';
- grouping = NULL;
convbuf = NULL;
fmt = (char *)fmt0;
argtable = NULL;
nextarg = 1;
va_copy(orgap, ap);
- uio.uio_iov = iovp = iov;
- uio.uio_resid = 0;
- uio.uio_iovcnt = 0;
+ io_init(&io, fp);
ret = 0;
#ifndef NO_FLOATING_POINT
dtoaresult = NULL;
decimal_point = localeconv()->decimal_point;
+ /* The overwhelmingly common case is decpt_len == 1. */
+ decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point));
#endif
/*
@@ -614,6 +481,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap)
dprec = 0;
width = 0;
prec = -1;
+ gs.grouping = NULL;
sign = '\0';
ox[1] = '\0';
@@ -651,8 +519,6 @@ reswitch: switch (ch) {
goto rflag;
case '\'':
flags |= GROUPING;
- thousands_sep = *(localeconv()->thousands_sep);
- grouping = localeconv()->grouping;
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
@@ -873,7 +739,7 @@ fp_common:
expsize = exponent(expstr, expt - 1, expchar);
size = expsize + prec;
if (prec > 1 || flags & ALT)
- ++size;
+ size += decpt_len;
} else {
/* space for digits before decimal point */
if (expt > 0)
@@ -882,24 +748,9 @@ fp_common:
size = 1;
/* space for decimal pt and following digits */
if (prec || flags & ALT)
- size += prec + 1;
- if (grouping && expt > 0) {
- /* space for thousands' grouping */
- nseps = nrepeats = 0;
- lead = expt;
- while (*grouping != CHAR_MAX) {
- if (lead <= *grouping)
- break;
- lead -= *grouping;
- if (*(grouping+1)) {
- nseps++;
- grouping++;
- } else
- nrepeats++;
- }
- size += nseps + nrepeats;
- } else
- lead = expt;
+ size += prec + decpt_len;
+ if ((flags & GROUPING) && expt > 0)
+ size += grouping_init(&gs, expt);
}
break;
#endif /* !NO_FLOATING_POINT */
@@ -1040,20 +891,18 @@ number: if ((dprec = prec) >= 0)
if (ujval != 0 || prec != 0 ||
(flags & ALT && base == 8))
cp = __ujtoa(ujval, cp, base,
- flags & ALT, xdigs,
- flags & GROUPING, thousands_sep,
- grouping);
+ flags & ALT, xdigs);
} else {
if (ulval != 0 || prec != 0 ||
(flags & ALT && base == 8))
cp = __ultoa(ulval, cp, base,
- flags & ALT, xdigs,
- flags & GROUPING, thousands_sep,
- grouping);
+ flags & ALT, xdigs);
}
size = buf + BUF - cp;
if (size > BUF) /* should never happen */
abort();
+ if ((flags & GROUPING) && size != 0)
+ size += grouping_init(&gs, size);
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
@@ -1109,51 +958,48 @@ number: if ((dprec = prec) >= 0)
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD(width - realsz, zeroes);
- /* leading zeroes from decimal precision */
- PAD(dprec - size, zeroes);
-
/* the string or number proper */
#ifndef NO_FLOATING_POINT
if ((flags & FPT) == 0) {
- PRINT(cp, size);
+#endif
+ /* leading zeroes from decimal precision */
+ PAD(dprec - size, zeroes);
+ if (gs.grouping) {
+ if (grouping_print(&gs, &io, cp, buf+BUF) < 0)
+ goto error;
+ } else {
+ PRINT(cp, size);
+ }
+#ifndef NO_FLOATING_POINT
} else { /* glue together f_p fragments */
if (!expchar) { /* %[fF] or sufficiently short %[gG] */
if (expt <= 0) {
PRINT(zeroes, 1);
if (prec || flags & ALT)
- PRINT(decimal_point, 1);
+ PRINT(decimal_point,decpt_len);
PAD(-expt, zeroes);
/* already handled initial 0's */
prec += expt;
} else {
- PRINTANDPAD(cp, dtoaend, lead, zeroes);
- cp += lead;
- if (grouping) {
- while (nseps>0 || nrepeats>0) {
- if (nrepeats > 0)
- nrepeats--;
- else {
- grouping--;
- nseps--;
- }
- PRINT(&thousands_sep,
- 1);
- PRINTANDPAD(cp,dtoaend,
- *grouping, zeroes);
- cp += *grouping;
- }
- if (cp > dtoaend)
- cp = dtoaend;
+ if (gs.grouping) {
+ n = grouping_print(&gs, &io,
+ cp, dtoaend);
+ if (n < 0)
+ goto error;
+ cp += n;
+ } else {
+ PRINTANDPAD(cp, dtoaend,
+ expt, zeroes);
+ cp += expt;
}
if (prec || flags & ALT)
- PRINT(decimal_point,1);
+ PRINT(decimal_point,decpt_len);
}
PRINTANDPAD(cp, dtoaend, prec, zeroes);
} else { /* %[eE] or sufficiently long %[gG] */
if (prec > 1 || flags & ALT) {
- buf[0] = *cp++;
- buf[1] = *decimal_point;
- PRINT(buf, 2);
+ PRINT(cp++, 1);
+ PRINT(decimal_point, decpt_len);
PRINT(cp, ndig-1);
PAD(prec - ndig, zeroes);
} else /* XeYYY */
@@ -1161,8 +1007,6 @@ number: if ((dprec = prec) >= 0)
PRINT(expstr, expsize);
}
}
-#else
- PRINT(cp, size);
#endif
/* left-adjusting padding (always blank) */
if (flags & LADJUST)
@@ -1191,42 +1035,3 @@ error:
/* NOTREACHED */
}
-
-#ifndef NO_FLOATING_POINT
-
-static int
-exponent(char *p0, int exp, int fmtch)
-{
- char *p, *t;
- char expbuf[MAXEXPDIG];
-
- p = p0;
- *p++ = fmtch;
- if (exp < 0) {
- exp = -exp;
- *p++ = '-';
- }
- else
- *p++ = '+';
- t = expbuf + MAXEXPDIG;
- if (exp > 9) {
- do {
- *--t = to_char(exp % 10);
- } while ((exp /= 10) > 9);
- *--t = to_char(exp);
- for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
- }
- else {
- /*
- * Exponents for decimal floating point conversions
- * (%[eEgG]) must be at least two characters long,
- * whereas exponents for hexadecimal conversions can
- * be only one character long.
- */
- if (fmtch == 'e' || fmtch == 'E')
- *p++ = '0';
- *p++ = to_char(exp);
- }
- return (p - p0);
-}
-#endif /* !NO_FLOATING_POINT */
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index 9d724eb..bce4481 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -911,13 +911,13 @@ static int
parsefloat(FILE *fp, char *buf, char *end)
{
char *commit, *p;
- int infnanpos = 0;
+ int infnanpos = 0, decptpos = 0;
enum {
- S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
- S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
+ S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX,
+ S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS
} state = S_START;
unsigned char c;
- char decpt = *localeconv()->decimal_point;
+ const char *decpt = localeconv()->decimal_point;
_Bool gotmantdig = 0, ishex = 0;
/*
@@ -970,8 +970,6 @@ reswitch:
break;
case S_NAN:
switch (infnanpos) {
- case -1: /* XXX kludge to deal with nan(...) */
- goto parsedone;
case 0:
if (c != 'A' && c != 'a')
goto parsedone;
@@ -989,13 +987,15 @@ reswitch:
default:
if (c == ')') {
commit = p;
- infnanpos = -2;
+ state = S_DONE;
} else if (!isalnum(c) && c != '_')
goto parsedone;
break;
}
infnanpos++;
break;
+ case S_DONE:
+ goto parsedone;
case S_MAYBEHEX:
state = S_DIGITS;
if (c == 'X' || c == 'x') {
@@ -1006,16 +1006,34 @@ reswitch:
goto reswitch;
}
case S_DIGITS:
- if ((ishex && isxdigit(c)) || isdigit(c))
+ if ((ishex && isxdigit(c)) || isdigit(c)) {
gotmantdig = 1;
- else {
+ commit = p;
+ break;
+ } else {
+ state = S_DECPT;
+ goto reswitch;
+ }
+ case S_DECPT:
+ if (c == decpt[decptpos]) {
+ if (decpt[++decptpos] == '\0') {
+ /* We read the complete decpt seq. */
+ state = S_FRAC;
+ if (gotmantdig)
+ commit = p;
+ }
+ break;
+ } else if (!decptpos) {
+ /* We didn't read any decpt characters. */
state = S_FRAC;
- if (c != decpt)
- goto reswitch;
+ goto reswitch;
+ } else {
+ /*
+ * We read part of a multibyte decimal point,
+ * but the rest is invalid, so bail.
+ */
+ goto parsedone;
}
- if (gotmantdig)
- commit = p;
- break;
case S_FRAC:
if (((c == 'E' || c == 'e') && !ishex) ||
((c == 'P' || c == 'p') && ishex)) {
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
index 9f06f1b..054299a 100644
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -66,14 +66,139 @@ __FBSDID("$FreeBSD$");
#include "fvwrite.h"
#include "printflocal.h"
-static int __sbprintf(FILE *, const wchar_t *, va_list);
+static int __sprint(FILE *, struct __suio *);
+static int __sbprintf(FILE *, const wchar_t *, va_list) __noinline;
static wint_t __xfputwc(wchar_t, FILE *);
-static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int,
- char, const char *);
-static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int,
- char, const char *);
static wchar_t *__mbsconv(char *, int);
+#define CHAR wchar_t
+#include "printfcommon.h"
+
+struct grouping_state {
+ wchar_t thousands_sep; /* locale-specific thousands separator */
+ const char *grouping; /* locale-specific numeric grouping rules */
+ int lead; /* sig figs before decimal or group sep */
+ int nseps; /* number of group separators with ' */
+ int nrepeats; /* number of repeats of the last group */
+};
+
+static const mbstate_t initial_mbs;
+
+static inline wchar_t
+get_decpt(void)
+{
+ mbstate_t mbs;
+ wchar_t decpt;
+ int nconv;
+
+ mbs = initial_mbs;
+ nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs);
+ if (nconv == (size_t)-1 || nconv == (size_t)-2)
+ decpt = '.'; /* failsafe */
+ return (decpt);
+}
+
+static inline wchar_t
+get_thousep(void)
+{
+ mbstate_t mbs;
+ wchar_t thousep;
+ int nconv;
+
+ mbs = initial_mbs;
+ nconv = mbrtowc(&thousep, localeconv()->thousands_sep,
+ MB_CUR_MAX, &mbs);
+ if (nconv == (size_t)-1 || nconv == (size_t)-2)
+ thousep = '\0'; /* failsafe */
+ return (thousep);
+}
+
+/*
+ * Initialize the thousands' grouping state in preparation to print a
+ * number with ndigits digits. This routine returns the total number
+ * of wide characters that will be printed.
+ */
+static int
+grouping_init(struct grouping_state *gs, int ndigits)
+{
+
+ gs->grouping = localeconv()->grouping;
+ gs->thousands_sep = get_thousep();
+
+ gs->nseps = gs->nrepeats = 0;
+ gs->lead = ndigits;
+ while (*gs->grouping != CHAR_MAX) {
+ if (gs->lead <= *gs->grouping)
+ break;
+ gs->lead -= *gs->grouping;
+ if (*(gs->grouping+1)) {
+ gs->nseps++;
+ gs->grouping++;
+ } else
+ gs->nrepeats++;
+ }
+ return (gs->nseps + gs->nrepeats);
+}
+
+/*
+ * Print a number with thousands' separators.
+ */
+static int
+grouping_print(struct grouping_state *gs, struct io_state *iop,
+ const CHAR *cp, const CHAR *ep)
+{
+ const CHAR *cp0 = cp;
+
+ if (io_printandpad(iop, cp, ep, gs->lead, zeroes))
+ return (-1);
+ cp += gs->lead;
+ while (gs->nseps > 0 || gs->nrepeats > 0) {
+ if (gs->nrepeats > 0)
+ gs->nrepeats--;
+ else {
+ gs->grouping--;
+ gs->nseps--;
+ }
+ if (io_print(iop, &gs->thousands_sep, 1))
+ return (-1);
+ if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes))
+ return (-1);
+ cp += *gs->grouping;
+ }
+ if (cp > ep)
+ cp = ep;
+ return (cp - cp0);
+}
+
+
+/*
+ * Flush out all the vectors defined by the given uio,
+ * then reset it so that it can be reused.
+ *
+ * XXX The fact that we do this a character at a time and convert to a
+ * multibyte character sequence even if the destination is a wide
+ * string eclipses the benefits of buffering.
+ */
+static int
+__sprint(FILE *fp, struct __suio *uio)
+{
+ struct __siov *iov;
+ wchar_t *p;
+ int i, len;
+
+ iov = uio->uio_iov;
+ for (; uio->uio_resid != 0; uio->uio_resid -= len, iov++) {
+ p = (wchar_t *)iov->iov_base;
+ len = iov->iov_len;
+ for (i = 0; i < len; i++) {
+ if (__xfputwc(p[i], fp) == WEOF)
+ return (-1);
+ }
+ }
+ uio->uio_iovcnt = 0;
+ return (0);
+}
+
/*
* Helper function for `fprintf to unbuffered unix file': creates a
* temporary buffer. We only work on write-only files; this avoids
@@ -86,6 +211,10 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
FILE fake;
unsigned char buf[BUFSIZ];
+ /* XXX This is probably not needed. */
+ if (prepwrite(fp) != 0)
+ return (EOF);
+
/* copy the important variables */
fake._flags = fp->_flags & ~__SNBF;
fake._file = fp->_file;
@@ -115,7 +244,6 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
static wint_t
__xfputwc(wchar_t wc, FILE *fp)
{
- static const mbstate_t initial;
mbstate_t mbs;
char buf[MB_LEN_MAX];
struct __suio uio;
@@ -125,7 +253,7 @@ __xfputwc(wchar_t wc, FILE *fp)
if ((fp->_flags & __SSTR) == 0)
return (__fputwc(wc, fp));
- mbs = initial;
+ mbs = initial_mbs;
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
fp->_flags |= __SERR;
return (WEOF);
@@ -139,160 +267,6 @@ __xfputwc(wchar_t wc, FILE *fp)
}
/*
- * Convert an unsigned long to ASCII for printf purposes, returning
- * a pointer to the first character of the string representation.
- * Octal numbers can be forced to have a leading zero; hex numbers
- * use the given digits.
- */
-static wchar_t *
-__ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs,
- int needgrp, char thousep, const char *grp)
-{
- wchar_t *cp = endp;
- long sval;
- int ndig;
-
- /*
- * Handle the three cases separately, in the hope of getting
- * better/faster code.
- */
- switch (base) {
- case 10:
- if (val < 10) { /* many numbers are 1 digit */
- *--cp = to_char(val);
- return (cp);
- }
- ndig = 0;
- /*
- * On many machines, unsigned arithmetic is harder than
- * signed arithmetic, so we do at most one unsigned mod and
- * divide; this is sufficient to reduce the range of
- * the incoming value to where signed arithmetic works.
- */
- if (val > LONG_MAX) {
- *--cp = to_char(val % 10);
- ndig++;
- sval = val / 10;
- } else
- sval = val;
- do {
- *--cp = to_char(sval % 10);
- ndig++;
- /*
- * If (*grp == CHAR_MAX) then no more grouping
- * should be performed.
- */
- if (needgrp && ndig == *grp && *grp != CHAR_MAX
- && sval > 9) {
- *--cp = thousep;
- ndig = 0;
- /*
- * If (*(grp+1) == '\0') then we have to
- * use *grp character (last grouping rule)
- * for all next cases
- */
- if (*(grp+1) != '\0')
- grp++;
- }
- sval /= 10;
- } while (sval != 0);
- break;
-
- case 8:
- do {
- *--cp = to_char(val & 7);
- val >>= 3;
- } while (val);
- if (octzero && *cp != '0')
- *--cp = '0';
- break;
-
- case 16:
- do {
- *--cp = xdigs[val & 15];
- val >>= 4;
- } while (val);
- break;
-
- default: /* oops */
- abort();
- }
- return (cp);
-}
-
-/* Identical to __ultoa, but for intmax_t. */
-static wchar_t *
-__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
- const char *xdigs, int needgrp, char thousep, const char *grp)
-{
- wchar_t *cp = endp;
- intmax_t sval;
- int ndig;
-
- /* quick test for small values; __ultoa is typically much faster */
- /* (perhaps instead we should run until small, then call __ultoa?) */
- if (val <= ULONG_MAX)
- return (__ultoa((u_long)val, endp, base, octzero, xdigs,
- needgrp, thousep, grp));
- switch (base) {
- case 10:
- if (val < 10) {
- *--cp = to_char(val % 10);
- return (cp);
- }
- ndig = 0;
- if (val > INTMAX_MAX) {
- *--cp = to_char(val % 10);
- ndig++;
- sval = val / 10;
- } else
- sval = val;
- do {
- *--cp = to_char(sval % 10);
- ndig++;
- /*
- * If (*grp == CHAR_MAX) then no more grouping
- * should be performed.
- */
- if (needgrp && *grp != CHAR_MAX && ndig == *grp
- && sval > 9) {
- *--cp = thousep;
- ndig = 0;
- /*
- * If (*(grp+1) == '\0') then we have to
- * use *grp character (last grouping rule)
- * for all next cases
- */
- if (*(grp+1) != '\0')
- grp++;
- }
- sval /= 10;
- } while (sval != 0);
- break;
-
- case 8:
- do {
- *--cp = to_char(val & 7);
- val >>= 3;
- } while (val);
- if (octzero && *cp != '0')
- *--cp = '0';
- break;
-
- case 16:
- do {
- *--cp = xdigs[val & 15];
- val >>= 4;
- } while (val);
- break;
-
- default:
- abort();
- }
- return (cp);
-}
-
-/*
* Convert a multibyte character string argument for the %s format to a wide
* string representation. ``prec'' specifies the maximum number of bytes
* to output. If ``prec'' is greater than or equal to zero, we can't assume
@@ -301,7 +275,6 @@ __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
static wchar_t *
__mbsconv(char *mbsarg, int prec)
{
- static const mbstate_t initial;
mbstate_t mbs;
wchar_t *convbuf, *wcp;
const char *p;
@@ -321,7 +294,7 @@ __mbsconv(char *mbsarg, int prec)
*/
p = mbsarg;
insize = nchars = 0;
- mbs = initial;
+ mbs = initial_mbs;
while (nchars != (size_t)prec) {
nconv = mbrlen(p, MB_CUR_MAX, &mbs);
if (nconv == 0 || nconv == (size_t)-1 ||
@@ -348,7 +321,7 @@ __mbsconv(char *mbsarg, int prec)
return (NULL);
wcp = convbuf;
p = mbsarg;
- mbs = initial;
+ mbs = initial_mbs;
while (insize != 0) {
nconv = mbrtowc(wcp, p, insize, &mbs);
if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
@@ -376,35 +349,26 @@ vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap)
int ret;
FLOCKFILE(fp);
- ret = __vfwprintf(fp, fmt0, ap);
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0)
+ ret = __sbprintf(fp, fmt0, ap);
+ else
+ ret = __vfwprintf(fp, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
-#ifndef NO_FLOATING_POINT
-
-#define dtoa __dtoa
-#define freedtoa __freedtoa
-
-#include <float.h>
-#include <math.h>
-#include "floatio.h"
-#include "gdtoa.h"
-
-#define DEFPREC 6
-
-static int exponent(wchar_t *, int, wchar_t);
-
-#endif /* !NO_FLOATING_POINT */
-
/*
* The size of the buffer we use as scratch space for integer
- * conversions, among other things. Technically, we would need the
- * most space for base 10 conversions with thousands' grouping
- * characters between each pair of digits. 100 bytes is a
- * conservative overestimate even for a 128-bit uintmax_t.
+ * conversions, among other things. We need enough space to
+ * write a uintmax_t in octal (plus one byte).
*/
-#define BUF 100
+#if UINTMAX_MAX <= UINT64_MAX
+#define BUF 32
+#else
+#error "BUF must be large enough to format a uintmax_t"
+#endif
/*
* Non-MT-safe version
@@ -414,15 +378,14 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
{
wchar_t *fmt; /* format string */
wchar_t ch; /* character from fmt */
- int n, n2, n3; /* handy integer (short term usage) */
+ int n, n2; /* handy integer (short term usage) */
wchar_t *cp; /* handy char pointer (short term usage) */
int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format; <0 for N/A */
wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */
- char thousands_sep; /* locale specific thousands separator */
- const char *grouping; /* locale specific numeric grouping rules */
+ struct grouping_state gs; /* thousands' grouping info */
#ifndef NO_FLOATING_POINT
/*
* We can decompose the printed representation of floating
@@ -438,7 +401,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
* D: expchar holds this character; '\0' if no exponent, e.g. %f
* F: at least two digits for decimal, at least one digit for hex
*/
- char *decimal_point; /* locale specific decimal point */
+ wchar_t decimal_point; /* locale specific decimal point */
int signflag; /* true if float is negative */
union { /* floating point arguments %[aAeEfFgG] */
double dbl;
@@ -448,12 +411,9 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
char expchar; /* exponent character: [eEpP\0] */
char *dtoaend; /* pointer to end of converted digits */
int expsize; /* character count for expstr */
- int lead; /* sig figs before decimal or group sep */
int ndig; /* actual number of digits returned by dtoa */
wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
char *dtoaresult; /* buffer allocated by dtoa */
- int nseps; /* number of group separators with ' */
- int nrepeats; /* number of repeats of the last group */
#endif
u_long ulval; /* integer arguments %[diouxX] */
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
@@ -463,6 +423,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
int size; /* size of converted field or string */
int prsize; /* max size of printed field */
const char *xdigs; /* digits for [xX] conversion */
+ struct io_state io; /* I/O buffering state */
wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */
wchar_t ox[2]; /* space for 0x hex-prefix */
union arg *argtable; /* args, built due to positional arg */
@@ -471,45 +432,26 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
va_list orgap; /* original argument pointer */
wchar_t *convbuf; /* multibyte to wide conversion result */
- /*
- * Choose PADSIZE to trade efficiency vs. size. If larger printf
- * fields occur frequently, increase PADSIZE and make the initialisers
- * below longer.
- */
-#define PADSIZE 16 /* pad chunk size */
- static wchar_t blanks[PADSIZE] =
- {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
- static wchar_t zeroes[PADSIZE] =
- {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
static const char xdigs_lower[16] = "0123456789abcdef";
static const char xdigs_upper[16] = "0123456789ABCDEF";
- /*
- * BEWARE, these `goto error' on error, PRINT uses `n2' and
- * PAD uses `n'.
- */
+ /* BEWARE, these `goto error' on error. */
#define PRINT(ptr, len) do { \
- for (n3 = 0; n3 < (len); n3++) \
- __xfputwc((ptr)[n3], fp); \
+ if (io_print(&io, (ptr), (len))) \
+ goto error; \
} while (0)
-#define PAD(howmany, with) do { \
- if ((n = (howmany)) > 0) { \
- while (n > PADSIZE) { \
- PRINT(with, PADSIZE); \
- n -= PADSIZE; \
- } \
- PRINT(with, n); \
- } \
-} while (0)
-#define PRINTANDPAD(p, ep, len, with) do { \
- n2 = (ep) - (p); \
- if (n2 > (len)) \
- n2 = (len); \
- if (n2 > 0) \
- PRINT((p), n2); \
- PAD((len) - (n2 > 0 ? n2 : 0), (with)); \
-} while(0)
+#define PAD(howmany, with) { \
+ if (io_pad(&io, (howmany), (with))) \
+ goto error; \
+}
+#define PRINTANDPAD(p, ep, len, with) { \
+ if (io_printandpad(&io, (p), (ep), (len), (with))) \
+ goto error; \
+}
+#define FLUSH() { \
+ if (io_flush(&io)) \
+ goto error; \
+}
/*
* Get the argument indexed by nextarg. If the argument table is
@@ -579,21 +521,15 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
if (prepwrite(fp) != 0)
return (EOF);
- /* optimise fprintf(stderr) (and other unbuffered Unix files) */
- if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0)
- return (__sbprintf(fp, fmt0, ap));
-
- thousands_sep = '\0';
- grouping = NULL;
convbuf = NULL;
fmt = (wchar_t *)fmt0;
argtable = NULL;
nextarg = 1;
va_copy(orgap, ap);
+ io_init(&io, fp);
ret = 0;
#ifndef NO_FLOATING_POINT
- decimal_point = localeconv()->decimal_point;
+ decimal_point = get_decpt();
#endif
/*
@@ -618,6 +554,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
dprec = 0;
width = 0;
prec = -1;
+ gs.grouping = NULL;
sign = '\0';
ox[1] = '\0';
@@ -655,8 +592,6 @@ reswitch: switch (ch) {
goto rflag;
case '\'':
flags |= GROUPING;
- thousands_sep = *(localeconv()->thousands_sep);
- grouping = localeconv()->grouping;
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
@@ -880,23 +815,8 @@ fp_common:
/* space for decimal pt and following digits */
if (prec || flags & ALT)
size += prec + 1;
- if (grouping && expt > 0) {
- /* space for thousands' grouping */
- nseps = nrepeats = 0;
- lead = expt;
- while (*grouping != CHAR_MAX) {
- if (lead <= *grouping)
- break;
- lead -= *grouping;
- if (*(grouping+1)) {
- nseps++;
- grouping++;
- } else
- nrepeats++;
- }
- size += nseps + nrepeats;
- } else
- lead = expt;
+ if ((flags & GROUPING) && expt > 0)
+ size += grouping_init(&gs, expt);
}
break;
#endif /* !NO_FLOATING_POINT */
@@ -1040,20 +960,18 @@ number: if ((dprec = prec) >= 0)
if (ujval != 0 || prec != 0 ||
(flags & ALT && base == 8))
cp = __ujtoa(ujval, cp, base,
- flags & ALT, xdigs,
- flags & GROUPING, thousands_sep,
- grouping);
+ flags & ALT, xdigs);
} else {
if (ulval != 0 || prec != 0 ||
(flags & ALT && base == 8))
cp = __ultoa(ulval, cp, base,
- flags & ALT, xdigs,
- flags & GROUPING, thousands_sep,
- grouping);
+ flags & ALT, xdigs);
}
size = buf + BUF - cp;
if (size > BUF) /* should never happen */
abort();
+ if ((flags & GROUPING) && size != 0)
+ size += grouping_init(&gs, size);
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
@@ -1109,53 +1027,48 @@ number: if ((dprec = prec) >= 0)
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD(width - realsz, zeroes);
- /* leading zeroes from decimal precision */
- PAD(dprec - size, zeroes);
-
/* the string or number proper */
#ifndef NO_FLOATING_POINT
if ((flags & FPT) == 0) {
- PRINT(cp, size);
+#endif
+ /* leading zeroes from decimal precision */
+ PAD(dprec - size, zeroes);
+ if (gs.grouping) {
+ if (grouping_print(&gs, &io, cp, buf+BUF) < 0)
+ goto error;
+ } else {
+ PRINT(cp, size);
+ }
+#ifndef NO_FLOATING_POINT
} else { /* glue together f_p fragments */
if (!expchar) { /* %[fF] or sufficiently short %[gG] */
if (expt <= 0) {
PRINT(zeroes, 1);
if (prec || flags & ALT)
- PRINT(decimal_point, 1);
+ PRINT(&decimal_point, 1);
PAD(-expt, zeroes);
/* already handled initial 0's */
prec += expt;
} else {
- PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
- cp += lead;
- if (grouping) {
- while (nseps>0 || nrepeats>0) {
- if (nrepeats > 0)
- nrepeats--;
- else {
- grouping--;
- nseps--;
- }
- PRINT(&thousands_sep,
- 1);
- PRINTANDPAD(cp,
- convbuf + ndig,
- *grouping, zeroes);
- cp += *grouping;
- }
- if (cp > convbuf + ndig)
- cp = convbuf + ndig;
- }
- if (prec || flags & ALT) {
- buf[0] = *decimal_point;
- PRINT(buf, 1);
+ if (gs.grouping) {
+ n = grouping_print(&gs, &io,
+ cp, convbuf + ndig);
+ if (n < 0)
+ goto error;
+ cp += n;
+ } else {
+ PRINTANDPAD(cp, convbuf + ndig,
+ expt, zeroes);
+ cp += expt;
}
+ if (prec || flags & ALT)
+ PRINT(&decimal_point, 1);
}
PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
} else { /* %[eE] or sufficiently long %[gG] */
if (prec > 1 || flags & ALT) {
buf[0] = *cp++;
- buf[1] = *decimal_point;
+ buf[1] = decimal_point;
PRINT(buf, 2);
PRINT(cp, ndig-1);
PAD(prec - ndig, zeroes);
@@ -1164,8 +1077,6 @@ number: if ((dprec = prec) >= 0)
PRINT(expstr, expsize);
}
}
-#else
- PRINT(cp, size);
#endif
/* left-adjusting padding (always blank) */
if (flags & LADJUST)
@@ -1173,8 +1084,11 @@ number: if ((dprec = prec) >= 0)
/* finally, adjust ret */
ret += prsize;
+
+ FLUSH(); /* copy out the I/O vectors */
}
done:
+ FLUSH();
error:
va_end(orgap);
if (convbuf != NULL)
@@ -1186,43 +1100,3 @@ error:
return (ret);
/* NOTREACHED */
}
-
-
-#ifndef NO_FLOATING_POINT
-
-static int
-exponent(wchar_t *p0, int exp, wchar_t fmtch)
-{
- wchar_t *p, *t;
- wchar_t expbuf[MAXEXPDIG];
-
- p = p0;
- *p++ = fmtch;
- if (exp < 0) {
- exp = -exp;
- *p++ = '-';
- }
- else
- *p++ = '+';
- t = expbuf + MAXEXPDIG;
- if (exp > 9) {
- do {
- *--t = to_char(exp % 10);
- } while ((exp /= 10) > 9);
- *--t = to_char(exp);
- for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
- }
- else {
- /*
- * Exponents for decimal floating point conversions
- * (%[eEgG]) must be at least two characters long,
- * whereas exponents for hexadecimal conversions can
- * be only one character long.
- */
- if (fmtch == 'e' || fmtch == 'E')
- *p++ = '0';
- *p++ = to_char(exp);
- }
- return (p - p0);
-}
-#endif /* !NO_FLOATING_POINT */
diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c
index 8a62a8f7..60c7c71 100644
--- a/lib/libc/stdio/vfwscanf.c
+++ b/lib/libc/stdio/vfwscanf.c
@@ -103,6 +103,8 @@ static int parsefloat(FILE *, wchar_t *, wchar_t *);
(cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \
(wmemchr(ccls, (_c), ccle - ccls) != NULL))
+static const mbstate_t initial_mbs;
+
/*
* MT-safe version.
*/
@@ -142,7 +144,6 @@ __vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
char *mbp; /* multibyte string pointer for %c %s %[ */
size_t nconv; /* number of bytes in mb. conversion */
char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
- static const mbstate_t initial;
mbstate_t mbs;
/* `basefix' is used to avoid `if' tests in the integer scanner */
@@ -375,7 +376,7 @@ literal:
if (!(flags & SUPPRESS))
mbp = va_arg(ap, char *);
n = 0;
- mbs = initial;
+ mbs = initial_mbs;
while (width != 0 &&
(wi = __fgetwc(fp)) != WEOF) {
if (width >= MB_CUR_MAX &&
@@ -440,7 +441,7 @@ literal:
if (!(flags & SUPPRESS))
mbp = va_arg(ap, char *);
n = 0;
- mbs = initial;
+ mbs = initial_mbs;
while ((wi = __fgetwc(fp)) != WEOF &&
width != 0 && INCCL(wi)) {
if (width >= MB_CUR_MAX &&
@@ -501,7 +502,7 @@ literal:
} else {
if (!(flags & SUPPRESS))
mbp = va_arg(ap, char *);
- mbs = initial;
+ mbs = initial_mbs;
while ((wi = __fgetwc(fp)) != WEOF &&
width != 0 &&
!iswspace(wi)) {
@@ -721,16 +722,23 @@ match_failure:
static int
parsefloat(FILE *fp, wchar_t *buf, wchar_t *end)
{
+ mbstate_t mbs;
+ size_t nconv;
wchar_t *commit, *p;
int infnanpos = 0;
enum {
- S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
+ S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX,
S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
} state = S_START;
wchar_t c;
- wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point;
+ wchar_t decpt;
_Bool gotmantdig = 0, ishex = 0;
+ mbs = initial_mbs;
+ nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs);
+ if (nconv == (size_t)-1 || nconv == (size_t)-2)
+ decpt = '.'; /* failsafe */
+
/*
* We set commit = p whenever the string we have read so far
* constitutes a valid representation of a floating point
@@ -783,8 +791,6 @@ reswitch:
break;
case S_NAN:
switch (infnanpos) {
- case -1: /* XXX kludge to deal with nan(...) */
- goto parsedone;
case 0:
if (c != 'A' && c != 'a')
goto parsedone;
@@ -802,13 +808,15 @@ reswitch:
default:
if (c == ')') {
commit = p;
- infnanpos = -2;
+ state = S_DONE;
} else if (!iswalnum(c) && c != '_')
goto parsedone;
break;
}
infnanpos++;
break;
+ case S_DONE:
+ goto parsedone;
case S_MAYBEHEX:
state = S_DIGITS;
if (c == 'X' || c == 'x') {
diff --git a/lib/libc/stdio/vswscanf.c b/lib/libc/stdio/vswscanf.c
index 67bfb47..8a70d44 100644
--- a/lib/libc/stdio/vswscanf.c
+++ b/lib/libc/stdio/vswscanf.c
@@ -66,6 +66,7 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
char *mbstr;
size_t mlen;
int r;
+ const wchar_t *strp;
/*
* XXX Convert the wide character string to multibyte, which
@@ -74,7 +75,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX + 1)) == NULL)
return (EOF);
mbs = initial;
- if ((mlen = wcsrtombs(mbstr, &str, SIZE_T_MAX, &mbs)) == (size_t)-1) {
+ strp = str;
+ if ((mlen = wcsrtombs(mbstr, &strp, SIZE_T_MAX, &mbs)) == (size_t)-1) {
free(mbstr);
return (EOF);
}
diff --git a/lib/libc/stdio/wsetup.c b/lib/libc/stdio/wsetup.c
index a5da23f..37bfc58 100644
--- a/lib/libc/stdio/wsetup.c
+++ b/lib/libc/stdio/wsetup.c
@@ -60,6 +60,7 @@ __swsetup(fp)
if ((fp->_flags & __SWR) == 0) {
if ((fp->_flags & __SRW) == 0) {
errno = EBADF;
+ fp->_flags |= __SERR;
return (EOF);
}
if (fp->_flags & __SRD) {
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index 7fddae4..dffaf87 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -35,34 +35,45 @@ MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \
strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wcscoll.3 wcstok.3 \
wcswidth.3 wcsxfrm.3 wmemchr.3
-MLINKS+=ffs.3 ffsl.3
-MLINKS+=ffs.3 fls.3
-MLINKS+=ffs.3 flsl.3
-MLINKS+=ffs.3 ffsll.3
-MLINKS+=ffs.3 flsll.3
+MLINKS+=ffs.3 ffsl.3 \
+ ffs.3 ffsll.3 \
+ ffs.3 fls.3 \
+ ffs.3 flsl.3 \
+ ffs.3 flsll.3
MLINKS+=index.3 rindex.3
MLINKS+=memchr.3 memrchr.3
MLINKS+=strcasecmp.3 strncasecmp.3
MLINKS+=strcat.3 strncat.3
MLINKS+=strchr.3 strrchr.3
MLINKS+=strcmp.3 strncmp.3
-MLINKS+=strcpy.3 stpcpy.3
+MLINKS+=strcpy.3 stpcpy.3 \
+ strcpy.3 strncpy.3
MLINKS+=strdup.3 strndup.3
-MLINKS+=strcpy.3 strncpy.3
-MLINKS+=strerror.3 perror.3 strerror.3 sys_errlist.3 strerror.3 sys_nerr.3
-MLINKS+=strerror.3 strerror_r.3
+MLINKS+=strerror.3 perror.3 \
+ strerror.3 strerror_r.3 \
+ strerror.3 sys_errlist.3 \
+ strerror.3 sys_nerr.3
MLINKS+=strlcpy.3 strlcat.3
+MLINKS+=strstr.3 strcasestr.3 \
+ strstr.3 strnstr.3
MLINKS+=strtok.3 strtok_r.3
-MLINKS+=strstr.3 strcasestr.3
-MLINKS+=strstr.3 strnstr.3
-MLINKS+=wmemchr.3 wmemcmp.3 wmemchr.3 wmemcpy.3 \
- wmemchr.3 wmemmove.3 wmemchr.3 wmemset.3 \
- wmemchr.3 wcscat.3 wmemchr.3 wcschr.3 \
- wmemchr.3 wcscmp.3 wmemchr.3 wcscpy.3 \
- wmemchr.3 wcscspn.3 wmemchr.3 wcsdup.3 \
+MLINKS+=wmemchr.3 wcscat.3 \
+ wmemchr.3 wcschr.3 \
+ wmemchr.3 wcscmp.3 \
+ wmemchr.3 wcscpy.3 \
+ wmemchr.3 wcscspn.3 \
+ wmemchr.3 wcsdup.3 \
wmemchr.3 wcslcat.3 \
- wmemchr.3 wcslcpy.3 wmemchr.3 wcslen.3 \
- wmemchr.3 wcsncat.3 wmemchr.3 wcsncmp.3 \
- wmemchr.3 wcsncpy.3 wmemchr.3 wcspbrk.3 \
- wmemchr.3 wcsrchr.3 wmemchr.3 wcsspn.3 \
- wmemchr.3 wcsstr.3
+ wmemchr.3 wcslcpy.3 \
+ wmemchr.3 wcslen.3 \
+ wmemchr.3 wcsncat.3 \
+ wmemchr.3 wcsncmp.3 \
+ wmemchr.3 wcsncpy.3 \
+ wmemchr.3 wcspbrk.3 \
+ wmemchr.3 wcsrchr.3 \
+ wmemchr.3 wcsspn.3 \
+ wmemchr.3 wcsstr.3 \
+ wmemchr.3 wmemcmp.3 \
+ wmemchr.3 wmemcpy.3 \
+ wmemchr.3 wmemmove.3 \
+ wmemchr.3 wmemset.3
diff --git a/lib/libc/string/ffs.3 b/lib/libc/string/ffs.3
index e66d7eb..acb1ac8 100644
--- a/lib/libc/string/ffs.3
+++ b/lib/libc/string/ffs.3
@@ -108,4 +108,4 @@ The
and
.Fn flsll
functions appeared in
-.Fx 8.0 .
+.Fx 7.1 .
diff --git a/lib/libc/string/memccpy.c b/lib/libc/string/memccpy.c
index 5b4223e..539d33e 100644
--- a/lib/libc/string/memccpy.c
+++ b/lib/libc/string/memccpy.c
@@ -36,11 +36,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
void *
-memccpy(t, f, c, n)
- void *t;
- const void *f;
- int c;
- size_t n;
+memccpy(void *t, const void *f, int c, size_t n)
{
if (n) {
diff --git a/lib/libc/string/memchr.c b/lib/libc/string/memchr.c
index 2b1231d..6d7c2fd 100644
--- a/lib/libc/string/memchr.c
+++ b/lib/libc/string/memchr.c
@@ -39,10 +39,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
void *
-memchr(s, c, n)
- const void *s;
- unsigned char c;
- size_t n;
+memchr(const void *s, int c, size_t n)
{
if (n != 0) {
const unsigned char *p = s;
diff --git a/lib/libc/string/memcmp.c b/lib/libc/string/memcmp.c
index d048068..4a1b66e 100644
--- a/lib/libc/string/memcmp.c
+++ b/lib/libc/string/memcmp.c
@@ -42,9 +42,7 @@ __FBSDID("$FreeBSD$");
* Compare memory regions.
*/
int
-memcmp(s1, s2, n)
- const void *s1, *s2;
- size_t n;
+memcmp(const void *s1, const void *s2, size_t n)
{
if (n != 0) {
const unsigned char *p1 = s1, *p2 = s2;
diff --git a/lib/libc/string/memmem.c b/lib/libc/string/memmem.c
index 0ac0a6d..72e6517 100644
--- a/lib/libc/string/memmem.c
+++ b/lib/libc/string/memmem.c
@@ -36,9 +36,7 @@ __FBSDID("$FreeBSD$");
*/
void *
-memmem(l, l_len, s, s_len)
- const void *l; size_t l_len;
- const void *s; size_t s_len;
+memmem(const void *l, size_t l_len, const void *s, size_t s_len)
{
register char *cur, *last;
const char *cl = (const char *)l;
diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c
index 2efcf55..4a474fe 100644
--- a/lib/libc/string/strcasecmp.c
+++ b/lib/libc/string/strcasecmp.c
@@ -39,8 +39,7 @@ __FBSDID("$FreeBSD$");
typedef unsigned char u_char;
int
-strcasecmp(s1, s2)
- const char *s1, *s2;
+strcasecmp(const char *s1, const char *s2)
{
const u_char
*us1 = (const u_char *)s1,
@@ -53,9 +52,7 @@ strcasecmp(s1, s2)
}
int
-strncasecmp(s1, s2, n)
- const char *s1, *s2;
- size_t n;
+strncasecmp(const char *s1, const char *s2, size_t n)
{
if (n != 0) {
const u_char
diff --git a/lib/libc/string/strcasestr.c b/lib/libc/string/strcasestr.c
index b358b7d..9b28bf5 100644
--- a/lib/libc/string/strcasestr.c
+++ b/lib/libc/string/strcasestr.c
@@ -40,8 +40,7 @@ __FBSDID("$FreeBSD$");
* Find the first occurrence of find in s, ignore case.
*/
char *
-strcasestr(s, find)
- const char *s, *find;
+strcasestr(const char *s, const char *find)
{
char c, sc;
size_t len;
diff --git a/lib/libc/string/strcmp.c b/lib/libc/string/strcmp.c
index ab95333..95c778d 100644
--- a/lib/libc/string/strcmp.c
+++ b/lib/libc/string/strcmp.c
@@ -42,11 +42,10 @@ __FBSDID("$FreeBSD$");
* Compare strings.
*/
int
-strcmp(s1, s2)
- const char *s1, *s2;
+strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2++)
- if (*s1++ == 0)
+ if (*s1++ == '\0')
return (0);
return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}
diff --git a/lib/libc/string/strcoll.c b/lib/libc/string/strcoll.c
index a0daf8d..0da5c57 100644
--- a/lib/libc/string/strcoll.c
+++ b/lib/libc/string/strcoll.c
@@ -33,8 +33,7 @@ __FBSDID("$FreeBSD$");
#include "collate.h"
int
-strcoll(s, s2)
- const char *s, *s2;
+strcoll(const char *s, const char *s2)
{
int len, len2, prim, prim2, sec, sec2, ret, ret2;
const char *t, *t2;
diff --git a/lib/libc/string/strdup.c b/lib/libc/string/strdup.c
index c0b581d..570ad83 100644
--- a/lib/libc/string/strdup.c
+++ b/lib/libc/string/strdup.c
@@ -38,8 +38,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
char *
-strdup(str)
- const char *str;
+strdup(const char *str)
{
size_t len;
char *copy;
diff --git a/lib/libc/string/strlcat.c b/lib/libc/string/strlcat.c
index 7f19f6b..feeac3b 100644
--- a/lib/libc/string/strlcat.c
+++ b/lib/libc/string/strlcat.c
@@ -1,35 +1,21 @@
-/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */
+/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.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:
- * 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 the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * 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.
*
- * THIS SOFTWARE IS PROVIDED ``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.
+ * 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.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $";
-#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -44,10 +30,7 @@ __FBSDID("$FreeBSD$");
* If retval >= siz, truncation occurred.
*/
size_t
-strlcat(dst, src, siz)
- char *dst;
- const char *src;
- size_t siz;
+strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
diff --git a/lib/libc/string/strlcpy.3 b/lib/libc/string/strlcpy.3
index f674fe2..88af06d 100644
--- a/lib/libc/string/strlcpy.3
+++ b/lib/libc/string/strlcpy.3
@@ -1,18 +1,18 @@
-.\" $OpenBSD: strlcpy.3,v 1.5 1999/06/06 15:17:32 aaron Exp $
+.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $
.\"
-.\" Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
-.\" All rights reserved.
+.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
-.\" 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 the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
+.\" 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.
.\"
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
@@ -64,7 +64,7 @@ is larger than 0 or, in the case of
.Fn strlcat ,
as long as there is at least one byte free in
.Fa dst ) .
-Note that you should include a byte for the NUL in
+Note that a byte for the NUL should be included in
.Fa size .
Also note that
.Fn strlcpy
@@ -121,7 +121,7 @@ that means the initial length of
plus
the length of
.Fa src .
-While this may seem somewhat confusing it was done to make
+While this may seem somewhat confusing, it was done to make
truncation detection simple.
.Pp
Note however, that if
@@ -168,8 +168,8 @@ if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
goto toolong;
.Ed
.Pp
-Since we know how many characters we copied the first time, we can
-speed things up a bit by using a copy instead of an append:
+Since it is known how many characters were copied the first time, things
+can be sped up a bit by using a copy instead of an append
.Bd -literal -offset indent
char *dir, *file, pname[MAXPATHLEN];
size_t n;
diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c
index db4fe26..860a988 100644
--- a/lib/libc/string/strlen.c
+++ b/lib/libc/string/strlen.c
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2009 Xin LI <delphij@FreeBSD.org>
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,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)
@@ -27,21 +24,87 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strlen.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/limits.h>
+#include <sys/types.h>
#include <string.h>
+/*
+ * Portable strlen() for 32-bit and 64-bit systems.
+ *
+ * Rationale: it is generally much more efficient to do word length
+ * operations and avoid branches on modern computer systems, as
+ * compared to byte-length operations with a lot of branches.
+ *
+ * The expression:
+ *
+ * ((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:
+ *
+ * ((x - 0x01....01) & 0x80....80)
+ *
+ * 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.
+ */
+
+/* Magic numbers for the algorithm */
+#if LONG_BIT == 32
+static const unsigned long mask01 = 0x01010101;
+static const unsigned long mask80 = 0x80808080;
+#elif LONG_BIT == 64
+static const unsigned long mask01 = 0x0101010101010101;
+static const unsigned long mask80 = 0x8080808080808080;
+#else
+#error Unsupported word size
+#endif
+
+#define LONGPTR_MASK (sizeof(long) - 1)
+
+/*
+ * Helper macro to return string length if we caught the zero
+ * byte.
+ */
+#define testbyte(x) \
+ do { \
+ if (p[x] == '\0') \
+ return (p - str + x); \
+ } while (0)
+
size_t
-strlen(str)
- const char *str;
+strlen(const char *str)
{
- const char *s;
+ const char *p;
+ const unsigned long *lp;
+
+ /* 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);
+
+ /* 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);
+#if (LONG_BIT >= 64)
+ testbyte(4);
+ testbyte(5);
+ testbyte(6);
+ testbyte(7);
+#endif
+ }
- for (s = str; *s; ++s);
- return(s - str);
+ /* NOTREACHED */
+ return (0);
}
diff --git a/lib/libc/string/strmode.c b/lib/libc/string/strmode.c
index be09d7a..57295d7 100644
--- a/lib/libc/string/strmode.c
+++ b/lib/libc/string/strmode.c
@@ -38,9 +38,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
void
-strmode(mode, p)
- mode_t mode;
- char *p;
+strmode(/* mode_t */ int mode, char *p)
{
/* print type */
switch (mode & S_IFMT) {
diff --git a/lib/libc/string/strncmp.c b/lib/libc/string/strncmp.c
index 659a7cb..5bc3d5e 100644
--- a/lib/libc/string/strncmp.c
+++ b/lib/libc/string/strncmp.c
@@ -36,9 +36,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
int
-strncmp(s1, s2, n)
- const char *s1, *s2;
- size_t n;
+strncmp(const char *s1, const char *s2, size_t n)
{
if (n == 0)
@@ -47,7 +45,7 @@ strncmp(s1, s2, n)
if (*s1 != *s2++)
return (*(const unsigned char *)s1 -
*(const unsigned char *)(s2 - 1));
- if (*s1++ == 0)
+ if (*s1++ == '\0')
break;
} while (--n != 0);
return (0);
diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c
index 07b9166..980dbc7 100644
--- a/lib/libc/string/strncpy.c
+++ b/lib/libc/string/strncpy.c
@@ -50,10 +50,10 @@ strncpy(char * __restrict dst, const char * __restrict src, size_t n)
const char *s = src;
do {
- if ((*d++ = *s++) == 0) {
+ if ((*d++ = *s++) == '\0') {
/* NUL pad the remaining n-1 bytes */
while (--n != 0)
- *d++ = 0;
+ *d++ = '\0';
break;
}
} while (--n != 0);
diff --git a/lib/libc/string/strnstr.c b/lib/libc/string/strnstr.c
index bbb1ca6..45be95d 100644
--- a/lib/libc/string/strnstr.c
+++ b/lib/libc/string/strnstr.c
@@ -44,10 +44,7 @@ __FBSDID("$FreeBSD$");
* first slen characters of s.
*/
char *
-strnstr(s, find, slen)
- const char *s;
- const char *find;
- size_t slen;
+strnstr(const char *s, const char *find, size_t slen)
{
char c, sc;
size_t len;
diff --git a/lib/libc/string/strpbrk.c b/lib/libc/string/strpbrk.c
index efbdc8a..2069bee 100644
--- a/lib/libc/string/strpbrk.c
+++ b/lib/libc/string/strpbrk.c
@@ -39,14 +39,13 @@ __FBSDID("$FreeBSD$");
* Find the first occurrence in s1 of a character in s2 (excluding NUL).
*/
char *
-strpbrk(s1, s2)
- const char *s1, *s2;
+strpbrk(const char *s1, const char *s2)
{
const char *scanp;
int c, sc;
while ((c = *s1++) != 0) {
- for (scanp = s2; (sc = *scanp++) != 0;)
+ for (scanp = s2; (sc = *scanp++) != '\0';)
if (sc == c)
return ((char *)(s1 - 1));
}
diff --git a/lib/libc/string/strsep.c b/lib/libc/string/strsep.c
index 0850b0b..670ab04 100644
--- a/lib/libc/string/strsep.c
+++ b/lib/libc/string/strsep.c
@@ -48,9 +48,7 @@ __FBSDID("$FreeBSD$");
* If *stringp is NULL, strsep returns NULL.
*/
char *
-strsep(stringp, delim)
- char **stringp;
- const char *delim;
+strsep(char **stringp, const char *delim)
{
char *s;
const char *spanp;
diff --git a/lib/libc/string/strstr.c b/lib/libc/string/strstr.c
index e2edd80..82b4c5a 100644
--- a/lib/libc/string/strstr.c
+++ b/lib/libc/string/strstr.c
@@ -42,17 +42,16 @@ __FBSDID("$FreeBSD$");
* Find the first occurrence of find in s.
*/
char *
-strstr(s, find)
- const char *s, *find;
+strstr(const char *s, const char *find)
{
char c, sc;
size_t len;
- if ((c = *find++) != 0) {
+ if ((c = *find++) != '\0') {
len = strlen(find);
do {
do {
- if ((sc = *s++) == 0)
+ if ((sc = *s++) == '\0')
return (NULL);
} while (sc != c);
} while (strncmp(s, find, len) != 0);
diff --git a/lib/libc/string/wcscat.c b/lib/libc/string/wcscat.c
index 1c96533..7ae4e80 100644
--- a/lib/libc/string/wcscat.c
+++ b/lib/libc/string/wcscat.c
@@ -37,9 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wcscat(s1, s2)
- wchar_t * __restrict s1;
- const wchar_t * __restrict s2;
+wcscat(wchar_t * __restrict s1, const wchar_t * __restrict s2)
{
wchar_t *cp;
diff --git a/lib/libc/string/wcscmp.c b/lib/libc/string/wcscmp.c
index 59c3eef..2d48914 100644
--- a/lib/libc/string/wcscmp.c
+++ b/lib/libc/string/wcscmp.c
@@ -45,12 +45,11 @@ __FBSDID("$FreeBSD$");
* Compare strings.
*/
int
-wcscmp(s1, s2)
- const wchar_t *s1, *s2;
+wcscmp(const wchar_t *s1, const wchar_t *s2)
{
while (*s1 == *s2++)
- if (*s1++ == 0)
+ if (*s1++ == '\0')
return (0);
/* XXX assumes wchar_t = int */
return (*(const unsigned int *)s1 - *(const unsigned int *)--s2);
diff --git a/lib/libc/string/wcscpy.c b/lib/libc/string/wcscpy.c
index 180bbd1..0c6e1f2 100644
--- a/lib/libc/string/wcscpy.c
+++ b/lib/libc/string/wcscpy.c
@@ -37,9 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wcscpy(s1, s2)
- wchar_t * __restrict s1;
- const wchar_t * __restrict s2;
+wcscpy(wchar_t * __restrict s1, const wchar_t * __restrict s2)
{
wchar_t *cp;
diff --git a/lib/libc/string/wcscspn.c b/lib/libc/string/wcscspn.c
index 57a804c..7729dc8 100644
--- a/lib/libc/string/wcscspn.c
+++ b/lib/libc/string/wcscspn.c
@@ -37,9 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
size_t
-wcscspn(s, set)
- const wchar_t *s;
- const wchar_t *set;
+wcscspn(const wchar_t *s, const wchar_t *set)
{
const wchar_t *p;
const wchar_t *q;
diff --git a/lib/libc/string/wcslcat.c b/lib/libc/string/wcslcat.c
index 6466f06..f5f1e1e 100644
--- a/lib/libc/string/wcslcat.c
+++ b/lib/libc/string/wcslcat.c
@@ -46,10 +46,7 @@ __FBSDID("$FreeBSD$");
* truncation occurred.
*/
size_t
-wcslcat(dst, src, siz)
- wchar_t *dst;
- const wchar_t *src;
- size_t siz;
+wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
{
wchar_t *d = dst;
const wchar_t *s = src;
diff --git a/lib/libc/string/wcslcpy.c b/lib/libc/string/wcslcpy.c
index 1b9459a..b104a06 100644
--- a/lib/libc/string/wcslcpy.c
+++ b/lib/libc/string/wcslcpy.c
@@ -44,10 +44,7 @@ __FBSDID("$FreeBSD$");
* Returns wcslen(src); if retval >= siz, truncation occurred.
*/
size_t
-wcslcpy(dst, src, siz)
- wchar_t *dst;
- const wchar_t *src;
- size_t siz;
+wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
{
wchar_t *d = dst;
const wchar_t *s = src;
diff --git a/lib/libc/string/wcslen.c b/lib/libc/string/wcslen.c
index 1636d98..ca3004e 100644
--- a/lib/libc/string/wcslen.c
+++ b/lib/libc/string/wcslen.c
@@ -37,8 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
size_t
-wcslen(s)
- const wchar_t *s;
+wcslen(const wchar_t *s)
{
const wchar_t *p;
diff --git a/lib/libc/string/wcsncat.c b/lib/libc/string/wcsncat.c
index ba49a9e..44f1ff9 100644
--- a/lib/libc/string/wcsncat.c
+++ b/lib/libc/string/wcsncat.c
@@ -37,10 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wcsncat(s1, s2, n)
- wchar_t * __restrict s1;
- const wchar_t * __restrict s2;
- size_t n;
+wcsncat(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n)
{
wchar_t *p;
wchar_t *q;
diff --git a/lib/libc/string/wcsncmp.c b/lib/libc/string/wcsncmp.c
index 5b7b3ee..86d7a51 100644
--- a/lib/libc/string/wcsncmp.c
+++ b/lib/libc/string/wcsncmp.c
@@ -39,9 +39,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
int
-wcsncmp(s1, s2, n)
- const wchar_t *s1, *s2;
- size_t n;
+wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
{
if (n == 0)
diff --git a/lib/libc/string/wcspbrk.c b/lib/libc/string/wcspbrk.c
index 7315c44..2ff71ba 100644
--- a/lib/libc/string/wcspbrk.c
+++ b/lib/libc/string/wcspbrk.c
@@ -37,9 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wcspbrk(s, set)
- const wchar_t *s;
- const wchar_t *set;
+wcspbrk(const wchar_t *s, const wchar_t *set)
{
const wchar_t *p;
const wchar_t *q;
diff --git a/lib/libc/string/wcsspn.c b/lib/libc/string/wcsspn.c
index 584a9d3..6569206 100644
--- a/lib/libc/string/wcsspn.c
+++ b/lib/libc/string/wcsspn.c
@@ -37,9 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
size_t
-wcsspn(s, set)
- const wchar_t *s;
- const wchar_t *set;
+wcsspn(const wchar_t *s, const wchar_t *set)
{
const wchar_t *p;
const wchar_t *q;
diff --git a/lib/libc/string/wcsstr.c b/lib/libc/string/wcsstr.c
index b8a7598..a9dc27b 100644
--- a/lib/libc/string/wcsstr.c
+++ b/lib/libc/string/wcsstr.c
@@ -49,7 +49,7 @@ wcsstr(const wchar_t * __restrict s, const wchar_t * __restrict find)
wchar_t c, sc;
size_t len;
- if ((c = *find++) != 0) {
+ if ((c = *find++) != L'\0') {
len = wcslen(find);
do {
do {
diff --git a/lib/libc/string/wmemchr.c b/lib/libc/string/wmemchr.c
index 2d96708..cab89c9 100644
--- a/lib/libc/string/wmemchr.c
+++ b/lib/libc/string/wmemchr.c
@@ -37,10 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wmemchr(s, c, n)
- const wchar_t *s;
- wchar_t c;
- size_t n;
+wmemchr(const wchar_t *s, wchar_t c, size_t n)
{
size_t i;
diff --git a/lib/libc/string/wmemcmp.c b/lib/libc/string/wmemcmp.c
index c9a9095..fdb1f986 100644
--- a/lib/libc/string/wmemcmp.c
+++ b/lib/libc/string/wmemcmp.c
@@ -37,10 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
int
-wmemcmp(s1, s2, n)
- const wchar_t *s1;
- const wchar_t *s2;
- size_t n;
+wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n)
{
size_t i;
diff --git a/lib/libc/string/wmemcpy.c b/lib/libc/string/wmemcpy.c
index 38d563d..c10770c 100644
--- a/lib/libc/string/wmemcpy.c
+++ b/lib/libc/string/wmemcpy.c
@@ -38,11 +38,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wmemcpy(d, s, n)
- wchar_t * __restrict d;
- const wchar_t * __restrict s;
- size_t n;
+wmemcpy(wchar_t * __restrict d, const wchar_t * __restrict s, size_t n)
{
-
return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t));
}
diff --git a/lib/libc/string/wmemmove.c b/lib/libc/string/wmemmove.c
index 6b3ee94..05cfd10 100644
--- a/lib/libc/string/wmemmove.c
+++ b/lib/libc/string/wmemmove.c
@@ -38,11 +38,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wmemmove(d, s, n)
- wchar_t *d;
- const wchar_t *s;
- size_t n;
+wmemmove(wchar_t *d, const wchar_t *s, size_t n)
{
-
return (wchar_t *)memmove(d, s, n * sizeof(wchar_t));
}
diff --git a/lib/libc/string/wmemset.c b/lib/libc/string/wmemset.c
index b923f14..0e96356 100644
--- a/lib/libc/string/wmemset.c
+++ b/lib/libc/string/wmemset.c
@@ -37,10 +37,7 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
wchar_t *
-wmemset(s, c, n)
- wchar_t *s;
- wchar_t c;
- size_t n;
+wmemset(wchar_t *s, wchar_t c, size_t n)
{
size_t i;
wchar_t *p;
diff --git a/lib/libc/sys/jail.2 b/lib/libc/sys/jail.2
index f7b3912..cdf89dc 100644
--- a/lib/libc/sys/jail.2
+++ b/lib/libc/sys/jail.2
@@ -8,7 +8,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 29, 2008
+.Dd January 6, 2009
.Dt JAIL 2
.Os
.Sh NAME
@@ -118,6 +118,12 @@ or, if present, the per-jail
.Pp
All IP activity will be forced to happen to/from the IP number specified,
which should be an alias on one of the network interfaces.
+All connections to/from the loopback address
+.Pf ( Li 127.0.0.1
+for IPv4,
+.Li ::1
+for IPv6) will be changed to be to/from the primary address
+of the jail for the given address family.
.Pp
It is possible to identify a process as jailed by examining
.Dq Li /proc/<pid>/status :
diff --git a/lib/libc/sys/send.2 b/lib/libc/sys/send.2
index 6a61426..8fa2c64 100644
--- a/lib/libc/sys/send.2
+++ b/lib/libc/sys/send.2
@@ -28,7 +28,7 @@
.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
.\" $FreeBSD$
.\"
-.Dd September 13, 2006
+.Dd February 5, 2009
.Dt SEND 2
.Os
.Sh NAME
@@ -190,7 +190,7 @@ receiver is not listening on the remote port.
The remote host was down.
.It Bq Er ENETDOWN
The remote network was down.
-.It Bq Er EPERM
+.It Bq Er EADDRNOTAVAIL
The process using a
.Dv SOCK_RAW
socket was jailed and the source
diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2
index ce4c1fb..dae33d0 100644
--- a/lib/libc/sys/socket.2
+++ b/lib/libc/sys/socket.2
@@ -28,7 +28,7 @@
.\" From: @(#)socket.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd August 4, 2008
+.Dd January 5, 2009
.Dt SOCKET 2
.Os
.Sh NAME
@@ -131,6 +131,11 @@ in which communication
is to take place; see
.Xr protocols 5 .
.Pp
+The
+.Fa protocol
+argument may be set to zero (0) to request the default
+implementation of a socket type for the protocol, if any.
+.Pp
Sockets of type
.Dv SOCK_STREAM
are full-duplex byte streams, similar
diff --git a/lib/libc/sys/timer_create.2 b/lib/libc/sys/timer_create.2
index 36eae43..3fb415c 100644
--- a/lib/libc/sys/timer_create.2
+++ b/lib/libc/sys/timer_create.2
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 11, 2000
+.Dd January 12, 2009
.Dt TIMER_CREATE 2
.Os
.Sh NAME
@@ -37,6 +37,7 @@
.Lb librt
.Sh SYNOPSIS
.In time.h
+.In signal.h
.Ft int
.Fo timer_create
.Fa "clockid_t clockid" "struct sigevent *restrict evp"
@@ -100,7 +101,7 @@ or
.Dv CLOCK_MONOTONIC .
.Pp
If
-.Fa evp->sigev_sigev_notify
+.Fa evp->sigev_notify
is
.Dv SIGEV_THREAD
and
diff --git a/lib/libelf/README b/lib/libelf/README
new file mode 100644
index 0000000..726fcc9
--- /dev/null
+++ b/lib/libelf/README
@@ -0,0 +1,12 @@
+# $FreeBSD$
+# $NetBSD$
+
+libelf: a BSD-licensed implementation of the ELF(3)/GELF(3) API.
+
+Documentation:
+ * Manual page elf.3 contains an overview of the library. Other
+ manual pages document individual APIs in the library.
+ * A tutorial "libelf by Example" is available at:
+ http://people.freebsd.org/~jkoshy/download/libelf/article.html
+
+For ongoing development please see http://elftoolchain.sourceforge.net/
diff --git a/lib/libmagic/Makefile b/lib/libmagic/Makefile
index 97d2752..fc604d2 100644
--- a/lib/libmagic/Makefile
+++ b/lib/libmagic/Makefile
@@ -19,9 +19,9 @@ MAGICPATH?= /usr/share/misc
CFLAGS+= -DMAGIC='"${MAGICPATH}/magic"' -DHAVE_CONFIG_H
CFLAGS+= -I${.CURDIR} -I${CONTRDIR}
-CLEANFILES+= magic magic.mgc magic.mime.mgc
+CLEANFILES+= magic magic.mgc
-FILES= magic magic.mgc ${CONTRDIR}/magic.mime magic.mime.mgc
+FILES= magic magic.mgc
FILESDIR= ${MAGICPATH}
MAGFILES= ${CONTRDIR}/Header\
@@ -34,9 +34,6 @@ magic: ${MAGFILES}
magic.mgc: mkmagic magic
./mkmagic magic
-magic.mime.mgc: mkmagic magic.mime
- ./mkmagic ${CONTRDIR}/magic.mime
-
CLEANFILES+= mkmagic
build-tools: mkmagic
mkmagic: apprentice.c funcs.c magic.c print.c
diff --git a/lib/libmd/mdX.3 b/lib/libmd/mdX.3
index c0567c5..03f50f1 100644
--- a/lib/libmd/mdX.3
+++ b/lib/libmd/mdX.3
@@ -164,11 +164,6 @@ argument is non-null it must point to at least 33 characters of buffer space.
.%O RFC 1321
.Re
.Rs
-.%A RSA Laboratories
-.%T Frequently Asked Questions About today's Cryptography
-.%O \&<http://www.rsa.com/rsalabs/faq/>
-.Re
-.Rs
.%A H. Dobbertin
.%T Alf Swindles Ann
.%J CryptoBytes
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 21bd995..b1d6653 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -152,6 +152,11 @@ static const struct pmc_event_descr core2_event_table[] =
__PMC_EV_ALIAS_CORE2()
};
+static const struct pmc_event_descr corei7_event_table[] =
+{
+ __PMC_EV_ALIAS_COREI7()
+};
+
/*
* PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...)
*
@@ -165,6 +170,7 @@ static const struct pmc_event_descr core2_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(k7, K7, PMC_CLASS_TSC);
PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
@@ -194,6 +200,7 @@ PMC_CLASS_TABLE_DESC(iaf, IAF, iaf, iaf);
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);
#endif
#if defined(__i386__)
PMC_CLASS_TABLE_DESC(k7, K7, k7, k7);
@@ -448,6 +455,7 @@ static struct pmc_event_alias core2_aliases[] = {
EV_ALIAS(NULL, NULL)
};
#define atom_aliases core2_aliases
+#define corei7_aliases core2_aliases
#define IAF_KW_OS "os"
#define IAF_KW_USR "usr"
@@ -604,7 +612,8 @@ 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_CORE2EXTREME ||
+ cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7) {
if (KWMATCH(p, IAP_KW_SNOOPRESPONSE)) {
n = pmc_parse_mask(iap_snoopresponse_mask, p,
&evmask);
@@ -2278,6 +2287,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = core2_event_table;
count = PMC_EVENT_TABLE_SIZE(core2);
break;
+ case PMC_CPU_INTEL_COREI7:
+ ev = corei7_event_table;
+ count = PMC_EVENT_TABLE_SIZE(corei7);
+ break;
}
break;
case PMC_CLASS_TSC:
@@ -2462,6 +2475,11 @@ pmc_init(void)
pmc_class_table[n++] = &iaf_class_table_descr;
pmc_class_table[n] = &core2_class_table_descr;
break;
+ case PMC_CPU_INTEL_COREI7:
+ PMC_MDEP_INIT(corei7);
+ pmc_class_table[n++] = &iaf_class_table_descr;
+ pmc_class_table[n] = &corei7_class_table_descr;
+ break;
case PMC_CPU_INTEL_PIV:
PMC_MDEP_INIT(p4);
pmc_class_table[n] = &p4_class_table_descr;
@@ -2560,6 +2578,10 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
ev = core2_event_table;
evfence = core2_event_table + PMC_EVENT_TABLE_SIZE(core2);
break;
+ case PMC_CPU_INTEL_COREI7:
+ ev = corei7_event_table;
+ evfence = corei7_event_table + PMC_EVENT_TABLE_SIZE(corei7);
+ break;
default: /* Unknown CPU type. */
break;
}
diff --git a/lib/libstand/bootp.c b/lib/libstand/bootp.c
index 4ddfa6c..401b691 100644
--- a/lib/libstand/bootp.c
+++ b/lib/libstand/bootp.c
@@ -496,7 +496,7 @@ static struct dhcp_opt vndr_opt[] = { /* Vendor Specific Options */
{94, __BYTES, "network-interface"},
{97, __BYTES, "machine-identifier"},
#else /* default (empty) table */
- {0, 0, ""}, /* prefix */
+ {0, 0, "dhcp.vendor."}, /* prefix */
#endif
{0, __TXT, "%soption-%d"}
};
diff --git a/lib/libusb20/libusb20.c b/lib/libusb20/libusb20.c
index f9c99cb..e9ef1fc 100644
--- a/lib/libusb20/libusb20.c
+++ b/lib/libusb20/libusb20.c
@@ -486,6 +486,8 @@ libusb20_dev_close(struct libusb20_device *pdev)
pdev->is_opened = 0;
+ pdev->claimed_interfaces = 0;
+
return (error);
}
diff --git a/lib/libusb20/libusb20_desc.c b/lib/libusb20/libusb20_desc.c
index bba4d25..e0d2c54 100644
--- a/lib/libusb20/libusb20_desc.c
+++ b/lib/libusb20/libusb20_desc.c
@@ -238,23 +238,37 @@ const uint8_t *
libusb20_desc_foreach(const struct libusb20_me_struct *pdesc,
const uint8_t *psubdesc)
{
- const void *end;
+ const uint8_t *start;
+ const uint8_t *end;
+ const uint8_t *desc_next;
- if (pdesc == NULL) {
+ /* be NULL safe */
+ if (pdesc == NULL)
return (NULL);
- }
- end = LIBUSB20_ADD_BYTES(pdesc->ptr, pdesc->len);
- if (psubdesc == NULL) {
- psubdesc = LIBUSB20_ADD_BYTES(pdesc->ptr, 0);
- } else {
- psubdesc = LIBUSB20_ADD_BYTES(psubdesc, psubdesc[0]);
- }
- return (((((const void *)psubdesc) >= ((void *)(pdesc->ptr))) &&
- (((const void *)psubdesc) < end) &&
- (LIBUSB20_ADD_BYTES(psubdesc, psubdesc[0]) >= ((void *)(pdesc->ptr))) &&
- (LIBUSB20_ADD_BYTES(psubdesc, psubdesc[0]) <= end) &&
- (psubdesc[0] >= 3)) ? psubdesc : NULL);
+ start = (const uint8_t *)pdesc->ptr;
+ end = LIBUSB20_ADD_BYTES(start, pdesc->len);
+
+ /* get start of next descriptor */
+ if (psubdesc == NULL)
+ psubdesc = start;
+ else
+ psubdesc = psubdesc + psubdesc[0];
+
+ /* check that the next USB descriptor is within the range */
+ if ((psubdesc < start) || (psubdesc >= end))
+ return (NULL); /* out of range, or EOD */
+
+ /* check start of the second next USB descriptor, if any */
+ desc_next = psubdesc + psubdesc[0];
+ if ((desc_next < start) || (desc_next > end))
+ return (NULL); /* out of range */
+
+ /* check minimum descriptor length */
+ if (psubdesc[0] < 3)
+ return (NULL); /* too short descriptor */
+
+ return (psubdesc); /* return start of next descriptor */
}
/*------------------------------------------------------------------------*
diff --git a/lib/libusbhid/Makefile b/lib/libusbhid/Makefile
index 23b4068..d681302 100644
--- a/lib/libusbhid/Makefile
+++ b/lib/libusbhid/Makefile
@@ -15,7 +15,7 @@ MLINKS= usbhid.3 libusbhid.3 usbhid.3 hid_get_report_desc.3 \
usbhid.3 hid_init.3 \
usbhid.3 hid_get_data.3 usbhid.3 hid_set_data.3
-SRCS= descr.c parse.c usage.c data.c
+SRCS= descr.c descr_compat.c parse.c usage.c data.c
INCS= usbhid.h
diff --git a/lib/libusbhid/descr.c b/lib/libusbhid/descr.c
index 4afdb61..cc1737b 100644
--- a/lib/libusbhid/descr.c
+++ b/lib/libusbhid/descr.c
@@ -39,21 +39,83 @@ __FBSDID("$FreeBSD$");
#include <sys/time.h>
#include <sys/ioctl.h>
-#include <dev/usb/usb.h>
+#include <dev/usb2/include/usb2_ioctl.h>
#include "usbhid.h"
#include "usbvar.h"
+int
+hid_set_immed(int fd, int enable)
+{
+ int ret;
+ ret = ioctl(fd, USB_SET_IMMED, &enable);
+ if (ret < 0)
+ ret = hid_set_immed_compat7(fd, enable);
+ return (ret);
+}
+
+int
+hid_get_report_id(int fd)
+{
+ int temp = -1;
+ int ret;
+
+ ret = ioctl(fd, USB_GET_REPORT_ID, &temp);
+ if (ret < 0)
+ ret = hid_get_report_id_compat7(fd);
+ else
+ ret = temp;
+
+ return (ret);
+}
+
report_desc_t
hid_get_report_desc(int fd)
{
- struct usb_ctl_report_desc rep;
+ struct usb2_gen_descriptor ugd;
+ report_desc_t rep;
+ void *data;
- rep.ucrd_size = 0;
- if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0)
+ memset(&ugd, 0, sizeof(ugd));
+
+ /* get actual length first */
+ ugd.ugd_data = NULL;
+ ugd.ugd_maxlen = 65535;
+ if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) {
+ /* could not read descriptor */
+ /* try FreeBSD 7 compat code */
+ return (hid_get_report_desc_compat7(fd));
+ }
+
+ /*
+ * NOTE: The kernel will return a failure if
+ * "ugd_actlen" is zero.
+ */
+ data = malloc(ugd.ugd_actlen);
+ if (data == NULL)
+ return (NULL);
+
+ /* fetch actual descriptor */
+ ugd.ugd_data = data;
+ ugd.ugd_maxlen = ugd.ugd_actlen;
+ if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) {
+ /* could not read descriptor */
+ free(data);
return (NULL);
+ }
+
+ /* check END_COLLECTION */
+ if (((unsigned char *)ugd.ugd_data)[ugd.ugd_actlen -1] != 0xC0) {
+ /* invalid end byte */
+ free(data);
+ return (NULL);
+ }
+
+ rep = hid_use_report_desc(data, ugd.ugd_actlen);
+
+ free(data);
- return hid_use_report_desc(rep.ucrd_data, (unsigned int)rep.ucrd_size);
+ return (rep);
}
report_desc_t
diff --git a/lib/libusbhid/descr_compat.c b/lib/libusbhid/descr_compat.c
new file mode 100644
index 0000000..3cbcdbf
--- /dev/null
+++ b/lib/libusbhid/descr_compat.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.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.
+ */
+
+/*
+ * This file contains fallback-compatibility code for the old FreeBSD
+ * USB stack.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include <dev/usb/usb.h>
+
+#include "usbhid.h"
+#include "usbvar.h"
+
+int
+hid_set_immed_compat7(int fd, int enable)
+{
+ return (ioctl(fd, USB_SET_IMMED, &enable));
+}
+
+int
+hid_get_report_id_compat7(int fd)
+{
+ int temp = -1;
+
+ if (ioctl(fd, USB_GET_REPORT_ID, &temp) < 0)
+ return (-1);
+
+ return (temp);
+}
+
+report_desc_t
+hid_get_report_desc_compat7(int fd)
+{
+ struct usb_ctl_report_desc rep;
+
+ rep.ucrd_size = 0;
+ if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0)
+ return (NULL);
+
+ return (hid_use_report_desc(rep.ucrd_data, (unsigned int)rep.ucrd_size));
+}
diff --git a/lib/libusbhid/usbhid.3 b/lib/libusbhid/usbhid.3
index a11709b..b4951f2 100644
--- a/lib/libusbhid/usbhid.3
+++ b/lib/libusbhid/usbhid.3
@@ -26,12 +26,13 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 29, 2001
+.Dd January 27, 2009
.Dt USBHID 3
.Os
.Sh NAME
.Nm usbhid ,
.Nm hid_get_report_desc ,
+.Nm hid_get_report_id ,
.Nm hid_use_report_desc ,
.Nm hid_dispose_report_desc ,
.Nm hid_start_parse ,
@@ -51,6 +52,10 @@
.In usbhid.h
.Ft report_desc_t
.Fn hid_get_report_desc "int file"
+.Ft int
+.Fn hid_get_report_id "int file"
+.Ft int
+.Fn hid_set_immed "int fd" "int enable"
.Ft report_desc_t
.Fn hid_use_report_desc "unsigned char *data" "unsigned int size"
.Ft void
@@ -94,7 +99,15 @@ which contains the data layout information and then use this information.
The routines can be divided into four parts: extraction of the descriptor,
parsing of the descriptor, translating to/from symbolic names, and
data manipulation.
+.Ss Synchronous HID operation
+Synchronous HID operation can be enabled or disabled by a call to
+.Fn hid_set_immed .
+If the second argument is zero synchronous HID operation is disabled.
+Else synchronous HID operation is enabled.
+The function returns a negative value on failure.
.Ss Descriptor Functions
+The report descriptor ID can be obtained by calling
+.Fn hid_get_report_id .
A report descriptor can be obtained by calling
.Fn hid_get_report_desc
with a file descriptor obtained by opening a
diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h
index af3228f..b8751cd 100644
--- a/lib/libusbhid/usbhid.h
+++ b/lib/libusbhid/usbhid.h
@@ -87,6 +87,8 @@ __BEGIN_DECLS
report_desc_t hid_get_report_desc(int file);
report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size);
void hid_dispose_report_desc(report_desc_t);
+int hid_get_report_id(int file);
+int hid_set_immed(int fd, int enable);
/* Parsing of a HID report descriptor, parse.c: */
hid_data_t hid_start_parse(report_desc_t d, int kindset, int id);
diff --git a/lib/libusbhid/usbvar.h b/lib/libusbhid/usbvar.h
index 7ed04e5..b8fbf37 100644
--- a/lib/libusbhid/usbvar.h
+++ b/lib/libusbhid/usbvar.h
@@ -34,3 +34,8 @@ struct report_desc {
unsigned char data[1];
};
+/* internal backwards compatibility functions */
+
+int hid_set_immed_compat7(int fd, int enable);
+int hid_get_report_id_compat7(int fd);
+report_desc_t hid_get_report_desc_compat7(int fd);
diff --git a/lib/msun/src/e_rem_pio2.c b/lib/msun/src/e_rem_pio2.c
index f68df9a..f94efe5 100644
--- a/lib/msun/src/e_rem_pio2.c
+++ b/lib/msun/src/e_rem_pio2.c
@@ -49,7 +49,7 @@ pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
#ifdef INLINE_REM_PIO2
-extern inline
+extern __gnu89_inline
#endif
int
__ieee754_rem_pio2(double x, double *y)
diff --git a/lib/msun/src/e_rem_pio2f.c b/lib/msun/src/e_rem_pio2f.c
index e07694c..7ec7b95 100644
--- a/lib/msun/src/e_rem_pio2f.c
+++ b/lib/msun/src/e_rem_pio2f.c
@@ -41,7 +41,7 @@ pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
#ifdef INLINE_REM_PIO2F
-extern inline
+extern __gnu89_inline
#endif
int
__ieee754_rem_pio2f(float x, double *y)
diff --git a/lib/msun/src/k_cosf.c b/lib/msun/src/k_cosf.c
index 30c301a..5084e85 100644
--- a/lib/msun/src/k_cosf.c
+++ b/lib/msun/src/k_cosf.c
@@ -31,7 +31,7 @@ C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
#ifdef INLINE_KERNEL_COSDF
-extern inline
+extern __gnu89_inline
#endif
float
__kernel_cosdf(double x)
diff --git a/lib/msun/src/k_sinf.c b/lib/msun/src/k_sinf.c
index e390b50..c1b1d85 100644
--- a/lib/msun/src/k_sinf.c
+++ b/lib/msun/src/k_sinf.c
@@ -30,7 +30,7 @@ S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
#ifdef INLINE_KERNEL_SINDF
-extern inline
+extern __gnu89_inline
#endif
float
__kernel_sindf(double x)
diff --git a/lib/msun/src/k_tanf.c b/lib/msun/src/k_tanf.c
index f8152e2..d8b1ebf 100644
--- a/lib/msun/src/k_tanf.c
+++ b/lib/msun/src/k_tanf.c
@@ -33,7 +33,7 @@ T[] = {
};
#ifdef INLINE_KERNEL_TANDF
-extern inline
+extern __gnu89_inline
#endif
float
__kernel_tandf(double x, int iy)
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
index 374f95f..521ee3f 100644
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -55,8 +55,8 @@ extern const union __nan_un {
#ifdef __MATH_BUILTIN_CONSTANTS
#define HUGE_VALF __builtin_huge_valf()
#define HUGE_VALL __builtin_huge_vall()
-#define INFINITY __builtin_inf()
-#define NAN __builtin_nan("")
+#define INFINITY __builtin_inff()
+#define NAN __builtin_nanf("")
#else
#define HUGE_VALF (float)HUGE_VAL
#define HUGE_VALL (long double)HUGE_VAL
@@ -70,12 +70,12 @@ extern const union __nan_un {
/* XXX We need a <machine/math.h>. */
#if defined(__ia64__) || defined(__sparc64__)
-#define FP_FAST_FMA
+#define FP_FAST_FMA 1
#endif
#ifdef __ia64__
-#define FP_FAST_FMAL
+#define FP_FAST_FMAL 1
#endif
-#define FP_FAST_FMAF
+#define FP_FAST_FMAF 1
/* Symbolic constants to classify floating point numbers. */
#define FP_INFINITE 0x01
diff --git a/libexec/comsat/comsat.c b/libexec/comsat/comsat.c
index ed14b1a..fd7cc8d 100644
--- a/libexec/comsat/comsat.c
+++ b/libexec/comsat/comsat.c
@@ -203,21 +203,32 @@ notify(struct utmp *utp, char file[], off_t offset, int folder)
struct stat stb;
struct termios tio;
char tty[20], name[sizeof(utmp[0].ut_name) + 1];
+ const char *cr = utp->ut_line;
- (void)snprintf(tty, sizeof(tty), "%s%.*s",
- _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line);
- if (strchr(tty + sizeof(_PATH_DEV) - 1, '/')) {
+ if (strncmp(cr, "pts/", 4) == 0)
+ cr += 4;
+ if (strchr(cr, '/')) {
/* A slash is an attempt to break security... */
- syslog(LOG_AUTH | LOG_NOTICE, "'/' in \"%s\"", tty);
+ syslog(LOG_AUTH | LOG_NOTICE, "Unexpected `/' in `%s'",
+ utp->ut_line);
return;
}
- if (stat(tty, &stb) || !(stb.st_mode & (S_IXUSR | S_IXGRP))) {
+ (void)snprintf(tty, sizeof(tty), "%s%.*s",
+ _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line);
+ if (stat(tty, &stb) == -1 || !(stb.st_mode & (S_IXUSR | S_IXGRP))) {
dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_name, tty);
return;
}
dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty);
- if (fork())
+ switch (fork()) {
+ case -1:
+ syslog(LOG_NOTICE, "fork failed (%m)");
return;
+ case 0:
+ break;
+ default:
+ return;
+ }
(void)signal(SIGALRM, SIG_DFL);
(void)alarm((u_int)30);
if ((tp = fopen(tty, "w")) == NULL) {
diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8
index ae5d62c..9334bd9 100644
--- a/libexec/ftpd/ftpd.8
+++ b/libexec/ftpd/ftpd.8
@@ -205,7 +205,7 @@ for more information.
Note that option is a virtual no-op in
.Fx 5.0
and above; both port
-ranges are indentical by default.
+ranges are identical by default.
.It Fl u
The default file creation mode mask is set to
.Ar umask ,
diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml
index 32807b7..e27db7f 100644
--- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml
+++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml
@@ -29,6 +29,7 @@
<year>2006</year>
<year>2007</year>
<year>2008</year>
+ <year>2009</year>
<holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
</copyright>
@@ -347,6 +348,12 @@
<para>The &man.fdopendir.3; library function has been added.</para>
+ <para role="merged">The &man.fetch.3; library now support HTTP 1.1
+ If-Modified-Since behavior. The &man.fetch.1; program now
+ supports <option>-i <replaceable>filename</replaceable></option>
+ which will only download the specified HTTP URL if the content
+ is newer than <replaceable>filename</replaceable>.</para>
+
<para>&man.find.1; has been enhanced by the addition of a number
of primaries that were present in GNU find but not &os;
&man.find.1;.</para>
diff --git a/sbin/dumpfs/dumpfs.8 b/sbin/dumpfs/dumpfs.8
index 8879f78..6614a74 100644
--- a/sbin/dumpfs/dumpfs.8
+++ b/sbin/dumpfs/dumpfs.8
@@ -28,7 +28,7 @@
.\" @(#)dumpfs.8 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd January 19, 2003
+.Dd January 28, 2009
.Dt DUMPFS 8
.Os
.Sh NAME
@@ -36,15 +36,18 @@
.Nd dump file system information
.Sh SYNOPSIS
.Nm
+.Op Fl f
.Op Fl m
.Ar filesys | device
.Sh DESCRIPTION
The
.Nm
utility prints out the super block and cylinder group information
-for the file system or special device specified, unless
+for the file system or special device specified, unless the
+.Fl f
+or
.Fl m
-is specified.
+flag is specified.
The listing is very long and detailed.
This
command is useful mostly for finding out certain file system
@@ -52,6 +55,15 @@ information such as the file system block size and minimum
free space percentage.
.Pp
If
+.Fl f
+is specified, a sorted list of all free fragments and free fragment ranges,
+as represented in cylinder group block free lists, is printed.
+If the flag is specified twice, contiguous free fragments are not collapsed
+into ranges and instead printed in a simple list.
+Fragment numbers may be converted to raw byte offsets by multiplying by the
+fragment size, which may be useful when recovering deleted data.
+.Pp
+If
.Fl m
is specified, a
.Xr newfs 8
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c
index e0b809e..2f577d9 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -1,4 +1,10 @@
/*
+ * Copyright (c) 2009 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * This software was developed at the University of Cambridge Computer
+ * Laboratory with support from a grant from Google, Inc.
+ *
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
*
@@ -74,8 +80,11 @@ struct uufsd disk;
int dumpfs(const char *);
int dumpcg(void);
+int dumpfreespace(const char *, int);
+void dumpfreespacecg(int);
int marshal(const char *);
void pbits(void *, int);
+void pblklist(void *, int, off_t, int);
void ufserr(const char *);
void usage(void) __dead2;
@@ -83,12 +92,15 @@ int
main(int argc, char *argv[])
{
const char *name;
- int ch, domarshal, eval;
+ int ch, dofreespace, domarshal, eval;
- domarshal = eval = 0;
+ dofreespace = domarshal = eval = 0;
- while ((ch = getopt(argc, argv, "m")) != -1) {
+ while ((ch = getopt(argc, argv, "fm")) != -1) {
switch (ch) {
+ case 'f':
+ dofreespace++;
+ break;
case 'm':
domarshal = 1;
break;
@@ -102,6 +114,10 @@ main(int argc, char *argv[])
if (argc < 1)
usage();
+ if (dofreespace && domarshal)
+ usage();
+ if (dofreespace > 2)
+ usage();
while ((name = *argv++) != NULL) {
if (ufs_disk_fillout(&disk, name) == -1) {
@@ -109,7 +125,9 @@ main(int argc, char *argv[])
eval |= 1;
continue;
}
- if (domarshal)
+ if (dofreespace)
+ eval |= dumpfreespace(name, dofreespace);
+ else if (domarshal)
eval |= marshal(name);
else
eval |= dumpfs(name);
@@ -333,6 +351,30 @@ dumpcg(void)
}
int
+dumpfreespace(const char *name, int fflag)
+{
+ int i;
+
+ while ((i = cgread(&disk)) != 0) {
+ if (i == -1)
+ goto err;
+ dumpfreespacecg(fflag);
+ }
+ return (0);
+err:
+ ufserr(name);
+ return (1);
+}
+
+void
+dumpfreespacecg(int fflag)
+{
+
+ pblklist(cg_blksfree(&acg), afs.fs_fpg, disk.d_lcg * afs.fs_fpg,
+ fflag);
+}
+
+int
marshal(const char *name)
{
struct fs *fs;
@@ -401,6 +443,27 @@ pbits(void *vp, int max)
}
void
+pblklist(void *vp, int max, off_t offset, int fflag)
+{
+ int i, j;
+ char *p;
+
+ for (i = 0, p = vp; i < max; i++) {
+ if (isset(p, i)) {
+ printf("%jd", (intmax_t)(i + offset));
+ if (fflag < 2) {
+ j = i;
+ while ((i+1)<max && isset(p, i+1))
+ i++;
+ if (i != j)
+ printf("-%jd", (intmax_t)(i + offset));
+ }
+ printf("\n");
+ }
+ }
+}
+
+void
ufserr(const char *name)
{
if (disk.d_error != NULL)
@@ -412,6 +475,6 @@ ufserr(const char *name)
void
usage(void)
{
- (void)fprintf(stderr, "usage: dumpfs [-m] filesys | device\n");
+ (void)fprintf(stderr, "usage: dumpfs [-fm] filesys | device\n");
exit(1);
}
diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c
index 90b3403..c500d03 100644
--- a/sbin/fdisk/fdisk.c
+++ b/sbin/fdisk/fdisk.c
@@ -74,7 +74,6 @@ static char *disk;
static int cyls, sectors, heads, cylsecs, disksecs;
struct mboot {
- unsigned char padding[2]; /* force the longs to be long aligned */
unsigned char *bootinst; /* boot code */
off_t bootinst_size;
struct dos_partition parts[NDOSPART];
@@ -123,102 +122,113 @@ static char *f_flag = NULL; /* Read config info from file */
static int v_flag = 0; /* Be verbose */
static int print_config_flag = 0;
-static struct part_type
-{
- unsigned char type;
- const char *name;
-} part_types[] = {
- {0x00, "unused"}
- ,{0x01, "Primary DOS with 12 bit FAT"}
- ,{0x02, "XENIX / file system"}
- ,{0x03, "XENIX /usr file system"}
- ,{0x04, "Primary DOS with 16 bit FAT (< 32MB)"}
- ,{0x05, "Extended DOS"}
- ,{0x06, "Primary 'big' DOS (>= 32MB)"}
- ,{0x07, "OS/2 HPFS, NTFS, QNX-2 (16 bit) or Advanced UNIX"}
- ,{0x08, "AIX file system or SplitDrive"}
- ,{0x09, "AIX boot partition or Coherent"}
- ,{0x0A, "OS/2 Boot Manager, OPUS or Coherent swap"}
- ,{0x0B, "DOS or Windows 95 with 32 bit FAT"}
- ,{0x0C, "DOS or Windows 95 with 32 bit FAT (LBA)"}
- ,{0x0E, "Primary 'big' DOS (>= 32MB, LBA)"}
- ,{0x0F, "Extended DOS (LBA)"}
- ,{0x10, "OPUS"}
- ,{0x11, "OS/2 BM: hidden DOS with 12-bit FAT"}
- ,{0x12, "Compaq diagnostics"}
- ,{0x14, "OS/2 BM: hidden DOS with 16-bit FAT (< 32MB)"}
- ,{0x16, "OS/2 BM: hidden DOS with 16-bit FAT (>= 32MB)"}
- ,{0x17, "OS/2 BM: hidden IFS (e.g. HPFS)"}
- ,{0x18, "AST Windows swapfile"}
- ,{0x24, "NEC DOS"}
- ,{0x3C, "PartitionMagic recovery"}
- ,{0x39, "plan9"}
- ,{0x40, "VENIX 286"}
- ,{0x41, "Linux/MINIX (sharing disk with DRDOS)"}
- ,{0x42, "SFS or Linux swap (sharing disk with DRDOS)"}
- ,{0x43, "Linux native (sharing disk with DRDOS)"}
- ,{0x4D, "QNX 4.2 Primary"}
- ,{0x4E, "QNX 4.2 Secondary"}
- ,{0x4F, "QNX 4.2 Tertiary"}
- ,{0x50, "DM (disk manager)"}
- ,{0x51, "DM6 Aux1 (or Novell)"}
- ,{0x52, "CP/M or Microport SysV/AT"}
- ,{0x53, "DM6 Aux3"}
- ,{0x54, "DM6"}
- ,{0x55, "EZ-Drive (disk manager)"}
- ,{0x56, "Golden Bow (disk manager)"}
- ,{0x5c, "Priam Edisk (disk manager)"} /* according to S. Widlake */
- ,{0x61, "SpeedStor"}
- ,{0x63, "System V/386 (such as ISC UNIX), GNU HURD or Mach"}
- ,{0x64, "Novell Netware/286 2.xx"}
- ,{0x65, "Novell Netware/386 3.xx"}
- ,{0x70, "DiskSecure Multi-Boot"}
- ,{0x75, "PCIX"}
- ,{0x77, "QNX4.x"}
- ,{0x78, "QNX4.x 2nd part"}
- ,{0x79, "QNX4.x 3rd part"}
- ,{0x80, "Minix until 1.4a"}
- ,{0x81, "Minix since 1.4b, early Linux partition or Mitac disk manager"}
- ,{0x82, "Linux swap or Solaris x86"}
- ,{0x83, "Linux native"}
- ,{0x84, "OS/2 hidden C: drive"}
- ,{0x85, "Linux extended"}
- ,{0x86, "NTFS volume set??"}
- ,{0x87, "NTFS volume set??"}
- ,{0x93, "Amoeba file system"}
- ,{0x94, "Amoeba bad block table"}
- ,{0x9F, "BSD/OS"}
- ,{0xA0, "Suspend to Disk"}
- ,{0xA5, "FreeBSD/NetBSD/386BSD"}
- ,{0xA6, "OpenBSD"}
- ,{0xA7, "NeXTSTEP"}
- ,{0xA9, "NetBSD"}
- ,{0xAC, "IBM JFS"}
- ,{0xAF, "HFS+"}
- ,{0xB7, "BSDI BSD/386 file system"}
- ,{0xB8, "BSDI BSD/386 swap"}
- ,{0xBE, "Solaris x86 boot"}
- ,{0xBF, "Solaris x86 (new)"}
- ,{0xC1, "DRDOS/sec with 12-bit FAT"}
- ,{0xC4, "DRDOS/sec with 16-bit FAT (< 32MB)"}
- ,{0xC6, "DRDOS/sec with 16-bit FAT (>= 32MB)"}
- ,{0xC7, "Syrinx"}
- ,{0xDB, "CP/M, Concurrent CP/M, Concurrent DOS or CTOS"}
- ,{0xE1, "DOS access or SpeedStor with 12-bit FAT extended partition"}
- ,{0xE3, "DOS R/O or SpeedStor"}
- ,{0xE4, "SpeedStor with 16-bit FAT extended partition < 1024 cyl."}
- ,{0xEB, "BeOS file system"}
- ,{0xEE, "EFI GPT"}
- ,{0xEF, "EFI System Partition"}
- ,{0xF1, "SpeedStor"}
- ,{0xF2, "DOS 3.3+ Secondary"}
- ,{0xF4, "SpeedStor large partition"}
- ,{0xFE, "SpeedStor >1024 cyl. or LANstep"}
- ,{0xFF, "Xenix bad blocks table"}
+/*
+ * A list of partition types, probably outdated.
+ */
+static const char *const part_types[256] = {
+ [0x00] = "unused",
+ [0x01] = "Primary DOS with 12 bit FAT",
+ [0x02] = "XENIX / file system",
+ [0x03] = "XENIX /usr file system",
+ [0x04] = "Primary DOS with 16 bit FAT (< 32MB)",
+ [0x05] = "Extended DOS",
+ [0x06] = "Primary DOS, 16 bit FAT (>= 32MB)",
+ [0x07] = "NTFS, OS/2 HPFS, QNX-2 (16 bit) or Advanced UNIX",
+ [0x08] = "AIX file system or SplitDrive",
+ [0x09] = "AIX boot partition or Coherent",
+ [0x0A] = "OS/2 Boot Manager, OPUS or Coherent swap",
+ [0x0B] = "DOS or Windows 95 with 32 bit FAT",
+ [0x0C] = "DOS or Windows 95 with 32 bit FAT (LBA)",
+ [0x0E] = "Primary 'big' DOS (>= 32MB, LBA)",
+ [0x0F] = "Extended DOS (LBA)",
+ [0x10] = "OPUS",
+ [0x11] = "OS/2 BM: hidden DOS with 12-bit FAT",
+ [0x12] = "Compaq diagnostics",
+ [0x14] = "OS/2 BM: hidden DOS with 16-bit FAT (< 32MB)",
+ [0x16] = "OS/2 BM: hidden DOS with 16-bit FAT (>= 32MB)",
+ [0x17] = "OS/2 BM: hidden IFS (e.g. HPFS)",
+ [0x18] = "AST Windows swapfile",
+ [0x1b] = "ASUS Recovery partition (NTFS)",
+ [0x24] = "NEC DOS",
+ [0x3C] = "PartitionMagic recovery",
+ [0x39] = "plan9",
+ [0x40] = "VENIX 286",
+ [0x41] = "Linux/MINIX (sharing disk with DRDOS)",
+ [0x42] = "SFS or Linux swap (sharing disk with DRDOS)",
+ [0x43] = "Linux native (sharing disk with DRDOS)",
+ [0x4D] = "QNX 4.2 Primary",
+ [0x4E] = "QNX 4.2 Secondary",
+ [0x4F] = "QNX 4.2 Tertiary",
+ [0x50] = "DM (disk manager)",
+ [0x51] = "DM6 Aux1 (or Novell)",
+ [0x52] = "CP/M or Microport SysV/AT",
+ [0x53] = "DM6 Aux3",
+ [0x54] = "DM6",
+ [0x55] = "EZ-Drive (disk manager)",
+ [0x56] = "Golden Bow (disk manager)",
+ [0x5c] = "Priam Edisk (disk manager)", /* according to S. Widlake */
+ [0x61] = "SpeedStor",
+ [0x63] = "System V/386 (such as ISC UNIX), GNU HURD or Mach",
+ [0x64] = "Novell Netware/286 2.xx",
+ [0x65] = "Novell Netware/386 3.xx",
+ [0x70] = "DiskSecure Multi-Boot",
+ [0x75] = "PCIX",
+ [0x77] = "QNX4.x",
+ [0x78] = "QNX4.x 2nd part",
+ [0x79] = "QNX4.x 3rd part",
+ [0x80] = "Minix until 1.4a",
+ [0x81] = "Minix since 1.4b, early Linux partition or Mitac disk manager",
+ [0x82] = "Linux swap or Solaris x86",
+ [0x83] = "Linux native",
+ [0x84] = "OS/2 hidden C: drive",
+ [0x85] = "Linux extended",
+ [0x86] = "NTFS volume set??",
+ [0x87] = "NTFS volume set??",
+ [0x93] = "Amoeba file system",
+ [0x94] = "Amoeba bad block table",
+ [0x9F] = "BSD/OS",
+ [0xA0] = "Suspend to Disk",
+ [0xA5] = "FreeBSD/NetBSD/386BSD",
+ [0xA6] = "OpenBSD",
+ [0xA7] = "NeXTSTEP",
+ [0xA9] = "NetBSD",
+ [0xAC] = "IBM JFS",
+ [0xAF] = "HFS+",
+ [0xB7] = "BSDI BSD/386 file system",
+ [0xB8] = "BSDI BSD/386 swap",
+ [0xBE] = "Solaris x86 boot",
+ [0xBF] = "Solaris x86 (new)",
+ [0xC1] = "DRDOS/sec with 12-bit FAT",
+ [0xC4] = "DRDOS/sec with 16-bit FAT (< 32MB)",
+ [0xC6] = "DRDOS/sec with 16-bit FAT (>= 32MB)",
+ [0xC7] = "Syrinx",
+ [0xDB] = "CP/M, Concurrent CP/M, Concurrent DOS or CTOS",
+ [0xDE] = "DELL Utilities - FAT filesystem",
+ [0xE1] = "DOS access or SpeedStor with 12-bit FAT extended partition",
+ [0xE3] = "DOS R/O or SpeedStor",
+ [0xE4] = "SpeedStor with 16-bit FAT extended partition < 1024 cyl.",
+ [0xEB] = "BeOS file system",
+ [0xEE] = "EFI GPT",
+ [0xEF] = "EFI System Partition",
+ [0xF1] = "SpeedStor",
+ [0xF2] = "DOS 3.3+ Secondary",
+ [0xF4] = "SpeedStor large partition",
+ [0xFE] = "SpeedStor >1024 cyl. or LANstep",
+ [0xFF] = "Xenix bad blocks table",
};
-static void print_s0(int which);
-static void print_part(int i);
+static const char *
+get_type(int t)
+{
+ const char *ret;
+
+ ret = (t >= 0 && t <= 255) ? part_types[t] : NULL;
+ return ret ? ret : "unknown";
+}
+
+
+static void print_s0(void);
+static void print_part(const struct dos_partition *);
static void init_sector0(unsigned long start);
static void init_boot(void);
static void change_part(int i);
@@ -236,7 +246,6 @@ static int read_s0(void);
static int write_s0(void);
static int ok(const char *str);
static int decimal(const char *str, int *num, int deflt);
-static const char *get_type(int type);
static int read_config(char *config_file);
static void reset_boot(void);
static int sanitize_partition(struct dos_partition *);
@@ -308,7 +317,7 @@ main(int argc, char *argv[])
} else {
disk = g_device_path(argv[0]);
if (disk == NULL)
- err(1, "unable to get correct path for %s\n", argv[0]);
+ err(1, "unable to get correct path for %s", argv[0]);
}
if (open_disk(u_flag) < 0)
err(1, "cannot open disk %s", disk);
@@ -329,7 +338,7 @@ main(int argc, char *argv[])
printf("g c%d h%d s%d\n", dos_cyls, dos_heads, dos_sectors);
for (i = 0; i < NDOSPART; i++) {
- partp = ((struct dos_partition *)&mboot.parts) + i;
+ partp = &mboot.parts[i];
if (partp->dp_start == 0 && partp->dp_size == 0)
continue;
@@ -350,7 +359,7 @@ main(int argc, char *argv[])
dos_sectors);
printf("Part %11s %11s Type Flags\n", "Start", "Size");
for (i = 0; i < NDOSPART; i++) {
- partp = ((struct dos_partition *) &mboot.parts) + i;
+ partp = &mboot.parts[i];
if (partp->dp_start == 0 && partp->dp_size == 0)
continue;
printf("%4d: %11lu %11lu 0x%02x 0x%02x\n", i + 1,
@@ -366,7 +375,7 @@ main(int argc, char *argv[])
if (I_flag) {
read_s0();
reset_boot();
- partp = (struct dos_partition *) (&mboot.parts[0]);
+ partp = &mboot.parts[0];
partp->dp_typ = DOSPTYP_386BSD;
partp->dp_flag = ACTIVE;
partp->dp_start = dos_sectors;
@@ -374,7 +383,7 @@ main(int argc, char *argv[])
dos_sectors;
dos(partp);
if (v_flag)
- print_s0(-1);
+ print_s0();
if (!t_flag)
write_s0();
exit(0);
@@ -385,7 +394,7 @@ main(int argc, char *argv[])
if (!read_config(f_flag))
exit(1);
if (v_flag)
- print_s0(-1);
+ print_s0();
if (!t_flag)
write_s0();
} else {
@@ -417,7 +426,7 @@ main(int argc, char *argv[])
printf("\nWe haven't changed the partition table yet. ");
printf("This is your last chance.\n");
}
- print_s0(-1);
+ print_s0();
if (!t_flag) {
if (ok("Should we write new partition table?"))
write_s0();
@@ -440,29 +449,25 @@ usage()
}
static void
-print_s0(int which)
+print_s0(void)
{
int i;
print_params();
printf("Information from DOS bootblock is:\n");
- if (which == -1)
- for (i = 1; i <= NDOSPART; i++)
- printf("%d: ", i), print_part(i);
- else
- print_part(which);
+ for (i = 1; i <= NDOSPART; i++) {
+ printf("%d: ", i);
+ print_part(&mboot.parts[i - 1]);
+ }
}
static struct dos_partition mtpart;
static void
-print_part(int i)
+print_part(const struct dos_partition *partp)
{
- struct dos_partition *partp;
u_int64_t part_mb;
- partp = ((struct dos_partition *) &mboot.parts) + i - 1;
-
if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) {
printf("<UNUSED>\n");
return;
@@ -529,7 +534,7 @@ init_boot(void)
static void
init_sector0(unsigned long start)
{
- struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[0]);
+ struct dos_partition *partp = &mboot.parts[0];
init_boot();
@@ -547,21 +552,21 @@ init_sector0(unsigned long start)
static void
change_part(int i)
{
- struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i - 1;
+ struct dos_partition *partp = &mboot.parts[i - 1];
printf("The data for partition %d is:\n", i);
- print_part(i);
+ print_part(partp);
if (u_flag && ok("Do you want to change it?")) {
int tmp;
if (i_flag) {
- bzero((char *)partp, sizeof (struct dos_partition));
- if (i == 1) {
- init_sector0(1);
- printf("\nThe static data for the slice 1 has been reinitialized to:\n");
- print_part(i);
- }
+ bzero(partp, sizeof (*partp));
+ if (i == 1) {
+ init_sector0(1);
+ printf("\nThe static data for the slice 1 has been reinitialized to:\n");
+ print_part(partp);
+ }
}
do {
@@ -598,7 +603,7 @@ change_part(int i)
} else
dos(partp);
- print_part(i);
+ print_part(partp);
} while (!ok("Are we happy with this entry?"));
}
}
@@ -873,7 +878,7 @@ write_s0()
int sector, i;
if (iotest) {
- print_s0(-1);
+ print_s0();
return 0;
}
for(i = 0; i < NDOSPART; i++)
@@ -945,23 +950,6 @@ decimal(const char *str, int *num, int deflt)
}
-static const char *
-get_type(int type)
-{
- int numentries = (sizeof(part_types)/sizeof(struct part_type));
- int counter = 0;
- struct part_type *ptr = part_types;
-
-
- while(counter < numentries) {
- if(ptr->type == type)
- return(ptr->name);
- ptr++;
- counter++;
- }
- return("unknown");
-}
-
static void
parse_config_line(char *line, CMD *command)
@@ -1112,21 +1100,21 @@ process_partition(CMD *command)
current_line_number, partition);
break;
}
- partp = ((struct dos_partition *) &mboot.parts) + partition - 1;
- bzero((char *)partp, sizeof (struct dos_partition));
+ partp = &mboot.parts[partition - 1];
+ bzero(partp, sizeof (*partp));
partp->dp_typ = command->args[1].arg_val;
partp->dp_start = command->args[2].arg_val;
partp->dp_size = command->args[3].arg_val;
max_end = partp->dp_start + partp->dp_size;
- if (partp->dp_typ == 0) {
+ if (partp->dp_typ == 0) {
/*
* Get out, the partition is marked as unused.
*/
/*
* Insure that it's unused.
*/
- bzero((char *)partp, sizeof (struct dos_partition));
+ bzero(partp, sizeof(*partp));
status = 1;
break;
}
@@ -1213,7 +1201,7 @@ process_active(CMD *command)
/*
* Reset active partition
*/
- partp = ((struct dos_partition *) &mboot.parts);
+ partp = mboot.parts;
for (i = 0; i < NDOSPART; i++)
partp[i].dp_flag = 0;
partp[partition-1].dp_flag = ACTIVE;
@@ -1308,9 +1296,9 @@ reset_boot(void)
struct dos_partition *partp;
init_boot();
- for (i = 0; i < 4; ++i) {
- partp = ((struct dos_partition *) &mboot.parts) + i;
- bzero((char *)partp, sizeof (struct dos_partition));
+ for (i = 0; i < 4; ++i) {
+ partp = &mboot.parts[i];
+ bzero(partp, sizeof(*partp));
}
}
diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8
index b7360d9..a4f6d4b 100644
--- a/sbin/fsck/fsck.8
+++ b/sbin/fsck/fsck.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 25, 2001
+.Dd January 25, 2009
.Dt FSCK 8
.Os
.Sh NAME
@@ -37,7 +37,7 @@
.Nd file system consistency check and interactive repair
.Sh SYNOPSIS
.Nm
-.Op Fl dfnpvy
+.Op Fl Cdfnpvy
.Op Fl B | F
.Op Fl T Ar fstype : Ns Ar fsoptions
.Op Fl t Ar fstype
@@ -112,6 +112,11 @@ to be the partition and slice designators.
.Pp
The options are as follows:
.Bl -tag -width indent
+.It Fl C
+Check if the
+.Dq clean
+flag is set in the superblock and skip file system checks if file system was
+properly dismounted and marked clean.
.It Fl d
Debugging mode.
Just print the commands without executing them.
diff --git a/sbin/fsck/fsck.c b/sbin/fsck/fsck.c
index 490a29a..13eb9f0 100644
--- a/sbin/fsck/fsck.c
+++ b/sbin/fsck/fsck.c
@@ -103,7 +103,7 @@ main(int argc, char *argv[])
TAILQ_INIT(&selhead);
TAILQ_INIT(&opthead);
- while ((i = getopt(argc, argv, "BdvpfFnyl:t:T:")) != -1)
+ while ((i = getopt(argc, argv, "BCdvpfFnyl:t:T:")) != -1)
switch (i) {
case 'B':
if (flags & CHECK_BACKGRD)
@@ -128,6 +128,9 @@ main(int argc, char *argv[])
case 'p':
flags |= CHECK_PREEN;
/*FALLTHROUGH*/
+ case 'C':
+ flags |= CHECK_CLEAN;
+ /*FALLTHROUGH*/
case 'n':
case 'y':
globopt[1] = i;
@@ -566,7 +569,7 @@ static void
usage(void)
{
static const char common[] =
- "[-dfnpvy] [-B | -F] [-T fstype:fsoptions] [-t fstype]";
+ "[-Cdfnpvy] [-B | -F] [-T fstype:fsoptions] [-t fstype]";
(void)fprintf(stderr, "usage: %s %s [special | node] ...\n",
getprogname(), common);
diff --git a/sbin/fsck/fsutil.h b/sbin/fsck/fsutil.h
index 84e7290..657668e 100644
--- a/sbin/fsck/fsutil.h
+++ b/sbin/fsck/fsutil.h
@@ -48,6 +48,7 @@ char *estrdup(const char *);
#define CHECK_DEBUG 0x0004
#define CHECK_BACKGRD 0x0008
#define DO_BACKGRD 0x0010
+#define CHECK_CLEAN 0x0020
struct fstab;
int checkfstab(int, int (*)(struct fstab *),
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 14f49d6..887b94e 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -270,7 +270,8 @@ char yflag; /* assume a yes response */
int bkgrdflag; /* use a snapshot to run on an active system */
int bflag; /* location of alternate super block */
int debug; /* output debugging info */
-char catastrophicflag; /* run in catastrophic mode */
+int inoopt; /* trim out unused inodes */
+char ckclean; /* only do work if not cleanly unmounted */
int cvtlevel; /* convert to newer file system format */
int bkgrdcheck; /* determine if background check is possible */
int bkgrdsumadj; /* whether the kernel have ability to adjust superblock summary */
@@ -336,7 +337,7 @@ void cacheino(union dinode *dp, ino_t inumber);
void catch(int);
void catchquit(int);
int changeino(ino_t dir, const char *name, ino_t newnum);
-void check_cgmagic(int cg, struct cg *cgp);
+int check_cgmagic(int cg, struct cg *cgp);
int chkrange(ufs2_daddr_t blk, int cnt);
void ckfini(int markclean);
int ckinode(union dinode *dp, struct inodesc *);
@@ -361,7 +362,7 @@ int ftypeok(union dinode *dp);
void getblk(struct bufarea *bp, ufs2_daddr_t blk, long size);
struct bufarea *getdatablk(ufs2_daddr_t blkno, long size);
struct inoinfo *getinoinfo(ino_t inumber);
-union dinode *getnextinode(ino_t inumber);
+union dinode *getnextinode(ino_t inumber, int rebuildcg);
void getpathname(char *namebuf, ino_t curdir, ino_t ino);
union dinode *ginode(ino_t inumber);
void infohandler(int sig);
diff --git a/sbin/fsck_ffs/fsck_ffs.8 b/sbin/fsck_ffs/fsck_ffs.8
index 3139124..8b02e2d 100644
--- a/sbin/fsck_ffs/fsck_ffs.8
+++ b/sbin/fsck_ffs/fsck_ffs.8
@@ -29,7 +29,7 @@
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
-.Dd April 10, 2008
+.Dd January 25, 2009
.Dt FSCK_FFS 8
.Os
.Sh NAME
@@ -38,7 +38,7 @@
.Nd file system consistency check and interactive repair
.Sh SYNOPSIS
.Nm
-.Op Fl BCFpfny
+.Op Fl BFprfny
.Op Fl b Ar block
.Op Fl c Ar level
.Op Fl m Ar mode
@@ -46,9 +46,9 @@
.Ar ...
.Sh DESCRIPTION
The specified disk partitions and/or file systems are checked.
-In "preen" mode the clean flag of each file system's superblock is examined
-and only those file systems that
-are not marked clean are checked.
+In "preen" or "check clean" mode the clean flag of each file system's
+superblock is examined and only those file systems that are not marked clean
+are checked.
File systems are marked clean when they are unmounted,
when they have been mounted read-only, or when
.Nm
@@ -176,25 +176,13 @@ the super block for the file system.
An alternate super block is usually located at block 32 for UFS1,
and block 160 for UFS2.
.It Fl C
-Run
+Check if file system was dismouted cleanly.
+If so, skip file system checks (like "preen").
+However, if the file system was not cleanly dismounted, do full checks,
+is if
.Nm
-in 'catastrophic recovery' mode, which will enable certain aggressive
-operations that can make
-.Nm
-to survive with file systems that has very serious data damage, which
-is an useful last resort when on disk data damage is very serious
-and causes
-.Nm
-to crash otherwise. Be
-.Em very careful
-using this flag, is dangerous if there are data transmission hazards
-because a false positive cylinder group magic number mismatch could
-cause
-.Em irrevertible data loss!
-.Pp
-This option implies the
-.Fl f
-flag.
+was invoked without
+.Fl C .
.It Fl c
Convert the file system to the specified level.
Note that the level of a file system can only be raised.
@@ -228,6 +216,10 @@ are being converted at once.
The format of a file system can be determined from the
first line of output from
.Xr dumpfs 8 .
+.Pp
+This option implies the
+.Fl f
+flag.
.It Fl f
Force
.Nm
@@ -251,6 +243,15 @@ which is assumed to be affirmative;
do not open the file system for writing.
.It Fl p
Preen file systems (see above).
+.It Fl r
+Free up excess unused inodes.
+Decreasing the number of preallocated inodes reduces the
+running time of future runs of
+.Nm
+and frees up space that can allocated to files.
+The
+.Fl r
+option is ignored when running in preen mode.
.It Fl y
Assume a yes response to all questions asked by
.Nm ;
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 7ca0c44..4ce2ef2 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -333,9 +333,13 @@ ckfini(int markclean)
if (!markclean)
rerun = 1;
}
- } else if (!preen && !markclean) {
- printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
- rerun = 1;
+ } else if (!preen) {
+ if (markclean) {
+ printf("\n***** FILE SYSTEM IS CLEAN *****\n");
+ } else {
+ printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
+ rerun = 1;
+ }
}
if (debug && totalreads > 0)
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
@@ -418,32 +422,73 @@ blwrite(int fd, char *buf, ufs2_daddr_t blk, long size)
}
/*
- * Check cg's magic number. If catastrophic mode is enabled and the cg's
- * magic number is bad, offer an option to clear the whole cg.
+ * Verify cylinder group's magic number and other parameters. If the
+ * test fails, offer an option to rebuild the whole cylinder group.
*/
-void
+int
check_cgmagic(int cg, struct cg *cgp)
{
- if (!cg_chkmagic(cgp)) {
- pwarn("CG %d: BAD MAGIC NUMBER\n", cg);
- if (catastrophicflag) {
- if (reply("CLEAR CG")) {
- memset(cgp, 0, (size_t)sblock.fs_cgsize);
- cgp->cg_initediblk = sblock.fs_ipg;
- cgp->cg_old_niblk = sblock.fs_ipg;
- cgp->cg_old_ncyl = sblock.fs_old_cpg;
- cgp->cg_cgx = cg;
- cgp->cg_niblk = sblock.fs_ipg;
- cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg);
- cgp->cg_magic = CG_MAGIC;
- cgdirty();
- printf("PLEASE RERUN FSCK.\n");
- rerun = 1;
- }
- } else
- printf("YOU MAY NEED TO RERUN FSCK WITH -C IF IT CRASHED.\n");
+ /*
+ * Extended cylinder group checks.
+ */
+ if (cg_chkmagic(cgp) &&
+ ((sblock.fs_magic == FS_UFS1_MAGIC &&
+ cgp->cg_old_niblk == sblock.fs_ipg &&
+ cgp->cg_ndblk <= sblock.fs_fpg &&
+ cgp->cg_old_ncyl == sblock.fs_old_cpg) ||
+ (sblock.fs_magic == FS_UFS2_MAGIC &&
+ cgp->cg_niblk == sblock.fs_ipg &&
+ cgp->cg_ndblk <= sblock.fs_fpg &&
+ cgp->cg_initediblk <= sblock.fs_ipg))) {
+ return (1);
+ }
+ pfatal("CYLINDER GROUP %d: BAD MAGIC NUMBER", cg);
+ if (!reply("REBUILD CYLINDER GROUP")) {
+ printf("YOU WILL NEED TO RERUN FSCK.\n");
+ rerun = 1;
+ return (1);
+ }
+ /*
+ * Zero out the cylinder group and then initialize critical fields.
+ * Bit maps and summaries will be recalculated by later passes.
+ */
+ memset(cgp, 0, (size_t)sblock.fs_cgsize);
+ cgp->cg_magic = CG_MAGIC;
+ cgp->cg_cgx = cg;
+ cgp->cg_niblk = sblock.fs_ipg;
+ cgp->cg_initediblk = sblock.fs_ipg < 2 * INOPB(&sblock) ?
+ sblock.fs_ipg : 2 * INOPB(&sblock);
+ if (cgbase(&sblock, cg) + sblock.fs_fpg < sblock.fs_size)
+ cgp->cg_ndblk = sblock.fs_fpg;
+ else
+ cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg);
+ cgp->cg_iusedoff = &cgp->cg_space[0] - (u_char *)(&cgp->cg_firstfield);
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ cgp->cg_niblk = 0;
+ cgp->cg_initediblk = 0;
+ cgp->cg_old_ncyl = sblock.fs_old_cpg;
+ cgp->cg_old_niblk = sblock.fs_ipg;
+ cgp->cg_old_btotoff = cgp->cg_iusedoff;
+ cgp->cg_old_boff = cgp->cg_old_btotoff +
+ sblock.fs_old_cpg * sizeof(int32_t);
+ cgp->cg_iusedoff = cgp->cg_old_boff +
+ sblock.fs_old_cpg * sizeof(u_int16_t);
+ }
+ cgp->cg_freeoff = cgp->cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT);
+ cgp->cg_nextfreeoff = cgp->cg_freeoff + howmany(sblock.fs_fpg,CHAR_BIT);
+ if (sblock.fs_contigsumsize > 0) {
+ cgp->cg_nclusterblks = cgp->cg_ndblk / sblock.fs_frag;
+ cgp->cg_clustersumoff =
+ roundup(cgp->cg_nextfreeoff, sizeof(u_int32_t));
+ cgp->cg_clustersumoff -= sizeof(u_int32_t);
+ cgp->cg_clusteroff = cgp->cg_clustersumoff +
+ (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t);
+ cgp->cg_nextfreeoff = cgp->cg_clusteroff +
+ howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
}
+ cgdirty();
+ return (0);
}
/*
@@ -470,7 +515,8 @@ allocblk(long frags)
}
cg = dtog(&sblock, i + j);
getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
- check_cgmagic(cg, cgp);
+ if (!check_cgmagic(cg, cgp))
+ return (0);
baseblk = dtogd(&sblock, i + j);
for (k = 0; k < frags; k++) {
setbmap(i + j + k);
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 94c637e..5feead0 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -309,10 +309,12 @@ static long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
static caddr_t inodebuf;
union dinode *
-getnextinode(ino_t inumber)
+getnextinode(ino_t inumber, int rebuildcg)
{
+ int j;
long size;
- ufs2_daddr_t dblk;
+ mode_t mode;
+ ufs2_daddr_t ndb, dblk;
union dinode *dp;
static caddr_t nextinop;
@@ -336,6 +338,54 @@ getnextinode(ino_t inumber)
nextinop = inodebuf;
}
dp = (union dinode *)nextinop;
+ if (rebuildcg && nextinop == inodebuf) {
+ /*
+ * Try to determine if we have reached the end of the
+ * allocated inodes.
+ */
+ mode = DIP(dp, di_mode) & IFMT;
+ if (mode == 0) {
+ if (memcmp(dp->dp2.di_db, ufs2_zino.di_db,
+ NDADDR * sizeof(ufs2_daddr_t)) ||
+ memcmp(dp->dp2.di_ib, ufs2_zino.di_ib,
+ NIADDR * sizeof(ufs2_daddr_t)) ||
+ dp->dp2.di_mode || dp->dp2.di_size)
+ return (NULL);
+ goto inodegood;
+ }
+ if (!ftypeok(dp))
+ return (NULL);
+ ndb = howmany(DIP(dp, di_size), sblock.fs_bsize);
+ if (ndb < 0)
+ return (NULL);
+ if (mode == IFBLK || mode == IFCHR)
+ ndb++;
+ if (mode == IFLNK) {
+ /*
+ * Fake ndb value so direct/indirect block checks below
+ * will detect any garbage after symlink string.
+ */
+ if (DIP(dp, di_size) < (off_t)sblock.fs_maxsymlinklen) {
+ ndb = howmany(DIP(dp, di_size),
+ sizeof(ufs2_daddr_t));
+ if (ndb > NDADDR) {
+ j = ndb - NDADDR;
+ for (ndb = 1; j > 1; j--)
+ ndb *= NINDIR(&sblock);
+ ndb += NDADDR;
+ }
+ }
+ }
+ for (j = ndb; ndb < NDADDR && j < NDADDR; j++)
+ if (DIP(dp, di_db[j]) != 0)
+ return (NULL);
+ for (j = 0, ndb -= NDADDR; ndb > 0; j++)
+ ndb /= NINDIR(&sblock);
+ for (; j < NIADDR; j++)
+ if (DIP(dp, di_ib[j]) != 0)
+ return (NULL);
+ }
+inodegood:
if (sblock.fs_magic == FS_UFS1_MAGIC)
nextinop += sizeof(struct ufs1_dinode);
else
@@ -617,7 +667,8 @@ allocino(ino_t request, int type)
return (0);
cg = ino_to_cg(&sblock, ino);
getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
- check_cgmagic(cg, cgp);
+ if (!check_cgmagic(cg, cgp))
+ return (0);
setbit(cg_inosused(cgp), ino % sblock.fs_ipg);
cgp->cg_cs.cs_nifree--;
switch (type & IFMT) {
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index 2187e45..0366e45 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -81,8 +81,8 @@ main(int argc, char *argv[])
sync();
skipclean = 1;
- catastrophicflag = 0;
- while ((ch = getopt(argc, argv, "b:Bc:CdfFm:npy")) != -1) {
+ inoopt = 0;
+ while ((ch = getopt(argc, argv, "b:Bc:CdfFm:npry")) != -1) {
switch (ch) {
case 'b':
skipclean = 0;
@@ -106,10 +106,6 @@ main(int argc, char *argv[])
debug++;
break;
- case 'C':
- catastrophicflag = 1;
- /* FALLTHROUGH */
-
case 'f':
skipclean = 0;
break;
@@ -132,6 +128,14 @@ main(int argc, char *argv[])
case 'p':
preen++;
+ /*FALLTHROUGH*/
+
+ case 'C':
+ ckclean++;
+ break;
+
+ case 'r':
+ inoopt++;
break;
case 'y':
@@ -151,7 +155,7 @@ main(int argc, char *argv[])
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
(void)signal(SIGINT, catch);
- if (preen)
+ if (ckclean)
(void)signal(SIGQUIT, catchquit);
signal(SIGINFO, infohandler);
if (bkgrdflag) {
@@ -215,7 +219,7 @@ checkfilesys(char *filesys)
errmsg[0] = '\0';
cdevname = filesys;
- if (debug && preen)
+ if (debug && ckclean)
pwarn("starting\n");
/*
* Make best effort to get the disk name. Check first to see
@@ -250,7 +254,7 @@ checkfilesys(char *filesys)
exit(7); /* Filesystem clean, report it now */
exit(0);
}
- if (preen && skipclean) {
+ if (ckclean && skipclean) {
/*
* If file system is gjournaled, check it here.
*/
@@ -301,7 +305,7 @@ checkfilesys(char *filesys)
"CANNOT RUN IN BACKGROUND\n");
}
if ((sblock.fs_flags & FS_UNCLEAN) == 0 &&
- skipclean && preen) {
+ skipclean && ckclean) {
/*
* file system is clean;
* skip snapshot and report it clean
@@ -602,7 +606,7 @@ static void
usage(void)
{
(void) fprintf(stderr,
- "usage: %s [-BCFpfny] [-b block] [-c level] [-m mode] "
+ "usage: %s [-BFprfny] [-b block] [-c level] [-m mode] "
"filesystem ...\n",
getprogname());
exit(1);
diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c
index 9bfc95d..73b6419 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -54,17 +54,17 @@ static ufs2_daddr_t badblk;
static ufs2_daddr_t dupblk;
static ino_t lastino; /* last inode in use */
-static void checkinode(ino_t inumber, struct inodesc *);
+static int checkinode(ino_t inumber, struct inodesc *, int rebuildcg);
void
pass1(void)
{
struct inostat *info;
struct inodesc idesc;
- ino_t inumber, inosused;
+ ino_t inumber, inosused, mininos;
ufs2_daddr_t i, cgd;
u_int8_t *cp;
- int c;
+ int c, rebuildcg;
/*
* Set file system reserved blocks in used block map.
@@ -93,7 +93,10 @@ pass1(void)
inumber = c * sblock.fs_ipg;
setinodebuf(inumber);
getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
- if (sblock.fs_magic == FS_UFS2_MAGIC) {
+ rebuildcg = 0;
+ if (!check_cgmagic(c, &cgrp))
+ rebuildcg = 1;
+ if (!rebuildcg && sblock.fs_magic == FS_UFS2_MAGIC) {
inosused = cgrp.cg_initediblk;
if (inosused > sblock.fs_ipg)
inosused = sblock.fs_ipg;
@@ -117,9 +120,7 @@ pass1(void)
* to find the inodes that are really in use, and then
* read only those inodes in from disk.
*/
- if (preen && usedsoftdep) {
- if (!cg_chkmagic(&cgrp))
- pfatal("CG %d: BAD MAGIC NUMBER\n", c);
+ if ((preen || inoopt) && usedsoftdep && !rebuildcg) {
cp = &cg_inosused(&cgrp)[(inosused - 1) / CHAR_BIT];
for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
if (*cp == 0)
@@ -152,24 +153,60 @@ pass1(void)
*/
for (i = 0; i < inosused; i++, inumber++) {
if (inumber < ROOTINO) {
- (void)getnextinode(inumber);
+ (void)getnextinode(inumber, rebuildcg);
continue;
}
- checkinode(inumber, &idesc);
+ /*
+ * NULL return indicates probable end of allocated
+ * inodes during cylinder group rebuild attempt.
+ * We always keep trying until we get to the minimum
+ * valid number for this cylinder group.
+ */
+ if (checkinode(inumber, &idesc, rebuildcg) == 0 &&
+ i > cgrp.cg_initediblk)
+ break;
}
- lastino += 1;
- if (inosused < sblock.fs_ipg || inumber == lastino)
+ /*
+ * This optimization speeds up future runs of fsck
+ * by trimming down the number of inodes in cylinder
+ * groups that formerly had many inodes but now have
+ * fewer in use.
+ */
+ mininos = roundup(inosused + INOPB(&sblock), INOPB(&sblock));
+ if (inoopt && !preen && !rebuildcg &&
+ sblock.fs_magic == FS_UFS2_MAGIC &&
+ cgrp.cg_initediblk > 2 * INOPB(&sblock) &&
+ mininos < cgrp.cg_initediblk) {
+ i = cgrp.cg_initediblk;
+ if (mininos < 2 * INOPB(&sblock))
+ cgrp.cg_initediblk = 2 * INOPB(&sblock);
+ else
+ cgrp.cg_initediblk = mininos;
+ pwarn("CYLINDER GROUP %d: RESET FROM %ju TO %d %s\n",
+ c, i, cgrp.cg_initediblk, "VALID INODES");
+ cgdirty();
+ }
+ if (inosused < sblock.fs_ipg)
continue;
+ lastino += 1;
+ if (lastino < (c * sblock.fs_ipg))
+ inosused = 0;
+ else
+ inosused = lastino - (c * sblock.fs_ipg);
+ if (rebuildcg && inosused > cgrp.cg_initediblk &&
+ sblock.fs_magic == FS_UFS2_MAGIC) {
+ cgrp.cg_initediblk = roundup(inosused, INOPB(&sblock));
+ pwarn("CYLINDER GROUP %d: FOUND %d VALID INODES\n", c,
+ cgrp.cg_initediblk);
+ }
/*
* If we were not able to determine in advance which inodes
* were in use, then reduce the size of the inoinfo structure
* to the size necessary to describe the inodes that we
* really found.
*/
- if (lastino < (c * sblock.fs_ipg))
- inosused = 0;
- else
- inosused = lastino - (c * sblock.fs_ipg);
+ if (inumber == lastino)
+ continue;
inostathead[c].il_numalloced = inosused;
if (inosused == 0) {
free(inostathead[c].il_stat);
@@ -187,8 +224,8 @@ pass1(void)
freeinodebuf();
}
-static void
-checkinode(ino_t inumber, struct inodesc *idesc)
+static int
+checkinode(ino_t inumber, struct inodesc *idesc, int rebuildcg)
{
union dinode *dp;
off_t kernmaxfilesize;
@@ -196,7 +233,8 @@ checkinode(ino_t inumber, struct inodesc *idesc)
mode_t mode;
int j, ret, offset;
- dp = getnextinode(inumber);
+ if ((dp = getnextinode(inumber, rebuildcg)) == NULL)
+ return (0);
mode = DIP(dp, di_mode) & IFMT;
if (mode == 0) {
if ((sblock.fs_magic == FS_UFS1_MAGIC &&
@@ -220,7 +258,7 @@ checkinode(ino_t inumber, struct inodesc *idesc)
}
}
inoinfo(inumber)->ino_state = USTATE;
- return;
+ return (1);
}
lastino = inumber;
/* This should match the file size limit in ffs_mountfs(). */
@@ -352,7 +390,7 @@ checkinode(ino_t inumber, struct inodesc *idesc)
if (preen)
printf(" (CORRECTED)\n");
else if (reply("CORRECT") == 0)
- return;
+ return (1);
if (bkgrdflag == 0) {
dp = ginode(inumber);
DIP_SET(dp, di_blocks, idesc->id_entryno);
@@ -368,7 +406,7 @@ checkinode(ino_t inumber, struct inodesc *idesc)
rwerror("ADJUST INODE BLOCK COUNT", cmd.value);
}
}
- return;
+ return (1);
unknown:
pfatal("UNKNOWN FILE TYPE I=%lu", (u_long)inumber);
inoinfo(inumber)->ino_state = FCLEAR;
@@ -378,6 +416,7 @@ unknown:
clearinode(dp);
inodirty();
}
+ return (1);
}
int
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index f6b37a3..1628ffb 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -65,7 +65,7 @@ static struct disklabel *getdisklabel(char *s, int fd);
/*
* Read in a superblock finding an alternate if necessary.
* Return 1 if successful, 0 if unsuccessful, -1 if file system
- * is already clean (preen mode only).
+ * is already clean (ckclean and preen mode only).
*/
int
setup(char *dev)
@@ -201,7 +201,7 @@ setup(char *dev)
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
bflag = 0;
}
- if (skipclean && preen && sblock.fs_clean) {
+ if (skipclean && ckclean && sblock.fs_clean) {
pwarn("FILE SYSTEM CLEAN; SKIPPING CHECKS\n");
return (-1);
}
diff --git a/sbin/geom/class/virstor/gvirstor.8 b/sbin/geom/class/virstor/gvirstor.8
index 5807af9..ebb7431 100644
--- a/sbin/geom/class/virstor/gvirstor.8
+++ b/sbin/geom/class/virstor/gvirstor.8
@@ -1,5 +1,4 @@
-.\" Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
-.\" Copyright (c) 2005 Ivan Voras <ivoras@FreeBSD.org>
+.\" Copyright (c) 2006-2008 Ivan Voras <ivoras@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -25,12 +24,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 8, 2006
+.Dd December 17, 2008
.Dt GVIRSTOR 8
.Os
.Sh NAME
.Nm gvirstor
-.Nd "provides virtual data storage geom"
+.Nd "control utility for virtual data storage devices"
.Sh SYNOPSIS
.Nm
.Cm label
@@ -69,37 +68,50 @@
.Sh DESCRIPTION
The
.Nm
-utility is used for setting up a storage device of arbitrary large size (for example,
-several TB), consisting of an arbitrary number of physical storage devices with
-total size <= the virtual size. Data for the virtual devices will be allocated from
-physical devices on demand. In short, this is the virtual storage functionality.
+utility is used for setting up a virtual storage device of arbitrary
+large size
+.Pq for example, several TB ,
+consisting of an arbitrary number of physical storage devices with the
+total size which is equal to or smaller than the virtual size.
+Data for the virtual devices will be allocated from physical devices on
+demand.
+The idea behind
+.Nm
+is similar to the concept of Virtual Memory in operating systems,
+effectively allowing users to overcommit on storage
+.Pq free file system space .
The first argument to
.Nm
indicates an action to be performed:
-.Bl -tag -width ".Cm destroy"
+.Bl -tag -width ".Cm remove"
.It Cm label
Set up a virtual device from the given components with the specified
.Ar name .
-Metadata are stored in the last sector of every component.
+Metadata is stored in the last sector of every component.
Argument
-.Ar virsize
-is the size of new virtual device, with default being 2 TiB (2097152 MiB).
+.Fl s Ar virsize
+is the size of new virtual device, with default being set to 2 TiB
+.Pq 2097152 MiB .
Argument
-.Ar chunksize
-is the chunk size, with default being 4 MiB (4096 KiB).
-The default is thus "-s 2097152 -m 4096".
+.Fl m Ar chunksize
+is the chunk size, with default being set to 4 MiB
+.Pq 4096 KiB .
+The default arguments are thus
+.Qq Fl s Ar 2097152 Fl m Ar 4096 .
.It Cm stop
-Turn off an existing virtual device by its
+Turn off an existing virtual device with the given
.Ar name .
This command does not touch on-disk metadata.
As with other GEOM classes, stopped geoms cannot be started manually.
.It Cm add
-Adds new components to existing virtual device by its
+Adds new components to existing virtual device with the given
.Ar name .
-The specified virstor device must exist and be active (i.e.
-module loaded, device present in /dev).
+The specified virstor device must exist and be active
+.Pq i.e. module loaded, device present in Pa /dev .
+This action can be safely performed while the virstor device is in use
+.Pq Qo hot Qc operation
.It Cm remove
-Removes components from existing virtual device by its
+Removes components from existing virtual device with the given
.Ar name .
Only unallocated providers can be removed.
.It Cm clear
@@ -129,99 +141,147 @@ Hardcode providers' names in metadata.
.It Fl v
Be more verbose.
.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 virtual device of default size
-(2 TiB), of default chunk (extent) size (4 MiB), with two physical devices for
-backing storage.
+.Pq 2 TiB ,
+of default chunk
+.Pq extent
+size
+.Pq 4 MiB ,
+with two physical devices for backing storage.
.Bd -literal -offset indent
-gvirstor label -v mydata /dev/ad4 /dev/ad6
-newfs /dev/virstor/mydata
+.No gvirstor label -v Ar mydata Ar /dev/ad4 Ar /dev/ad6
+.No newfs Ar /dev/virstor/mydata
.Ed
.Pp
From now on, the virtual device will be available via the
.Pa /dev/virstor/mydata
device entry.
-To add a new physical device / provider to an active virstor device:
+To add a new physical device / component to an active virstor device:
.Bd -literal -offset indent
-gvirstor add mydata ad8
+.No gvirstor add Ar mydata Ar ad8
.Ed
.Pp
-This will add physical storage (from ad8) to
+This will add physical storage of
+.Ar ad8
+to
.Pa /dev/virstor/mydata
device.
-To see device status information (including how much physical storage
-is still available for the virtual device), use:
+.Pp
+To see the device status information
+.Pq including how much physical storage is still available for the virtual device ,
+use:
.Bd -literal -offset indent
gvirstor list
.Ed
.Pp
All standard
.Xr geom 8
-subcommands (e.g. "status", "help") are also supported.
-.Sh SYSCTLs
+subcommands
+.Pq e.g. Cm status , Cm help
+are also supported.
+.Sh SYSCTL VARIABLES
.Nm
-has several
+has several
.Xr sysctl 8
tunable variables.
.Bd -literal -offset indent
-.Pa int kern.geom.virstor.debug
+.Va int kern.geom.virstor.debug
.Ed
.Pp
This sysctl controls verbosity of the kernel module, in the range
-1 to 15. Messages that are marked with higher verbosity levels than
-this are supressed. Default value is 5 and it's not
-recommented to set this tunable to less than 2, because level 1 messages
-are error events, and level 2 messages are system warnings.
+1 to 15.
+Messages that are marked with higher verbosity levels than this are
+suppressed.
+Default value is 5 and it is not recommended to set this tunable to less
+than 2, because level 1 messages are error events, and level 2 messages
+are system warnings.
.Bd -literal -offset indent
-.Pa int kern.geom.virstor.chunk_watermark
+.Va int kern.geom.virstor.chunk_watermark
.Ed
.Pp
-Value in this sysctl sets warning watermark level for physical chunk usage
-on a single component. The warning is issued when a virstor component
-has less than this many free chunks (default 100).
+Value in this sysctl sets warning watermark level for physical chunk
+usage on a single component.
+The warning is issued when a virstor component has less than this many
+free chunks
+.Pq default 100 .
.Bd -literal -offset indent
-.Pa int kern.geom.virstor.component_watermark
+.Va int kern.geom.virstor.component_watermark
.Ed
.Pp
Value in this sysctl sets warning watermark level for component usage.
-The warning is issed when there are less than this many unallocated
-components (default is 1).
+The warning is issued when there are less than this many unallocated
+components
+.Pq default is 1 .
.Pp
All these sysctls are also available as
.Xr loader 8
tunables.
-.Sh LOG MESSAGES
+.Sh DIAGNOSTICS
+.Ex -std
+.Pp
.Nm
-kernel module issues log messages with prefixes in standardised format,
-which is useful for log message filtering and dispatching. Each message
-line begins with
+kernel module issues log messages with prefixes in standardized format,
+which is useful for log message filtering and dispatching.
+Each message line begins with
.Bd -literal -offset indent
-.Pa GEOM_VIRSTOR[%d]:
+.Li GEOM_VIRSTOR[%d]:
.Ed
.Pp
-The number (%d) is message verbosity / importance level, in the range
-1 to 15. If a message filtering, dispatching or operator alert system is
-used, it is recommended that messages with levels 1 and 2 be taken
-seriously (for example, to catch out-of-space conditions as set by
-watermark sysctls).
+The number
+.Pq %d
+is message verbosity / importance level, in the range 1 to 15.
+If a message filtering, dispatching or operator alert system is used, it
+is recommended that messages with levels 1 and 2 be taken seriously
+.Pq for example, to catch out-of-space conditions as set by watermark
+sysctls.
.Sh SEE ALSO
.Xr geom 4 ,
-.Xr geom 8 ,
-.Xr newfs 8 ,
.Xr fstab 5 ,
-.Xr glabel 8
+.Xr geom 8 ,
+.Xr glabel 8 ,
+.Xr newfs 8
.Sh HISTORY
The
.Nm
-utility appeared in
+utility first appeared in
.Fx 7.0 .
.Sh BUGS
-Commands "add" and "remove" contain unavoidable critical sections
-which may make the virstor device unusable if a power failure (or
-other disruptive event) happens during their execution.
-It's recommended to run them when the system is quiescent.
+Commands
+.Cm add
+and
+.Cm remove
+contain unavoidable critical sections which may make the virstor
+device unusable if a power failure
+.Pq or other disruptive event
+happens during their execution.
+It is recommended to run them when the system is quiescent.
+.Sh ASSUMPTIONS AND INTERACTION WITH FILE SYSTEMS
+There are several assumptions that
+.Nm
+has in its operation: that the size of the virtual storage device will not
+change once it is set, and that the sizes of individual physical storage
+components will always remain constant during their existence.
+For alternative ways to implement virtual or resizable file systems see
+.Xr zfs 1M ,
+.Xr gconcat 8 and
+.Xr growfs 8 .
+.Pp
+Note that
+.Nm
+has nontrivial interaction with file systems which initialize a large
+number of on-disk structures during newfs.
+If such file systems attempt to spread their structures across the drive
+media
+.Pq like UFS/UFS2 does ,
+their efforts will be effectively foiled by sequential allocation of
+chunks in
+.Nm
+and all their structures will be physically allocated at the start
+of the first virstor component.
+This could have a significant impact on file system performance
+.Pq which can in some rare cases be even positive .
.Sh AUTHOR
-.An Ivan Voras Aq ivoras@FreeBSD.org
-Sponsored by Google Summer of Code 2006
+.An Ivan Voras Aq ivoras@FreeBSD.org
+.Pp
+Sponsored by Google Summer of Code 2006.
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index f0d82e8..f7656dc 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -487,13 +487,13 @@ library_path(void)
static void
load_library(void)
{
- char *curpath, path[MAXPATHLEN], *totalpath;
+ char *curpath, path[MAXPATHLEN], *tofree, *totalpath;
uint32_t *lib_version;
void *dlh;
int ret;
ret = 0;
- totalpath = strdup(library_path());
+ tofree = totalpath = strdup(library_path());
if (totalpath == NULL)
err(EXIT_FAILURE, "Not enough memory for library path");
@@ -519,7 +519,7 @@ load_library(void)
}
break;
}
- free(totalpath);
+ free(tofree);
/* No library was found, but standard commands can still be used */
if (ret == -1)
return;
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index debe746..d27bed8 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
-.Dd October 19, 2008
+.Dd January 7, 2009
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -610,9 +610,15 @@ is one of
(or
.Cm hostap ),
.Cm wds ,
+.Cm tdma ,
and
.Cm monitor .
The operating mode of a cloned interface cannot be changed.
+The
+.Cm tdma
+mode is actually implemented as an
+.Cm adhoc-demo
+interface with special properties.
.It Cm wlanbssid Ar bssid
The 802.11 mac address to use for the bssid.
This must be specified at create time for a legacy
@@ -1530,6 +1536,60 @@ hexadecimal when preceded by
.Ql 0x .
Additionally, the SSID may be cleared by setting it to
.Ql - .
+.It Cm tdmaslot Ar slot
+When operating with TDMA, use the specified
+.Ar slot
+configuration.
+The
+.Ar slot
+is a number between 0 and the maximum number of slots in the BSS.
+Note that a station configured as slot 0 is a master and
+will broadcast beacon frames advertising the BSS;
+stations configured to use other slots will always
+scan to locate a master before they ever transmit.
+By default
+.Cm tdmaslot
+is set to 1.
+.It Cm tdmaslotcnt Ar cnt
+When operating with TDMA, setup a BSS with
+.Ar cnt
+slots.
+The slot count may be at most 8.
+The current implementation is only tested with two stations
+(i.e. point to point applications).
+This setting is only meaningful when a station is configured as slot 0;
+other stations adopt this setting from the BSS they join.
+By default
+.Cm tdmaslotcnt
+is set to 2.
+.It Cm tdmaslotlen Ar len
+When operating with TDMA, setup a BSS such that each station has a slot
+.Ar len
+microseconds long.
+The slot length must be at least 150 microseconds (1/8 TU)
+and no more than 65 milliseconds.
+Note that setting too small a slot length may result in poor channel
+bandwidth utilization due to factors such as timer granularity and
+guard time.
+This setting is only meaningful when a station is configured as slot 0;
+other stations adopt this setting from the BSS they join.
+By default
+.Cm tdmaslotlen
+is set to 10 milliseconds.
+.It Cm tdmabintval Ar intval
+When operating with TDMA, setup a BSS such that beacons are transmitted every
+.Ar intval
+superframes to synchronize the TDMA slot timing.
+A superframe is defined as the number of slots times the slot length; e.g.
+a BSS with two slots of 10 milliseconds has a 20 millisecond superframe.
+The beacon interval may not be zero.
+A lower setting of
+.Cm tdmabintval
+causes the timers to be resynchronized more often; this can be help if
+significant timer drift is observed.
+By default
+.Cm tdmabintval
+is set to 5.
.It Cm tsn
When operating as an access point with WPA/802.11i allow legacy
stations to associate using static key WEP and open authentication.
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index c9e6f7f..3b6138d 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -697,13 +697,13 @@ setifflags(const char *vname, int value, int s, const struct afswtch *afp)
struct ifreq my_ifr;
int flags;
- bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq));
+ memset(&my_ifr, 0, sizeof(my_ifr));
+ (void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
exit(1);
}
- strncpy(my_ifr.ifr_name, name, sizeof (my_ifr.ifr_name));
flags = (my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16);
if (value < 0) {
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index d496644..bc1e89f 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -79,6 +79,7 @@
#include <net80211/ieee80211_ioctl.h>
+#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -98,10 +99,6 @@
#define IEEE80211_FIXED_RATE_NONE 0xff
#endif
-#define REQ_ECM 0x01000000 /* enable if ECM set */
-#define REQ_OUTDOOR 0x02000000 /* enable for outdoor operation */
-#define REQ_FLAGS 0xff000000 /* private flags, don't pass to os */
-
/* XXX need these publicly defined or similar */
#ifndef IEEE80211_NODE_AUTH
#define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */
@@ -119,6 +116,8 @@
#define IEEE80211_NODE_RIFS 0x4000 /* RIFS enabled */
#endif
+#define MAXCHAN 1536 /* max 1.5K channels */
+
#define MAXCOL 78
static int col;
static char spacer;
@@ -145,7 +144,7 @@ static void print_channels(int, const struct ieee80211req_chaninfo *,
static void regdomain_makechannels(struct ieee80211_regdomain_req *,
const struct ieee80211_devcaps_req *);
-static struct ieee80211req_chaninfo chaninfo;
+static struct ieee80211req_chaninfo *chaninfo;
static struct ieee80211_regdomain regdomain;
static int gotregdomain = 0;
static struct ieee80211_roamparams_req roamparams;
@@ -175,10 +174,14 @@ gethtconf(int s)
static void
getchaninfo(int s)
{
- if (chaninfo.ic_nchans != 0)
+ if (chaninfo != NULL)
return;
- if (get80211(s, IEEE80211_IOC_CHANINFO, &chaninfo, sizeof(chaninfo)) < 0)
- errx(1, "unable to get channel information");
+ chaninfo = malloc(IEEE80211_CHANINFO_SIZE(MAXCHAN));
+ if (chaninfo == NULL)
+ errx(1, "no space for channel list");
+ if (get80211(s, IEEE80211_IOC_CHANINFO, chaninfo,
+ IEEE80211_CHANINFO_SIZE(MAXCHAN)) < 0)
+ err(1, "unable to get channel information");
ifmr = ifmedia_getstate(s);
gethtconf(s);
}
@@ -205,19 +208,19 @@ getregdata(void)
static int
canpromote(int i, int from, int to)
{
- const struct ieee80211_channel *fc = &chaninfo.ic_chans[i];
+ const struct ieee80211_channel *fc = &chaninfo->ic_chans[i];
int j;
if ((fc->ic_flags & from) != from)
return i;
/* NB: quick check exploiting ordering of chans w/ same frequency */
- if (i+1 < chaninfo.ic_nchans &&
- chaninfo.ic_chans[i+1].ic_freq == fc->ic_freq &&
- (chaninfo.ic_chans[i+1].ic_flags & to) == to)
+ if (i+1 < chaninfo->ic_nchans &&
+ chaninfo->ic_chans[i+1].ic_freq == fc->ic_freq &&
+ (chaninfo->ic_chans[i+1].ic_flags & to) == to)
return i+1;
/* brute force search in case channel list is not ordered */
- for (j = 0; j < chaninfo.ic_nchans; j++) {
- const struct ieee80211_channel *tc = &chaninfo.ic_chans[j];
+ for (j = 0; j < chaninfo->ic_nchans; j++) {
+ const struct ieee80211_channel *tc = &chaninfo->ic_chans[j];
if (j != i &&
tc->ic_freq == fc->ic_freq && (tc->ic_flags & to) == to)
return j;
@@ -287,13 +290,13 @@ mapfreq(struct ieee80211_channel *chan, int freq, int flags)
{
int i;
- for (i = 0; i < chaninfo.ic_nchans; i++) {
- const struct ieee80211_channel *c = &chaninfo.ic_chans[i];
+ for (i = 0; i < chaninfo->ic_nchans; i++) {
+ const struct ieee80211_channel *c = &chaninfo->ic_chans[i];
if (c->ic_freq == freq && (c->ic_flags & flags) == flags) {
if (flags == 0) {
/* when ambiguous promote to ``best'' */
- c = &chaninfo.ic_chans[promote(i)];
+ c = &chaninfo->ic_chans[promote(i)];
}
*chan = *c;
return;
@@ -307,13 +310,13 @@ mapchan(struct ieee80211_channel *chan, int ieee, int flags)
{
int i;
- for (i = 0; i < chaninfo.ic_nchans; i++) {
- const struct ieee80211_channel *c = &chaninfo.ic_chans[i];
+ for (i = 0; i < chaninfo->ic_nchans; i++) {
+ const struct ieee80211_channel *c = &chaninfo->ic_chans[i];
if (c->ic_ieee == ieee && (c->ic_flags & flags) == flags) {
if (flags == 0) {
/* when ambiguous promote to ``best'' */
- c = &chaninfo.ic_chans[promote(i)];
+ c = &chaninfo->ic_chans[promote(i)];
}
*chan = *c;
return;
@@ -331,7 +334,7 @@ getcurchan(int s)
int val;
/* fall back to legacy ioctl */
if (get80211val(s, IEEE80211_IOC_CHANNEL, &val) < 0)
- errx(-1, "cannot figure out current channel");
+ err(-1, "cannot figure out current channel");
getchaninfo(s);
mapchan(&curchan, val, 0);
}
@@ -370,7 +373,7 @@ getroam(int s)
return;
if (get80211(s, IEEE80211_IOC_ROAM,
&roamparams, sizeof(roamparams)) < 0)
- errx(1, "unable to get roaming parameters");
+ err(1, "unable to get roaming parameters");
gotroam = 1;
}
@@ -388,7 +391,7 @@ gettxparams(int s)
return;
if (get80211(s, IEEE80211_IOC_TXPARAMS,
&txparams, sizeof(txparams)) < 0)
- errx(1, "unable to get transmit parameters");
+ err(1, "unable to get transmit parameters");
gottxparams = 1;
}
@@ -406,23 +409,24 @@ getregdomain(int s)
return;
if (get80211(s, IEEE80211_IOC_REGDOMAIN,
&regdomain, sizeof(regdomain)) < 0)
- errx(1, "unable to get regulatory domain info");
+ err(1, "unable to get regulatory domain info");
gotregdomain = 1;
}
static void
getdevcaps(int s, struct ieee80211_devcaps_req *dc)
{
- if (get80211(s, IEEE80211_IOC_DEVCAPS, dc, sizeof(*dc)) < 0)
- errx(1, "unable to get device capabilities");
+ if (get80211(s, IEEE80211_IOC_DEVCAPS, dc,
+ IEEE80211_DEVCAPS_SPACE(dc)) < 0)
+ err(1, "unable to get device capabilities");
}
static void
setregdomain_cb(int s, void *arg)
{
- struct ieee80211_regdomain_req req;
+ struct ieee80211_regdomain_req *req;
struct ieee80211_regdomain *rd = arg;
- struct ieee80211_devcaps_req dc;
+ struct ieee80211_devcaps_req *dc;
struct regdata *rdp = getregdata();
if (rd->country != NO_COUNTRY) {
@@ -462,34 +466,52 @@ setregdomain_cb(int s, void *arg)
rp->name);
}
}
- req.rd = *rd;
/*
* Fetch the device capabilities and calculate the
* full set of netbands for which we request a new
* channel list be constructed. Once that's done we
* push the regdomain info + channel list to the kernel.
*/
- getdevcaps(s, &dc);
+ dc = malloc(IEEE80211_DEVCAPS_SIZE(MAXCHAN));
+ if (dc == NULL)
+ errx(1, "no space for device capabilities");
+ dc->dc_chaninfo.ic_nchans = MAXCHAN;
+ getdevcaps(s, dc);
#if 0
if (verbose) {
- printf("drivercaps: 0x%x\n", dc.dc_drivercaps);
- printf("cryptocaps: 0x%x\n", dc.dc_cryptocaps);
- printf("htcaps : 0x%x\n", dc.dc_htcaps);
- memcpy(&chaninfo, &dc.dc_chaninfo, sizeof(chaninfo));
- print_channels(s, &dc.dc_chaninfo, 1/*allchans*/, 1/*verbose*/);
+ printf("drivercaps: 0x%x\n", dc->dc_drivercaps);
+ printf("cryptocaps: 0x%x\n", dc->dc_cryptocaps);
+ printf("htcaps : 0x%x\n", dc->dc_htcaps);
+ memcpy(chaninfo, &dc->dc_chaninfo,
+ IEEE80211_CHANINFO_SPACE(&dc->dc_chaninfo));
+ print_channels(s, &dc->dc_chaninfo, 1/*allchans*/, 1/*verbose*/);
}
#endif
- regdomain_makechannels(&req, &dc);
+ req = malloc(IEEE80211_REGDOMAIN_SIZE(dc->dc_chaninfo.ic_nchans));
+ if (req == NULL)
+ errx(1, "no space for regdomain request");
+ req->rd = *rd;
+ regdomain_makechannels(req, dc);
if (verbose) {
LINE_INIT(':');
print_regdomain(rd, 1/*verbose*/);
LINE_BREAK();
- memcpy(&chaninfo, &req.chaninfo, sizeof(chaninfo));
- print_channels(s, &req.chaninfo, 1/*allchans*/, 1/*verbose*/);
+ /* blech, reallocate channel list for new data */
+ if (chaninfo != NULL)
+ free(chaninfo);
+ chaninfo = malloc(IEEE80211_CHANINFO_SPACE(&req->chaninfo));
+ if (chaninfo == NULL)
+ errx(1, "no space for channel list");
+ memcpy(chaninfo, &req->chaninfo,
+ IEEE80211_CHANINFO_SPACE(&req->chaninfo));
+ print_channels(s, &req->chaninfo, 1/*allchans*/, 1/*verbose*/);
}
- if (req.chaninfo.ic_nchans == 0)
+ if (req->chaninfo.ic_nchans == 0)
errx(1, "no channels calculated");
- set80211(s, IEEE80211_IOC_REGDOMAIN, 0, sizeof(req), &req);
+ set80211(s, IEEE80211_IOC_REGDOMAIN, 0,
+ IEEE80211_REGDOMAIN_SPACE(req), req);
+ free(req);
+ free(dc);
}
static int
@@ -980,7 +1002,6 @@ static void
set80211chanlist(const char *val, int d, int s, const struct afswtch *rafp)
{
struct ieee80211req_chanlist chanlist;
-#define MAXCHAN (sizeof(chanlist.ic_channels)*NBBY)
char *temp, *cp, *tp;
temp = malloc(strlen(val) + 1);
@@ -997,18 +1018,18 @@ set80211chanlist(const char *val, int d, int s, const struct afswtch *rafp)
*tp++ = '\0';
switch (sscanf(cp, "%u-%u", &first, &last)) {
case 1:
- if (first > MAXCHAN)
- errx(-1, "channel %u out of range, max %zu",
- first, MAXCHAN);
+ if (first > IEEE80211_CHAN_MAX)
+ errx(-1, "channel %u out of range, max %u",
+ first, IEEE80211_CHAN_MAX);
setbit(chanlist.ic_channels, first);
break;
case 2:
- if (first > MAXCHAN)
- errx(-1, "channel %u out of range, max %zu",
- first, MAXCHAN);
- if (last > MAXCHAN)
- errx(-1, "channel %u out of range, max %zu",
- last, MAXCHAN);
+ if (first > IEEE80211_CHAN_MAX)
+ errx(-1, "channel %u out of range, max %u",
+ first, IEEE80211_CHAN_MAX);
+ if (last > IEEE80211_CHAN_MAX)
+ errx(-1, "channel %u out of range, max %u",
+ last, IEEE80211_CHAN_MAX);
if (first > last)
errx(-1, "void channel range, %u > %u",
first, last);
@@ -1026,7 +1047,6 @@ set80211chanlist(const char *val, int d, int s, const struct afswtch *rafp)
cp = tp;
}
set80211(s, IEEE80211_IOC_CHANLIST, 0, sizeof(chanlist), &chanlist);
-#undef MAXCHAN
}
static void
@@ -1641,7 +1661,7 @@ set80211amsdu(const char *val, int d, int s, const struct afswtch *rafp)
int amsdu;
if (get80211val(s, IEEE80211_IOC_AMSDU, &amsdu) < 0)
- errx(-1, "cannot get AMSDU setting");
+ err(-1, "cannot get AMSDU setting");
if (d < 0) {
d = -d;
amsdu &= ~d;
@@ -1711,6 +1731,30 @@ set80211rifs(const char *val, int d, int s, const struct afswtch *rafp)
set80211(s, IEEE80211_IOC_RIFS, d, 0, NULL);
}
+static
+DECL_CMD_FUNC(set80211tdmaslot, val, d)
+{
+ set80211(s, IEEE80211_IOC_TDMA_SLOT, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211tdmaslotcnt, val, d)
+{
+ set80211(s, IEEE80211_IOC_TDMA_SLOTCNT, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211tdmaslotlen, val, d)
+{
+ set80211(s, IEEE80211_IOC_TDMA_SLOTLEN, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211tdmabintval, val, d)
+{
+ set80211(s, IEEE80211_IOC_TDMA_BINTERVAL, atoi(val), 0, NULL);
+}
+
static int
regdomain_sort(const void *a, const void *b)
{
@@ -1741,6 +1785,70 @@ chanlookup(const struct ieee80211_channel chans[], int nchans,
return NULL;
}
+static int
+chanfind(const struct ieee80211_channel chans[], int nchans, int flags)
+{
+ int i;
+
+ for (i = 0; i < nchans; i++) {
+ const struct ieee80211_channel *c = &chans[i];
+ if ((c->ic_flags & flags) == flags)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Check channel compatibility.
+ */
+static int
+checkchan(const struct ieee80211req_chaninfo *avail, int freq, int flags)
+{
+ flags &= ~REQ_FLAGS;
+ /*
+ * Check if exact channel is in the calibration table;
+ * everything below is to deal with channels that we
+ * want to include but that are not explicitly listed.
+ */
+ if (flags & IEEE80211_CHAN_HT40) {
+ /* NB: we use an HT40 channel center that matches HT20 */
+ flags = (flags &~ IEEE80211_CHAN_HT40) | IEEE80211_CHAN_HT20;
+ }
+ if (chanlookup(avail->ic_chans, avail->ic_nchans, freq, flags) != NULL)
+ return 1;
+ if (flags & IEEE80211_CHAN_GSM) {
+ /*
+ * XXX GSM frequency mapping is handled in the kernel
+ * so we cannot find them in the calibration table;
+ * just accept the channel and the kernel will reject
+ * the channel list if it's wrong.
+ */
+ return 1;
+ }
+ /*
+ * If this is a 1/2 or 1/4 width channel allow it if a full
+ * width channel is present for this frequency, and the device
+ * supports fractional channels on this band. This is a hack
+ * that avoids bloating the calibration table; it may be better
+ * by per-band attributes though (we are effectively calculating
+ * this attribute by scanning the channel list ourself).
+ */
+ if ((flags & (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER)) == 0)
+ return 0;
+ if (chanlookup(avail->ic_chans, avail->ic_nchans, freq,
+ flags &~ (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER)) == NULL)
+ return 0;
+ if (flags & IEEE80211_CHAN_HALF) {
+ return chanfind(avail->ic_chans, avail->ic_nchans,
+ IEEE80211_CHAN_HALF |
+ (flags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ)));
+ } else {
+ return chanfind(avail->ic_chans, avail->ic_nchans,
+ IEEE80211_CHAN_QUARTER |
+ (flags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ)));
+ }
+}
+
static void
regdomain_addchans(struct ieee80211req_chaninfo *ci,
const netband_head *bands,
@@ -1751,63 +1859,96 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
const struct netband *nb;
const struct freqband *b;
struct ieee80211_channel *c, *prev;
- int freq, channelSep;
+ int freq, hi_adj, lo_adj, channelSep;
+ uint32_t flags;
+ hi_adj = (chanFlags & IEEE80211_CHAN_HT40U) ? -20 : 0;
+ lo_adj = (chanFlags & IEEE80211_CHAN_HT40D) ? 20 : 0;
channelSep = (chanFlags & IEEE80211_CHAN_2GHZ) ? 0 : 40;
LIST_FOREACH(nb, bands, next) {
b = nb->band;
- if (verbose)
- printf("%s: chanFlags 0x%x b %p\n",
- __func__, chanFlags, b);
+ if (verbose) {
+ printf("%s:", __func__);
+ printb(" chanFlags", chanFlags, IEEE80211_CHAN_BITS);
+ printb(" bandFlags", nb->flags | b->flags,
+ IEEE80211_CHAN_BITS);
+ putchar('\n');
+ }
prev = NULL;
- for (freq = b->freqStart; freq <= b->freqEnd; freq += b->chanSep) {
- uint32_t flags = nb->flags | b->flags;
-
- /* check if device can operate on this frequency */
- if (chanlookup(avail->ic_chans, avail->ic_nchans, freq, chanFlags) == NULL) {
- if (verbose)
- printf("%u: skip, flags 0x%x not available\n", freq, chanFlags);
- continue;
- }
+ for (freq = b->freqStart + lo_adj;
+ freq <= b->freqEnd + hi_adj; freq += b->chanSep) {
/*
- * NB: don't enforce 1/2 and 1/4 rate channels being
- * specified in the device's calibration list for
- * 900MHz cards because most are not self-identifying.
+ * Construct flags for the new channel. We take
+ * the attributes from the band descriptions except
+ * for HT40 which is enabled generically (i.e. +/-
+ * extension channel) in the band description and
+ * then constrained according by channel separation.
*/
- if ((flags & IEEE80211_CHAN_HALF) &&
- ((chanFlags & IEEE80211_CHAN_HALF) == 0 &&
- (flags & IEEE80211_CHAN_GSM) == 0)) {
- if (verbose)
- printf("%u: skip, device does not support half-rate channels\n", freq);
- continue;
- }
- if ((flags & IEEE80211_CHAN_QUARTER) &&
- ((chanFlags & IEEE80211_CHAN_HALF) == 0 &&
- (flags & IEEE80211_CHAN_GSM) == 0)) {
- if (verbose)
- printf("%u: skip, device does not support quarter-rate channels\n", freq);
- continue;
+ flags = nb->flags | b->flags;
+ if (flags & IEEE80211_CHAN_HT) {
+ /*
+ * HT channels are generated specially; we're
+ * called to add HT20, HT40+, and HT40- chan's
+ * so we need to expand only band specs for
+ * the HT channel type being added.
+ */
+ if ((chanFlags & IEEE80211_CHAN_HT20) &&
+ (flags & IEEE80211_CHAN_HT20) == 0) {
+ if (verbose)
+ printf("%u: skip, not an "
+ "HT20 channel\n", freq);
+ continue;
+ }
+ if ((chanFlags & IEEE80211_CHAN_HT40) &&
+ (flags & IEEE80211_CHAN_HT40) == 0) {
+ if (verbose)
+ printf("%u: skip, not an "
+ "HT40 channel\n", freq);
+ continue;
+ }
+ /*
+ * DFS and HT40 don't mix. This should be
+ * expressed in the regdomain database but
+ * just in case enforce it here.
+ */
+ if ((chanFlags & IEEE80211_CHAN_HT40) &&
+ (flags & IEEE80211_CHAN_DFS)) {
+ if (verbose)
+ printf("%u: skip, HT40+DFS "
+ "not permitted\n", freq);
+ continue;
+ }
+ /* NB: HT attribute comes from caller */
+ flags &= ~IEEE80211_CHAN_HT;
+ flags |= chanFlags & IEEE80211_CHAN_HT;
}
- if ((flags & IEEE80211_CHAN_HT20) &&
- (chanFlags & IEEE80211_CHAN_HT20) == 0) {
- if (verbose)
- printf("%u: skip, device does not support HT20 operation\n", freq);
+ /*
+ * Check if device can operate on this frequency.
+ */
+ if (!checkchan(avail, freq, flags)) {
+ if (verbose) {
+ printf("%u: skip, ", freq);
+ printb("flags", flags,
+ IEEE80211_CHAN_BITS);
+ printf(" not available\n");
+ }
continue;
}
- if ((flags & IEEE80211_CHAN_HT40) &&
- (chanFlags & IEEE80211_CHAN_HT40) == 0) {
+ if ((flags & REQ_ECM) && !reg->ecm) {
if (verbose)
- printf("%u: skip, device does not support HT40 operation\n", freq);
+ printf("%u: skip, ECM channel\n", freq);
continue;
}
- if ((flags & REQ_ECM) && !reg->ecm) {
+ if ((flags & REQ_INDOOR) && reg->location == 'O') {
if (verbose)
- printf("%u: skip, ECM channel\n", freq);
+ printf("%u: skip, indoor channel\n",
+ freq);
continue;
}
if ((flags & REQ_OUTDOOR) && reg->location == 'I') {
if (verbose)
- printf("%u: skip, outdoor channel\n", freq);
+ printf("%u: skip, outdoor channel\n",
+ freq);
continue;
}
if ((flags & IEEE80211_CHAN_HT40) &&
@@ -1820,21 +1961,24 @@ regdomain_addchans(struct ieee80211req_chaninfo *ci,
}
if (ci->ic_nchans == IEEE80211_CHAN_MAX) {
if (verbose)
- printf("%u: skip, channel table full\n", freq);
+ printf("%u: skip, channel table full\n",
+ freq);
break;
}
c = &ci->ic_chans[ci->ic_nchans++];
+ memset(c, 0, sizeof(*c));
c->ic_freq = freq;
- c->ic_flags = chanFlags |
- (flags &~ (REQ_FLAGS | IEEE80211_CHAN_HT40));
+ c->ic_flags = flags;
if (c->ic_flags & IEEE80211_CHAN_DFS)
c->ic_maxregpower = nb->maxPowerDFS;
else
c->ic_maxregpower = nb->maxPower;
- if (verbose)
- printf("[%3d] add freq %u flags 0x%x power %u\n",
- ci->ic_nchans-1, c->ic_freq, c->ic_flags,
- c->ic_maxregpower);
+ if (verbose) {
+ printf("[%3d] add freq %u ",
+ ci->ic_nchans-1, c->ic_freq);
+ printb("flags", c->ic_flags, IEEE80211_CHAN_BITS);
+ printf(" power %u\n", c->ic_maxregpower);
+ }
/* NB: kernel fills in other fields */
prev = c;
}
@@ -1872,7 +2016,14 @@ regdomain_makechannels(
errx(1, "internal error, regdomain %d not found",
reg->regdomain);
if (rd->sku != SKU_DEBUG) {
- memset(ci, 0, sizeof(*ci));
+ /*
+ * regdomain_addchans incrememnts the channel count for
+ * each channel it adds so initialize ic_nchans to zero.
+ * Note that we know we have enough space to hold all possible
+ * channels because the devcaps list size was used to
+ * allocate our request.
+ */
+ ci->ic_nchans = 0;
if (!LIST_EMPTY(&rd->bands_11b))
regdomain_addchans(ci, &rd->bands_11b, reg,
IEEE80211_CHAN_B, &dc->dc_chaninfo);
@@ -1882,32 +2033,37 @@ regdomain_makechannels(
if (!LIST_EMPTY(&rd->bands_11a))
regdomain_addchans(ci, &rd->bands_11a, reg,
IEEE80211_CHAN_A, &dc->dc_chaninfo);
- if (!LIST_EMPTY(&rd->bands_11na)) {
+ if (!LIST_EMPTY(&rd->bands_11na) && dc->dc_htcaps != 0) {
regdomain_addchans(ci, &rd->bands_11na, reg,
IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,
&dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11na, reg,
- IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U,
- &dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11na, reg,
- IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D,
- &dc->dc_chaninfo);
+ if (dc->dc_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
+ regdomain_addchans(ci, &rd->bands_11na, reg,
+ IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U,
+ &dc->dc_chaninfo);
+ regdomain_addchans(ci, &rd->bands_11na, reg,
+ IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D,
+ &dc->dc_chaninfo);
+ }
}
- if (!LIST_EMPTY(&rd->bands_11ng)) {
+ if (!LIST_EMPTY(&rd->bands_11ng) && dc->dc_htcaps != 0) {
regdomain_addchans(ci, &rd->bands_11ng, reg,
IEEE80211_CHAN_G | IEEE80211_CHAN_HT20,
&dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11ng, reg,
- IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U,
- &dc->dc_chaninfo);
- regdomain_addchans(ci, &rd->bands_11ng, reg,
- IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D,
- &dc->dc_chaninfo);
+ if (dc->dc_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
+ regdomain_addchans(ci, &rd->bands_11ng, reg,
+ IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U,
+ &dc->dc_chaninfo);
+ regdomain_addchans(ci, &rd->bands_11ng, reg,
+ IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D,
+ &dc->dc_chaninfo);
+ }
}
qsort(ci->ic_chans, ci->ic_nchans, sizeof(ci->ic_chans[0]),
regdomain_sort);
} else
- *ci = dc->dc_chaninfo;
+ memcpy(ci, &dc->dc_chaninfo,
+ IEEE80211_CHANINFO_SPACE(&dc->dc_chaninfo));
}
static void
@@ -2558,6 +2714,22 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
#undef N
}
+static void
+printtdmaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
+{
+ printf("%s", tag);
+ if (verbose && ielen >= sizeof(struct ieee80211_tdma_param)) {
+ const struct ieee80211_tdma_param *tdma =
+ (const struct ieee80211_tdma_param *) ie;
+
+ /* XXX tstamp */
+ printf("<v%u slot:%u slotcnt:%u slotlen:%u bintval:%u inuse:0x%x>",
+ tdma->tdma_version, tdma->tdma_slot, tdma->tdma_slotcnt,
+ LE_READ_2(&tdma->tdma_slotlen), tdma->tdma_bintval,
+ tdma->tdma_inuse[0]);
+ }
+}
+
/*
* Copy the ssid string contents into buf, truncating to fit. If the
* ssid is entirely printable then just copy intact. Otherwise convert
@@ -2681,6 +2853,12 @@ isatherosoui(const u_int8_t *frm)
}
static __inline int
+istdmaoui(const uint8_t *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI);
+}
+
+static __inline int
iswpsoui(const uint8_t *frm)
{
return frm[1] > 3 && LE_READ_4(frm+2) == ((WPS_OUI_TYPE<<24)|WPA_OUI);
@@ -2749,6 +2927,8 @@ printies(const u_int8_t *vp, int ielen, int maxcols)
printathie(" ATH", vp, 2+vp[1], maxcols);
else if (iswpsoui(vp))
printwpsie(" WPS", vp, 2+vp[1], maxcols);
+ else if (istdmaoui(vp))
+ printtdmaie(" TDMA", vp, 2+vp[1], maxcols);
else if (verbose)
printie(" VEN", vp, 2+vp[1], maxcols);
break;
@@ -3003,23 +3183,16 @@ get_chaninfo(const struct ieee80211_channel *c, int precise,
buf[0] = '\0';
if (IEEE80211_IS_CHAN_FHSS(c))
strlcat(buf, " FHSS", bsize);
- if (IEEE80211_IS_CHAN_A(c)) {
- if (IEEE80211_IS_CHAN_HALF(c))
- strlcat(buf, " 11a/10Mhz", bsize);
- else if (IEEE80211_IS_CHAN_QUARTER(c))
- strlcat(buf, " 11a/5Mhz", bsize);
- else
- strlcat(buf, " 11a", bsize);
- }
- if (IEEE80211_IS_CHAN_ANYG(c)) {
- if (IEEE80211_IS_CHAN_HALF(c))
- strlcat(buf, " 11g/10Mhz", bsize);
- else if (IEEE80211_IS_CHAN_QUARTER(c))
- strlcat(buf, " 11g/5Mhz", bsize);
- else
- strlcat(buf, " 11g", bsize);
- } else if (IEEE80211_IS_CHAN_B(c))
+ if (IEEE80211_IS_CHAN_A(c))
+ strlcat(buf, " 11a", bsize);
+ else if (IEEE80211_IS_CHAN_ANYG(c))
+ strlcat(buf, " 11g", bsize);
+ else if (IEEE80211_IS_CHAN_B(c))
strlcat(buf, " 11b", bsize);
+ if (IEEE80211_IS_CHAN_HALF(c))
+ strlcat(buf, "/10Mhz", bsize);
+ if (IEEE80211_IS_CHAN_QUARTER(c))
+ strlcat(buf, "/5Mhz", bsize);
if (IEEE80211_IS_CHAN_TURBO(c))
strlcat(buf, " Turbo", bsize);
if (precise) {
@@ -3047,23 +3220,49 @@ print_chaninfo(const struct ieee80211_channel *c, int verb)
get_chaninfo(c, verb, buf, sizeof(buf)));
}
+static int
+chanpref(const struct ieee80211_channel *c)
+{
+ if (IEEE80211_IS_CHAN_HT40(c))
+ return 40;
+ if (IEEE80211_IS_CHAN_HT20(c))
+ return 30;
+ if (IEEE80211_IS_CHAN_HALF(c))
+ return 10;
+ if (IEEE80211_IS_CHAN_QUARTER(c))
+ return 5;
+ if (IEEE80211_IS_CHAN_TURBO(c))
+ return 25;
+ if (IEEE80211_IS_CHAN_A(c))
+ return 20;
+ if (IEEE80211_IS_CHAN_G(c))
+ return 20;
+ if (IEEE80211_IS_CHAN_B(c))
+ return 15;
+ if (IEEE80211_IS_CHAN_PUREG(c))
+ return 15;
+ return 0;
+}
+
static void
print_channels(int s, const struct ieee80211req_chaninfo *chans,
int allchans, int verb)
{
- struct ieee80211req_chaninfo achans;
+ struct ieee80211req_chaninfo *achans;
uint8_t reported[IEEE80211_CHAN_BYTES];
const struct ieee80211_channel *c;
int i, half;
- memset(&achans, 0, sizeof(achans));
+ achans = malloc(IEEE80211_CHANINFO_SPACE(chans));
+ if (achans == NULL)
+ errx(1, "no space for active channel list");
+ achans->ic_nchans = 0;
memset(reported, 0, sizeof(reported));
if (!allchans) {
struct ieee80211req_chanlist active;
if (get80211(s, IEEE80211_IOC_CHANLIST, &active, sizeof(active)) < 0)
errx(1, "unable to get active channel list");
- memset(&achans, 0, sizeof(achans));
for (i = 0; i < chans->ic_nchans; i++) {
c = &chans->ic_chans[i];
if (!isset(active.ic_channels, c->ic_ieee))
@@ -3076,9 +3275,9 @@ print_channels(int s, const struct ieee80211req_chaninfo *chans,
*/
if (isset(reported, c->ic_ieee) && !verb) {
/* XXX we assume duplicates are adjacent */
- achans.ic_chans[achans.ic_nchans-1] = *c;
+ achans->ic_chans[achans->ic_nchans-1] = *c;
} else {
- achans.ic_chans[achans.ic_nchans++] = *c;
+ achans->ic_chans[achans->ic_nchans++] = *c;
setbit(reported, c->ic_ieee);
}
}
@@ -3088,33 +3287,37 @@ print_channels(int s, const struct ieee80211req_chaninfo *chans,
/* suppress duplicates as above */
if (isset(reported, c->ic_ieee) && !verb) {
/* XXX we assume duplicates are adjacent */
- achans.ic_chans[achans.ic_nchans-1] = *c;
+ struct ieee80211_channel *a =
+ &achans->ic_chans[achans->ic_nchans-1];
+ if (chanpref(c) > chanpref(a))
+ *a = *c;
} else {
- achans.ic_chans[achans.ic_nchans++] = *c;
+ achans->ic_chans[achans->ic_nchans++] = *c;
setbit(reported, c->ic_ieee);
}
}
}
- half = achans.ic_nchans / 2;
- if (achans.ic_nchans % 2)
+ half = achans->ic_nchans / 2;
+ if (achans->ic_nchans % 2)
half++;
- for (i = 0; i < achans.ic_nchans / 2; i++) {
- print_chaninfo(&achans.ic_chans[i], verb);
- print_chaninfo(&achans.ic_chans[half+i], verb);
+ for (i = 0; i < achans->ic_nchans / 2; i++) {
+ print_chaninfo(&achans->ic_chans[i], verb);
+ print_chaninfo(&achans->ic_chans[half+i], verb);
printf("\n");
}
- if (achans.ic_nchans % 2) {
- print_chaninfo(&achans.ic_chans[i], verb);
+ if (achans->ic_nchans % 2) {
+ print_chaninfo(&achans->ic_chans[i], verb);
printf("\n");
}
+ free(achans);
}
static void
list_channels(int s, int allchans)
{
getchaninfo(s);
- print_channels(s, &chaninfo, allchans, verbose);
+ print_channels(s, chaninfo, allchans, verbose);
}
static void
@@ -3139,48 +3342,52 @@ print_txpow_verbose(const struct ieee80211_channel *c)
static void
list_txpow(int s)
{
- struct ieee80211req_chaninfo achans;
+ struct ieee80211req_chaninfo *achans;
uint8_t reported[IEEE80211_CHAN_BYTES];
struct ieee80211_channel *c, *prev;
int i, half;
getchaninfo(s);
- memset(&achans, 0, sizeof(achans));
+ achans = malloc(IEEE80211_CHANINFO_SPACE(chaninfo));
+ if (achans == NULL)
+ errx(1, "no space for active channel list");
+ achans->ic_nchans = 0;
memset(reported, 0, sizeof(reported));
- for (i = 0; i < chaninfo.ic_nchans; i++) {
- c = &chaninfo.ic_chans[i];
+ for (i = 0; i < chaninfo->ic_nchans; i++) {
+ c = &chaninfo->ic_chans[i];
/* suppress duplicates as above */
if (isset(reported, c->ic_ieee) && !verbose) {
/* XXX we assume duplicates are adjacent */
- prev = &achans.ic_chans[achans.ic_nchans-1];
+ prev = &achans->ic_chans[achans->ic_nchans-1];
/* display highest power on channel */
if (c->ic_maxpower > prev->ic_maxpower)
*prev = *c;
} else {
- achans.ic_chans[achans.ic_nchans++] = *c;
+ achans->ic_chans[achans->ic_nchans++] = *c;
setbit(reported, c->ic_ieee);
}
}
if (!verbose) {
- half = achans.ic_nchans / 2;
- if (achans.ic_nchans % 2)
+ half = achans->ic_nchans / 2;
+ if (achans->ic_nchans % 2)
half++;
- for (i = 0; i < achans.ic_nchans / 2; i++) {
- print_txpow(&achans.ic_chans[i]);
- print_txpow(&achans.ic_chans[half+i]);
+ for (i = 0; i < achans->ic_nchans / 2; i++) {
+ print_txpow(&achans->ic_chans[i]);
+ print_txpow(&achans->ic_chans[half+i]);
printf("\n");
}
- if (achans.ic_nchans % 2) {
- print_txpow(&achans.ic_chans[i]);
+ if (achans->ic_nchans % 2) {
+ print_txpow(&achans->ic_chans[i]);
printf("\n");
}
} else {
- for (i = 0; i < achans.ic_nchans; i++) {
- print_txpow_verbose(&achans.ic_chans[i]);
+ for (i = 0; i < achans->ic_nchans; i++) {
+ print_txpow_verbose(&achans->ic_chans[i]);
printf("\n");
}
}
+ free(achans);
}
static void
@@ -3192,31 +3399,36 @@ list_keys(int s)
"\20\1STA\7FF\10TURBOP\11IBSS\12PMGT" \
"\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \
"\21MONITOR\22DFS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
- "\37TXFRAG"
-
-#define IEEE80211_CRYPTO_BITS \
- "\20\1WEP\2TKIP\3AES\4AES_CCM\5TKIPMIC\6CKIP\12PMGT"
-
-#define IEEE80211_HTCAP_BITS \
- "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
- "\21AMPDU\22AMSDU\23HT"
+ "\37TXFRAG\40TDMA"
static void
list_capabilities(int s)
{
- struct ieee80211_devcaps_req dc;
+ struct ieee80211_devcaps_req *dc;
- getdevcaps(s, &dc);
- printb("drivercaps", dc.dc_drivercaps, IEEE80211_C_BITS);
- if (dc.dc_cryptocaps != 0 || verbose) {
+ if (verbose)
+ dc = malloc(IEEE80211_DEVCAPS_SIZE(MAXCHAN));
+ else
+ dc = malloc(IEEE80211_DEVCAPS_SIZE(1));
+ if (dc == NULL)
+ errx(1, "no space for device capabilities");
+ dc->dc_chaninfo.ic_nchans = verbose ? MAXCHAN : 1;
+ getdevcaps(s, dc);
+ printb("drivercaps", dc->dc_drivercaps, IEEE80211_C_BITS);
+ if (dc->dc_cryptocaps != 0 || verbose) {
putchar('\n');
- printb("cryptocaps", dc.dc_cryptocaps, IEEE80211_CRYPTO_BITS);
+ printb("cryptocaps", dc->dc_cryptocaps, IEEE80211_CRYPTO_BITS);
}
- if (dc.dc_htcaps != 0 || verbose) {
+ if (dc->dc_htcaps != 0 || verbose) {
putchar('\n');
- printb("htcaps", dc.dc_htcaps, IEEE80211_HTCAP_BITS);
+ printb("htcaps", dc->dc_htcaps, IEEE80211_HTCAP_BITS);
}
putchar('\n');
+ if (verbose) {
+ chaninfo = &dc->dc_chaninfo; /* XXX */
+ print_channels(s, &dc->dc_chaninfo, 1/*allchans*/, verbose);
+ }
+ free(dc);
}
static int
@@ -3495,7 +3707,7 @@ list_regdomain(int s, int channelsalso)
spacer = ':';
print_regdomain(&regdomain, 1);
LINE_BREAK();
- print_channels(s, &chaninfo, 1/*allchans*/, 1/*verbose*/);
+ print_channels(s, chaninfo, 1/*allchans*/, 1/*verbose*/);
} else
print_regdomain(&regdomain, verbose);
}
@@ -4263,7 +4475,16 @@ end:
}
}
- if (get80211val(s, IEEE80211_IOC_BEACON_INTERVAL, &val) != -1) {
+ if (opmode == IEEE80211_M_AHDEMO) {
+ if (get80211val(s, IEEE80211_IOC_TDMA_SLOT, &val) != -1)
+ LINE_CHECK("tdmaslot %u", val);
+ if (get80211val(s, IEEE80211_IOC_TDMA_SLOTCNT, &val) != -1)
+ LINE_CHECK("tdmaslotcnt %u", val);
+ if (get80211val(s, IEEE80211_IOC_TDMA_SLOTLEN, &val) != -1)
+ LINE_CHECK("tdmaslotlen %u", val);
+ if (get80211val(s, IEEE80211_IOC_TDMA_BINTERVAL, &val) != -1)
+ LINE_CHECK("tdmabintval %u", val);
+ } else if (get80211val(s, IEEE80211_IOC_BEACON_INTERVAL, &val) != -1) {
/* XXX default define not visible */
if (val != 100 || verbose)
LINE_CHECK("bintval %u", val);
@@ -4298,6 +4519,7 @@ get80211len(int s, int type, void *data, int len, int *plen)
(void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
ireq.i_type = type;
ireq.i_len = len;
+ assert(ireq.i_len == len); /* NB: check for 16-bit truncation */
ireq.i_data = data;
if (ioctl(s, SIOCG80211, &ireq) < 0)
return -1;
@@ -4329,6 +4551,7 @@ set80211(int s, int type, int val, int len, void *data)
ireq.i_type = type;
ireq.i_val = val;
ireq.i_len = len;
+ assert(ireq.i_len == len); /* NB: check for 16-bit truncation */
ireq.i_data = data;
if (ioctl(s, SIOCS80211, &ireq) < 0)
err(1, "SIOCS80211");
@@ -4486,7 +4709,10 @@ DECL_CMD_FUNC(set80211clone_wlanmode, arg, d)
params.icp_opmode = IEEE80211_M_WDS;
else if (iseq(arg, "monitor"))
params.icp_opmode = IEEE80211_M_MONITOR;
- else
+ else if (iseq(arg, "tdma")) {
+ params.icp_opmode = IEEE80211_M_AHDEMO;
+ params.icp_flags |= IEEE80211_CLONE_TDMA;
+ } else
errx(1, "Don't know to create %s for %s", arg, name);
clone_setcallback(wlan_create);
#undef iseq
@@ -4662,6 +4888,11 @@ static struct cmd ieee80211_cmds[] = {
/* XXX for testing */
DEF_CMD_ARG("chanswitch", set80211chanswitch),
+ DEF_CMD_ARG("tdmaslot", set80211tdmaslot),
+ DEF_CMD_ARG("tdmaslotcnt", set80211tdmaslotcnt),
+ DEF_CMD_ARG("tdmaslotlen", set80211tdmaslotlen),
+ DEF_CMD_ARG("tdmabintval", set80211tdmabintval),
+
/* vap cloning support */
DEF_CLONE_CMD_ARG("wlanaddr", set80211clone_wlanaddr),
DEF_CLONE_CMD_ARG("wlanbssid", set80211clone_wlanbssid),
diff --git a/sbin/ifconfig/regdomain.c b/sbin/ifconfig/regdomain.c
index 5846469..a06ba55 100644
--- a/sbin/ifconfig/regdomain.c
+++ b/sbin/ifconfig/regdomain.c
@@ -208,6 +208,9 @@ decode_flag(struct mystate *mt, const char *p, int len)
FLAG(IEEE80211_CHAN_108A),
FLAG(IEEE80211_CHAN_108G),
#undef FLAG
+ { "ECM", 3, REQ_ECM },
+ { "INDOOR", 6, REQ_INDOOR },
+ { "OUTDOOR", 7, REQ_OUTDOOR },
};
int i;
@@ -289,6 +292,10 @@ end_element(void *data, const char *name)
mt->netband->maxPowerDFS = strtoul(p, NULL, 0);
goto done;
}
+ if (iseq(name, "maxantgain") && mt->netband != NULL) {
+ mt->netband->maxAntGain = strtoul(p, NULL, 0);
+ goto done;
+ }
/* <country>...</country> */
if (iseq(name, "isocc") && mt->country != NULL) {
diff --git a/sbin/ifconfig/regdomain.h b/sbin/ifconfig/regdomain.h
index 5b37a0b..cfc2be0 100644
--- a/sbin/ifconfig/regdomain.h
+++ b/sbin/ifconfig/regdomain.h
@@ -45,10 +45,18 @@ struct freqband {
LIST_ENTRY(freqband) next;
};
+/* private flags, don't pass to os */
+#define REQ_ECM 0x1 /* enable if ECM set */
+#define REQ_INDOOR 0x2 /* enable only for indoor operation */
+#define REQ_OUTDOOR 0x4 /* enable only for outdoor operation */
+
+#define REQ_FLAGS (REQ_ECM|REQ_INDOOR|REQ_OUTDOOR)
+
struct netband {
const struct freqband *band; /* channel list description */
uint8_t maxPower; /* regulatory cap on tx power (dBm) */
uint8_t maxPowerDFS; /* regulatory cap w/ DFS (dBm) */
+ uint8_t maxAntGain; /* max allowed antenna gain (.5 dBm) */
uint32_t flags; /* net80211 channel flags */
LIST_ENTRY(netband) next;
diff --git a/sbin/ipfw/Makefile b/sbin/ipfw/Makefile
index 023f682..3205c66 100644
--- a/sbin/ipfw/Makefile
+++ b/sbin/ipfw/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
PROG= ipfw
-SRCS= ipfw2.c
-WARNS?= 0
+SRCS= ipfw2.c dummynet.c ipv6.c main.c nat.c altq.c
+WARNS?= 2
MAN= ipfw.8
.include <bsd.prog.mk>
diff --git a/sbin/ipfw/altq.c b/sbin/ipfw/altq.c
new file mode 100644
index 0000000..088b80e
--- /dev/null
+++ b/sbin/ipfw/altq.c
@@ -0,0 +1,150 @@
+/*
+ * 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
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ * $FreeBSD$
+ *
+ * altq interface
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include "ipfw2.h"
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <net/if.h> /* IFNAMSIZ */
+#include <net/pfvar.h>
+#include <netinet/ip_fw.h>
+
+/*
+ * Map between current altq queue id numbers and names.
+ */
+static TAILQ_HEAD(, pf_altq) altq_entries =
+ TAILQ_HEAD_INITIALIZER(altq_entries);
+
+void
+altq_set_enabled(int enabled)
+{
+ int pffd;
+
+ pffd = open("/dev/pf", O_RDWR);
+ if (pffd == -1)
+ err(EX_UNAVAILABLE,
+ "altq support opening pf(4) control device");
+ if (enabled) {
+ if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST)
+ err(EX_UNAVAILABLE, "enabling altq");
+ } else {
+ if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT)
+ err(EX_UNAVAILABLE, "disabling altq");
+ }
+ close(pffd);
+}
+
+static void
+altq_fetch(void)
+{
+ struct pfioc_altq pfioc;
+ struct pf_altq *altq;
+ int pffd;
+ unsigned int mnr;
+ static int altq_fetched = 0;
+
+ if (altq_fetched)
+ return;
+ altq_fetched = 1;
+ pffd = open("/dev/pf", O_RDONLY);
+ if (pffd == -1) {
+ warn("altq support opening pf(4) control device");
+ return;
+ }
+ bzero(&pfioc, sizeof(pfioc));
+ if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
+ warn("altq support getting queue list");
+ close(pffd);
+ return;
+ }
+ mnr = pfioc.nr;
+ for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
+ if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
+ if (errno == EBUSY)
+ break;
+ warn("altq support getting queue list");
+ close(pffd);
+ return;
+ }
+ if (pfioc.altq.qid == 0)
+ continue;
+ altq = safe_calloc(1, sizeof(*altq));
+ *altq = pfioc.altq;
+ TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
+ }
+ close(pffd);
+}
+
+u_int32_t
+altq_name_to_qid(const char *name)
+{
+ struct pf_altq *altq;
+
+ altq_fetch();
+ TAILQ_FOREACH(altq, &altq_entries, entries)
+ if (strcmp(name, altq->qname) == 0)
+ break;
+ if (altq == NULL)
+ errx(EX_DATAERR, "altq has no queue named `%s'", name);
+ return altq->qid;
+}
+
+const char *
+altq_qid_to_name(u_int32_t qid)
+{
+ struct pf_altq *altq;
+
+ altq_fetch();
+ TAILQ_FOREACH(altq, &altq_entries, entries)
+ if (qid == altq->qid)
+ break;
+ if (altq == NULL)
+ return NULL;
+ return altq->qname;
+}
+
+void
+print_altq_cmd(ipfw_insn_altq *altqptr)
+{
+ if (altqptr) {
+ const char *qname;
+
+ qname = altq_qid_to_name(altqptr->qid);
+ if (qname == NULL)
+ printf(" altq ?<%u>", altqptr->qid);
+ else
+ printf(" altq %s", qname);
+ }
+}
diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c
new file mode 100644
index 0000000..5c83db9
--- /dev/null
+++ b/sbin/ipfw/dummynet.c
@@ -0,0 +1,719 @@
+/*
+ * 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
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ * $FreeBSD$
+ *
+ * dummynet support
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+/* XXX there are several sysctl leftover here */
+#include <sys/sysctl.h>
+
+#include "ipfw2.h"
+
+#include <ctype.h>
+#include <err.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/ip_fw.h>
+#include <netinet/ip_dummynet.h>
+#include <arpa/inet.h> /* inet_ntoa */
+
+static struct _s_x dummynet_params[] = {
+ { "plr", TOK_PLR },
+ { "noerror", TOK_NOERROR },
+ { "buckets", TOK_BUCKETS },
+ { "dst-ip", TOK_DSTIP },
+ { "src-ip", TOK_SRCIP },
+ { "dst-port", TOK_DSTPORT },
+ { "src-port", TOK_SRCPORT },
+ { "proto", TOK_PROTO },
+ { "weight", TOK_WEIGHT },
+ { "all", TOK_ALL },
+ { "mask", TOK_MASK },
+ { "droptail", TOK_DROPTAIL },
+ { "red", TOK_RED },
+ { "gred", TOK_GRED },
+ { "bw", TOK_BW },
+ { "bandwidth", TOK_BW },
+ { "delay", TOK_DELAY },
+ { "pipe", TOK_PIPE },
+ { "queue", TOK_QUEUE },
+ { "flow-id", TOK_FLOWID},
+ { "dst-ipv6", TOK_DSTIP6},
+ { "dst-ip6", TOK_DSTIP6},
+ { "src-ipv6", TOK_SRCIP6},
+ { "src-ip6", TOK_SRCIP6},
+ { "dummynet-params", TOK_NULL },
+ { NULL, 0 } /* terminator */
+};
+
+static int
+sort_q(const void *pa, const void *pb)
+{
+ int rev = (co.do_sort < 0);
+ int field = rev ? -co.do_sort : co.do_sort;
+ long long res = 0;
+ const struct dn_flow_queue *a = pa;
+ const struct dn_flow_queue *b = pb;
+
+ switch (field) {
+ case 1: /* pkts */
+ res = a->len - b->len;
+ break;
+ case 2: /* bytes */
+ res = a->len_bytes - b->len_bytes;
+ break;
+
+ case 3: /* tot pkts */
+ res = a->tot_pkts - b->tot_pkts;
+ break;
+
+ case 4: /* tot bytes */
+ res = a->tot_bytes - b->tot_bytes;
+ break;
+ }
+ if (res < 0)
+ res = -1;
+ if (res > 0)
+ res = 1;
+ return (int)(rev ? res : -res);
+}
+
+static void
+list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
+{
+ int l;
+ int index_printed, indexes = 0;
+ char buff[255];
+ struct protoent *pe;
+
+ if (fs->rq_elements == 0)
+ return;
+
+ if (co.do_sort != 0)
+ heapsort(q, fs->rq_elements, sizeof *q, sort_q);
+
+ /* Print IPv4 flows */
+ index_printed = 0;
+ for (l = 0; l < fs->rq_elements; l++) {
+ struct in_addr ina;
+
+ /* 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);
+ if (pe)
+ printf("%-4s ", pe->p_name);
+ else
+ printf("%4u ", q[l].id.proto);
+ ina.s_addr = htonl(q[l].id.src_ip);
+ printf("%15s/%-5d ",
+ inet_ntoa(ina), q[l].id.src_port);
+ ina.s_addr = htonl(q[l].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);
+ 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(" %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));
+ }
+}
+
+static void
+print_flowset_parms(struct dn_flow_set *fs, char *prefix)
+{
+ int l;
+ char qs[30];
+ char plr[30];
+ char red[90]; /* Display RED parameters */
+
+ l = fs->qsize;
+ if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
+ if (l >= 8192)
+ sprintf(qs, "%d KB", l / 1024);
+ else
+ sprintf(qs, "%d B", l);
+ } else
+ sprintf(qs, "%3d sl.", l);
+ if (fs->plr)
+ sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
+ else
+ plr[0] = '\0';
+ if (fs->flags_fs & 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' : ' ',
+ 1.0 * fs->w_q / (double)(1 << SCALE_RED),
+ SCALE_VAL(fs->min_th),
+ SCALE_VAL(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);
+}
+
+void
+ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[])
+{
+ 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];
+
+ 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 (co.verbose)
+ printf(" V %20llu\n", align_uint64(&p->V) >> MY_M);
+
+ 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);
+ }
+}
+
+/*
+ * Delete pipe or queue i
+ */
+int
+ipfw_delete_pipe(int pipe_or_queue, 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);
+ if (i) {
+ i = 1;
+ warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i);
+ }
+ return i;
+}
+
+void
+ipfw_config_pipe(int ac, char **av)
+{
+ struct dn_pipe p;
+ int i;
+ char *end;
+ void *par = NULL;
+
+ memset(&p, 0, sizeof p);
+
+ 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;
+ }
+ while (ac > 0) {
+ double d;
+ int tok = match_token(dummynet_params, *av);
+ ac--; av++;
+
+ switch(tok) {
+ case TOK_NOERROR:
+ p.fs.flags_fs |= DN_NOERROR;
+ break;
+
+ case TOK_PLR:
+ 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);
+ ac--; av++;
+ break;
+
+ case TOK_QUEUE:
+ NEED1("queue needs queue size\n");
+ end = NULL;
+ p.fs.qsize = strtoul(av[0], &end, 0);
+ if (*end == 'K' || *end == 'k') {
+ p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
+ p.fs.qsize *= 1024;
+ } else if (*end == 'B' ||
+ _substrcmp2(end, "by", "bytes") == 0) {
+ p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
+ }
+ ac--; av++;
+ break;
+
+ case TOK_BUCKETS:
+ NEED1("buckets needs argument\n");
+ p.fs.rq_size = strtoul(av[0], NULL, 0);
+ ac--; av++;
+ break;
+
+ case TOK_MASK:
+ NEED1("mask needs mask specifier\n");
+ /*
+ * per-flow queue, mask is dst_ip, dst_port,
+ * src_ip, src_port, proto measured in bits
+ */
+ par = NULL;
+
+ bzero(&p.fs.flow_mask, sizeof(p.fs.flow_mask));
+ end = NULL;
+
+ while (ac >= 1) {
+ uint32_t *p32 = NULL;
+ uint16_t *p16 = NULL;
+ uint32_t *p20 = NULL;
+ struct in6_addr *pa6 = NULL;
+ uint32_t a;
+
+ tok = match_token(dummynet_params, *av);
+ ac--; av++;
+ switch(tok) {
+ case TOK_ALL:
+ /*
+ * special case, all bits significant
+ */
+ 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;
+ goto end_mask;
+
+ case TOK_DSTIP:
+ p32 = &p.fs.flow_mask.dst_ip;
+ break;
+
+ case TOK_SRCIP:
+ p32 = &p.fs.flow_mask.src_ip;
+ break;
+
+ case TOK_DSTIP6:
+ pa6 = &(p.fs.flow_mask.dst_ip6);
+ break;
+
+ case TOK_SRCIP6:
+ pa6 = &(p.fs.flow_mask.src_ip6);
+ break;
+
+ case TOK_FLOWID:
+ p20 = &p.fs.flow_mask.flow_id6;
+ break;
+
+ case TOK_DSTPORT:
+ p16 = &p.fs.flow_mask.dst_port;
+ break;
+
+ case TOK_SRCPORT:
+ p16 = &p.fs.flow_mask.src_port;
+ break;
+
+ case TOK_PROTO:
+ break;
+
+ default:
+ ac++; av--; /* backtrack */
+ goto end_mask;
+ }
+ if (ac < 1)
+ errx(EX_USAGE, "mask: value missing");
+ if (*av[0] == '/') {
+ a = strtoul(av[0]+1, &end, 0);
+ if (pa6 == NULL)
+ a = (a == 32) ? ~0 : (1 << a) - 1;
+ } else
+ a = strtoul(av[0], &end, 0);
+ if (p32 != NULL)
+ *p32 = a;
+ else if (p16 != NULL) {
+ if (a > 0xFFFF)
+ errx(EX_DATAERR,
+ "port mask must be 16 bit");
+ *p16 = (uint16_t)a;
+ } else if (p20 != NULL) {
+ if (a > 0xfffff)
+ errx(EX_DATAERR,
+ "flow_id mask must be 20 bit");
+ *p20 = (uint32_t)a;
+ } else if (pa6 != NULL) {
+ if (a > 128)
+ errx(EX_DATAERR,
+ "in6addr invalid mask len");
+ else
+ n2mask(pa6, a);
+ } else {
+ if (a > 0xFF)
+ errx(EX_DATAERR,
+ "proto mask must be 8 bit");
+ p.fs.flow_mask.proto = (uint8_t)a;
+ }
+ if (a != 0)
+ p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
+ ac--; av++;
+ } /* end while, config masks */
+end_mask:
+ break;
+
+ 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;
+ if (tok == TOK_GRED)
+ p.fs.flags_fs |= DN_IS_GENTLE_RED;
+ /*
+ * the format for parameters is w_q/min_th/max_th/max_p
+ */
+ if ((end = strsep(&av[0], "/"))) {
+ 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));
+ }
+ if ((end = strsep(&av[0], "/"))) {
+ p.fs.min_th = strtoul(end, &end, 0);
+ if (*end == 'K' || *end == 'k')
+ p.fs.min_th *= 1024;
+ }
+ if ((end = strsep(&av[0], "/"))) {
+ p.fs.max_th = strtoul(end, &end, 0);
+ if (*end == 'K' || *end == 'k')
+ p.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));
+ }
+ ac--; av++;
+ break;
+
+ case TOK_DROPTAIL:
+ p.fs.flags_fs &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
+ break;
+
+ case TOK_BW:
+ NEED1("bw needs bandwidth or interface\n");
+ if (co.do_pipe != 1)
+ errx(EX_DATAERR, "bandwidth only valid for pipes");
+ /*
+ * set clocking interface or bandwidth value
+ */
+ if (av[0][0] >= 'a' && av[0][0] <= 'z') {
+ int l = sizeof(p.if_name)-1;
+ /* interface name */
+ strncpy(p.if_name, av[0], l);
+ p.if_name[l] = '\0';
+ p.bandwidth = 0;
+ } else {
+ p.if_name[0] = '\0';
+ p.bandwidth = strtoul(av[0], &end, 0);
+ if (*end == 'K' || *end == 'k') {
+ end++;
+ p.bandwidth *= 1000;
+ } else if (*end == 'M') {
+ end++;
+ p.bandwidth *= 1000000;
+ }
+ if ((*end == 'B' &&
+ _substrcmp2(end, "Bi", "Bit/s") != 0) ||
+ _substrcmp2(end, "by", "bytes") == 0)
+ p.bandwidth *= 8;
+ if (p.bandwidth < 0)
+ errx(EX_DATAERR, "bandwidth too large");
+ }
+ ac--; av++;
+ break;
+
+ case TOK_DELAY:
+ if (co.do_pipe != 1)
+ errx(EX_DATAERR, "delay only valid for pipes");
+ NEED1("delay needs argument 0..10000ms\n");
+ p.delay = strtoul(av[0], NULL, 0);
+ 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);
+ ac--; av++;
+ break;
+
+ 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);
+ ac--; av++;
+ break;
+
+ default:
+ 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");
+ }
+ if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) {
+ size_t len;
+ long limit;
+
+ len = sizeof(limit);
+ if (sysctlbyname("net.inet.ip.dummynet.pipe_byte_limit",
+ &limit, &len, NULL, 0) == -1)
+ limit = 1024*1024;
+ if (p.fs.qsize > limit)
+ errx(EX_DATAERR, "queue size must be < %ldB", limit);
+ } else {
+ size_t len;
+ long limit;
+
+ len = sizeof(limit);
+ if (sysctlbyname("net.inet.ip.dummynet.pipe_slot_limit",
+ &limit, &len, NULL, 0) == -1)
+ limit = 100;
+ if (p.fs.qsize > limit)
+ errx(EX_DATAERR, "2 <= queue size <= %ld", limit);
+ }
+ if (p.fs.flags_fs & DN_IS_RED) {
+ size_t len;
+ int lookup_depth, avg_pkt_size;
+ double s, idle, weight, w_q;
+ struct clockinfo ck;
+ int t;
+
+ if (p.fs.min_th >= p.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)
+ 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");
+ if (lookup_depth == 0)
+ errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth"
+ " must be greater than zero");
+
+ len = sizeof(int);
+ if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
+ &avg_pkt_size, &len, NULL, 0) == -1)
+
+ 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
+ * do not have bandwidth information, because that is stored
+ * in the parent pipe, and also we have multiple queues
+ * competing for it. So we set s=0, which is not very
+ * correct. But on the other hand, why do we want RED with
+ * WF2Q+ ?
+ */
+ if (p.bandwidth==0) /* this is a WF2Q+ queue */
+ s = 0;
+ else
+ s = (double)ck.hz * avg_pkt_size * 8 / p.bandwidth;
+
+ /*
+ * 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);
+ idle = s * 3. / w_q;
+ p.fs.lookup_step = (int)idle / lookup_depth;
+ if (!p.fs.lookup_step)
+ p.fs.lookup_step = 1;
+ weight = 1 - w_q;
+ for (t = p.fs.lookup_step; t > 1; --t)
+ weight *= 1 - w_q;
+ p.fs.lookup_weight = (int)(weight * (1 << SCALE_RED));
+ }
+ i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p);
+ if (i)
+ err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
+}
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 83ba7a4..997be62 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -2183,17 +2183,173 @@ Redirect and LSNAT support follow closely the syntax used in
See Section
.Sx EXAMPLES
for some examples on how to do redirect and lsnat.
+.Sh SCTP NAT SUPPORT
+Sctp nat can be configured in a simillar manner to TCP through the
+ipfw command line tool
+.Xr ipfw 8
+, the main difference is that
+.Nm sctp nat
+does not do port
+translation. Since the local and global side ports will be the same,
+there is no need to specify both. Ports are redirected as follows:
+.Bd -ragged -offset indent
+.Bk -words
+.Cm nat
+.Ar nat_number
+.Cm config if
+.Ar nic
+.Cm redirect_port sctp
+.Ar ip_address [,addr_list] {[port | port-port] [,ports]}
+.Ek
+.Ed
+.Pp
+.
+Most
+.B sctp nat
+configuration can be done in real-time through the
+.B sysctl(8)
+interface. All may be changed dynamically, though the hash_table size will only
+change for new
+.Nm nat
+instances. See
+.Sx SYSCTL VARIABLES
+for more info.
.Sh SYSCTL VARIABLES
A set of
.Xr sysctl 8
variables controls the behaviour of the firewall and
associated modules
-.Pq Nm dummynet , bridge .
+.Pq Nm dummynet , bridge , sctp nat .
These are shown below together with their default value
(but always check with the
.Xr sysctl 8
command what value is actually in use) and meaning:
.Bl -tag -width indent
+.It Va net.inet.ip.alias.sctp.accept_global_ootb_addip: No 0
+Defines how the
+.Nm nat
+responds to receipt of global OOTB ASCONF-AddIP:
+.Bl -tag -width indent
+.It Cm 0
+No response (unless a partially matching association exists -
+ports and vtags match but global address does not)
+.It Cm 1
+.Nm nat
+will accept and process all OOTB global AddIP messages.
+.El
+.Pp
+Option 1 should never be selected as this forms a security risk. An attacker can
+establish multiple fake associations by sending AddIP messages.
+.It Va net.inet.ip.alias.sctp.chunk_proc_limit: No 5
+Defines the maximum number of chunks in an SCTP packet that will be parsed for a
+packet that matches an existing association. This value is enforced to be greater or equal
+than
+.Cm net.inet.ip.alias.sctp.initialising_chunk_proc_limit .
+A high value is
+a DoS risk yet setting too low a value may result in important control chunks in
+the packet not being located and parsed.
+.It Va net.inet.ip.alias.sctp.error_on_ootb: No 1
+Defines when the
+.Nm nat
+responds to any Out-of-the-Blue (OOTB) packets with ErrorM
+packets. An OOTB packet is a packet that arrives with no existing association
+registered in the
+.Nm nat
+and is not an INIT or ASCONF-AddIP packet:
+.Bl -tag -width indent
+.It Cm 0
+ErrorM is never sent in response to OOTB packets.
+.It Cm 1
+ErrorM is only sent to OOTB packets received on the local side.
+.It Cm 2
+ErrorM is sent to the local side and on the global side ONLY if there is a
+partial match (ports and vtags match but the source global IP does not). This
+value is only useful if the
+.Nm nat
+is tracking global IP addresses.
+.It Cm 3
+ErrorM is sent in response to all OOTB packets on both the local and global side
+(DoS risk).
+.El
+.Pp
+At the moment the default is 0, since the ErrorM packet is not yet
+supported by most SCTP stacks. When it is supported, and if not tracking
+global addresses, we recommend setting this value to 1 to allow
+multi-homed local hosts to function with the
+.Nm nat .
+To track global addresses, we recommend setting this value to 2 to
+allow global hosts to be informed when they need to (re)send an
+ASCONF-AddIP. Value 3 should never be chosen (except for debugging) as
+the
+.Nm nat
+will respond to all OOTB global packets (a DoS risk).
+.It Va net.inet.ip.alias.sctp.hashtable_size: No 2003
+Size of hash tables used for
+.Nm nat
+lookups (100 < prime_number > 1000001)
+This value sets the
+.Nm hash table
+size for any future created
+.Nm nat
+instance and therefore must be set prior to creating a
+.Nm nat
+instance.
+The table sizes my be changed to suit specific needs. If there will be few
+concurrent associations, and memory is scarce, you may make these smaller. If
+there will be many thousands (or millions) of concurrent associations, you
+should make these larger. A prime number is best for the table size. The sysctl
+update function will adjust your input value to the next highest prime number.
+.It Va net.inet.ip.alias.sctp.holddown_time: No 0
+Hold association in table for this many seconds after receiving a
+SHUTDOWN-COMPLETE. This allows endpoints to correct shutdown gracefully if a
+shutdown_complete is lost and retransmissions are required.
+.It Va net.inet.ip.alias.sctp.init_timer: No 15
+Timeout value while waiting for (INIT-ACK|AddIP-ACK).
+This value cannot be 0.
+.It Va net.inet.ip.alias.sctp.initialising_chunk_proc_limit: No 2
+Defines the maximum number of chunks in an SCTP packet that will be parsed when
+no existing association exists that matches that packet. Ideally this packet
+will only be an INIT or ASCONF-AddIP packet. A higher value may become a DoS
+risk as malformed packets can consume processing resources.
+.It Va net.inet.ip.alias.sctp.param_proc_limit: No 25
+Defines the maximum number of parameters within a chunk that will be parsed in a
+packet. As for other similar sysctl variables, larger values pose a DoS risk.
+.It Va net.inet.ip.alias.sctp.log_level: No 0
+Level of detail in the system log messages (0 \- minimal, 1 \- event,
+2 \- info, 3 \- detail, 4 \- debug, 5 \- max debug). May be a good
+option in high loss environments.
+.It Va net.inet.ip.alias.sctp.shutdown_time: No 15
+Timeout value while waiting for SHUTDOWN-COMPLETE.
+This value cannot be 0.
+.It Va net.inet.ip.alias.sctp.track_global_addresses: No 0
+Enables/disables global IP address tracking within the
+.Nm nat
+and places an
+upper limit on the number of addresses tracked for each association:
+.Bl -tag -width indent
+.It Cm 0
+Global tracking is disabled
+.It Cm >1
+Enables tracking, the maximum number of addresses tracked for each
+association is limited to this value
+.El
+.Pp
+This variable is fully dynamic, the new value will be adopted for all newly
+arriving associations, existing association are treated as they were previously.
+Global tracking will decrease the number of collisions within the
+.Nm nat
+at a cost
+of increased processing load, memory usage, complexity, and possible
+.Nm nat
+state
+problems in complex networks with multiple
+.Nm nats .
+We recommend not tracking
+global IP addresses, this will still result in a fully functional
+.Nm nat .
+.It Va net.inet.ip.alias.sctp.up_timer: No 300
+Timeout value to keep an association up with no traffic.
+This value cannot be 0.
.It Va net.inet.ip.dummynet.expire : No 1
Lazily delete dynamic pipes/queue once they have no pending traffic.
You can disable this by setting the variable to 0, in which case
@@ -2718,6 +2874,15 @@ as part of a Summer of Code 2005 project.
Work on
.Nm dummynet
traffic shaper supported by Akamba Corp.
+.Pp
+Sctp
+.Nm nat
+support has been developed by
+.An The Centre for Advanced Internet Architectures (CAIA) Aq http://www.caia.swin.edu.au .
+The primary developers and maintainers are David Hayes and Jason But.
+For further information visit:
+.Aq http://www.caia.swin.edu.au/urp/SONATA
+.
.Sh BUGS
The syntax has grown over the years and sometimes it might be confusing.
Unfortunately, backward compatibility prevents cleaning up mistakes
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 6694eaf..c0dfac3 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -20,76 +20,41 @@
* $FreeBSD$
*/
-#include <sys/param.h>
-#include <sys/mbuf.h>
+#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <sys/queue.h>
+
+#include "ipfw2.h"
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <grp.h>
-#include <limits.h>
#include <netdb.h>
#include <pwd.h>
-#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
#include <string.h>
-#include <timeconv.h> /* XXX do we need this ? */
-#include <unistd.h>
#include <sysexits.h>
+#include <time.h> /* ctime */
+#include <timeconv.h> /* _long_to_time */
#include <unistd.h>
#include <fcntl.h>
-#define IPFW_INTERNAL /* Access to protected structures in ip_fw.h. */
-#define _ALIAS_SCTP /*Using alias_sctp*/
-
#include <net/ethernet.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/pfvar.h>
-#include <net/route.h> /* def. of struct route */
+#include <net/if.h> /* only IFNAMSIZ */
#include <netinet/in.h>
-#include <netinet/in_systm.h>
+#include <netinet/in_systm.h> /* only n_short, n_long */
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
-#include <netinet/icmp6.h>
#include <netinet/ip_fw.h>
-#include <netinet/ip_dummynet.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
-#include <alias.h>
-int
- do_value_as_ip, /* show table value as IP */
- do_resolv, /* Would try to resolve all */
- do_time, /* Show time stamps */
- do_quiet, /* Be quiet in add and flush */
- do_pipe, /* this cmd refers to a pipe */
- do_nat, /* Nat configuration. */
- do_sort, /* field to sort results (0 = no) */
- do_dynamic, /* display dynamic rules */
- do_expired, /* display expired dynamic rules */
- do_compact, /* show rules in compact mode */
- do_force, /* do not ask for confirmation */
- use_set, /* work with specified set number */
- show_sets, /* display rule sets */
- test_only, /* only check syntax */
- comment_only, /* only print action and comment */
- verbose;
-
-#define IP_MASK_ALL 0xffffffff
-/*
- * the following macro returns an error message if we run out of
- * arguments.
- */
-#define NEED1(msg) {if (!ac) errx(EX_USAGE, msg);}
+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) \
@@ -120,27 +85,16 @@ int
} \
} while (0)
-#define PRINT_UINT_ARG(str, arg) do { \
- if (str != NULL) \
- printf("%s",str); \
- if (arg == IP_FW_TABLEARG) \
- printf("tablearg"); \
- else \
- printf("%u", (uint32_t)arg); \
-} while (0)
-
-/*
- * _s_x is a structure that stores a string <-> token pairs, used in
- * various places in the parser. Entries are stored in arrays,
- * with an entry with s=NULL as terminator.
- * The search routines are match_token() and match_value().
- * Often, an element with x=0 contains an error string.
- *
- */
-struct _s_x {
- char const *s;
- int x;
-};
+static void
+PRINT_UINT_ARG(const char *str, uint32_t arg)
+{
+ if (str != NULL)
+ printf("%s",str);
+ if (arg == IP_FW_TABLEARG)
+ printf("tablearg");
+ else
+ printf("%u", arg);
+}
static struct _s_x f_tcpflags[] = {
{ "syn", TH_SYN },
@@ -231,168 +185,8 @@ static struct _s_x ether_types[] = {
{ NULL, 0 }
};
-static void show_usage(void);
-
-enum tokens {
- TOK_NULL=0,
-
- TOK_OR,
- TOK_NOT,
- TOK_STARTBRACE,
- TOK_ENDBRACE,
-
- TOK_ACCEPT,
- TOK_COUNT,
- TOK_PIPE,
- TOK_QUEUE,
- TOK_DIVERT,
- TOK_TEE,
- TOK_NETGRAPH,
- TOK_NGTEE,
- TOK_FORWARD,
- TOK_SKIPTO,
- TOK_DENY,
- TOK_REJECT,
- TOK_RESET,
- TOK_UNREACH,
- TOK_CHECKSTATE,
- TOK_NAT,
-
- TOK_ALTQ,
- TOK_LOG,
- TOK_TAG,
- TOK_UNTAG,
-
- TOK_TAGGED,
- TOK_UID,
- TOK_GID,
- TOK_JAIL,
- TOK_IN,
- TOK_LIMIT,
- TOK_KEEPSTATE,
- TOK_LAYER2,
- TOK_OUT,
- TOK_DIVERTED,
- TOK_DIVERTEDLOOPBACK,
- TOK_DIVERTEDOUTPUT,
- TOK_XMIT,
- TOK_RECV,
- TOK_VIA,
- TOK_FRAG,
- TOK_IPOPTS,
- TOK_IPLEN,
- TOK_IPID,
- TOK_IPPRECEDENCE,
- TOK_IPTOS,
- TOK_IPTTL,
- TOK_IPVER,
- TOK_ESTAB,
- TOK_SETUP,
- TOK_TCPDATALEN,
- TOK_TCPFLAGS,
- TOK_TCPOPTS,
- TOK_TCPSEQ,
- TOK_TCPACK,
- TOK_TCPWIN,
- TOK_ICMPTYPES,
- TOK_MAC,
- TOK_MACTYPE,
- TOK_VERREVPATH,
- TOK_VERSRCREACH,
- TOK_ANTISPOOF,
- TOK_IPSEC,
- TOK_COMMENT,
-
- TOK_PLR,
- TOK_NOERROR,
- TOK_BUCKETS,
- TOK_DSTIP,
- TOK_SRCIP,
- TOK_DSTPORT,
- TOK_SRCPORT,
- TOK_ALL,
- TOK_MASK,
- TOK_BW,
- TOK_DELAY,
- TOK_RED,
- TOK_GRED,
- TOK_DROPTAIL,
- TOK_PROTO,
- TOK_WEIGHT,
- TOK_IP,
- TOK_IF,
- TOK_ALOG,
- TOK_DENY_INC,
- TOK_SAME_PORTS,
- TOK_UNREG_ONLY,
- TOK_RESET_ADDR,
- TOK_ALIAS_REV,
- TOK_PROXY_ONLY,
- TOK_REDIR_ADDR,
- TOK_REDIR_PORT,
- TOK_REDIR_PROTO,
-
- TOK_IPV6,
- TOK_FLOWID,
- TOK_ICMP6TYPES,
- TOK_EXT6HDR,
- TOK_DSTIP6,
- TOK_SRCIP6,
-
- TOK_IPV4,
- TOK_UNREACH6,
- TOK_RESET6,
-
- TOK_FIB,
- TOK_SETFIB,
-};
-struct _s_x dummynet_params[] = {
- { "plr", TOK_PLR },
- { "noerror", TOK_NOERROR },
- { "buckets", TOK_BUCKETS },
- { "dst-ip", TOK_DSTIP },
- { "src-ip", TOK_SRCIP },
- { "dst-port", TOK_DSTPORT },
- { "src-port", TOK_SRCPORT },
- { "proto", TOK_PROTO },
- { "weight", TOK_WEIGHT },
- { "all", TOK_ALL },
- { "mask", TOK_MASK },
- { "droptail", TOK_DROPTAIL },
- { "red", TOK_RED },
- { "gred", TOK_GRED },
- { "bw", TOK_BW },
- { "bandwidth", TOK_BW },
- { "delay", TOK_DELAY },
- { "pipe", TOK_PIPE },
- { "queue", TOK_QUEUE },
- { "flow-id", TOK_FLOWID},
- { "dst-ipv6", TOK_DSTIP6},
- { "dst-ip6", TOK_DSTIP6},
- { "src-ipv6", TOK_SRCIP6},
- { "src-ip6", TOK_SRCIP6},
- { "dummynet-params", TOK_NULL },
- { NULL, 0 } /* terminator */
-};
-
-struct _s_x nat_params[] = {
- { "ip", TOK_IP },
- { "if", TOK_IF },
- { "log", TOK_ALOG },
- { "deny_in", TOK_DENY_INC },
- { "same_ports", TOK_SAME_PORTS },
- { "unreg_only", TOK_UNREG_ONLY },
- { "reset", TOK_RESET_ADDR },
- { "reverse", TOK_ALIAS_REV },
- { "proxy_only", TOK_PROXY_ONLY },
- { "redirect_addr", TOK_REDIR_ADDR },
- { "redirect_port", TOK_REDIR_PORT },
- { "redirect_proto", TOK_REDIR_PROTO },
- { NULL, 0 } /* terminator */
-};
-
-struct _s_x rule_actions[] = {
+static struct _s_x rule_actions[] = {
{ "accept", TOK_ACCEPT },
{ "pass", TOK_ACCEPT },
{ "allow", TOK_ACCEPT },
@@ -421,7 +215,7 @@ struct _s_x rule_actions[] = {
{ NULL, 0 } /* terminator */
};
-struct _s_x rule_action_params[] = {
+static struct _s_x rule_action_params[] = {
{ "altq", TOK_ALTQ },
{ "log", TOK_LOG },
{ "tag", TOK_TAG },
@@ -429,7 +223,7 @@ struct _s_x rule_action_params[] = {
{ NULL, 0 } /* terminator */
};
-struct _s_x rule_options[] = {
+static struct _s_x rule_options[] = {
{ "tagged", TOK_TAGGED },
{ "uid", TOK_UID },
{ "gid", TOK_GID },
@@ -508,26 +302,54 @@ struct _s_x rule_options[] = {
{ NULL, 0 } /* terminator */
};
-#define TABLEARG "tablearg"
-
-static __inline uint64_t
-align_uint64(uint64_t *pll) {
+/*
+ * 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.
+ */
+unsigned long long
+align_uint64(const uint64_t *pll)
+{
uint64_t ret;
bcopy (pll, &ret, sizeof(ret));
return ret;
}
+void *
+safe_calloc(size_t number, size_t size)
+{
+ void *ret = calloc(number, size);
+
+ if (ret == NULL)
+ err(EX_OSERR, "calloc");
+ return ret;
+}
+
+void *
+safe_realloc(void *ptr, size_t size)
+{
+ void *ret = realloc(ptr, size);
+
+ if (ret == NULL)
+ err(EX_OSERR, "realloc");
+ return ret;
+}
+
/*
* conditionally runs the command.
*/
-static int
+int
do_cmd(int optname, void *optval, uintptr_t optlen)
{
static int s = -1; /* the socket */
int i;
- if (test_only)
+ if (co.test_only)
return 0;
if (s == -1)
@@ -551,7 +373,7 @@ do_cmd(int optname, void *optval, uintptr_t optlen)
* match_token takes a table and a string, returns the value associated
* with the string (-1 in case of failure).
*/
-static int
+int
match_token(struct _s_x *table, char *string)
{
struct _s_x *pt;
@@ -567,7 +389,7 @@ match_token(struct _s_x *table, char *string)
* match_value takes a table and a value, returns the string associated
* with the value (NULL in case of failure).
*/
-static char const *
+char const *
match_value(struct _s_x *p, int value)
{
for (; p->s != NULL; p++)
@@ -585,7 +407,7 @@ match_value(struct _s_x *p, int value)
* This function will be removed in the future through the usual
* deprecation process.
*/
-static int
+int
_substrcmp(const char *str1, const char* str2)
{
@@ -613,7 +435,7 @@ _substrcmp(const char *str1, const char* str2)
* This function will be removed in the future through the usual
* deprecation process.
*/
-static int
+int
_substrcmp2(const char *str1, const char* str2, const char* str3)
{
@@ -636,13 +458,13 @@ print_port(int proto, uint16_t port)
if (proto == IPPROTO_ETHERTYPE) {
char const *s;
- if (do_resolv && (s = match_value(ether_types, port)) )
+ if (co.do_resolv && (s = match_value(ether_types, port)) )
printf("%s", s);
else
printf("0x%04x", port);
} else {
struct servent *se = NULL;
- if (do_resolv) {
+ if (co.do_resolv) {
struct protoent *pe = getprotobynumber(proto);
se = getservbyport(htons(port), pe ? pe->p_name : NULL);
@@ -654,7 +476,7 @@ print_port(int proto, uint16_t port)
}
}
-struct _s_x _port_name[] = {
+static struct _s_x _port_name[] = {
{"dst-port", O_IP_DSTPORT},
{"src-port", O_IP_SRCPORT},
{"ipid", O_IPID},
@@ -725,9 +547,7 @@ strtoport(char *s, char **end, int base, int proto)
if (*s1 == '\\' && s1[1] != '\0')
s1++;
- buf = malloc(s1 - s + 1);
- if (buf == NULL)
- return 0;
+ buf = safe_calloc(s1 - s + 1, 1);
/*
* copy into a buffer skipping backslashes
@@ -762,107 +582,6 @@ strtoport(char *s, char **end, int base, int proto)
}
/*
- * Map between current altq queue id numbers and names.
- */
-static int altq_fetched = 0;
-static TAILQ_HEAD(, pf_altq) altq_entries =
- TAILQ_HEAD_INITIALIZER(altq_entries);
-
-static void
-altq_set_enabled(int enabled)
-{
- int pffd;
-
- pffd = open("/dev/pf", O_RDWR);
- if (pffd == -1)
- err(EX_UNAVAILABLE,
- "altq support opening pf(4) control device");
- if (enabled) {
- if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST)
- err(EX_UNAVAILABLE, "enabling altq");
- } else {
- if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT)
- err(EX_UNAVAILABLE, "disabling altq");
- }
- close(pffd);
-}
-
-static void
-altq_fetch()
-{
- struct pfioc_altq pfioc;
- struct pf_altq *altq;
- int pffd, mnr;
-
- if (altq_fetched)
- return;
- altq_fetched = 1;
- pffd = open("/dev/pf", O_RDONLY);
- if (pffd == -1) {
- warn("altq support opening pf(4) control device");
- return;
- }
- bzero(&pfioc, sizeof(pfioc));
- if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
- warn("altq support getting queue list");
- close(pffd);
- return;
- }
- mnr = pfioc.nr;
- for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
- if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
- if (errno == EBUSY)
- break;
- warn("altq support getting queue list");
- close(pffd);
- return;
- }
- if (pfioc.altq.qid == 0)
- continue;
- altq = malloc(sizeof(*altq));
- if (altq == NULL)
- err(EX_OSERR, "malloc");
- *altq = pfioc.altq;
- TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
- }
- close(pffd);
-}
-
-static u_int32_t
-altq_name_to_qid(const char *name)
-{
- struct pf_altq *altq;
-
- altq_fetch();
- TAILQ_FOREACH(altq, &altq_entries, entries)
- if (strcmp(name, altq->qname) == 0)
- break;
- if (altq == NULL)
- errx(EX_DATAERR, "altq has no queue named `%s'", name);
- return altq->qid;
-}
-
-static const char *
-altq_qid_to_name(u_int32_t qid)
-{
- struct pf_altq *altq;
-
- altq_fetch();
- TAILQ_FOREACH(altq, &altq_entries, entries)
- if (qid == altq->qid)
- break;
- if (altq == NULL)
- return NULL;
- return altq->qname;
-}
-
-static void
-fill_altq_qid(u_int32_t *qid, const char *av)
-{
- *qid = altq_name_to_qid(av);
-}
-
-/*
* Fill the body of the command with the list of port ranges.
*/
static int
@@ -955,40 +674,6 @@ print_reject_code(uint16_t code)
printf("unreach %u", code);
}
-static struct _s_x icmp6codes[] = {
- { "no-route", ICMP6_DST_UNREACH_NOROUTE },
- { "admin-prohib", ICMP6_DST_UNREACH_ADMIN },
- { "address", ICMP6_DST_UNREACH_ADDR },
- { "port", ICMP6_DST_UNREACH_NOPORT },
- { NULL, 0 }
-};
-
-static void
-fill_unreach6_code(u_short *codep, char *str)
-{
- int val;
- char *s;
-
- val = strtoul(str, &s, 0);
- if (s == str || *s != '\0' || val >= 0x100)
- val = match_token(icmp6codes, str);
- if (val < 0)
- errx(EX_DATAERR, "unknown ICMPv6 unreachable code ``%s''", str);
- *codep = val;
- return;
-}
-
-static void
-print_unreach6_code(uint16_t code)
-{
- char const *s = match_value(icmp6codes, code);
-
- if (s != NULL)
- printf("unreach6 %s", s);
- else
- printf("unreach6 %u", code);
-}
-
/*
* Returns the number of bits set (from left) in a contiguous bitmask,
* or -1 if the mask is not contiguous.
@@ -1000,7 +685,7 @@ print_unreach6_code(uint16_t code)
* the first bit on the wire is bit 0 of the first byte.
* len is the max length in bits.
*/
-static int
+int
contigmask(uint8_t *p, int len)
{
int i, n;
@@ -1112,7 +797,7 @@ print_ip(ipfw_insn_ip *cmd, char const *s)
int mb = /* mask length */
(cmd->o.opcode == O_IP_SRC || cmd->o.opcode == O_IP_DST) ?
32 : contigmask((uint8_t *)&(a[1]), 32);
- if (mb == 32 && do_resolv)
+ if (mb == 32 && co.do_resolv)
he = gethostbyaddr((char *)&(a[0]), sizeof(u_long), AF_INET);
if (he != NULL) /* resolved to name */
printf("%s", he->h_name);
@@ -1191,226 +876,6 @@ print_icmptypes(ipfw_insn_u32 *cmd)
}
}
-/*
- * Print the ip address contained in a command.
- */
-static void
-print_ip6(ipfw_insn_ip6 *cmd, char const *s)
-{
- struct hostent *he = NULL;
- int len = F_LEN((ipfw_insn *) cmd) - 1;
- struct in6_addr *a = &(cmd->addr6);
- char trad[255];
-
- printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
-
- if (cmd->o.opcode == O_IP6_SRC_ME || cmd->o.opcode == O_IP6_DST_ME) {
- printf("me6");
- return;
- }
- if (cmd->o.opcode == O_IP6) {
- printf(" ip6");
- return;
- }
-
- /*
- * len == 4 indicates a single IP, whereas lists of 1 or more
- * addr/mask pairs have len = (2n+1). We convert len to n so we
- * use that to count the number of entries.
- */
-
- for (len = len / 4; len > 0; len -= 2, a += 2) {
- int mb = /* mask length */
- (cmd->o.opcode == O_IP6_SRC || cmd->o.opcode == O_IP6_DST) ?
- 128 : contigmask((uint8_t *)&(a[1]), 128);
-
- if (mb == 128 && do_resolv)
- he = gethostbyaddr((char *)a, sizeof(*a), AF_INET6);
- if (he != NULL) /* resolved to name */
- printf("%s", he->h_name);
- else if (mb == 0) /* any */
- printf("any");
- else { /* numeric IP followed by some kind of mask */
- if (inet_ntop(AF_INET6, a, trad, sizeof( trad ) ) == NULL)
- printf("Error ntop in print_ip6\n");
- printf("%s", trad );
- if (mb < 0) /* XXX not really legal... */
- printf(":%s",
- inet_ntop(AF_INET6, &a[1], trad, sizeof(trad)));
- else if (mb < 128)
- printf("/%d", mb);
- }
- if (len > 2)
- printf(",");
- }
-}
-
-static void
-fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av)
-{
- uint8_t type;
-
- bzero(cmd, sizeof(*cmd));
- while (*av) {
- if (*av == ',')
- av++;
- type = strtoul(av, &av, 0);
- if (*av != ',' && *av != '\0')
- errx(EX_DATAERR, "invalid ICMP6 type");
- /*
- * XXX: shouldn't this be 0xFF? I can't see any reason why
- * we shouldn't be able to filter all possiable values
- * regardless of the ability of the rest of the kernel to do
- * anything useful with them.
- */
- if (type > ICMP6_MAXTYPE)
- errx(EX_DATAERR, "ICMP6 type out of range");
- cmd->d[type / 32] |= ( 1 << (type % 32));
- }
- cmd->o.opcode = O_ICMP6TYPE;
- cmd->o.len |= F_INSN_SIZE(ipfw_insn_icmp6);
-}
-
-
-static void
-print_icmp6types(ipfw_insn_u32 *cmd)
-{
- int i, j;
- char sep= ' ';
-
- printf(" ip6 icmp6types");
- for (i = 0; i < 7; i++)
- for (j=0; j < 32; ++j) {
- if ( (cmd->d[i] & (1 << (j))) == 0)
- continue;
- printf("%c%d", sep, (i*32 + j));
- sep = ',';
- }
-}
-
-static void
-print_flow6id( ipfw_insn_u32 *cmd)
-{
- uint16_t i, limit = cmd->o.arg1;
- char sep = ',';
-
- printf(" flow-id ");
- for( i=0; i < limit; ++i) {
- if (i == limit - 1)
- sep = ' ';
- printf("%d%c", cmd->d[i], sep);
- }
-}
-
-/* structure and define for the extension header in ipv6 */
-static struct _s_x ext6hdrcodes[] = {
- { "frag", EXT_FRAGMENT },
- { "hopopt", EXT_HOPOPTS },
- { "route", EXT_ROUTING },
- { "dstopt", EXT_DSTOPTS },
- { "ah", EXT_AH },
- { "esp", EXT_ESP },
- { "rthdr0", EXT_RTHDR0 },
- { "rthdr2", EXT_RTHDR2 },
- { NULL, 0 }
-};
-
-/* fills command for the extension header filtering */
-int
-fill_ext6hdr( ipfw_insn *cmd, char *av)
-{
- int tok;
- char *s = av;
-
- cmd->arg1 = 0;
-
- while(s) {
- av = strsep( &s, ",") ;
- tok = match_token(ext6hdrcodes, av);
- switch (tok) {
- case EXT_FRAGMENT:
- cmd->arg1 |= EXT_FRAGMENT;
- break;
-
- case EXT_HOPOPTS:
- cmd->arg1 |= EXT_HOPOPTS;
- break;
-
- case EXT_ROUTING:
- cmd->arg1 |= EXT_ROUTING;
- break;
-
- case EXT_DSTOPTS:
- cmd->arg1 |= EXT_DSTOPTS;
- break;
-
- case EXT_AH:
- cmd->arg1 |= EXT_AH;
- break;
-
- case EXT_ESP:
- cmd->arg1 |= EXT_ESP;
- break;
-
- case EXT_RTHDR0:
- cmd->arg1 |= EXT_RTHDR0;
- break;
-
- case EXT_RTHDR2:
- cmd->arg1 |= EXT_RTHDR2;
- break;
-
- default:
- errx( EX_DATAERR, "invalid option for ipv6 exten header" );
- break;
- }
- }
- if (cmd->arg1 == 0 )
- return 0;
- cmd->opcode = O_EXT_HDR;
- cmd->len |= F_INSN_SIZE( ipfw_insn );
- return 1;
-}
-
-void
-print_ext6hdr( ipfw_insn *cmd )
-{
- char sep = ' ';
-
- printf(" extension header:");
- if (cmd->arg1 & EXT_FRAGMENT ) {
- printf("%cfragmentation", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_HOPOPTS ) {
- printf("%chop options", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_ROUTING ) {
- printf("%crouting options", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_RTHDR0 ) {
- printf("%crthdr0", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_RTHDR2 ) {
- printf("%crthdr2", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_DSTOPTS ) {
- printf("%cdestination options", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_AH ) {
- printf("%cauthentication header", sep);
- sep = ',';
- }
- if (cmd->arg1 & EXT_ESP ) {
- printf("%cencapsulated security payload", sep);
- }
-}
-
/*
* show_ipfw() prints the body of an ipfw rule.
* Because the standard rule has at least proto src_ip dst_ip, we use
@@ -1433,22 +898,22 @@ print_ext6hdr( ipfw_insn *cmd )
#define HAVE_IP (HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP)
static void
-show_prerequisites(int *flags, int want, int cmd)
+show_prerequisites(int *flags, int want, int cmd __unused)
{
- if (comment_only)
+ if (co.comment_only)
return;
if ( (*flags & HAVE_IP) == HAVE_IP)
*flags |= HAVE_OPTIONS;
if ( !(*flags & HAVE_OPTIONS)) {
- if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO))
+ if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO)) {
if ( (*flags & HAVE_PROTO4))
printf(" ip4");
else if ( (*flags & HAVE_PROTO6))
printf(" ip6");
else
printf(" ip");
-
+ }
if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP))
printf(" from any");
if ( !(*flags & HAVE_DSTIP) && (want & HAVE_DSTIP))
@@ -1463,7 +928,7 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
static int twidth = 0;
int l;
ipfw_insn *cmd, *tagptr = NULL;
- char *comment = NULL; /* ptr to comment if we have one */
+ const char *comment = NULL; /* ptr to comment if we have one */
int proto = 0; /* default */
int flags = 0; /* prerequisites */
ipfw_insn_log *logptr = NULL; /* set if we find an O_LOG */
@@ -1474,7 +939,7 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
bcopy(&rule->next_rule, &set_disable, sizeof(set_disable));
if (set_disable & (1 << rule->set)) { /* disabled */
- if (!show_sets)
+ if (!co.show_sets)
return;
else
printf("# DISABLED ");
@@ -1485,9 +950,9 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
printf("%*llu %*llu ", pcwidth, align_uint64(&rule->pcnt),
bcwidth, align_uint64(&rule->bcnt));
- if (do_time == 2)
+ if (co.do_time == 2)
printf("%10u ", rule->timestamp);
- else if (do_time == 1) {
+ else if (co.do_time == 1) {
char timestr[30];
time_t t = (time_t)0;
@@ -1507,7 +972,7 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
}
}
- if (show_sets)
+ if (co.show_sets)
printf("set %d ", rule->set);
/*
@@ -1637,13 +1102,7 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
printf(" log");
}
if (altqptr) {
- const char *qname;
-
- qname = altq_qid_to_name(altqptr->qid);
- if (qname == NULL)
- printf(" altq ?<%u>", altqptr->qid);
- else
- printf(" altq %s", qname);
+ print_altq_cmd(altqptr);
}
if (tagptr) {
if (tagptr->len & F_NOT)
@@ -1668,14 +1127,14 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
}
}
if (rule->_pad & 1) { /* empty rules before options */
- if (!do_compact) {
+ if (!co.do_compact) {
show_prerequisites(&flags, HAVE_PROTO, 0);
printf(" from any to any");
}
flags |= HAVE_IP | HAVE_OPTIONS;
}
- if (comment_only)
+ if (co.comment_only)
comment = "...";
for (l = rule->act_ofs, cmd = rule->cmd ;
@@ -1683,7 +1142,7 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
/* useful alias */
ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd;
- if (comment_only) {
+ if (co.comment_only) {
if (cmd->opcode != O_NOP)
continue;
printf(" // %s\n", (char *)(cmd + 1));
@@ -2070,7 +1529,7 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth)
uint16_t rulenum;
char buf[INET6_ADDRSTRLEN];
- if (!do_expired) {
+ if (!co.do_expired) {
if (!d->expire && !(d->dyn_type == O_LIMIT_PARENT))
return;
}
@@ -2114,254 +1573,6 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth)
printf("\n");
}
-static int
-sort_q(const void *pa, const void *pb)
-{
- int rev = (do_sort < 0);
- int field = rev ? -do_sort : do_sort;
- long long res = 0;
- const struct dn_flow_queue *a = pa;
- const struct dn_flow_queue *b = pb;
-
- switch (field) {
- case 1: /* pkts */
- res = a->len - b->len;
- break;
- case 2: /* bytes */
- res = a->len_bytes - b->len_bytes;
- break;
-
- case 3: /* tot pkts */
- res = a->tot_pkts - b->tot_pkts;
- break;
-
- case 4: /* tot bytes */
- res = a->tot_bytes - b->tot_bytes;
- break;
- }
- if (res < 0)
- res = -1;
- if (res > 0)
- res = 1;
- return (int)(rev ? res : -res);
-}
-
-static void
-list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
-{
- int l;
- int index_printed, indexes = 0;
- char buff[255];
- struct protoent *pe;
-
- if (fs->rq_elements == 0)
- return;
-
- if (do_sort != 0)
- heapsort(q, fs->rq_elements, sizeof *q, sort_q);
-
- /* Print IPv4 flows */
- index_printed = 0;
- for (l = 0; l < fs->rq_elements; l++) {
- struct in_addr ina;
-
- /* 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);
- if (pe)
- printf("%-4s ", pe->p_name);
- else
- printf("%4u ", q[l].id.proto);
- ina.s_addr = htonl(q[l].id.src_ip);
- printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.src_port);
- ina.s_addr = htonl(q[l].id.dst_ip);
- printf("%15s/%-5d ",
- inet_ntoa(ina), q[l].id.dst_port);
- printf("%4qu %8qu %2u %4u %3u\n",
- q[l].tot_pkts, q[l].tot_bytes,
- q[l].len, q[l].len_bytes, q[l].drops);
- if (verbose)
- printf(" S %20qd F %20qd\n",
- q[l].S, 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);
- 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(" %39s/%-5d ",
- inet_ntop(AF_INET6, &(q[l].id.dst_ip6), buff, sizeof(buff)),
- q[l].id.dst_port);
- printf(" %4qu %8qu %2u %4u %3u\n",
- q[l].tot_pkts, q[l].tot_bytes,
- q[l].len, q[l].len_bytes, q[l].drops);
- if (verbose)
- printf(" S %20qd F %20qd\n", q[l].S, q[l].F);
- }
-}
-
-static void
-print_flowset_parms(struct dn_flow_set *fs, char *prefix)
-{
- int l;
- char qs[30];
- char plr[30];
- char red[90]; /* Display RED parameters */
-
- l = fs->qsize;
- if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
- if (l >= 8192)
- sprintf(qs, "%d KB", l / 1024);
- else
- sprintf(qs, "%d B", l);
- } else
- sprintf(qs, "%3d sl.", l);
- if (fs->plr)
- sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
- else
- plr[0] = '\0';
- if (fs->flags_fs & 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' : ' ',
- 1.0 * fs->w_q / (double)(1 << SCALE_RED),
- SCALE_VAL(fs->min_th),
- SCALE_VAL(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);
-}
-
-static void
-list_pipes(void *data, uint nbytes, int ac, char *av[])
-{
- 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];
-
- 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) || 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 (verbose)
- printf(" V %20qd\n", p->V >> MY_M);
-
- 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 && do_pipe == 2) ||
- (rulenum != fs->parent_nr && 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);
- }
-}
-
/*
* This one handles all set-related commands
* ipfw set { show | enable | disable }
@@ -2369,8 +1580,8 @@ list_pipes(void *data, uint nbytes, int ac, char *av[])
* ipfw set move X to Y
* ipfw set move rule X to Y
*/
-static void
-sets_handler(int ac, char *av[])
+void
+ipfw_sets_handler(int ac, char *av[])
{
uint32_t set_disable, masks[2];
int i, nbytes;
@@ -2387,8 +1598,7 @@ sets_handler(int ac, char *av[])
char const *msg;
nbytes = sizeof(struct ip_fw);
- if ((data = calloc(1, nbytes)) == NULL)
- err(EX_OSERR, "calloc");
+ 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,
@@ -2470,8 +1680,8 @@ sets_handler(int ac, char *av[])
errx(EX_USAGE, "invalid set command %s\n", *av);
}
-static void
-sysctl_handler(int ac, char *av[], int which)
+void
+ipfw_sysctl_handler(int ac, char *av[], int which)
{
ac--;
av++;
@@ -2500,8 +1710,8 @@ sysctl_handler(int ac, char *av[], int which)
}
}
-static void
-list(int ac, char *av[], int show_counters)
+void
+ipfw_list(int ac, char *av[], int show_counters)
{
struct ip_fw *r;
ipfw_dyn_rule *dynrules, *d;
@@ -2518,12 +1728,12 @@ list(int ac, char *av[], int show_counters)
int seen = 0;
uint8_t set;
- const int ocmd = do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
+ const int ocmd = co.do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
int nalloc = 1024; /* start somewhere... */
last = 0;
- if (test_only) {
+ if (co.test_only) {
fprintf(stderr, "Testing only, list disabled\n");
return;
}
@@ -2537,15 +1747,14 @@ list(int ac, char *av[], int show_counters)
while (nbytes >= nalloc) {
nalloc = nalloc * 2 + 200;
nbytes = nalloc;
- if ((data = realloc(data, nbytes)) == NULL)
- err(EX_OSERR, "realloc");
+ data = safe_realloc(data, nbytes);
if (do_cmd(ocmd, data, (uintptr_t)&nbytes) < 0)
err(EX_OSERR, "getsockopt(IP_%s_GET)",
- do_pipe ? "DUMMYNET" : "FW");
+ co.do_pipe ? "DUMMYNET" : "FW");
}
- if (do_pipe) {
- list_pipes(data, nbytes, ac, av);
+ if (co.do_pipe) {
+ ipfw_list_pipes(data, nbytes, ac, av);
goto done;
}
@@ -2572,7 +1781,7 @@ list(int ac, char *av[], int show_counters)
if (show_counters) {
for (n = 0, r = data; n < nstat; n++, r = NEXT(r)) {
/* skip rules from another set */
- if (use_set && r->set != use_set - 1)
+ if (co.use_set && r->set != co.use_set - 1)
continue;
/* packet counter */
@@ -2588,13 +1797,13 @@ list(int ac, char *av[], int show_counters)
bcwidth = width;
}
}
- if (do_dynamic && ndyn) {
+ if (co.do_dynamic && ndyn) {
for (n = 0, d = dynrules; n < ndyn; n++, d++) {
- if (use_set) {
+ if (co.use_set) {
/* skip rules from another set */
bcopy((char *)&d->rule + sizeof(uint16_t),
&set, sizeof(uint8_t));
- if (set != use_set - 1)
+ if (set != co.use_set - 1)
continue;
}
width = snprintf(NULL, 0, "%llu",
@@ -2611,18 +1820,18 @@ list(int ac, char *av[], int show_counters)
/* if no rule numbers were specified, list all rules */
if (ac == 0) {
for (n = 0, r = data; n < nstat; n++, r = NEXT(r)) {
- if (use_set && r->set != use_set - 1)
+ if (co.use_set && r->set != co.use_set - 1)
continue;
show_ipfw(r, pcwidth, bcwidth);
}
- if (do_dynamic && ndyn) {
+ if (co.do_dynamic && ndyn) {
printf("## Dynamic rules (%d):\n", ndyn);
for (n = 0, d = dynrules; n < ndyn; n++, d++) {
- if (use_set) {
+ if (co.use_set) {
bcopy((char *)&d->rule + sizeof(uint16_t),
&set, sizeof(uint8_t));
- if (set != use_set - 1)
+ if (set != co.use_set - 1)
continue;
}
show_dyn_ipfw(d, pcwidth, bcwidth);
@@ -2646,7 +1855,7 @@ list(int ac, char *av[], int show_counters)
for (n = seen = 0, r = data; n < nstat; n++, r = NEXT(r) ) {
if (r->rulenum > last)
break;
- if (use_set && r->set != use_set - 1)
+ if (co.use_set && r->set != co.use_set - 1)
continue;
if (r->rulenum >= rnum && r->rulenum <= last) {
show_ipfw(r, pcwidth, bcwidth);
@@ -2661,7 +1870,7 @@ list(int ac, char *av[], int show_counters)
}
}
- if (do_dynamic && ndyn) {
+ if (co.do_dynamic && ndyn) {
printf("## Dynamic rules:\n");
for (lac = ac, lav = av; lac != 0; lac--) {
last = rnum = strtoul(*lav++, &endptr, 10);
@@ -2676,10 +1885,10 @@ list(int ac, char *av[], int show_counters)
bcopy(&d->rule, &rulenum, sizeof(rulenum));
if (rulenum > rnum)
break;
- if (use_set) {
+ if (co.use_set) {
bcopy((char *)&d->rule + sizeof(uint16_t),
&set, sizeof(uint8_t));
- if (set != use_set - 1)
+ if (set != co.use_set - 1)
continue;
}
if (r->rulenum >= rnum && r->rulenum <= last)
@@ -2698,60 +1907,6 @@ done:
#undef NEXT
}
-static void
-show_usage(void)
-{
- fprintf(stderr, "usage: ipfw [options]\n"
-"do \"ipfw -h\" or see ipfw manpage for details\n"
-);
- exit(EX_USAGE);
-}
-
-static void
-help(void)
-{
- fprintf(stderr,
-"ipfw syntax summary (but please do read the ipfw(8) manpage):\n"
-"ipfw [-abcdefhnNqStTv] <command> where <command> is one of:\n"
-"add [num] [set N] [prob x] RULE-BODY\n"
-"{pipe|queue} N config PIPE-BODY\n"
-"[pipe|queue] {zero|delete|show} [N{,N}]\n"
-"nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|reset|\n"
-" reverse|proxy_only|redirect_addr linkspec|\n"
-" redirect_port linkspec|redirect_proto linkspec}\n"
-"set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n"
-"set N {show|list|zero|resetlog|delete} [N{,N}] | flush\n"
-"table N {add ip[/bits] [value] | delete ip[/bits] | flush | list}\n"
-"table all {flush | list}\n"
-"\n"
-"RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n"
-"ACTION: check-state | allow | count | deny | unreach{,6} CODE |\n"
-" skipto N | {divert|tee} PORT | forward ADDR |\n"
-" pipe N | queue N | nat N | setfib FIB\n"
-"PARAMS: [log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n"
-"ADDR: [ MAC dst src ether_type ] \n"
-" [ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
-" [ ipv6|ip6 from IP6ADDR [ PORT ] to IP6ADDR [ PORTLIST ] ]\n"
-"IPADDR: [not] { any | me | ip/bits{x,y,z} | table(t[,v]) | IPLIST }\n"
-"IP6ADDR: [not] { any | me | me6 | ip6/bits | IP6LIST }\n"
-"IP6LIST: { ip6 | ip6/bits }[,IP6LIST]\n"
-"IPLIST: { ip | ip/bits | ip:mask }[,IPLIST]\n"
-"OPTION_LIST: OPTION [OPTION_LIST]\n"
-"OPTION: bridged | diverted | diverted-loopback | diverted-output |\n"
-" {dst-ip|src-ip} IPADDR | {dst-ip6|src-ip6|dst-ipv6|src-ipv6} IP6ADDR |\n"
-" {dst-port|src-port} LIST |\n"
-" estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n"
-" iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n"
-" ipttl LIST | ipversion VER | keep-state | layer2 | limit ... |\n"
-" icmp6types LIST | ext6hdr LIST | flow-id N[,N] | fib FIB |\n"
-" mac ... | mac-type LIST | proto LIST | {recv|xmit|via} {IF|IPADDR} |\n"
-" setup | {tcpack|tcpseq|tcpwin} NN | tcpflags SPEC | tcpoptions SPEC |\n"
-" tcpdatalen LIST | verrevpath | versrcreach | antispoof\n"
-);
-exit(0);
-}
-
-
static int
lookup_host (char *host, struct in_addr *ipaddr)
{
@@ -2815,7 +1970,7 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
*/
char *t = NULL, *p = strpbrk(av, "/:,{");
int masklen;
- char md, nd;
+ char md, nd = '\0';
if (p) {
md = *p;
@@ -2950,7 +2105,7 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
return;
}
/* A single IP can be stored in an optimized format */
- if (d[1] == IP_MASK_ALL && av == NULL && len == 0) {
+ if (d[1] == ~0 && av == NULL && len == 0) {
cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32);
return;
}
@@ -2963,23 +2118,8 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
}
-/* Try to find ipv6 address by hostname */
-static int
-lookup_host6 (char *host, struct in6_addr *ip6addr)
-{
- struct hostent *he;
-
- if (!inet_pton(AF_INET6, host, ip6addr)) {
- if ((he = gethostbyname2(host, AF_INET6)) == NULL)
- return(-1);
- memcpy(ip6addr, he->h_addr_list[0], sizeof( struct in6_addr));
- }
- return(0);
-}
-
-
/* n2mask sets n bits of the mask */
-static void
+void
n2mask(struct in6_addr *mask, int n)
{
static int minimask[9] =
@@ -2999,198 +2139,6 @@ n2mask(struct in6_addr *mask, int n)
/*
- * fill the addr and mask fields in the instruction as appropriate from av.
- * Update length as appropriate.
- * The following formats are allowed:
- * any matches any IP6. Actually returns an empty instruction.
- * me returns O_IP6_*_ME
- *
- * 03f1::234:123:0342 single IP6 addres
- * 03f1::234:123:0342/24 address/mask
- * 03f1::234:123:0342/24,03f1::234:123:0343/ List of address
- *
- * Set of address (as in ipv6) not supported because ipv6 address
- * are typically random past the initial prefix.
- * Return 1 on success, 0 on failure.
- */
-static int
-fill_ip6(ipfw_insn_ip6 *cmd, char *av)
-{
- int len = 0;
- struct in6_addr *d = &(cmd->addr6);
- /*
- * Needed for multiple address.
- * Note d[1] points to struct in6_add r mask6 of cmd
- */
-
- cmd->o.len &= ~F_LEN_MASK; /* zero len */
-
- if (strcmp(av, "any") == 0)
- return (1);
-
-
- if (strcmp(av, "me") == 0) { /* Set the data for "me" opt*/
- cmd->o.len |= F_INSN_SIZE(ipfw_insn);
- return (1);
- }
-
- if (strcmp(av, "me6") == 0) { /* Set the data for "me" opt*/
- cmd->o.len |= F_INSN_SIZE(ipfw_insn);
- return (1);
- }
-
- av = strdup(av);
- while (av) {
- /*
- * After the address we can have '/' indicating a mask,
- * or ',' indicating another address follows.
- */
-
- char *p;
- int masklen;
- char md = '\0';
-
- if ((p = strpbrk(av, "/,")) ) {
- md = *p; /* save the separator */
- *p = '\0'; /* terminate address string */
- p++; /* and skip past it */
- }
- /* now p points to NULL, mask or next entry */
-
- /* lookup stores address in *d as a side effect */
- if (lookup_host6(av, d) != 0) {
- /* XXX: failed. Free memory and go */
- errx(EX_DATAERR, "bad address \"%s\"", av);
- }
- /* next, look at the mask, if any */
- masklen = (md == '/') ? atoi(p) : 128;
- if (masklen > 128 || masklen < 0)
- errx(EX_DATAERR, "bad width \"%s\''", p);
- else
- n2mask(&d[1], masklen);
-
- APPLY_MASK(d, &d[1]) /* mask base address with mask */
-
- /* find next separator */
-
- if (md == '/') { /* find separator past the mask */
- p = strpbrk(p, ",");
- if (p != NULL)
- p++;
- }
- av = p;
-
- /* Check this entry */
- if (masklen == 0) {
- /*
- * 'any' turns the entire list into a NOP.
- * 'not any' never matches, so it is removed from the
- * list unless it is the only item, in which case we
- * report an error.
- */
- if (cmd->o.len & F_NOT && av == NULL && len == 0)
- errx(EX_DATAERR, "not any never matches");
- continue;
- }
-
- /*
- * A single IP can be stored alone
- */
- if (masklen == 128 && av == NULL && len == 0) {
- len = F_INSN_SIZE(struct in6_addr);
- break;
- }
-
- /* Update length and pointer to arguments */
- len += F_INSN_SIZE(struct in6_addr)*2;
- d += 2;
- } /* end while */
-
- /*
- * Total length of the command, remember that 1 is the size of
- * the base command.
- */
- if (len + 1 > F_LEN_MASK)
- errx(EX_DATAERR, "address list too long");
- cmd->o.len |= len+1;
- free(av);
- return (1);
-}
-
-/*
- * fills command for ipv6 flow-id filtering
- * note that the 20 bit flow number is stored in a array of u_int32_t
- * it's supported lists of flow-id, so in the o.arg1 we store how many
- * additional flow-id we want to filter, the basic is 1
- */
-void
-fill_flow6( ipfw_insn_u32 *cmd, char *av )
-{
- u_int32_t type; /* Current flow number */
- u_int16_t nflow = 0; /* Current flow index */
- char *s = av;
- cmd->d[0] = 0; /* Initializing the base number*/
-
- while (s) {
- av = strsep( &s, ",") ;
- type = strtoul(av, &av, 0);
- if (*av != ',' && *av != '\0')
- errx(EX_DATAERR, "invalid ipv6 flow number %s", av);
- if (type > 0xfffff)
- errx(EX_DATAERR, "flow number out of range %s", av);
- cmd->d[nflow] |= type;
- nflow++;
- }
- if( nflow > 0 ) {
- cmd->o.opcode = O_FLOW6ID;
- cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32) + nflow;
- cmd->o.arg1 = nflow;
- }
- else {
- errx(EX_DATAERR, "invalid ipv6 flow number %s", av);
- }
-}
-
-static ipfw_insn *
-add_srcip6(ipfw_insn *cmd, char *av)
-{
-
- fill_ip6((ipfw_insn_ip6 *)cmd, av);
- if (F_LEN(cmd) == 0) /* any */
- ;
- if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) { /* "me" */
- cmd->opcode = O_IP6_SRC_ME;
- } else if (F_LEN(cmd) ==
- (F_INSN_SIZE(struct in6_addr) + F_INSN_SIZE(ipfw_insn))) {
- /* single IP, no mask*/
- cmd->opcode = O_IP6_SRC;
- } else { /* addr/mask opt */
- cmd->opcode = O_IP6_SRC_MASK;
- }
- return cmd;
-}
-
-static ipfw_insn *
-add_dstip6(ipfw_insn *cmd, char *av)
-{
-
- fill_ip6((ipfw_insn_ip6 *)cmd, av);
- if (F_LEN(cmd) == 0) /* any */
- ;
- if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) { /* "me" */
- cmd->opcode = O_IP6_DST_ME;
- } else if (F_LEN(cmd) ==
- (F_INSN_SIZE(struct in6_addr) + F_INSN_SIZE(ipfw_insn))) {
- /* single IP, no mask*/
- cmd->opcode = O_IP6_DST;
- } else { /* addr/mask opt */
- cmd->opcode = O_IP6_DST_MASK;
- }
- return cmd;
-}
-
-
-/*
* helper function to process a set of flags and set bits in the
* appropriate masks.
*/
@@ -3225,16 +2173,14 @@ fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode,
}
-static void
-delete(int ac, char *av[])
+void
+ipfw_delete(int ac, char *av[])
{
uint32_t rulenum;
- struct dn_pipe p;
int i;
int exitval = EX_OK;
int do_set = 0;
- memset(&p, 0, sizeof p);
av++; ac--;
NEED1("missing rule specification");
@@ -3242,7 +2188,7 @@ delete(int ac, char *av[])
/* Do not allow using the following syntax:
* ipfw set N delete set M
*/
- if (use_set)
+ if (co.use_set)
errx(EX_DATAERR, "invalid syntax");
do_set = 1; /* delete set */
ac--; av++;
@@ -3251,27 +2197,18 @@ delete(int ac, char *av[])
/* Rule number */
while (ac && isdigit(**av)) {
i = atoi(*av); av++; ac--;
- if (do_nat) {
+ if (co.do_nat) {
exitval = do_cmd(IP_FW_NAT_DEL, &i, sizeof i);
if (exitval) {
exitval = EX_UNAVAILABLE;
warn("rule %u not available", i);
}
- } else if (do_pipe) {
- if (do_pipe == 1)
- p.pipe_nr = i;
- else
- p.fs.fs_nr = i;
- i = do_cmd(IP_DUMMYNET_DEL, &p, sizeof p);
- if (i) {
- exitval = 1;
- warn("rule %u: setsockopt(IP_DUMMYNET_DEL)",
- do_pipe == 1 ? p.pipe_nr : p.fs.fs_nr);
- }
+ } else if (co.do_pipe) {
+ exitval = ipfw_delete_pipe(co.do_pipe, i);
} else {
- if (use_set)
+ if (co.use_set)
rulenum = (i & 0xffff) | (5 << 24) |
- ((use_set - 1) << 16);
+ ((co.use_set - 1) << 16);
else
rulenum = (i & 0xffff) | (do_set << 24);
i = do_cmd(IP_FW_DEL, &rulenum, sizeof rulenum);
@@ -3310,1191 +2247,6 @@ fill_iface(ipfw_insn_if *cmd, char *arg)
errx(EX_DATAERR, "bad ip address ``%s''", arg);
}
-/*
- * Search for interface with name "ifn", and fill n accordingly:
- *
- * n->ip ip address of interface "ifn"
- * n->if_name copy of interface name "ifn"
- */
-static void
-set_addr_dynamic(const char *ifn, struct cfg_nat *n)
-{
- size_t needed;
- int mib[6];
- char *buf, *lim, *next;
- struct if_msghdr *ifm;
- struct ifa_msghdr *ifam;
- struct sockaddr_dl *sdl;
- struct sockaddr_in *sin;
- int ifIndex, ifMTU;
-
- mib[0] = CTL_NET;
- mib[1] = PF_ROUTE;
- mib[2] = 0;
- mib[3] = AF_INET;
- mib[4] = NET_RT_IFLIST;
- mib[5] = 0;
-/*
- * Get interface data.
- */
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
- err(1, "iflist-sysctl-estimate");
- if ((buf = malloc(needed)) == NULL)
- errx(1, "malloc failed");
- if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
- err(1, "iflist-sysctl-get");
- lim = buf + needed;
-/*
- * Loop through interfaces until one with
- * given name is found. This is done to
- * find correct interface index for routing
- * message processing.
- */
- ifIndex = 0;
- next = buf;
- while (next < lim) {
- ifm = (struct if_msghdr *)next;
- next += ifm->ifm_msglen;
- if (ifm->ifm_version != RTM_VERSION) {
- if (verbose)
- warnx("routing message version %d "
- "not understood", ifm->ifm_version);
- continue;
- }
- if (ifm->ifm_type == RTM_IFINFO) {
- sdl = (struct sockaddr_dl *)(ifm + 1);
- if (strlen(ifn) == sdl->sdl_nlen &&
- strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) {
- ifIndex = ifm->ifm_index;
- ifMTU = ifm->ifm_data.ifi_mtu;
- break;
- }
- }
- }
- if (!ifIndex)
- errx(1, "unknown interface name %s", ifn);
-/*
- * Get interface address.
- */
- sin = NULL;
- while (next < lim) {
- ifam = (struct ifa_msghdr *)next;
- next += ifam->ifam_msglen;
- if (ifam->ifam_version != RTM_VERSION) {
- if (verbose)
- warnx("routing message version %d "
- "not understood", ifam->ifam_version);
- continue;
- }
- if (ifam->ifam_type != RTM_NEWADDR)
- break;
- if (ifam->ifam_addrs & RTA_IFA) {
- int i;
- char *cp = (char *)(ifam + 1);
-
- for (i = 1; i < RTA_IFA; i <<= 1) {
- if (ifam->ifam_addrs & i)
- cp += SA_SIZE((struct sockaddr *)cp);
- }
- if (((struct sockaddr *)cp)->sa_family == AF_INET) {
- sin = (struct sockaddr_in *)cp;
- break;
- }
- }
- }
- if (sin == NULL)
- errx(1, "%s: cannot get interface address", ifn);
-
- n->ip = sin->sin_addr;
- strncpy(n->if_name, ifn, IF_NAMESIZE);
-
- free(buf);
-}
-
-/*
- * XXX - The following functions, macros and definitions come from natd.c:
- * it would be better to move them outside natd.c, in a file
- * (redirect_support.[ch]?) shared by ipfw and natd, but for now i can live
- * with it.
- */
-
-/*
- * Definition of a port range, and macros to deal with values.
- * FORMAT: HI 16-bits == first port in range, 0 == all ports.
- * LO 16-bits == number of ports in range
- * NOTES: - Port values are not stored in network byte order.
- */
-
-#define port_range u_long
-
-#define GETLOPORT(x) ((x) >> 0x10)
-#define GETNUMPORTS(x) ((x) & 0x0000ffff)
-#define GETHIPORT(x) (GETLOPORT((x)) + GETNUMPORTS((x)))
-
-/* Set y to be the low-port value in port_range variable x. */
-#define SETLOPORT(x,y) ((x) = ((x) & 0x0000ffff) | ((y) << 0x10))
-
-/* Set y to be the number of ports in port_range variable x. */
-#define SETNUMPORTS(x,y) ((x) = ((x) & 0xffff0000) | (y))
-
-static void
-StrToAddr (const char* str, struct in_addr* addr)
-{
- struct hostent* hp;
-
- if (inet_aton (str, addr))
- return;
-
- hp = gethostbyname (str);
- if (!hp)
- errx (1, "unknown host %s", str);
-
- memcpy (addr, hp->h_addr, sizeof (struct in_addr));
-}
-
-static int
-StrToPortRange (const char* str, const char* proto, port_range *portRange)
-{
- char* sep;
- struct servent* sp;
- char* end;
- u_short loPort;
- u_short hiPort;
-
- /* First see if this is a service, return corresponding port if so. */
- sp = getservbyname (str,proto);
- if (sp) {
- SETLOPORT(*portRange, ntohs(sp->s_port));
- SETNUMPORTS(*portRange, 1);
- return 0;
- }
-
- /* Not a service, see if it's a single port or port range. */
- sep = strchr (str, '-');
- if (sep == NULL) {
- SETLOPORT(*portRange, strtol(str, &end, 10));
- if (end != str) {
- /* Single port. */
- SETNUMPORTS(*portRange, 1);
- return 0;
- }
-
- /* Error in port range field. */
- errx (EX_DATAERR, "%s/%s: unknown service", str, proto);
- }
-
- /* Port range, get the values and sanity check. */
- sscanf (str, "%hu-%hu", &loPort, &hiPort);
- SETLOPORT(*portRange, loPort);
- SETNUMPORTS(*portRange, 0); /* Error by default */
- if (loPort <= hiPort)
- SETNUMPORTS(*portRange, hiPort - loPort + 1);
-
- if (GETNUMPORTS(*portRange) == 0)
- errx (EX_DATAERR, "invalid port range %s", str);
-
- return 0;
-}
-
-static int
-StrToProto (const char* str)
-{
- if (!strcmp (str, "tcp"))
- return IPPROTO_TCP;
-
- if (!strcmp (str, "udp"))
- return IPPROTO_UDP;
-
-#ifdef _ALIAS_SCTP /*Using alias_sctp*/
- if (!strcmp (str, "sctp"))
- return IPPROTO_SCTP;
- errx (EX_DATAERR, "unknown protocol %s. Expected sctp, tcp or udp", str);
-#else
- errx (EX_DATAERR, "unknown protocol %s. Expected tcp or udp", str);
-#endif
-}
-
-static int
-StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto,
- port_range *portRange)
-{
- char* ptr;
-
- ptr = strchr (str, ':');
- if (!ptr)
- errx (EX_DATAERR, "%s is missing port number", str);
-
- *ptr = '\0';
- ++ptr;
-
- StrToAddr (str, addr);
- return StrToPortRange (ptr, proto, portRange);
-}
-
-/* End of stuff taken from natd.c. */
-
-#define INC_ARGCV() do { \
- (*_av)++; \
- (*_ac)--; \
- av = *_av; \
- ac = *_ac; \
-} while(0)
-
-/*
- * The next 3 functions add support for the addr, port and proto redirect and
- * their logic is loosely based on SetupAddressRedirect(), SetupPortRedirect()
- * and SetupProtoRedirect() from natd.c.
- *
- * Every setup_* function fills at least one redirect entry
- * (struct cfg_redir) and zero or more server pool entry (struct cfg_spool)
- * in buf.
- *
- * The format of data in buf is:
- *
- *
- * cfg_nat cfg_redir cfg_spool ...... cfg_spool
- *
- * ------------------------------------- ------------
- * | | .....X ... | | | | .....
- * ------------------------------------- ...... ------------
- * ^
- * spool_cnt n=0 ...... n=(X-1)
- *
- * len points to the amount of available space in buf
- * space counts the memory consumed by every function
- *
- * XXX - Every function get all the argv params so it
- * has to check, in optional parameters, that the next
- * args is a valid option for the redir entry and not
- * another token. Only redir_port and redir_proto are
- * affected by this.
- */
-
-static int
-setup_redir_addr(char *spool_buf, int len,
- int *_ac, char ***_av)
-{
- char **av, *sep; /* Token separator. */
- /* Temporary buffer used to hold server pool ip's. */
- char tmp_spool_buf[NAT_BUF_LEN];
- int ac, space, lsnat;
- struct cfg_redir *r;
- struct cfg_spool *tmp;
-
- av = *_av;
- ac = *_ac;
- space = 0;
- lsnat = 0;
- if (len >= SOF_REDIR) {
- r = (struct cfg_redir *)spool_buf;
- /* Skip cfg_redir at beginning of buf. */
- spool_buf = &spool_buf[SOF_REDIR];
- space = SOF_REDIR;
- len -= SOF_REDIR;
- } else
- goto nospace;
- r->mode = REDIR_ADDR;
- /* Extract local address. */
- if (ac == 0)
- errx(EX_DATAERR, "redirect_addr: missing local address");
- sep = strchr(*av, ',');
- if (sep) { /* LSNAT redirection syntax. */
- r->laddr.s_addr = INADDR_NONE;
- /* Preserve av, copy spool servers to tmp_spool_buf. */
- strncpy(tmp_spool_buf, *av, strlen(*av)+1);
- lsnat = 1;
- } else
- StrToAddr(*av, &r->laddr);
- INC_ARGCV();
-
- /* Extract public address. */
- if (ac == 0)
- errx(EX_DATAERR, "redirect_addr: missing public address");
- StrToAddr(*av, &r->paddr);
- INC_ARGCV();
-
- /* Setup LSNAT server pool. */
- if (sep) {
- sep = strtok(tmp_spool_buf, ",");
- while (sep != NULL) {
- tmp = (struct cfg_spool *)spool_buf;
- if (len < SOF_SPOOL)
- goto nospace;
- len -= SOF_SPOOL;
- space += SOF_SPOOL;
- StrToAddr(sep, &tmp->addr);
- tmp->port = ~0;
- r->spool_cnt++;
- /* Point to the next possible cfg_spool. */
- spool_buf = &spool_buf[SOF_SPOOL];
- sep = strtok(NULL, ",");
- }
- }
- return(space);
-nospace:
- errx(EX_DATAERR, "redirect_addr: buf is too small\n");
-}
-
-static int
-setup_redir_port(char *spool_buf, int len,
- int *_ac, char ***_av)
-{
- char **av, *sep, *protoName;
- char tmp_spool_buf[NAT_BUF_LEN];
- int ac, space, lsnat;
- struct cfg_redir *r;
- struct cfg_spool *tmp;
- u_short numLocalPorts;
- port_range portRange;
-
- av = *_av;
- ac = *_ac;
- space = 0;
- lsnat = 0;
- numLocalPorts = 0;
-
- if (len >= SOF_REDIR) {
- r = (struct cfg_redir *)spool_buf;
- /* Skip cfg_redir at beginning of buf. */
- spool_buf = &spool_buf[SOF_REDIR];
- space = SOF_REDIR;
- len -= SOF_REDIR;
- } else
- goto nospace;
- r->mode = REDIR_PORT;
- /*
- * Extract protocol.
- */
- if (ac == 0)
- errx (EX_DATAERR, "redirect_port: missing protocol");
- r->proto = StrToProto(*av);
- protoName = *av;
- INC_ARGCV();
-
- /*
- * Extract local address.
- */
- if (ac == 0)
- errx (EX_DATAERR, "redirect_port: missing local address");
-
- sep = strchr(*av, ',');
- /* LSNAT redirection syntax. */
- if (sep) {
- r->laddr.s_addr = INADDR_NONE;
- r->lport = ~0;
- numLocalPorts = 1;
- /* Preserve av, copy spool servers to tmp_spool_buf. */
- strncpy(tmp_spool_buf, *av, strlen(*av)+1);
- lsnat = 1;
- } else {
-#ifdef _ALIAS_SCTP /*Using alias_sctp*/
- /*
- * The sctp nat does not allow the port numbers to be mapped to new port numbers
- * Therefore, no ports are to be specified in the target port field
- */
- if (r->proto == IPPROTO_SCTP) {
- if (strchr (*av, ':'))
- errx(EX_DATAERR, "redirect_port:"
- "port numbers do not change in sctp, so do not specify them as part of the target");
- else
- StrToAddr(*av, &r->laddr);
- } else {
-#endif /*Using alias_sctp*/
- if (StrToAddrAndPortRange (*av, &r->laddr, protoName,
- &portRange) != 0)
- errx(EX_DATAERR, "redirect_port:"
- "invalid local port range");
-
- r->lport = GETLOPORT(portRange);
- numLocalPorts = GETNUMPORTS(portRange);
-#ifdef _ALIAS_SCTP /*Using alias_sctp*/
- }
-#endif /*Using alias_sctp*/
- }
- INC_ARGCV();
-
- /*
- * Extract public port and optionally address.
- */
- if (ac == 0)
- errx (EX_DATAERR, "redirect_port: missing public port");
-
- sep = strchr (*av, ':');
- if (sep) {
- if (StrToAddrAndPortRange (*av, &r->paddr, protoName,
- &portRange) != 0)
- errx(EX_DATAERR, "redirect_port:"
- "invalid public port range");
- } else {
- r->paddr.s_addr = INADDR_ANY;
- if (StrToPortRange (*av, protoName, &portRange) != 0)
- errx(EX_DATAERR, "redirect_port:"
- "invalid public port range");
- }
-
- r->pport = GETLOPORT(portRange);
-#ifdef _ALIAS_SCTP /*Using alias_sctp*/
- if (r->proto == IPPROTO_SCTP) { /* so the logic below still works */
- numLocalPorts = GETNUMPORTS(portRange);
- r->lport = r->pport;
- }
-#endif /*Using alias_sctp*/
- r->pport_cnt = GETNUMPORTS(portRange);
- INC_ARGCV();
-
- /*
- * Extract remote address and optionally port.
- */
- /*
- * NB: isalpha(**av) => we've to check that next parameter is really an
- * option for this redirect entry, else stop here processing arg[cv].
- */
- if (ac != 0 && !isalpha(**av)) {
- sep = strchr (*av, ':');
- if (sep) {
- if (StrToAddrAndPortRange (*av, &r->raddr, protoName,
- &portRange) != 0)
- errx(EX_DATAERR, "redirect_port:"
- "invalid remote port range");
- } else {
- SETLOPORT(portRange, 0);
- SETNUMPORTS(portRange, 1);
- StrToAddr (*av, &r->raddr);
- }
- INC_ARGCV();
- } else {
- SETLOPORT(portRange, 0);
- SETNUMPORTS(portRange, 1);
- r->raddr.s_addr = INADDR_ANY;
- }
- r->rport = GETLOPORT(portRange);
- r->rport_cnt = GETNUMPORTS(portRange);
-
- /*
- * Make sure port ranges match up, then add the redirect ports.
- */
- if (numLocalPorts != r->pport_cnt)
- errx(EX_DATAERR, "redirect_port:"
- "port ranges must be equal in size");
-
- /* Remote port range is allowed to be '0' which means all ports. */
- if (r->rport_cnt != numLocalPorts &&
- (r->rport_cnt != 1 || r->rport != 0))
- errx(EX_DATAERR, "redirect_port: remote port must"
- "be 0 or equal to local port range in size");
-
- /*
- * Setup LSNAT server pool.
- */
- if (lsnat) {
- sep = strtok(tmp_spool_buf, ",");
- while (sep != NULL) {
- tmp = (struct cfg_spool *)spool_buf;
- if (len < SOF_SPOOL)
- goto nospace;
- len -= SOF_SPOOL;
- space += SOF_SPOOL;
-
-#ifdef _ALIAS_SCTP /*Using alias_sctp*/
- /*
- * The sctp nat does not allow the port numbers to be mapped to new port numbers
- * Therefore, no ports are to be specified in the target port field
- */
- if (r->proto == IPPROTO_SCTP) {
- if (strchr (sep, ':')) {
- errx(EX_DATAERR, "redirect_port:"
- "port numbers do not change in sctp, so do not specify them as part of the target");
- } else {
- StrToAddr(sep, &tmp->addr);
- tmp->port = r->pport;
- }
- } else {
-#endif /*Using alias_sctp*/
- if (StrToAddrAndPortRange(sep, &tmp->addr, protoName,
- &portRange) != 0)
- errx(EX_DATAERR, "redirect_port:"
- "invalid local port range");
- if (GETNUMPORTS(portRange) != 1)
- errx(EX_DATAERR, "redirect_port: local port"
- "must be single in this context");
- tmp->port = GETLOPORT(portRange);
-#ifdef _ALIAS_SCTP /*Using alias_sctp*/
- }
-#endif /*Using alias_sctp*/
- r->spool_cnt++;
- /* Point to the next possible cfg_spool. */
- spool_buf = &spool_buf[SOF_SPOOL];
- sep = strtok(NULL, ",");
- }
- }
- return (space);
-nospace:
- errx(EX_DATAERR, "redirect_port: buf is too small\n");
-}
-
-static int
-setup_redir_proto(char *spool_buf, int len,
- int *_ac, char ***_av)
-{
- char **av;
- int ac, space;
- struct protoent *protoent;
- struct cfg_redir *r;
-
- av = *_av;
- ac = *_ac;
- if (len >= SOF_REDIR) {
- r = (struct cfg_redir *)spool_buf;
- /* Skip cfg_redir at beginning of buf. */
- spool_buf = &spool_buf[SOF_REDIR];
- space = SOF_REDIR;
- len -= SOF_REDIR;
- } else
- goto nospace;
- r->mode = REDIR_PROTO;
- /*
- * Extract protocol.
- */
- if (ac == 0)
- errx(EX_DATAERR, "redirect_proto: missing protocol");
-
- protoent = getprotobyname(*av);
- if (protoent == NULL)
- errx(EX_DATAERR, "redirect_proto: unknown protocol %s", *av);
- else
- r->proto = protoent->p_proto;
-
- INC_ARGCV();
-
- /*
- * Extract local address.
- */
- if (ac == 0)
- errx(EX_DATAERR, "redirect_proto: missing local address");
- else
- StrToAddr(*av, &r->laddr);
-
- INC_ARGCV();
-
- /*
- * Extract optional public address.
- */
- if (ac == 0) {
- r->paddr.s_addr = INADDR_ANY;
- r->raddr.s_addr = INADDR_ANY;
- } else {
- /* see above in setup_redir_port() */
- if (!isalpha(**av)) {
- StrToAddr(*av, &r->paddr);
- INC_ARGCV();
-
- /*
- * Extract optional remote address.
- */
- /* see above in setup_redir_port() */
- if (ac!=0 && !isalpha(**av)) {
- StrToAddr(*av, &r->raddr);
- INC_ARGCV();
- }
- }
- }
- return (space);
-nospace:
- errx(EX_DATAERR, "redirect_proto: buf is too small\n");
-}
-
-static void
-show_nat(int ac, char **av);
-
-static void
-print_nat_config(char *buf) {
- struct cfg_nat *n;
- int i, cnt, flag, off;
- struct cfg_redir *t;
- struct cfg_spool *s;
- struct protoent *p;
-
- n = (struct cfg_nat *)buf;
- flag = 1;
- off = sizeof(*n);
- printf("ipfw nat %u config", n->id);
- if (strlen(n->if_name) != 0)
- printf(" if %s", n->if_name);
- else if (n->ip.s_addr != 0)
- printf(" ip %s", inet_ntoa(n->ip));
- while (n->mode != 0) {
- if (n->mode & PKT_ALIAS_LOG) {
- printf(" log");
- n->mode &= ~PKT_ALIAS_LOG;
- } else if (n->mode & PKT_ALIAS_DENY_INCOMING) {
- printf(" deny_in");
- n->mode &= ~PKT_ALIAS_DENY_INCOMING;
- } else if (n->mode & PKT_ALIAS_SAME_PORTS) {
- printf(" same_ports");
- n->mode &= ~PKT_ALIAS_SAME_PORTS;
- } else if (n->mode & PKT_ALIAS_UNREGISTERED_ONLY) {
- printf(" unreg_only");
- n->mode &= ~PKT_ALIAS_UNREGISTERED_ONLY;
- } else if (n->mode & PKT_ALIAS_RESET_ON_ADDR_CHANGE) {
- printf(" reset");
- n->mode &= ~PKT_ALIAS_RESET_ON_ADDR_CHANGE;
- } else if (n->mode & PKT_ALIAS_REVERSE) {
- printf(" reverse");
- n->mode &= ~PKT_ALIAS_REVERSE;
- } else if (n->mode & PKT_ALIAS_PROXY_ONLY) {
- printf(" proxy_only");
- n->mode &= ~PKT_ALIAS_PROXY_ONLY;
- }
- }
- /* Print all the redirect's data configuration. */
- for (cnt = 0; cnt < n->redir_cnt; cnt++) {
- t = (struct cfg_redir *)&buf[off];
- off += SOF_REDIR;
- switch (t->mode) {
- case REDIR_ADDR:
- printf(" redirect_addr");
- if (t->spool_cnt == 0)
- printf(" %s", inet_ntoa(t->laddr));
- else
- for (i = 0; i < t->spool_cnt; i++) {
- s = (struct cfg_spool *)&buf[off];
- if (i)
- printf(",");
- else
- printf(" ");
- printf("%s", inet_ntoa(s->addr));
- off += SOF_SPOOL;
- }
- printf(" %s", inet_ntoa(t->paddr));
- break;
- case REDIR_PORT:
- p = getprotobynumber(t->proto);
- printf(" redirect_port %s ", p->p_name);
- if (!t->spool_cnt) {
- printf("%s:%u", inet_ntoa(t->laddr), t->lport);
- if (t->pport_cnt > 1)
- printf("-%u", t->lport +
- t->pport_cnt - 1);
- } else
- for (i=0; i < t->spool_cnt; i++) {
- s = (struct cfg_spool *)&buf[off];
- if (i)
- printf(",");
- printf("%s:%u", inet_ntoa(s->addr),
- s->port);
- off += SOF_SPOOL;
- }
-
- printf(" ");
- if (t->paddr.s_addr)
- printf("%s:", inet_ntoa(t->paddr));
- printf("%u", t->pport);
- if (!t->spool_cnt && t->pport_cnt > 1)
- printf("-%u", t->pport + t->pport_cnt - 1);
-
- if (t->raddr.s_addr) {
- printf(" %s", inet_ntoa(t->raddr));
- if (t->rport) {
- printf(":%u", t->rport);
- if (!t->spool_cnt && t->rport_cnt > 1)
- printf("-%u", t->rport +
- t->rport_cnt - 1);
- }
- }
- break;
- case REDIR_PROTO:
- p = getprotobynumber(t->proto);
- printf(" redirect_proto %s %s", p->p_name,
- inet_ntoa(t->laddr));
- if (t->paddr.s_addr != 0) {
- printf(" %s", inet_ntoa(t->paddr));
- if (t->raddr.s_addr)
- printf(" %s", inet_ntoa(t->raddr));
- }
- break;
- default:
- errx(EX_DATAERR, "unknown redir mode");
- break;
- }
- }
- printf("\n");
-}
-
-static void
-config_nat(int ac, char **av)
-{
- struct cfg_nat *n; /* Nat instance configuration. */
- int i, len, off, tok;
- char *id, buf[NAT_BUF_LEN]; /* Buffer for serialized data. */
-
- len = NAT_BUF_LEN;
- /* Offset in buf: save space for n at the beginning. */
- off = sizeof(*n);
- memset(buf, 0, sizeof(buf));
- n = (struct cfg_nat *)buf;
-
- av++; ac--;
- /* Nat id. */
- if (ac && isdigit(**av)) {
- id = *av;
- i = atoi(*av);
- ac--; av++;
- n->id = i;
- } else
- errx(EX_DATAERR, "missing nat id");
- if (ac == 0)
- errx(EX_DATAERR, "missing option");
-
- while (ac > 0) {
- tok = match_token(nat_params, *av);
- ac--; av++;
- switch (tok) {
- case TOK_IP:
- if (ac == 0)
- errx(EX_DATAERR, "missing option");
- if (!inet_aton(av[0], &(n->ip)))
- errx(EX_DATAERR, "bad ip address ``%s''",
- av[0]);
- ac--; av++;
- break;
- case TOK_IF:
- if (ac == 0)
- errx(EX_DATAERR, "missing option");
- set_addr_dynamic(av[0], n);
- ac--; av++;
- break;
- case TOK_ALOG:
- n->mode |= PKT_ALIAS_LOG;
- break;
- case TOK_DENY_INC:
- n->mode |= PKT_ALIAS_DENY_INCOMING;
- break;
- case TOK_SAME_PORTS:
- n->mode |= PKT_ALIAS_SAME_PORTS;
- break;
- case TOK_UNREG_ONLY:
- n->mode |= PKT_ALIAS_UNREGISTERED_ONLY;
- break;
- case TOK_RESET_ADDR:
- n->mode |= PKT_ALIAS_RESET_ON_ADDR_CHANGE;
- break;
- case TOK_ALIAS_REV:
- n->mode |= PKT_ALIAS_REVERSE;
- break;
- case TOK_PROXY_ONLY:
- n->mode |= PKT_ALIAS_PROXY_ONLY;
- break;
- /*
- * All the setup_redir_* functions work directly in the final
- * buffer, see above for details.
- */
- case TOK_REDIR_ADDR:
- case TOK_REDIR_PORT:
- case TOK_REDIR_PROTO:
- switch (tok) {
- case TOK_REDIR_ADDR:
- i = setup_redir_addr(&buf[off], len, &ac, &av);
- break;
- case TOK_REDIR_PORT:
- i = setup_redir_port(&buf[off], len, &ac, &av);
- break;
- case TOK_REDIR_PROTO:
- i = setup_redir_proto(&buf[off], len, &ac, &av);
- break;
- }
- n->redir_cnt++;
- off += i;
- len -= i;
- break;
- default:
- errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]);
- }
- }
-
- i = do_cmd(IP_FW_NAT_CFG, buf, off);
- if (i)
- err(1, "setsockopt(%s)", "IP_FW_NAT_CFG");
-
- if (!do_quiet) {
- /* After every modification, we show the resultant rule. */
- int _ac = 3;
- char *_av[] = {"show", "config", id};
- show_nat(_ac, _av);
- }
-}
-
-static void
-config_pipe(int ac, char **av)
-{
- struct dn_pipe p;
- int i;
- char *end;
- void *par = NULL;
-
- memset(&p, 0, sizeof p);
-
- av++; ac--;
- /* Pipe number */
- if (ac && isdigit(**av)) {
- i = atoi(*av); av++; ac--;
- if (do_pipe == 1)
- p.pipe_nr = i;
- else
- p.fs.fs_nr = i;
- }
- while (ac > 0) {
- double d;
- int tok = match_token(dummynet_params, *av);
- ac--; av++;
-
- switch(tok) {
- case TOK_NOERROR:
- p.fs.flags_fs |= DN_NOERROR;
- break;
-
- case TOK_PLR:
- 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);
- ac--; av++;
- break;
-
- case TOK_QUEUE:
- NEED1("queue needs queue size\n");
- end = NULL;
- p.fs.qsize = strtoul(av[0], &end, 0);
- if (*end == 'K' || *end == 'k') {
- p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
- p.fs.qsize *= 1024;
- } else if (*end == 'B' ||
- _substrcmp2(end, "by", "bytes") == 0) {
- p.fs.flags_fs |= DN_QSIZE_IS_BYTES;
- }
- ac--; av++;
- break;
-
- case TOK_BUCKETS:
- NEED1("buckets needs argument\n");
- p.fs.rq_size = strtoul(av[0], NULL, 0);
- ac--; av++;
- break;
-
- case TOK_MASK:
- NEED1("mask needs mask specifier\n");
- /*
- * per-flow queue, mask is dst_ip, dst_port,
- * src_ip, src_port, proto measured in bits
- */
- par = NULL;
-
- bzero(&p.fs.flow_mask, sizeof(p.fs.flow_mask));
- end = NULL;
-
- while (ac >= 1) {
- uint32_t *p32 = NULL;
- uint16_t *p16 = NULL;
- uint32_t *p20 = NULL;
- struct in6_addr *pa6 = NULL;
- uint32_t a;
-
- tok = match_token(dummynet_params, *av);
- ac--; av++;
- switch(tok) {
- case TOK_ALL:
- /*
- * special case, all bits significant
- */
- 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;
- goto end_mask;
-
- case TOK_DSTIP:
- p32 = &p.fs.flow_mask.dst_ip;
- break;
-
- case TOK_SRCIP:
- p32 = &p.fs.flow_mask.src_ip;
- break;
-
- case TOK_DSTIP6:
- pa6 = &(p.fs.flow_mask.dst_ip6);
- break;
-
- case TOK_SRCIP6:
- pa6 = &(p.fs.flow_mask.src_ip6);
- break;
-
- case TOK_FLOWID:
- p20 = &p.fs.flow_mask.flow_id6;
- break;
-
- case TOK_DSTPORT:
- p16 = &p.fs.flow_mask.dst_port;
- break;
-
- case TOK_SRCPORT:
- p16 = &p.fs.flow_mask.src_port;
- break;
-
- case TOK_PROTO:
- break;
-
- default:
- ac++; av--; /* backtrack */
- goto end_mask;
- }
- if (ac < 1)
- errx(EX_USAGE, "mask: value missing");
- if (*av[0] == '/') {
- a = strtoul(av[0]+1, &end, 0);
- if (pa6 == NULL)
- a = (a == 32) ? ~0 : (1 << a) - 1;
- } else
- a = strtoul(av[0], &end, 0);
- if (p32 != NULL)
- *p32 = a;
- else if (p16 != NULL) {
- if (a > 0xFFFF)
- errx(EX_DATAERR,
- "port mask must be 16 bit");
- *p16 = (uint16_t)a;
- } else if (p20 != NULL) {
- if (a > 0xfffff)
- errx(EX_DATAERR,
- "flow_id mask must be 20 bit");
- *p20 = (uint32_t)a;
- } else if (pa6 != NULL) {
- if (a < 0 || a > 128)
- errx(EX_DATAERR,
- "in6addr invalid mask len");
- else
- n2mask(pa6, a);
- } else {
- if (a > 0xFF)
- errx(EX_DATAERR,
- "proto mask must be 8 bit");
- p.fs.flow_mask.proto = (uint8_t)a;
- }
- if (a != 0)
- p.fs.flags_fs |= DN_HAVE_FLOW_MASK;
- ac--; av++;
- } /* end while, config masks */
-end_mask:
- break;
-
- 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;
- if (tok == TOK_GRED)
- p.fs.flags_fs |= DN_IS_GENTLE_RED;
- /*
- * the format for parameters is w_q/min_th/max_th/max_p
- */
- if ((end = strsep(&av[0], "/"))) {
- 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));
- }
- if ((end = strsep(&av[0], "/"))) {
- p.fs.min_th = strtoul(end, &end, 0);
- if (*end == 'K' || *end == 'k')
- p.fs.min_th *= 1024;
- }
- if ((end = strsep(&av[0], "/"))) {
- p.fs.max_th = strtoul(end, &end, 0);
- if (*end == 'K' || *end == 'k')
- p.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));
- }
- ac--; av++;
- break;
-
- case TOK_DROPTAIL:
- p.fs.flags_fs &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
- break;
-
- case TOK_BW:
- NEED1("bw needs bandwidth or interface\n");
- if (do_pipe != 1)
- errx(EX_DATAERR, "bandwidth only valid for pipes");
- /*
- * set clocking interface or bandwidth value
- */
- if (av[0][0] >= 'a' && av[0][0] <= 'z') {
- int l = sizeof(p.if_name)-1;
- /* interface name */
- strncpy(p.if_name, av[0], l);
- p.if_name[l] = '\0';
- p.bandwidth = 0;
- } else {
- p.if_name[0] = '\0';
- p.bandwidth = strtoul(av[0], &end, 0);
- if (*end == 'K' || *end == 'k') {
- end++;
- p.bandwidth *= 1000;
- } else if (*end == 'M') {
- end++;
- p.bandwidth *= 1000000;
- }
- if ((*end == 'B' &&
- _substrcmp2(end, "Bi", "Bit/s") != 0) ||
- _substrcmp2(end, "by", "bytes") == 0)
- p.bandwidth *= 8;
- if (p.bandwidth < 0)
- errx(EX_DATAERR, "bandwidth too large");
- }
- ac--; av++;
- break;
-
- case TOK_DELAY:
- if (do_pipe != 1)
- errx(EX_DATAERR, "delay only valid for pipes");
- NEED1("delay needs argument 0..10000ms\n");
- p.delay = strtoul(av[0], NULL, 0);
- ac--; av++;
- break;
-
- case TOK_WEIGHT:
- if (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);
- ac--; av++;
- break;
-
- case TOK_PIPE:
- if (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);
- ac--; av++;
- break;
-
- default:
- errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]);
- }
- }
- if (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 { /* 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");
- }
- if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) {
- size_t len;
- long limit;
-
- len = sizeof(limit);
- if (sysctlbyname("net.inet.ip.dummynet.pipe_byte_limit",
- &limit, &len, NULL, 0) == -1)
- limit = 1024*1024;
- if (p.fs.qsize > limit)
- errx(EX_DATAERR, "queue size must be < %ldB", limit);
- } else {
- size_t len;
- long limit;
-
- len = sizeof(limit);
- if (sysctlbyname("net.inet.ip.dummynet.pipe_slot_limit",
- &limit, &len, NULL, 0) == -1)
- limit = 100;
- if (p.fs.qsize > limit)
- errx(EX_DATAERR, "2 <= queue size <= %ld", limit);
- }
- if (p.fs.flags_fs & DN_IS_RED) {
- size_t len;
- int lookup_depth, avg_pkt_size;
- double s, idle, weight, w_q;
- struct clockinfo ck;
- int t;
-
- if (p.fs.min_th >= p.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)
- 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");
- if (lookup_depth == 0)
- errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth"
- " must be greater than zero");
-
- len = sizeof(int);
- if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
- &avg_pkt_size, &len, NULL, 0) == -1)
-
- 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
- * do not have bandwidth information, because that is stored
- * in the parent pipe, and also we have multiple queues
- * competing for it. So we set s=0, which is not very
- * correct. But on the other hand, why do we want RED with
- * WF2Q+ ?
- */
- if (p.bandwidth==0) /* this is a WF2Q+ queue */
- s = 0;
- else
- s = (double)ck.hz * avg_pkt_size * 8 / p.bandwidth;
-
- /*
- * 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);
- idle = s * 3. / w_q;
- p.fs.lookup_step = (int)idle / lookup_depth;
- if (!p.fs.lookup_step)
- p.fs.lookup_step = 1;
- weight = 1 - w_q;
- for (t = p.fs.lookup_step; t > 1; --t)
- weight *= 1 - w_q;
- p.fs.lookup_weight = (int)(weight * (1 << SCALE_RED));
- }
- i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p);
- if (i)
- err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
-}
-
static void
get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
{
@@ -4804,8 +2556,8 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto)
* various match patterns, log/altq actions, and the actual action.
*
*/
-static void
-add(int ac, char *av[])
+void
+ipfw_add(int ac, char *av[])
{
/*
* rules are added into the 'rulebuf' and then copied in
@@ -4957,7 +2709,7 @@ chkarg:
if (action->arg1 <= 0 || action->arg1 >= IP_FW_TABLEARG)
errx(EX_DATAERR, "illegal argument for %s",
*(av - 1));
- } else if (_substrcmp(*av, TABLEARG) == 0) {
+ } else if (_substrcmp(*av, "tablearg") == 0) {
action->arg1 = IP_FW_TABLEARG;
} else if (i == TOK_DIVERT || i == TOK_TEE) {
struct servent *s;
@@ -4981,7 +2733,10 @@ chkarg:
action->opcode = O_FORWARD_IP;
action->len = F_INSN_SIZE(ipfw_insn_sa);
- p->sa.sin_len = sizeof(struct sockaddr_in);
+ /*
+ * In the kernel we assume AF_INET and use only
+ * sin_port and sin_addr.
+ */
p->sa.sin_family = AF_INET;
p->sa.sin_port = 0;
/*
@@ -5083,7 +2838,7 @@ chkarg:
have_altq = (ipfw_insn *)a;
cmd->len = F_INSN_SIZE(ipfw_insn_altq);
cmd->opcode = O_ALTQ;
- fill_altq_qid(&a->qid, *av);
+ a->qid = altq_name_to_qid(*av);
ac--; av++;
}
break;
@@ -5809,17 +3564,22 @@ done:
i = (char *)dst - (char *)rule;
if (do_cmd(IP_FW_ADD, rule, (uintptr_t)&i) == -1)
err(EX_UNAVAILABLE, "getsockopt(%s)", "IP_FW_ADD");
- if (!do_quiet)
+ if (!co.do_quiet)
show_ipfw(rule, 0, 0);
}
-static void
-zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */)
+/*
+ * clear the counters or the log counters.
+ */
+void
+ipfw_zero(int ac, char *av[], int optname /* 0 = IP_FW_ZERO, 1 = IP_FW_RESETLOG */)
{
uint32_t arg, saved_arg;
int failed = EX_OK;
- char const *name = optname == IP_FW_ZERO ? "ZERO" : "RESETLOG";
char const *errstr;
+ char const *name = optname ? "RESETLOG" : "ZERO";
+
+ optname = optname ? IP_FW_RESETLOG : IP_FW_ZERO;
av++; ac--;
@@ -5827,7 +3587,7 @@ zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */)
/* clear all entries */
if (do_cmd(optname, NULL, 0) < 0)
err(EX_UNAVAILABLE, "setsockopt(IP_FW_%s)", name);
- if (!do_quiet)
+ if (!co.do_quiet)
printf("%s.\n", optname == IP_FW_ZERO ?
"Accounting cleared":"Logging counts reset");
@@ -5842,15 +3602,15 @@ zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */)
errx(EX_DATAERR,
"invalid rule number %s\n", *av);
saved_arg = arg;
- if (use_set)
- arg |= (1 << 24) | ((use_set - 1) << 16);
+ if (co.use_set)
+ arg |= (1 << 24) | ((co.use_set - 1) << 16);
av++;
ac--;
if (do_cmd(optname, &arg, sizeof(arg))) {
warn("rule %u: setsockopt(IP_FW_%s)",
saved_arg, name);
failed = EX_UNAVAILABLE;
- } else if (!do_quiet)
+ } else if (!co.do_quiet)
printf("Entry %d %s.\n", saved_arg,
optname == IP_FW_ZERO ?
"cleared" : "logging count reset");
@@ -5862,12 +3622,12 @@ zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */)
exit(failed);
}
-static void
-flush(int force)
+void
+ipfw_flush(int force)
{
- int cmd = do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH;
+ int cmd = co.do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH;
- if (!force && !do_quiet) { /* need to ask user */
+ if (!force && !co.do_quiet) { /* need to ask user */
int c;
printf("Are you sure? [yn] ");
@@ -5883,29 +3643,17 @@ flush(int force)
return;
}
/* `ipfw set N flush` - is the same that `ipfw delete set N` */
- if (use_set) {
- uint32_t arg = ((use_set - 1) & 0xffff) | (1 << 24);
+ if (co.use_set) {
+ uint32_t arg = ((co.use_set - 1) & 0xffff) | (1 << 24);
if (do_cmd(IP_FW_DEL, &arg, sizeof(arg)) < 0)
err(EX_UNAVAILABLE, "setsockopt(IP_FW_DEL)");
} else if (do_cmd(cmd, NULL, 0) < 0)
err(EX_UNAVAILABLE, "setsockopt(IP_%s_FLUSH)",
- do_pipe ? "DUMMYNET" : "FW");
- if (!do_quiet)
- printf("Flushed all %s.\n", do_pipe ? "pipes" : "rules");
+ co.do_pipe ? "DUMMYNET" : "FW");
+ if (!co.do_quiet)
+ printf("Flushed all %s.\n", co.do_pipe ? "pipes" : "rules");
}
-/*
- * 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);
-}
static void table_list(ipfw_table_entry ent, int need_header);
@@ -5916,8 +3664,8 @@ static void table_list(ipfw_table_entry ent, int need_header);
* ipfw table {N | all} flush
* ipfw table {N | all} list
*/
-static void
-table_handler(int ac, char *av[])
+void
+ipfw_table_handler(int ac, char *av[])
{
ipfw_table_entry ent;
int do_add;
@@ -5994,7 +3742,7 @@ table_handler(int ac, char *av[])
if (do_cmd(do_add ? IP_FW_TABLE_ADD : IP_FW_TABLE_DEL,
&ent, sizeof(ent)) < 0) {
/* If running silent, don't bomb out on these errors. */
- if (!(do_quiet && (errno == (do_add ? EEXIST : ESRCH))))
+ if (!(co.do_quiet && (errno == (do_add ? EEXIST : ESRCH))))
err(EX_OSERR, "setsockopt(IP_FW_TABLE_%s)",
do_add ? "ADD" : "DEL");
/* In silent mode, react to a failed add by deleting */
@@ -6039,9 +3787,7 @@ table_list(ipfw_table_entry ent, int need_header)
return;
l = sizeof(*tbl) + a * sizeof(ipfw_table_entry);
- tbl = malloc(l);
- if (tbl == NULL)
- err(EX_OSERR, "malloc");
+ tbl = safe_calloc(1, l);
tbl->tbl = ent.tbl;
if (do_cmd(IP_FW_TABLE_LIST, tbl, (uintptr_t)&l) < 0)
err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)");
@@ -6050,7 +3796,7 @@ table_list(ipfw_table_entry ent, int need_header)
for (a = 0; a < tbl->cnt; a++) {
unsigned int tval;
tval = tbl->ent[a].value;
- if (do_value_as_ip) {
+ if (co.do_value_as_ip) {
char tbuf[128];
strncpy(tbuf, inet_ntoa(*(struct in_addr *)
&tbl->ent[a].addr), 127);
@@ -6066,506 +3812,3 @@ table_list(ipfw_table_entry ent, int need_header)
}
free(tbl);
}
-
-static void
-show_nat(int ac, char **av)
-{
- struct cfg_nat *n;
- struct cfg_redir *e;
- int cmd, i, nbytes, do_cfg, do_rule, frule, lrule, nalloc, size;
- int nat_cnt, redir_cnt, r;
- uint8_t *data, *p;
- char *endptr;
-
- do_rule = 0;
- nalloc = 1024;
- size = 0;
- data = NULL;
- frule = 0;
- lrule = IPFW_DEFAULT_RULE; /* max ipfw rule number */
- ac--; av++;
-
- if (test_only)
- return;
-
- /* Parse parameters. */
- for (cmd = IP_FW_NAT_GET_LOG, do_cfg = 0; ac != 0; ac--, av++) {
- if (!strncmp(av[0], "config", strlen(av[0]))) {
- cmd = IP_FW_NAT_GET_CONFIG, do_cfg = 1;
- continue;
- }
- /* Convert command line rule #. */
- frule = lrule = strtoul(av[0], &endptr, 10);
- if (*endptr == '-')
- lrule = strtoul(endptr+1, &endptr, 10);
- if (lrule == 0)
- err(EX_USAGE, "invalid rule number: %s", av[0]);
- do_rule = 1;
- }
-
- nbytes = nalloc;
- while (nbytes >= nalloc) {
- nalloc = nalloc * 2;
- nbytes = nalloc;
- if ((data = realloc(data, nbytes)) == NULL)
- err(EX_OSERR, "realloc");
- if (do_cmd(cmd, data, (uintptr_t)&nbytes) < 0)
- err(EX_OSERR, "getsockopt(IP_FW_GET_%s)",
- (cmd == IP_FW_NAT_GET_LOG) ? "LOG" : "CONFIG");
- }
- if (nbytes == 0)
- exit(0);
- if (do_cfg) {
- nat_cnt = *((int *)data);
- for (i = sizeof(nat_cnt); nat_cnt; nat_cnt--) {
- n = (struct cfg_nat *)&data[i];
- if (frule <= n->id && lrule >= n->id)
- print_nat_config(&data[i]);
- i += sizeof(struct cfg_nat);
- for (redir_cnt = 0; redir_cnt < n->redir_cnt; redir_cnt++) {
- e = (struct cfg_redir *)&data[i];
- i += sizeof(struct cfg_redir) + e->spool_cnt *
- sizeof(struct cfg_spool);
- }
- }
- } else {
- for (i = 0; 1; i += LIBALIAS_BUF_SIZE + sizeof(int)) {
- p = &data[i];
- if (p == data + nbytes)
- break;
- bcopy(p, &r, sizeof(int));
- if (do_rule) {
- if (!(frule <= r && lrule >= r))
- continue;
- }
- printf("nat %u: %s\n", r, p+sizeof(int));
- }
- }
-}
-
-/*
- * Called with the arguments (excluding program name).
- * Returns 0 if successful, 1 if empty command, errx() in case of errors.
- */
-static int
-ipfw_main(int oldac, char **oldav)
-{
- int ch, ac, save_ac;
- const char *errstr;
- char **av, **save_av;
- int do_acct = 0; /* Show packet/byte count */
-
-#define WHITESP " \t\f\v\n\r"
- if (oldac == 0)
- return 1;
- else if (oldac == 1) {
- /*
- * 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.
- */
- char *arg = oldav[0]; /* The string... */
- int l = strlen(arg);
- int copy = 0; /* 1 if we need to copy, 0 otherwise */
- int i, j;
- for (i = j = 0; i < l; i++) {
- if (arg[i] == '#') /* comment marker */
- break;
- if (copy) {
- arg[j++] = arg[i];
- copy = !index("," WHITESP, arg[i]);
- } else {
- copy = !index(WHITESP, arg[i]);
- if (copy)
- arg[j++] = arg[i];
- }
- }
- if (!copy && j > 0) /* last char was a 'blank', remove it */
- j--;
- l = j; /* the new argument length */
- arg[j++] = '\0';
- if (l == 0) /* empty string! */
- return 1;
-
- /*
- * First, count number of arguments. Because of the previous
- * processing, this is just the number of blanks plus 1.
- */
- for (i = 0, ac = 1; i < l; i++)
- if (index(WHITESP, arg[i]) != NULL)
- ac++;
-
- av = calloc(ac, sizeof(char *));
-
- /*
- * Second, copy arguments from cmd[] to av[]. For each one,
- * j is the initial character, i is the one past the end.
- */
- for (ac = 0, i = j = 0; i < l; i++)
- if (index(WHITESP, arg[i]) != NULL || i == l-1) {
- if (i == l-1)
- i++;
- av[ac] = calloc(i-j+1, 1);
- bcopy(arg+j, av[ac], i-j);
- ac++;
- j = i + 1;
- }
- } else {
- /*
- * If an argument ends with ',' join with the next one.
- */
- int first, i, l;
-
- av = calloc(oldac, sizeof(char *));
- for (first = i = ac = 0, l = 0; i < oldac; i++) {
- char *arg = oldav[i];
- int k = strlen(arg);
-
- l += k;
- if (arg[k-1] != ',' || i == oldac-1) {
- /* Time to copy. */
- av[ac] = calloc(l+1, 1);
- for (l=0; first <= i; first++) {
- strcat(av[ac]+l, oldav[first]);
- l += strlen(oldav[first]);
- }
- ac++;
- l = 0;
- first = i+1;
- }
- }
- }
-
- /* Set the force flag for non-interactive processes */
- if (!do_force)
- do_force = !isatty(STDIN_FILENO);
-
- /* Save arguments for final freeing of memory. */
- save_ac = ac;
- save_av = av;
-
- optind = optreset = 0;
- while ((ch = getopt(ac, av, "abcdefhinNqs:STtv")) != -1)
- switch (ch) {
- case 'a':
- do_acct = 1;
- break;
-
- case 'b':
- comment_only = 1;
- do_compact = 1;
- break;
-
- case 'c':
- do_compact = 1;
- break;
-
- case 'd':
- do_dynamic = 1;
- break;
-
- case 'e':
- do_expired = 1;
- break;
-
- case 'f':
- do_force = 1;
- break;
-
- case 'h': /* help */
- free_args(save_ac, save_av);
- help();
- break; /* NOTREACHED */
-
- case 'i':
- do_value_as_ip = 1;
- break;
-
- case 'n':
- test_only = 1;
- break;
-
- case 'N':
- do_resolv = 1;
- break;
-
- case 'q':
- do_quiet = 1;
- break;
-
- case 's': /* sort */
- do_sort = atoi(optarg);
- break;
-
- case 'S':
- show_sets = 1;
- break;
-
- case 't':
- do_time = 1;
- break;
-
- case 'T':
- do_time = 2; /* numeric timestamp */
- break;
-
- case 'v': /* verbose */
- verbose = 1;
- break;
-
- default:
- free_args(save_ac, save_av);
- return 1;
- }
-
- ac -= optind;
- av += optind;
- NEED1("bad arguments, for usage summary ``ipfw''");
-
- /*
- * An undocumented behaviour of ipfw1 was to allow rule numbers first,
- * e.g. "100 add allow ..." instead of "add 100 allow ...".
- * In case, swap first and second argument to get the normal form.
- */
- if (ac > 1 && isdigit(*av[0])) {
- char *p = av[0];
-
- av[0] = av[1];
- av[1] = p;
- }
-
- /*
- * Optional: pipe, queue or nat.
- */
- do_nat = 0;
- do_pipe = 0;
- if (!strncmp(*av, "nat", strlen(*av)))
- do_nat = 1;
- else if (!strncmp(*av, "pipe", strlen(*av)))
- do_pipe = 1;
- else if (_substrcmp(*av, "queue") == 0)
- do_pipe = 2;
- else if (!strncmp(*av, "set", strlen(*av))) {
- if (ac > 1 && isdigit(av[1][0])) {
- use_set = strtonum(av[1], 0, RESVD_SET, &errstr);
- if (errstr)
- errx(EX_DATAERR,
- "invalid set number %s\n", av[1]);
- ac -= 2; av += 2; use_set++;
- }
- }
-
- if (do_pipe || do_nat) {
- ac--;
- av++;
- }
- NEED1("missing command");
-
- /*
- * For pipes, queues and nats we normally say 'nat|pipe NN config'
- * but the code is easier to parse as 'nat|pipe config NN'
- * so we swap the two arguments.
- */
- if ((do_pipe || do_nat) && ac > 1 && isdigit(*av[0])) {
- char *p = av[0];
-
- av[0] = av[1];
- av[1] = p;
- }
-
- int try_next = 0;
- if (use_set == 0) {
- if (_substrcmp(*av, "add") == 0)
- add(ac, av);
- else if (do_nat && _substrcmp(*av, "show") == 0)
- show_nat(ac, av);
- else if (do_pipe && _substrcmp(*av, "config") == 0)
- config_pipe(ac, av);
- else if (do_nat && _substrcmp(*av, "config") == 0)
- config_nat(ac, av);
- else if (_substrcmp(*av, "set") == 0)
- sets_handler(ac, av);
- else if (_substrcmp(*av, "table") == 0)
- table_handler(ac, av);
- else if (_substrcmp(*av, "enable") == 0)
- sysctl_handler(ac, av, 1);
- else if (_substrcmp(*av, "disable") == 0)
- sysctl_handler(ac, av, 0);
- else
- try_next = 1;
- }
-
- if (use_set || try_next) {
- if (_substrcmp(*av, "delete") == 0)
- delete(ac, av);
- else if (_substrcmp(*av, "flush") == 0)
- flush(do_force);
- else if (_substrcmp(*av, "zero") == 0)
- zero(ac, av, IP_FW_ZERO);
- else if (_substrcmp(*av, "resetlog") == 0)
- zero(ac, av, IP_FW_RESETLOG);
- else if (_substrcmp(*av, "print") == 0 ||
- _substrcmp(*av, "list") == 0)
- list(ac, av, do_acct);
- else if (_substrcmp(*av, "show") == 0)
- list(ac, av, 1 /* show counters */);
- else
- errx(EX_USAGE, "bad command `%s'", *av);
- }
-
- /* Free memory allocated in the argument parsing. */
- free_args(save_ac, save_av);
- return 0;
-}
-
-
-static void
-ipfw_readfile(int ac, char *av[])
-{
-#define MAX_ARGS 32
- char buf[BUFSIZ];
- char *cmd = NULL, *filename = av[ac-1];
- int c, lineno=0;
- FILE *f = NULL;
- pid_t preproc = 0;
-
- filename = av[ac-1];
-
- while ((c = getopt(ac, av, "cfNnp:qS")) != -1) {
- switch(c) {
- case 'c':
- do_compact = 1;
- break;
-
- case 'f':
- do_force = 1;
- break;
-
- case 'N':
- do_resolv = 1;
- break;
-
- case 'n':
- test_only = 1;
- break;
-
- case 'p':
- cmd = optarg;
- /*
- * Skip previous args and delete last one, so we
- * pass all but the last argument to the preprocessor
- * via av[optind-1]
- */
- av += optind - 1;
- ac -= optind - 1;
- if (ac < 2)
- errx(EX_USAGE, "no filename argument");
- av[ac-1] = NULL;
- fprintf(stderr, "command is %s\n", av[0]);
- break;
-
- case 'q':
- do_quiet = 1;
- break;
-
- case 'S':
- show_sets = 1;
- break;
-
- default:
- errx(EX_USAGE, "bad arguments, for usage"
- " summary ``ipfw''");
- }
-
- if (cmd != NULL)
- break;
- }
-
- if (cmd == NULL && ac != optind + 1) {
- fprintf(stderr, "ac %d, optind %d\n", ac, optind);
- errx(EX_USAGE, "extraneous filename arguments");
- }
-
- if ((f = fopen(filename, "r")) == NULL)
- err(EX_UNAVAILABLE, "fopen: %s", filename);
-
- if (cmd != NULL) { /* pipe through preprocessor */
- int pipedes[2];
-
- if (pipe(pipedes) == -1)
- err(EX_OSERR, "cannot create pipe");
-
- preproc = fork();
- if (preproc == -1)
- err(EX_OSERR, "cannot fork");
-
- if (preproc == 0) {
- /*
- * Child, will run the preprocessor with the
- * file on stdin and the pipe on stdout.
- */
- if (dup2(fileno(f), 0) == -1
- || dup2(pipedes[1], 1) == -1)
- err(EX_OSERR, "dup2()");
- fclose(f);
- close(pipedes[1]);
- close(pipedes[0]);
- execvp(cmd, av);
- err(EX_OSERR, "execvp(%s) failed", cmd);
- } else { /* parent, will reopen f as the pipe */
- fclose(f);
- close(pipedes[1]);
- if ((f = fdopen(pipedes[0], "r")) == NULL) {
- int savederrno = errno;
-
- (void)kill(preproc, SIGTERM);
- errno = savederrno;
- err(EX_OSERR, "fdopen()");
- }
- }
- }
-
- while (fgets(buf, BUFSIZ, f)) { /* read commands */
- char linename[10];
- char *args[1];
-
- lineno++;
- sprintf(linename, "Line %d", lineno);
- setprogname(linename); /* XXX */
- args[0] = buf;
- ipfw_main(1, args);
- }
- fclose(f);
- if (cmd != NULL) {
- int status;
-
- if (waitpid(preproc, &status, 0) == -1)
- errx(EX_OSERR, "waitpid()");
- if (WIFEXITED(status) && WEXITSTATUS(status) != EX_OK)
- errx(EX_UNAVAILABLE,
- "preprocessor exited with status %d",
- WEXITSTATUS(status));
- else if (WIFSIGNALED(status))
- errx(EX_UNAVAILABLE,
- "preprocessor exited with signal %d",
- WTERMSIG(status));
- }
-}
-
-int
-main(int ac, char *av[])
-{
- /*
- * If the last argument is an absolute pathname, interpret it
- * as a file to be preprocessed.
- */
-
- if (ac > 1 && av[ac - 1][0] == '/' && access(av[ac - 1], R_OK) == 0)
- ipfw_readfile(ac, av);
- else {
- if (ipfw_main(ac-1, av+1))
- show_usage();
- }
- return EX_OK;
-}
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
new file mode 100644
index 0000000..442e7b6
--- /dev/null
+++ b/sbin/ipfw/ipfw2.h
@@ -0,0 +1,270 @@
+/*
+ * 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
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Options that can be set on the command line.
+ * When reading commands from a file, a subset of the options can also
+ * be applied globally by specifying them before the file name.
+ * After that, each line can contain its own option that changes
+ * the global value.
+ * XXX The context is not restored after each line.
+ */
+
+struct cmdline_opts {
+ /* boolean options: */
+ int do_value_as_ip; /* show table value as IP */
+ 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_nat; /* this cmd refers to a nat config */
+ int do_dynamic; /* display dynamic rules */
+ int do_expired; /* display expired dynamic rules */
+ int do_compact; /* show rules in compact mode */
+ int do_force; /* do not ask for confirmation */
+ int show_sets; /* display the set each rule belongs to */
+ int test_only; /* only check syntax */
+ int comment_only; /* only print action and comment */
+ int verbose; /* be verbose on some commands */
+
+ /* The options below can have multiple values. */
+
+ int do_sort; /* field to sort results (0 = no) */
+ /* valid fields are 1 and above */
+
+ int use_set; /* work with specified set number */
+ /* 0 means all sets, otherwise apply to set use_set - 1 */
+
+};
+
+extern struct cmdline_opts co;
+
+/*
+ * _s_x is a structure that stores a string <-> token pairs, used in
+ * various places in the parser. Entries are stored in arrays,
+ * with an entry with s=NULL as terminator.
+ * The search routines are match_token() and match_value().
+ * Often, an element with x=0 contains an error string.
+ *
+ */
+struct _s_x {
+ char const *s;
+ int x;
+};
+
+enum tokens {
+ TOK_NULL=0,
+
+ TOK_OR,
+ TOK_NOT,
+ TOK_STARTBRACE,
+ TOK_ENDBRACE,
+
+ TOK_ACCEPT,
+ TOK_COUNT,
+ TOK_PIPE,
+ TOK_QUEUE,
+ TOK_DIVERT,
+ TOK_TEE,
+ TOK_NETGRAPH,
+ TOK_NGTEE,
+ TOK_FORWARD,
+ TOK_SKIPTO,
+ TOK_DENY,
+ TOK_REJECT,
+ TOK_RESET,
+ TOK_UNREACH,
+ TOK_CHECKSTATE,
+ TOK_NAT,
+
+ TOK_ALTQ,
+ TOK_LOG,
+ TOK_TAG,
+ TOK_UNTAG,
+
+ TOK_TAGGED,
+ TOK_UID,
+ TOK_GID,
+ TOK_JAIL,
+ TOK_IN,
+ TOK_LIMIT,
+ TOK_KEEPSTATE,
+ TOK_LAYER2,
+ TOK_OUT,
+ TOK_DIVERTED,
+ TOK_DIVERTEDLOOPBACK,
+ TOK_DIVERTEDOUTPUT,
+ TOK_XMIT,
+ TOK_RECV,
+ TOK_VIA,
+ TOK_FRAG,
+ TOK_IPOPTS,
+ TOK_IPLEN,
+ TOK_IPID,
+ TOK_IPPRECEDENCE,
+ TOK_IPTOS,
+ TOK_IPTTL,
+ TOK_IPVER,
+ TOK_ESTAB,
+ TOK_SETUP,
+ TOK_TCPDATALEN,
+ TOK_TCPFLAGS,
+ TOK_TCPOPTS,
+ TOK_TCPSEQ,
+ TOK_TCPACK,
+ TOK_TCPWIN,
+ TOK_ICMPTYPES,
+ TOK_MAC,
+ TOK_MACTYPE,
+ TOK_VERREVPATH,
+ TOK_VERSRCREACH,
+ TOK_ANTISPOOF,
+ TOK_IPSEC,
+ TOK_COMMENT,
+
+ TOK_PLR,
+ TOK_NOERROR,
+ TOK_BUCKETS,
+ TOK_DSTIP,
+ TOK_SRCIP,
+ TOK_DSTPORT,
+ TOK_SRCPORT,
+ TOK_ALL,
+ TOK_MASK,
+ TOK_BW,
+ TOK_DELAY,
+ TOK_RED,
+ TOK_GRED,
+ TOK_DROPTAIL,
+ TOK_PROTO,
+ TOK_WEIGHT,
+ TOK_IP,
+ TOK_IF,
+ TOK_ALOG,
+ TOK_DENY_INC,
+ TOK_SAME_PORTS,
+ TOK_UNREG_ONLY,
+ TOK_RESET_ADDR,
+ TOK_ALIAS_REV,
+ TOK_PROXY_ONLY,
+ TOK_REDIR_ADDR,
+ TOK_REDIR_PORT,
+ TOK_REDIR_PROTO,
+
+ TOK_IPV6,
+ TOK_FLOWID,
+ TOK_ICMP6TYPES,
+ TOK_EXT6HDR,
+ TOK_DSTIP6,
+ TOK_SRCIP6,
+
+ TOK_IPV4,
+ TOK_UNREACH6,
+ TOK_RESET6,
+
+ TOK_FIB,
+ TOK_SETFIB,
+};
+/*
+ * the following macro returns an error message if we run out of
+ * arguments.
+ */
+#define NEED1(msg) {if (!ac) errx(EX_USAGE, msg);}
+
+unsigned long long align_uint64(const uint64_t *pll);
+
+/* memory allocation support */
+void *safe_calloc(size_t number, size_t size);
+void *safe_realloc(void *ptr, size_t size);
+
+/* string comparison functions used for historical compatibility */
+int _substrcmp(const char *str1, const char* str2);
+int _substrcmp2(const char *str1, const char* str2, const char* str3);
+
+/* utility functions */
+int match_token(struct _s_x *table, char *string);
+char const *match_value(struct _s_x *p, int value);
+
+int do_cmd(int optname, void *optval, uintptr_t optlen);
+
+struct in6_addr;
+void n2mask(struct in6_addr *mask, int n);
+int contigmask(uint8_t *p, int len);
+
+/*
+ * Forward declarations to avoid include way too many headers.
+ * C does not allow duplicated typedefs, so we use the base struct
+ * that the typedef points to.
+ * Should the typedefs use a different type, the compiler will
+ * still detect the change when compiling the body of the
+ * functions involved, so we do not lose error checking.
+ */
+struct _ipfw_insn;
+struct _ipfw_insn_altq;
+struct _ipfw_insn_u32;
+struct _ipfw_insn_ip6;
+struct _ipfw_insn_icmp6;
+
+/*
+ * The reserved set numer. This is a constant in ip_fw.h
+ * but we store it in a variable so other files do not depend
+ * in that header just for one constant.
+ */
+extern int resvd_set_number;
+
+/* first-level command handlers */
+void ipfw_add(int ac, 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_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_flush(int force);
+void ipfw_zero(int ac, char *av[], int optname);
+void ipfw_list(int ac, char *av[], int show_counters);
+
+/* altq.c */
+void altq_set_enabled(int enabled);
+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[]);
+int ipfw_delete_pipe(int pipe_or_queue, int n);
+
+/* ipv6.c */
+void print_unreach6_code(uint16_t code);
+void print_ip6(struct _ipfw_insn_ip6 *cmd, char const *s);
+void print_flow6id(struct _ipfw_insn_u32 *cmd);
+void print_icmp6types(struct _ipfw_insn_u32 *cmd);
+void print_ext6hdr(struct _ipfw_insn *cmd );
+
+struct _ipfw_insn *add_srcip6(struct _ipfw_insn *cmd, char *av);
+struct _ipfw_insn *add_dstip6(struct _ipfw_insn *cmd, char *av);
+
+void fill_flow6(struct _ipfw_insn_u32 *cmd, char *av );
+void fill_unreach6_code(u_short *codep, char *str);
+void fill_icmp6types(struct _ipfw_insn_icmp6 *cmd, char *av);
+int fill_ext6hdr(struct _ipfw_insn *cmd, char *av);
diff --git a/sbin/ipfw/ipv6.c b/sbin/ipfw/ipv6.c
new file mode 100644
index 0000000..40f078b
--- /dev/null
+++ b/sbin/ipfw/ipv6.c
@@ -0,0 +1,501 @@
+/*
+ * 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
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ * $FreeBSD$
+ *
+ * ipv6 support
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "ipfw2.h"
+
+#include <err.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/icmp6.h>
+#include <netinet/ip_fw.h>
+#include <arpa/inet.h>
+
+static struct _s_x icmp6codes[] = {
+ { "no-route", ICMP6_DST_UNREACH_NOROUTE },
+ { "admin-prohib", ICMP6_DST_UNREACH_ADMIN },
+ { "address", ICMP6_DST_UNREACH_ADDR },
+ { "port", ICMP6_DST_UNREACH_NOPORT },
+ { NULL, 0 }
+};
+
+void
+fill_unreach6_code(u_short *codep, char *str)
+{
+ int val;
+ char *s;
+
+ val = strtoul(str, &s, 0);
+ if (s == str || *s != '\0' || val >= 0x100)
+ val = match_token(icmp6codes, str);
+ if (val < 0)
+ errx(EX_DATAERR, "unknown ICMPv6 unreachable code ``%s''", str);
+ *codep = val;
+ return;
+}
+
+void
+print_unreach6_code(uint16_t code)
+{
+ char const *s = match_value(icmp6codes, code);
+
+ if (s != NULL)
+ printf("unreach6 %s", s);
+ else
+ printf("unreach6 %u", code);
+}
+
+/*
+ * Print the ip address contained in a command.
+ */
+void
+print_ip6(ipfw_insn_ip6 *cmd, char const *s)
+{
+ struct hostent *he = NULL;
+ int len = F_LEN((ipfw_insn *) cmd) - 1;
+ struct in6_addr *a = &(cmd->addr6);
+ char trad[255];
+
+ printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
+
+ if (cmd->o.opcode == O_IP6_SRC_ME || cmd->o.opcode == O_IP6_DST_ME) {
+ printf("me6");
+ return;
+ }
+ if (cmd->o.opcode == O_IP6) {
+ printf(" ip6");
+ return;
+ }
+
+ /*
+ * len == 4 indicates a single IP, whereas lists of 1 or more
+ * addr/mask pairs have len = (2n+1). We convert len to n so we
+ * use that to count the number of entries.
+ */
+
+ for (len = len / 4; len > 0; len -= 2, a += 2) {
+ int mb = /* mask length */
+ (cmd->o.opcode == O_IP6_SRC || cmd->o.opcode == O_IP6_DST) ?
+ 128 : contigmask((uint8_t *)&(a[1]), 128);
+
+ if (mb == 128 && co.do_resolv)
+ he = gethostbyaddr((char *)a, sizeof(*a), AF_INET6);
+ if (he != NULL) /* resolved to name */
+ printf("%s", he->h_name);
+ else if (mb == 0) /* any */
+ printf("any");
+ else { /* numeric IP followed by some kind of mask */
+ if (inet_ntop(AF_INET6, a, trad, sizeof( trad ) ) == NULL)
+ printf("Error ntop in print_ip6\n");
+ printf("%s", trad );
+ if (mb < 0) /* XXX not really legal... */
+ printf(":%s",
+ inet_ntop(AF_INET6, &a[1], trad, sizeof(trad)));
+ else if (mb < 128)
+ printf("/%d", mb);
+ }
+ if (len > 2)
+ printf(",");
+ }
+}
+
+void
+fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av)
+{
+ uint8_t type;
+
+ bzero(cmd, sizeof(*cmd));
+ while (*av) {
+ if (*av == ',')
+ av++;
+ type = strtoul(av, &av, 0);
+ if (*av != ',' && *av != '\0')
+ errx(EX_DATAERR, "invalid ICMP6 type");
+ /*
+ * XXX: shouldn't this be 0xFF? I can't see any reason why
+ * we shouldn't be able to filter all possiable values
+ * regardless of the ability of the rest of the kernel to do
+ * anything useful with them.
+ */
+ if (type > ICMP6_MAXTYPE)
+ errx(EX_DATAERR, "ICMP6 type out of range");
+ cmd->d[type / 32] |= ( 1 << (type % 32));
+ }
+ cmd->o.opcode = O_ICMP6TYPE;
+ cmd->o.len |= F_INSN_SIZE(ipfw_insn_icmp6);
+}
+
+
+void
+print_icmp6types(ipfw_insn_u32 *cmd)
+{
+ int i, j;
+ char sep= ' ';
+
+ printf(" ip6 icmp6types");
+ for (i = 0; i < 7; i++)
+ for (j=0; j < 32; ++j) {
+ if ( (cmd->d[i] & (1 << (j))) == 0)
+ continue;
+ printf("%c%d", sep, (i*32 + j));
+ sep = ',';
+ }
+}
+
+void
+print_flow6id( ipfw_insn_u32 *cmd)
+{
+ uint16_t i, limit = cmd->o.arg1;
+ char sep = ',';
+
+ printf(" flow-id ");
+ for( i=0; i < limit; ++i) {
+ if (i == limit - 1)
+ sep = ' ';
+ printf("%d%c", cmd->d[i], sep);
+ }
+}
+
+/* structure and define for the extension header in ipv6 */
+static struct _s_x ext6hdrcodes[] = {
+ { "frag", EXT_FRAGMENT },
+ { "hopopt", EXT_HOPOPTS },
+ { "route", EXT_ROUTING },
+ { "dstopt", EXT_DSTOPTS },
+ { "ah", EXT_AH },
+ { "esp", EXT_ESP },
+ { "rthdr0", EXT_RTHDR0 },
+ { "rthdr2", EXT_RTHDR2 },
+ { NULL, 0 }
+};
+
+/* fills command for the extension header filtering */
+int
+fill_ext6hdr( ipfw_insn *cmd, char *av)
+{
+ int tok;
+ char *s = av;
+
+ cmd->arg1 = 0;
+
+ while(s) {
+ av = strsep( &s, ",") ;
+ tok = match_token(ext6hdrcodes, av);
+ switch (tok) {
+ case EXT_FRAGMENT:
+ cmd->arg1 |= EXT_FRAGMENT;
+ break;
+
+ case EXT_HOPOPTS:
+ cmd->arg1 |= EXT_HOPOPTS;
+ break;
+
+ case EXT_ROUTING:
+ cmd->arg1 |= EXT_ROUTING;
+ break;
+
+ case EXT_DSTOPTS:
+ cmd->arg1 |= EXT_DSTOPTS;
+ break;
+
+ case EXT_AH:
+ cmd->arg1 |= EXT_AH;
+ break;
+
+ case EXT_ESP:
+ cmd->arg1 |= EXT_ESP;
+ break;
+
+ case EXT_RTHDR0:
+ cmd->arg1 |= EXT_RTHDR0;
+ break;
+
+ case EXT_RTHDR2:
+ cmd->arg1 |= EXT_RTHDR2;
+ break;
+
+ default:
+ errx( EX_DATAERR, "invalid option for ipv6 exten header" );
+ break;
+ }
+ }
+ if (cmd->arg1 == 0 )
+ return 0;
+ cmd->opcode = O_EXT_HDR;
+ cmd->len |= F_INSN_SIZE( ipfw_insn );
+ return 1;
+}
+
+void
+print_ext6hdr( ipfw_insn *cmd )
+{
+ char sep = ' ';
+
+ printf(" extension header:");
+ if (cmd->arg1 & EXT_FRAGMENT ) {
+ printf("%cfragmentation", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_HOPOPTS ) {
+ printf("%chop options", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_ROUTING ) {
+ printf("%crouting options", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_RTHDR0 ) {
+ printf("%crthdr0", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_RTHDR2 ) {
+ printf("%crthdr2", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_DSTOPTS ) {
+ printf("%cdestination options", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_AH ) {
+ printf("%cauthentication header", sep);
+ sep = ',';
+ }
+ if (cmd->arg1 & EXT_ESP ) {
+ printf("%cencapsulated security payload", sep);
+ }
+}
+
+/* Try to find ipv6 address by hostname */
+static int
+lookup_host6 (char *host, struct in6_addr *ip6addr)
+{
+ struct hostent *he;
+
+ if (!inet_pton(AF_INET6, host, ip6addr)) {
+ if ((he = gethostbyname2(host, AF_INET6)) == NULL)
+ return(-1);
+ memcpy(ip6addr, he->h_addr_list[0], sizeof( struct in6_addr));
+ }
+ return(0);
+}
+
+
+/*
+ * fill the addr and mask fields in the instruction as appropriate from av.
+ * Update length as appropriate.
+ * The following formats are allowed:
+ * any matches any IP6. Actually returns an empty instruction.
+ * me returns O_IP6_*_ME
+ *
+ * 03f1::234:123:0342 single IP6 addres
+ * 03f1::234:123:0342/24 address/mask
+ * 03f1::234:123:0342/24,03f1::234:123:0343/ List of address
+ *
+ * Set of address (as in ipv6) not supported because ipv6 address
+ * are typically random past the initial prefix.
+ * Return 1 on success, 0 on failure.
+ */
+static int
+fill_ip6(ipfw_insn_ip6 *cmd, char *av)
+{
+ int len = 0;
+ struct in6_addr *d = &(cmd->addr6);
+ /*
+ * Needed for multiple address.
+ * Note d[1] points to struct in6_add r mask6 of cmd
+ */
+
+ cmd->o.len &= ~F_LEN_MASK; /* zero len */
+
+ if (strcmp(av, "any") == 0)
+ return (1);
+
+
+ if (strcmp(av, "me") == 0) { /* Set the data for "me" opt*/
+ cmd->o.len |= F_INSN_SIZE(ipfw_insn);
+ return (1);
+ }
+
+ if (strcmp(av, "me6") == 0) { /* Set the data for "me" opt*/
+ cmd->o.len |= F_INSN_SIZE(ipfw_insn);
+ return (1);
+ }
+
+ av = strdup(av);
+ while (av) {
+ /*
+ * After the address we can have '/' indicating a mask,
+ * or ',' indicating another address follows.
+ */
+
+ char *p;
+ int masklen;
+ char md = '\0';
+
+ if ((p = strpbrk(av, "/,")) ) {
+ md = *p; /* save the separator */
+ *p = '\0'; /* terminate address string */
+ p++; /* and skip past it */
+ }
+ /* now p points to NULL, mask or next entry */
+
+ /* lookup stores address in *d as a side effect */
+ if (lookup_host6(av, d) != 0) {
+ /* XXX: failed. Free memory and go */
+ errx(EX_DATAERR, "bad address \"%s\"", av);
+ }
+ /* next, look at the mask, if any */
+ masklen = (md == '/') ? atoi(p) : 128;
+ if (masklen > 128 || masklen < 0)
+ errx(EX_DATAERR, "bad width \"%s\''", p);
+ else
+ n2mask(&d[1], masklen);
+
+ APPLY_MASK(d, &d[1]) /* mask base address with mask */
+
+ /* find next separator */
+
+ if (md == '/') { /* find separator past the mask */
+ p = strpbrk(p, ",");
+ if (p != NULL)
+ p++;
+ }
+ av = p;
+
+ /* Check this entry */
+ if (masklen == 0) {
+ /*
+ * 'any' turns the entire list into a NOP.
+ * 'not any' never matches, so it is removed from the
+ * list unless it is the only item, in which case we
+ * report an error.
+ */
+ if (cmd->o.len & F_NOT && av == NULL && len == 0)
+ errx(EX_DATAERR, "not any never matches");
+ continue;
+ }
+
+ /*
+ * A single IP can be stored alone
+ */
+ if (masklen == 128 && av == NULL && len == 0) {
+ len = F_INSN_SIZE(struct in6_addr);
+ break;
+ }
+
+ /* Update length and pointer to arguments */
+ len += F_INSN_SIZE(struct in6_addr)*2;
+ d += 2;
+ } /* end while */
+
+ /*
+ * Total length of the command, remember that 1 is the size of
+ * the base command.
+ */
+ if (len + 1 > F_LEN_MASK)
+ errx(EX_DATAERR, "address list too long");
+ cmd->o.len |= len+1;
+ free(av);
+ return (1);
+}
+
+/*
+ * fills command for ipv6 flow-id filtering
+ * note that the 20 bit flow number is stored in a array of u_int32_t
+ * it's supported lists of flow-id, so in the o.arg1 we store how many
+ * additional flow-id we want to filter, the basic is 1
+ */
+void
+fill_flow6( ipfw_insn_u32 *cmd, char *av )
+{
+ u_int32_t type; /* Current flow number */
+ u_int16_t nflow = 0; /* Current flow index */
+ char *s = av;
+ cmd->d[0] = 0; /* Initializing the base number*/
+
+ while (s) {
+ av = strsep( &s, ",") ;
+ type = strtoul(av, &av, 0);
+ if (*av != ',' && *av != '\0')
+ errx(EX_DATAERR, "invalid ipv6 flow number %s", av);
+ if (type > 0xfffff)
+ errx(EX_DATAERR, "flow number out of range %s", av);
+ cmd->d[nflow] |= type;
+ nflow++;
+ }
+ if( nflow > 0 ) {
+ cmd->o.opcode = O_FLOW6ID;
+ cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32) + nflow;
+ cmd->o.arg1 = nflow;
+ }
+ else {
+ errx(EX_DATAERR, "invalid ipv6 flow number %s", av);
+ }
+}
+
+ipfw_insn *
+add_srcip6(ipfw_insn *cmd, char *av)
+{
+
+ fill_ip6((ipfw_insn_ip6 *)cmd, av);
+ if (F_LEN(cmd) == 0) { /* any */
+ } else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) { /* "me" */
+ cmd->opcode = O_IP6_SRC_ME;
+ } else if (F_LEN(cmd) ==
+ (F_INSN_SIZE(struct in6_addr) + F_INSN_SIZE(ipfw_insn))) {
+ /* single IP, no mask*/
+ cmd->opcode = O_IP6_SRC;
+ } else { /* addr/mask opt */
+ cmd->opcode = O_IP6_SRC_MASK;
+ }
+ return cmd;
+}
+
+ipfw_insn *
+add_dstip6(ipfw_insn *cmd, char *av)
+{
+
+ fill_ip6((ipfw_insn_ip6 *)cmd, av);
+ if (F_LEN(cmd) == 0) { /* any */
+ } else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) { /* "me" */
+ cmd->opcode = O_IP6_DST_ME;
+ } else if (F_LEN(cmd) ==
+ (F_INSN_SIZE(struct in6_addr) + F_INSN_SIZE(ipfw_insn))) {
+ /* single IP, no mask*/
+ cmd->opcode = O_IP6_DST;
+ } else { /* addr/mask opt */
+ cmd->opcode = O_IP6_DST_MASK;
+ }
+ return cmd;
+}
diff --git a/sbin/ipfw/main.c b/sbin/ipfw/main.c
new file mode 100644
index 0000000..5cb5a42
--- /dev/null
+++ b/sbin/ipfw/main.c
@@ -0,0 +1,539 @@
+/*
+ * 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
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * Command line interface for IP firewall facility
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/wait.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "ipfw2.h"
+
+static void
+help(void)
+{
+ fprintf(stderr,
+"ipfw syntax summary (but please do read the ipfw(8) manpage):\n\n"
+"\tipfw [-abcdefhnNqStTv] <command>\n\n"
+"where <command> is one of the following:\n\n"
+"add [num] [set N] [prob x] RULE-BODY\n"
+"{pipe|queue} N config PIPE-BODY\n"
+"[pipe|queue] {zero|delete|show} [N{,N}]\n"
+"nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|reset|\n"
+" reverse|proxy_only|redirect_addr linkspec|\n"
+" redirect_port linkspec|redirect_proto linkspec}\n"
+"set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n"
+"set N {show|list|zero|resetlog|delete} [N{,N}] | flush\n"
+"table N {add ip[/bits] [value] | delete ip[/bits] | flush | list}\n"
+"table all {flush | list}\n"
+"\n"
+"RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n"
+"ACTION: check-state | allow | count | deny | unreach{,6} CODE |\n"
+" skipto N | {divert|tee} PORT | forward ADDR |\n"
+" pipe N | queue N | nat N | setfib FIB\n"
+"PARAMS: [log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n"
+"ADDR: [ MAC dst src ether_type ] \n"
+" [ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
+" [ ipv6|ip6 from IP6ADDR [ PORT ] to IP6ADDR [ PORTLIST ] ]\n"
+"IPADDR: [not] { any | me | ip/bits{x,y,z} | table(t[,v]) | IPLIST }\n"
+"IP6ADDR: [not] { any | me | me6 | ip6/bits | IP6LIST }\n"
+"IP6LIST: { ip6 | ip6/bits }[,IP6LIST]\n"
+"IPLIST: { ip | ip/bits | ip:mask }[,IPLIST]\n"
+"OPTION_LIST: OPTION [OPTION_LIST]\n"
+"OPTION: bridged | diverted | diverted-loopback | diverted-output |\n"
+" {dst-ip|src-ip} IPADDR | {dst-ip6|src-ip6|dst-ipv6|src-ipv6} IP6ADDR |\n"
+" {dst-port|src-port} LIST |\n"
+" estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n"
+" iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n"
+" ipttl LIST | ipversion VER | keep-state | layer2 | limit ... |\n"
+" icmp6types LIST | ext6hdr LIST | flow-id N[,N] | fib FIB |\n"
+" mac ... | mac-type LIST | proto LIST | {recv|xmit|via} {IF|IPADDR} |\n"
+" setup | {tcpack|tcpseq|tcpwin} NN | tcpflags SPEC | tcpoptions SPEC |\n"
+" tcpdatalen LIST | verrevpath | versrcreach | antispoof\n"
+);
+
+ exit(0);
+}
+
+/*
+ * 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.
+ */
+static int
+ipfw_main(int oldac, char **oldav)
+{
+ int ch, ac, save_ac;
+ const char *errstr;
+ char **av, **save_av;
+ int do_acct = 0; /* Show packet/byte count */
+
+#define WHITESP " \t\f\v\n\r"
+ if (oldac < 2)
+ return 1; /* need at least one argument */
+
+ 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.
+ */
+ char *arg = oldav[1]; /* The string is the first arg. */
+ int l = strlen(arg);
+ int copy = 0; /* 1 if we need to copy, 0 otherwise */
+ int i, j;
+
+ for (i = j = 0; i < l; i++) {
+ if (arg[i] == '#') /* comment marker */
+ break;
+ if (copy) {
+ arg[j++] = arg[i];
+ copy = !index("," WHITESP, arg[i]);
+ } else {
+ copy = !index(WHITESP, arg[i]);
+ if (copy)
+ arg[j++] = arg[i];
+ }
+ }
+ if (!copy && j > 0) /* last char was a 'blank', remove it */
+ j--;
+ l = j; /* the new argument length */
+ arg[j++] = '\0';
+ if (l == 0) /* empty string! */
+ return 1;
+
+ /*
+ * First, count number of arguments. Because of the previous
+ * processing, this is just the number of blanks plus 1.
+ */
+ for (i = 0, ac = 1; i < l; i++)
+ if (index(WHITESP, arg[i]) != NULL)
+ ac++;
+
+ /*
+ * Allocate the argument list, including one entry for
+ * the program name because getopt expects it.
+ */
+ av = safe_calloc(ac + 1, sizeof(char *));
+
+ /*
+ * Second, 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++)
+ 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);
+ ac++;
+ j = i + 1;
+ }
+ } else {
+ /*
+ * If an argument ends with ',' join with the next one.
+ */
+ int first, i, l;
+
+ av = safe_calloc(oldac, sizeof(char *));
+ for (first = i = ac = 1, l = 0; i < oldac; i++) {
+ char *arg = oldav[i];
+ int k = strlen(arg);
+
+ l += k;
+ if (arg[k-1] != ',' || i == oldac-1) {
+ /* Time to copy. */
+ av[ac] = safe_calloc(l+1, 1);
+ for (l=0; first <= i; first++) {
+ strcat(av[ac]+l, oldav[first]);
+ l += strlen(oldav[first]);
+ }
+ ac++;
+ l = 0;
+ first = i+1;
+ }
+ }
+ }
+
+ av[0] = strdup(oldav[0]); /* copy progname from the caller */
+ /* Set the force flag for non-interactive processes */
+ if (!co.do_force)
+ co.do_force = !isatty(STDIN_FILENO);
+
+ /* Save arguments for final freeing of memory. */
+ save_ac = ac;
+ save_av = av;
+
+ optind = optreset = 1; /* restart getopt() */
+ while ((ch = getopt(ac, av, "abcdefhinNqs:STtv")) != -1)
+ switch (ch) {
+ case 'a':
+ do_acct = 1;
+ break;
+
+ case 'b':
+ co.comment_only = 1;
+ co.do_compact = 1;
+ break;
+
+ case 'c':
+ co.do_compact = 1;
+ break;
+
+ case 'd':
+ co.do_dynamic = 1;
+ break;
+
+ case 'e':
+ co.do_expired = 1;
+ break;
+
+ case 'f':
+ co.do_force = 1;
+ break;
+
+ case 'h': /* help */
+ free_args(save_ac, save_av);
+ help();
+ break; /* NOTREACHED */
+
+ case 'i':
+ co.do_value_as_ip = 1;
+ break;
+
+ case 'n':
+ co.test_only = 1;
+ break;
+
+ case 'N':
+ co.do_resolv = 1;
+ break;
+
+ case 'q':
+ co.do_quiet = 1;
+ break;
+
+ case 's': /* sort */
+ co.do_sort = atoi(optarg);
+ break;
+
+ case 'S':
+ co.show_sets = 1;
+ break;
+
+ case 't':
+ co.do_time = 1;
+ break;
+
+ case 'T':
+ co.do_time = 2; /* numeric timestamp */
+ break;
+
+ case 'v': /* verbose */
+ co.verbose = 1;
+ break;
+
+ default:
+ free_args(save_ac, save_av);
+ return 1;
+ }
+
+ ac -= optind;
+ av += optind;
+ NEED1("bad arguments, for usage summary ``ipfw''");
+
+ /*
+ * An undocumented behaviour of ipfw1 was to allow rule numbers first,
+ * e.g. "100 add allow ..." instead of "add 100 allow ...".
+ * In case, swap first and second argument to get the normal form.
+ */
+ if (ac > 1 && isdigit(*av[0])) {
+ char *p = av[0];
+
+ av[0] = av[1];
+ av[1] = p;
+ }
+
+ /*
+ * Optional: pipe, queue or nat.
+ */
+ co.do_nat = 0;
+ co.do_pipe = 0;
+ if (!strncmp(*av, "nat", strlen(*av)))
+ co.do_nat = 1;
+ else if (!strncmp(*av, "pipe", strlen(*av)))
+ co.do_pipe = 1;
+ else if (_substrcmp(*av, "queue") == 0)
+ co.do_pipe = 2;
+ else if (!strncmp(*av, "set", strlen(*av))) {
+ if (ac > 1 && isdigit(av[1][0])) {
+ co.use_set = strtonum(av[1], 0, resvd_set_number,
+ &errstr);
+ if (errstr)
+ errx(EX_DATAERR,
+ "invalid set number %s\n", av[1]);
+ ac -= 2; av += 2; co.use_set++;
+ }
+ }
+
+ if (co.do_pipe || co.do_nat) {
+ ac--;
+ av++;
+ }
+ NEED1("missing command");
+
+ /*
+ * For pipes, queues and nats we normally say 'nat|pipe NN config'
+ * but the code is easier to parse as 'nat|pipe config NN'
+ * so we swap the two arguments.
+ */
+ if ((co.do_pipe || co.do_nat) && ac > 1 && isdigit(*av[0])) {
+ char *p = av[0];
+
+ av[0] = av[1];
+ av[1] = p;
+ }
+
+ int try_next = 0;
+ if (co.use_set == 0) {
+ if (_substrcmp(*av, "add") == 0)
+ ipfw_add(ac, av);
+ else if (co.do_nat && _substrcmp(*av, "show") == 0)
+ ipfw_show_nat(ac, av);
+ else if (co.do_pipe && _substrcmp(*av, "config") == 0)
+ ipfw_config_pipe(ac, av);
+ 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);
+ else if (_substrcmp(*av, "table") == 0)
+ ipfw_table_handler(ac, av);
+ else if (_substrcmp(*av, "enable") == 0)
+ ipfw_sysctl_handler(ac, av, 1);
+ else if (_substrcmp(*av, "disable") == 0)
+ ipfw_sysctl_handler(ac, av, 0);
+ else
+ try_next = 1;
+ }
+
+ if (co.use_set || try_next) {
+ if (_substrcmp(*av, "delete") == 0)
+ ipfw_delete(ac, av);
+ else if (_substrcmp(*av, "flush") == 0)
+ ipfw_flush(co.do_force);
+ else if (_substrcmp(*av, "zero") == 0)
+ ipfw_zero(ac, av, 0 /* IP_FW_ZERO */);
+ else if (_substrcmp(*av, "resetlog") == 0)
+ ipfw_zero(ac, av, 1 /* IP_FW_RESETLOG */);
+ else if (_substrcmp(*av, "print") == 0 ||
+ _substrcmp(*av, "list") == 0)
+ ipfw_list(ac, av, do_acct);
+ else if (_substrcmp(*av, "show") == 0)
+ ipfw_list(ac, av, 1 /* show counters */);
+ else
+ errx(EX_USAGE, "bad command `%s'", *av);
+ }
+
+ /* Free memory allocated in the argument parsing. */
+ free_args(save_ac, save_av);
+ return 0;
+}
+
+
+static void
+ipfw_readfile(int ac, char *av[])
+{
+#define MAX_ARGS 32
+ char buf[BUFSIZ];
+ char *progname = av[0]; /* original program name */
+ const char *cmd = NULL; /* preprocessor name, if any */
+ const char *filename = av[ac-1]; /* file to read */
+ int c, lineno=0;
+ FILE *f = NULL;
+ pid_t preproc = 0;
+
+ while ((c = getopt(ac, av, "cfNnp:qS")) != -1) {
+ switch(c) {
+ case 'c':
+ co.do_compact = 1;
+ break;
+
+ case 'f':
+ co.do_force = 1;
+ break;
+
+ case 'N':
+ co.do_resolv = 1;
+ break;
+
+ case 'n':
+ co.test_only = 1;
+ break;
+
+ case 'p':
+ /*
+ * ipfw -p cmd [args] filename
+ *
+ * We are done with getopt(). All arguments
+ * except the filename go to the preprocessor,
+ * so we need to do the following:
+ * - check that a filename is actually present;
+ * - advance av by optind-1 to skip arguments
+ * already processed;
+ * - decrease ac by optind, to remove the args
+ * already processed and the final filename;
+ * - set the last entry in av[] to NULL so
+ * popen() can detect the end of the array;
+ * - set optind=ac to let getopt() terminate.
+ */
+ if (optind == ac)
+ errx(EX_USAGE, "no filename argument");
+ cmd = optarg;
+ av[ac-1] = NULL;
+ av += optind - 1;
+ ac -= optind;
+ optind = ac;
+ break;
+
+ case 'q':
+ co.do_quiet = 1;
+ break;
+
+ case 'S':
+ co.show_sets = 1;
+ break;
+
+ default:
+ errx(EX_USAGE, "bad arguments, for usage"
+ " summary ``ipfw''");
+ }
+
+ }
+
+ if (cmd == NULL && ac != optind + 1)
+ errx(EX_USAGE, "extraneous filename arguments %s", av[ac-1]);
+
+ if ((f = fopen(filename, "r")) == NULL)
+ err(EX_UNAVAILABLE, "fopen: %s", filename);
+
+ if (cmd != NULL) { /* pipe through preprocessor */
+ int pipedes[2];
+
+ if (pipe(pipedes) == -1)
+ err(EX_OSERR, "cannot create pipe");
+
+ preproc = fork();
+ if (preproc == -1)
+ err(EX_OSERR, "cannot fork");
+
+ if (preproc == 0) {
+ /*
+ * Child, will run the preprocessor with the
+ * file on stdin and the pipe on stdout.
+ */
+ if (dup2(fileno(f), 0) == -1
+ || dup2(pipedes[1], 1) == -1)
+ err(EX_OSERR, "dup2()");
+ fclose(f);
+ close(pipedes[1]);
+ close(pipedes[0]);
+ execvp(cmd, av);
+ err(EX_OSERR, "execvp(%s) failed", cmd);
+ } else { /* parent, will reopen f as the pipe */
+ fclose(f);
+ close(pipedes[1]);
+ if ((f = fdopen(pipedes[0], "r")) == NULL) {
+ int savederrno = errno;
+
+ (void)kill(preproc, SIGTERM);
+ errno = savederrno;
+ err(EX_OSERR, "fdopen()");
+ }
+ }
+ }
+
+ while (fgets(buf, BUFSIZ, f)) { /* read commands */
+ char linename[10];
+ char *args[2];
+
+ lineno++;
+ sprintf(linename, "Line %d", lineno);
+ setprogname(linename); /* XXX */
+ args[0] = progname;
+ args[1] = buf;
+ ipfw_main(2, args);
+ }
+ fclose(f);
+ if (cmd != NULL) {
+ int status;
+
+ if (waitpid(preproc, &status, 0) == -1)
+ errx(EX_OSERR, "waitpid()");
+ if (WIFEXITED(status) && WEXITSTATUS(status) != EX_OK)
+ errx(EX_UNAVAILABLE,
+ "preprocessor exited with status %d",
+ WEXITSTATUS(status));
+ else if (WIFSIGNALED(status))
+ errx(EX_UNAVAILABLE,
+ "preprocessor exited with signal %d",
+ WTERMSIG(status));
+ }
+}
+
+int
+main(int ac, char *av[])
+{
+ /*
+ * If the last argument is an absolute pathname, interpret it
+ * as a file to be preprocessed.
+ */
+
+ if (ac > 1 && av[ac - 1][0] == '/' && access(av[ac - 1], R_OK) == 0)
+ ipfw_readfile(ac, av);
+ else {
+ if (ipfw_main(ac, av)) {
+ errx(EX_USAGE,
+ "usage: ipfw [options]\n"
+ "do \"ipfw -h\" or \"man ipfw\" for details");
+ }
+ }
+ return EX_OK;
+}
diff --git a/sbin/ipfw/nat.c b/sbin/ipfw/nat.c
new file mode 100644
index 0000000..bfc325a
--- /dev/null
+++ b/sbin/ipfw/nat.c
@@ -0,0 +1,940 @@
+/*
+ * 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
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * Redistribution in binary form may occur without any restrictions.
+ * Obviously, it would be nice if you gave credit where credit is due
+ * but requiring it would be too onerous.
+ *
+ * This software is provided ``AS IS'' without any warranties of any kind.
+ *
+ * NEW command line interface for IP firewall facility
+ *
+ * $FreeBSD$
+ *
+ * In-kernel nat support
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include "ipfw2.h"
+
+#include <ctype.h>
+#include <err.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#define IPFW_INTERNAL /* Access to protected structures in ip_fw.h. */
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h> /* def. of struct route */
+#include <netinet/in.h>
+#include <netinet/ip_fw.h>
+#include <arpa/inet.h>
+#include <alias.h>
+
+static struct _s_x nat_params[] = {
+ { "ip", TOK_IP },
+ { "if", TOK_IF },
+ { "log", TOK_ALOG },
+ { "deny_in", TOK_DENY_INC },
+ { "same_ports", TOK_SAME_PORTS },
+ { "unreg_only", TOK_UNREG_ONLY },
+ { "reset", TOK_RESET_ADDR },
+ { "reverse", TOK_ALIAS_REV },
+ { "proxy_only", TOK_PROXY_ONLY },
+ { "redirect_addr", TOK_REDIR_ADDR },
+ { "redirect_port", TOK_REDIR_PORT },
+ { "redirect_proto", TOK_REDIR_PROTO },
+ { NULL, 0 } /* terminator */
+};
+
+
+/*
+ * Search for interface with name "ifn", and fill n accordingly:
+ *
+ * n->ip ip address of interface "ifn"
+ * n->if_name copy of interface name "ifn"
+ */
+static void
+set_addr_dynamic(const char *ifn, struct cfg_nat *n)
+{
+ size_t needed;
+ int mib[6];
+ char *buf, *lim, *next;
+ struct if_msghdr *ifm;
+ struct ifa_msghdr *ifam;
+ struct sockaddr_dl *sdl;
+ struct sockaddr_in *sin;
+ int ifIndex, ifMTU;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = AF_INET;
+ mib[4] = NET_RT_IFLIST;
+ mib[5] = 0;
+/*
+ * Get interface data.
+ */
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
+ err(1, "iflist-sysctl-estimate");
+ buf = safe_calloc(1, needed);
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
+ err(1, "iflist-sysctl-get");
+ lim = buf + needed;
+/*
+ * Loop through interfaces until one with
+ * given name is found. This is done to
+ * find correct interface index for routing
+ * message processing.
+ */
+ ifIndex = 0;
+ next = buf;
+ while (next < lim) {
+ ifm = (struct if_msghdr *)next;
+ next += ifm->ifm_msglen;
+ if (ifm->ifm_version != RTM_VERSION) {
+ if (co.verbose)
+ warnx("routing message version %d "
+ "not understood", ifm->ifm_version);
+ continue;
+ }
+ if (ifm->ifm_type == RTM_IFINFO) {
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ if (strlen(ifn) == sdl->sdl_nlen &&
+ strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) {
+ ifIndex = ifm->ifm_index;
+ ifMTU = ifm->ifm_data.ifi_mtu;
+ break;
+ }
+ }
+ }
+ if (!ifIndex)
+ errx(1, "unknown interface name %s", ifn);
+/*
+ * Get interface address.
+ */
+ sin = NULL;
+ while (next < lim) {
+ ifam = (struct ifa_msghdr *)next;
+ next += ifam->ifam_msglen;
+ if (ifam->ifam_version != RTM_VERSION) {
+ if (co.verbose)
+ warnx("routing message version %d "
+ "not understood", ifam->ifam_version);
+ continue;
+ }
+ if (ifam->ifam_type != RTM_NEWADDR)
+ break;
+ if (ifam->ifam_addrs & RTA_IFA) {
+ int i;
+ char *cp = (char *)(ifam + 1);
+
+ for (i = 1; i < RTA_IFA; i <<= 1) {
+ if (ifam->ifam_addrs & i)
+ cp += SA_SIZE((struct sockaddr *)cp);
+ }
+ if (((struct sockaddr *)cp)->sa_family == AF_INET) {
+ sin = (struct sockaddr_in *)cp;
+ break;
+ }
+ }
+ }
+ if (sin == NULL)
+ errx(1, "%s: cannot get interface address", ifn);
+
+ n->ip = sin->sin_addr;
+ strncpy(n->if_name, ifn, IF_NAMESIZE);
+
+ free(buf);
+}
+
+/*
+ * XXX - The following functions, macros and definitions come from natd.c:
+ * it would be better to move them outside natd.c, in a file
+ * (redirect_support.[ch]?) shared by ipfw and natd, but for now i can live
+ * with it.
+ */
+
+/*
+ * Definition of a port range, and macros to deal with values.
+ * FORMAT: HI 16-bits == first port in range, 0 == all ports.
+ * LO 16-bits == number of ports in range
+ * NOTES: - Port values are not stored in network byte order.
+ */
+
+#define port_range u_long
+
+#define GETLOPORT(x) ((x) >> 0x10)
+#define GETNUMPORTS(x) ((x) & 0x0000ffff)
+#define GETHIPORT(x) (GETLOPORT((x)) + GETNUMPORTS((x)))
+
+/* Set y to be the low-port value in port_range variable x. */
+#define SETLOPORT(x,y) ((x) = ((x) & 0x0000ffff) | ((y) << 0x10))
+
+/* Set y to be the number of ports in port_range variable x. */
+#define SETNUMPORTS(x,y) ((x) = ((x) & 0xffff0000) | (y))
+
+static void
+StrToAddr (const char* str, struct in_addr* addr)
+{
+ struct hostent* hp;
+
+ if (inet_aton (str, addr))
+ return;
+
+ hp = gethostbyname (str);
+ if (!hp)
+ errx (1, "unknown host %s", str);
+
+ memcpy (addr, hp->h_addr, sizeof (struct in_addr));
+}
+
+static int
+StrToPortRange (const char* str, const char* proto, port_range *portRange)
+{
+ char* sep;
+ struct servent* sp;
+ char* end;
+ u_short loPort;
+ u_short hiPort;
+
+ /* First see if this is a service, return corresponding port if so. */
+ sp = getservbyname (str,proto);
+ if (sp) {
+ SETLOPORT(*portRange, ntohs(sp->s_port));
+ SETNUMPORTS(*portRange, 1);
+ return 0;
+ }
+
+ /* Not a service, see if it's a single port or port range. */
+ sep = strchr (str, '-');
+ if (sep == NULL) {
+ SETLOPORT(*portRange, strtol(str, &end, 10));
+ if (end != str) {
+ /* Single port. */
+ SETNUMPORTS(*portRange, 1);
+ return 0;
+ }
+
+ /* Error in port range field. */
+ errx (EX_DATAERR, "%s/%s: unknown service", str, proto);
+ }
+
+ /* Port range, get the values and sanity check. */
+ sscanf (str, "%hu-%hu", &loPort, &hiPort);
+ SETLOPORT(*portRange, loPort);
+ SETNUMPORTS(*portRange, 0); /* Error by default */
+ if (loPort <= hiPort)
+ SETNUMPORTS(*portRange, hiPort - loPort + 1);
+
+ if (GETNUMPORTS(*portRange) == 0)
+ errx (EX_DATAERR, "invalid port range %s", str);
+
+ return 0;
+}
+
+static int
+StrToProto (const char* str)
+{
+ if (!strcmp (str, "tcp"))
+ return IPPROTO_TCP;
+
+ if (!strcmp (str, "udp"))
+ return IPPROTO_UDP;
+
+ if (!strcmp (str, "sctp"))
+ return IPPROTO_SCTP;
+ errx (EX_DATAERR, "unknown protocol %s. Expected sctp, tcp or udp", str);
+}
+
+static int
+StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto,
+ port_range *portRange)
+{
+ char* ptr;
+
+ ptr = strchr (str, ':');
+ if (!ptr)
+ errx (EX_DATAERR, "%s is missing port number", str);
+
+ *ptr = '\0';
+ ++ptr;
+
+ StrToAddr (str, addr);
+ return StrToPortRange (ptr, proto, portRange);
+}
+
+/* End of stuff taken from natd.c. */
+
+#define INC_ARGCV() do { \
+ (*_av)++; \
+ (*_ac)--; \
+ av = *_av; \
+ ac = *_ac; \
+} while(0)
+
+/*
+ * The next 3 functions add support for the addr, port and proto redirect and
+ * their logic is loosely based on SetupAddressRedirect(), SetupPortRedirect()
+ * and SetupProtoRedirect() from natd.c.
+ *
+ * Every setup_* function fills at least one redirect entry
+ * (struct cfg_redir) and zero or more server pool entry (struct cfg_spool)
+ * in buf.
+ *
+ * The format of data in buf is:
+ *
+ *
+ * cfg_nat cfg_redir cfg_spool ...... cfg_spool
+ *
+ * ------------------------------------- ------------
+ * | | .....X ... | | | | .....
+ * ------------------------------------- ...... ------------
+ * ^
+ * spool_cnt n=0 ...... n=(X-1)
+ *
+ * len points to the amount of available space in buf
+ * space counts the memory consumed by every function
+ *
+ * XXX - Every function get all the argv params so it
+ * has to check, in optional parameters, that the next
+ * args is a valid option for the redir entry and not
+ * another token. Only redir_port and redir_proto are
+ * affected by this.
+ */
+
+static int
+setup_redir_addr(char *spool_buf, int len,
+ int *_ac, char ***_av)
+{
+ char **av, *sep; /* Token separator. */
+ /* Temporary buffer used to hold server pool ip's. */
+ char tmp_spool_buf[NAT_BUF_LEN];
+ int ac, space, lsnat;
+ struct cfg_redir *r;
+ struct cfg_spool *tmp;
+
+ av = *_av;
+ ac = *_ac;
+ space = 0;
+ lsnat = 0;
+ if (len >= SOF_REDIR) {
+ r = (struct cfg_redir *)spool_buf;
+ /* Skip cfg_redir at beginning of buf. */
+ spool_buf = &spool_buf[SOF_REDIR];
+ space = SOF_REDIR;
+ len -= SOF_REDIR;
+ } else
+ goto nospace;
+ r->mode = REDIR_ADDR;
+ /* Extract local address. */
+ if (ac == 0)
+ errx(EX_DATAERR, "redirect_addr: missing local address");
+ sep = strchr(*av, ',');
+ if (sep) { /* LSNAT redirection syntax. */
+ r->laddr.s_addr = INADDR_NONE;
+ /* Preserve av, copy spool servers to tmp_spool_buf. */
+ strncpy(tmp_spool_buf, *av, strlen(*av)+1);
+ lsnat = 1;
+ } else
+ StrToAddr(*av, &r->laddr);
+ INC_ARGCV();
+
+ /* Extract public address. */
+ if (ac == 0)
+ errx(EX_DATAERR, "redirect_addr: missing public address");
+ StrToAddr(*av, &r->paddr);
+ INC_ARGCV();
+
+ /* Setup LSNAT server pool. */
+ if (sep) {
+ sep = strtok(tmp_spool_buf, ",");
+ while (sep != NULL) {
+ tmp = (struct cfg_spool *)spool_buf;
+ if (len < SOF_SPOOL)
+ goto nospace;
+ len -= SOF_SPOOL;
+ space += SOF_SPOOL;
+ StrToAddr(sep, &tmp->addr);
+ tmp->port = ~0;
+ r->spool_cnt++;
+ /* Point to the next possible cfg_spool. */
+ spool_buf = &spool_buf[SOF_SPOOL];
+ sep = strtok(NULL, ",");
+ }
+ }
+ return(space);
+nospace:
+ errx(EX_DATAERR, "redirect_addr: buf is too small\n");
+}
+
+static int
+setup_redir_port(char *spool_buf, int len,
+ int *_ac, char ***_av)
+{
+ char **av, *sep, *protoName;
+ char tmp_spool_buf[NAT_BUF_LEN];
+ int ac, space, lsnat;
+ struct cfg_redir *r;
+ struct cfg_spool *tmp;
+ u_short numLocalPorts;
+ port_range portRange;
+
+ av = *_av;
+ ac = *_ac;
+ space = 0;
+ lsnat = 0;
+ numLocalPorts = 0;
+
+ if (len >= SOF_REDIR) {
+ r = (struct cfg_redir *)spool_buf;
+ /* Skip cfg_redir at beginning of buf. */
+ spool_buf = &spool_buf[SOF_REDIR];
+ space = SOF_REDIR;
+ len -= SOF_REDIR;
+ } else
+ goto nospace;
+ r->mode = REDIR_PORT;
+ /*
+ * Extract protocol.
+ */
+ if (ac == 0)
+ errx (EX_DATAERR, "redirect_port: missing protocol");
+ r->proto = StrToProto(*av);
+ protoName = *av;
+ INC_ARGCV();
+
+ /*
+ * Extract local address.
+ */
+ if (ac == 0)
+ errx (EX_DATAERR, "redirect_port: missing local address");
+
+ sep = strchr(*av, ',');
+ /* LSNAT redirection syntax. */
+ if (sep) {
+ r->laddr.s_addr = INADDR_NONE;
+ r->lport = ~0;
+ numLocalPorts = 1;
+ /* Preserve av, copy spool servers to tmp_spool_buf. */
+ strncpy(tmp_spool_buf, *av, strlen(*av)+1);
+ lsnat = 1;
+ } else {
+ /*
+ * The sctp nat does not allow the port numbers to be mapped to
+ * new port numbers. Therefore, no ports are to be specified
+ * in the target port field.
+ */
+ if (r->proto == IPPROTO_SCTP) {
+ if (strchr (*av, ':'))
+ errx(EX_DATAERR, "redirect_port:"
+ "port numbers do not change in sctp, so do not "
+ "specify them as part of the target");
+ else
+ StrToAddr(*av, &r->laddr);
+ } else {
+ if (StrToAddrAndPortRange (*av, &r->laddr, protoName,
+ &portRange) != 0)
+ errx(EX_DATAERR, "redirect_port:"
+ "invalid local port range");
+
+ r->lport = GETLOPORT(portRange);
+ numLocalPorts = GETNUMPORTS(portRange);
+ }
+ }
+ INC_ARGCV();
+
+ /*
+ * Extract public port and optionally address.
+ */
+ if (ac == 0)
+ errx (EX_DATAERR, "redirect_port: missing public port");
+
+ sep = strchr (*av, ':');
+ if (sep) {
+ if (StrToAddrAndPortRange (*av, &r->paddr, protoName,
+ &portRange) != 0)
+ errx(EX_DATAERR, "redirect_port:"
+ "invalid public port range");
+ } else {
+ r->paddr.s_addr = INADDR_ANY;
+ if (StrToPortRange (*av, protoName, &portRange) != 0)
+ errx(EX_DATAERR, "redirect_port:"
+ "invalid public port range");
+ }
+
+ r->pport = GETLOPORT(portRange);
+ if (r->proto == IPPROTO_SCTP) { /* so the logic below still works */
+ numLocalPorts = GETNUMPORTS(portRange);
+ r->lport = r->pport;
+ }
+ r->pport_cnt = GETNUMPORTS(portRange);
+ INC_ARGCV();
+
+ /*
+ * Extract remote address and optionally port.
+ */
+ /*
+ * NB: isalpha(**av) => we've to check that next parameter is really an
+ * option for this redirect entry, else stop here processing arg[cv].
+ */
+ if (ac != 0 && !isalpha(**av)) {
+ sep = strchr (*av, ':');
+ if (sep) {
+ if (StrToAddrAndPortRange (*av, &r->raddr, protoName,
+ &portRange) != 0)
+ errx(EX_DATAERR, "redirect_port:"
+ "invalid remote port range");
+ } else {
+ SETLOPORT(portRange, 0);
+ SETNUMPORTS(portRange, 1);
+ StrToAddr (*av, &r->raddr);
+ }
+ INC_ARGCV();
+ } else {
+ SETLOPORT(portRange, 0);
+ SETNUMPORTS(portRange, 1);
+ r->raddr.s_addr = INADDR_ANY;
+ }
+ r->rport = GETLOPORT(portRange);
+ r->rport_cnt = GETNUMPORTS(portRange);
+
+ /*
+ * Make sure port ranges match up, then add the redirect ports.
+ */
+ if (numLocalPorts != r->pport_cnt)
+ errx(EX_DATAERR, "redirect_port:"
+ "port ranges must be equal in size");
+
+ /* Remote port range is allowed to be '0' which means all ports. */
+ if (r->rport_cnt != numLocalPorts &&
+ (r->rport_cnt != 1 || r->rport != 0))
+ errx(EX_DATAERR, "redirect_port: remote port must"
+ "be 0 or equal to local port range in size");
+
+ /*
+ * Setup LSNAT server pool.
+ */
+ if (lsnat) {
+ sep = strtok(tmp_spool_buf, ",");
+ while (sep != NULL) {
+ tmp = (struct cfg_spool *)spool_buf;
+ if (len < SOF_SPOOL)
+ goto nospace;
+ len -= SOF_SPOOL;
+ space += SOF_SPOOL;
+ /*
+ * The sctp nat does not allow the port numbers to be mapped to new port numbers
+ * Therefore, no ports are to be specified in the target port field
+ */
+ if (r->proto == IPPROTO_SCTP) {
+ if (strchr (sep, ':')) {
+ errx(EX_DATAERR, "redirect_port:"
+ "port numbers do not change in "
+ "sctp, so do not specify them as "
+ "part of the target");
+ } else {
+ StrToAddr(sep, &tmp->addr);
+ tmp->port = r->pport;
+ }
+ } else {
+ if (StrToAddrAndPortRange(sep, &tmp->addr,
+ protoName, &portRange) != 0)
+ errx(EX_DATAERR, "redirect_port:"
+ "invalid local port range");
+ if (GETNUMPORTS(portRange) != 1)
+ errx(EX_DATAERR, "redirect_port: "
+ "local port must be single in "
+ "this context");
+ tmp->port = GETLOPORT(portRange);
+ }
+ r->spool_cnt++;
+ /* Point to the next possible cfg_spool. */
+ spool_buf = &spool_buf[SOF_SPOOL];
+ sep = strtok(NULL, ",");
+ }
+ }
+ return (space);
+nospace:
+ errx(EX_DATAERR, "redirect_port: buf is too small\n");
+}
+
+static int
+setup_redir_proto(char *spool_buf, int len,
+ int *_ac, char ***_av)
+{
+ char **av;
+ int ac, space;
+ struct protoent *protoent;
+ struct cfg_redir *r;
+
+ av = *_av;
+ ac = *_ac;
+ if (len >= SOF_REDIR) {
+ r = (struct cfg_redir *)spool_buf;
+ /* Skip cfg_redir at beginning of buf. */
+ spool_buf = &spool_buf[SOF_REDIR];
+ space = SOF_REDIR;
+ len -= SOF_REDIR;
+ } else
+ goto nospace;
+ r->mode = REDIR_PROTO;
+ /*
+ * Extract protocol.
+ */
+ if (ac == 0)
+ errx(EX_DATAERR, "redirect_proto: missing protocol");
+
+ protoent = getprotobyname(*av);
+ if (protoent == NULL)
+ errx(EX_DATAERR, "redirect_proto: unknown protocol %s", *av);
+ else
+ r->proto = protoent->p_proto;
+
+ INC_ARGCV();
+
+ /*
+ * Extract local address.
+ */
+ if (ac == 0)
+ errx(EX_DATAERR, "redirect_proto: missing local address");
+ else
+ StrToAddr(*av, &r->laddr);
+
+ INC_ARGCV();
+
+ /*
+ * Extract optional public address.
+ */
+ if (ac == 0) {
+ r->paddr.s_addr = INADDR_ANY;
+ r->raddr.s_addr = INADDR_ANY;
+ } else {
+ /* see above in setup_redir_port() */
+ if (!isalpha(**av)) {
+ StrToAddr(*av, &r->paddr);
+ INC_ARGCV();
+
+ /*
+ * Extract optional remote address.
+ */
+ /* see above in setup_redir_port() */
+ if (ac!=0 && !isalpha(**av)) {
+ StrToAddr(*av, &r->raddr);
+ INC_ARGCV();
+ }
+ }
+ }
+ return (space);
+nospace:
+ errx(EX_DATAERR, "redirect_proto: buf is too small\n");
+}
+
+static void
+print_nat_config(unsigned char *buf)
+{
+ struct cfg_nat *n;
+ int i, cnt, flag, off;
+ struct cfg_redir *t;
+ struct cfg_spool *s;
+ struct protoent *p;
+
+ n = (struct cfg_nat *)buf;
+ flag = 1;
+ off = sizeof(*n);
+ printf("ipfw nat %u config", n->id);
+ if (strlen(n->if_name) != 0)
+ printf(" if %s", n->if_name);
+ else if (n->ip.s_addr != 0)
+ printf(" ip %s", inet_ntoa(n->ip));
+ while (n->mode != 0) {
+ if (n->mode & PKT_ALIAS_LOG) {
+ printf(" log");
+ n->mode &= ~PKT_ALIAS_LOG;
+ } else if (n->mode & PKT_ALIAS_DENY_INCOMING) {
+ printf(" deny_in");
+ n->mode &= ~PKT_ALIAS_DENY_INCOMING;
+ } else if (n->mode & PKT_ALIAS_SAME_PORTS) {
+ printf(" same_ports");
+ n->mode &= ~PKT_ALIAS_SAME_PORTS;
+ } else if (n->mode & PKT_ALIAS_UNREGISTERED_ONLY) {
+ printf(" unreg_only");
+ n->mode &= ~PKT_ALIAS_UNREGISTERED_ONLY;
+ } else if (n->mode & PKT_ALIAS_RESET_ON_ADDR_CHANGE) {
+ printf(" reset");
+ n->mode &= ~PKT_ALIAS_RESET_ON_ADDR_CHANGE;
+ } else if (n->mode & PKT_ALIAS_REVERSE) {
+ printf(" reverse");
+ n->mode &= ~PKT_ALIAS_REVERSE;
+ } else if (n->mode & PKT_ALIAS_PROXY_ONLY) {
+ printf(" proxy_only");
+ n->mode &= ~PKT_ALIAS_PROXY_ONLY;
+ }
+ }
+ /* Print all the redirect's data configuration. */
+ for (cnt = 0; cnt < n->redir_cnt; cnt++) {
+ t = (struct cfg_redir *)&buf[off];
+ off += SOF_REDIR;
+ switch (t->mode) {
+ case REDIR_ADDR:
+ printf(" redirect_addr");
+ if (t->spool_cnt == 0)
+ printf(" %s", inet_ntoa(t->laddr));
+ else
+ for (i = 0; i < t->spool_cnt; i++) {
+ s = (struct cfg_spool *)&buf[off];
+ if (i)
+ printf(",");
+ else
+ printf(" ");
+ printf("%s", inet_ntoa(s->addr));
+ off += SOF_SPOOL;
+ }
+ printf(" %s", inet_ntoa(t->paddr));
+ break;
+ case REDIR_PORT:
+ p = getprotobynumber(t->proto);
+ printf(" redirect_port %s ", p->p_name);
+ if (!t->spool_cnt) {
+ printf("%s:%u", inet_ntoa(t->laddr), t->lport);
+ if (t->pport_cnt > 1)
+ printf("-%u", t->lport +
+ t->pport_cnt - 1);
+ } else
+ for (i=0; i < t->spool_cnt; i++) {
+ s = (struct cfg_spool *)&buf[off];
+ if (i)
+ printf(",");
+ printf("%s:%u", inet_ntoa(s->addr),
+ s->port);
+ off += SOF_SPOOL;
+ }
+
+ printf(" ");
+ if (t->paddr.s_addr)
+ printf("%s:", inet_ntoa(t->paddr));
+ printf("%u", t->pport);
+ if (!t->spool_cnt && t->pport_cnt > 1)
+ printf("-%u", t->pport + t->pport_cnt - 1);
+
+ if (t->raddr.s_addr) {
+ printf(" %s", inet_ntoa(t->raddr));
+ if (t->rport) {
+ printf(":%u", t->rport);
+ if (!t->spool_cnt && t->rport_cnt > 1)
+ printf("-%u", t->rport +
+ t->rport_cnt - 1);
+ }
+ }
+ break;
+ case REDIR_PROTO:
+ p = getprotobynumber(t->proto);
+ printf(" redirect_proto %s %s", p->p_name,
+ inet_ntoa(t->laddr));
+ if (t->paddr.s_addr != 0) {
+ printf(" %s", inet_ntoa(t->paddr));
+ if (t->raddr.s_addr)
+ printf(" %s", inet_ntoa(t->raddr));
+ }
+ break;
+ default:
+ errx(EX_DATAERR, "unknown redir mode");
+ break;
+ }
+ }
+ printf("\n");
+}
+
+void
+ipfw_config_nat(int ac, char **av)
+{
+ struct cfg_nat *n; /* Nat instance configuration. */
+ int i, len, off, tok;
+ char *id, buf[NAT_BUF_LEN]; /* Buffer for serialized data. */
+
+ len = NAT_BUF_LEN;
+ /* Offset in buf: save space for n at the beginning. */
+ off = sizeof(*n);
+ memset(buf, 0, sizeof(buf));
+ n = (struct cfg_nat *)buf;
+
+ av++; ac--;
+ /* Nat id. */
+ if (ac && isdigit(**av)) {
+ id = *av;
+ i = atoi(*av);
+ ac--; av++;
+ n->id = i;
+ } else
+ errx(EX_DATAERR, "missing nat id");
+ if (ac == 0)
+ errx(EX_DATAERR, "missing option");
+
+ while (ac > 0) {
+ tok = match_token(nat_params, *av);
+ ac--; av++;
+ switch (tok) {
+ case TOK_IP:
+ if (ac == 0)
+ errx(EX_DATAERR, "missing option");
+ if (!inet_aton(av[0], &(n->ip)))
+ errx(EX_DATAERR, "bad ip address ``%s''",
+ av[0]);
+ ac--; av++;
+ break;
+ case TOK_IF:
+ if (ac == 0)
+ errx(EX_DATAERR, "missing option");
+ set_addr_dynamic(av[0], n);
+ ac--; av++;
+ break;
+ case TOK_ALOG:
+ n->mode |= PKT_ALIAS_LOG;
+ break;
+ case TOK_DENY_INC:
+ n->mode |= PKT_ALIAS_DENY_INCOMING;
+ break;
+ case TOK_SAME_PORTS:
+ n->mode |= PKT_ALIAS_SAME_PORTS;
+ break;
+ case TOK_UNREG_ONLY:
+ n->mode |= PKT_ALIAS_UNREGISTERED_ONLY;
+ break;
+ case TOK_RESET_ADDR:
+ n->mode |= PKT_ALIAS_RESET_ON_ADDR_CHANGE;
+ break;
+ case TOK_ALIAS_REV:
+ n->mode |= PKT_ALIAS_REVERSE;
+ break;
+ case TOK_PROXY_ONLY:
+ n->mode |= PKT_ALIAS_PROXY_ONLY;
+ break;
+ /*
+ * All the setup_redir_* functions work directly in the final
+ * buffer, see above for details.
+ */
+ case TOK_REDIR_ADDR:
+ case TOK_REDIR_PORT:
+ case TOK_REDIR_PROTO:
+ switch (tok) {
+ case TOK_REDIR_ADDR:
+ i = setup_redir_addr(&buf[off], len, &ac, &av);
+ break;
+ case TOK_REDIR_PORT:
+ i = setup_redir_port(&buf[off], len, &ac, &av);
+ break;
+ case TOK_REDIR_PROTO:
+ i = setup_redir_proto(&buf[off], len, &ac, &av);
+ break;
+ }
+ n->redir_cnt++;
+ off += i;
+ len -= i;
+ break;
+ default:
+ errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]);
+ }
+ }
+
+ i = do_cmd(IP_FW_NAT_CFG, buf, off);
+ if (i)
+ err(1, "setsockopt(%s)", "IP_FW_NAT_CFG");
+
+ if (!co.do_quiet) {
+ /* After every modification, we show the resultant rule. */
+ int _ac = 3;
+ char *_av[] = {"show", "config", id};
+ ipfw_show_nat(_ac, _av);
+ }
+}
+
+
+void
+ipfw_show_nat(int ac, char **av)
+{
+ struct cfg_nat *n;
+ struct cfg_redir *e;
+ int cmd, i, nbytes, do_cfg, do_rule, frule, lrule, nalloc, size;
+ int nat_cnt, redir_cnt, r;
+ uint8_t *data, *p;
+ char *endptr;
+
+ do_rule = 0;
+ nalloc = 1024;
+ size = 0;
+ data = NULL;
+ frule = 0;
+ lrule = IPFW_DEFAULT_RULE; /* max ipfw rule number */
+ ac--; av++;
+
+ if (co.test_only)
+ return;
+
+ /* Parse parameters. */
+ for (cmd = IP_FW_NAT_GET_LOG, do_cfg = 0; ac != 0; ac--, av++) {
+ if (!strncmp(av[0], "config", strlen(av[0]))) {
+ cmd = IP_FW_NAT_GET_CONFIG, do_cfg = 1;
+ continue;
+ }
+ /* Convert command line rule #. */
+ frule = lrule = strtoul(av[0], &endptr, 10);
+ if (*endptr == '-')
+ lrule = strtoul(endptr+1, &endptr, 10);
+ if (lrule == 0)
+ err(EX_USAGE, "invalid rule number: %s", av[0]);
+ do_rule = 1;
+ }
+
+ nbytes = nalloc;
+ while (nbytes >= nalloc) {
+ nalloc = nalloc * 2;
+ nbytes = nalloc;
+ data = safe_realloc(data, nbytes);
+ if (do_cmd(cmd, data, (uintptr_t)&nbytes) < 0)
+ err(EX_OSERR, "getsockopt(IP_FW_GET_%s)",
+ (cmd == IP_FW_NAT_GET_LOG) ? "LOG" : "CONFIG");
+ }
+ if (nbytes == 0)
+ exit(0);
+ if (do_cfg) {
+ nat_cnt = *((int *)data);
+ for (i = sizeof(nat_cnt); nat_cnt; nat_cnt--) {
+ n = (struct cfg_nat *)&data[i];
+ if (frule <= n->id && lrule >= n->id)
+ print_nat_config(&data[i]);
+ i += sizeof(struct cfg_nat);
+ for (redir_cnt = 0; redir_cnt < n->redir_cnt; redir_cnt++) {
+ e = (struct cfg_redir *)&data[i];
+ i += sizeof(struct cfg_redir) + e->spool_cnt *
+ sizeof(struct cfg_spool);
+ }
+ }
+ } else {
+ for (i = 0; 1; i += LIBALIAS_BUF_SIZE + sizeof(int)) {
+ p = &data[i];
+ if (p == data + nbytes)
+ break;
+ bcopy(p, &r, sizeof(int));
+ if (do_rule) {
+ if (!(frule <= r && lrule >= r))
+ continue;
+ }
+ printf("nat %u: %s\n", r, p+sizeof(int));
+ }
+ }
+}
diff --git a/sbin/md5/md5.1 b/sbin/md5/md5.1
index 0972953..2397d9e 100644
--- a/sbin/md5/md5.1
+++ b/sbin/md5/md5.1
@@ -49,15 +49,24 @@ key under a public-key cryptosystem such as
.Tn RSA .
.Pp
.Tn MD5
-has not yet (2007-03-05) been broken, but sufficient attacks have been
-made that its security is in some doubt.
-The attacks on
+has been completely broken as far as finding collisions is
+concerned, and should not be relied upon to produce unique outputs.
+This also means that
.Tn MD5
-are in the nature of finding
-.Dq collisions
-\(em that is, multiple
-inputs which hash to the same value; it is still unlikely for an attacker
-to be able to determine the exact original input given a hash value.
+should not be used as part of a cryptographic signature scheme.
+At the current time (2009-01-06) there is no publicly known method to
+.Dq reverse
+MD5, i.e., to find an input given a hash value.
+.Pp
+.Tn SHA-1
+currently (2009-01-06) has no known collisions, but an attack has been
+found which is faster than a brute-force search, placing the security of
+.Tn SHA-1
+in doubt.
+.Pp
+It is recommended that all new applications use
+.Tn SHA-256
+instead of one of the other hash functions.
.Pp
The following options may be used in any combination and must
precede any files named on the command line.
diff --git a/sbin/mdconfig/mdconfig.8 b/sbin/mdconfig/mdconfig.8
index 28c17c5..0288474 100644
--- a/sbin/mdconfig/mdconfig.8
+++ b/sbin/mdconfig/mdconfig.8
@@ -62,6 +62,7 @@
.Nm
.Fl d
.Fl u Ar unit
+.Op Fl o Oo Cm no Oc Ns Ar force
.Nm
.Fl l
.Op Fl n
diff --git a/sbin/mdconfig/mdconfig.c b/sbin/mdconfig/mdconfig.c
index d1abf68..107a259 100644
--- a/sbin/mdconfig/mdconfig.c
+++ b/sbin/mdconfig/mdconfig.c
@@ -58,7 +58,7 @@ usage()
"usage: mdconfig -a -t type [-n] [-o [no]option] ... [-f file]\n"
" [-s size] [-S sectorsize] [-u unit]\n"
" [-x sectors/track] [-y heads/cyl]\n"
-" mdconfig -d -u unit\n"
+" mdconfig -d -u unit [-o [no]force]\n"
" mdconfig -l [-v] [-n] [-u unit]\n");
fprintf(stderr, "\t\ttype = {malloc, preload, vnode, swap}\n");
fprintf(stderr, "\t\toption = {cluster, compress, reserve}\n");
@@ -160,6 +160,16 @@ main(int argc, char **argv)
close(fd);
break;
case 'o':
+ if (action == DETACH) {
+ if (!strcmp(optarg, "force"))
+ mdio.md_options |= MD_FORCE;
+ else if (!strcmp(optarg, "noforce"))
+ mdio.md_options &= ~MD_FORCE;
+ else
+ errx(1, "Unknown option: %s.", optarg);
+ break;
+ }
+
if (cmdline != 2)
usage();
if (!strcmp(optarg, "async"))
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 1cc15a7..66b9c13 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -31,16 +31,14 @@
static const char copyright[] =
"@(#) Copyright (c) 1980, 1989, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
#if 0
static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95";
#endif
-static const char rcsid[] =
- "$FreeBSD$";
#endif /* not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
@@ -68,16 +66,20 @@ static const char rcsid[] =
#define MOUNT_META_OPTION_FSTAB "fstab"
#define MOUNT_META_OPTION_CURRENT "current"
-#define MAX_ARGS 100
-
int debug, fstab_style, verbose;
+struct cpa {
+ char **a;
+ ssize_t sz;
+ int c;
+};
+
char *catopt(char *, const char *);
struct statfs *getmntpt(const char *);
int hasopt(const char *, const char *);
int ismounted(struct fstab *, struct statfs *, int);
int isremountable(const char *);
-void mangle(char *, int *, char *[]);
+void mangle(char *, struct cpa *);
char *update_options(char *, char *, int);
int mountfs(const char *, const char *, const char *,
int, const char *, const char *);
@@ -499,15 +501,26 @@ hasopt(const char *mntopts, const char *option)
return (found);
}
+static void
+append_arg(struct cpa *sa, char *arg)
+{
+ if (sa->c + 1 == sa->sz) {
+ sa->sz = sa->sz == 0 ? 8 : sa->sz * 2;
+ sa->a = realloc(sa->a, sizeof(sa->a) * sa->sz);
+ if (sa->a == NULL)
+ errx(1, "realloc failed");
+ }
+ sa->a[++sa->c] = arg;
+}
+
int
mountfs(const char *vfstype, const char *spec, const char *name, int flags,
const char *options, const char *mntopts)
{
- static int argc;
- char *argv[MAX_ARGS];
struct statfs sf;
int i, ret;
char *optbuf, execname[PATH_MAX], mntpath[PATH_MAX];
+ static struct cpa mnt_argv;
/* resolve the mountpoint with realpath(3) */
(void)checkpath(name, mntpath);
@@ -542,32 +555,28 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags,
/* Construct the name of the appropriate mount command */
(void)snprintf(execname, sizeof(execname), "mount_%s", vfstype);
- argc = 0;
- argv[argc++] = execname;
- mangle(optbuf, &argc, argv);
- argv[argc++] = strdup(spec);
- argv[argc++] = strdup(name);
- argv[argc] = NULL;
-
- if (MAX_ARGS <= argc )
- errx(1, "Cannot process more than %d mount arguments",
- MAX_ARGS);
+ mnt_argv.c = -1;
+ append_arg(&mnt_argv, execname);
+ mangle(optbuf, &mnt_argv);
+ append_arg(&mnt_argv, strdup(spec));
+ append_arg(&mnt_argv, strdup(name));
+ append_arg(&mnt_argv, NULL);
if (debug) {
if (use_mountprog(vfstype))
printf("exec: mount_%s", vfstype);
else
printf("mount -t %s", vfstype);
- for (i = 1; i < argc; i++)
- (void)printf(" %s", argv[i]);
+ for (i = 1; i < mnt_argv.c; i++)
+ (void)printf(" %s", mnt_argv.a[i]);
(void)printf("\n");
return (0);
}
if (use_mountprog(vfstype)) {
- ret = exec_mountprog(name, execname, argv);
+ ret = exec_mountprog(name, execname, mnt_argv.a);
} else {
- ret = mount_fs(vfstype, argc, argv);
+ ret = mount_fs(vfstype, mnt_argv.c, mnt_argv.a);
}
free(optbuf);
@@ -670,12 +679,10 @@ catopt(char *s0, const char *s1)
}
void
-mangle(char *options, int *argcp, char *argv[])
+mangle(char *options, struct cpa *a)
{
char *p, *s;
- int argc;
- argc = *argcp;
for (s = options; (p = strsep(&s, ",")) != NULL;)
if (*p != '\0') {
if (strcmp(p, "noauto") == 0) {
@@ -707,19 +714,17 @@ mangle(char *options, int *argcp, char *argv[])
sizeof(groupquotaeq) - 1) == 0) {
continue;
} else if (*p == '-') {
- argv[argc++] = p;
+ append_arg(a, p);
p = strchr(p, '=');
if (p != NULL) {
*p = '\0';
- argv[argc++] = p+1;
+ append_arg(a, p + 1);
}
} else {
- argv[argc++] = strdup("-o");
- argv[argc++] = p;
+ append_arg(a, strdup("-o"));
+ append_arg(a, p);
}
}
-
- *argcp = argc;
}
diff --git a/sbin/mount_msdosfs/mount_msdosfs.8 b/sbin/mount_msdosfs/mount_msdosfs.8
index 42a158c..857899b 100644
--- a/sbin/mount_msdosfs/mount_msdosfs.8
+++ b/sbin/mount_msdosfs/mount_msdosfs.8
@@ -75,7 +75,7 @@ The following MSDOS file system-specific options are available:
.Bl -tag -width indent
.It Cm large
Support file systems larger than 128 gigabytes at the expense
-of 32 bytes of kernel memory.
+of 32 bytes of kernel memory for each file on disk.
This memory will not be reclaimed until the file system has
been unmounted.
.It Cm longnames
diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index fdfecc4..a2f5e89 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -469,6 +469,12 @@ copyopt(struct iovec **newiov, int *newiovlen,
build_iovec(newiov, newiovlen, name, value, len);
}
+/*
+ * XXX: This function is provided for backwards
+ * compatibility with older kernels which did not support
+ * passing NFS mount options to nmount() as individual
+ * parameters. It should be eventually be removed.
+ */
int
fallback_mount(struct iovec *iov, int iovlen, int mntflags)
{
@@ -584,27 +590,31 @@ fallback_mount(struct iovec *iov, int iovlen, int mntflags)
}
if (findopt(iov, iovlen, "acregmin", &opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acregmin);
- if (ret != 1 || args.acregmin <= 0) {
+ if (ret != 1 || args.acregmin < 0) {
errx(1, "illegal acregmin: %s", opt);
}
+ args.flags |= NFSMNT_ACREGMIN;
}
if (findopt(iov, iovlen, "acregmax", &opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acregmax);
- if (ret != 1 || args.acregmax <= 0) {
+ if (ret != 1 || args.acregmax < 0) {
errx(1, "illegal acregmax: %s", opt);
}
+ args.flags |= NFSMNT_ACREGMAX;
}
if (findopt(iov, iovlen, "acdirmin", &opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acdirmin);
- if (ret != 1 || args.acdirmin <= 0) {
+ if (ret != 1 || args.acdirmin < 0) {
errx(1, "illegal acdirmin: %s", opt);
}
+ args.flags |= NFSMNT_ACDIRMIN;
}
if (findopt(iov, iovlen, "acdirmax", &opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acdirmax);
- if (ret != 1 || args.acdirmax <= 0) {
+ if (ret != 1 || args.acdirmax < 0) {
errx(1, "illegal acdirmax: %s", opt);
}
+ args.flags |= NFSMNT_ACDIRMAX;
}
if (findopt(iov, iovlen, "deadthresh", &opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.deadthresh);
diff --git a/sbin/mount_ntfs/mount_ntfs.8 b/sbin/mount_ntfs/mount_ntfs.8
index 059618f..60c2e3b 100644
--- a/sbin/mount_ntfs/mount_ntfs.8
+++ b/sbin/mount_ntfs/mount_ntfs.8
@@ -154,6 +154,9 @@ This utility is primarily used for read access to an NTFS volume.
See the
.Sx WRITING
section for details about writing to an NTFS volume.
+.Pp
+For a full read-write NTFS support consider sysutils/fusefs-ntfs
+port/package.
.Sh HISTORY
The
.Nm
diff --git a/sbin/ping/ping.8 b/sbin/ping/ping.8
index b710991..7617585 100644
--- a/sbin/ping/ping.8
+++ b/sbin/ping/ping.8
@@ -503,17 +503,21 @@ packets that they use for
packets, for example either 30 or 60.
Others may use completely wild values.
.El
-.Sh RETURN VALUES
+.Sh EXIT STATUS
The
.Nm
-utility returns an exit status of zero if at least one response was
-heard from the specified
-.Ar host ;
-a status of two if the transmission was successful but no responses
-were received; or another value
-(from
-.In sysexits.h )
-if an error occurred.
+utility exits with one of the following values:
+.Bl -tag -width indent
+.It 0
+At least one response was heard from the specified
+.Ar host .
+.It 2
+The transmission was successful but no responses were received.
+.It any other value
+An error occurred.
+These values are defined in
+.In sysexits.h .
+.El
.Sh SEE ALSO
.Xr netstat 1 ,
.Xr ifconfig 8 ,
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index de40307..3a4d20c 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -65,7 +65,7 @@ int
main(int argc, char *argv[])
{
const struct passwd *pw;
- int ch, howto, i, fd, lflag, nflag, qflag, pflag, sverrno;
+ int ch, howto, i, fd, lflag, nflag, qflag, sverrno;
u_int pageins;
const char *p, *user, *kernel = NULL;
@@ -91,7 +91,6 @@ main(int argc, char *argv[])
howto |= RB_NOSYNC;
break;
case 'p':
- pflag = 1;
howto |= RB_POWEROFF;
break;
case 'q':
diff --git a/sbin/recoverdisk/recoverdisk.c b/sbin/recoverdisk/recoverdisk.c
index 0dc5d7c..6353635 100644
--- a/sbin/recoverdisk/recoverdisk.c
+++ b/sbin/recoverdisk/recoverdisk.c
@@ -276,7 +276,10 @@ main(int argc, char * const argv[])
lp->len -= i;
continue;
}
- printf("\n%jd %zu failed %d\n", lp->start, i, errno);
+ printf("\n%jd %zu failed (%s)\n",
+ lp->start, i, strerror(errno));
+ if (errno == ENXIO)
+ aborting = 1;
new_lump(lp->start, i, lp->state + 1);
lp->start += i;
lp->len -= i;
diff --git a/sbin/restore/interactive.c b/sbin/restore/interactive.c
index 1fffd28..c977df1 100644
--- a/sbin/restore/interactive.c
+++ b/sbin/restore/interactive.c
@@ -545,6 +545,7 @@ printlist(char *name, char *basename)
strcmp(dp->d_name, ".") == 0 ||
strcmp(dp->d_name, "..") == 0))
continue;
+ locname[namelen] = '\0';
if (namelen + dp->d_namlen >= MAXPATHLEN) {
fprintf(stderr, "%s%s: name exceeds %d char\n",
locname, dp->d_name, MAXPATHLEN);
diff --git a/sbin/route/route.c b/sbin/route/route.c
index bae9983..90ea509 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -791,33 +791,34 @@ inet_makenetandmask(net, sin, bits)
char *cp;
rtm_addrs |= RTA_NETMASK;
- if (net == 0)
- mask = addr = 0;
- else {
- if (net <= 0xff)
- addr = net << IN_CLASSA_NSHIFT;
- else if (net <= 0xffff)
- addr = net << IN_CLASSB_NSHIFT;
- else if (net <= 0xffffff)
- addr = net << IN_CLASSC_NSHIFT;
- else
- addr = net;
+ /*
+ * XXX: This approach unable to handle 0.0.0.1/32 correctly
+ * as inet_network() converts 0.0.0.1 and 1 equally.
+ */
+ if (net <= 0xff)
+ addr = net << IN_CLASSA_NSHIFT;
+ else if (net <= 0xffff)
+ addr = net << IN_CLASSB_NSHIFT;
+ else if (net <= 0xffffff)
+ addr = net << IN_CLASSC_NSHIFT;
+ else
+ addr = net;
+
+ if (bits != 0)
+ mask = 0xffffffff << (32 - bits);
+ else if (net == 0)
+ mask = 0;
+ else if (IN_CLASSA(addr))
+ mask = IN_CLASSA_NET;
+ else if (IN_CLASSB(addr))
+ mask = IN_CLASSB_NET;
+ else if (IN_CLASSC(addr))
+ mask = IN_CLASSC_NET;
+ else if (IN_MULTICAST(addr))
+ mask = IN_CLASSD_NET;
+ else
+ mask = 0xffffffff;
- if (bits != 0)
- mask = 0xffffffff << (32 - bits);
- else {
- if (IN_CLASSA(addr))
- mask = IN_CLASSA_NET;
- else if (IN_CLASSB(addr))
- mask = IN_CLASSB_NET;
- else if (IN_CLASSC(addr))
- mask = IN_CLASSC_NET;
- else if (IN_MULTICAST(addr))
- mask = IN_CLASSD_NET;
- else
- mask = 0xffffffff;
- }
- }
sin->sin_addr.s_addr = htonl(addr);
sin = &so_mask.sin;
sin->sin_addr.s_addr = htonl(mask);
diff --git a/share/examples/cvsup/refuse.README b/share/examples/cvsup/refuse.README
index 0b9bbac..5af4d46 100644
--- a/share/examples/cvsup/refuse.README
+++ b/share/examples/cvsup/refuse.README
@@ -12,8 +12,8 @@ everything beneath that directory will be left alone.
You can copy "refuse" to your sup directory and add or remove
whatever you like. The example supfiles in this directory set
-CVSup's base directory to "/usr". The sup directory is in the base
-directory; i.e., it is "/usr/sup". If you have changed your base
+CVSup's base directory to "/var/db". The sup directory is in the base
+directory; i.e., it is "/var/db/sup". If you have changed your base
directory, your sup directory is /path/to/base/sup.
This file used to contain /usr/src/etc/sendmail/freebsd.mc in case
@@ -62,4 +62,4 @@ depend on files in completely different parts.
For more information about refuse files see cvsup(1), which is
installed by the "cvsup" and "cvsup-bin" ports. See also the CVSup
-FAQ at <http://www.polstra.com/projects/freeware/CVSup/>.
+FAQ at <http://www.cvsup.org/faq.html>.
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 15189b0..80ce734 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -316,6 +316,7 @@ MAN= aac.4 \
screen.4 \
scsi.4 \
sctp.4 \
+ sdhci.4 \
sem.4 \
ses.4 \
sf.4 \
@@ -417,6 +418,7 @@ MAN= aac.4 \
uplcom.4 \
ural.4 \
urio.4 \
+ ${_urtw.4} \
usb.4 \
uscanner.4 \
uslcom.4 \
@@ -567,6 +569,7 @@ MLINKS+=u3g.4 u3gstub.4
MLINKS+=udav.4 if_udav.4
MLINKS+=upgt.4 if_upgt.4
MLINKS+=ural.4 if_ural.4
+MLINKS+=${_urtw.4} ${_if_urtw.4}
MLINKS+=vge.4 if_vge.4
MLINKS+=vlan.4 if_vlan.4
MLINKS+=vpo.4 imm.4
@@ -600,6 +603,7 @@ _if_ndis.4= if_ndis.4
_if_nfe.4= if_nfe.4
_if_nve.4= if_nve.4
_if_nxge.4= if_nxge.4
+_if_urtw.4= if_urtw.4
_if_wpi.4= if_wpi.4
_ipmi.4= ipmi.4
_io.4= io.4
@@ -613,6 +617,7 @@ _nxge.4= nxge.4
_rr232x.4= rr232x.4
_speaker.4= speaker.4
_spkr.4= spkr.4
+_urtw.4= urtw.4
_wpi.4= wpi.4
.endif
diff --git a/share/man/man4/ae.4 b/share/man/man4/ae.4
index 8134eb1..0b5e8f8 100644
--- a/share/man/man4/ae.4
+++ b/share/man/man4/ae.4
@@ -121,8 +121,7 @@ the network connection (cable).
.It "ae%d: reset timeout."
The card reset operation has been timed out.
.It "ae%d: Generating random ethernet address."
-No valid ethernet address was found neither in the controller registers not in
-NVRAM.
+No valid Ethernet address was found in the controller NVRAM and registers.
Random locally administered address with ASUS OUI identifier will be used
instead.
.El
@@ -135,8 +134,8 @@ instead.
.Xr vlan 4 ,
.Xr ifconfig 8
.Sh BUGS
-The Attansic L2 FastEthernet contoller supports DMA but do not use a descriptor
-based transfer mechanism via scatter-gather DMA.
+The Attansic L2 FastEthernet contoller supports DMA but does not use a
+descriptor based transfer mechanism via scatter-gather DMA.
Thus the data should be copied to/from the controller memory on each
transmit/receive.
Furthermore, a lot of data alignment restrictions apply.
@@ -150,4 +149,4 @@ driver and this manual page was written by
.An Stanislav Sedov
.Aq stas@FreeBSD.org .
It first appeared in
-.Fx 8.0 .
+.Fx 7.1 .
diff --git a/share/man/man4/ath.4 b/share/man/man4/ath.4
index 80d094a..7719b0e 100644
--- a/share/man/man4/ath.4
+++ b/share/man/man4/ath.4
@@ -1,5 +1,5 @@
.\"-
-.\" Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+.\" Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
.\" All rights reserved.
.\""
.\" Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"/
-.Dd April 13, 2008
+.Dd January 13, 2009
.Dt ATH 4
.Os
.Sh NAME
@@ -41,6 +41,7 @@ kernel configuration file:
.Bd -ragged -offset indent
.Cd "device ath"
.Cd "device ath_hal"
+.Cd "options AH_SUPPORT_AR5416"
.Cd "device ath_rate_sample"
.Cd "device wlan"
.Ed
@@ -55,14 +56,14 @@ if_ath_load="YES"
The
.Nm
driver provides support for wireless network adapters based on
-the Atheros AR5210, AR5211, and AR5212 programming APIs.
+the Atheros AR5210, AR5211, AR5212, and AR5416 programming APIs.
These APIs are used by a wide variety of chips; most all chips with
a PCI and/or CardBus interface are supported.
Chip-specific support is provided by the Atheros Hardware Access Layer
-(HAL), that is packaged separately.
+(HAL).
.Pp
Supported features include 802.11 and 802.3 frames, power management, BSS,
-IBSS, and host-based access point operation modes.
+IBSS, TDMA, and host-based access point operation modes.
All host/device interaction is via DMA.
.Pp
The
@@ -78,17 +79,21 @@ speeds as above for 802.11a operation and
1Mbps, 2Mbps, 5.5 Mbps and 11Mbps for 802.11b operation.
AR5212-based devices support 802.11a, 802.11b, and 802.11g operation
with transmit speeds appropriate to each.
+AR5416-class devices are capable of 802.11n operation
+but are supported only in legacy modes (802.11a, 11b, 11g).
Most chips also support an Atheros Turbo Mode (TM) that operates in
the 5Ghz frequency range with 2x the transmit speeds.
Some chips also support Turbo mode in the 2.4Ghz range with 802.11g
though this support is not presently available due to regulatory requirements.
(Note that Turbo modes are, however,
only interoperable with other Atheros-based devices.)
+AR5212-based devices also support half- (10MHz) and quarter-width (5MHz) channels.
The actual transmit speed used is dependent on signal quality and the
.Dq "rate control"
algorithm employed by the driver.
All chips support WEP encryption.
-The AR5212 has hardware support for the AES-CCM, TKIP, and Michael cryptographic
+AR5212 and AR5416 parts have hardware support for the
+AES-CCM, TKIP, and Michael cryptographic
operations required for WPA.
To enable encryption, use
.Xr ifconfig 8
@@ -120,6 +125,13 @@ Multiple
interfaces may be operated together with
.Cm hostap
interfaces to construct a wireless repeater device.
+The driver also support
+.Cm tdma
+operation when compiled with
+.Cd "options AH_SUPPORT_TDMA"
+(and the wlan module is build with
+.Cd "options IEEE80211_SUPPORT_TDMA"
+to enable the associated 802.11 support).
For more information on configuring this device, see
.Xr ifconfig 8 .
.Pp
@@ -180,6 +192,14 @@ ifconfig wlan1 create wlandev ath0 wlanmode hostap bssid \e
ssid freeloaders up
ifconfig bridge0 create addm wlan0 addm wlan1 addm fxp0 up
.Ed
+.Pp
+Create a master node in a two slot TDMA BSS configured to use
+2.5 millisecond slots.
+.Bd -literal -offset indent
+ifconfig wlan0 create wlandev ath0 wlanmode tdma \e
+ ssid tdma-test tmdaslot 0 tdmaslotlen 2500 \e
+ channel 36 up
+.Ed
.Sh DIAGNOSTICS
.Bl -diag
.It "ath%d: unable to attach hardware; HAL status %u"
diff --git a/share/man/man4/bce.4 b/share/man/man4/bce.4
index 774217a..93e3bc0 100644
--- a/share/man/man4/bce.4
+++ b/share/man/man4/bce.4
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 2, 2008
+.Dd January 15, 2009
.Dt BCE 4
.Os
.Sh NAME
@@ -160,6 +160,26 @@ HP NC370F Multifunction Gigabit Server Adapter
HP NC370T Multifunction Gigabit Server Adapter
.It
HP NC370i Multifunction Gigabit Server Adapter
+.It
+HP NC371i Multifunction Gigabit Server Adapter
+.It
+HP NC373F PCIe Multifunc Giga Server Adapter
+.It
+HP NC373T PCIe Multifunction Gig Server Adapter
+.It
+HP NC373i Multifunction Gigabit Server Adapter
+.It
+HP NC373m Multifunction Gigabit Server Adapter
+.It
+HP NC374m PCIe Multifunction Adapter
+.It
+HP NC380T PCIe DP Multifunc Gig Server Adapter
+.It
+HP NC382T PCIe DP Multifunction Gigabit Server Adapter
+.It
+HP NC382i DP Multifunction Gigabit Server Adapter
+.It
+HP NC382m DP 1GbE Multifunction BL-c Adapter
.El
.Sh SYSCTL VARIABLES
The following variables are available as both
diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4
index 45b4590..d9d3be3 100644
--- a/share/man/man4/bge.4
+++ b/share/man/man4/bge.4
@@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 25, 2007
+.Dd January 15, 2009
.Dt BGE 4
.Os
.Sh NAME
@@ -82,7 +82,7 @@ copper gigabit transceivers,
which support autonegotiation of 10, 100 and 1000Mbps modes in
full or half duplex.
.Pp
-The BCM5700, BCM5701, BCM5703, BCM5704, BCM5714 and BCM5780 also support
+The BCM5700, BCM5701, BCM5702, BCM5703 and BCM5704 also support
jumbo frames, which can be configured
via the interface MTU setting.
Selecting an MTU larger than 1500 bytes with the
diff --git a/share/man/man4/cd.4 b/share/man/man4/cd.4
index 19113b7..ec16751 100644
--- a/share/man/man4/cd.4
+++ b/share/man/man4/cd.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 2, 2003
+.Dd January 8, 2009
.Dt CD 4
.Os
.Sh NAME
@@ -370,43 +370,6 @@ Some work is planned to support
some of the more common `broken'
.Tn CD-ROM
drives; however, this is not yet under way.
-.Pp
-The
-.Nm
-driver attempts to automatically determine whether the drive it is talking
-to supports 6 byte or 10 byte MODE SENSE/MODE SELECT operations.
-Many
-.Tn SCSI
-drives only support 6 byte commands, and
-.Tn ATAPI
-drives only support 10 byte commands.
-The
-.Nm
-driver first attempts to determine whether the protocol in use typically
-supports 6 byte commands by issuing a CAM Path Inquiry CCB.
-It will then default to 6 byte or 10 byte commands as appropriate.
-After that, the
-.Nm
-driver defaults to using 6 byte commands (assuming the protocol the drive
-speaks claims to support 6 byte commands), until one fails with a
-.Tn SCSI
-ILLEGAL REQUEST error.
-Then it tries the 10 byte version of the command to
-see if that works instead.
-Users can change the default via per-drive
-sysctl variables and loader tunables.
-The variable names are the same in
-both instances:
-.Pp
-.Va kern.cam.cd.%d.minimum_cmd_size
-.Pp
-Where
-.Dq %d
-is the unit number of the drive in question.
-Valid minimum command sizes
-are 6 and 10.
-Any value above 6 will be rounded to 10, and any value below
-6 will be rounded to 6.
.Sh CHANGER OPERATION
This driver has built-in support for LUN-based CD changers.
A LUN-based CD
@@ -466,6 +429,63 @@ probe messages for the various LUNs of the changer will continue to appear
while the boot process is going on.
This is normal, and is caused by the
changer scheduling code.
+.Sh SYSCTL VARIABLES
+The following variables are available as both
+.Xr sysctl 8
+variables and
+.Xr loader 8
+tunables:
+.Bl -tag -width 12
+.It kern.cam.cd.retry_count
+.Pp
+This variable determines how many times the
+.Nm
+driver will retry a READ or WRITE command.
+This does not affect the number of retries used during probe time or for
+the
+.Nm
+driver dump routine.
+This value currently defaults to 4.
+.It kern.cam.cd.%d.minimum_cmd_size
+.Pp
+The
+.Nm
+driver attempts to automatically determine whether the drive it is talking
+to supports 6 byte or 10 byte MODE SENSE/MODE SELECT operations.
+Many
+.Tn SCSI
+drives only support 6 byte commands, and
+.Tn ATAPI
+drives only support 10 byte commands.
+The
+.Nm
+driver first attempts to determine whether the protocol in use typically
+supports 6 byte commands by issuing a CAM Path Inquiry CCB.
+It will then default to 6 byte or 10 byte commands as appropriate.
+After that, the
+.Nm
+driver defaults to using 6 byte commands (assuming the protocol the drive
+speaks claims to support 6 byte commands), until one fails with a
+.Tn SCSI
+ILLEGAL REQUEST error.
+Then it tries the 10 byte version of the command to
+see if that works instead.
+Users can change the default via per-drive
+sysctl variables and loader tunables.
+Where
+.Dq %d
+is the unit number of the drive in question.
+Valid minimum command sizes
+are 6 and 10.
+Any value above 6 will be rounded to 10, and any value below
+6 will be rounded to 6.
+.It kern.cam.cd.changer.min_busy_seconds
+.It kern.cam.cd.changer.max_busy_seconds
+.Pp
+Tune how long individual LUNs are 'locked' for I/O operations to
+optimize changer operation.
+See CHANGER OPERATION section for information on how to use these items.
+.El
.Sh FILES
.Bl -tag -width /dev/cd[0-9][a-h] -compact
.It Pa /dev/cd[0-9][a-h]
diff --git a/share/man/man4/cpuctl.4 b/share/man/man4/cpuctl.4
index 0e60801..ee86dc0 100644
--- a/share/man/man4/cpuctl.4
+++ b/share/man/man4/cpuctl.4
@@ -45,30 +45,33 @@ at boot time, place the following in
cpuctl_load="YES"
.Ed
.Sh DESCRIPTION
-The special file
+The special device
.Pa /dev/cpuctl
-presents interace to the system CPU. It provides functionality to retrieve
+presents interface to the system CPU.
+It provides functionality to retrieve
CPUID information, read/write machine specific registers (MSR) and perform
-cpu firmware updates.
+CPU firmware updates.
.Pp
-For each cpu present in the system, special file
+For each CPU present in the system, the special device
.Pa /dev/cpuctl%d
-with the appropriate index will be created. For multicore cpus the
-special file will be created for each core.
+with the appropriate index will be created.
+For multicore CPUs such a
+special device will be created for each core.
.Pp
Currently, only i386 and amd64 processors are
supported.
.Sh IOCTL INTERFACE
All of the supported operations are invoked using the
-.Fr ioctl 2
-system call. Refer to that manpage for further information about
-this interface. Currently, the following ioctls are defined:
+.Xr ioctl 2
+system call.
+Currently, the following ioctls are defined:
.Bl -tag -width CPUCTL_UPDATE
.It Dv CPUCTL_RDMSR Fa cpuctl_msr_args_t *args
.It Dv CPUCTL_WRMSR Fa cpuctl_msr_args_t *args
-Read/write cpu machine specific register. The
+Read/write CPU machine specific register.
+The
.Vt cpuctl_msr_args_t
-structure defined in
+structure is defined in
.In sys/cpuctl.h
as:
.Pp
@@ -79,7 +82,8 @@ typedef struct {
} cpuctl_msr_args_t;
.Ed
.It Dv CPUCTL_CPUID Fa cpuctl_cpuid_args_t *args
-Retrieve CPUID information. Arguments are supplied in
+Retrieve CPUID information.
+Arguments are supplied in
the following struct:
.Pp
.Bd -literal
@@ -93,9 +97,10 @@ The
.Va level
field indicates the CPUID level to retrieve information for, while the
.Va data
-used to store CPUID data received.
+field is used to store the received CPUID data.
.It Dv CPUCTL_UPDATE cpuctl_update_args_t *args
-Update cpu firmware (microcode). The structure defined in
+Update CPU firmware (microcode).
+The structure is defined in
.In sys/cpuctl.h
as:
.Pp
@@ -117,30 +122,31 @@ For additional information refer to
.Sh RETURN VALUES
.Bl -tag -width Er
.It Bq Er ENXIO
-The operation requested is not supported by device (e.g. unsupported
-architecture or cpu was disabled)
+The operation requested is not supported by the device (e.g. unsupported
+architecture or the CPU is disabled)
.It Bq Er EINVAL
Incorrect request was supplied, or microcode image is not correct.
.It Bq Er ENOMEM
No physical memory was available to complete the request.
.It Bq Er EFAULT
-The firmware image address points outside process address space.
+The firmware image address points outside the process address space.
.El
.Sh FILES
.Bl -tag -width /dev/cpuctl -compact
.It Pa /dev/cpuctl
.El
.Sh SEE ALSO
-.Xr hwpmc 4
+.Xr hwpmc 4 ,
+.Xr cpucontrol 8
.Sh HISTORY
The
.Nm
driver first appeared in
-.Fx 8.0
+.Fx 8.0 .
.Sh BUGS
Yes, probably, report if any.
.Sh AUTHORS
The
.Nm
-module and this manual page was written by
+module and this manual page were written by
.An Stanislav Sedov Aq stas@FreeBSD.org .
diff --git a/share/man/man4/gem.4 b/share/man/man4/gem.4
index 2e0939f..827dda0 100644
--- a/share/man/man4/gem.4
+++ b/share/man/man4/gem.4
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 26, 2007
+.Dd January 15, 2009
.Dt GEM 4
.Os
.Sh NAME
@@ -115,7 +115,6 @@ driver fails to attach to Sun Gigabit Ethernet SBus 2.0/3.0 (GBE/S) cards,
as no SBus front-end has been written so far.
.Sh SEE ALSO
.Xr altq 4 ,
-.Xr hme 4 ,
.Xr miibus 4 ,
.Xr netintro 4 ,
.Xr eeprom 8 ,
diff --git a/share/man/man4/hme.4 b/share/man/man4/hme.4
index 4e2b4eb..7813867 100644
--- a/share/man/man4/hme.4
+++ b/share/man/man4/hme.4
@@ -36,7 +36,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 16, 2005
+.Dd January 16, 2009
.Dt HME 4
.Os
.Sh NAME
@@ -120,7 +120,6 @@ on boards equipped with more than one Ethernet interface and all add-on cards
except the single-port SBus versions.
.Sh SEE ALSO
.Xr altq 4 ,
-.Xr gem 4 ,
.Xr intro 4 ,
.Xr miibus 4 ,
.Xr netintro 4 ,
@@ -130,7 +129,7 @@ except the single-port SBus versions.
.%T "STP2002QFP Fast Ethernet, Parallel Port, SCSI (FEPS) User's Guide"
.%D April 1996
.%A Sun Microelectronics
-.%O http://www.sun.com/oem/products/manuals/STP2002QFP-UG.pdf
+.%O http://mediacast.sun.com/users/Barton808/media/STP2002QFP-FEPs_UG.pdf
.Re
.Sh HISTORY
The
diff --git a/share/man/man4/iic.4 b/share/man/man4/iic.4
index 0112ff8..7d6141c 100644
--- a/share/man/man4/iic.4
+++ b/share/man/man4/iic.4
@@ -45,13 +45,19 @@ In order to control I2C devices, use
.Pa /dev/iic?
with the
following ioctls:
-.Bl -tag -width ".Dv I2CRSTCARD"
+.Bl -tag -width ".Dv I2CRPTSTART"
.It Dv I2CSTART
.Pq Vt "struct iiccmd"
Sends the start condition to the slave specified by the
.Va slave
element to the bus.
All other elements are ignored.
+.It Dv I2CRPTSTART
+.Pq Vt "struct iiccmd"
+Sends the repeated start condition to the slave specified by the
+.Va slave
+element to the bus.
+All other elements are ignored.
.It Dv I2CSTOP
No argument is passed.
Sends the stop condition to the bus.
diff --git a/share/man/man4/man4.powerpc/Makefile b/share/man/man4/man4.powerpc/Makefile
index 1aea0f0..d8f0fb9 100644
--- a/share/man/man4/man4.powerpc/Makefile
+++ b/share/man/man4/man4.powerpc/Makefile
@@ -2,7 +2,9 @@
MAN= bm.4 \
pmu.4 \
- powermac_nvram.4
+ powermac_nvram.4 \
+ snd_ai2s.4 \
+ snd_davbus.4
MANSUBDIR=/powerpc
diff --git a/share/man/man4/man4.powerpc/snd_ai2s.4 b/share/man/man4/man4.powerpc/snd_ai2s.4
new file mode 100644
index 0000000..eabea34
--- /dev/null
+++ b/share/man/man4/man4.powerpc/snd_ai2s.4
@@ -0,0 +1,90 @@
+.\"-
+.\" Copyright (c) 2009 Nathan Whitehorn <nwhitehorn@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$
+.\"
+.Dd January 20, 2009
+.Dt SND_AI2S 4
+.Os
+.Sh NAME
+.Nm snd_ai2s
+.Nd "Apple I2S audio device 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 sound"
+.Cd "device snd_ai2s"
+.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
+snd_ai2s_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the Apple I2S audio controllers found
+predominantly in G4 and G5 machines, along with the snapper and tumbler
+codecs. Some machines (e.g. the Mac Mini) do not have configurable
+codecs and so lack hardware volume control.
+.Sh HARDWARE
+.Pp
+Chips supported by the
+.Nm
+driver include:
+.Pp
+.Bl -bullet -compact
+.It
+Apple Tumbler Audio
+.It
+Apple Snapper Audio
+.El
+.Pp
+.Sh BUGS
+Recording and operation with non-44.1 Khz audio are not currently supported.
+.Sh SEE ALSO
+.Xr sound 4 ,
+.Xr snd_davbus 4
+.Sh HISTORY
+The
+.Nm
+device driver appeared in
+.Nx 2.0
+and then in
+.Fx 8.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Tsubai Masanari
+.Aq tsubai@netbsd.org ,
+and ported to FreeBSD by
+.An Marco Trillo
+.Aq marcotrillo@gmail.com .
diff --git a/share/man/man4/man4.powerpc/snd_davbus.4 b/share/man/man4/man4.powerpc/snd_davbus.4
new file mode 100644
index 0000000..934886e
--- /dev/null
+++ b/share/man/man4/man4.powerpc/snd_davbus.4
@@ -0,0 +1,83 @@
+.\"-
+.\" Copyright (c) 2009 Nathan Whitehorn <nwhitehorn@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$
+.\"
+.Dd January 20, 2009
+.Dt SND_DAVBUS 4
+.Os
+.Sh NAME
+.Nm snd_davbus
+.Nd "Apple Davbus audio device 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 sound"
+.Cd "device snd_davbus"
+.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
+snd_davbus_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the Apple Davbus audio controllers found in
+many G3-era Apple machines.
+.Sh HARDWARE
+.Pp
+Chips supported by the
+.Nm
+driver include:
+.Pp
+.Bl -bullet -compact
+.It
+Apple Burgundy Audio
+.It
+Apple Screamer Audio
+.El
+.Pp
+.Sh BUGS
+Recording is not currently supported.
+.Sh SEE ALSO
+.Xr sound 4 ,
+.Xr snd_ai2s 4
+.Sh HISTORY
+The
+.Nm
+device driver appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Marco Trillo
+.Aq marcotrillo@gmail.com .
diff --git a/share/man/man4/ng_bpf.4 b/share/man/man4/ng_bpf.4
index 9e6f3d5..4f89729 100644
--- a/share/man/man4/ng_bpf.4
+++ b/share/man/man4/ng_bpf.4
@@ -156,21 +156,14 @@ INHOOK="hook1"
MATCHHOOK="hook2"
NOTMATCHHOOK="hook3"
-cat > /tmp/bpf.awk << xxENDxx
-{
- if (!init) {
- printf "bpf_prog_len=%d bpf_prog=[", \\$1;
- init=1;
- } else {
- printf " { code=%d jt=%d jf=%d k=%d }", \\$1, \\$2, \\$3, \\$4;
- }
-}
-END {
- print " ]"
-}
-xxENDxx
-
-BPFPROG=`tcpdump -s 8192 -ddd ${PATTERN} | awk -f /tmp/bpf.awk`
+BPFPROG=$( tcpdump -s 8192 -ddd ${PATTERN} | \\
+ ( read len ; \\
+ echo -n "bpf_prog_len=$len" ; \\
+ echo -n "bpf_prog=[" ; \\
+ while read code jt jf k ; do \\
+ echo -n " { code=$code jt=$jt jf=$jf k=$k }" ; \\
+ done ; \\
+ echo " ]" ) )
ngctl msg ${NODEPATH} setprogram { thisHook=\\"${INHOOK}\\" \\
ifMatch=\\"${MATCHHOOK}\\" \\
diff --git a/share/man/man4/nge.4 b/share/man/man4/nge.4
index 855ee46..4db964f 100644
--- a/share/man/man4/nge.4
+++ b/share/man/man4/nge.4
@@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 14, 2006
+.Dd January 23, 2009
.Dt NGE 4
.Os
.Sh NAME
@@ -170,6 +170,8 @@ Asante FriendlyNet GigaNIX 1000TA and 1000TPC
.It
D-Link DGE-500T
.It
+Linksys EG1032, revision 1
+.It
Netgear GA621
.It
Netgear GA622T
diff --git a/share/man/man4/rum.4 b/share/man/man4/rum.4
index a1e0ca0..560ab5c 100644
--- a/share/man/man4/rum.4
+++ b/share/man/man4/rum.4
@@ -91,6 +91,7 @@ including:
.It "Belkin F5D7050 ver 3" Ta USB
.It "Belkin F5D9050 ver 3" Ta USB
.It "Buffalo WLI-U2-SG54HP" Ta USB
+.It "Buffalo WLI-U2-SG54HG" Ta USB
.It "Buffalo WLI-U2-G54HP" Ta USB
.It "CNet CWD-854 ver F" Ta USB
.It "Conceptronic C54RU ver 2" Ta USB
diff --git a/share/man/man4/sdhci.4 b/share/man/man4/sdhci.4
index 58635ab..09d4313 100644
--- a/share/man/man4/sdhci.4
+++ b/share/man/man4/sdhci.4
@@ -24,16 +24,29 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 22, 2008
+.Dd January 14, 2009
.Dt SDHCI 4
.Os
.Sh NAME
.Nm sdhci
.Nd PCI SD Host Controller bridge driver
.Sh SYNOPSIS
-.Cd device mmc
-.Cd device mmcsd
-.Cd device sdhci
+To compile this driver into the kernel, place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device mmc"
+.Cd "device mmcsd"
+.Cd "device sdhci"
+.Ed
+.Pp
+Alternatively, to load the driver as a module at boot time, place the
+following lines in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+mmc_load="YES"
+mmcsd_load="YES"
+sdhci_load="YES"
+.Ed
.Sh DESCRIPTION
The
.Nm
@@ -42,6 +55,22 @@ SD Host Controller Specification.
Driver supports up to six high speed 4bit MMC/SD slots per controller.
Driver attaches mmc bus to the respective slot on card insertion and
detaches it on card removing.
+.Sh HARDWARE
+The
+.Nm
+driver supports different specification compatible chips. The following
+chips have been verified to work:
+.Pp
+.Bl -bullet -compact
+.It
+ENE CB712
+.It
+ENE CB714
+.It
+RICOH R5C822
+.It
+TI PCIXX21/XX11
+.El
.Sh SEE ALSO
.Xr mmc 4 ,
.Xr mmcsd 4
@@ -50,3 +79,8 @@ detaches it on card removing.
.Re
.Sh AUTHORS
.An Alexander Motin Aq mav@FreeBSD.org .
+.Sh BUGS
+Many of existing SD controller chips have some nonstandard requirements,
+proprietary registers and hardware bugs, requiring additional handling.
+ENE chips are handled to work fine, while some revisions of RICOH and TI
+controllers still don't see cards without some additional initialization.
diff --git a/share/man/man4/sk.4 b/share/man/man4/sk.4
index bc7cd92..6501905 100644
--- a/share/man/man4/sk.4
+++ b/share/man/man4/sk.4
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 14, 2008
+.Dd January 23, 2009
.Dt SK 4
.Os
.Sh NAME
@@ -82,7 +82,7 @@ second port on dual port adapters for failover purposes: if the link
on the primary port fails, the SysKonnect driver will automatically
switch traffic onto the second port.
.Pp
-Also supported is the Marvell Semiconductor 88E1000* gigabit PHY.
+Also supported is the Marvell Semiconductor 88E100* gigabit PHY.
.Pp
The XaQti XMAC II supports full and half duplex operation with
autonegotiation.
@@ -173,7 +173,7 @@ Belkin F5D5005 single port, 1000baseT adapter
.It
D-Link DGE-530T single port, 1000baseT adapter
.It
-Linksys EG1032 single port, 1000baseT adapter
+Linksys (revision 2) single port, 1000baseT adapter
.It
SK-9521 SK-NET GE-T single port, 1000baseT adapter
.It
diff --git a/share/man/man4/smb.4 b/share/man/man4/smb.4
index 3aa93ad..620b102 100644
--- a/share/man/man4/smb.4
+++ b/share/man/man4/smb.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 25, 1998
+.Dd February 6, 2009
.Dt SMB 4
.Os
.Sh NAME
@@ -72,6 +72,9 @@ The
.Fa slave
field is always used, and provides the address of the
SMBus slave device to talk to.
+The slave address is specified in the seven most significant bits
+.Pq i.e. Dq "left-justified" .
+The least significant bit of the slave address must be zero.
.Pp
.Bl -column ".Dv SMB_QUICK_WRITE" -compact
.It Em Ioctl Ta Em Description
diff --git a/share/man/man4/snd_hda.4 b/share/man/man4/snd_hda.4
index b323fe3..feb6ed2 100644
--- a/share/man/man4/snd_hda.4
+++ b/share/man/man4/snd_hda.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 8, 2008
+.Dd January 7, 2009
.Dt SND_HDA 4
.Os
.Sh NAME
@@ -455,7 +455,8 @@ On headphones connection rear connectors will be muted.
.Sh HARDWARE
The
.Nm
-driver supports the following audio chipsets:
+driver supports many Intel HDA compatible audio chipsets including the
+following:
.Pp
.Bl -bullet -compact
.It
@@ -465,13 +466,17 @@ ATI SB600
.It
Intel 631x/632xESB
.It
-Intel 82801F
+Intel 82801F (ICH6)
.It
-Intel 82801G
+Intel 82801G (ICH7)
.It
-Intel 82801H
+Intel 82801H (ICH8)
.It
-Intel 82801I
+Intel 82801I (ICH9)
+.It
+Intel 82801J (ICH10)
+.It
+Intel US15W (SCH)
.It
nVidia MCP51
.It
@@ -481,6 +486,8 @@ nVidia MCP61A
.It
nVidia MCP61B
.It
+nVidia MCP63
+.It
nVidia MCP65A
.It
nVidia MCP65B
@@ -489,14 +496,16 @@ nVidia MCP67A
.It
nVidia MCP67B
.It
+nVidia MCP68
+.It
+nVidia MCP69
+.It
SiS 966
.It
VIA VT8251/8237A
.El
.Pp
-Generic audio chipsets compatible with the Intel HDA specification should work,
-but have not been verified yet.
-The following codecs have been verified to work:
+The following and many other codecs have been verified to work:
.Pp
.Bl -bullet -compact
.It
@@ -514,9 +523,11 @@ Analog Devices AD1988B
.It
CMedia CMI9880
.It
-Conexant Venice
+Conexant CX20549 (Venice)
+.It
+Conexant CX20551 (Waikiki)
.It
-Conexant Waikiki
+Conexant CX20561 (Hermosa)
.It
Realtek ALC260
.It
@@ -574,10 +585,13 @@ Sigmatel STAC9872AK
.It
VIA VT1708
.It
+VIA VT1708B
+.It
VIA VT1709
.El
.Sh SEE ALSO
.Xr sound 4 ,
+.Xr snd_ich 4 ,
.Xr device.hints 5 ,
.Xr loader.conf 5 ,
.Xr sysctl 8
@@ -606,7 +620,11 @@ rendering the
.Nm
driver useless, which usually results in a state where the
.Nm
-driver seems to attach and work, but without any sound.
+driver seems to attach and work, but without any sound. Some of
+that cases can be solved by tuning loader.conf variables. But before
+trying to fix problem that way, make sure that problem is really exists
+and the PCM audio device you are using really corresponds to expected
+audio connector.
.Pp
Due to OSS limitation multichannel (not multidevice) playback is not
supported.
diff --git a/share/man/man4/snd_ich.4 b/share/man/man4/snd_ich.4
index c415fb8..71f47a7 100644
--- a/share/man/man4/snd_ich.4
+++ b/share/man/man4/snd_ich.4
@@ -24,12 +24,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 15, 2005
+.Dd January 6, 2009
.Dt SND_ICH 4
.Os
.Sh NAME
.Nm snd_ich
-.Nd "Intel ICH PCI and compatible bridge device driver"
+.Nd "Intel ICH AC'97 and compatible bridge device driver"
.Sh SYNOPSIS
To compile this driver into the kernel, place the following lines in your
kernel configuration file:
@@ -49,7 +49,12 @@ The
.Nm
bridge driver allows the generic audio driver
.Xr sound 4
-to attach to Intel ICH and compatible audio devices.
+to attach to Intel ICH AC'97 and compatible audio devices.
+.Pp
+Some later chips, like ICH6/ICH7, depending on wiring can instead implement
+newer Intel HD Audio specification, which is supported by
+.Xr snd_hda 4
+driver.
.Sh HARDWARE
The
.Nm
@@ -94,7 +99,8 @@ NVIDIA nForce4
SiS 7012
.El
.Sh SEE ALSO
-.Xr sound 4
+.Xr sound 4 ,
+.Xr snd_hda 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/sysmouse.4 b/share/man/man4/sysmouse.4
index 96547bc..f439258 100644
--- a/share/man/man4/sysmouse.4
+++ b/share/man/man4/sysmouse.4
@@ -385,7 +385,7 @@ They are intended to replace functions performed by
.Dv MOUSE_ACTION
alone.
.Pp
-.It Dv u
+.It Dv Sq u
This union is one of
.Pp
.Bl -tag -width data -compact
diff --git a/share/man/man4/urtw.4 b/share/man/man4/urtw.4
new file mode 100644
index 0000000..a62fa94
--- /dev/null
+++ b/share/man/man4/urtw.4
@@ -0,0 +1,118 @@
+.\" Copyright (c) 2008 Weongyo Jeong
+.\" 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 November 15 2008 $
+.Dt URTW 4
+.Os
+.Sh NAME
+.Nm urtw
+.Nd Realtek RTL8187L USB IEEE 802.11b/g wireless network device
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device ehci"
+.Cd "device uhci"
+.Cd "device ohci"
+.Cd "device usb"
+.Cd "device urtw"
+.Cd "device wlan"
+.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_urtw_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver supports USB 802.11b/g wireless adapters based on the
+Realtek RTL8187L.
+.Pp
+.Nm
+supports
+.Cm station
+and
+.Cm monitor
+mode operation.
+Only one virtual interface may be configured at any time.
+For more information on configuring this device, see
+.Xr ifconfig 8 .
+.Sh HARDWARE
+The following adapters should work:
+.Pp
+.Bl -column "Card " "Radio " "Bus" -compact -offset 6n
+.It Em "Card Radio Bus"
+.It Li "Netgear WG111v2" Ta RTL8225 Ta USB
+.It Li "Safehome WLG-1500SMA5" Ta RTL8225 Ta USB
+.It Li "Shuttle XPC Accessory PN20" Ta RTL8225 Ta USB
+.El
+.Sh EXAMPLES
+Join an existing BSS network (i.e., connect to an access point):
+.Pp
+.Bd -literal -offset indent
+ifconfig wlan create wlandev urtw0 inet 192.168.0.20 \e
+ netmask 0xffffff00
+.Ed
+.Pp
+Join a specific BSS network with network name
+.Dq Li my_net :
+.Pp
+.Dl "ifconfig wlan create wlandev urtw0 ssid my_net up"
+.Pp
+Join a specific BSS network with 64-bit WEP encryption:
+.Bd -literal -offset indent
+ifconfig wlan create wlandev urtw0 ssid my_net \e
+ wepmode on wepkey 0x1234567890 weptxkey 1 up
+.Ed
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr netintro 4 ,
+.Xr usb 4 ,
+.Xr wlan 4 ,
+.Xr wlan_ccmp 4 ,
+.Xr wlan_tkip 4 ,
+.Xr wlan_wep 4 ,
+.Xr ifconfig 8 ,
+.Xr wpa_supplicant 8
+.Rs
+.%T Realtek
+.%O http://www.realtek.com.tw
+.Re
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Weongyo Jeong
+.Aq weongyo@FreeBSD.org .
diff --git a/share/man/man5/Makefile b/share/man/man5/Makefile
index f7ff059..615ebf1 100644
--- a/share/man/man5/Makefile
+++ b/share/man/man5/Makefile
@@ -51,6 +51,7 @@ MAN= acct.5 \
pbm.5 \
periodic.conf.5 \
phones.5 \
+ portindex.5 \
portsnap.conf.5 \
procfs.5 \
protocols.5 \
diff --git a/share/man/man5/portindex.5 b/share/man/man5/portindex.5
new file mode 100644
index 0000000..f7b126f
--- /dev/null
+++ b/share/man/man5/portindex.5
@@ -0,0 +1,101 @@
+.\"
+.\" Copyright (c) 2004 Paul Armstrong
+.\" Copyright (c) 2009 Thomas Abthorpe
+.\"
+.\" 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 DEVELOPERS ``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 DEVELOPERS 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 January 28, 2009
+.Dt PORTINDEX 5
+.Os
+.Sh NAME
+.Nm INDEX
+.Nd "File containing information about the state of the ports tree"
+.Sh DESCRIPTION
+The port index file in
+.Pa /usr/ports
+contains various bits of information about the ports tree.
+Each major branch of
+.Fx
+has a separate index file, named
+.Dq INDEX- Ns Ar N ,
+where
+.Ar N
+is the major version number of the
+.Fx
+branch, i.e.:
+.Pa INDEX-7 ,
+or
+.Pa INDEX-8 .
+.Bl -tag -compact -width indent
+.It Cm \&name
+The name of the package.
+.It Cm \&path
+The path to the port directory.
+.It Cm \&install prefix
+The default install prefix.
+.It Cm \&short description
+A short description.
+.It Cm \&full description
+The path to the full description.
+.It Cm \&maintainer email
+The email address of the maintainer.
+.It Cm \&index
+The categories this port is part of.
+.It Cm \&build dependencies
+Ports required to be installed prior to building this port.
+.It Cm \&run dependencies
+Ports required to be installed for this port to run.
+.It Cm \&website
+The project website for the port.
+.It Cm \&e-deps
+Ports that may be required to extract this port.
+.It Cm \&p-deps
+Ports that may be required to patch this port.
+.It Cm \&f-deps
+Ports that may be required to fetch this port.
+.El
+.Sh FILES
+.Bl -tag -width /usr/ports/INDEX-8
+.It Pa /usr/ports/INDEX- Ns Ar N
+where
+.Ar N
+is the major version number of the
+.Fx
+branch.
+.El
+.Sh EXAMPLES
+.Bd -literal
+vim-6.3.15|/usr/ports/editors/vim|/usr/local|Vi "workalike", with many additional features|/usr/ports/editors/vim/pkg-descr|obrien@FreeBSD.org|editors|libiconv-1.9.2_1|libiconv-1.9.2_1|http://www.vim.org/|||
+.Ed
+.Sh SEE ALSO
+.Xr build 1 ,
+.Xr csup 1 ,
+.Xr ports 7
+.Sh AUTHORS
+.An -nosplit
+This manual page was written by
+.An Paul Armstrong
+and
+.An Thomas Abthorpe Aq tabthorpe@FreeBSD.org .
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index efb3aa8..afc24c6 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 24, 2008
+.Dd January 27, 2009
.Dt RC.CONF 5
.Os
.Sh NAME
@@ -1089,9 +1089,9 @@ One can configure more than one IPv4 address with the
variable.
One or more IP addresses must be provided in Classless Inter-Domain
Routing (CIDR) address notation, whose last byte can be a range like
-192.168.0.5-23/24.
-In this case the address 192.168.0.5 will be configured with the
-netmask /24 and the addresses 192.168.0.6 to 192.168.0.23 with
+192.0.2.5-23/24.
+In this case the address 192.0.2.5 will be configured with the
+netmask /24 and the addresses 192.0.2.6 to 192.0.2.23 with
the non-conflicting netmask /32 as explained in the
.Xr ifconfig 8
alias section.
@@ -1099,7 +1099,7 @@ With the interface in question being
.Li ed0 ,
an example could look like:
.Bd -literal
-ipv4_addrs_ed0="192.168.0.1/24 192.168.1.1-5/28"
+ipv4_addrs_ed0="192.0.2.129/27 192.0.2.1-5/28"
.Ed
.Pp
It is also possible to add IP alias entries using
@@ -1233,7 +1233,7 @@ variable.
It is also possible to rename interface by doing:
.Bd -literal
ifconfig_ed0_name="net0"
-ifconfig_net0="inet 10.0.0.1 netmask 0xffff0000"
+ifconfig_net0="inet 192.0.2.1 netmask 0xffffff00"
.Ed
.It Va ipv6_network_interfaces
.Pq Vt str
@@ -3188,7 +3188,7 @@ The allowed range of
ranges from \-1 (the compile time default) to 3 (the
most secure).
See
-.Xr init 8
+.Xr security 7
for the list of possible security levels and their effect
on system operation.
.It Va sshd_program
@@ -3309,7 +3309,7 @@ Assuming that the jail in question was named
you would have the following dependent variables:
.Bd -literal
jail_vjail_hostname="jail.example.com"
-jail_vjail_ip="192.168.1.100"
+jail_vjail_ip="192.0.2.100"
jail_vjail_rootdir="/var/jails/vjail/root"
.Ed
.Pp
@@ -3426,8 +3426,38 @@ Set to the fully qualified domain name (FQDN) assigned to jail
.It Va jail_ Ns Ao Ar jname Ac Ns Va _ip
.Pq Vt str
Unset by default.
-Set to the IP address assigned to jail
-.Va jname .
+Set to the (primary) IPv4 and/or IPv6 address(es) assigned to the jail.
+The argument can be a sole address or a comma separated list of addresses.
+Additionally each address can be prefixed by the name of an interface
+followed by a pipe to overwrite
+.Va jail_ Ns Ao Ar jname Ac Ns Va _interface
+or
+.Va jail_interface
+and/or suffixed by a netmask, prefixlen or prefix.
+In case no netmask, prefixlen or prefix is given,
+.Sq /32
+will be used for IPv4 and
+.Sq /128
+will be used for an IPv6 address.
+If no address is given for the jail then the jail will be started with
+no networking support.
+.It Va jail_ Ns Ao Ar jname Ac Ns Va _ip_multi Ns Aq Ar n
+.Pq Vt str
+Unset by default.
+Set additional IPv4 and/or IPv6 address(es) assigned to the jail.
+The sequence starts with
+.Dq Li _multi0
+and the numbers have to be strictly ascending.
+These entries follow the same syntax as their primary
+.Va jail_ Ns Ao Ar jname Ac Ns Va _ip
+entry.
+The order of the entries can be important as the first address for
+each address family found will be the primary address of the jail.
+See
+.Va ip-addresses
+option in
+.Xr jail 8
+for more details.
.It Va jail_ Ns Ao Ar jname Ac Ns Va _flags
.Pq Vt str
Set to
@@ -3440,12 +3470,6 @@ These are flags to pass to
Unset by default.
When set, sets the interface to use when setting IP address alias.
Note that the alias is created at jail startup and removed at jail shutdown.
-.It Va jail_ Ns Ao Ar jname Ac Ns Va _netmask
-.Pq Vt str
-Set to
-.Li 255.255.255.255
-by default.
-This is the IP netmask to use when setting IP address alias.
.It Va jail_ Ns Ao Ar jname Ac Ns Va _fib
.Pq Vt str
Unset by default.
@@ -3987,6 +4011,7 @@ Default
.Xr motd 5 ,
.Xr newsyslog.conf 5 ,
.Xr pf.conf 5 ,
+.Xr security 7 ,
.Xr accton 8 ,
.Xr amd 8 ,
.Xr apm 8 ,
diff --git a/share/man/man7/Makefile b/share/man/man7/Makefile
index fbe29d6..d979a64 100644
--- a/share/man/man7/Makefile
+++ b/share/man/man7/Makefile
@@ -2,7 +2,8 @@
# $FreeBSD$
#MISSING: eqnchar.7 ms.7 term.7
-MAN= ascii.7 \
+MAN= adding_user.7 \
+ ascii.7 \
bsd.snmpmod.mk.7 \
build.7 \
clocks.7 \
diff --git a/share/man/man8/adding_user.8 b/share/man/man7/adding_user.7
index 2f4dab1..1b467714 100644
--- a/share/man/man8/adding_user.8
+++ b/share/man/man7/adding_user.7
@@ -32,7 +32,7 @@
.\" @(#)adduser.8 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd June 5, 1993
+.Dd Jan 30, 2009
.Dt ADDING_USER 8
.Os
.Sh NAME
@@ -108,10 +108,3 @@ skeletal login directory
.Xr adduser 8 ,
.Xr pwd_mkdb 8 ,
.Xr vipw 8
-.Sh HISTORY
-The
-.Nm
-utility appeared in
-.Bx 3.0 .
-.Sh BUGS
-User information should (and eventually will) be stored elsewhere.
diff --git a/share/man/man7/build.7 b/share/man/man7/build.7
index 9e5ca59..4a94a0a 100644
--- a/share/man/man7/build.7
+++ b/share/man/man7/build.7
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 1, 2006
+.Dd January 23, 2009
.Dt BUILD 7
.Os
.Sh NAME
@@ -335,6 +335,25 @@ are influenced by the following
.Xr make 1
variables:
.Bl -tag -width ".Va SUBDIR_OVERRIDE"
+.It Va KERNCONF
+Overrides which kernel to build and install for the various kernel
+make targets.
+It defaults to
+.Cm GENERIC .
+.It Va KERNFAST
+If set, the build target
+.Cm buildkernel
+defaults to setting
+.Va NO_KERNELCLEAN ,
+.Va NO_KERNELCONFIG
+and
+.Va NO_KERNELDEPEND .
+When set to a value other than
+.Cm 1
+then
+.Va KERNCONF
+is set to the value of
+.Va KERNFAST .
.It Va LOCAL_DIRS
If set, this variable supplies a list of additional directories to
build, relative to the root of the source tree.
@@ -370,6 +389,71 @@ defaults to the current machine architecture, unless
.Va TARGET
is also set, in which case it defaults to the appropriate
value for that platform.
+Typically, one only needs to set
+.Va TARGET .
+.El
+.Pp
+Builds under directory
+.Pa /usr/src
+are also influenced by defining one or more the following symbols,
+using the
+.Fl D
+option of
+.Xr make 1 :
+.Bl -tag -width ".Va -DNO_KERNELDEPEND"
+.It Va NO_CLEANDIR
+If set, the build targets that clean parts of the object tree use the
+equivalent of
+.Dq make clean
+instead of
+.Dq make cleandir .
+.It Va NO_CLEAN
+If set, no object tree files are cleaned at all.
+Setting
+.Va NO_CLEAN
+implies
+.Va NO_KERNELCLEAN ,
+so when
+.Va NO_CLEAN
+is set no kernel objects are cleaned either.
+.It Va NO_CTF
+If set, the build process does not run the DTrace CTF conversion tools
+on built objects.
+.It Va NO_SHARE
+If set, the build does not descend into the
+.Pa /usr/src/share
+subdirectory (i.e. manpages, locale data files, timezone data files and
+other
+.Pa /usr/src/share
+files will not be rebuild from their sources).
+.It Va NO_KERNELCLEAN
+If set, the build process does not run
+.Dq make clean
+as part of the
+.Cm buildkernel
+target.
+.It Va NO_KERNELCONFIG
+If set, the build process does not run
+.Xr config 8
+as part of the
+.Cm buildkernel
+target.
+.It Va NO_KERNELDEPEND
+If set, the build process does not run
+.Dq make depend
+as part of the
+.Cm buildkernel
+target.
+.It Va NO_DOCUPDATE
+If set, the update process does not update the source of the
+.Fx
+documentation as part of the
+.Dq make update
+target.
+.It Va NO_PORTSUPDATE
+If set, the update process does not update the Ports tree as part of the
+.Dq make update
+target.
.El
.Pp
Builds under directory
diff --git a/share/man/man7/ports.7 b/share/man/man7/ports.7
index 0d79913..bcbb2ab 100644
--- a/share/man/man7/ports.7
+++ b/share/man/man7/ports.7
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 22, 2008
+.Dd January 21, 2009
.Dt PORTS 7
.Os
.Sh NAME
@@ -196,11 +196,14 @@ Fetch the distfiles of the port and all its dependencies.
.It Cm fetch-recursive-list
Show list of files that would be retrieved by
.Cm fetch-recursive .
+.It Cm run-depends-list , build-depends-list
+Print a list of all the compile and run dependencies, and dependencies
+of those dependencies, by port directory.
.It Cm all-depends-list
Print a list of all dependencies for the port.
.It Cm pretty-print-run-depends-list , pretty-print-build-depends-list
Print a list of all the compile and run dependencies, and dependencies
-of those dependencies.
+of those dependencies, by port name and version.
.It Cm missing
Print a list of missing dependencies to be installed for the port.
.It Cm clean
@@ -251,6 +254,8 @@ and
Like
.Cm package ,
but makes a package for each depending port as well.
+.It Cm package-name
+Prints the name with version of the port.
.It Cm readmes
Create a port's
.Pa README.html .
diff --git a/share/man/man7/tuning.7 b/share/man/man7/tuning.7
index 45aee26..538f441 100644
--- a/share/man/man7/tuning.7
+++ b/share/man/man7/tuning.7
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 19, 2007
+.Dd January 23, 2009
.Dt TUNING 7
.Os
.Sh NAME
@@ -402,6 +402,19 @@ In this document we will only cover the ones that have the greatest effect
on the system.
.Pp
The
+.Va kern.ipc.maxpipekva
+loader tunable is used to set a hard limit on the
+amount of kernel address space allocated to mapping of pipe buffers.
+Use of the mapping allows the kernel to eliminate a copy of the
+data from writer address space into the kernel, directly copying
+the content of mapped buffer to the reader.
+Increasing this value to a higher setting, such as `25165824' might
+improve performance on systems where space for mapping pipe buffers
+is quickly exhausted.
+This exhaustion is not fatal; however, and it will only cause pipes to
+to fall back to using double-copy.
+.Pp
+The
.Va kern.ipc.shm_use_phys
sysctl defaults to 0 (off) and may be set to 0 (off) or 1 (on).
Setting
diff --git a/share/man/man8/Makefile b/share/man/man8/Makefile
index 0d27aea..0b16544 100644
--- a/share/man/man8/Makefile
+++ b/share/man/man8/Makefile
@@ -1,8 +1,7 @@
# @(#)Makefile 8.1 (Berkeley) 6/5/93
# $FreeBSD$
-MAN= adding_user.8 \
- crash.8 \
+MAN= crash.8 \
diskless.8 \
intro.8 \
MAKEDEV.8 \
@@ -13,8 +12,7 @@ MAN= adding_user.8 \
rc.subr.8 \
rescue.8 \
sticky.8 \
- yp.8 \
- alias_sctp.8
+ yp.8
MLINKS= rc.8 rc.atm.8 \
rc.8 rc.d.8 \
diff --git a/share/man/man8/alias_sctp.8 b/share/man/man8/alias_sctp.8
deleted file mode 100644
index 5767535..0000000
--- a/share/man/man8/alias_sctp.8
+++ /dev/null
@@ -1,241 +0,0 @@
-.\" * Copyright (c) 2008, Centre for Advanced Internet Architectures
-.\" * Swinburne University of Technology, Melbourne, Australia
-.\" * (CRICOS number 00111D).
-.\" *
-.\" * Alias_sctp forms part of the libalias kernel module to handle
-.\" * Network Address Translation (NAT) for the SCTP protocol.
-.\" *
-.\" * This software was developed by David A. Hayes and Jason But
-.\" *
-.\" * The design is outlined in CAIA technical report number 080618A
-.\" * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW")
-.\" *
-.\" * Development is part of the CAIA SONATA project,
-.\" * proposed by Jason But and Grenville Armitage:
-.\" * http://caia.swin.edu.au/urp/sonata/
-.\" *
-.\" *
-.\" * This project has been made possible in part by a grant from
-.\" * the Cisco University Research Program Fund at Community
-.\" * Foundation Silicon Valley.
-.\" *
-.\" *
-.\" *
-.\" * 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. The names of the authors, the "Centre for Advanced Internet Architectures"
-.\" * and "Swinburne University of Technology" may not be used to endorse
-.\" * or promote products derived from this software without specific
-.\" * prior written permission.
-.\" *
-.\" * 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.
-.TH ALIAS_SCTP 8 "30 September 08" "version 0.2"
-.SH NAME
-alias_sctp - SCTP NAT functionality for libalias in FreeBSD
-.SH SYNOPSIS
-.B alias_sctp \- libalias enhancements to support SCTP NAT
-.PP
-.B ipfw \- Extensions to user-land tool to configure SCTP NAT
-.PP
-.B sysctl net.inet.ip.alias.sctp.* \- sysctl interface to alias_sctp
-./"========================================================================="
-.SH DESCRIPTION
-.B alias_sctp
-is a kernel space addition to libalias that implements NAT for SCTP within the
-.B ipfw2
-framework for FreeBSD. The
-.B alias_sctp
-implementation is based on the details provided in Internet Draft xxxxx and our
-own ideas discovered during implementation.
-.B alias_sctp
-is a dynamically configurable NAT module that supports the following functionality:
-.IP o
-Optional support for tracking of Global IP Addresses (see Internet Draft xxxx)
-.IP o
-Dynamically configurable timeouts for various states within the NAT
-.IP o
-Dynamically configurable packet parsing limits (to protect against DoS attacks)
-.IP o
-Per port/IP-address forwarding of incoming associations
-.IP o
-Dynamically configurable hash table size and logging details
-.IP o
-NAT configured via user-land
-.B ipfw
-tool
-.IP o
-NAT statistics available via
-.B ipfw
-user-land command
-./"========================================================================="
-.SH USING alias_sctp
-.SS Configuring alias_sctp via ipfw
-.B Alias_sctp
-can be configured in a simillar manner to TCP through the ipfw command line tool
-(see ipfw(8)). The main difference in configuring SCTP NAT rules, is that
-.B alias_sctp
-does not do port translation. Since the local and global side ports will be the
-same, there is no need to specify both. Ports are redirected as follows:
-.IP
-.B ipfw nat
-inst#
-.B config if
-nic
-.B redirect_port sctp
-ip-addr [,addr-list] {port | port-port] [,ports]}
-./"========================================================================="
-.SH "sysctl" INTERFACE
-Most
-.B alias_sctp
-configuration can be done in real-time through the
-.B sysctl(8)
-interface. All may be changed dynamically, though the hash_table size will only
-change for new NAT instances. Default values are also listed below.
-
-.SS net.inet.ip.alias.sctp.hashtable_size (Default = 2003)
-Size of hash tables used for NAT lookups (100 < prime_number > 1000001)
-This value sets the hash table size for any _future_ created NAT
-instance and therefore must be set prior to creating a NAT instance (ie
-ipfw nat 100 config ...).
-.PP
-The table sizes my be changed to suit specific needs. If there will be few
-concurrent associations, and memory is scarce, you may make these smaller. If
-there will be many thousands (or millions) of concurrent associations, you
-should make these larger. A prime number is best for the table size. The sysctl
-update function will adjust your input value to the next highest prime number.
-
-.SS net.inet.ip.alias.sctp.error_on_ootb (Default = 1)
-Defines when the NAT responds to any Out-of-the-Blue (OOTB) packets with ErrorM
-packets. An OOTB packet is a packet that arrives with no existing association
-registered in the NAT AND is not an INIT or ASCONF-AddIP packet:
-.PP
-.IP "0 \-"
-ErrorM is never sent in response to OOTB packets
-.IP "1 \-"
-ErrorM is only sent to OOTB packets received on the local side
-.IP "2 \-"
-ErrorM is sent to the local side and on the global side ONLY if there is a
-partial match (ports and vtags match but the source global IP does not). This
-value is only useful if the NAT is tracking global IP addresses
-.IP "3 \-"
-ErrorM is sent in response to all OOTB packets on both the local and global side
-(DoS risk)
-.PP
-At the moment the default is 0, since the ErrorM packet is not yet
-supported by most SCTP stacks. When it is supported, and if not tracking
-global addresses we recommend setting this value to 1 to allow
-multi-homed local hosts to function with the NAT. If tracking global addresses
-we recommend setting this value to 2 to allow global hosts to be informed when
-they need to (re)send an ASCONF-AddIP. Value 3 should never be chosen (except
-for debugging) as the NAT will respond to all OOTB global packets (a DoS risk).
-
-.SS net.inet.ip.alias.sctp.accept_global_ootb_addip (Default = 0)
-Defines how the NAT responds to receipt of global OOTB ASCONF-AddIP:
-.PP
-.IP "0 \-"
-No response (unless a partially matching association exists -
-ports and vtags match but global address does not)
-.IP "1 \-"
-NAT will accept and process all OOTB global AddIP messages.
-.PP
-Option 1 should never be selected as this forms a security risk. An attacker can
-establish multiple fake associations by sending AddIP messages.
-
-.SS net.inet.ip.alias.sctp.initialising_chunk_proc_limit (Default = 2)
-Defines the maximum number of chunks in an SCTP packet that will be parsed when
-no existing association exists that matches that packet. Ideally this packet
-will only be an INIT or ASCONF-AddIP packet. A higher value may become a DoS
-risk as malformed packets can consume processing resources.
-
-.SS net.inet.ip.alias.sctp.chunk_proc_limit (Default = 5)
-Defines the maximum number of chunks in an SCTP packet that will be parsed for a
-packet that matches an existing association. This value is enforced to be >=
-(initialising_chunk_proc_limit). As for the previous parameter, a high value is
-a DoS risk yet setting too low a value may result in important control chunks in
-the packet not being located and parsed.
-
-.SS net.inet.ip.alias.sctp.param_proc_limit (Default = 25)
-Defines the maximum number of parameters within a chunk that will be parsed in a
-packet. As for other similar sysctl variables, larger values pose a DoS risk.
-
-.SS net.inet.ip.alias.sctp.track_global_addresses (Default = 0)
-Enables/disables global IP address tracking within the NAT and places an
-upper limit on the number of addresses tracked for each association:
-.PP
-.IP "0 \-"
-Global tracking is disabled
-.IP ">1 \-"
-Enables tracking, the maximum number of addresses tracked for each
-association is limited to this value
-.PP
-This variable is fully dynamic, the new value will be adopted for all newly
-arriving associations, existing association are treated as they were previously.
-Global tracking will decrease the number of collisions within the NAT at a cost
-of increased processing load, memory usage, complexity, and possible NAT state
-problems in complex networks with multiple NATs. We recommend not tracking
-global IP addresses, this will still result in a fully functional NAT.
-
-.SS net.inet.ip.alias.sctp.init_timer (Default = 15)
-Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK).
-This value cannot be 0.
-
-.SS net.inet.ip.alias.sctp.up_timer (Default = 300)
-Timeout value (s) to keep an association up with no traffic.
-This value cannot be 0.
-
-.SS net.inet.ip.alias.sctp.shutdown_time (Default = 15)
-Timeout value (s) while waiting for SHUTDOWN-COMPLETE.
-This value cannot be 0.
-
-.SS net.inet.ip.alias.sctp.holddown_time (Default = 0)
-Hold association in table for this many seconds after receiving a
-SHUTDOWN-COMPLETE. This allows endpoints to correct shutdown gracefully if a
-shutdown_complete is lost and retransmissions are required. This
-net.inet.ip.alias.sctp.log_level (Default = 0) Level of detail in the system log
-messages (0 \- minimal, 1 \- event, 2 \- info, 3 \- detail, 4 \- debug, 5 \- max
-debug)
-.PP
-May be a good option in high loss environments.
-
-.SH "SEE ALSO"
-.BR ipfw (8),
-.BR libalias (8),
-.BR sysctl (8)
-.SH AUTHOR
-.B alias_sctp
-has been developed and released by:
-
-The Centre for Advanced Internet Architectures (CAIA), Swinburne University,
-Melbourne, Australia.
-.IP
-.I http://www.caia.swin.edu.au
-.LP
-The primary developers and maintainers of
-.B alias_sctp
-are David Hayes and Jason But.
-
-.B alias_sctp
-can be downloaded from its website:
-.IP
-.I http://www.caia.swin.edu.au/urp/SONATA
-.LP
-This site contains the latest updates and further information on how to use and
-.B alias_sctp
diff --git a/share/man/man9/dev_clone.9 b/share/man/man9/dev_clone.9
index ce3774a..4fa9367 100644
--- a/share/man/man9/dev_clone.9
+++ b/share/man/man9/dev_clone.9
@@ -24,7 +24,9 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 8, 2008
+.Dd January 3, 2009
+.Dt DEV_CLONE 9
+.Os
.Sh NAME
.Nm dev_clone ,
.Nm drain_dev_clone_events
@@ -40,11 +42,11 @@ EVENTHANDLER_REGISTER(dev_clone, clone_handler, arg, priority);
.Ft void
.Fn drain_dev_clone_events
.Sh DESCRIPTION
-Device driver may register a listener that will be notified each time
-name lookup on the
-.Xr devfs
+A device driver may register a listener that will be notified each time
+a name lookup on the
+.Xr devfs 5
mount point fails to find the vnode.
-Listener shall be registered for the
+A listener shall be registered for the
.Va dev_clone
event.
When called, it is supplied with the first argument
@@ -52,23 +54,25 @@ When called, it is supplied with the first argument
that was specified at handler registration time,
appropriate credentials
.Va cr ,
+and a name
.Va name
-of the length
+of length
.Va namelen
-that was looked for.
-If handler decides that the name is appropriate and want to create device
-that will be associated with the name, it should return it to the devfs
+that we look for.
+If the handler decides that the name is appropriate and wants to create the device
+that will be associated with the name, it should return it to devfs
in the
-.Va dev .
+.Va dev
+argument.
.Pp
The
.Fn drain_dev_clone_events
function is a barrier.
-It is guaranteed that all calls to eventhandlers for dev_clone that were
-started before
+It is guaranteed that all calls to eventhandlers for
+.Nm dev_clone
+that were started before
.Fn drain_dev_clone_events
call, are finished before it returns control.
-.Pp
.Sh SEE ALSO
.Xr devfs 5 ,
.Xr namei 9
diff --git a/share/man/man9/domain.9 b/share/man/man9/domain.9
index b406d90..e868c97 100644
--- a/share/man/man9/domain.9
+++ b/share/man/man9/domain.9
@@ -94,8 +94,6 @@ struct protosw {
pr_output_t *pr_output; /* output to protocol (from above) */
pr_ctlinput_t *pr_ctlinput; /* control input (from below) */
pr_ctloutput_t *pr_ctloutput; /* control output (from above) */
-/* user-protocol hook */
- pr_usrreq_t *pr_ousrreq;
/* utility hooks */
pr_init_t *pr_init;
pr_fasttimo_t *pr_fasttimo; /* fast timeout (200ms) */
diff --git a/share/man/man9/insmntque.9 b/share/man/man9/insmntque.9
index 204d288..de506e4 100644
--- a/share/man/man9/insmntque.9
+++ b/share/man/man9/insmntque.9
@@ -46,7 +46,7 @@ The
function associates a vnode with a mount.
This includes updating
.Va v_mount
-for the vnode, and inserting the vnode into the mounts vnode list.
+for the vnode, and inserting the vnode into the mount's vnode list.
.Pp
The mount reference count is incremented for each vnode added to the
mount, and that reference is decremented by
@@ -75,13 +75,14 @@ The
.Fa dtr_arg
argument is the second, supplying any additional context needed.
.Sh RETURN VALUES
+The
.Fn insmntque
-will always return 0, unless the file system is currently being unmounted
+function will always return 0, unless the file system is currently being unmounted
in which case it may return
.Dv EBUSY .
-The
+Also,
.Fn insmntque
-function may be forced to insert the vnode into the mount's vnode list
+may be forced to insert the vnode into the mount's vnode list
by setting the
.Va VV_FORCEINSMQ
flag in the vnode
diff --git a/share/man/man9/kthread.9 b/share/man/man9/kthread.9
index 148a34e..29d678c 100644
--- a/share/man/man9/kthread.9
+++ b/share/man/man9/kthread.9
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 26, 2007
+.Dd January 26, 2009
.Dt KTHREAD 9
.Os
.Sh NAME
@@ -43,12 +43,6 @@
.Fn kthread_start "const void *udata"
.Ft void
.Fn kthread_shutdown "void *arg" "int howto"
-.Ft int
-.Fo kthread_add
-.Fa "void (*func)(void *)" "void *arg" "struct proc *procp"
-.Fa "struct thread **newtdpp" "int flags" "int pages"
-.Fa "const char *fmt" ...
-.Fc
.Ft void
.Fn kthread_exit "void"
.Ft int
@@ -57,6 +51,13 @@
.Fn kthread_suspend "struct thread *td" "int timo"
.Ft void
.Fn kthread_suspend_check "struct thread *td"
+.In sys/unistd.h
+.Ft int
+.Fo kthread_add
+.Fa "void (*func)(void *)" "void *arg" "struct proc *procp"
+.Fa "struct thread **newtdpp" "int flags" "int pages"
+.Fa "const char *fmt" ...
+.Fc
.Ft int
.Fo kproc_kthread_add
.Fa "void (*func)(void *)" "void *arg"
@@ -142,8 +143,12 @@ If this argument is
then it is ignored.
The
.Fa flags
-argument specifies a set of flags as described in
-.Xr rfork 2 .
+argument may be set to
+.Dv RFSTOPPED
+to leave the thread in a stopped state.
+The caller must call
+.Fn sched_add
+to start the thread.
The
.Fa pages
argument specifies the size of the new kernel thread's stack in pages.
@@ -274,23 +279,10 @@ The
.Fn kthread_add
function will fail if:
.Bl -tag -width Er
-.It Bq Er EAGAIN
-The system-imposed limit on the total
-number of processes under execution would be exceeded.
-The limit is given by the
-.Xr sysctl 3
-MIB variable
-.Dv KERN_MAXPROC .
-.It Bq Er EINVAL
-The
-.Dv RFCFDG
-flag was specified in the
-.Fa flags
-parameter.
+.It Bq Er ENOMEM
+Memory for a thread's stack could not be allocated.
.El
.Sh SEE ALSO
-.Xr rfork 2 ,
-.Xr exit1 9 ,
.Xr kproc 9 ,
.Xr SYSINIT 9 ,
.Xr wakeup 9
diff --git a/share/man/man9/lock.9 b/share/man/man9/lock.9
index 99af66f..d2edc0e 100644
--- a/share/man/man9/lock.9
+++ b/share/man/man9/lock.9
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 12, 2008
+.Dd February 05, 2009
.Dt LOCK 9
.Os
.Sh NAME
@@ -279,14 +279,6 @@ lock pointed to by the first argument.
Assert that the current thread has no lock on the
.Vt lkp
lock pointed to by the first argument.
-.It Dv KA_HELD
-Assert that an unspecified thread has a lock on the
-.Vt lkp
-lock pointed to by the first argument.
-.It Dv KA_UNHELD
-Assert that no thread has a lock on the
-.Vt lkp
-lock pointed to by the first argument.
.El
.Pp
In addition, one of the following optional assertions can be used with
@@ -305,15 +297,6 @@ Assert that the current thread does not have a recursed lock on
.Fa lkp .
.El
.Pp
-Note that
-.Dv KA_HELD
-and
-.Dv KA_UNHELD
-usage is highly discouraged.
-They are intended to cater a bad behaviour
-introduced by buffer cache lock handling.
-They will hopefully be
-made useless by revisiting such locks.
.Sh RETURN VALUES
The
.Fn lockmgr
diff --git a/share/man/man9/redzone.9 b/share/man/man9/redzone.9
index ef3cb53..98723c7 100644
--- a/share/man/man9/redzone.9
+++ b/share/man/man9/redzone.9
@@ -24,13 +24,15 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 31, 2006
+.Dd January 9, 2009
.Dt REDZONE 9
.Os
.Sh NAME
.Nm RedZone
.Nd "buffer corruptions detector"
.Sh SYNOPSIS
+.Cd "options KDB"
+.Cd "options DDB"
.Cd "options DEBUG_REDZONE"
.Sh DESCRIPTION
.Nm
diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree
index aa043bf..8e247a6 100644
--- a/share/misc/bsd-family-tree
+++ b/share/misc/bsd-family-tree
@@ -221,9 +221,13 @@ FreeBSD 5.2 | | | |
*--FreeBSD | | | | DragonFly 1.12.0
| 7.0 | | | | |
| | | | | OpenBSD 4.3 |
- | V | | | | DragonFly 2.0.0
- | FreeBSD | | OpenBSD 4.4 |
- | 6.4 | | | |
+ | | | | | | DragonFly 2.0.0
+ | | FreeBSD | | OpenBSD 4.4 |
+ | | 6.4 | | | |
+ | | | | | |
+ | FreeBSD 7.1 | | | |
+ | | | | | |
+ | V | | | |
| | | | |
FreeBSD 8 -current | NetBSD -current OpenBSD -current |
| | | | |
@@ -490,6 +494,7 @@ OpenBSD 4.3 2008-05-01 [OBD]
DragonFly 2.0.0 2008-07-21 [DFB]
OpenBSD 4.4 2008-11-01 [OBD]
FreeBSD 6.4 2008-11-28 [FBD]
+FreeBSD 7.1 2009-01-04 [FBD]
Bibliography
------------------------
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index 78ce794..a0e09b8 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -102,6 +102,7 @@ iedowse [label="Ian Dowse\niedowse@FreeBSD.org\n2000/12/01"]
imp [label="Warner Losh\nimp@FreeBSD.org\n1996/09/20"]
ivoras [label="Ivan Voras\nivoras@FreeBSD.org\n2008/06/10"]
jake [label="Jake Burkholder\njake@FreeBSD.org\n2000/05/16"]
+jamie [label="Jamie Gritton\njamie@FreeBSD.org\n2009/01/28"]
jayanth [label="Jayanth Vijayaraghavan\njayanth@FreeBSD.org\n2000/05/08"]
jinmei [label="JINMEI Tatuya\njinmei@FreeBSD.org\n2007/03/17"]
jdp [label="John Polstra\njdp@FreeBSD.org\n????/??/??"]
@@ -219,7 +220,9 @@ bms -> thompsa
brian -> joe
brooks -> bushman
+brooks -> jamie
+bz -> jamie
bz -> syrinx
cperciva -> flz
diff --git a/share/misc/pci_vendors b/share/misc/pci_vendors
index 8a4a835..dff3595 100644
--- a/share/misc/pci_vendors
+++ b/share/misc/pci_vendors
@@ -4606,7 +4606,7 @@
6041 MV88SX6041 Marvell Technology Group Ltd. MV88SX6041 4-port SATA II PCI-X Controller (rev 03)
6042 MV88SX6042 4-port SATA II PCI-X Controller
6081 MV88SX6081 8-port SATA II PCI-X Controller
- 6101 6101 SATA2 Controller
+ 6101 MV88SX6101 1-port UltraATA/133 Controller
6111 6111 SATA2 Controller
6120 6120 SATA2 Controller
6121 6121 SATA2 Controller
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index ebcc60f..0a364af 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -14,6 +14,7 @@ LIBALIAS?= ${DESTDIR}${LIBDIR}/libalias.a
LIBARCHIVE?= ${DESTDIR}${LIBDIR}/libarchive.a
LIBASN1?= ${DESTDIR}${LIBDIR}/libasn1.a
LIBATM?= ${DESTDIR}${LIBDIR}/libatm.a
+LIBAUDITD?= ${DESTDIR}${LIBDIR}/libauditd.a
LIBAVL?= ${DESTDIR}${LIBDIR}/libavl.a
LIBBEGEMOT?= ${DESTDIR}${LIBDIR}/libbegemot.a
.if ${MK_BIND_LIBS} != "no"
diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk
index 5910a13..7912430 100644
--- a/share/mk/bsd.own.mk
+++ b/share/mk/bsd.own.mk
@@ -44,9 +44,9 @@
# KMODDIR Base path for loadable kernel modules
# (see kld(4)). [/boot/kernel]
#
-# KMODOWN KLD owner. [${BINOWN}]
+# KMODOWN Kernel and KLD owner. [${BINOWN}]
#
-# KMODGRP KLD group. [${BINGRP}]
+# KMODGRP Kernel and KLD group. [${BINGRP}]
#
# KMODMODE KLD mode. [${BINMODE}]
#
diff --git a/share/zoneinfo/asia b/share/zoneinfo/asia
index eb9f411..7eedb2b 100644
--- a/share/zoneinfo/asia
+++ b/share/zoneinfo/asia
@@ -1,4 +1,4 @@
-# @(#)asia 8.24
+# @(#)asia 8.25
# <pre>
# This data is by no means authoritative; if you think you know better,
@@ -1474,7 +1474,7 @@ Zone Asia/Choibalsan 7:38:00 - LMT 1905 Aug
# Nepal
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Katmandu 5:41:16 - LMT 1920
+Zone Asia/Kathmandu 5:41:16 - LMT 1920
5:30 - IST 1986
5:45 - NPT # Nepal Time
diff --git a/share/zoneinfo/backward b/share/zoneinfo/backward
index a65991c..e3f5429 100644
--- a/share/zoneinfo/backward
+++ b/share/zoneinfo/backward
@@ -1,4 +1,4 @@
-# @(#)backward 8.6
+# @(#)backward 8.7
# This file provides links between current names for time zones
# and their old names. Many names changed in late 1993.
@@ -24,6 +24,7 @@ Link America/St_Thomas America/Virgin
Link Asia/Ashgabat Asia/Ashkhabad
Link Asia/Chongqing Asia/Chungking
Link Asia/Dhaka Asia/Dacca
+Link Asia/Kathmandu Asia/Katmandu
Link Asia/Kolkata Asia/Calcutta
Link Asia/Macau Asia/Macao
Link Asia/Jerusalem Asia/Tel_Aviv
diff --git a/share/zoneinfo/europe b/share/zoneinfo/europe
index 7bb9864..09f3e1e 100644
--- a/share/zoneinfo/europe
+++ b/share/zoneinfo/europe
@@ -1,4 +1,4 @@
-# @(#)europe 8.18
+# @(#)europe 8.20
# <pre>
# This data is by no means authoritative; if you think you know better,
@@ -2313,11 +2313,64 @@ Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1
# mean time in preference to apparent time -- Geneva from 1780 ....
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
# From Whitman (who writes ``Midnight?''):
-Rule Swiss 1940 only - Nov 2 0:00 1:00 S
-Rule Swiss 1940 only - Dec 31 0:00 0 -
+# Rule Swiss 1940 only - Nov 2 0:00 1:00 S
+# Rule Swiss 1940 only - Dec 31 0:00 0 -
# From Shanks & Pottenger:
-Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S
-Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 -
+# Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S
+# Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 -
+
+# From Alois Treindl (2008-12-17):
+# I have researched the DST usage in Switzerland during the 1940ies.
+#
+# As I wrote in an earlier message, I suspected the current tzdata values
+# to be wrong. This is now verified.
+#
+# I have found copies of the original ruling by the Swiss Federal
+# government, in 'Eidgen[o]ssische Gesetzessammlung 1941 and 1942' (Swiss
+# federal law collection)...
+#
+# DST began on Monday 5 May 1941, 1:00 am by shifting the clocks to 2:00 am
+# DST ended on Monday 6 Oct 1941, 2:00 am by shifting the clocks to 1:00 am.
+#
+# DST began on Monday, 4 May 1942 at 01:00 am
+# DST ended on Monday, 5 Oct 1942 at 02:00 am
+#
+# There was no DST in 1940, I have checked the law collection carefully.
+# It is also indicated by the fact that the 1942 entry in the law
+# collection points back to 1941 as a reference, but no reference to any
+# other years are made.
+#
+# Newspaper articles I have read in the archives on 6 May 1941 reported
+# about the introduction of DST (Sommerzeit in German) during the previous
+# night as an absolute novelty, because this was the first time that such
+# a thing had happened in Switzerland.
+#
+# I have also checked 1916, because one book source (Gabriel, Traite de
+# l'heure dans le monde) claims that Switzerland had DST in 1916. This is
+# false, no official document could be found. Probably Gabriel got misled
+# by references to Germany, which introduced DST in 1916 for the first time.
+#
+# The tzdata rules for Switzerland must be changed to:
+# Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S
+# Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 -
+#
+# The 1940 rules must be deleted.
+#
+# One further detail for Switzerland, which is probably out of scope for
+# most users of tzdata:
+# The zone file
+# Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
+# 0:29:44 - BMT 1894 Jun #Bern Mean Time
+# 1:00 Swiss CE%sT 1981
+# 1:00 EU CE%sT
+# describes all of Switzerland correctly, with the exception of
+# the Cantone Geneve (Geneva, Genf). Between 1848 and 1894 Geneve did not
+# follow Bern Mean Time but kept its own local mean time.
+# To represent this, an extra zone would be needed.
+
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S
+Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
0:29:44 - BMT 1894 Jun # Bern Mean Time
diff --git a/share/zoneinfo/leapseconds b/share/zoneinfo/leapseconds
index a2f4f0b..6e0f238 100644
--- a/share/zoneinfo/leapseconds
+++ b/share/zoneinfo/leapseconds
@@ -58,28 +58,19 @@ Leap 2008 Dec 31 23:59:60 + S
# e-mail : services.iers@obspm.fr
# http://hpiers.obspm.fr/eop-pc
#
-# Paris, 4 July 2008
+# Paris, 15 January 2009
#
-# Bulletin C 36
+# Bulletin C 37
#
# To authorities responsible
# for the measurement and
# distribution of time
#
-# UTC TIME STEP
-# on the 1st of January 2009
-#
-# A positive leap second will be introduced at the end of December 2008.
-# The sequence of dates of the UTC second markers will be:
-#
-# 2008 December 31, 23h 59m 59s
-# 2008 December 31, 23h 59m 60s
-# 2009 January 1, 0h 0m 0s
-#
-# The difference between UTC and the International Atomic Time TAI is:
-#
-# from 2006 January 1, 0h UTC, to 2009 January 1 0h UTC : UTC-TAI = - 33s
-# from 2009 January 1, 0h UTC, until further notice : UTC-TAI = - 34s
+# NO positive leap second will be introduced at the end of June 2009.
+# The difference between Coordinated Universal Time UTC and the
+# International Atomic Time TAI is :
+#
+# from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
#
# Leap seconds can be introduced in UTC at the end of the months of December
# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every
diff --git a/share/zoneinfo/northamerica b/share/zoneinfo/northamerica
index b8b333c..04a74c7 100644
--- a/share/zoneinfo/northamerica
+++ b/share/zoneinfo/northamerica
@@ -1,4 +1,4 @@
-# @(#)northamerica 8.24
+# @(#)northamerica 8.26
# <pre>
# also includes Central America and the Caribbean
@@ -1742,9 +1742,13 @@ Zone America/Dawson_Creek -8:00:56 - LMT 1884
# The individual that answered the phone confirmed that the clocks did not
# move at the end of daylight saving on October 29/2006. He also told me that
# the clocks did not move this past weekend (March 11/2007)....
-#
-# America/Resolute should use the "Canada" Rule up to October 29/2006.
-# After that it should be fixed on Eastern Standard Time until further notice.
+
+# From Chris Walton (2008-11-13):
+# ...the residents of Resolute believe that they are changing "time zones"
+# twice a year. In winter months, local time is qualified with "Eastern
+# Time" which is really "Eastern Standard Time (UTC-5)". In summer
+# months, local time is qualified with "Central Time" which is really
+# "Central Daylight Time (UTC-5)"...
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule NT_YK 1918 only - Apr 14 2:00 1:00 D
@@ -1772,11 +1776,14 @@ Zone America/Iqaluit 0 - zzz 1942 Aug # Frobisher Bay est.
-6:00 Canada C%sT 2000 Oct 29 2:00
-5:00 Canada E%sT
# aka Qausuittuq
+# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+Rule Resolute 2006 max - Nov Sun>=1 2:00 0 ES
+Rule Resolute 2007 max - Mar Sun>=8 2:00 0 CD
Zone America/Resolute 0 - zzz 1947 Aug 31 # Resolute founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00
-5:00 - EST 2001 Apr 1 3:00
-6:00 Canada C%sT 2006 Oct 29 2:00
- -5:00 - EST
+ -5:00 Resolute %sT
# aka Kangiqiniq
Zone America/Rankin_Inlet 0 - zzz 1957 # Rankin Inlet founded
-6:00 NT_YK C%sT 2000 Oct 29 2:00
@@ -2280,7 +2287,7 @@ Rule Cuba 1996 only - Oct 6 0:00s 0 S
Rule Cuba 1997 only - Oct 12 0:00s 0 S
Rule Cuba 1998 1999 - Mar lastSun 0:00s 1:00 D
Rule Cuba 1998 2003 - Oct lastSun 0:00s 0 S
-Rule Cuba 2000 2006 - Apr Sun>=1 0:00s 1:00 D
+Rule Cuba 2000 2004 - Apr Sun>=1 0:00s 1:00 D
Rule Cuba 2006 max - Oct lastSun 0:00s 0 S
Rule Cuba 2007 only - Mar Sun>=8 0:00s 1:00 D
Rule Cuba 2008 max - Mar Sun>=15 0:00s 1:00 D
diff --git a/share/zoneinfo/zone.tab b/share/zoneinfo/zone.tab
index 41ae98a..3dca589 100644
--- a/share/zoneinfo/zone.tab
+++ b/share/zoneinfo/zone.tab
@@ -1,4 +1,4 @@
-# @(#)zone.tab 8.21
+# @(#)zone.tab 8.26
#
# TZ zone descriptions
#
@@ -116,7 +116,7 @@ CA +4901-08816 America/Nipigon Eastern Time - Ontario & Quebec - places that did
CA +4823-08915 America/Thunder_Bay Eastern Time - Thunder Bay, Ontario
CA +6344-06828 America/Iqaluit Eastern Time - east Nunavut - most locations
CA +6608-06544 America/Pangnirtung Eastern Time - Pangnirtung, Nunavut
-CA +744144-0944945 America/Resolute Eastern Time - Resolute, Nunavut
+CA +744144-0944945 America/Resolute Eastern Standard Time - Resolute, Nunavut
CA +484531-0913718 America/Atikokan Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
CA +624900-0920459 America/Rankin_Inlet Central Time - central Nunavut
CA +4953-09709 America/Winnipeg Central Time - Manitoba & west Ontario
@@ -292,7 +292,7 @@ NG +0627+00324 Africa/Lagos
NI +1209-08617 America/Managua
NL +5222+00454 Europe/Amsterdam
NO +5955+01045 Europe/Oslo
-NP +2743+08519 Asia/Katmandu
+NP +2743+08519 Asia/Kathmandu
NR -0031+16655 Pacific/Nauru
NU -1901-16955 Pacific/Niue
NZ -3652+17446 Pacific/Auckland most locations
diff --git a/sys/amd64/amd64/amd64_mem.c b/sys/amd64/amd64/amd64_mem.c
index 7f1f428..2b5a73d 100644
--- a/sys/amd64/amd64/amd64_mem.c
+++ b/sys/amd64/amd64/amd64_mem.c
@@ -678,9 +678,17 @@ amd64_mem_drvinit(void *unused)
return;
if ((cpu_id & 0xf00) != 0x600 && (cpu_id & 0xf00) != 0xf00)
return;
- if (cpu_vendor_id != CPU_VENDOR_INTEL &&
- cpu_vendor_id != CPU_VENDOR_AMD)
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_INTEL:
+ case CPU_VENDOR_AMD:
+ break;
+ case CPU_VENDOR_CENTAUR:
+ if (cpu_exthigh >= 0x80000008)
+ break;
+ /* FALLTHROUGH */
+ default:
return;
+ }
mem_range_softc.mr_op = &amd64_mrops;
}
SYSINIT(amd64memdev, SI_SUB_DRIVERS, SI_ORDER_FIRST, amd64_mem_drvinit, NULL);
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index 99d6716..bc1a4bb 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -199,6 +199,7 @@ done_load_seg:
cmpq PCB_FSBASE(%r8),%r9
jz 1f
/* Restore userland %fs */
+restore_fsbase:
movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx
@@ -259,12 +260,12 @@ do_kthread:
jmp do_tss
store_seg:
- movl %gs,PCB_GS(%r8)
+ mov %gs,PCB_GS(%r8)
testl $PCB_GS32BIT,PCB_FLAGS(%r8)
jnz 2f
-1: movl %ds,PCB_DS(%r8)
- movl %es,PCB_ES(%r8)
- movl %fs,PCB_FS(%r8)
+1: mov %ds,PCB_DS(%r8)
+ mov %es,PCB_ES(%r8)
+ mov %fs,PCB_FS(%r8)
jmp done_store_seg
2: movq PCPU(GS32P),%rax
movq (%rax),%rax
@@ -276,12 +277,12 @@ load_seg:
jnz 2f
1: movl $MSR_GSBASE,%ecx
rdmsr
- movl PCB_GS(%r8),%gs
+ mov PCB_GS(%r8),%gs
wrmsr
- movl PCB_DS(%r8),%ds
- movl PCB_ES(%r8),%es
- movl PCB_FS(%r8),%fs
- jmp done_load_seg
+ mov PCB_DS(%r8),%ds
+ mov PCB_ES(%r8),%es
+ mov PCB_FS(%r8),%fs
+ jmp restore_fsbase
/* Restore userland %gs while preserving kernel gsbase */
2: movq PCPU(GS32P),%rax
movq PCB_GS32SD(%r8),%rcx
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 80308a9..897bfec 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -383,22 +383,24 @@ IDTVEC(fast_syscall32)
* NMI handling is special.
*
* First, NMIs do not respect the state of the processor's RFLAGS.IF
- * bit and the NMI handler may be invoked at any time, including when
- * the processor is in a critical section with RFLAGS.IF == 0. In
- * particular, this means that the processor's GS.base values could be
- * inconsistent on entry to the handler, and so we need to read
- * MSR_GSBASE to determine if a 'swapgs' is needed. We use '%ebx', a
- * C-preserved register, to remember whether to swap GS back on the
- * exit path.
+ * bit. The NMI handler may be entered at any time, including when
+ * the processor is in a critical section with RFLAGS.IF == 0.
+ * The processor's GS.base value could be invalid on entry to the
+ * handler.
*
* Second, the processor treats NMIs specially, blocking further NMIs
- * until an 'iretq' instruction is executed. We therefore need to
- * execute the NMI handler with interrupts disabled to prevent a
- * nested interrupt from executing an 'iretq' instruction and
- * inadvertently taking the processor out of NMI mode.
+ * until an 'iretq' instruction is executed. We thus need to execute
+ * the NMI handler with interrupts disabled, to prevent a nested interrupt
+ * from executing an 'iretq' instruction and inadvertently taking the
+ * processor out of NMI mode.
*
- * Third, the NMI handler runs on its own stack (tss_ist1), shared
- * with the double fault handler.
+ * Third, the NMI handler runs on its own stack (tss_ist2). The canonical
+ * GS.base value for the processor is stored just above the bottom of its
+ * NMI stack. For NMIs taken from kernel mode, the current value in
+ * the processor's GS.base is saved at entry to C-preserved register %r12,
+ * the canonical value for GS.base is then loaded into the processor, and
+ * the saved value is restored at exit time. For NMIs taken from user mode,
+ * the cheaper 'SWAPGS' instructions are used for swapping GS.base.
*/
IDTVEC(nmi)
@@ -423,12 +425,22 @@ IDTVEC(nmi)
movq %r15,TF_R15(%rsp)
xorl %ebx,%ebx
testb $SEL_RPL_MASK,TF_CS(%rsp)
- jnz nmi_needswapgs /* we came from userland */
+ jnz nmi_fromuserspace
+ /*
+ * We've interrupted the kernel. Preserve GS.base in %r12.
+ */
movl $MSR_GSBASE,%ecx
rdmsr
- cmpl $VM_MAXUSER_ADDRESS >> 32,%edx
- jae nmi_calltrap /* GS.base holds a kernel VA */
-nmi_needswapgs:
+ movq %rax,%r12
+ shlq $32,%rdx
+ orq %rdx,%r12
+ /* Retrieve and load the canonical value for GS.base. */
+ movq TF_SIZE(%rsp),%rdx
+ movl %edx,%eax
+ shrq $32,%rdx
+ wrmsr
+ jmp nmi_calltrap
+nmi_fromuserspace:
incl %ebx
swapgs
/* Note: this label is also used by ddb and gdb: */
@@ -439,14 +451,19 @@ nmi_calltrap:
MEXITCOUNT
#ifdef HWPMC_HOOKS
/*
- * Check if the current trap was from user mode and if so
- * whether the current thread needs a user call chain to be
- * captured. We are still in NMI mode at this point.
+ * Capture a userspace callchain if needed.
+ *
+ * - Check if the current trap was from user mode.
+ * - Check if the current thread is valid.
+ * - Check if the thread requires a user call chain to be
+ * captured.
+ *
+ * We are still in NMI mode at this point.
*/
- testb $SEL_RPL_MASK,TF_CS(%rsp)
- jz nocallchain
- movq PCPU(CURTHREAD),%rax /* curthread present? */
- orq %rax,%rax
+ testl %ebx,%ebx
+ jz nocallchain /* not from userspace */
+ movq PCPU(CURTHREAD),%rax
+ orq %rax,%rax /* curthread present? */
jz nocallchain
testl $TDP_CALLCHAIN,TD_PFLAGS(%rax) /* flagged for capture? */
jz nocallchain
@@ -494,11 +511,22 @@ outofnmi:
movq %rsp,%rdx /* frame */
sti
call *%rax
+ cli
nocallchain:
#endif
testl %ebx,%ebx
- jz nmi_restoreregs
+ jz nmi_kernelexit
swapgs
+ jmp nmi_restoreregs
+nmi_kernelexit:
+ /*
+ * Put back the preserved MSR_GSBASE value.
+ */
+ movl $MSR_GSBASE,%ecx
+ movq %r12,%rdx
+ movl %edx,%eax
+ shrq $32,%rdx
+ wrmsr
nmi_restoreregs:
movq TF_RDI(%rsp),%rdi
movq TF_RSI(%rsp),%rsi
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 513b36b..d051713 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -391,6 +391,7 @@ fpudna()
{
struct pcb *pcb;
register_t s;
+ u_short control;
if (PCPU_GET(fpcurthread) == curthread) {
printf("fpudna: fpcurthread == curthread %d times\n",
@@ -421,6 +422,10 @@ fpudna()
* explicitly load sanitized registers.
*/
fxrstor(&fpu_cleanstate);
+ if (pcb->pcb_flags & PCB_32BIT) {
+ control = __INITIAL_FPUCW_I386__;
+ fldcw(&control);
+ }
pcb->pcb_flags |= PCB_FPUINITDONE;
} else
fxrstor(&pcb->pcb_save);
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index f417e0f..a1112cc 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -72,6 +72,7 @@ void panicifcpuunsupported(void);
static u_int find_cpu_vendor_id(void);
static void print_AMD_info(void);
static void print_AMD_assoc(int i);
+static void print_via_padlock_info(void);
int cpu_class;
char machine[] = "amd64";
@@ -102,6 +103,7 @@ static struct {
} cpu_vendors[] = {
{ INTEL_VENDOR_ID, CPU_VENDOR_INTEL }, /* GenuineIntel */
{ AMD_VENDOR_ID, CPU_VENDOR_AMD }, /* AuthenticAMD */
+ { CENTAUR_VENDOR_ID, CPU_VENDOR_CENTAUR }, /* CentaurHauls */
};
int cpu_cores;
@@ -131,24 +133,33 @@ printcpuinfo(void)
}
}
- if (cpu_vendor_id == CPU_VENDOR_INTEL) {
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_INTEL:
/* Please make up your mind folks! */
strcat(cpu_model, "EM64T");
- } else if (cpu_vendor_id == CPU_VENDOR_AMD) {
+ break;
+ case CPU_VENDOR_AMD:
/*
* Values taken from AMD Processor Recognition
* http://www.amd.com/K6/k6docs/pdf/20734g.pdf
* (also describes ``Features'' encodings.
*/
strcpy(cpu_model, "AMD ");
- switch (cpu_id & 0xF00) {
- case 0xf00:
+ if ((cpu_id & 0xf00) == 0xf00)
strcat(cpu_model, "AMD64 Processor");
- break;
- default:
+ else
strcat(cpu_model, "Unknown");
- break;
- }
+ break;
+ case CPU_VENDOR_CENTAUR:
+ strcpy(cpu_model, "VIA ");
+ if ((cpu_id & 0xff0) == 0x6f0)
+ strcat(cpu_model, "Nano Processor");
+ else
+ strcat(cpu_model, "Unknown");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
}
/*
@@ -180,7 +191,8 @@ printcpuinfo(void)
printf(" Id = 0x%x", cpu_id);
if (cpu_vendor_id == CPU_VENDOR_INTEL ||
- cpu_vendor_id == CPU_VENDOR_AMD) {
+ cpu_vendor_id == CPU_VENDOR_AMD ||
+ cpu_vendor_id == CPU_VENDOR_CENTAUR) {
printf(" Stepping = %u", cpu_id & 0xf);
if (cpu_high > 0) {
u_int cmp = 1, htt = 1;
@@ -352,6 +364,9 @@ printcpuinfo(void)
);
}
+ if (cpu_vendor_id == CPU_VENDOR_CENTAUR)
+ print_via_padlock_info();
+
if ((cpu_feature & CPUID_HTT) &&
cpu_vendor_id == CPU_VENDOR_AMD)
cpu_feature &= ~CPUID_HTT;
@@ -375,6 +390,12 @@ printcpuinfo(void)
AMD64_CPU_MODEL(cpu_id) >= 0x3))
tsc_is_invariant = 1;
break;
+ case CPU_VENDOR_CENTAUR:
+ if (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
+ AMD64_CPU_MODEL(cpu_id) >= 0xf &&
+ (rdmsr(0x1203) & 0x100000000ULL) == 0)
+ tsc_is_invariant = 1;
+ break;
}
if (tsc_is_invariant)
printf("\n TSC: P-state invariant");
@@ -456,7 +477,7 @@ EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
EVENTHANDLER_PRI_ANY);
/*
- * Final stage of CPU identification. -- Should I check TI?
+ * Final stage of CPU identification.
*/
void
identify_cpu(void)
@@ -478,7 +499,8 @@ identify_cpu(void)
cpu_feature2 = regs[2];
if (cpu_vendor_id == CPU_VENDOR_INTEL ||
- cpu_vendor_id == CPU_VENDOR_AMD) {
+ cpu_vendor_id == CPU_VENDOR_AMD ||
+ cpu_vendor_id == CPU_VENDOR_CENTAUR) {
do_cpuid(0x80000000, regs);
cpu_exthigh = regs[0];
}
@@ -599,3 +621,37 @@ print_AMD_info(void)
print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);
}
}
+
+static void
+print_via_padlock_info(void)
+{
+ u_int regs[4];
+
+ /* Check for supported models. */
+ switch (cpu_id & 0xff0) {
+ case 0x690:
+ if ((cpu_id & 0xf) < 3)
+ return;
+ case 0x6a0:
+ case 0x6d0:
+ case 0x6f0:
+ break;
+ default:
+ return;
+ }
+
+ do_cpuid(0xc0000000, regs);
+ if (regs[0] >= 0xc0000001)
+ do_cpuid(0xc0000001, regs);
+ else
+ return;
+
+ printf("\n VIA Padlock Features=0x%b", regs[3],
+ "\020"
+ "\003RNG" /* RNG */
+ "\007AES" /* ACE */
+ "\011AES-CTR" /* ACE2 */
+ "\013SHA1,SHA256" /* PHE */
+ "\015RSA" /* PMM */
+ );
+}
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 23cf082..edf1a98 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -54,6 +54,8 @@ u_int cpu_feature2; /* Feature flags */
u_int amd_feature; /* AMD feature flags */
u_int amd_feature2; /* AMD feature flags */
u_int amd_pminfo; /* AMD advanced power management info */
+u_int via_feature_rng; /* VIA RNG features */
+u_int via_feature_xcrypt; /* VIA ACE features */
u_int cpu_high; /* Highest arg to CPUID */
u_int cpu_exthigh; /* Highest arg to extended CPUID */
u_int cpu_id; /* Stepping ID */
@@ -64,6 +66,75 @@ u_int cpu_vendor_id; /* CPU vendor ID */
u_int cpu_fxsr; /* SSE enabled */
u_int cpu_mxcsr_mask; /* Valid bits in mxcsr */
+SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
+ &via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU");
+SYSCTL_UINT(_hw, OID_AUTO, via_feature_xcrypt, CTLFLAG_RD,
+ &via_feature_xcrypt, 0, "VIA C3/C7 xcrypt feature available in CPU");
+
+/*
+ * Initialize special VIA C3/C7 features
+ */
+static void
+init_via(void)
+{
+ u_int regs[4], val;
+ u_int64_t msreg;
+
+ do_cpuid(0xc0000000, regs);
+ val = regs[0];
+ if (val >= 0xc0000001) {
+ do_cpuid(0xc0000001, regs);
+ val = regs[3];
+ } else
+ val = 0;
+
+ /* Enable RNG if present and disabled */
+ if (val & VIA_CPUID_HAS_RNG) {
+ if (!(val & VIA_CPUID_DO_RNG)) {
+ msreg = rdmsr(0x110B);
+ msreg |= 0x40;
+ wrmsr(0x110B, msreg);
+ }
+ via_feature_rng = VIA_HAS_RNG;
+ }
+ /* Enable AES engine if present and disabled */
+ if (val & VIA_CPUID_HAS_ACE) {
+ if (!(val & VIA_CPUID_DO_ACE)) {
+ msreg = rdmsr(0x1107);
+ msreg |= (0x01 << 28);
+ wrmsr(0x1107, msreg);
+ }
+ via_feature_xcrypt |= VIA_HAS_AES;
+ }
+ /* Enable ACE2 engine if present and disabled */
+ if (val & VIA_CPUID_HAS_ACE2) {
+ if (!(val & VIA_CPUID_DO_ACE2)) {
+ msreg = rdmsr(0x1107);
+ msreg |= (0x01 << 28);
+ wrmsr(0x1107, msreg);
+ }
+ via_feature_xcrypt |= VIA_HAS_AESCTR;
+ }
+ /* Enable SHA engine if present and disabled */
+ if (val & VIA_CPUID_HAS_PHE) {
+ if (!(val & VIA_CPUID_DO_PHE)) {
+ msreg = rdmsr(0x1107);
+ msreg |= (0x01 << 28/**/);
+ wrmsr(0x1107, msreg);
+ }
+ via_feature_xcrypt |= VIA_HAS_SHA;
+ }
+ /* Enable MM engine if present and disabled */
+ if (val & VIA_CPUID_HAS_PMM) {
+ if (!(val & VIA_CPUID_DO_PMM)) {
+ msreg = rdmsr(0x1107);
+ msreg |= (0x01 << 28/**/);
+ wrmsr(0x1107, msreg);
+ }
+ via_feature_xcrypt |= VIA_HAS_MM;
+ }
+}
+
/*
* Initialize CPU control registers
*/
@@ -81,4 +152,8 @@ initializecpu(void)
wrmsr(MSR_EFER, msr);
pg_nx = PG_NX;
}
+ if (cpu_vendor_id == CPU_VENDOR_CENTAUR &&
+ AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
+ AMD64_CPU_MODEL(cpu_id) >= 0xf)
+ init_via();
}
diff --git a/sys/amd64/amd64/io_apic.c b/sys/amd64/amd64/io_apic.c
index 79796db..72b142b 100644
--- a/sys/amd64/amd64/io_apic.c
+++ b/sys/amd64/amd64/io_apic.c
@@ -327,39 +327,56 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id)
{
struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
struct ioapic *io = (struct ioapic *)isrc->is_pic;
+ u_int old_vector;
+ u_int old_id;
+ /*
+ * keep 1st core as the destination for NMI
+ */
+ if (intpin->io_irq == IRQ_NMI)
+ apic_id = 0;
+
+ /*
+ * Set us up to free the old irq.
+ */
+ old_vector = intpin->io_vector;
+ old_id = intpin->io_cpu;
+ if (old_vector && apic_id == old_id)
+ return;
+
+ /*
+ * Allocate an APIC vector for this interrupt pin. Once
+ * we have a vector we program the interrupt pin.
+ */
intpin->io_cpu = apic_id;
+ intpin->io_vector = apic_alloc_vector(apic_id, intpin->io_irq);
if (bootverbose) {
- printf("ioapic%u: Assigning ", io->io_id);
+ printf("ioapic%u: routing intpin %u (", io->io_id,
+ intpin->io_intpin);
ioapic_print_irq(intpin);
- printf(" to local APIC %u\n", intpin->io_cpu);
+ printf(") to lapic %u vector %u\n", intpin->io_cpu,
+ intpin->io_vector);
}
ioapic_program_intpin(intpin);
+ /*
+ * Free the old vector after the new one is established. This is done
+ * to prevent races where we could miss an interrupt.
+ */
+ if (old_vector)
+ apic_free_vector(old_id, old_vector, intpin->io_irq);
}
static void
ioapic_enable_intr(struct intsrc *isrc)
{
struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
- struct ioapic *io = (struct ioapic *)isrc->is_pic;
- if (intpin->io_vector == 0) {
- /*
- * Allocate an APIC vector for this interrupt pin. Once
- * we have a vector we program the interrupt pin.
- */
- intpin->io_vector = apic_alloc_vector(intpin->io_irq);
- if (bootverbose) {
- printf("ioapic%u: routing intpin %u (", io->io_id,
- intpin->io_intpin);
- ioapic_print_irq(intpin);
- printf(") to vector %u\n", intpin->io_vector);
- }
- ioapic_program_intpin(intpin);
- apic_enable_vector(intpin->io_vector);
- }
+ if (intpin->io_vector == 0)
+ ioapic_assign_cpu(isrc, pcpu_find(0)->pc_apic_id);
+ apic_enable_vector(intpin->io_cpu, intpin->io_vector);
}
+
static void
ioapic_disable_intr(struct intsrc *isrc)
{
@@ -369,11 +386,11 @@ ioapic_disable_intr(struct intsrc *isrc)
if (intpin->io_vector != 0) {
/* Mask this interrupt pin and free its APIC vector. */
vector = intpin->io_vector;
- apic_disable_vector(vector);
+ apic_disable_vector(intpin->io_cpu, vector);
intpin->io_masked = 1;
intpin->io_vector = 0;
ioapic_program_intpin(intpin);
- apic_free_vector(vector, intpin->io_irq);
+ apic_free_vector(intpin->io_cpu, vector, intpin->io_irq);
}
}
diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index 6991969..40e4a06 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
#include <sys/smp.h>
#include <vm/vm.h>
@@ -109,6 +111,8 @@ struct lapic {
u_long la_hard_ticks;
u_long la_stat_ticks;
u_long la_prof_ticks;
+ /* Include IDT_SYSCALL to make indexing easier. */
+ u_int la_ioint_irqs[APIC_NUM_IOINTS + 1];
} static lapics[MAX_APIC_ID + 1];
/* XXX: should thermal be an NMI? */
@@ -134,8 +138,6 @@ static inthand_t *ioint_handlers[] = {
IDTVEC(apic_isr7), /* 224 - 255 */
};
-/* Include IDT_SYSCALL to make indexing easier. */
-static u_int ioint_irqs[APIC_NUM_IOINTS + 1];
static u_int32_t lapic_timer_divisors[] = {
APIC_TDCR_1, APIC_TDCR_2, APIC_TDCR_4, APIC_TDCR_8, APIC_TDCR_16,
@@ -215,14 +217,12 @@ lapic_init(vm_paddr_t addr)
/* Perform basic initialization of the BSP's local APIC. */
lapic_enable();
- ioint_irqs[IDT_SYSCALL - APIC_IO_INTS] = IRQ_SYSCALL;
/* Set BSP's per-CPU local APIC ID. */
PCPU_SET(apic_id, lapic_id());
/* Local APIC timer interrupt. */
setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYSIGT, SEL_KPL, 0);
- ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] = IRQ_TIMER;
/* XXX: error/thermal interrupts */
}
@@ -254,6 +254,9 @@ lapic_create(u_int apic_id, int boot_cpu)
lapics[apic_id].la_lvts[i] = lvts[i];
lapics[apic_id].la_lvts[i].lvt_active = 0;
}
+ lapics[apic_id].la_ioint_irqs[IDT_SYSCALL - APIC_IO_INTS] = IRQ_SYSCALL;
+ lapics[apic_id].la_ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] =
+ IRQ_TIMER;
#ifdef SMP
cpu_add(apic_id, boot_cpu);
@@ -664,7 +667,8 @@ lapic_handle_intr(int vector, struct trapframe *frame)
if (vector == -1)
panic("Couldn't get vector from ISR!");
- isrc = intr_lookup_source(apic_idt_to_irq(vector));
+ isrc = intr_lookup_source(apic_idt_to_irq(PCPU_GET(apic_id),
+ vector));
intr_execute_handlers(isrc, frame);
}
@@ -779,9 +783,19 @@ lapic_timer_enable_intr(void)
lapic->lvt_timer = value;
}
+u_int
+apic_cpuid(u_int apic_id)
+{
+#ifdef SMP
+ return apic_cpuids[apic_id];
+#else
+ return 0;
+#endif
+}
+
/* Request a free IDT vector to be used by the specified IRQ. */
u_int
-apic_alloc_vector(u_int irq)
+apic_alloc_vector(u_int apic_id, u_int irq)
{
u_int vector;
@@ -793,9 +807,9 @@ apic_alloc_vector(u_int irq)
*/
mtx_lock_spin(&icu_lock);
for (vector = 0; vector < APIC_NUM_IOINTS; vector++) {
- if (ioint_irqs[vector] != 0)
+ if (lapics[apic_id].la_ioint_irqs[vector] != 0)
continue;
- ioint_irqs[vector] = irq;
+ lapics[apic_id].la_ioint_irqs[vector] = irq;
mtx_unlock_spin(&icu_lock);
return (vector + APIC_IO_INTS);
}
@@ -810,7 +824,7 @@ apic_alloc_vector(u_int irq)
* satisfied, 0 is returned.
*/
u_int
-apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
+apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
{
u_int first, run, vector;
@@ -833,7 +847,7 @@ apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
for (vector = 0; vector < APIC_NUM_IOINTS; vector++) {
/* Vector is in use, end run. */
- if (ioint_irqs[vector] != 0) {
+ if (lapics[apic_id].la_ioint_irqs[vector] != 0) {
run = 0;
first = 0;
continue;
@@ -853,7 +867,8 @@ apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
/* Found a run, assign IRQs and return the first vector. */
for (vector = 0; vector < count; vector++)
- ioint_irqs[first + vector] = irqs[vector];
+ lapics[apic_id].la_ioint_irqs[first + vector] =
+ irqs[vector];
mtx_unlock_spin(&icu_lock);
return (first + APIC_IO_INTS);
}
@@ -862,8 +877,14 @@ apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
return (0);
}
+/*
+ * Enable a vector for a particular apic_id. Since all lapics share idt
+ * entries and ioint_handlers this enables the vector on all lapics. lapics
+ * which do not have the vector configured would report spurious interrupts
+ * should it fire.
+ */
void
-apic_enable_vector(u_int vector)
+apic_enable_vector(u_int apic_id, u_int vector)
{
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
@@ -873,7 +894,7 @@ apic_enable_vector(u_int vector)
}
void
-apic_disable_vector(u_int vector)
+apic_disable_vector(u_int apic_id, u_int vector)
{
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
@@ -884,27 +905,42 @@ apic_disable_vector(u_int vector)
/* Release an APIC vector when it's no longer in use. */
void
-apic_free_vector(u_int vector, u_int irq)
+apic_free_vector(u_int apic_id, u_int vector, u_int irq)
{
+ struct thread *td;
KASSERT(vector >= APIC_IO_INTS && vector != IDT_SYSCALL &&
vector <= APIC_IO_INTS + APIC_NUM_IOINTS,
("Vector %u does not map to an IRQ line", vector));
KASSERT(irq < NUM_IO_INTS, ("Invalid IRQ %u", irq));
- KASSERT(ioint_irqs[vector - APIC_IO_INTS] == irq, ("IRQ mismatch"));
+ KASSERT(lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] ==
+ irq, ("IRQ mismatch"));
+
+ /*
+ * Bind us to the cpu that owned the vector before freeing it so
+ * we don't lose an interrupt delivery race.
+ */
+ td = curthread;
+ thread_lock(td);
+ if (sched_is_bound(td))
+ panic("apic_free_vector: Thread already bound.\n");
+ sched_bind(td, apic_cpuid(apic_id));
mtx_lock_spin(&icu_lock);
- ioint_irqs[vector - APIC_IO_INTS] = 0;
+ lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] = 0;
mtx_unlock_spin(&icu_lock);
+ sched_unbind(td);
+ thread_unlock(td);
+
}
/* Map an IDT vector (APIC) to an IRQ (interrupt source). */
u_int
-apic_idt_to_irq(u_int vector)
+apic_idt_to_irq(u_int apic_id, u_int vector)
{
KASSERT(vector >= APIC_IO_INTS && vector != IDT_SYSCALL &&
vector <= APIC_IO_INTS + APIC_NUM_IOINTS,
("Vector %u does not map to an IRQ line", vector));
- return (ioint_irqs[vector - APIC_IO_INTS]);
+ return (lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS]);
}
#ifdef DDB
@@ -915,6 +951,7 @@ DB_SHOW_COMMAND(apic, db_show_apic)
{
struct intsrc *isrc;
int i, verbose;
+ u_int apic_id;
u_int irq;
if (strcmp(modif, "vv") == 0)
@@ -923,9 +960,14 @@ DB_SHOW_COMMAND(apic, db_show_apic)
verbose = 1;
else
verbose = 0;
- for (i = 0; i < APIC_NUM_IOINTS + 1 && !db_pager_quit; i++) {
- irq = ioint_irqs[i];
- if (irq != 0 && irq != IRQ_SYSCALL) {
+ for (apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) {
+ if (lapics[apic_id].la_present == 0)
+ continue;
+ db_printf("Interrupts bound to lapic %u\n", apic_id);
+ for (i = 0; i < APIC_NUM_IOINTS + 1 && !db_pager_quit; i++) {
+ irq = lapics[apic_id].la_ioint_irqs[i];
+ if (irq == 0 || irq == IRQ_SYSCALL)
+ continue;
db_printf("vec 0x%2x -> ", i + APIC_IO_INTS);
if (irq == IRQ_TIMER)
db_printf("lapic timer\n");
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 988b039..2bfde47 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -809,6 +809,9 @@ struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
static char dblfault_stack[PAGE_SIZE] __aligned(16);
+static char nmi0_stack[PAGE_SIZE] __aligned(16);
+CTASSERT(sizeof(struct nmi_pcpu) == 16);
+
struct amd64tss common_tss[MAXCPU];
/* software prototypes -- in more palatable form */
@@ -1291,6 +1294,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
caddr_t kmdp;
int gsel_tss, x;
struct pcpu *pc;
+ struct nmi_pcpu *np;
u_int64_t msr;
char *env;
@@ -1365,7 +1369,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
setidt(x, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
setidt(IDT_DE, &IDTVEC(div), SDT_SYSIGT, SEL_KPL, 0);
setidt(IDT_DB, &IDTVEC(dbg), SDT_SYSIGT, SEL_KPL, 0);
- setidt(IDT_NMI, &IDTVEC(nmi), SDT_SYSIGT, SEL_KPL, 1);
+ setidt(IDT_NMI, &IDTVEC(nmi), SDT_SYSIGT, SEL_KPL, 2);
setidt(IDT_BP, &IDTVEC(bpt), SDT_SYSIGT, SEL_UPL, 0);
setidt(IDT_OF, &IDTVEC(ofl), SDT_SYSIGT, SEL_KPL, 0);
setidt(IDT_BR, &IDTVEC(bnd), SDT_SYSIGT, SEL_KPL, 0);
@@ -1438,6 +1442,14 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
/* doublefault stack space, runs on ist1 */
common_tss[0].tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)];
+ /*
+ * NMI stack, runs on ist2. The pcpu pointer is stored just
+ * above the start of the ist2 stack.
+ */
+ np = ((struct nmi_pcpu *) &nmi0_stack[sizeof(nmi0_stack)]) - 1;
+ np->np_pcpu = (register_t) pc;
+ common_tss[0].tss_ist2 = (long) np;
+
/* Set the IO permission bitmap (empty due to tss seg limit) */
common_tss[0].tss_iobase = sizeof(struct amd64tss);
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 6578b20..51e906a 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -92,6 +92,7 @@ void *bootstacks[MAXCPU];
/* Temporary holder for double fault stack */
char *doublefault_stack;
+char *nmi_stack;
/* Hotwire a 0->4MB V==P mapping */
extern pt_entry_t *KPTphys;
@@ -152,6 +153,7 @@ struct cpu_info {
int cpu_disabled:1;
} static cpu_info[MAX_APIC_ID + 1];
int cpu_apic_ids[MAXCPU];
+int apic_cpuids[MAX_APIC_ID + 1];
/* Holds pending bitmap based IPIs per CPU */
static volatile u_int cpu_ipi_pending[MAXCPU];
@@ -349,6 +351,7 @@ cpu_mp_start(void)
KASSERT(boot_cpu_id == PCPU_GET(apic_id),
("BSP's APIC ID doesn't match boot_cpu_id"));
cpu_apic_ids[0] = boot_cpu_id;
+ apic_cpuids[boot_cpu_id] = 0;
assign_cpu_ids();
@@ -435,6 +438,7 @@ void
init_secondary(void)
{
struct pcpu *pc;
+ struct nmi_pcpu *np;
u_int64_t msr, cr0;
int cpu, gsel_tss, x;
struct region_descriptor ap_gdt;
@@ -448,6 +452,10 @@ init_secondary(void)
common_tss[cpu].tss_iobase = sizeof(struct amd64tss);
common_tss[cpu].tss_ist1 = (long)&doublefault_stack[PAGE_SIZE];
+ /* The NMI stack runs on IST2. */
+ np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1;
+ common_tss[cpu].tss_ist2 = (long) np;
+
/* Prepare private GDT */
gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu];
ssdtosyssd(&gdt_segs[GPROC0_SEL],
@@ -472,6 +480,9 @@ init_secondary(void)
pc->pc_rsp0 = 0;
pc->pc_gs32p = &gdt[NGDT * cpu + GUGS32_SEL];
+ /* Save the per-cpu pointer for use by the NMI handler. */
+ np->np_pcpu = (register_t) pc;
+
wrmsr(MSR_FSBASE, 0); /* User value */
wrmsr(MSR_GSBASE, (u_int64_t)pc);
wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* XXX User value while we're in the kernel */
@@ -656,6 +667,7 @@ assign_cpu_ids(void)
if (mp_ncpus < MAXCPU) {
cpu_apic_ids[mp_ncpus] = i;
+ apic_cpuids[i] = mp_ncpus;
mp_ncpus++;
} else
cpu_info[i].cpu_disabled = 1;
@@ -722,6 +734,7 @@ start_all_aps(void)
/* allocate and set up an idle stack data page */
bootstacks[cpu] = (void *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
doublefault_stack = (char *)kmem_alloc(kernel_map, PAGE_SIZE);
+ nmi_stack = (char *)kmem_alloc(kernel_map, PAGE_SIZE);
bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
bootAP = cpu;
diff --git a/sys/amd64/amd64/msi.c b/sys/amd64/amd64/msi.c
index f8d92d6..b34d835 100644
--- a/sys/amd64/amd64/msi.c
+++ b/sys/amd64/amd64/msi.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
+#include <machine/specialreg.h>
#include <dev/pci/pcivar.h>
/* Fields in address for Intel MSI messages. */
@@ -160,7 +161,9 @@ msi_enable_intr(struct intsrc *isrc)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
- apic_enable_vector(msi->msi_vector);
+ if (msi->msi_vector == 0)
+ msi_assign_cpu(isrc, 0);
+ apic_enable_vector(msi->msi_cpu, msi->msi_vector);
}
static void
@@ -168,7 +171,7 @@ msi_disable_intr(struct intsrc *isrc)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
- apic_disable_vector(msi->msi_vector);
+ apic_disable_vector(msi->msi_cpu, msi->msi_vector);
}
static int
@@ -198,23 +201,52 @@ static void
msi_assign_cpu(struct intsrc *isrc, u_int apic_id)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
-
+ int old_vector;
+ u_int old_id;
+ int vector;
+
+ /* Store information to free existing irq. */
+ old_vector = msi->msi_vector;
+ old_id = msi->msi_cpu;
+ if (old_vector && old_id == apic_id)
+ return;
+ /* Allocate IDT vector on this cpu. */
+ vector = apic_alloc_vector(apic_id, msi->msi_irq);
+ if (vector == 0)
+ return; /* XXX alloc_vector panics on failure. */
msi->msi_cpu = apic_id;
+ msi->msi_vector = vector;
if (bootverbose)
- printf("msi: Assigning %s IRQ %d to local APIC %u\n",
+ printf("msi: Assigning %s IRQ %d to local APIC %u vector %u\n",
msi->msi_msix ? "MSI-X" : "MSI", msi->msi_irq,
- msi->msi_cpu);
+ msi->msi_cpu, msi->msi_vector);
pci_remap_msi_irq(msi->msi_dev, msi->msi_irq);
+ /*
+ * Free the old vector after the new one is established. This is done
+ * to prevent races where we could miss an interrupt.
+ */
+ if (old_vector)
+ apic_free_vector(old_id, old_vector, msi->msi_irq);
}
+
void
msi_init(void)
{
/* Check if we have a supported CPU. */
- if (!(cpu_vendor_id == CPU_VENDOR_INTEL ||
- cpu_vendor_id == CPU_VENDOR_AMD))
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_INTEL:
+ case CPU_VENDOR_AMD:
+ break;
+ case CPU_VENDOR_CENTAUR:
+ if (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
+ AMD64_CPU_MODEL(cpu_id) >= 0xf)
+ break;
+ /* FALLTHROUGH */
+ default:
return;
+ }
msi_enabled = 1;
intr_register_pic(&msi_pic);
@@ -253,7 +285,7 @@ int
msi_alloc(device_t dev, int count, int maxcount, int *irqs)
{
struct msi_intsrc *msi, *fsrc;
- int cnt, i, vector;
+ int cnt, i;
if (!msi_enabled)
return (ENXIO);
@@ -299,22 +331,12 @@ again:
/* Ok, we now have the IRQs allocated. */
KASSERT(cnt == count, ("count mismatch"));
- /* Allocate 'count' IDT vectors. */
- vector = apic_alloc_vectors(irqs, count, maxcount);
- if (vector == 0) {
- mtx_unlock(&msi_lock);
- return (ENOSPC);
- }
-
/* Assign IDT vectors and make these messages owned by 'dev'. */
fsrc = (struct msi_intsrc *)intr_lookup_source(irqs[0]);
for (i = 0; i < count; i++) {
msi = (struct msi_intsrc *)intr_lookup_source(irqs[i]);
msi->msi_dev = dev;
- msi->msi_vector = vector + i;
- if (bootverbose)
- printf("msi: routing MSI IRQ %d to vector %u\n",
- msi->msi_irq, msi->msi_vector);
+ msi->msi_vector = 0;
msi->msi_first = fsrc;
KASSERT(msi->msi_intsrc.is_handlers == 0,
("dead MSI has handlers"));
@@ -367,14 +389,18 @@ msi_release(int *irqs, int count)
KASSERT(msi->msi_dev == first->msi_dev, ("owner mismatch"));
msi->msi_first = NULL;
msi->msi_dev = NULL;
- apic_free_vector(msi->msi_vector, msi->msi_irq);
+ if (msi->msi_vector)
+ apic_free_vector(msi->msi_cpu, msi->msi_vector,
+ msi->msi_irq);
msi->msi_vector = 0;
}
/* Clear out the first message. */
first->msi_first = NULL;
first->msi_dev = NULL;
- apic_free_vector(first->msi_vector, first->msi_irq);
+ if (first->msi_vector)
+ apic_free_vector(first->msi_cpu, first->msi_vector,
+ first->msi_irq);
first->msi_vector = 0;
first->msi_count = 0;
@@ -423,7 +449,7 @@ int
msix_alloc(device_t dev, int *irq)
{
struct msi_intsrc *msi;
- int i, vector;
+ int i;
if (!msi_enabled)
return (ENXIO);
@@ -458,15 +484,9 @@ again:
goto again;
}
- /* Allocate an IDT vector. */
- vector = apic_alloc_vector(i);
- if (bootverbose)
- printf("msi: routing MSI-X IRQ %d to vector %u\n", msi->msi_irq,
- vector);
-
/* Setup source. */
msi->msi_dev = dev;
- msi->msi_vector = vector;
+ msi->msi_vector = 0;
msi->msi_msix = 1;
KASSERT(msi->msi_intsrc.is_handlers == 0, ("dead MSI-X has handlers"));
@@ -498,7 +518,8 @@ msix_release(int irq)
/* Clear out the message. */
msi->msi_dev = NULL;
- apic_free_vector(msi->msi_vector, msi->msi_irq);
+ if (msi->msi_vector)
+ apic_free_vector(msi->msi_cpu, msi->msi_vector, msi->msi_irq);
msi->msi_vector = 0;
msi->msi_msix = 0;
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 01873ba..c3a8f49 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -1,8 +1,8 @@
#
# GENERIC -- Generic kernel configuration file for FreeBSD/amd64
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -24,6 +24,12 @@ ident GENERIC
# To statically compile in device wiring instead of /boot/device.hints
#hints "GENERIC.hints" # Default places to look for devices.
+# Use the following to compile in values accessible to the kernel
+# through getenv() (or kenv(1) in userland). The format of the file
+# is 'variable=value', see kenv(1)
+#
+# env "GENERIC.env"
+
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options SCHED_ULE # ULE scheduler
@@ -41,7 +47,6 @@ options NFSCLIENT # Network Filesystem Client
options NFSSERVER # Network Filesystem Server
options NFSLOCKD # Network Lock Manager
options NFS_ROOT # NFS usable as /, requires NFSCLIENT
-options NTFS # NT File System
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
@@ -63,8 +68,10 @@ options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options STOP_NMI # Stop CPUS using NMI instead of IPI
+options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
-options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
+#options KDTRACE_FRAME # Ensure frames are compiled in
+#options KDTRACE_HOOKS # Kernel DTrace hooks
# Debugging for use in -current
options KDB # Enable kernel debugger support.
@@ -130,6 +137,8 @@ device ses # SCSI Environmental Services (and SAF-TE)
# RAID controllers interfaced to the SCSI subsystem
device amr # AMI MegaRAID
device arcmsr # Areca SATA II RAID
+#XXX it is not 64-bit clean, -scottl
+#device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID
device ciss # Compaq Smart RAID 5*
device dpt # DPT Smartcache III, IV - See NOTES for options
device hptmv # Highpoint RocketRAID 182x
@@ -222,6 +231,7 @@ 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 tl # Texas Instruments ThunderLAN
device tx # SMC EtherPower II (83c170 ``EPIC'')
device vge # VIA VT612x gigabit Ethernet
@@ -241,8 +251,8 @@ device xe # Xircom pccard Ethernet
# Wireless NIC cards
device wlan # 802.11 support
-options IEEE80211_DEBUG # enable debug msgs
-options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
+options IEEE80211_DEBUG # enable debug msgs
+options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
device wlan_wep # 802.11 WEP support
device wlan_ccmp # 802.11 CCMP support
device wlan_tkip # 802.11 TKIP support
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index a1cbfa4..76dca9d 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -150,6 +150,11 @@ device pci
# AGP GART support
device agp
+#
+# AGP debugging.
+#
+options AGP_DEBUG
+
#####################################################################
# HARDWARE DEVICE CONFIGURATION
@@ -267,7 +272,6 @@ options DRM_DEBUG # Include debug printfs (slow)
# nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source)
# nve: nVidia nForce MCP on-board Ethernet Networking
# ral: Ralink Technology IEEE 802.11 wireless adapter
-# ural: Ralink Technology RT2500USB IEEE 802.11 wireless adapter
# wpi: Intel 3945ABG Wireless LAN controller
device ed
@@ -277,10 +281,9 @@ options ED_SIC
device iwi
device iwn
device ipw
-device nfe # nVidia nForce MCP on-board Ethernet Networking
-device nve # nVidia nForce MCP on-board Ethernet Networking
+device nfe
+device nve
device ral
-device ural
device wpi
device ath # Atheros pci/cardbus NIC's
@@ -356,9 +359,11 @@ options SAFE_RNDTEST # enable rndtest support
# Miscellaneous hardware:
#
# ipmi: Intelligent Platform Management Interface
+# pbio: Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724)
# smbios: DMI/SMBIOS entry point
# vpd: Vital Product Data kernel interface
# asmc: Apple System Management Controller
+# si: Specialix International SI/XIO or SX intelligent serial card
# Notes on the Specialix SI/XIO driver:
# The host card is memory, not IO mapped.
@@ -367,13 +372,14 @@ options SAFE_RNDTEST # enable rndtest support
# The cards can use an IRQ of 11, 12 or 15.
device ipmi
-# Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724)
device pbio
hint.pbio.0.at="isa"
hint.pbio.0.port="0x360"
device smbios
device vpd
device asmc
+#device si
+
#
# Laptop/Notebook options:
#
diff --git a/sys/amd64/conf/USB2 b/sys/amd64/conf/USB2
new file mode 100644
index 0000000..f6477af
--- /dev/null
+++ b/sys/amd64/conf/USB2
@@ -0,0 +1,114 @@
+#
+# USB2 -- Generic kernel configuration file for FreeBSD/amd64 with USBng
+# stack.
+#
+# $FreeBSD$
+
+include GENERIC
+
+ident USB2-GENERIC
+
+# Remove support for the old USB stack.
+nodevice uhci
+nodevice ohci
+nodevice ehci
+nodevice usb
+nodevice ugen
+nodevice uhid
+nodevice ukbd
+nodevice ulpt
+nodevice umass
+nodevice ums
+nodevice ural
+nodevice rum
+nodevice zyd
+nodevice urio
+nodevice uscanner
+# USB Serial devices
+nodevice ucom
+nodevice u3g
+nodevice uark
+nodevice ubsa
+nodevice uftdi
+nodevice uipaq
+nodevice uplcom
+nodevice uslcom
+nodevice uvisor
+nodevice uvscom
+# USB Ethernet, requires miibus
+nodevice aue
+nodevice axe
+nodevice cdce
+nodevice cue
+nodevice kue
+nodevice rue
+nodevice udav
+
+#
+# The following drivers belong to the new USB stack.
+#
+
+# USB core support
+device usb2_core
+
+# USB controller support
+device usb2_controller
+device usb2_controller_ehci
+device usb2_controller_ohci
+device usb2_controller_uhci
+
+# USB mass storage support
+device usb2_storage
+device usb2_storage_mass
+
+# USB ethernet support, requires miibus
+device usb2_ethernet
+device usb2_ethernet_aue
+device usb2_ethernet_axe
+device usb2_ethernet_cdce
+device usb2_ethernet_cue
+device usb2_ethernet_kue
+device usb2_ethernet_rue
+device usb2_ethernet_dav
+
+# USB wireless LAN support
+device usb2_wlan
+device usb2_wlan_rum
+device usb2_wlan_ral
+device usb2_wlan_zyd
+
+# USB serial device support
+device usb2_serial
+device usb2_serial_ark
+device usb2_serial_bsa
+device usb2_serial_bser
+device usb2_serial_chcom
+device usb2_serial_cycom
+device usb2_serial_foma
+device usb2_serial_ftdi
+device usb2_serial_gensa
+device usb2_serial_ipaq
+device usb2_serial_lpt
+device usb2_serial_mct
+device usb2_serial_modem
+device usb2_serial_moscom
+device usb2_serial_plcom
+device usb2_serial_visor
+device usb2_serial_vscom
+
+# USB bluetooth support
+#device usb2_bluetooth
+#device usb2_bluetooth_ng
+
+# USB input device support
+device usb2_input
+device usb2_input_hid
+device usb2_input_kbd
+device usb2_input_ms
+
+# USB sound and MIDI device support
+#device usb2_sound
+
+# USB scanner support
+device usb2_image
+device usb2_scanner
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index 162dcf9..d3b9ae3 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -328,8 +328,8 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
sf.sf_uc.uc_mcontext.mc_fs = rfs();
- __asm __volatile("movl %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es));
- __asm __volatile("movl %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds));
+ __asm __volatile("mov %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es));
+ __asm __volatile("mov %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds));
sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi;
sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi;
sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp;
@@ -443,8 +443,8 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
sf.sf_uc.uc_mcontext.mc_fs = rfs();
- __asm __volatile("movl %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es));
- __asm __volatile("movl %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds));
+ __asm __volatile("mov %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es));
+ __asm __volatile("mov %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds));
sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi;
sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi;
sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp;
diff --git a/sys/amd64/ia32/ia32_sigtramp.S b/sys/amd64/ia32/ia32_sigtramp.S
index 7b20bc4..1cd220a 100644
--- a/sys/amd64/ia32/ia32_sigtramp.S
+++ b/sys/amd64/ia32/ia32_sigtramp.S
@@ -45,8 +45,8 @@ ia32_sigcode:
calll *IA32_SIGF_HANDLER(%esp)
leal IA32_SIGF_UC(%esp),%eax /* get ucontext */
pushl %eax
- movl IA32_UC_ES(%eax),%es /* restore %es */
- movl IA32_UC_DS(%eax),%ds /* restore %ds */
+ mov IA32_UC_ES(%eax),%es /* restore %es */
+ mov IA32_UC_DS(%eax),%ds /* restore %ds */
movl $SYS_sigreturn,%eax
pushl %eax /* junk to fake return addr. */
int $0x80 /* enter kernel with args */
@@ -60,8 +60,8 @@ freebsd4_ia32_sigcode:
calll *IA32_SIGF_HANDLER(%esp)
leal IA32_SIGF_UC4(%esp),%eax/* get ucontext */
pushl %eax
- movl IA32_UC4_ES(%eax),%es /* restore %es */
- movl IA32_UC4_DS(%eax),%ds /* restore %ds */
+ mov IA32_UC4_ES(%eax),%es /* restore %es */
+ mov IA32_UC4_DS(%eax),%ds /* restore %ds */
movl $344,%eax /* 4.x SYS_sigreturn */
pushl %eax /* junk to fake return addr. */
int $0x80 /* enter kernel with args */
diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 623d637..ea971ec 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
@@ -176,14 +176,17 @@ inthand_t
IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
extern vm_paddr_t lapic_paddr;
-
-u_int apic_alloc_vector(u_int irq);
-u_int apic_alloc_vectors(u_int *irqs, u_int count, u_int align);
-void apic_disable_vector(u_int vector);
-void apic_enable_vector(u_int vector);
-void apic_free_vector(u_int vector, u_int irq);
-u_int apic_idt_to_irq(u_int vector);
+extern int apic_cpuids[];
+
+u_int apic_alloc_vector(u_int apic_id, u_int irq);
+u_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count,
+ u_int align);
+void apic_disable_vector(u_int apic_id, u_int vector);
+void apic_enable_vector(u_int apic_id, u_int vector);
+void apic_free_vector(u_int apic_id, u_int vector, u_int irq);
+u_int apic_idt_to_irq(u_int apic_id, u_int vector);
void apic_register_enumerator(struct apic_enumerator *enumerator);
+u_int apic_cpuid(u_int apic_id);
void *ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase);
int ioapic_disable_pin(void *cookie, u_int pin);
int ioapic_get_vector(void *cookie, u_int pin);
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index a4a84b7..cec9b4a 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -482,7 +482,7 @@ static __inline u_int
rfs(void)
{
u_int sel;
- __asm __volatile("movl %%fs,%0" : "=rm" (sel));
+ __asm __volatile("mov %%fs,%0" : "=rm" (sel));
return (sel);
}
@@ -490,7 +490,7 @@ static __inline u_int
rgs(void)
{
u_int sel;
- __asm __volatile("movl %%gs,%0" : "=rm" (sel));
+ __asm __volatile("mov %%gs,%0" : "=rm" (sel));
return (sel);
}
@@ -498,20 +498,20 @@ static __inline u_int
rss(void)
{
u_int sel;
- __asm __volatile("movl %%ss,%0" : "=rm" (sel));
+ __asm __volatile("mov %%ss,%0" : "=rm" (sel));
return (sel);
}
static __inline void
load_ds(u_int sel)
{
- __asm __volatile("movl %0,%%ds" : : "rm" (sel));
+ __asm __volatile("mov %0,%%ds" : : "rm" (sel));
}
static __inline void
load_es(u_int sel)
{
- __asm __volatile("movl %0,%%es" : : "rm" (sel));
+ __asm __volatile("mov %0,%%es" : : "rm" (sel));
}
static inline void
@@ -539,7 +539,7 @@ load_fs(u_int sel)
/* Preserve the fsbase value across the selector load */
fsbase = MSR_FSBASE;
- __asm __volatile("rdmsr; movl %0,%%fs; wrmsr"
+ __asm __volatile("rdmsr; mov %0,%%fs; wrmsr"
: : "rm" (sel), "c" (fsbase) : "eax", "edx");
}
@@ -557,7 +557,7 @@ load_gs(u_int sel)
* being trashed happens to be the kernel gsbase at the time.
*/
gsbase = MSR_GSBASE;
- __asm __volatile("pushfq; cli; rdmsr; movl %0,%%gs; wrmsr; popfq"
+ __asm __volatile("pushfq; cli; rdmsr; mov %0,%%gs; wrmsr; popfq"
: : "rm" (sel), "c" (gsbase) : "eax", "edx");
}
#else
@@ -565,13 +565,13 @@ load_gs(u_int sel)
static __inline void
load_fs(u_int sel)
{
- __asm __volatile("movl %0,%%fs" : : "rm" (sel));
+ __asm __volatile("mov %0,%%fs" : : "rm" (sel));
}
static __inline void
load_gs(u_int sel)
{
- __asm __volatile("movl %0,%%gs" : : "rm" (sel));
+ __asm __volatile("mov %0,%%gs" : : "rm" (sel));
}
#endif
diff --git a/sys/amd64/include/cputypes.h b/sys/amd64/include/cputypes.h
index 9cf6fbc..eeec4e0 100644
--- a/sys/amd64/include/cputypes.h
+++ b/sys/amd64/include/cputypes.h
@@ -47,7 +47,9 @@
* Vendors of processor.
*/
#define CPU_VENDOR_AMD 0x1022 /* AMD */
+#define CPU_VENDOR_IDT 0x111d /* Centaur/IDT/VIA */
#define CPU_VENDOR_INTEL 0x8086 /* Intel */
+#define CPU_VENDOR_CENTAUR CPU_VENDOR_IDT
#ifndef LOCORE
extern int cpu;
diff --git a/sys/amd64/include/fpu.h b/sys/amd64/include/fpu.h
index 88932ed..9b99fd8 100644
--- a/sys/amd64/include/fpu.h
+++ b/sys/amd64/include/fpu.h
@@ -92,6 +92,7 @@ struct savefpu {
* SSE2 based math. For FreeBSD/amd64, we go with the default settings.
*/
#define __INITIAL_FPUCW__ 0x037F
+#define __INITIAL_FPUCW_I386__ 0x127F
#define __INITIAL_MXCSR__ 0x1F80
#define __INITIAL_MXCSR_MASK__ 0xFFBF
diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h
index 7e1c43f..35b8666 100644
--- a/sys/amd64/include/intr_machdep.h
+++ b/sys/amd64/include/intr_machdep.h
@@ -47,7 +47,7 @@
* IRQ values beyond 256 are used by MSI. We leave 255 unused to avoid
* confusion since 255 is used in PCI to indicate an invalid IRQ.
*/
-#define NUM_MSI_INTS 128
+#define NUM_MSI_INTS 512
#define FIRST_MSI_INT 256
#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS)
@@ -120,6 +120,15 @@ struct intsrc {
struct trapframe;
+/*
+ * The following data structure holds per-cpu data, and is placed just
+ * above the top of the space used for the NMI stack.
+ */
+struct nmi_pcpu {
+ register_t np_pcpu;
+ register_t __padding; /* pad to 16 bytes */
+};
+
extern struct mtx icu_lock;
extern int elcr_found;
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index b0807b3..2125b9f 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -45,6 +45,8 @@ extern u_int cpu_feature2;
extern u_int amd_feature;
extern u_int amd_feature2;
extern u_int amd_pminfo;
+extern u_int via_feature_rng;
+extern u_int via_feature_xcrypt;
extern u_int cpu_fxsr;
extern u_int cpu_high;
extern u_int cpu_id;
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index 674638c..eb2ff9b 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -205,6 +205,7 @@
* CPUID manufacturers identifiers
*/
#define AMD_VENDOR_ID "AuthenticAMD"
+#define CENTAUR_VENDOR_ID "CentaurHauls"
#define INTEL_VENDOR_ID "GenuineIntel"
/*
@@ -458,4 +459,40 @@
#define MSR_TOP_MEM2 0xc001001d /* boundary for ram above 4G */
#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */
+/* VIA ACE crypto featureset: for via_feature_rng */
+#define VIA_HAS_RNG 1 /* cpu has RNG */
+
+/* VIA ACE crypto featureset: for via_feature_xcrypt */
+#define VIA_HAS_AES 1 /* cpu has AES */
+#define VIA_HAS_SHA 2 /* cpu has SHA1 & SHA256 */
+#define VIA_HAS_MM 4 /* cpu has RSA instructions */
+#define VIA_HAS_AESCTR 8 /* cpu has AES-CTR instructions */
+
+/* Centaur Extended Feature flags */
+#define VIA_CPUID_HAS_RNG 0x000004
+#define VIA_CPUID_DO_RNG 0x000008
+#define VIA_CPUID_HAS_ACE 0x000040
+#define VIA_CPUID_DO_ACE 0x000080
+#define VIA_CPUID_HAS_ACE2 0x000100
+#define VIA_CPUID_DO_ACE2 0x000200
+#define VIA_CPUID_HAS_PHE 0x000400
+#define VIA_CPUID_DO_PHE 0x000800
+#define VIA_CPUID_HAS_PMM 0x001000
+#define VIA_CPUID_DO_PMM 0x002000
+
+/* VIA ACE xcrypt-* instruction context control options */
+#define VIA_CRYPT_CWLO_ROUND_M 0x0000000f
+#define VIA_CRYPT_CWLO_ALG_M 0x00000070
+#define VIA_CRYPT_CWLO_ALG_AES 0x00000000
+#define VIA_CRYPT_CWLO_KEYGEN_M 0x00000080
+#define VIA_CRYPT_CWLO_KEYGEN_HW 0x00000000
+#define VIA_CRYPT_CWLO_KEYGEN_SW 0x00000080
+#define VIA_CRYPT_CWLO_NORMAL 0x00000000
+#define VIA_CRYPT_CWLO_INTERMEDIATE 0x00000100
+#define VIA_CRYPT_CWLO_ENCRYPT 0x00000000
+#define VIA_CRYPT_CWLO_DECRYPT 0x00000200
+#define VIA_CRYPT_CWLO_KEY128 0x0000000a /* 128bit, 10 rds */
+#define VIA_CRYPT_CWLO_KEY192 0x0000040c /* 192bit, 12 rds */
+#define VIA_CRYPT_CWLO_KEY256 0x0000080e /* 256bit, 15 rds */
+
#endif /* !_MACHINE_SPECIALREG_H_ */
diff --git a/sys/amd64/linux32/linux32_locore.s b/sys/amd64/linux32/linux32_locore.s
index 9183374..6045925 100644
--- a/sys/amd64/linux32/linux32_locore.s
+++ b/sys/amd64/linux32/linux32_locore.s
@@ -11,8 +11,8 @@
NON_GPROF_ENTRY(linux_sigcode)
call *LINUX_SIGF_HANDLER(%esp)
leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
- movl LINUX_SC_ES(%ebx),%es
- movl LINUX_SC_DS(%ebx),%ds
+ mov LINUX_SC_ES(%ebx),%es
+ mov LINUX_SC_DS(%ebx),%ds
movl %esp, %ebx /* pass sigframe */
push %eax /* fake ret addr */
movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
@@ -24,8 +24,8 @@ linux_rt_sigcode:
call *LINUX_RT_SIGF_HANDLER(%esp)
leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */
- movl LINUX_SC_ES(%ecx),%es
- movl LINUX_SC_DS(%ecx),%ds
+ mov LINUX_SC_ES(%ecx),%es
+ mov LINUX_SC_DS(%ecx),%ds
push %eax /* fake ret addr */
movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
int $0x80 /* enter kernel with args */
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index aaa7458..bcb6069 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -348,12 +348,12 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
- frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
- frame.sf_sc.uc_mcontext.sc_gs = rgs();
- frame.sf_sc.uc_mcontext.sc_fs = rfs();
- __asm __volatile("movl %%es,%0" :
+ frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
+ frame.sf_sc.uc_mcontext.sc_gs = rgs();
+ frame.sf_sc.uc_mcontext.sc_fs = rfs();
+ __asm __volatile("mov %%es,%0" :
"=rm" (frame.sf_sc.uc_mcontext.sc_es));
- __asm __volatile("movl %%ds,%0" :
+ __asm __volatile("mov %%ds,%0" :
"=rm" (frame.sf_sc.uc_mcontext.sc_ds));
frame.sf_sc.uc_mcontext.sc_edi = regs->tf_rdi;
frame.sf_sc.uc_mcontext.sc_esi = regs->tf_rsi;
@@ -483,10 +483,10 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
* Build the signal context to be used by sigreturn.
*/
frame.sf_sc.sc_mask = lmask.__bits[0];
- frame.sf_sc.sc_gs = rgs();
- frame.sf_sc.sc_fs = rfs();
- __asm __volatile("movl %%es,%0" : "=rm" (frame.sf_sc.sc_es));
- __asm __volatile("movl %%ds,%0" : "=rm" (frame.sf_sc.sc_ds));
+ frame.sf_sc.sc_gs = rgs();
+ frame.sf_sc.sc_fs = rfs();
+ __asm __volatile("mov %%es,%0" : "=rm" (frame.sf_sc.sc_es));
+ __asm __volatile("mov %%ds,%0" : "=rm" (frame.sf_sc.sc_ds));
frame.sf_sc.sc_edi = regs->tf_rdi;
frame.sf_sc.sc_esi = regs->tf_rsi;
frame.sf_sc.sc_ebp = regs->tf_rbp;
@@ -768,35 +768,37 @@ static int exec_linux_imgact_try(struct image_params *iparams);
static int
exec_linux_imgact_try(struct image_params *imgp)
{
- const char *head = (const char *)imgp->image_header;
- char *rpath;
- int error = -1, len;
-
- /*
- * The interpreter for shell scripts run from a linux binary needs
- * to be located in /compat/linux if possible in order to recursively
- * maintain linux path emulation.
- */
- if (((const short *)head)[0] == SHELLMAGIC) {
- /*
- * Run our normal shell image activator. If it succeeds attempt
- * to use the alternate path for the interpreter. If an alternate
- * path is found, use our stringspace to store it.
- */
- if ((error = exec_shell_imgact(imgp)) == 0) {
- linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
- imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD);
- if (rpath != NULL) {
- len = strlen(rpath) + 1;
-
- if (len <= MAXSHELLCMDLEN) {
- memcpy(imgp->interpreter_name, rpath, len);
- }
- free(rpath, M_TEMP);
- }
- }
- }
- return(error);
+ const char *head = (const char *)imgp->image_header;
+ char *rpath;
+ int error = -1, len;
+
+ /*
+ * The interpreter for shell scripts run from a linux binary needs
+ * to be located in /compat/linux if possible in order to recursively
+ * maintain linux path emulation.
+ */
+ if (((const short *)head)[0] == SHELLMAGIC) {
+ /*
+ * Run our normal shell image activator. If it succeeds attempt
+ * to use the alternate path for the interpreter. If an
+ * alternate * path is found, use our stringspace to store it.
+ */
+ if ((error = exec_shell_imgact(imgp)) == 0) {
+ linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
+ imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0,
+ AT_FDCWD);
+ if (rpath != NULL) {
+ len = strlen(rpath) + 1;
+
+ if (len <= MAXSHELLCMDLEN) {
+ memcpy(imgp->interpreter_name, rpath,
+ len);
+ }
+ free(rpath, M_TEMP);
+ }
+ }
+ }
+ return(error);
}
/*
@@ -864,7 +866,7 @@ linux_copyout_strings(struct image_params *imgp)
arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
sigcodesz = *(imgp->proc->p_sysent->sv_szsigcode);
destp = (caddr_t)arginfo - sigcodesz - SPARE_USRSPACE -
- roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+ roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
/*
* install sigcode
@@ -882,23 +884,24 @@ linux_copyout_strings(struct image_params *imgp)
* '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);
+ 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) * sizeof(u_int32_t));
+ vectp = (u_int32_t *) (destp - (imgp->args->argc +
+ imgp->args->envc + 2 + imgp->auxarg_size) *
+ 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 = (u_int32_t *)(destp - (imgp->args->argc +
+ imgp->args->envc + 2) * sizeof(u_int32_t));
/*
* vectp also becomes our initial stack base
@@ -970,7 +973,7 @@ linux32_fixlimit(struct rlimit *rl, int which)
switch (which) {
case RLIMIT_DATA:
- if (linux32_maxdsiz != 0) {
+ if (linux32_maxdsiz != 0) {
if (rl->rlim_cur > linux32_maxdsiz)
rl->rlim_cur = linux32_maxdsiz;
if (rl->rlim_max > linux32_maxdsiz)
@@ -1080,12 +1083,12 @@ linux_elf_modevent(module_t mod, int type, void *data)
sx_init(&emul_shared_lock, "emuldata->shared lock");
LIST_INIT(&futex_list);
sx_init(&futex_sx, "futex protection lock");
- linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
- NULL, 1000);
- linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail,
- NULL, 1000);
- linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
- NULL, 1000);
+ linux_exit_tag = EVENTHANDLER_REGISTER(process_exit,
+ linux_proc_exit, NULL, 1000);
+ linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail,
+ linux_schedtail, NULL, 1000);
+ linux_exec_tag = EVENTHANDLER_REGISTER(process_exec,
+ linux_proc_exec, NULL, 1000);
if (bootverbose)
printf("Linux ELF exec handler installed\n");
} else
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index 959276c..f53a47b 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -1144,6 +1144,7 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
cpu_l2cache_wb_range(bpage->vaddr,
bpage->datacount);
}
+ dmat->bounce_zone->total_bounced++;
}
if (op & BUS_DMASYNC_POSTREAD) {
if (bpage->vaddr_nocache == 0) {
@@ -1155,6 +1156,7 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
bcopy((void *)(bpage->vaddr_nocache != 0 ?
bpage->vaddr_nocache : bpage->vaddr),
(void *)bpage->datavaddr, bpage->datacount);
+ dmat->bounce_zone->total_bounced++;
}
}
}
@@ -1166,7 +1168,7 @@ _bus_dma_buf_is_in_bp(bus_dmamap_t map, void *buf, int len)
STAILQ_FOREACH(bpage, &map->bpages, links) {
if ((vm_offset_t)buf >= bpage->datavaddr &&
- (vm_offset_t)buf + len < bpage->datavaddr +
+ (vm_offset_t)buf + len <= bpage->datavaddr +
bpage->datacount)
return (1);
}
diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c
index df4f067..a13e6da 100644
--- a/sys/arm/arm/cpufunc.c
+++ b/sys/arm/arm/cpufunc.c
@@ -358,7 +358,7 @@ struct cpu_functions armv5_ec_cpufuncs = {
};
-struct cpu_functions feroceon_cpufuncs = {
+struct cpu_functions sheeva_cpufuncs = {
/* CPU functions */
cpufunc_id, /* id */
@@ -368,7 +368,7 @@ struct cpu_functions feroceon_cpufuncs = {
cpufunc_control, /* control */
cpufunc_domains, /* Domain */
- feroceon_setttb, /* Setttb */
+ sheeva_setttb, /* Setttb */
cpufunc_faultstatus, /* Faultstatus */
cpufunc_faultaddress, /* Faultaddress */
@@ -387,17 +387,17 @@ struct cpu_functions feroceon_cpufuncs = {
armv5_ec_icache_sync_range, /* icache_sync_range */
armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */
- feroceon_dcache_wbinv_range, /* dcache_wbinv_range */
- feroceon_dcache_inv_range, /* dcache_inv_range */
- feroceon_dcache_wb_range, /* dcache_wb_range */
+ sheeva_dcache_wbinv_range, /* dcache_wbinv_range */
+ sheeva_dcache_inv_range, /* dcache_inv_range */
+ sheeva_dcache_wb_range, /* dcache_wb_range */
armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */
- feroceon_idcache_wbinv_range, /* idcache_wbinv_all */
+ sheeva_idcache_wbinv_range, /* idcache_wbinv_all */
- feroceon_l2cache_wbinv_all, /* l2cache_wbinv_all */
- feroceon_l2cache_wbinv_range, /* l2cache_wbinv_range */
- feroceon_l2cache_inv_range, /* l2cache_inv_range */
- feroceon_l2cache_wb_range, /* l2cache_wb_range */
+ sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */
+ sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */
+ sheeva_l2cache_inv_range, /* l2cache_inv_range */
+ sheeva_l2cache_wb_range, /* l2cache_wb_range */
/* Other functions */
@@ -1000,7 +1000,7 @@ set_cpufuncs()
cputype == CPU_ID_MV88FR571_VD ||
cputype == CPU_ID_MV88FR571_41) {
- cpufuncs = feroceon_cpufuncs;
+ cpufuncs = sheeva_cpufuncs;
/*
* Workaround for Marvell MV78100 CPU: Cache prefetch
* mechanism may affect the cache coherency validity,
@@ -1011,12 +1011,12 @@ set_cpufuncs()
*/
if (cputype == CPU_ID_MV88FR571_VD ||
cputype == CPU_ID_MV88FR571_41) {
- feroceon_control_ext(0xffffffff,
+ sheeva_control_ext(0xffffffff,
FC_DCACHE_STREAM_EN | FC_WR_ALLOC_EN |
FC_BRANCH_TARG_BUF_DIS | FC_L2CACHE_EN |
FC_L2_PREF_DIS);
} else {
- feroceon_control_ext(0xffffffff,
+ sheeva_control_ext(0xffffffff,
FC_DCACHE_STREAM_EN | FC_WR_ALLOC_EN |
FC_BRANCH_TARG_BUF_DIS | FC_L2CACHE_EN);
}
diff --git a/sys/arm/arm/cpufunc_asm_feroceon.S b/sys/arm/arm/cpufunc_asm_sheeva.S
index 0e89c63..021b6f3 100644
--- a/sys/arm/arm/cpufunc_asm_feroceon.S
+++ b/sys/arm/arm/cpufunc_asm_sheeva.S
@@ -34,12 +34,12 @@ __FBSDID("$FreeBSD$");
#include <machine/param.h>
-.Lferoceon_cache_line_size:
+.Lsheeva_cache_line_size:
.word _C_LABEL(arm_pdcache_line_size)
-.Lferoceon_asm_page_mask:
+.Lsheeva_asm_page_mask:
.word _C_LABEL(PAGE_MASK)
-ENTRY(feroceon_setttb)
+ENTRY(sheeva_setttb)
/* Disable irqs */
mrs r2, cpsr
orr r3, r2, #I32_bit | F32_bit
@@ -63,11 +63,11 @@ ENTRY(feroceon_setttb)
mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */
RET
-ENTRY(feroceon_dcache_wbinv_range)
+ENTRY(sheeva_dcache_wbinv_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -76,7 +76,7 @@ ENTRY(feroceon_dcache_wbinv_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -105,11 +105,11 @@ ENTRY(feroceon_dcache_wbinv_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_idcache_wbinv_range)
+ENTRY(sheeva_idcache_wbinv_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -118,7 +118,7 @@ ENTRY(feroceon_idcache_wbinv_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -136,7 +136,7 @@ ENTRY(feroceon_idcache_wbinv_range)
msr cpsr_c, lr
/* Invalidate and clean icache line by line */
- ldr r3, .Lferoceon_cache_line_size
+ ldr r3, .Lsheeva_cache_line_size
ldr r3, [r3]
2:
mcr p15, 0, r0, c7, c5, 1
@@ -156,11 +156,11 @@ ENTRY(feroceon_idcache_wbinv_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_dcache_inv_range)
+ENTRY(sheeva_dcache_inv_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -169,7 +169,7 @@ ENTRY(feroceon_dcache_inv_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -198,11 +198,11 @@ ENTRY(feroceon_dcache_inv_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_dcache_wb_range)
+ENTRY(sheeva_dcache_wb_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -211,7 +211,7 @@ ENTRY(feroceon_dcache_wb_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -240,11 +240,11 @@ ENTRY(feroceon_dcache_wb_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_l2cache_wbinv_range)
+ENTRY(sheeva_l2cache_wbinv_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -253,7 +253,7 @@ ENTRY(feroceon_l2cache_wbinv_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -284,11 +284,11 @@ ENTRY(feroceon_l2cache_wbinv_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_l2cache_inv_range)
+ENTRY(sheeva_l2cache_inv_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -297,7 +297,7 @@ ENTRY(feroceon_l2cache_inv_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -326,11 +326,11 @@ ENTRY(feroceon_l2cache_inv_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_l2cache_wb_range)
+ENTRY(sheeva_l2cache_wb_range)
str lr, [sp, #-4]!
mrs lr, cpsr
/* Start with cache line aligned address */
- ldr ip, .Lferoceon_cache_line_size
+ ldr ip, .Lsheeva_cache_line_size
ldr ip, [ip]
sub ip, ip, #1
and r2, r0, ip
@@ -339,7 +339,7 @@ ENTRY(feroceon_l2cache_wb_range)
bics r1, r1, ip
bics r0, r0, ip
- ldr ip, .Lferoceon_asm_page_mask
+ ldr ip, .Lsheeva_asm_page_mask
and r2, r0, ip
rsb r2, r2, #PAGE_SIZE
cmp r1, r2
@@ -368,14 +368,14 @@ ENTRY(feroceon_l2cache_wb_range)
ldr lr, [sp], #4
RET
-ENTRY(feroceon_l2cache_wbinv_all)
+ENTRY(sheeva_l2cache_wbinv_all)
mov r0, #0
mcr p15, 1, r0, c15, c9, 0 /* Clean L2 */
mcr p15, 1, r0, c15, c11, 0 /* Invalidate L2 */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
-ENTRY(feroceon_control_ext)
+ENTRY(sheeva_control_ext)
mrc p15, 1, r3, c15, c1, 0 /* Read the control register */
bic r2, r3, r0 /* Clear bits */
eor r2, r2, r1 /* XOR bits */
diff --git a/sys/arm/arm/dump_machdep.c b/sys/arm/arm/dump_machdep.c
index d253e55..c45581f 100644
--- a/sys/arm/arm/dump_machdep.c
+++ b/sys/arm/arm/dump_machdep.c
@@ -158,14 +158,12 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
{
struct dumperinfo *di = (struct dumperinfo*)arg;
vm_paddr_t pa;
- vm_offset_t va;
uint32_t pgs;
size_t counter, sz, chunk;
int c, error;
error = 0; /* catch case in which chunk size is 0 */
counter = 0;
- va = 0;
pgs = mdp->md_size / PAGE_SIZE;
pa = mdp->md_start;
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index 98e76fe..5db11ca 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -74,7 +74,7 @@ void __startC(void);
#ifdef CPU_XSCALE_81342
#define cpu_l2cache_wbinv_all xscalec3_l2cache_purge
#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
-#define cpu_l2cache_wbinv_all feroceon_l2cache_wbinv_all
+#define cpu_l2cache_wbinv_all sheeva_l2cache_wbinv_all
#else
#define cpu_l2cache_wbinv_all()
#endif
@@ -404,11 +404,11 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
int symtabindex = -1;
int symstrindex = -1;
vm_offset_t lastaddr = 0;
- Elf_Addr ssym = 0, esym = 0;
+ Elf_Addr ssym = 0;
Elf_Dyn *dp;
eh = (Elf32_Ehdr *)kstart;
- ssym = esym = 0;
+ ssym = 0;
entry_point = (void*)eh->e_entry;
memcpy(phdr, (void *)(kstart + eh->e_phoff ),
eh->e_phnum * sizeof(phdr[0]));
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index db2d03ff..b209bd7 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -3102,7 +3102,7 @@ void
pmap_remove_all(vm_page_t m)
{
pv_entry_t pv;
- pt_entry_t *ptep, pte;
+ pt_entry_t *ptep;
struct l2_bucket *l2b;
boolean_t flush = FALSE;
pmap_t curpm;
@@ -3130,7 +3130,6 @@ pmap_remove_all(vm_page_t m)
l2b = pmap_get_l2_bucket(pv->pv_pmap, pv->pv_va);
KASSERT(l2b != NULL, ("No l2 bucket"));
ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
- pte = *ptep;
*ptep = 0;
PTE_SYNC_CURRENT(pv->pv_pmap, ptep);
pmap_free_l2_bucket(pv->pv_pmap, l2b, 1);
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 0867153..36ef2d4 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -108,14 +108,13 @@ void
cpu_fork(register struct thread *td1, register struct proc *p2,
struct thread *td2, int flags)
{
- struct pcb *pcb1, *pcb2;
+ struct pcb *pcb2;
struct trapframe *tf;
struct switchframe *sf;
struct mdproc *mdp2;
if ((flags & RFPROC) == 0)
return;
- pcb1 = td1->td_pcb;
pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
#ifdef __XSCALE__
#ifndef CPU_XSCALE_CORE3
diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c
index 2c44857..c983e53 100644
--- a/sys/arm/at91/at91.c
+++ b/sys/arm/at91/at91.c
@@ -50,6 +50,8 @@ static struct at91_softc *at91_softc;
static void at91_eoi(void *);
+uint32_t at91_master_clock = AT91C_MASTER_CLOCK;
+
static int
at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
diff --git a/sys/arm/at91/at91_mci.c b/sys/arm/at91/at91_mci.c
index 80ebe89..9e18eee 100644
--- a/sys/arm/at91/at91_mci.c
+++ b/sys/arm/at91/at91_mci.c
@@ -67,6 +67,9 @@ __FBSDID("$FreeBSD$");
struct at91_mci_softc {
void *intrhand; /* Interrupt handle */
device_t dev;
+ int sc_cap;
+#define CAP_HAS_4WIRE 1 /* Has 4 wire bus */
+#define CAP_NEEDS_BOUNCE 2 /* broken hardware needing bounce */
int flags;
#define CMD_STARTED 1
#define STOP_STARTED 2
@@ -77,7 +80,6 @@ struct at91_mci_softc {
bus_dmamap_t map;
int mapped;
struct mmc_host host;
- int wire4;
int bus_busy;
struct mmc_request *req;
struct mmc_command *curcmd;
@@ -167,6 +169,7 @@ at91_mci_attach(device_t dev)
device_t child;
sc->dev = dev;
+ sc->sc_cap = CAP_NEEDS_BOUNCE;
err = at91_mci_activate(dev);
if (err)
goto out;
@@ -199,9 +202,12 @@ at91_mci_attach(device_t dev)
goto out;
}
sc->host.f_min = 375000;
- sc->host.f_max = 30000000;
+ sc->host.f_max = at91_master_clock / 2; /* Typically 30MHz */
sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
- sc->host.caps = MMC_CAP_4_BIT_DATA;
+ if (sc->sc_cap & CAP_HAS_4WIRE)
+ sc->host.caps = MMC_CAP_4_BIT_DATA;
+ else
+ sc->host.caps = 0;
child = device_add_child(dev, "mmc", 0);
device_set_ivars(dev, &sc->host);
err = bus_generic_attach(dev);
@@ -274,7 +280,6 @@ at91_mci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
static int
at91_mci_update_ios(device_t brdev, device_t reqdev)
{
- uint32_t at91_master_clock = AT91C_MASTER_CLOCK;
struct at91_mci_softc *sc;
struct mmc_host *host;
struct mmc_ios *ios;
@@ -294,11 +299,12 @@ at91_mci_update_ios(device_t brdev, device_t reqdev)
else
clkdiv = (at91_master_clock / ios->clock) / 2;
}
- if (ios->bus_width == bus_width_4 && sc->wire4)
+ if (ios->bus_width == bus_width_4)
WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) | MCI_SDCR_SDCBUS);
else
WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) & ~MCI_SDCR_SDCBUS);
WR4(sc, MCI_MR, (RD4(sc, MCI_MR) & ~MCI_MR_CLKDIV) | clkdiv);
+ /* Do we need a settle time here? */
/* XXX We need to turn the device on/off here with a GPIO pin */
return (0);
}
@@ -311,7 +317,6 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
int i;
struct mmc_data *data;
struct mmc_request *req;
- size_t block_size = 1 << 9; // Fixed, per mmc/sd spec for 2GB cards
void *vaddr;
bus_addr_t paddr;
@@ -353,19 +358,21 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
// Set block size and turn on PDC mode for dma xfer and disable
// PDC until we're ready.
mr = RD4(sc, MCI_MR) & ~MCI_MR_BLKLEN;
- WR4(sc, MCI_MR, mr | (block_size << 16) | MCI_MR_PDCMODE);
+ WR4(sc, MCI_MR, mr | (data->len << 16) | MCI_MR_PDCMODE);
WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
if (cmdr & MCI_CMDR_TRCMD_START) {
if (cmdr & MCI_CMDR_TRDIR)
vaddr = cmd->data->data;
else {
- if (data->len != BBSZ)
- panic("Write multiblock write support");
- vaddr = sc->bounce_buffer;
- src = (uint32_t *)cmd->data->data;
- dst = (uint32_t *)vaddr;
- for (i = 0; i < data->len / 4; i++)
- dst[i] = bswap32(src[i]);
+ if (sc->sc_cap & CAP_NEEDS_BOUNCE) {
+ vaddr = sc->bounce_buffer;
+ src = (uint32_t *)cmd->data->data;
+ dst = (uint32_t *)vaddr;
+ for (i = 0; i < data->len / 4; i++)
+ dst[i] = bswap32(src[i]);
+ }
+ else
+ vaddr = cmd->data->data;
}
data->xfer_len = 0;
if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, data->len,
@@ -496,10 +503,12 @@ at91_mci_read_done(struct at91_mci_softc *sc)
bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->dmatag, sc->map);
sc->mapped--;
- walker = (uint32_t *)cmd->data->data;
- len = cmd->data->len / 4;
- for (i = 0; i < len; i++)
- walker[i] = bswap32(walker[i]);
+ if (sc->sc_cap & CAP_NEEDS_BOUNCE) {
+ walker = (uint32_t *)cmd->data->data;
+ len = cmd->data->len / 4;
+ for (i = 0; i < len; i++)
+ walker[i] = bswap32(walker[i]);
+ }
// Finish up the sequence...
WR4(sc, MCI_IDR, MCI_SR_ENDRX);
WR4(sc, MCI_IER, MCI_SR_RXBUFF);
@@ -643,6 +652,9 @@ at91_mci_read_ivar(device_t bus, device_t child, int which, u_char *result)
case MMCBR_IVAR_VDD:
*(int *)result = sc->host.ios.vdd;
break;
+ case MMCBR_IVAR_CAPS:
+ *(int *)result = sc->host.caps;
+ break;
case MMCBR_IVAR_MAX_DATA:
*(int *)result = 1;
break;
@@ -683,6 +695,7 @@ at91_mci_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
sc->host.ios.vdd = value;
break;
/* These are read-only */
+ case MMCBR_IVAR_CAPS:
case MMCBR_IVAR_HOST_OCR:
case MMCBR_IVAR_F_MIN:
case MMCBR_IVAR_F_MAX:
diff --git a/sys/arm/at91/at91_twi.c b/sys/arm/at91/at91_twi.c
index ff976cb..12df6c0 100644
--- a/sys/arm/at91/at91_twi.c
+++ b/sys/arm/at91/at91_twi.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_twireg.h>
+#include <arm/at91/at91var.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
@@ -128,7 +129,7 @@ at91_twi_attach(device_t dev)
AT91_TWI_LOCK_DESTROY(sc);
goto out;
}
- sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / TWI_FASTEST_CLOCK) |
+ sc->cwgr = TWI_CWGR_CKDIV(8 * at91_master_clock / TWI_FASTEST_CLOCK) |
TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) |
TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK));
WR4(sc, TWI_CR, TWI_CR_SWRST);
diff --git a/sys/arm/at91/at91_twireg.h b/sys/arm/at91/at91_twireg.h
index 1f846ea..6cca101 100644
--- a/sys/arm/at91/at91_twireg.h
+++ b/sys/arm/at91/at91_twireg.h
@@ -63,7 +63,7 @@
#define TWI_CWGR_CKDIV(x) ((x) << 16) /* Clock Divider */
#define TWI_CWGR_CHDIV(x) ((x) << 8) /* Clock High Divider */
#define TWI_CWGR_CLDIV(x) ((x) << 0) /* Clock Low Divider */
-#define TWI_CWGR_DIV(rate) ((AT91C_MASTER_CLOCK /(4*(rate))) - 2)
+#define TWI_CWGR_DIV(rate) ((at91_master_clock /(4*(rate))) - 2)
/* TWI_SR */
/* TWI_IER */
diff --git a/sys/arm/at91/at91var.h b/sys/arm/at91/at91var.h
index 3a32339..3f82dd7 100644
--- a/sys/arm/at91/at91var.h
+++ b/sys/arm/at91/at91var.h
@@ -43,4 +43,6 @@ struct at91_ivar {
struct resource_list resources;
};
+extern uint32_t at91_master_clock;
+
#endif /* _AT91VAR_H_ */
diff --git a/sys/arm/at91/uart_bus_at91usart.c b/sys/arm/at91/uart_bus_at91usart.c
index 44a5b76..aa246cb 100644
--- a/sys/arm/at91/uart_bus_at91usart.c
+++ b/sys/arm/at91/uart_bus_at91usart.c
@@ -38,13 +38,12 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/resource.h>
-#include <dev/pci/pcivar.h>
-
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91var.h>
#include "uart_if.h"
@@ -103,6 +102,8 @@ usart_at91rm92_probe(device_t dev)
break;
}
sc->sc_class = &at91_usart_class;
+ if (sc->sc_class->uc_rclk == 0)
+ sc->sc_class->uc_rclk = at91_master_clock;
return (uart_bus_probe(dev, 0, 0, 0, device_get_unit(dev)));
}
diff --git a/sys/arm/at91/uart_cpu_at91rm9200usart.c b/sys/arm/at91/uart_cpu_at91rm9200usart.c
index 78c84e8..d290c28 100644
--- a/sys/arm/at91/uart_cpu_at91rm9200usart.c
+++ b/sys/arm/at91/uart_cpu_at91rm9200usart.c
@@ -35,12 +35,16 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cons.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91var.h>
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
@@ -60,6 +64,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
struct uart_class *class;
class = &at91_usart_class;
+ if (class->uc_rclk == 0)
+ class->uc_rclk = at91_master_clock;
di->ops = uart_getops(class);
di->bas.chan = 0;
di->bas.bst = &at91_bs_tag;
diff --git a/sys/arm/at91/uart_dev_at91usart.c b/sys/arm/at91/uart_dev_at91usart.c
index 526b82d..0f50fb4 100644
--- a/sys/arm/at91/uart_dev_at91usart.c
+++ b/sys/arm/at91/uart_dev_at91usart.c
@@ -45,10 +45,11 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_usartreg.h>
#include <arm/at91/at91_pdcreg.h>
+#include <arm/at91/at91var.h>
#include "uart_if.h"
-#define DEFAULT_RCLK AT91C_MASTER_CLOCK
+#define DEFAULT_RCLK at91_master_clock
#define USART_BUFFER_SIZE 128
/*
@@ -684,6 +685,5 @@ struct uart_class at91_usart_class = {
at91_usart_methods,
sizeof(struct at91_usart_softc),
.uc_ops = &at91_usart_ops,
- .uc_range = 8,
- .uc_rclk = DEFAULT_RCLK
+ .uc_range = 8
};
diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA
index 4ff8098..c18c28a 100644
--- a/sys/arm/conf/AVILA
+++ b/sys/arm/conf/AVILA
@@ -66,13 +66,15 @@ options BOOTP_COMPAT
device pci
device uart
+device ixpwdog # watchdog timer
+device cfi # flash support
+
# I2C Bus
device iicbus
device iicbb
device iic
device ixpiic # I2C bus glue
-device ixpwdog # watchdog timer
device ds1672 # DS1672 on I2C bus
device ad7418 # AD7418 on I2C bus
diff --git a/sys/arm/conf/AVILA.hints b/sys/arm/conf/AVILA.hints
index ba3a04b..2d6d4dc 100644
--- a/sys/arm/conf/AVILA.hints
+++ b/sys/arm/conf/AVILA.hints
@@ -29,6 +29,10 @@ hint.npe.1.mac="C"
hint.npe.1.mii="B"
hint.npe.1.phy=1
+# FLASH
+hint.cfi.0.at="ixp0"
+hint.cfi.0.addr=0x50000000
+
# CF IDE controller
hint.ata_avila.0.at="ixp0"
diff --git a/sys/arm/include/atomic.h b/sys/arm/include/atomic.h
index 72e198d..71e31c3 100644
--- a/sys/arm/include/atomic.h
+++ b/sys/arm/include/atomic.h
@@ -344,7 +344,8 @@ atomic_readandclear_32(volatile u_int32_t *p)
#define atomic_clear_ptr atomic_clear_32
#define atomic_set_ptr atomic_set_32
-#define atomic_cmpset_ptr atomic_cmpset_32
+#define atomic_cmpset_ptr(dst, old, new) \
+ atomic_cmpset_32((volatile u_int *)(dst), (u_int)(old), (u_int)(new))
#define atomic_cmpset_rel_ptr atomic_cmpset_ptr
#define atomic_cmpset_acq_ptr atomic_cmpset_ptr
#define atomic_store_ptr atomic_store_32
diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h
index 0e3b33b..74f21e4 100644
--- a/sys/arm/include/cpufunc.h
+++ b/sys/arm/include/cpufunc.h
@@ -377,17 +377,17 @@ extern unsigned arm10_dcache_sets_inc;
extern unsigned arm10_dcache_index_max;
extern unsigned arm10_dcache_index_inc;
-u_int feroceon_control_ext (u_int, u_int);
-void feroceon_setttb (u_int);
-void feroceon_dcache_wbinv_range (vm_offset_t, vm_size_t);
-void feroceon_dcache_inv_range (vm_offset_t, vm_size_t);
-void feroceon_dcache_wb_range (vm_offset_t, vm_size_t);
-void feroceon_idcache_wbinv_range (vm_offset_t, vm_size_t);
-
-void feroceon_l2cache_wbinv_range (vm_offset_t, vm_size_t);
-void feroceon_l2cache_inv_range (vm_offset_t, vm_size_t);
-void feroceon_l2cache_wb_range (vm_offset_t, vm_size_t);
-void feroceon_l2cache_wbinv_all (void);
+u_int sheeva_control_ext (u_int, u_int);
+void sheeva_setttb (u_int);
+void sheeva_dcache_wbinv_range (vm_offset_t, vm_size_t);
+void sheeva_dcache_inv_range (vm_offset_t, vm_size_t);
+void sheeva_dcache_wb_range (vm_offset_t, vm_size_t);
+void sheeva_idcache_wbinv_range (vm_offset_t, vm_size_t);
+
+void sheeva_l2cache_wbinv_range (vm_offset_t, vm_size_t);
+void sheeva_l2cache_inv_range (vm_offset_t, vm_size_t);
+void sheeva_l2cache_wb_range (vm_offset_t, vm_size_t);
+void sheeva_l2cache_wbinv_all (void);
#endif
#ifdef CPU_ARM11
diff --git a/sys/arm/include/vmparam.h b/sys/arm/include/vmparam.h
index a3d8425..bc82fd0 100644
--- a/sys/arm/include/vmparam.h
+++ b/sys/arm/include/vmparam.h
@@ -97,6 +97,13 @@
#define VM_MIN_ADDRESS (0x00001000)
#ifdef ARM_USE_SMALL_ALLOC
+/*
+ * ARM_KERN_DIRECTMAP is used to make sure there's enough space between
+ * VM_MAXUSER_ADDRESS and KERNBASE to map the whole memory.
+ * It has to be a compile-time constant, even if arm_init_smallalloc(),
+ * which will do the mapping, gets the real amount of memory at runtime,
+ * because VM_MAXUSER_ADDRESS is a constant.
+ */
#ifndef ARM_KERN_DIRECTMAP
#define ARM_KERN_DIRECTMAP 512 * 1024 * 1024 /* 512 MB */
#endif
diff --git a/sys/arm/mv/common.c b/sys/arm/mv/common.c
index 5c8d003..1f64c5a 100644
--- a/sys/arm/mv/common.c
+++ b/sys/arm/mv/common.c
@@ -46,13 +46,19 @@ static int decode_win_cpu_valid(void);
static int decode_win_usb_valid(void);
static int decode_win_eth_valid(void);
static int decode_win_pcie_valid(void);
+static int decode_win_sata_valid(void);
+static int decode_win_cesa_valid(void);
static void decode_win_cpu_setup(void);
-static void decode_win_usb_setup(uint32_t ctrl);
+static void decode_win_usb_setup(void);
static void decode_win_eth_setup(uint32_t base);
static void decode_win_pcie_setup(uint32_t base);
+static void decode_win_sata_setup(void);
+static void decode_win_cesa_setup(void);
+
+static void decode_win_cesa_dump(void);
+static void decode_win_usb_dump(void);
-static uint32_t dev, rev;
static uint32_t used_cpu_wins;
uint32_t
@@ -81,6 +87,7 @@ cpu_reset(void)
uint32_t
cpu_extra_feat(void)
{
+ uint32_t dev, rev;
uint32_t ef = 0;
soc_id(&dev, &rev);
@@ -104,17 +111,6 @@ soc_power_ctrl_get(uint32_t mask)
return (mask);
}
-uint32_t
-get_tclk(void)
-{
-
-#if defined(SOC_MV_DISCOVERY)
- return (TCLK_200MHZ);
-#else
- return (TCLK_166MHZ);
-#endif
-}
-
void
soc_id(uint32_t *dev, uint32_t *rev)
{
@@ -165,6 +161,10 @@ soc_identify(void)
break;
case MV_DEV_88F6281:
dev = "Marvell 88F6281";
+ if (r == 0)
+ rev = "Z0";
+ else if (r == 2)
+ rev = "A0";
break;
case MV_DEV_MV78100:
dev = "Marvell MV78100";
@@ -185,22 +185,27 @@ soc_identify(void)
int
soc_decode_win(void)
{
+ uint32_t dev, rev;
/* Retrieve our ID: some windows facilities vary between SoC models */
soc_id(&dev, &rev);
if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
- decode_win_pcie_valid() != 1)
+ decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
+ decode_win_cesa_valid() != 1)
return(-1);
decode_win_cpu_setup();
- decode_win_usb_setup(MV_USB0_BASE);
+ decode_win_usb_setup();
decode_win_eth_setup(MV_ETH0_BASE);
if (dev == MV_DEV_MV78100)
decode_win_eth_setup(MV_ETH1_BASE);
+ if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100)
+ decode_win_cesa_setup();
decode_win_idma_setup();
+ decode_win_xor_setup();
if (dev == MV_DEV_MV78100) {
decode_win_pcie_setup(MV_PCIE00_BASE);
@@ -214,7 +219,8 @@ soc_decode_win(void)
} else
decode_win_pcie_setup(MV_PCIE_BASE);
- /* TODO set up decode wins for SATA */
+ if (dev != MV_DEV_88F5281)
+ decode_win_sata_setup();
return (0);
}
@@ -234,10 +240,15 @@ WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
-WIN_REG_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
-WIN_REG_IDX_RD(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
-WIN_REG_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
-WIN_REG_IDX_WR(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
+WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
+WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
+WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
+WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
+
+WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
+WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
+WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
+WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
@@ -245,6 +256,16 @@ WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
+
+WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
+WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
+WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
+WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
+
WIN_REG_BASE_RD(win_eth, bare, 0x290)
WIN_REG_BASE_RD(win_eth, epap, 0x294)
WIN_REG_BASE_WR(win_eth, bare, 0x290)
@@ -269,12 +290,18 @@ WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
+WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
+WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
+WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
+WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
+
/**************************************************************************
* Decode windows helper routines
**************************************************************************/
void
soc_dump_decode_win(void)
{
+ uint32_t dev, rev;
int i;
soc_id(&dev, &rev);
@@ -297,10 +324,6 @@ soc_dump_decode_win(void)
for (i = 0; i < MV_WIN_DDR_MAX; i++)
printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
ddr_br_read(i), ddr_sz_read(i));
-
- for (i = 0; i < MV_WIN_USB_MAX; i++)
- printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
- win_usb_cr_read(i), win_usb_br_read(i));
for (i = 0; i < MV_WIN_ETH_MAX; i++) {
printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
@@ -318,6 +341,8 @@ soc_dump_decode_win(void)
win_eth_epap_read(MV_ETH0_BASE));
decode_win_idma_dump();
+ decode_win_cesa_dump();
+ decode_win_usb_dump();
printf("\n");
}
@@ -327,6 +352,9 @@ soc_dump_decode_win(void)
int
win_cpu_can_remap(int i)
{
+ uint32_t dev, rev;
+
+ soc_id(&dev, &rev);
/* Depending on the SoC certain windows have remap capability */
if ((dev == MV_DEV_88F5182 && i < 2) ||
@@ -556,42 +584,69 @@ decode_win_usb_valid(void)
return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
}
+static __inline int
+usb_max_ports(void)
+{
+ uint32_t dev, rev;
+
+ soc_id(&dev, &rev);
+ return (dev == MV_DEV_MV78100 ? 3 : 1);
+}
+
+static void
+decode_win_usb_dump(void)
+{
+ int i, p, m;
+
+ m = usb_max_ports();
+ for (p = 0; p < m; p++)
+ for (i = 0; i < MV_WIN_USB_MAX; i++)
+ printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
+ win_usb_cr_read(i, p), win_usb_br_read(i, p));
+}
+
/*
* Set USB decode windows.
*/
static void
-decode_win_usb_setup(uint32_t ctrl)
+decode_win_usb_setup(void)
{
uint32_t br, cr;
- int i, j;
+ int i, j, p, m;
- /* Disable and clear all USB windows */
- for (i = 0; i < MV_WIN_USB_MAX; i++) {
- win_usb_cr_write(i, 0);
- win_usb_br_write(i, 0);
- }
+ /* Disable and clear all USB windows for all ports */
+ m = usb_max_ports();
+ for (p = 0; p < m; p++) {
- /* Only access to active DRAM banks is required */
- for (i = 0; i < MV_WIN_DDR_MAX; i++)
- if (ddr_is_active(i)) {
- br = ddr_base(i);
- /*
- * XXX for 6281 we should handle Mbus write burst limit
- * field in the ctrl reg
- */
- cr = (((ddr_size(i) - 1) & 0xffff0000) |
- (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
-
- /* Set the first free USB window */
- for (j = 0; j < MV_WIN_USB_MAX; j++) {
- if (win_usb_cr_read(j) & 0x1)
- continue;
+ for (i = 0; i < MV_WIN_USB_MAX; i++) {
+ win_usb_cr_write(i, p, 0);
+ win_usb_br_write(i, p, 0);
+ }
- win_usb_br_write(j, br);
- win_usb_cr_write(j, cr);
- break;
+ /* Only access to active DRAM banks is required */
+ for (i = 0; i < MV_WIN_DDR_MAX; i++) {
+ if (ddr_is_active(i)) {
+ br = ddr_base(i);
+ /*
+ * XXX for 6281 we should handle Mbus write
+ * burst limit field in the ctrl reg
+ */
+ cr = (((ddr_size(i) - 1) & 0xffff0000) |
+ (ddr_attr(i) << 8) |
+ (ddr_target(i) << 4) | 1);
+
+ /* Set the first free USB window */
+ for (j = 0; j < MV_WIN_USB_MAX; j++) {
+ if (win_usb_cr_read(j, p) & 0x1)
+ continue;
+
+ win_usb_br_write(j, p, br);
+ win_usb_cr_write(j, p, cr);
+ break;
+ }
}
}
+ }
}
/**************************************************************************
@@ -941,7 +996,7 @@ decode_win_idma_valid(void)
j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
if (j >= 0) {
printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
- "with " "#%d (0x%08x - 0x%08x)\n", i, b, e, j,
+ "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
idma_wins[j].base,
idma_wins[j].base + idma_wins[j].size - 1);
rv = 0;
@@ -990,3 +1045,413 @@ decode_win_idma_dump(void)
{
}
#endif
+
+/**************************************************************************
+ * XOR windows routines
+ **************************************************************************/
+#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+static int
+xor_ctrl_read(int i, int c, int e)
+{
+ uint32_t v;
+ v = win_xor_ctrl_read(c, e);
+ v &= (1 << i);
+
+ return (v >> i);
+}
+
+static void
+xor_ctrl_write(int i, int c, int e, int val)
+{
+ uint32_t v;
+
+ v = win_xor_ctrl_read(c, e);
+ v &= ~(1 << i);
+ v |= (val << i);
+ win_xor_ctrl_write(c, e, v);
+}
+
+/*
+ * Set channel protection 'val' for window 'w' on channel 'c'
+ */
+
+static void
+xor_chan_write(int c, int e, int w, int val)
+{
+ uint32_t v;
+
+ v = win_xor_ctrl_read(c, e);
+ v &= ~(0x3 << (w * 2 + 16));
+ v |= (val << (w * 2 + 16));
+ win_xor_ctrl_write(c, e, v);
+}
+
+/*
+ * Set protection 'val' on all channels for window 'w' on engine 'e'
+ */
+static void
+xor_set_prot(int w, int e, int val)
+{
+ int c;
+
+ for (c = 0; c < MV_XOR_CHAN_MAX; c++)
+ xor_chan_write(c, e, w, val);
+}
+
+static int
+win_xor_can_remap(int i)
+{
+
+ /* XOR decode windows 0-3 have remap capability */
+ if (i < 4)
+ return (1);
+
+ return (0);
+}
+
+static __inline int
+xor_max_eng(void)
+{
+ uint32_t dev, rev;
+
+ soc_id(&dev, &rev);
+ return ((dev == MV_DEV_88F6281) ? 2 :
+ (dev == MV_DEV_MV78100) ? 1 : 0);
+}
+
+static void
+xor_active_dram(int c, int e, int *window)
+{
+ uint32_t br, sz;
+ int i, m, w;
+
+ /*
+ * Set up access to all active DRAM banks
+ */
+ m = xor_max_eng();
+ for (i = 0; i < m; i++)
+ if (ddr_is_active(i)) {
+ br = ddr_base(i) | (ddr_attr(i) << 8) |
+ ddr_target(i);
+ sz = ((ddr_size(i) - 1) & 0xffff0000);
+
+ /* Place DDR entries in non-remapped windows */
+ for (w = 0; w < MV_WIN_XOR_MAX; w++)
+ if (win_xor_can_remap(w) != 1 &&
+ (xor_ctrl_read(w, c, e) == 0) &&
+ w > *window) {
+ /* Configure window */
+ win_xor_br_write(w, e, br);
+ win_xor_sz_write(w, e, sz);
+
+ /* Set protection RW on all channels */
+ xor_set_prot(w, e, 0x3);
+
+ /* Enable window */
+ xor_ctrl_write(w, c, e, 1);
+ (*window)++;
+ break;
+ }
+ }
+}
+
+void
+decode_win_xor_setup(void)
+{
+ uint32_t br, sz;
+ int i, j, z, e = 1, m, window;
+
+ /*
+ * Disable and clear all XOR windows, revoke protection for all
+ * channels
+ */
+ m = xor_max_eng();
+ for (j = 0; j < m; j++, e--) {
+
+ /* Number of non-remaped windows */
+ window = MV_XOR_NON_REMAP - 1;
+
+ for (i = 0; i < MV_WIN_XOR_MAX; i++) {
+ win_xor_br_write(i, e, 0);
+ win_xor_sz_write(i, e, 0);
+ }
+
+ if (win_xor_can_remap(i) == 1)
+ win_xor_har_write(i, e, 0);
+
+ for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
+ win_xor_ctrl_write(i, e, 0);
+ xor_active_dram(i, e, &window);
+ }
+
+ /*
+ * Remaining targets -- from a statically defined table
+ */
+ for (i = 0; i < xor_wins_no; i++)
+ if (xor_wins[i].target > 0) {
+ br = (xor_wins[i].base & 0xffff0000) |
+ (xor_wins[i].attr << 8) |
+ xor_wins[i].target;
+ sz = ((xor_wins[i].size - 1) & 0xffff0000);
+
+ /* Set the first free XOR window */
+ for (z = 0; z < MV_WIN_XOR_MAX; z++) {
+ if (xor_ctrl_read(z, 0, e) &&
+ xor_ctrl_read(z, 1, e))
+ continue;
+
+ /* Configure window */
+ win_xor_br_write(z, e, br);
+ win_xor_sz_write(z, e, sz);
+ if (win_xor_can_remap(z) &&
+ xor_wins[z].remap >= 0)
+ win_xor_har_write(z, e,
+ xor_wins[z].remap);
+
+ /* Set protection RW on all channels */
+ xor_set_prot(z, e, 0x3);
+
+ /* Enable window */
+ xor_ctrl_write(z, 0, e, 1);
+ xor_ctrl_write(z, 1, e, 1);
+ break;
+ }
+ }
+ }
+}
+
+int
+decode_win_xor_valid(void)
+{
+ const struct decode_win *wintab;
+ int c, i, j, rv;
+ uint32_t b, e, s;
+
+ if (xor_wins_no > MV_WIN_XOR_MAX) {
+ printf("XOR windows: too many entries: %d\n", xor_wins_no);
+ return (-1);
+ }
+ for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
+ if (ddr_is_active(i))
+ c++;
+
+ if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
+ printf("XOR windows: too many entries: %d, available: %d\n",
+ xor_wins_no, MV_WIN_IDMA_MAX - c);
+ return (-1);
+ }
+
+ wintab = xor_wins;
+ rv = 1;
+ for (i = 0; i < xor_wins_no; i++, wintab++) {
+
+ if (wintab->target == 0) {
+ printf("XOR window#%d: DDR target window is not "
+ "supposed to be reprogrammed!\n", i);
+ rv = 0;
+ }
+
+ if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
+ printf("XOR window#%d: not capable of remapping, but "
+ "val 0x%08x defined\n", i, wintab->remap);
+ rv = 0;
+ }
+
+ s = wintab->size;
+ b = wintab->base;
+ e = b + s - 1;
+ if (s > (0xFFFFFFFF - b + 1)) {
+ /*
+ * XXX this boundary check should account for 64bit
+ * and remapping..
+ */
+ printf("XOR window#%d: no space for size 0x%08x at "
+ "0x%08x\n", i, s, b);
+ rv = 0;
+ continue;
+ }
+
+ j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
+ if (j >= 0) {
+ printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
+ "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
+ xor_wins[j].base,
+ xor_wins[j].base + xor_wins[j].size - 1);
+ rv = 0;
+ }
+ }
+
+ return (rv);
+}
+
+void
+decode_win_xor_dump(void)
+{
+ int i, j;
+ int e = 1;
+
+ for (j = 0; j < xor_max_eng(); j++, e--) {
+ for (i = 0; i < MV_WIN_XOR_MAX; i++) {
+ printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
+ win_xor_br_read(i, e), win_xor_sz_read(i, e));
+
+ if (win_xor_can_remap(i))
+ printf(", ha 0x%08x", win_xor_har_read(i, e));
+
+ printf("\n");
+ }
+ for (i = 0; i < MV_XOR_CHAN_MAX; i++)
+ printf("XOR control#%d: 0x%08x\n", i,
+ win_xor_ctrl_read(i, e));
+ }
+}
+
+#else
+/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
+int
+decode_win_xor_valid(void)
+{
+
+ return (1);
+}
+
+void
+decode_win_xor_setup(void)
+{
+}
+
+void
+decode_win_xor_dump(void)
+{
+}
+#endif
+
+/**************************************************************************
+ * CESA TDMA windows routines
+ **************************************************************************/
+#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+/*
+ * Dump CESA TDMA decode windows.
+ */
+static void
+decode_win_cesa_dump(void)
+{
+ int i;
+
+ for (i = 0; i < MV_WIN_CESA_MAX; i++)
+ printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
+ win_cesa_cr_read(i), win_cesa_br_read(i));
+}
+
+
+/*
+ * Set CESA TDMA decode windows.
+ */
+static void
+decode_win_cesa_setup(void)
+{
+ uint32_t br, cr;
+ int i, j;
+
+ /* Disable and clear all CESA windows */
+ for (i = 0; i < MV_WIN_CESA_MAX; i++) {
+ win_cesa_cr_write(i, 0);
+ win_cesa_br_write(i, 0);
+ }
+
+ /* Only access to active DRAM banks is required. */
+ for (i = 0; i < MV_WIN_DDR_MAX; i++)
+ if (ddr_is_active(i)) {
+ br = ddr_base(i);
+ cr = (((ddr_size(i) - 1) & 0xffff0000) |
+ (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
+
+ /* Set the first available CESA window */
+ for (j = 0; j < MV_WIN_CESA_MAX; j++) {
+ if (win_cesa_cr_read(j) & 0x1)
+ continue;
+
+ win_cesa_br_write(j, br);
+ win_cesa_cr_write(j, cr);
+ break;
+ }
+ }
+}
+
+/*
+ * Check CESA TDMA decode windows.
+ */
+static int
+decode_win_cesa_valid(void)
+{
+
+ return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
+}
+#else
+
+/*
+ * Provide dummy functions to satisfy the build for SoCs not equipped with
+ * CESA
+ */
+
+int
+decode_win_cesa_valid(void)
+{
+
+ return (1);
+}
+
+void
+decode_win_cesa_setup(void)
+{
+}
+
+void
+decode_win_cesa_dump(void)
+{
+}
+#endif
+
+/**************************************************************************
+ * SATA windows routines
+ **************************************************************************/
+static void
+decode_win_sata_setup(void)
+{
+ uint32_t cr, br;
+ int i, j;
+
+ for (i = 0; i < MV_WIN_SATA_MAX; i++) {
+ win_sata_cr_write(i, 0);
+ win_sata_br_write(i, 0);
+ }
+
+ for (i = 0; i < MV_WIN_DDR_MAX; i++)
+ if (ddr_is_active(i)) {
+ cr = ((ddr_size(i) - 1) & 0xffff0000) |
+ (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
+ br = ddr_base(i);
+
+ /* Use the first available SATA window */
+ for (j = 0; j < MV_WIN_SATA_MAX; j++) {
+ if ((win_sata_cr_read(j) & 1) != 0)
+ continue;
+
+ win_sata_br_write(j, br);
+ win_sata_cr_write(j, cr);
+ break;
+ }
+ }
+}
+
+static int
+decode_win_sata_valid(void)
+{
+ uint32_t dev, rev;
+
+ soc_id(&dev, &rev);
+ if (dev == MV_DEV_88F5281)
+ return (1);
+
+ return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
+}
diff --git a/sys/arm/mv/discovery/db78xxx.c b/sys/arm/mv/discovery/db78xxx.c
index 16736b0..52db6b6 100644
--- a/sys/arm/mv/discovery/db78xxx.c
+++ b/sys/arm/mv/discovery/db78xxx.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
@@ -99,6 +100,10 @@ static const struct pmap_devmap pmap_devmap[] = {
{ 0, 0, 0, 0, 0, }
};
+const struct gpio_config mv_gpio_config[] = {
+ { -1, -1, -1 }
+};
+
int
platform_pmap_init(void)
{
@@ -109,6 +114,52 @@ platform_pmap_init(void)
return (0);
}
+void
+platform_mpp_init(void)
+{
+
+ /*
+ * MPP Configuration for DB-78100-BP
+ *
+ * MPP[0]: GE1_TXCLK
+ * MPP[1]: GE1_TXCTL
+ * MPP[2]: GE1_RXCTL
+ * MPP[3]: GE1_RXCLK
+ * MPP[4]: GE1_TXD[0]
+ * MPP[5]: GE1_TXD[1]
+ * MPP[6]: GE1_TXD[2]
+ * MPP[7]: GE1_TXD[3]
+ * MPP[8]: GE1_RXD[0]
+ * MPP[9]: GE1_RXD[1]
+ * MPP[10]: GE1_RXD[2]
+ * MPP[11]: GE1_RXD[3]
+ * MPP[13]: SYSRST_OUTn
+ * MPP[14]: SATA1_ACT
+ * MPP[15]: SATA0_ACT
+ * MPP[16]: UA2_TXD
+ * MPP[17]: UA2_RXD
+ * MPP[18]: <UNKNOWN>
+ * MPP[19]: <UNKNOWN>
+ * MPP[20]: <UNKNOWN>
+ * MPP[21]: <UNKNOWN>
+ * MPP[22]: UA3_TXD
+ * MPP[23]: UA3_RXD
+ * MPP[48]: <UNKNOWN>
+ * MPP[49]: <UNKNOWN>
+ *
+ * Others: GPIO
+ *
+ * <UNKNOWN> entries are not documented, not on the schematics etc.
+ */
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x22222222);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x33302222);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x44333344);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x0000FFFF);
+}
+
static void
platform_identify(void *dummy)
{
@@ -121,7 +172,3 @@ platform_identify(void *dummy)
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
-
-/*
- * TODO routine setting GPIO/MPP pins
- */
diff --git a/sys/arm/mv/discovery/discovery.c b/sys/arm/mv/discovery/discovery.c
index c245fa9..ce35e99 100644
--- a/sys/arm/mv/discovery/discovery.c
+++ b/sys/arm/mv/discovery/discovery.c
@@ -103,6 +103,16 @@ struct obio_device obio_devices[] = {
{ -1 },
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
},
+ { "ehci", MV_USB1_BASE, MV_USB_SIZE,
+ { MV_INT_USB_ERR, MV_INT_USB1, -1 },
+ { -1 },
+ CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
+ },
+ { "ehci", MV_USB2_BASE, MV_USB_SIZE,
+ { MV_INT_USB_ERR, MV_INT_USB2, -1 },
+ { -1 },
+ CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
+ },
{ "mge", MV_ETH0_BASE, MV_ETH_SIZE,
{ MV_INT_GBERX, MV_INT_GBETX, MV_INT_GBEMISC,
MV_INT_GBESUM, MV_INT_GBE_ERR, -1 },
@@ -177,7 +187,7 @@ const struct obio_pci mv_pci_info[] = {
{ 0, 0, 0 }
};
-struct resource_spec mv_gpio_spec[] = {
+struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
@@ -186,7 +196,7 @@ struct resource_spec mv_gpio_spec[] = {
{ -1, 0 }
};
-struct resource_spec mv_xor_spec[] = {
+struct resource_spec mv_xor_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
@@ -206,6 +216,9 @@ const struct decode_win cpu_win_tbl[] = {
/* Device bus CS2 */
{ 1, 0x3b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
+
+ /* CESA */
+ { 9, 0x01, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
};
const struct decode_win *cpu_wins = cpu_win_tbl;
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
@@ -226,3 +239,33 @@ const struct decode_win idma_win_tbl[] = {
};
const struct decode_win *idma_wins = idma_win_tbl;
int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
+
+const struct decode_win xor_win_tbl[] = {
+ /* PCIE MEM */
+ { 4, 0xE8, _MV_PCIE_MEM_PHYS(0), _MV_PCIE_MEM_SIZE, -1},
+ { 4, 0xD8, _MV_PCIE_MEM_PHYS(1), _MV_PCIE_MEM_SIZE, -1},
+};
+const struct decode_win *xor_wins = xor_win_tbl;
+int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
+
+uint32_t
+get_tclk(void)
+{
+ uint32_t sar;
+
+ /*
+ * On Discovery TCLK is can be configured to 166 MHz or 200 MHz.
+ * Current setting is read from Sample At Reset register.
+ */
+ sar = bus_space_read_4(obio_tag, MV_MPP_BASE, SAMPLE_AT_RESET_HI);
+ sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
+
+ switch (sar) {
+ case 0:
+ return (TCLK_166MHZ);
+ case 1:
+ return (TCLK_200MHZ);
+ default:
+ panic("Unknown TCLK settings!");
+ }
+}
diff --git a/sys/arm/mv/files.mv b/sys/arm/mv/files.mv
index 0e834f6..eb9fa00 100644
--- a/sys/arm/mv/files.mv
+++ b/sys/arm/mv/files.mv
@@ -15,7 +15,7 @@
arm/arm/bus_space_generic.c standard
arm/arm/cpufunc_asm_arm10.S standard
arm/arm/cpufunc_asm_armv5_ec.S standard
-arm/arm/cpufunc_asm_feroceon.S standard
+arm/arm/cpufunc_asm_sheeva.S standard
arm/arm/irq_dispatch.S standard
arm/mv/bus_space.c standard
diff --git a/sys/arm/mv/gpio.c b/sys/arm/mv/gpio.c
index bb7f04b..9045455 100644
--- a/sys/arm/mv/gpio.c
+++ b/sys/arm/mv/gpio.c
@@ -62,7 +62,7 @@ struct mv_gpio_softc {
uint8_t use_high;
};
-extern struct resource_spec mv_gpio_spec[];
+extern struct resource_spec mv_gpio_res[];
static struct mv_gpio_softc *mv_gpio_softc = NULL;
static uint32_t gpio_setup[MV_GPIO_MAX_NPINS];
@@ -113,8 +113,8 @@ mv_gpio_probe(device_t dev)
static int
mv_gpio_attach(device_t dev)
{
- int error, i;
- struct mv_gpio_softc *sc;
+ int error, i;
+ struct mv_gpio_softc *sc;
uint32_t dev_id, rev_id;
sc = (struct mv_gpio_softc *)device_get_softc(dev);
@@ -143,7 +143,7 @@ mv_gpio_attach(device_t dev)
return (ENXIO);
}
- error = bus_alloc_resources(dev, mv_gpio_spec, sc->res);
+ error = bus_alloc_resources(dev, mv_gpio_res, sc->res);
if (error) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
@@ -171,21 +171,33 @@ mv_gpio_attach(device_t dev)
INTR_TYPE_MISC | INTR_FAST,
(driver_filter_t *)mv_gpio_intr, NULL,
sc, &sc->ih_cookie[i]) != 0) {
- bus_release_resources(dev, mv_gpio_spec, sc->res);
+ bus_release_resources(dev, mv_gpio_res, sc->res);
device_printf(dev, "could not set up intr %d\n", i);
return (ENXIO);
}
}
+ /* Setup GPIO lines */
+ for (i = 0; mv_gpio_config[i].gc_gpio >= 0; i++) {
+ mv_gpio_configure(mv_gpio_config[i].gc_gpio,
+ mv_gpio_config[i].gc_flags, ~0u);
+
+ if (mv_gpio_config[i].gc_output < 0)
+ mv_gpio_out_en(mv_gpio_config[i].gc_gpio, 0);
+ else
+ mv_gpio_out(mv_gpio_config[i].gc_gpio,
+ mv_gpio_config[i].gc_output, 1);
+ }
+
return (0);
}
static void
mv_gpio_intr(void *arg)
{
- uint32_t int_cause, gpio_val;
- uint32_t int_cause_hi, gpio_val_hi = 0;
- int i;
+ uint32_t int_cause, gpio_val;
+ uint32_t int_cause_hi, gpio_val_hi = 0;
+ int i;
int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE);
gpio_val = mv_gpio_reg_read(GPIO_DATA_IN);
@@ -219,7 +231,7 @@ mv_gpio_intr(void *arg)
* GPIO interrupt handling
*/
-static struct intr_event *gpio_events[MV_GPIO_MAX_NPINS];
+static struct intr_event *gpio_events[MV_GPIO_MAX_NPINS];
int
mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
@@ -243,8 +255,8 @@ mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
gpio_events[pin] = event;
}
- intr_event_add_handler(event, name, filt, hand, arg, intr_priority(flags),
- flags, cookiep);
+ intr_event_add_handler(event, name, filt, hand, arg,
+ intr_priority(flags), flags, cookiep);
return (0);
}
@@ -277,7 +289,7 @@ mv_gpio_intr_unmask(int pin)
static void
mv_gpio_intr_handler(int pin)
{
- struct intr_event *event;
+ struct intr_event *event;
event = gpio_events[pin];
if (event == NULL || TAILQ_EMPTY(&event->ie_handlers))
@@ -295,8 +307,8 @@ mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask)
if (mask & MV_GPIO_BLINK)
mv_gpio_blink(pin, flags & MV_GPIO_BLINK);
- if (mask & MV_GPIO_POLARITY)
- mv_gpio_polarity(pin, flags & MV_GPIO_POLARITY);
+ if (mask & MV_GPIO_POLAR_LOW)
+ mv_gpio_polarity(pin, flags & MV_GPIO_POLAR_LOW);
if (mask & MV_GPIO_EDGE)
mv_gpio_edge(pin, flags & MV_GPIO_EDGE);
if (mask & MV_GPIO_LEVEL)
diff --git a/sys/arm/mv/kirkwood/db88f6xxx.c b/sys/arm/mv/kirkwood/db88f6xxx.c
index 16736b0..8ff4f61 100644
--- a/sys/arm/mv/kirkwood/db88f6xxx.c
+++ b/sys/arm/mv/kirkwood/db88f6xxx.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
@@ -99,6 +100,10 @@ static const struct pmap_devmap pmap_devmap[] = {
{ 0, 0, 0, 0, 0, }
};
+const struct gpio_config mv_gpio_config[] = {
+ { -1, -1, -1 }
+};
+
int
platform_pmap_init(void)
{
@@ -109,6 +114,47 @@ platform_pmap_init(void)
return (0);
}
+void
+platform_mpp_init(void)
+{
+
+ /*
+ * MPP configuration for DB-88F6281-BP and DB-88F6281-BP-A
+ *
+ * MPP[0]: NF_IO[2]
+ * MPP[1]: NF_IO[3]
+ * MPP[2]: NF_IO[4]
+ * MPP[3]: NF_IO[5]
+ * MPP[4]: NF_IO[6]
+ * MPP[5]: NF_IO[7]
+ * MPP[6]: SYSRST_OUTn
+ * MPP[7]: SPI_SCn
+ * MPP[8]: TW_SDA
+ * MPP[9]: TW_SCK
+ * MPP[10]: UA0_TXD
+ * MPP[11]: UA0_RXD
+ * MPP[12]: SD_CLK
+ * MPP[13]: SD_CMD
+ * MPP[14]: SD_D[0]
+ * MPP[15]: SD_D[1]
+ * MPP[16]: SD_D[2]
+ * MPP[17]: SD_D[3]
+ * MPP[18]: NF_IO[0]
+ * MPP[19]: NF_IO[1]
+ * MPP[20]: SATA1_AC
+ * MPP[21]: SATA0_AC
+ *
+ * Others: GPIO
+ */
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x21111111);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x11113311);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00551111);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x00000000);
+}
+
static void
platform_identify(void *dummy)
{
@@ -121,7 +167,3 @@ platform_identify(void *dummy)
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
-
-/*
- * TODO routine setting GPIO/MPP pins
- */
diff --git a/sys/arm/mv/kirkwood/kirkwood.c b/sys/arm/mv/kirkwood/kirkwood.c
index 0ba34aa..a2d41a6 100644
--- a/sys/arm/mv/kirkwood/kirkwood.c
+++ b/sys/arm/mv/kirkwood/kirkwood.c
@@ -112,7 +112,7 @@ const struct obio_pci mv_pci_info[] = {
{ 0, 0, 0 }
};
-struct resource_spec mv_gpio_spec[] = {
+struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
@@ -124,7 +124,7 @@ struct resource_spec mv_gpio_spec[] = {
{ -1, 0 }
};
-struct resource_spec mv_xor_spec[] = {
+struct resource_spec mv_xor_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
@@ -147,6 +147,35 @@ const struct decode_win cpu_win_tbl[] = {
/* Device bus CS2 */
{ 1, 0x1b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
+
+ /* CESA */
+ { 3, 0x00, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
+
};
const struct decode_win *cpu_wins = cpu_win_tbl;
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
+
+const struct decode_win xor_win_tbl[] = {
+ /* PCIE MEM */
+ { 4, 0xE8, MV_PCIE_MEM_PHYS_BASE, MV_PCIE_MEM_SIZE, -1 },
+};
+const struct decode_win *xor_wins = xor_win_tbl;
+int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
+
+uint32_t
+get_tclk(void)
+{
+ uint32_t dev, rev;
+
+ /*
+ * On Kirkwood TCLK is not configurable and depends on silicon
+ * revision:
+ * - A0 has 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)
+ return (TCLK_200MHZ);
+
+ return (TCLK_166MHZ);
+}
diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index 8b5388f..1c00eb5 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -551,6 +551,11 @@ initarm(void *mdp, void *unused __unused)
print_kenv();
/*
+ * Re-initialise MPP
+ */
+ platform_mpp_init();
+
+ /*
* Re-initialise decode windows
*/
if (soc_decode_win() != 0)
diff --git a/sys/arm/mv/mv_pci.c b/sys/arm/mv/mv_pci.c
index b878b0a..61a64a1 100644
--- a/sys/arm/mv/mv_pci.c
+++ b/sys/arm/mv/mv_pci.c
@@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$");
#define PCIE_REG_STATUS 0x1A04
#define PCIE_REG_IRQ_MASK 0x1910
+#define STATUS_LINK_DOWN 1
#define STATUS_BUS_OFFS 8
#define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS)
#define STATUS_DEV_OFFS 16
@@ -95,10 +96,12 @@ __FBSDID("$FreeBSD$");
struct pcib_mbus_softc {
device_t sc_dev;
+ struct rman sc_iomem_rman;
bus_addr_t sc_iomem_base;
bus_addr_t sc_iomem_size;
bus_addr_t sc_iomem_alloc; /* Next allocation. */
+ struct rman sc_ioport_rman;
bus_addr_t sc_ioport_base;
bus_addr_t sc_ioport_size;
bus_addr_t sc_ioport_alloc; /* Next allocation. */
@@ -434,6 +437,8 @@ pcib_mbus_probe(device_t self)
P2P_CONF_DEV_OFFS;
} else {
val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS);
+ if (val & STATUS_LINK_DOWN)
+ goto out;
bus = sc->sc_busnr = (val & STATUS_BUS_MASK) >> STATUS_BUS_OFFS;
dev = sc->sc_devnr = (val & STATUS_DEV_MASK) >> STATUS_DEV_OFFS;
}
@@ -521,12 +526,39 @@ pcib_mbus_attach(device_t self)
sc->sc_ioport_size = sc->sc_info->op_io_size;
sc->sc_ioport_alloc = sc->sc_info->op_io_base;
+ sc->sc_iomem_rman.rm_type = RMAN_ARRAY;
+ err = rman_init(&sc->sc_iomem_rman);
+ if (err)
+ return (err);
+
+ sc->sc_ioport_rman.rm_type = RMAN_ARRAY;
+ err = rman_init(&sc->sc_ioport_rman);
+ if (err) {
+ rman_fini(&sc->sc_iomem_rman);
+ return (err);
+ }
+
+ err = rman_manage_region(&sc->sc_iomem_rman, sc->sc_iomem_base,
+ sc->sc_iomem_base + sc->sc_iomem_size - 1);
+ if (err)
+ goto error;
+
+ err = rman_manage_region(&sc->sc_ioport_rman, sc->sc_ioport_base,
+ sc->sc_ioport_base + sc->sc_ioport_size - 1);
+ if (err)
+ goto error;
+
err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev));
if (err)
- return(err);
+ goto error;
device_add_child(self, "pci", -1);
return (bus_generic_attach(self));
+
+error:
+ rman_fini(&sc->sc_iomem_rman);
+ rman_fini(&sc->sc_ioport_rman);
+ return (err);
}
static int
@@ -570,7 +602,7 @@ pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, int func,
return (width);
addr = (*allocp + mask) & ~mask;
- if ((*allocp = addr + size) >= limit)
+ if ((*allocp = addr + size) > limit)
return (-1);
if (bootverbose)
@@ -634,8 +666,10 @@ static int
pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot,
int func, int hdrtype)
{
+ const struct obio_pci_irq_map *map = sc->sc_info->op_pci_irq_map;
int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6;
- int bar = 0, irq, pin, i;
+ int bar = 0, irq = -1;
+ int pin, i;
/* Program the base address registers */
while (bar < maxbar) {
@@ -652,8 +686,14 @@ pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot,
pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func,
PCIR_INTPIN, 1);
- if (sc->sc_info->op_get_irq != NULL)
- irq = sc->sc_info->op_get_irq(bus, slot, func, pin);
+ if (map != NULL)
+ while (map->opim_irq >= 0) {
+ if ((map->opim_slot == slot || map->opim_slot < 0) &&
+ (map->opim_pin == pin || map->opim_pin < 0))
+ irq = map->opim_irq;
+
+ map++;
+ }
else
irq = sc->sc_info->op_irq;
@@ -728,9 +768,37 @@ static struct resource *
pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
+ struct pcib_mbus_softc *sc = device_get_softc(dev);
+ struct rman *rm = NULL;
+ struct resource *res;
- return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
- type, rid, start, end, count, flags));
+ switch (type) {
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_ioport_rman;
+ break;
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_iomem_rman;
+ break;
+ default:
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags));
+ };
+
+ res = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (res == NULL)
+ return (NULL);
+
+ rman_set_rid(res, *rid);
+ rman_set_bustag(res, obio_tag);
+ rman_set_bushandle(res, start);
+
+ if (flags & RF_ACTIVE)
+ if (bus_activate_resource(child, type, *rid, res)) {
+ rman_release_resource(res);
+ return (NULL);
+ }
+
+ return (res);
}
static int
@@ -738,8 +806,11 @@ pcib_mbus_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *res)
{
- return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
- type, rid, res));
+ if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY)
+ return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+ type, rid, res));
+
+ return (rman_release_resource(res));
}
static int
diff --git a/sys/arm/mv/mvreg.h b/sys/arm/mv/mvreg.h
index 9b86c07..3efd2cd 100644
--- a/sys/arm/mv/mvreg.h
+++ b/sys/arm/mv/mvreg.h
@@ -74,8 +74,12 @@
#define MV_DEV_CS2_PHYS_BASE (MV_DEV_CS1_PHYS_BASE + MV_DEV_CS1_SIZE)
#define MV_DEV_CS2_SIZE 1024 /* XXX u-boot has 1MB */
+#define MV_CESA_SRAM_PHYS_BASE 0xFD000000
+#define MV_CESA_SRAM_BASE MV_CESA_SRAM_PHYS_BASE /* VA == PA mapping */
+#define MV_CESA_SRAM_SIZE (1024 * 1024)
+
/* XXX this is probably not robust against wraparounds... */
-#if ((MV_DEV_CS2_PHYS_BASE + MV_DEV_CS2_SIZE) > 0xFFFEFFFF)
+#if ((MV_CESA_SRAM_PHYS_BASE + MV_CESA_SRAM_SIZE) > 0xFFFEFFFF)
#error Devices memory layout overlaps reset vectors range!
#endif
@@ -103,6 +107,12 @@
#define MV_TIMERS_SIZE 0x30
#define MV_PCI_BASE (MV_BASE + 0x30000)
#define MV_PCI_SIZE 0x2000
+#if defined (SOC_MV_KIRKWOOD)
+#define MV_CESA_BASE (MV_BASE + 0x30000) /* CESA,PCI don't coexist */
+#elif defined (SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
+#define MV_CESA_BASE (MV_BASE + 0x90000)
+#endif
+#define MV_CESA_SIZE 0x10000
#define MV_PCIE_BASE (MV_BASE + 0x40000)
#define MV_PCIE_SIZE 0x2000
@@ -128,6 +138,13 @@
#define MV_ETH0_BASE (MV_BASE + 0x72000)
#define MV_ETH1_BASE (MV_BASE + 0x76000)
#define MV_ETH_SIZE 0x2000
+#if defined(SOC_MV_ORION) || defined(SOC_MV_KIRKWOOD)
+#define MV_SATAHC_BASE (MV_BASE + 0x80000)
+#define MV_SATAHC_SIZE 0x6000
+#elif defined(SOC_MV_DISCOVERY)
+#define MV_SATAHC_BASE (MV_BASE + 0xA0000)
+#define MV_SATAHC_SIZE 0x6000
+#endif
#define MV_DEV_CS0_BASE MV_DEV_CS0_PHYS_BASE
@@ -178,6 +195,7 @@
#define MV_INT_GBE1MISC 18 /* GbE1 misc. interrupt */
#define MV_INT_USB_CI 19 /* USB Controller interrupt */
#define MV_INT_SATA 21 /* Serial-ATA Interrupt */
+#define MV_INT_CESA 22 /* Security engine completion int. */
#define MV_INT_IDMA_ERR 23 /* DMA error interrupt */
#define MV_INT_UART0 33 /* UART0 Interrupt */
#define MV_INT_UART1 34
@@ -216,7 +234,7 @@
#define MV_INT_USB0 16 /* USB0 interrupt */
#define MV_INT_USB1 17 /* USB1 interrupt */
#define MV_INT_USB2 18 /* USB2 interrupt */
-#define MV_INT_CRYPTO 19 /* Crypto engine completion interrupt */
+#define MV_INT_CESA 19 /* Crypto engine completion interrupt */
#define MV_INT_XOR0 22 /* XOR engine 0 completion interrupt */
#define MV_INT_XOR1 23 /* XOR engine 1 completion interrupt */
#define MV_INT_SATA 26 /* SATA interrupt */
@@ -394,7 +412,7 @@
#define MV_GPIO_MAX_NPINS 64
#define MV_GPIO_BLINK 0x1
-#define MV_GPIO_POLARITY 0x2
+#define MV_GPIO_POLAR_LOW 0x2
#define MV_GPIO_EDGE 0x4
#define MV_GPIO_LEVEL 0x8
@@ -405,15 +423,29 @@
/*
* MPP
*/
+#if defined(SOC_MV_ORION)
#define MPP_CONTROL0 0x00
#define MPP_CONTROL1 0x04
#define MPP_CONTROL2 0x50
-#define DEVICE_MULTIPLEX 0x08
+#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+#define MPP_CONTROL0 0x00
+#define MPP_CONTROL1 0x04
+#define MPP_CONTROL2 0x08
+#define MPP_CONTROL3 0x0C
+#define MPP_CONTROL4 0x10
+#define MPP_CONTROL5 0x14
+#define MPP_CONTROL6 0x18
+#else
+#error SOC_MV_XX not defined
+#endif
#if defined(SOC_MV_ORION)
#define SAMPLE_AT_RESET 0x10
-#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+#elif defined(SOC_MV_KIRKWOOD)
#define SAMPLE_AT_RESET 0x30
+#elif defined(SOC_MV_DISCOVERY)
+#define SAMPLE_AT_RESET_LO 0x30
+#define SAMPLE_AT_RESET_HI 0x34
#else
#error SOC_MV_XX not defined
#endif
@@ -421,14 +453,12 @@
/*
* Clocks
*/
-#ifdef SOC_MV_ORION
-#define TCLK_MASK 0x300
-#define TCLK_SHIFT 0x8
-#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
-#define TCLK_MASK 0x30000
-#define TCLK_SHIFT 0x10
-#else
-#error SOC_MV_XX not defined
+#if defined(SOC_MV_ORION)
+#define TCLK_MASK 0x00000300
+#define TCLK_SHIFT 0x08
+#elif defined(SOC_MV_DISCOVERY)
+#define TCLK_MASK 0x00000180
+#define TCLK_SHIFT 0x07
#endif
#define TCLK_100MHZ 100000000
@@ -464,8 +494,12 @@
#define MV_WIN_DDR_SIZE(n) (0x8 * (n) + 0x4)
#define MV_WIN_DDR_MAX 4
-#define MV_WIN_USB_CTRL(n) (0x10 * (n) + 0x0)
-#define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x4)
+#define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xa04)
+#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xa00)
+#define MV_WIN_CESA_MAX 4
+
+#define MV_WIN_USB_CTRL(n, m) (0x10 * (n) + (m) * 0x1000 + 0x0)
+#define MV_WIN_USB_BASE(n, m) (0x10 * (n) + (m) * 0x1000 + 0x4)
#define MV_WIN_USB_MAX 4
#define MV_WIN_ETH_BASE(n) (0x8 * (n) + 0x200)
@@ -480,6 +514,15 @@
#define MV_WIN_IDMA_MAX 8
#define MV_IDMA_CHAN_MAX 4
+#define MV_WIN_XOR_BASE(n, m) (0x4 * (n) + 0xa50 + (m) * 0x100)
+#define MV_WIN_XOR_SIZE(n, m) (0x4 * (n) + 0xa70 + (m) * 0x100)
+#define MV_WIN_XOR_REMAP(n, m) (0x4 * (n) + 0xa90 + (m) * 0x100)
+#define MV_WIN_XOR_CTRL(n, m) (0x4 * (n) + 0xa40 + (m) * 0x100)
+#define MV_WIN_XOR_OVERR(n, m) (0x4 * (n) + 0xaa0 + (m) * 0x100)
+#define MV_WIN_XOR_MAX 8
+#define MV_XOR_CHAN_MAX 2
+#define MV_XOR_NON_REMAP 4
+
#define MV_WIN_PCIE_CTRL(n) (0x10 * (((n) < 5) ? (n) : \
(n) + 1) + 0x1820)
#define MV_WIN_PCIE_BASE(n) (0x10 * (((n) < 5) ? (n) : \
@@ -491,6 +534,10 @@
#define MV_PCIE_BAR(n) (0x04 * (n) + 0x1804)
#define MV_PCIE_BAR_MAX 3
+#define MV_WIN_SATA_CTRL(n) (0x10 * (n) + 0x30)
+#define MV_WIN_SATA_BASE(n) (0x10 * (n) + 0x34)
+#define MV_WIN_SATA_MAX 4
+
#define WIN_REG_IDX_RD(pre,reg,off,base) \
static __inline uint32_t \
pre ## _ ## reg ## _read(int i) \
@@ -498,6 +545,13 @@
return (bus_space_read_4(obio_tag, base, off(i))); \
}
+#define WIN_REG_IDX_RD2(pre,reg,off,base) \
+ static __inline uint32_t \
+ pre ## _ ## reg ## _read(int i, int j) \
+ { \
+ return (bus_space_read_4(obio_tag, base, off(i, j))); \
+ } \
+
#define WIN_REG_BASE_IDX_RD(pre,reg,off) \
static __inline uint32_t \
pre ## _ ## reg ## _read(uint32_t base, int i) \
@@ -512,6 +566,13 @@
bus_space_write_4(obio_tag, base, off(i), val); \
}
+#define WIN_REG_IDX_WR2(pre,reg,off,base) \
+ static __inline void \
+ pre ## _ ## reg ## _write(int i, int j, uint32_t val) \
+ { \
+ bus_space_write_4(obio_tag, base, off(i, j), val); \
+ }
+
#define WIN_REG_BASE_IDX_WR(pre,reg,off) \
static __inline void \
pre ## _ ## reg ## _write(uint32_t base, int i, uint32_t val) \
diff --git a/sys/arm/mv/mvvar.h b/sys/arm/mv/mvvar.h
index 645c9ac7..061f363 100644
--- a/sys/arm/mv/mvvar.h
+++ b/sys/arm/mv/mvvar.h
@@ -63,7 +63,11 @@ struct obio_device {
struct resource_list od_resources;
};
-typedef int (*obio_get_irq_t)(u_int bus, u_int slot, u_int func, u_int pin);
+struct obio_pci_irq_map {
+ int opim_slot;
+ int opim_pin;
+ int opim_irq;
+};
struct obio_pci {
int op_type;
@@ -82,8 +86,14 @@ struct obio_pci {
int op_mem_win_target;
int op_mem_win_attr;
- obio_get_irq_t op_get_irq; /* IRQ Mapping callback */
- int op_irq; /* used if callback is NULL */
+ const struct obio_pci_irq_map *op_pci_irq_map;
+ int op_irq; /* used if IRQ map table is NULL */
+};
+
+struct gpio_config {
+ int gc_gpio; /* GPIO number */
+ uint32_t gc_flags; /* GPIO flags */
+ int gc_output; /* GPIO output value */
};
struct decode_win {
@@ -95,12 +105,15 @@ struct decode_win {
};
extern const struct obio_pci mv_pci_info[];
+extern const struct gpio_config mv_gpio_config[];
extern bus_space_tag_t obio_tag;
extern struct obio_device obio_devices[];
extern const struct decode_win *cpu_wins;
extern const struct decode_win *idma_wins;
+extern const struct decode_win *xor_wins;
extern int cpu_wins_no;
extern int idma_wins_no;
+extern int xor_wins_no;
/* Function prototypes */
int mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
@@ -112,6 +125,7 @@ void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable);
uint8_t mv_gpio_in(uint32_t pin);
int platform_pmap_init(void);
+void platform_mpp_init(void);
int soc_decode_win(void);
void soc_id(uint32_t *dev, uint32_t *rev);
void soc_identify(void);
@@ -127,6 +141,10 @@ void decode_win_idma_dump(void);
void decode_win_idma_setup(void);
int decode_win_idma_valid(void);
+void decode_win_xor_dump(void);
+void decode_win_xor_setup(void);
+int decode_win_xor_valid(void);
+
int ddr_is_active(int i);
uint32_t ddr_base(int i);
uint32_t ddr_size(int i);
diff --git a/sys/arm/mv/obio.c b/sys/arm/mv/obio.c
index 2e1eacd..5415804 100644
--- a/sys/arm/mv/obio.c
+++ b/sys/arm/mv/obio.c
@@ -131,8 +131,7 @@ mbus_print_child(device_t dev, device_t child)
if (od == NULL)
panic("Unknown device on %s", device_get_nameunit(dev));
- rv = 0;
- rv += bus_print_child_header(dev, child);
+ rv = bus_print_child_header(dev, child);
rv += resource_list_print_type(&od->od_resources, "at mem",
SYS_RES_MEMORY, "0x%08lx");
diff --git a/sys/arm/mv/orion/db88f5xxx.c b/sys/arm/mv/orion/db88f5xxx.c
index d3a1a8c..5a5f283 100644
--- a/sys/arm/mv/orion/db88f5xxx.c
+++ b/sys/arm/mv/orion/db88f5xxx.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
@@ -122,35 +123,64 @@ static const struct pmap_devmap pmap_devmap[] = {
{ 0, 0, 0, 0, 0, }
};
-int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin)
-{
- int irq;
-
- switch (slot) {
- case 7:
- irq = GPIO2IRQ(12); /* GPIO 0 for DB-88F5182 */
- break; /* GPIO 12 for DB-88F5281 */
- case 8:
- case 9:
- irq = GPIO2IRQ(13); /* GPIO 1 for DB-88F5182 */
- break; /* GPIO 13 for DB-88F5281 */
- default:
- irq = -1;
- break;
- };
+/*
+ * The pci_irq_map table consists of 3 columns:
+ * - PCI slot number (less than zero means ANY).
+ * - PCI IRQ pin (less than zero means ANY).
+ * - PCI IRQ (less than zero marks end of table).
+ *
+ * IRQ number from the first matching entry is used to configure PCI device
+ */
- /*
- * XXX This isn't the right place to setup GPIO, but it makes sure
- * that PCI works on 5XXX targets where U-Boot doesn't set up the GPIO
- * correctly to handle PCI IRQs (e.g., on 5182). This code will go
- * away once we set up GPIO in a generic way in a proper place (TBD).
- */
- if (irq >= 0)
- mv_gpio_configure(IRQ2GPIO(irq), MV_GPIO_POLARITY |
- MV_GPIO_LEVEL, ~0u);
+/* PCI IRQ Map for DB-88F5281 */
+const struct obio_pci_irq_map pci_irq_map[] = {
+ { 7, -1, GPIO2IRQ(12) },
+ { 8, -1, GPIO2IRQ(13) },
+ { 9, -1, GPIO2IRQ(13) },
+ { -1, -1, -1 }
+};
- return (irq);
-}
+#if 0
+/* PCI IRQ Map for DB-88F5182 */
+const struct obio_pci_irq_map pci_irq_map[] = {
+ { 7, -1, GPIO2IRQ(0) },
+ { 8, -1, GPIO2IRQ(1) },
+ { 9, -1, GPIO2IRQ(1) },
+ { -1, -1, -1 }
+};
+#endif
+
+/*
+ * mv_gpio_config row structure:
+ * <GPIO number>, <GPIO flags>, <GPIO mode>
+ *
+ * - GPIO pin number (less than zero marks end of table)
+ * - GPIO flags:
+ * MV_GPIO_BLINK
+ * MV_GPIO_POLAR_LOW
+ * MV_GPIO_EDGE
+ * MV_GPIO_LEVEL
+ * - GPIO mode:
+ * 1 - Output, set to HIGH.
+ * 0 - Output, set to LOW.
+ * -1 - Input.
+ */
+
+/* GPIO Configuration for DB-88F5281 */
+const struct gpio_config mv_gpio_config[] = {
+ { 12, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+ { 13, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+ { -1, -1, -1 }
+};
+
+#if 0
+/* GPIO Configuration for DB-88F5182 */
+const struct gpio_config mv_gpio_config[] = {
+ { 0, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+ { 1, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+ { -1, -1, -1 }
+};
+#endif
int
platform_pmap_init(void)
@@ -162,6 +192,63 @@ platform_pmap_init(void)
return (0);
}
+void
+platform_mpp_init(void)
+{
+
+ /*
+ * MPP configuration for DB-88F5281
+ *
+ * MPP[2]: PCI_REQn[3]
+ * MPP[3]: PCI_GNTn[3]
+ * MPP[4]: PCI_REQn[4]
+ * MPP[5]: PCI_GNTn[4]
+ * MPP[6]: <UNKNOWN>
+ * MPP[7]: <UNKNOWN>
+ * MPP[8]: <UNKNOWN>
+ * MPP[9]: <UNKNOWN>
+ * MPP[14]: NAND Flash REn[2]
+ * MPP[15]: NAND Flash WEn[2]
+ * MPP[16]: UA1_RXD
+ * MPP[17]: UA1_TXD
+ * MPP[18]: UA1_CTS
+ * MPP[19]: UA1_RTS
+ *
+ * Others: GPIO
+ *
+ * <UNKNOWN> entries are not documented, not on the schematics etc.
+ */
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x33222203);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x44000033);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00000000);
+
+#if 0
+ /*
+ * MPP configuration for DB-88F5182
+ *
+ * MPP[2]: PCI_REQn[3]
+ * MPP[3]: PCI_GNTn[3]
+ * MPP[4]: PCI_REQn[4]
+ * MPP[5]: PCI_GNTn[4]
+ * MPP[6]: SATA0_ACT
+ * MPP[7]: SATA1_ACT
+ * MPP[12]: SATA0_PRESENT
+ * MPP[13]: SATA1_PRESENT
+ * MPP[14]: NAND_FLASH_REn[2]
+ * MPP[15]: NAND_FLASH_WEn[2]
+ * MPP[16]: UA1_RXD
+ * MPP[17]: UA1_TXD
+ * MPP[18]: UA1_CTS
+ * MPP[19]: UA1_RTS
+ *
+ * Others: GPIO
+ */
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x55222203);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x44550000);
+ bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00000000);
+#endif
+}
+
static void
platform_identify(void *dummy)
{
@@ -174,7 +261,3 @@ platform_identify(void *dummy)
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
-
-/*
- * TODO routine setting GPIO/MPP pins
- */
diff --git a/sys/arm/mv/orion/orion.c b/sys/arm/mv/orion/orion.c
index 5ee3bac..e1852c1 100644
--- a/sys/arm/mv/orion/orion.c
+++ b/sys/arm/mv/orion/orion.c
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
-extern int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin);
+extern const struct obio_pci_irq_map pci_irq_map[];
struct obio_device obio_devices[] = {
{ "ic", MV_IC_BASE, MV_IC_SIZE,
@@ -106,13 +106,13 @@ const struct obio_pci mv_pci_info[] = {
MV_PCI_BASE, MV_PCI_SIZE,
MV_PCI_IO_BASE, MV_PCI_IO_SIZE, 3, 0x51,
MV_PCI_MEM_BASE, MV_PCI_MEM_SIZE, 3, 0x59,
- platform_pci_get_irq, -1
+ pci_irq_map, -1
},
{ 0, 0, 0 }
};
-struct resource_spec mv_gpio_spec[] = {
+struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
@@ -167,3 +167,24 @@ const struct decode_win idma_win_tbl[] = {
};
const struct decode_win *idma_wins = idma_win_tbl;
int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
+
+uint32_t
+get_tclk(void)
+{
+ uint32_t sar;
+
+ /*
+ * On Orion TCLK is can be configured to 150 MHz or 166 MHz.
+ * Current setting is read from Sample At Reset register.
+ */
+ sar = bus_space_read_4(obio_tag, MV_MPP_BASE, SAMPLE_AT_RESET);
+ sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
+ switch (sar) {
+ case 1:
+ return (TCLK_150MHZ);
+ case 2:
+ return (TCLK_166MHZ);
+ default:
+ panic("Unknown TCLK settings!");
+ }
+}
diff --git a/sys/arm/sa11x0/assabet_machdep.c b/sys/arm/sa11x0/assabet_machdep.c
index 24be01e..71d71da 100644
--- a/sys/arm/sa11x0/assabet_machdep.c
+++ b/sys/arm/sa11x0/assabet_machdep.c
@@ -210,12 +210,10 @@ initarm(void *arg, void *arg2)
struct pv_addr md_addr;
struct pv_addr md_bla;
int loop;
- u_int kerneldatasize, symbolsize;
u_int l1pagetable;
vm_offset_t freemempos;
vm_offset_t lastalloced;
vm_offset_t lastaddr;
- vm_size_t pt_size;
uint32_t memsize = 32 * 1024 * 1024;
sa1110_uart_vaddr = SACOM1_VBASE;
@@ -232,8 +230,6 @@ initarm(void *arg, void *arg2)
physical_end = lastaddr;
physical_freestart = (((vm_offset_t)physical_end) + PAGE_MASK) & ~PAGE_MASK;
md_addr.pv_va = md_addr.pv_pa = MDROOT_ADDR;
- kerneldatasize = (u_int32_t)&end - (u_int32_t)KERNVIRTADDR;
- symbolsize = 0;
freemempos = (vm_offset_t)round_page(physical_freestart);
memset((void *)freemempos, 0, 256*1024);
/* Define a macro to simplify memory allocation */
@@ -265,14 +261,12 @@ initarm(void *arg, void *arg2)
}
}
- valloc_pages(systempage, 1);
-
/*
* 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.
*/
- pt_size = round_page(freemempos) - physical_freestart;
+ valloc_pages(systempage, 1);
/* Allocate stacks for all modes */
valloc_pages(irqstack, IRQ_STACK_SIZE);
diff --git a/sys/arm/xscale/i8134x/i81342_mcu.c b/sys/arm/xscale/i8134x/i81342_mcu.c
index 40afe98..045fe96 100644
--- a/sys/arm/xscale/i8134x/i81342_mcu.c
+++ b/sys/arm/xscale/i8134x/i81342_mcu.c
@@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/bus.h>
#include <machine/bus.h>
#include <arm/xscale/i8134x/i81342reg.h>
diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c
index 181ccb4..f75ddd8 100644
--- a/sys/arm/xscale/ixp425/avila_machdep.c
+++ b/sys/arm/xscale/ixp425/avila_machdep.c
@@ -154,6 +154,10 @@ static const struct pmap_devmap ixp425_devmap[] = {
{ IXP425_EXP_VBASE, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, },
+ /* CFI Flash on the Expansion Bus */
+ { IXP425_EXP_BUS_CS0_VBASE, IXP425_EXP_BUS_CS0_HWBASE,
+ IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, },
+
/* IXP425 PCI Configuration */
{ IXP425_PCI_VBASE, IXP425_PCI_HWBASE, IXP425_PCI_SIZE,
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, },
diff --git a/sys/arm/xscale/ixp425/files.ixp425 b/sys/arm/xscale/ixp425/files.ixp425
index 02814f5..3538569 100644
--- a/sys/arm/xscale/ixp425/files.ixp425
+++ b/sys/arm/xscale/ixp425/files.ixp425
@@ -15,6 +15,7 @@ arm/xscale/ixp425/uart_cpu_ixp425.c optional uart
arm/xscale/ixp425/uart_bus_ixp425.c optional uart
arm/xscale/ixp425/ixp425_a4x_space.c optional uart
arm/xscale/ixp425/ixp425_a4x_io.S optional uart
+dev/cfi/cfi_bus_ixp4xx.c optional cfi
dev/uart/uart_dev_ns8250.c optional uart
#
# NPE-based Ethernet support (requires qmgr also).
diff --git a/sys/arm/xscale/ixp425/ixp425.c b/sys/arm/xscale/ixp425/ixp425.c
index 170b9f6..f2366de 100644
--- a/sys/arm/xscale/ixp425/ixp425.c
+++ b/sys/arm/xscale/ixp425/ixp425.c
@@ -329,6 +329,8 @@ static const struct {
{ IXP425_IO_HWBASE, IXP425_IO_SIZE, IXP425_IO_VBASE },
{ IXP425_PCI_HWBASE, IXP425_PCI_SIZE, IXP425_PCI_VBASE },
{ IXP425_PCI_MEM_HWBASE,IXP425_PCI_MEM_SIZE, IXP425_PCI_MEM_VBASE },
+ { IXP425_EXP_BUS_CS0_HWBASE, IXP425_EXP_BUS_CS0_SIZE,
+ IXP425_EXP_BUS_CS0_VBASE },
/* NB: needed only for uart_cpu_getdev */
{ IXP425_UART0_HWBASE, IXP425_REG_SIZE, IXP425_UART0_VBASE },
{ IXP425_UART1_HWBASE, IXP425_REG_SIZE, IXP425_UART1_VBASE },
diff --git a/sys/arm/xscale/ixp425/ixp425reg.h b/sys/arm/xscale/ixp425/ixp425reg.h
index afd12ff..f48fb59 100644
--- a/sys/arm/xscale/ixp425/ixp425reg.h
+++ b/sys/arm/xscale/ixp425/ixp425reg.h
@@ -76,6 +76,10 @@
* Global cache clean area
* FF00 0000 ---------------------------
*
+ * FE00 0000 ---------------------------
+ * 16M CFI Flash (on ext bus)
+ * FD00 0000 ---------------------------
+ *
* FC00 0000 ---------------------------
* PCI Data (memory space)
* F800 0000 --------------------------- IXP425_PCI_MEM_VBASE
@@ -649,6 +653,9 @@
#define IXP425_EXP_BUS_CSx_VBASE(i) \
(IXP425_MAC_B_VBASE + (i)*IXP425_MAC_B_SIZE)
+#define IXP425_EXP_BUS_CS0_HWBASE IXP425_EXP_BUS_CSx_HWBASE(0)
+#define IXP425_EXP_BUS_CS0_VBASE 0xFD000000UL
+#define IXP425_EXP_BUS_CS0_SIZE 0x01000000 /* NB: 16M */
#define IXP425_EXP_BUS_CS1_HWBASE IXP425_EXP_BUS_CSx_HWBASE(1)
#define IXP425_EXP_BUS_CS1_VBASE IXP425_EXP_BUS_CSx_VBASE(1)
#define IXP425_EXP_BUS_CS1_SIZE 0x1000
@@ -663,7 +670,6 @@
#define IXP425_EXP_BUS_CS4_SIZE 0x1000
/* NB: not mapped (yet) */
-#define IXP425_EXP_BUS_CS0_HWBASE IXP425_EXP_BUS_CSx_HWBASE(0)
#define IXP425_EXP_BUS_CS5_HWBASE IXP425_EXP_BUS_CSx_HWBASE(5)
#define IXP425_EXP_BUS_CS6_HWBASE IXP425_EXP_BUS_CSx_HWBASE(6)
#define IXP425_EXP_BUS_CS7_HWBASE IXP425_EXP_BUS_CSx_HWBASE(7)
diff --git a/sys/boot/common/load.c b/sys/boot/common/load.c
deleted file mode 100644
index a4c665d..0000000
--- a/sys/boot/common/load.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*-
- * 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 <stand.h>
-
-#define LOAD_TINYBUF 2048
-
-/*
- * Attempt to load the file at (path) into an allocated
- * area on the heap, return a pointer to it or NULL
- * on failure.
- *
- * Because in many cases it is impossible to determine the
- * true size of a file without reading it, we do just that.
- */
-char *
-filedup(const char *path, int flags)
-{
- char *buf;
- int fd;
- size_t size, result;
-
- if ((fd = open(path, F_READ | flags)) == -1)
- return(NULL);
-
- printf("%s open, flags 0x%x\n", path, files[fd].f_flags);
- buf = alloc(LOAD_TINYBUF);
-
- /* Read the first buffer-full */
- size = read(fd, buf, LOAD_TINYBUF);
- if (size < 1) {
- free(buf, LOAD_TINYBUF);
- close(fd);
- return(NULL);
- }
- /* If it all fitted, then just return the buffer straight out */
- if (size < LOAD_TINYBUF) {
- close(fd);
- buf[size] = 0;
- return(buf);
- }
-
- printf("tinybuf loaded, size %d\n", size);
- getchar();
-
- /* Read everything until we know how big it is */
- for (;;) {
- result = read(fd, buf, LOAD_TINYBUF);
- if (result == -1) {
- free(buf, LOAD_TINYBUF);
- close(fd);
- return(NULL);
- }
- if (result == 0)
- break;
- size += result;
- }
-
- /* discard the old buffer, close the file */
- free(buf, LOAD_TINYBUF);
- close(fd);
-
- /* reopen the file, realloc the buffer */
- if ((fd = open(path, F_READ | flags)) == -1)
- return(NULL);
- buf = alloc(size);
- result = read(fd, buf, size);
- close(fd);
- if (result != size) {
- free(buf, size);
- return(NULL);
- }
- return(buf);
-}
-
diff --git a/sys/boot/forth/loader.4th b/sys/boot/forth/loader.4th
index 234453c..7b22b6d 100644
--- a/sys/boot/forth/loader.4th
+++ b/sys/boot/forth/loader.4th
@@ -93,6 +93,7 @@ only forth definitions also support-functions
\
\ If a password was defined, execute autoboot and ask for
\ password if autoboot returns.
+\ Do not exit unless the right password is given.
: check-password
password .addr @ if
@@ -150,8 +151,7 @@ only forth definitions also support-functions
\ line, if interpreted, or given on the stack, if compiled in.
: (read-conf) ( addr len -- )
- conf_files .addr @ ?dup if free abort" Fatal error freeing memory" then
- strdup conf_files .len ! conf_files .addr !
+ conf_files string=
include_conf_files \ Will recurse on new loader_conf_files definitions
;
@@ -165,110 +165,26 @@ only forth definitions also support-functions
then
; immediate
-\ ***** enable-module
-\
-\ Turn a module loading on.
-
-: enable-module ( <module> -- )
- bl parse module_options @ >r
- begin
- r@
- while
- 2dup
- r@ module.name dup .addr @ swap .len @
- compare 0= if
- 2drop
- r@ module.name dup .addr @ swap .len @ type
- true r> module.flag !
- ." will be loaded." cr
- exit
- then
- r> module.next @ >r
- repeat
- r> drop
- type ." wasn't found." cr
-;
+\ show, enable, disable, toggle module loading. They all take module from
+\ the next word
-\ ***** disable-module
-\
-\ Turn a module loading off.
-
-: disable-module ( <module> -- )
- bl parse module_options @ >r
- begin
- r@
- while
- 2dup
- r@ module.name dup .addr @ swap .len @
- compare 0= if
- 2drop
- r@ module.name dup .addr @ swap .len @ type
- false r> module.flag !
- ." will not be loaded." cr
- exit
- then
- r> module.next @ >r
- repeat
- r> drop
- type ." wasn't found." cr
+: set-module-flag ( module_addr val -- ) \ set and print flag
+ over module.flag !
+ dup module.name strtype
+ module.flag @ if ." will be loaded" else ." will not be loaded" then cr
;
-\ ***** toggle-module
-\
-\ Turn a module loading on/off.
-
-: toggle-module ( <module> -- )
- bl parse module_options @ >r
- begin
- r@
- while
- 2dup
- r@ module.name dup .addr @ swap .len @
- compare 0= if
- 2drop
- r@ module.name dup .addr @ swap .len @ type
- r@ module.flag @ 0= dup r> module.flag !
- if
- ." will be loaded." cr
- else
- ." will not be loaded." cr
- then
- exit
- then
- r> module.next @ >r
- repeat
- r> drop
- type ." wasn't found." cr
-;
+: enable-module find-module ?dup if true set-module-flag then ;
+
+: disable-module find-module ?dup if false set-module-flag then ;
+
+: toggle-module find-module ?dup if dup module.flag @ 0= set-module-flag then ;
\ ***** show-module
\
\ Show loading information about a module.
-: show-module ( <module> -- )
- bl parse module_options @ >r
- begin
- r@
- while
- 2dup
- r@ module.name dup .addr @ swap .len @
- compare 0= if
- 2drop
- ." Name: " r@ module.name dup .addr @ swap .len @ type cr
- ." Path: " r@ module.loadname dup .addr @ swap .len @ type cr
- ." Type: " r@ module.type dup .addr @ swap .len @ type cr
- ." Flags: " r@ module.args dup .addr @ swap .len @ type cr
- ." Before load: " r@ module.beforeload dup .addr @ swap .len @ type cr
- ." After load: " r@ module.afterload dup .addr @ swap .len @ type cr
- ." Error: " r@ module.loaderror dup .addr @ swap .len @ type cr
- ." Status: " r> module.flag @ if ." Load" else ." Don't load" then cr
- exit
- then
- r> module.next @ >r
- repeat
- r> drop
- type ." wasn't found." cr
-;
+: show-module ( <module> -- ) find-module ?dup if show-one-module then ;
\ Words to be used inside configuration files
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
index b8fd81e..7443d68 100644
--- a/sys/boot/forth/loader.conf
+++ b/sys/boot/forth/loader.conf
@@ -278,6 +278,7 @@ if_vge_load="NO" # VIA VT6122 PCI Gigabit Ethernet
if_udav_load="NO" # Davicom DM9601 USB Ethernet
if_upgt_load="NO" # Conexant/Intersil PrismGT USB wireless
if_ural_load="NO" # Ralink Technology USB wireless
+if_urtw_load="NO" # Realtek 8187L USB wireless
if_vr_load="NO" # VIA Rhine I and Rhine II
if_vx_load="NO" # 3Com 3C590 family
if_wb_load="NO" # Winbond W89C840F
diff --git a/sys/boot/forth/pnp.4th b/sys/boot/forth/pnp.4th
index 395164d..8cd6bea 100644
--- a/sys/boot/forth/pnp.4th
+++ b/sys/boot/forth/pnp.4th
@@ -24,6 +24,39 @@
\
\ $FreeBSD$
+
+\ The following pnp code is used in pnp.4th and pnp.c
+structure: STAILQ_HEAD
+ ptr stqh_first \ type*
+ ptr stqh_last \ type**
+;structure
+
+structure: STAILQ_ENTRY
+ ptr stqe_next \ type*
+;structure
+
+structure: pnphandler
+ ptr pnph.name
+ ptr pnph.enumerate
+;structure
+
+structure: pnpident
+ ptr pnpid.ident \ char*
+ sizeof STAILQ_ENTRY cells member: pnpid.link \ pnpident
+;structure
+
+structure: pnpinfo \ sync with sys/boot/config/bootstrap.h
+ ptr pnpi.desc
+ int pnpi.revision
+ ptr pnpi.module \ (char*) module args
+ int pnpi.argc
+ ptr pnpi.argv
+ ptr pnpi.handler \ pnphandler
+ sizeof STAILQ_HEAD member: pnpi.ident \ pnpident
+ sizeof STAILQ_ENTRY member: pnpi.link \ pnpinfo
+;structure
+\ end of pnp support
+
pnpdevices drop
: enumerate
diff --git a/sys/boot/forth/support.4th b/sys/boot/forth/support.4th
index 2466499..5484e06 100644
--- a/sys/boot/forth/support.4th
+++ b/sys/boot/forth/support.4th
@@ -26,7 +26,6 @@
\ Loader.rc support functions:
\
-\ initialize_support ( -- ) initialize global variables
\ initialize ( addr len -- ) as above, plus load_conf_files
\ load_conf ( addr len -- ) load conf file given
\ include_conf_files ( -- ) load all conf files in load_conf_files
@@ -61,24 +60,23 @@
\ value any_conf_read? indicates if a conf file was succesfully read
\
\ Other exported words:
-\
+\ note, strlen is internal
\ strdup ( addr len -- addr' len) similar to strdup(3)
\ strcat ( addr len addr' len' -- addr len+len' ) similar to strcat(3)
-\ strlen ( addr -- len ) similar to strlen(3)
\ s' ( | string' -- addr len | ) similar to s"
\ rudimentary structure support
\ Exception values
-1 constant syntax_error
-2 constant out_of_memory
-3 constant free_error
-4 constant set_error
-5 constant read_error
-6 constant open_error
-7 constant exec_error
-8 constant before_load_error
-9 constant after_load_error
+1 constant ESYNTAX
+2 constant ENOMEM
+3 constant EFREE
+4 constant ESETERROR \ error setting environment variable
+5 constant EREAD \ error reading
+6 constant EOPEN
+7 constant EEXEC \ XXX never catched
+8 constant EBEFORELOAD
+9 constant EAFTERLOAD
\ I/O constants
@@ -132,7 +130,8 @@ structure: module
ptr module.next
;structure
-\ Internal loader structures
+\ Internal loader structures (preloaded_file, kernel_module, file_metadata)
+\ must be in sync with the C struct in sys/boot/common/bootstrap.h
structure: preloaded_file
ptr pf.name
ptr pf.type
@@ -159,51 +158,7 @@ structure: file_metadata
0 member: md.data \ variable size
;structure
-structure: config_resource
- ptr cf.name
- int cf.type
-0 constant RES_INT
-1 constant RES_STRING
-2 constant RES_LONG
- 2 cells member: u
-;structure
-
-structure: config_device
- ptr cd.name
- int cd.unit
- int cd.resource_count
- ptr cd.resources \ config_resource
-;structure
-
-structure: STAILQ_HEAD
- ptr stqh_first \ type*
- ptr stqh_last \ type**
-;structure
-
-structure: STAILQ_ENTRY
- ptr stqe_next \ type*
-;structure
-
-structure: pnphandler
- ptr pnph.name
- ptr pnph.enumerate
-;structure
-
-structure: pnpident
- ptr pnpid.ident \ char*
- sizeof STAILQ_ENTRY cells member: pnpid.link \ pnpident
-;structure
-
-structure: pnpinfo
- ptr pnpi.desc
- int pnpi.revision
- ptr pnpi.module \ (char*) module args
- int pnpi.argc
- ptr pnpi.argv
- ptr pnpi.handler \ pnphandler
- sizeof STAILQ_HEAD member: pnpi.ident \ pnpident
- sizeof STAILQ_ENTRY member: pnpi.link \ pnpinfo
-;structure
+\ end of structures
\ Global variables
@@ -216,11 +171,9 @@ create last_module_option sizeof module.next allot 0 last_module_option !
0 value nextboot?
\ Support string functions
-
-: strdup ( addr len -- addr' len )
- >r r@ allocate if out_of_memory throw then
- tuck r@ move
- r>
+: strdup { addr len -- addr' len' }
+ len allocate if ENOMEM throw then
+ addr over len move len
;
: strcat { addr len addr' len' -- addr len+len' }
@@ -228,29 +181,27 @@ create last_module_option sizeof module.next allot 0 last_module_option !
addr len len' +
;
-: strlen ( addr -- len )
- 0 >r
+: strchr { addr len c -- addr' len' }
begin
- dup c@ while
- 1+ r> 1+ >r repeat
- drop r>
+ len
+ while
+ addr c@ c = if addr len exit then
+ addr 1 + to addr
+ len 1 - to len
+ repeat
+ 0 0
;
-: s'
+: s' \ same as s", allows " in the string
[char] ' parse
- state @ if
- postpone sliteral
- then
+ state @ if postpone sliteral then
; immediate
: 2>r postpone >r postpone >r ; immediate
: 2r> postpone r> postpone r> ; immediate
: 2r@ postpone 2r> postpone 2dup postpone 2>r ; immediate
-: getenv?
- getenv
- -1 = if false else drop true then
-;
+: getenv? getenv -1 = if false else drop true then ;
\ Private definitions
@@ -271,27 +222,27 @@ only forth also support-functions definitions
\ Standard suffixes
-: load_module_suffix s" _load" ;
-: module_loadname_suffix s" _name" ;
-: module_type_suffix s" _type" ;
-: module_args_suffix s" _flags" ;
-: module_beforeload_suffix s" _before" ;
-: module_afterload_suffix s" _after" ;
-: module_loaderror_suffix s" _error" ;
+: load_module_suffix s" _load" ;
+: module_loadname_suffix s" _name" ;
+: module_type_suffix s" _type" ;
+: module_args_suffix s" _flags" ;
+: module_beforeload_suffix s" _before" ;
+: module_afterload_suffix s" _after" ;
+: module_loaderror_suffix s" _error" ;
\ Support operators
: >= < 0= ;
: <= > 0= ;
-\ Assorted support funcitons
+\ Assorted support functions
-: free-memory free if free_error throw then ;
+: free-memory free if EFREE throw then ;
: strget { var -- addr len } var .addr @ var .len @ ;
\ assign addr len to variable.
-: strset { addr len var -- } addr var .addr ! len var .len ! ;
+: strset { addr len var -- } addr var .addr ! len var .len ! ;
\ free memory and reset fields
: strfree { var -- } var .addr @ ?dup if free-memory 0 0 var strset then ;
@@ -299,6 +250,18 @@ only forth also support-functions definitions
\ free old content, make a copy of the string and assign to variable
: string= { addr len var -- } var strfree addr len strdup var strset ;
+: strtype ( str -- ) strget type ;
+
+\ assign a reference to what is on the stack
+: strref { addr len var -- addr len }
+ addr var .addr ! len var .len ! addr len
+;
+
+\ unquote a string
+: unquote ( addr len -- addr len )
+ over c@ [char] " = if 2 chars - swap char+ swap then
+;
+
\ Assignment data temporary storage
string name_buffer
@@ -366,16 +329,16 @@ line-reading definitions
line_buffer .len @ if
line_buffer .addr @
line_buffer .len @ r@ +
- resize if out_of_memory throw then
+ resize if ENOMEM throw then
else
- r@ allocate if out_of_memory throw then
+ r@ allocate if ENOMEM throw then
then
line_buffer .addr !
r>
;
: append_to_line_buffer ( addr len -- )
- line_buffer .addr @ line_buffer .len @
+ line_buffer strget
2swap strcat
line_buffer .len !
drop
@@ -395,23 +358,15 @@ line-reading definitions
: refill_buffer
0 to read_buffer_ptr
read_buffer .addr @ 0= if
- read_buffer_size allocate if out_of_memory throw then
+ read_buffer_size allocate if ENOMEM throw then
read_buffer .addr !
then
fd @ read_buffer .addr @ read_buffer_size fread
- dup -1 = if read_error throw then
+ dup -1 = if EREAD throw then
dup 0= if true to end_of_file? then
read_buffer .len !
;
-: reset_line_buffer
- line_buffer .addr @ ?dup if
- free-memory
- then
- 0 line_buffer .addr !
- 0 line_buffer .len !
-;
-
support-functions definitions
: reset_line_reading
@@ -419,7 +374,7 @@ support-functions definitions
;
: read_line
- reset_line_buffer
+ line_buffer strfree
skip_newlines
begin
read_from_buffer
@@ -459,9 +414,9 @@ also parser definitions also
0 value parsing_function
0 value end_of_line
-: end_of_line?
- line_pointer end_of_line =
-;
+: end_of_line? line_pointer end_of_line = ;
+
+\ classifiers for various character classes in the input line
: letter?
line_pointer c@ >r
@@ -480,70 +435,46 @@ also parser definitions also
or
;
-: quote?
- line_pointer c@ [char] " =
-;
+: quote? line_pointer c@ [char] " = ;
-: assignment_sign?
- line_pointer c@ [char] = =
-;
+: assignment_sign? line_pointer c@ [char] = = ;
-: comment?
- line_pointer c@ [char] # =
-;
+: comment? line_pointer c@ [char] # = ;
-: space?
- line_pointer c@ bl =
- line_pointer c@ tab = or
-;
+: space? line_pointer c@ bl = line_pointer c@ tab = or ;
-: backslash?
- line_pointer c@ [char] \ =
-;
+: backslash? line_pointer c@ [char] \ = ;
-: underscore?
- line_pointer c@ [char] _ =
-;
+: underscore? line_pointer c@ [char] _ = ;
-: dot?
- line_pointer c@ [char] . =
-;
+: dot? line_pointer c@ [char] . = ;
-: skip_character
- line_pointer char+ to line_pointer
-;
+\ manipulation of input line
+: skip_character line_pointer char+ to line_pointer ;
-: skip_to_end_of_line
- end_of_line to line_pointer
-;
+: skip_to_end_of_line end_of_line to line_pointer ;
: eat_space
begin
- space?
+ end_of_line? if 0 else space? then
while
skip_character
- end_of_line? if exit then
repeat
;
: parse_name ( -- addr len )
line_pointer
begin
- letter? digit? underscore? dot? or or or
+ end_of_line? if 0 else letter? digit? underscore? dot? or or or then
while
skip_character
- end_of_line? if
- line_pointer over -
- strdup
- exit
- then
repeat
line_pointer over -
strdup
;
: remove_backslashes { addr len | addr' len' -- addr' len' }
- len allocate if out_of_memory throw then
+ len allocate if ENOMEM throw then
to addr'
addr >r
begin
@@ -561,16 +492,16 @@ also parser definitions also
: parse_quote ( -- addr len )
line_pointer
skip_character
- end_of_line? if syntax_error throw then
+ end_of_line? if ESYNTAX throw then
begin
quote? 0=
while
backslash? if
skip_character
- end_of_line? if syntax_error throw then
+ end_of_line? if ESYNTAX throw then
then
skip_character
- end_of_line? if syntax_error throw then
+ end_of_line? if ESYNTAX throw then
repeat
skip_character
line_pointer over -
@@ -579,8 +510,7 @@ also parser definitions also
: read_name
parse_name ( -- addr len )
- name_buffer .len !
- name_buffer .addr !
+ name_buffer strset
;
: read_value
@@ -589,8 +519,7 @@ also parser definitions also
else
parse_name ( -- addr len )
then
- value_buffer .len !
- value_buffer .addr !
+ value_buffer strset
;
: comment
@@ -600,7 +529,7 @@ also parser definitions also
: white_space_4
eat_space
comment? if ['] comment to parsing_function exit then
- end_of_line? 0= if syntax_error throw then
+ end_of_line? 0= if ESYNTAX throw then
;
: variable_value
@@ -613,7 +542,7 @@ also parser definitions also
letter? digit? quote? or or if
['] variable_value to parsing_function exit
then
- syntax_error throw
+ ESYNTAX throw
;
: assignment_sign
@@ -624,7 +553,7 @@ also parser definitions also
: white_space_2
eat_space
assignment_sign? if ['] assignment_sign to parsing_function exit then
- syntax_error throw
+ ESYNTAX throw
;
: variable_name
@@ -636,13 +565,13 @@ also parser definitions also
eat_space
letter? if ['] variable_name to parsing_function exit then
comment? if ['] comment to parsing_function exit then
- end_of_line? 0= if syntax_error throw then
+ end_of_line? 0= if ESYNTAX throw then
;
file-processing definitions
: get_assignment
- line_buffer .addr @ line_buffer .len @ + to end_of_line
+ line_buffer strget + to end_of_line
line_buffer .addr @ to line_pointer
['] white_space_1 to parsing_function
begin
@@ -653,7 +582,7 @@ file-processing definitions
parsing_function ['] comment =
parsing_function ['] white_space_1 =
parsing_function ['] white_space_4 =
- or or 0= if syntax_error throw then
+ or or 0= if ESYNTAX throw then
;
only forth also support-functions also file-processing definitions also
@@ -661,7 +590,7 @@ only forth also support-functions also file-processing definitions also
\ Process line
: assignment_type? ( addr len -- flag )
- name_buffer .addr @ name_buffer .len @
+ name_buffer strget
compare 0=
;
@@ -671,69 +600,56 @@ only forth also support-functions also file-processing definitions also
over compare 0=
;
-: loader_conf_files?
- s" loader_conf_files" assignment_type?
-;
+: loader_conf_files? s" loader_conf_files" assignment_type? ;
-: nextboot_flag?
- s" nextboot_enable" assignment_type?
-;
+: nextboot_flag? s" nextboot_enable" assignment_type? ;
-: nextboot_conf?
- s" nextboot_conf" assignment_type?
-;
+: nextboot_conf? s" nextboot_conf" assignment_type? ;
-: verbose_flag?
- s" verbose_loading" assignment_type?
-;
+: verbose_flag? s" verbose_loading" assignment_type? ;
-: execute?
- s" exec" assignment_type?
-;
+: execute? s" exec" assignment_type? ;
-: password?
- s" password" assignment_type?
-;
+: password? s" password" assignment_type? ;
-: module_load?
- load_module_suffix suffix_type?
-;
+: module_load? load_module_suffix suffix_type? ;
-: module_loadname?
- module_loadname_suffix suffix_type?
-;
+: module_loadname? module_loadname_suffix suffix_type? ;
-: module_type?
- module_type_suffix suffix_type?
-;
+: module_type? module_type_suffix suffix_type? ;
-: module_args?
- module_args_suffix suffix_type?
-;
+: module_args? module_args_suffix suffix_type? ;
-: module_beforeload?
- module_beforeload_suffix suffix_type?
-;
+: module_beforeload? module_beforeload_suffix suffix_type? ;
-: module_afterload?
- module_afterload_suffix suffix_type?
-;
+: module_afterload? module_afterload_suffix suffix_type? ;
-: module_loaderror?
- module_loaderror_suffix suffix_type?
-;
+: module_loaderror? module_loaderror_suffix suffix_type? ;
-: set_nextboot_conf
- nextboot_conf_file .addr @ ?dup if
- free-memory
- then
- value_buffer .addr @ c@ [char] " = if
- value_buffer .addr @ char+ value_buffer .len @ 2 chars -
+\ build a 'set' statement and execute it
+: set_environment_variable
+ name_buffer .len @ value_buffer .len @ + 5 chars + \ size of result string
+ allocate if ENOMEM throw then
+ dup 0 \ start with an empty string and append the pieces
+ s" set " strcat
+ name_buffer strget strcat
+ s" =" strcat
+ value_buffer strget strcat
+ ['] evaluate catch if
+ 2drop free drop
+ ESETERROR throw
else
- value_buffer .addr @ value_buffer .len @
+ free-memory
then
- strdup
- nextboot_conf_file .len ! nextboot_conf_file .addr !
+;
+
+: set_conf_files
+ set_environment_variable
+ s" loader_conf_files" getenv conf_files string=
+;
+
+: set_nextboot_conf \ XXX maybe do as set_conf_files ?
+ value_buffer strget unquote nextboot_conf_file string=
;
: append_to_module_options_list ( addr -- )
@@ -746,35 +662,32 @@ only forth also support-functions also file-processing definitions also
then
;
-: set_module_name ( addr -- )
- name_buffer .addr @ name_buffer .len @
- strdup
- >r over module.name .addr !
- r> swap module.name .len !
+: set_module_name { addr -- } \ check leaks
+ name_buffer strget addr module.name string=
;
: yes_value?
- value_buffer .addr @ value_buffer .len @
+ value_buffer strget \ XXX could use unquote
2dup s' "YES"' compare >r
2dup s' "yes"' compare >r
2dup s" YES" compare >r
s" yes" compare r> r> r> and and and 0=
;
-: find_module_option ( -- addr | 0 )
+: find_module_option ( -- addr | 0 ) \ return ptr to entry matching name_buffer
module_options @
begin
dup
while
- dup module.name dup .addr @ swap .len @
- name_buffer .addr @ name_buffer .len @
+ dup module.name strget
+ name_buffer strget
compare 0= if exit then
module.next @
repeat
;
: new_module_option ( -- addr )
- sizeof module allocate if out_of_memory throw then
+ sizeof module allocate if ENOMEM throw then
dup sizeof module erase
dup append_to_module_options_list
dup set_module_name
@@ -792,103 +705,38 @@ only forth also support-functions also file-processing definitions also
: set_module_args
name_buffer .len @ module_args_suffix nip - name_buffer .len !
- get_module_option module.args
- dup .addr @ ?dup if free-memory then
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 chars - swap char+ swap
- then
- strdup
- >r over .addr !
- r> swap .len !
+ value_buffer strget unquote
+ get_module_option module.args string=
;
: set_module_loadname
name_buffer .len @ module_loadname_suffix nip - name_buffer .len !
- get_module_option module.loadname
- dup .addr @ ?dup if free-memory then
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 chars - swap char+ swap
- then
- strdup
- >r over .addr !
- r> swap .len !
+ value_buffer strget unquote
+ get_module_option module.loadname string=
;
: set_module_type
name_buffer .len @ module_type_suffix nip - name_buffer .len !
- get_module_option module.type
- dup .addr @ ?dup if free-memory then
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 chars - swap char+ swap
- then
- strdup
- >r over .addr !
- r> swap .len !
+ value_buffer strget unquote
+ get_module_option module.type string=
;
: set_module_beforeload
name_buffer .len @ module_beforeload_suffix nip - name_buffer .len !
- get_module_option module.beforeload
- dup .addr @ ?dup if free-memory then
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 chars - swap char+ swap
- then
- strdup
- >r over .addr !
- r> swap .len !
+ value_buffer strget unquote
+ get_module_option module.beforeload string=
;
: set_module_afterload
name_buffer .len @ module_afterload_suffix nip - name_buffer .len !
- get_module_option module.afterload
- dup .addr @ ?dup if free-memory then
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 chars - swap char+ swap
- then
- strdup
- >r over .addr !
- r> swap .len !
+ value_buffer strget unquote
+ get_module_option module.afterload string=
;
: set_module_loaderror
name_buffer .len @ module_loaderror_suffix nip - name_buffer .len !
- get_module_option module.loaderror
- dup .addr @ ?dup if free-memory then
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 chars - swap char+ swap
- then
- strdup
- >r over .addr !
- r> swap .len !
-;
-
-: set_environment_variable
- name_buffer .len @
- value_buffer .len @ +
- 5 chars +
- allocate if out_of_memory throw then
- dup 0 ( addr -- addr addr len )
- s" set " strcat
- name_buffer .addr @ name_buffer .len @ strcat
- s" =" strcat
- value_buffer .addr @ value_buffer .len @ strcat
- ['] evaluate catch if
- 2drop free drop
- set_error throw
- else
- free-memory
- then
-;
-
-: set_conf_files
- set_environment_variable
- s" loader_conf_files" getenv conf_files string=
+ value_buffer strget unquote
+ get_module_option module.loaderror string=
;
: set_nextboot_flag
@@ -900,23 +748,12 @@ only forth also support-functions also file-processing definitions also
;
: execute_command
- value_buffer .addr @ value_buffer .len @
- over c@ [char] " = if
- 2 - swap char+ swap
- then
- ['] evaluate catch if exec_error throw then
+ value_buffer strget unquote
+ ['] evaluate catch if EEXEC throw then
;
: set_password
- password .addr @ ?dup if free if free_error throw then then
- value_buffer .addr @ c@ [char] " = if
- value_buffer .addr @ char+ value_buffer .len @ 2 - strdup
- value_buffer .addr @ free if free_error throw then
- else
- value_buffer .addr @ value_buffer .len @
- then
- password .len ! password .addr !
- 0 value_buffer .addr !
+ value_buffer strget unquote password string=
;
: process_assignment
@@ -944,16 +781,8 @@ only forth also support-functions also file-processing definitions also
\ not allocated, it's value (0) is used as flag.
: free_buffers
- name_buffer .addr @ dup if free then
- value_buffer .addr @ dup if free then
- or if free_error throw then
-;
-
-: reset_assignment_buffers
- 0 name_buffer .addr !
- 0 name_buffer .len !
- 0 value_buffer .addr !
- 0 value_buffer .len !
+ name_buffer strfree
+ value_buffer strfree
;
\ Higher level file processing
@@ -964,7 +793,7 @@ support-functions definitions
begin
end_of_file? 0=
while
- reset_assignment_buffers
+ free_buffers
read_line
get_assignment
['] process_assignment catch
@@ -977,8 +806,8 @@ support-functions definitions
0 to end_of_file?
reset_line_reading
O_RDONLY fopen fd !
- fd @ -1 = if open_error throw then
- reset_assignment_buffers
+ fd @ -1 = if EOPEN throw then
+ free_buffers
read_line
get_assignment
['] process_assignment catch
@@ -991,39 +820,73 @@ only forth also support-functions definitions
\ Interface to loading conf files
: load_conf ( addr len -- )
+ \ ." ----- Trying conf " 2dup type cr \ debugging
0 to end_of_file?
reset_line_reading
O_RDONLY fopen fd !
- fd @ -1 = if open_error throw then
+ fd @ -1 = if EOPEN throw then
['] process_conf catch
fd @ fclose
throw
;
-: print_line
- line_buffer .addr @ line_buffer .len @ type cr
-;
+: print_line line_buffer strtype cr ;
: print_syntax_error
- line_buffer .addr @ line_buffer .len @ type cr
+ line_buffer strtype cr
line_buffer .addr @
begin
line_pointer over <>
while
- bl emit
- char+
+ bl emit char+
repeat
drop
." ^" cr
;
+
\ Debugging support functions
only forth definitions also support-functions
: test-file
['] load_conf catch dup .
- syntax_error = if cr print_syntax_error then
+ ESYNTAX = if cr print_syntax_error then
+;
+
+\ find a module name, leave addr on the stack (0 if not found)
+: find-module ( <module> -- ptr | 0 )
+ bl parse ( addr len )
+ module_options @ >r ( store current pointer )
+ begin
+ r@
+ while
+ 2dup ( addr len addr len )
+ r@ module.name strget
+ compare 0= if drop drop r> exit then ( found it )
+ r> module.next @ >r
+ repeat
+ type ." was not found" cr r>
+;
+
+: show-nonempty ( addr len mod -- )
+ strget dup verbose? or if
+ 2swap type type cr
+ else
+ drop drop drop drop
+ then ;
+
+: show-one-module { addr -- addr }
+ ." Name: " addr module.name strtype cr
+ s" Path: " addr module.loadname show-nonempty
+ s" Type: " addr module.type show-nonempty
+ s" Flags: " addr module.args show-nonempty
+ s" Before load: " addr module.beforeload show-nonempty
+ s" After load: " addr module.afterload show-nonempty
+ s" Error: " addr module.loaderror show-nonempty
+ ." Status: " addr module.flag @ if ." Load" else ." Don't load" then cr
+ cr
+ addr
;
: show-module-options
@@ -1031,14 +894,7 @@ only forth definitions also support-functions
begin
?dup
while
- ." Name: " dup module.name dup .addr @ swap .len @ type cr
- ." Path: " dup module.loadname dup .addr @ swap .len @ type cr
- ." Type: " dup module.type dup .addr @ swap .len @ type cr
- ." Flags: " dup module.args dup .addr @ swap .len @ type cr
- ." Before load: " dup module.beforeload dup .addr @ swap .len @ type cr
- ." After load: " dup module.afterload dup .addr @ swap .len @ type cr
- ." Error: " dup module.loaderror dup .addr @ swap .len @ type cr
- ." Status: " dup module.flag @ if ." Load" else ." Don't load" then cr
+ show-one-module
module.next @
repeat
;
@@ -1047,7 +903,7 @@ only forth also support-functions definitions
\ Variables used for processing multiple conf files
-string current_file_name
+string current_file_name_ref \ used to print the file name
\ Indicates if any conf file was succesfully read
@@ -1056,19 +912,20 @@ string current_file_name
\ loader_conf_files processing support functions
: get_conf_files ( -- addr len ) \ put addr/len on stack, reset var
+ \ ." -- starting on <" conf_files strtype ." >" cr \ debugging
conf_files strget 0 0 conf_files strset
;
: skip_leading_spaces { addr len pos -- addr len pos' }
begin
- pos len = if addr len pos exit then
- addr pos + c@ bl =
+ pos len = if 0 else addr pos + c@ bl = then
while
pos char+ to pos
repeat
addr len pos
;
+\ return the file name at pos, or free the string if nothing left
: get_file_name { addr len pos -- addr len pos' addr' len' || 0 }
pos len = if
addr free abort" Fatal error freeing memory"
@@ -1076,14 +933,13 @@ string current_file_name
then
pos >r
begin
- addr pos + c@ bl <>
+ \ stay in the loop until have chars and they are not blank
+ pos len = if 0 else addr pos + c@ bl <> then
while
pos char+ to pos
- pos len = if
- addr len pos addr r@ + pos r> - exit
- then
repeat
addr len pos addr r@ + pos r> -
+ \ 2dup ." get_file_name has " type cr \ debugging
;
: get_next_file ( addr len ptr -- addr len ptr' addr' len' | 0 )
@@ -1091,35 +947,30 @@ string current_file_name
get_file_name
;
-: set_current_file_name
- over current_file_name .addr !
- dup current_file_name .len !
-;
-
: print_current_file
- current_file_name .addr @ current_file_name .len @ type
+ current_file_name_ref strtype
;
: process_conf_errors
dup 0= if true to any_conf_read? drop exit then
>r 2drop r>
- dup syntax_error = if
+ dup ESYNTAX = if
." Warning: syntax error on file " print_current_file cr
print_syntax_error drop exit
then
- dup set_error = if
+ dup ESETERROR = if
." Warning: bad definition on file " print_current_file cr
print_line drop exit
then
- dup read_error = if
+ dup EREAD = if
." Warning: error reading file " print_current_file cr drop exit
then
- dup open_error = if
+ dup EOPEN = if
verbose? if ." Warning: unable to open file " print_current_file cr then
drop exit
then
- dup free_error = abort" Fatal error freeing memory"
- dup out_of_memory = abort" Out of memory"
+ dup EFREE = abort" Fatal error freeing memory"
+ dup ENOMEM = abort" Out of memory"
throw \ Unknown error -- pass ahead
;
@@ -1127,11 +978,11 @@ string current_file_name
\ Interface to loader_conf_files processing
: include_conf_files
- get_conf_files 0
+ get_conf_files 0 ( addr len offset )
begin
- get_next_file ?dup
+ get_next_file ?dup ( addr len 1 | 0 )
while
- set_current_file_name
+ current_file_name_ref strref
['] load_conf catch
process_conf_errors
conf_files .addr @ if recurse then
@@ -1139,13 +990,13 @@ string current_file_name
;
: get_nextboot_conf_file ( -- addr len )
- nextboot_conf_file .addr @ nextboot_conf_file .len @ strdup
+ nextboot_conf_file strget strdup \ XXX is the strdup a leak ?
;
: rewrite_nextboot_file ( -- )
get_nextboot_conf_file
O_WRONLY fopen fd !
- fd @ -1 = if open_error throw then
+ fd @ -1 = if EOPEN throw then
fd @ s' nextboot_enable="NO" ' fwrite
fd @ fclose
;
@@ -1163,52 +1014,47 @@ string current_file_name
\ Module loading functions
-: load_module?
- module.flag @
-;
-
-: load_parameters ( addr -- addr addrN lenN ... addr1 len1 N )
- dup >r
- r@ module.args .addr @ r@ module.args .len @
- r@ module.loadname .len @ if
- r@ module.loadname .addr @ r@ module.loadname .len @
+: load_parameters { addr -- addr addrN lenN ... addr1 len1 N }
+ addr
+ addr module.args strget
+ addr module.loadname .len @ if
+ addr module.loadname strget
else
- r@ module.name .addr @ r@ module.name .len @
+ addr module.name strget
then
- r@ module.type .len @ if
- r@ module.type .addr @ r@ module.type .len @
+ addr module.type .len @ if
+ addr module.type strget
s" -t "
4 ( -t type name flags )
else
2 ( name flags )
then
- r> drop
;
: before_load ( addr -- addr )
dup module.beforeload .len @ if
- dup module.beforeload .addr @ over module.beforeload .len @
- ['] evaluate catch if before_load_error throw then
+ dup module.beforeload strget
+ ['] evaluate catch if EBEFORELOAD throw then
then
;
: after_load ( addr -- addr )
dup module.afterload .len @ if
- dup module.afterload .addr @ over module.afterload .len @
- ['] evaluate catch if after_load_error throw then
+ dup module.afterload strget
+ ['] evaluate catch if EAFTERLOAD throw then
then
;
: load_error ( addr -- addr )
dup module.loaderror .len @ if
- dup module.loaderror .addr @ over module.loaderror .len @
+ dup module.loaderror strget
evaluate \ This we do not intercept so it can throw errors
then
;
: pre_load_message ( addr -- addr )
verbose? if
- dup module.name .addr @ over module.name .len @ type
+ dup module.name strtype
." ..."
then
;
@@ -1239,29 +1085,29 @@ string current_file_name
;
: process_module_errors ( addr ior -- )
- dup before_load_error = if
+ dup EBEFORELOAD = if
drop
." Module "
- dup module.name .addr @ over module.name .len @ type
+ dup module.name strtype
dup module.loadname .len @ if
- ." (" dup module.loadname .addr @ over module.loadname .len @ type ." )"
+ ." (" dup module.loadname strtype ." )"
then
cr
." Error executing "
- dup module.beforeload .addr @ over module.afterload .len @ type cr
+ dup module.beforeload strtype cr \ XXX there was a typo here
abort
then
- dup after_load_error = if
+ dup EAFTERLOAD = if
drop
." Module "
dup module.name .addr @ over module.name .len @ type
dup module.loadname .len @ if
- ." (" dup module.loadname .addr @ over module.loadname .len @ type ." )"
+ ." (" dup module.loadname strtype ." )"
then
cr
." Error executing "
- dup module.afterload .addr @ over module.afterload .len @ type cr
+ dup module.afterload strtype cr
abort
then
@@ -1270,12 +1116,13 @@ string current_file_name
\ Module loading interface
+\ scan the list of modules, load enabled ones.
: load_modules ( -- ) ( throws: abort & user-defined )
- module_options @
+ module_options @ ( list_head )
begin
?dup
while
- dup load_module? if
+ dup module.flag @ if
['] process_module catch
process_module_errors
then
@@ -1320,14 +1167,25 @@ string current_file_name
also builtins
-\ Parse filename from a comma-separated list
+\ Parse filename from a semicolon-separated list
+
+\ replacement, not working yet
+: newparse-; { addr len | a1 -- a' len-x addr x }
+ addr len [char] ; strchr dup if ( a1 len1 )
+ swap to a1 ( store address )
+ 1 - a1 @ 1 + swap ( remove match )
+ addr a1 addr -
+ else
+ 0 0 addr len
+ then
+;
: parse-; ( addr len -- addr' len-x addr x )
- over 0 2swap
+ over 0 2swap ( addr 0 addr len )
begin
- dup 0 <>
+ dup 0 <> ( addr 0 addr len )
while
- over c@ [char] ; <>
+ over c@ [char] ; <> ( addr 0 addr len flag )
while
1- swap 1+ swap
2swap 1+ 2swap
@@ -1421,8 +1279,8 @@ also builtins
2local path
args 1 = if 0 0 then
2local flags
- 0 0 2local oldmodulepath
- 0 0 2local newmodulepath
+ 0 0 2local oldmodulepath \ like a string
+ 0 0 2local newmodulepath \ like a string
end-locals
\ Set the environment variable module_path, and try loading
@@ -1430,16 +1288,13 @@ also builtins
modulepath getenv saveenv to oldmodulepath
\ Try prepending /boot/ first
- bootpath nip path nip +
+ bootpath nip path nip + \ total length
oldmodulepath nip dup -1 = if
drop
else
- 1+ +
- then
- allocate
- if ( out of memory )
- 1 exit
+ 1+ + \ add oldpath -- XXX why the 1+ ?
then
+ allocate if ( out of memory ) 1 exit then \ XXX throw ?
0
bootpath strcat
@@ -1522,7 +1377,7 @@ also builtins
;
: initialize ( addr len -- )
- strdup conf_files .len ! conf_files .addr !
+ strdup conf_files strset
;
: kernel_options ( -- addr len 1 | 0 )
@@ -1559,8 +1414,9 @@ also builtins
then
;
+\ pick the i-th argument, i starts at 0
: argv[] ( aN uN ... a1 u1 N i -- aN uN ... a1 u1 N ai+1 ui+1 )
- 2dup = if 0 0 exit then
+ 2dup = if 0 0 exit then \ out of range
dup >r
1+ 2* ( skip N and ui )
pick
@@ -1589,7 +1445,8 @@ also builtins
1- -rot
;
-: strlen(argv)
+\ compute the length of the buffer including the spaces between words
+: strlen(argv) ( aN uN .. a1 u1 N -- aN uN .. a1 u1 N len )
dup 0= if 0 exit then
0 >r \ Size
0 >r \ Index
@@ -1606,17 +1463,17 @@ also builtins
;
: concat_argv ( aN uN ... a1 u1 N -- a u )
- strlen(argv) allocate if out_of_memory throw then
- 0 2>r
+ strlen(argv) allocate if ENOMEM throw then
+ 0 2>r ( save addr 0 on return stack )
begin
- argc
+ dup
while
- unqueue_argv
- 2r> 2swap
+ unqueue_argv ( ... N a1 u1 )
+ 2r> 2swap ( old a1 u1 )
strcat
- s" " strcat
- 2>r
+ s" " strcat ( append one space ) \ XXX this gives a trailing space
+ 2>r ( store string on the result stack )
repeat
drop_args
2r>
@@ -1639,7 +1496,7 @@ also builtins
?dup if
concat_argv
2dup s" temp_options" setenv
- drop free if free_error throw then
+ drop free if EFREE throw then
else
set_defaultoptions
then
@@ -1675,8 +1532,9 @@ also builtins
?dup 0= if ['] load_modules catch then
;
+\ read and store only as many bytes as we need, drop the extra
: read-password { size | buf len -- }
- size allocate if out_of_memory throw then
+ size allocate if ENOMEM throw then
to buf
0 to len
begin
@@ -1692,11 +1550,7 @@ also builtins
else
dup <cr> = if cr drop buf len exit then
[char] * emit
- len size < if
- buf len chars + c!
- else
- drop
- then
+ len size < if buf len chars + c! else drop then
len 1+ to len
then
again
diff --git a/sys/boot/i386/boot0/Makefile b/sys/boot/i386/boot0/Makefile
index 27f66d5..3b3bb52 100644
--- a/sys/boot/i386/boot0/Makefile
+++ b/sys/boot/i386/boot0/Makefile
@@ -30,7 +30,7 @@ CFLAGS += ${OPTS}
# with the one in the boot sector.
# Default boot flags:
-BOOT_BOOT0_FLAGS?= 0xcf
+BOOT_BOOT0_FLAGS?= 0x8f
# The number of timer ticks to wait for a keypress before assuming the default
# selection. Since there are 18.2 ticks per second, the default value of
diff --git a/sys/boot/i386/boot0/boot0.S b/sys/boot/i386/boot0/boot0.S
index 3baf0e6..2950124 100644
--- a/sys/boot/i386/boot0/boot0.S
+++ b/sys/boot/i386/boot0/boot0.S
@@ -22,6 +22,7 @@
#endif
#ifdef PXE /* enable PXE/INT18 booting with F6 */
+#define SAVE_MORE_MEMORY
#endif
#ifdef CHECK_DRIVE /* make sure we boot from a HD. */
@@ -274,10 +275,11 @@ read_entry: movb %ch,-0x4(%bx) # Zero active flag (ch == 0)
* Scan the table of bootable ids, which starts at %di and has
* length TLEN. On a match, %di points to the element following the
* match; the corresponding offset to the description is $(TLEN-1)
- * bytes ahead. If we don't find a match, we hit the 'unknown' entry.
+ * bytes ahead. We use a count of TLEN+1 so if we don't find a match
+ * within the first TLEN entries, we hit the 'unknown' entry.
*/
movw $bootable_ids,%di # Lookup tables
- movb $(TLEN),%cl # Number of entries
+ movb $(TLEN+1),%cl # Number of entries
repne # Locate
scasb # type
/*
@@ -324,7 +326,7 @@ print_drive: addb $'0'|0x80,%al # Save next
callw putx # item
/*
* Menu is complete, display a prompt followed by current selection.
- * 'decw %si' makes the register point to the space after 'Default: '
+ * 'decw %si' makes the register point to the space after 'Boot: '
* so we do not see an extra CRLF on the screen.
*/
print_prompt: movw $prompt,%si # Display
@@ -371,6 +373,7 @@ read_key:
* Timed out or default selection
*/
use_default: movb _OPT(%bp),%al # Load default
+ orb $NOUPDATE,_FLAGS(%bp) # Disable updates
jmp check_selection # Join common code
/*
@@ -585,13 +588,12 @@ intx13: # Prepare CHS parameters
* Various menu strings. 'item' goes after 'prompt' to save space.
* Also use shorter versions to make room for the PXE/INT18 code.
*/
+prompt:
#ifdef PXE
-prompt: .ascii "\nBoot:"
-item: .ascii " "; .byte ' '|0x80
-#else
-prompt: .ascii "\nDefault:"
-item: .ascii " "; .byte ' '|0x80
+ .ascii "\nF6 PXE\r"
#endif
+ .ascii "\nBoot:"
+item: .ascii " "; .byte ' '|0x80
crlf: .ascii "\r"; .byte '\n'|0x80
/* Partition type tables */
@@ -602,13 +604,13 @@ bootable_ids:
* Corresponding descriptions are at desc_ofs:
* Entries don't need to be sorted.
*/
- .byte 0x1, 0x6, 0x7, 0xb, 0xc
-#ifndef SAVE_MEMORY
- .byte 0xe
-#endif
- .byte 0x83, 0xa5, 0xa6, 0xa9, 0x4
+ .byte 0x83, 0xa5, 0xa6, 0xa9, 0x06, 0x07, 0x0b
#ifndef SAVE_MORE_MEMORY
- .byte 0x5, 0xf
+ .byte 0x05 # extended partition
+#endif
+#ifndef SAVE_MEMORY /* other DOS partitions */
+ .byte 0x01 # FAT12
+ .byte 0x04 # FAT16 < 32M
#endif
desc_ofs:
@@ -617,24 +619,21 @@ desc_ofs:
* actual partition name. The last entry must point to os_misc,
* which is used for non-matching names.
*/
- .byte os_dos-. # 1, FAT12 DOS
- .byte os_dos-. # 6, FAT16 <32M, DOS/WIN
- .byte os_win-. # 7, FAT16 >=32M Windows
- .byte os_win-. # 11, FAT32
- .byte os_win-. # 12, FAT32-LBA
-#ifndef SAVE_MEMORY
- .byte os_win-. # 14, FAT16-LBA
-#endif
.byte os_linux-. # 131, Linux
.byte os_freebsd-. # 165, FreeBSD
.byte os_bsd-. # 166, OpenBSD
.byte os_bsd-. # 169, NetBSD
- .byte os_dos-. # 4, FAT16 < 32M
+ .byte os_dos-. # 6, FAT16 >= 32M
+ .byte os_win-. # 7, NTFS
+ .byte os_win-. # 11, FAT32
+
#ifndef SAVE_MORE_MEMORY
.byte os_ext-. # 5, DOS Ext
- .byte os_ext-. # 15, DOS Ext-LBA
#endif
-
+#ifndef SAVE_MEMORY
+ .byte os_dos-. # 1, FAT12 DOS
+ .byte os_dos-. # 4, FAT16 <32M
+#endif
.byte os_misc-. # Unknown
/*
@@ -643,10 +642,10 @@ desc_ofs:
*/
os_misc: .byte '?'|0x80
os_dos:
-#ifndef SAVE_MEMORY /* DOS string only if room */
+#ifndef SAVE_MORE_MEMORY /* 'DOS' remapped to 'WIN' if no room */
.ascii "DO"; .byte 'S'|0x80
#endif
-os_win: .ascii "WI"; .byte 'N'|0x80
+os_win: .ascii "Wi"; .byte 'n'|0x80
os_linux: .ascii "Linu"; .byte 'x'|0x80
os_freebsd: .ascii "Free"
os_bsd: .ascii "BS"; .byte 'D'|0x80
diff --git a/sys/boot/i386/libi386/bootinfo64.c b/sys/boot/i386/libi386/bootinfo64.c
index 5b2228c..0c6d077 100644
--- a/sys/boot/i386/libi386/bootinfo64.c
+++ b/sys/boot/i386/libi386/bootinfo64.c
@@ -150,8 +150,9 @@ bi_checkcpu(void)
cpu_vendor = (char *)vendor;
/* Check for vendors that support AMD features. */
- if (strncmp(cpu_vendor, "GenuineIntel", 12) != 0 &&
- strncmp(cpu_vendor, "AuthenticAMD", 12) != 0)
+ if (strncmp(cpu_vendor, INTEL_VENDOR_ID, 12) != 0 &&
+ strncmp(cpu_vendor, AMD_VENDOR_ID, 12) != 0 &&
+ strncmp(cpu_vendor, CENTAUR_VENDOR_ID, 12) != 0)
return (0);
/* Has to support AMD features. */
diff --git a/sys/boot/i386/pxeldr/pxeboot.8 b/sys/boot/i386/pxeldr/pxeboot.8
index c3989f3..d2ca703 100644
--- a/sys/boot/i386/pxeldr/pxeboot.8
+++ b/sys/boot/i386/pxeldr/pxeboot.8
@@ -24,8 +24,6 @@
.\"
.\" $FreeBSD$
.\"
-.\" Note: The date here should be updated whenever a non-trivial
-.\" change is made to the manual page.
.Dd May 1, 2000
.Dt PXEBOOT 8
.Os
diff --git a/sys/bsm/audit.h b/sys/bsm/audit.h
index 029919f..53eeadb 100644
--- a/sys/bsm/audit.h
+++ b/sys/bsm/audit.h
@@ -26,16 +26,21 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#1
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#4
* $FreeBSD$
*/
#ifndef _BSM_AUDIT_H
#define _BSM_AUDIT_H
+#ifdef __APPLE__
+/* Temporary until rdar://problem/6133383 is resolved. */
+#include <sys/types.h>
#include <sys/param.h>
+#include <sys/socket.h>
#include <sys/cdefs.h>
#include <sys/queue.h>
+#endif /* __APPLE__ */
#define AUDIT_RECORD_MAGIC 0x828a0f1b
#define MAX_AUDIT_RECORDS 20
@@ -60,8 +65,9 @@
#define AUDIT_TRIGGER_READ_FILE 3 /* Re-read config file. */
#define AUDIT_TRIGGER_CLOSE_AND_DIE 4 /* Terminate audit. */
#define AUDIT_TRIGGER_NO_SPACE 5 /* Below min free space. */
-#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests roate. */
-#define AUDIT_TRIGGER_MAX 6
+#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests rotate. */
+#define AUDIT_TRIGGER_INITIALIZE 7 /* Initialize audit. */
+#define AUDIT_TRIGGER_MAX 7
/*
* The special device filename (FreeBSD).
@@ -72,7 +78,9 @@
/*
* Pre-defined audit IDs
*/
-#define AU_DEFAUDITID -1
+#define AU_DEFAUDITID (uid_t)(-1)
+#define AU_DEFAUDITSID 0
+#define AU_ASSIGN_ASID -1
/*
* IPC types.
@@ -116,6 +124,7 @@
#define A_GETKAUDIT 29
#define A_SETKAUDIT 30
#define A_SENDTRIGGER 31
+#define A_GETSINFO_ADDR 32
/*
* Audit policy controls.
@@ -196,6 +205,7 @@ struct auditinfo_addr {
au_mask_t ai_mask; /* Audit masks. */
au_tid_addr_t ai_termid; /* Terminal ID. */
au_asid_t ai_asid; /* Audit session ID. */
+ u_int64_t ai_flags; /* Audit session flags. */
};
typedef struct auditinfo_addr auditinfo_addr_t;
@@ -205,6 +215,7 @@ struct auditpinfo {
au_mask_t ap_mask; /* Audit masks. */
au_tid_t ap_termid; /* Terminal ID. */
au_asid_t ap_asid; /* Audit session ID. */
+ u_int64_t ap_flags; /* Audit session flags. */
};
typedef struct auditpinfo auditpinfo_t;
@@ -217,6 +228,16 @@ struct auditpinfo_addr {
};
typedef struct auditpinfo_addr auditpinfo_addr_t;
+struct au_session {
+ auditinfo_addr_t *as_aia_p; /* Ptr to full audit info. */
+#define as_asid as_aia_p->ai_asid
+#define as_auid as_aia_p->ai_auid
+#define as_termid as_aia_p->ai_termid
+
+ au_mask_t as_mask; /* Process Audit Masks. */
+};
+typedef struct au_session au_session_t;
+
/*
* Contents of token_t are opaque outside of libbsm.
*/
@@ -259,8 +280,8 @@ typedef struct audit_stat au_stat_t;
* Structure for the audit file statistics.
*/
struct audit_fstat {
- u_quad_t af_filesz;
- u_quad_t af_currsz;
+ u_int64_t af_filesz;
+ u_int64_t af_currsz;
};
typedef struct audit_fstat au_fstat_t;
diff --git a/sys/bsm/audit_domain.h b/sys/bsm/audit_domain.h
new file mode 100644
index 0000000..1c839dd
--- /dev/null
+++ b/sys/bsm/audit_domain.h
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_domain.h#1
+ * $FreeBSD$
+ */
+
+#ifndef _BSM_AUDIT_DOMAIN_H_
+#define _BSM_AUDIT_DOMAIN_H_
+
+/*
+ * BSM protocol domain constants - protocol domains defined in Solaris.
+ */
+#define BSM_PF_UNSPEC 0
+#define BSM_PF_LOCAL 1
+#define BSM_PF_INET 2
+#define BSM_PF_IMPLINK 3
+#define BSM_PF_PUP 4
+#define BSM_PF_CHAOS 5
+#define BSM_PF_NS 6
+#define BSM_PF_NBS 7 /* Solaris-specific. */
+#define BSM_PF_ECMA 8
+#define BSM_PF_DATAKIT 9
+#define BSM_PF_CCITT 10
+#define BSM_PF_SNA 11
+#define BSM_PF_DECnet 12
+#define BSM_PF_DLI 13
+#define BSM_PF_LAT 14
+#define BSM_PF_HYLINK 15
+#define BSM_PF_APPLETALK 16
+#define BSM_PF_NIT 17 /* Solaris-specific. */
+#define BSM_PF_802 18 /* Solaris-specific. */
+#define BSM_PF_OSI 19
+#define BSM_PF_X25 20 /* Solaris/Linux-specific. */
+#define BSM_PF_OSINET 21 /* Solaris-specific. */
+#define BSM_PF_GOSIP 22 /* Solaris-specific. */
+#define BSM_PF_IPX 23
+#define BSM_PF_ROUTE 24
+#define BSM_PF_LINK 25
+#define BSM_PF_INET6 26
+#define BSM_PF_KEY 27
+#define BSM_PF_NCA 28 /* Solaris-specific. */
+#define BSM_PF_POLICY 29 /* Solaris-specific. */
+#define BSM_PF_INET_OFFLOAD 30 /* Solaris-specific. */
+
+/*
+ * BSM protocol domain constants - protocol domains not defined in Solaris.
+ */
+#define BSM_PF_NETBIOS 500 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_ISO 501 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_XTP 502 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_COIP 503 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_CNT 504 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_RTIP 505 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_SIP 506 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_PIP 507 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_ISDN 508 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_E164 509 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_NATM 510 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_ATM 511 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_NETGRAPH 512 /* FreeBSD/Darwin-specific. */
+#define BSM_PF_SLOW 513 /* FreeBSD-specific. */
+#define BSM_PF_SCLUSTER 514 /* FreeBSD-specific. */
+#define BSM_PF_ARP 515 /* FreeBSD-specific. */
+#define BSM_PF_BLUETOOTH 516 /* FreeBSD-specific. */
+#define BSM_PF_IEEE80211 517 /* FreeBSD-specific. */
+#define BSM_PF_AX25 518 /* Linux-specific. */
+#define BSM_PF_ROSE 519 /* Linux-specific. */
+#define BSM_PF_NETBEUI 520 /* Linux-specific. */
+#define BSM_PF_SECURITY 521 /* Linux-specific. */
+#define BSM_PF_PACKET 522 /* Linux-specific. */
+#define BSM_PF_ASH 523 /* Linux-specific. */
+#define BSM_PF_ECONET 524 /* Linux-specific. */
+#define BSM_PF_ATMSVC 525 /* Linux-specific. */
+#define BSM_PF_IRDA 526 /* Linux-specific. */
+#define BSM_PF_PPPOX 527 /* Linux-specific. */
+#define BSM_PF_WANPIPE 528 /* Linux-specific. */
+#define BSM_PF_LLC 529 /* Linux-specific. */
+#define BSM_PF_CAN 530 /* Linux-specific. */
+#define BSM_PF_TIPC 531 /* Linux-specific. */
+#define BSM_PF_IUCV 532 /* Linux-specific. */
+#define BSM_PF_RXRPC 533 /* Linux-specific. */
+#define BSM_PF_PHONET 534 /* Linux-specific. */
+
+/*
+ * Used when there is no mapping from a local to BSM protocol domain.
+ */
+#define BSM_PF_UNKNOWN 700 /* OpenBSM-specific. */
+
+#endif /* !_BSM_AUDIT_DOMAIN_H_ */
diff --git a/sys/bsm/audit_errno.h b/sys/bsm/audit_errno.h
new file mode 100644
index 0000000..9a13bd9
--- /dev/null
+++ b/sys/bsm/audit_errno.h
@@ -0,0 +1,215 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_errno.h#5
+ * $FreeBSD$
+ */
+
+#ifndef _BSM_AUDIT_ERRNO_H_
+#define _BSM_AUDIT_ERRNO_H_
+
+/*
+ * For the purposes of portable encoding, we convert between local error
+ * numbers and Solaris error numbers (as well as some extensions for error
+ * numbers that don't exist in Solaris). Although the first 35 or so
+ * constants are the same across all OS's, we don't handle that in any
+ * special way.
+ *
+ * When adding constants here, also add them to bsm_errno.c.
+ */
+#define BSM_ERRNO_ESUCCESS 0
+#define BSM_ERRNO_EPERM 1
+#define BSM_ERRNO_ENOENT 2
+#define BSM_ERRNO_ESRCH 3
+#define BSM_ERRNO_EINTR 4
+#define BSM_ERRNO_EIO 5
+#define BSM_ERRNO_ENXIO 6
+#define BSM_ERRNO_E2BIG 7
+#define BSM_ERRNO_ENOEXEC 8
+#define BSM_ERRNO_EBADF 9
+#define BSM_ERRNO_ECHILD 10
+#define BSM_ERRNO_EAGAIN 11
+#define BSM_ERRNO_ENOMEM 12
+#define BSM_ERRNO_EACCES 13
+#define BSM_ERRNO_EFAULT 14
+#define BSM_ERRNO_ENOTBLK 15
+#define BSM_ERRNO_EBUSY 16
+#define BSM_ERRNO_EEXIST 17
+#define BSM_ERRNO_EXDEV 18
+#define BSM_ERRNO_ENODEV 19
+#define BSM_ERRNO_ENOTDIR 20
+#define BSM_ERRNO_EISDIR 21
+#define BSM_ERRNO_EINVAL 22
+#define BSM_ERRNO_ENFILE 23
+#define BSM_ERRNO_EMFILE 24
+#define BSM_ERRNO_ENOTTY 25
+#define BSM_ERRNO_ETXTBSY 26
+#define BSM_ERRNO_EFBIG 27
+#define BSM_ERRNO_ENOSPC 28
+#define BSM_ERRNO_ESPIPE 29
+#define BSM_ERRNO_EROFS 30
+#define BSM_ERRNO_EMLINK 31
+#define BSM_ERRNO_EPIPE 32
+#define BSM_ERRNO_EDOM 33
+#define BSM_ERRNO_ERANGE 34
+#define BSM_ERRNO_ENOMSG 35
+#define BSM_ERRNO_EIDRM 36
+#define BSM_ERRNO_ECHRNG 37 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL2NSYNC 38 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL3HLT 39 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL3RST 40 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELNRNG 41 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EUNATCH 42 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOCSI 43 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EL2HLT 44 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EDEADLK 45
+#define BSM_ERRNO_ENOLCK 46
+#define BSM_ERRNO_ECANCELED 47
+#define BSM_ERRNO_ENOTSUP 48
+#define BSM_ERRNO_EDQUOT 49
+#define BSM_ERRNO_EBADE 50 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADR 51 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EXFULL 52 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOANO 53 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADRQC 54 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADSLT 55 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EDEADLOCK 56 /* Solaris-specific. */
+#define BSM_ERRNO_EBFONT 57 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EOWNERDEAD 58 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOTRECOVERABLE 59 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOSTR 60 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ENODATA 61 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ETIME 62 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ENOSR 63 /* Solaris/Darwin/Linux-specific. */
+#define BSM_ERRNO_ENONET 64 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOPKG 65 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EREMOTE 66
+#define BSM_ERRNO_ENOLINK 67
+#define BSM_ERRNO_EADV 68 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ESRMNT 69 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ECOMM 70 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EPROTO 71
+#define BSM_ERRNO_ELOCKUNMAPPED 72 /* Solaris-specific. */
+#define BSM_ERRNO_ENOTACTIVE 73 /* Solaris-specific. */
+#define BSM_ERRNO_EMULTIHOP 74
+#define BSM_ERRNO_EBADMSG 77
+#define BSM_ERRNO_ENAMETOOLONG 78
+#define BSM_ERRNO_EOVERFLOW 79
+#define BSM_ERRNO_ENOTUNIQ 80 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EBADFD 81 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EREMCHG 82 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBACC 83 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBBAD 84 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBSCN 85 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBMAX 86 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ELIBEXEC 87 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_EILSEQ 88
+#define BSM_ERRNO_ENOSYS 89
+#define BSM_ERRNO_ELOOP 90
+#define BSM_ERRNO_ERESTART 91
+#define BSM_ERRNO_ESTRPIPE 92 /* Solaris/Linux-specific. */
+#define BSM_ERRNO_ENOTEMPTY 93
+#define BSM_ERRNO_EUSERS 94
+#define BSM_ERRNO_ENOTSOCK 95
+#define BSM_ERRNO_EDESTADDRREQ 96
+#define BSM_ERRNO_EMSGSIZE 97
+#define BSM_ERRNO_EPROTOTYPE 98
+#define BSM_ERRNO_ENOPROTOOPT 99
+#define BSM_ERRNO_EPROTONOSUPPORT 120
+#define BSM_ERRNO_ESOCKTNOSUPPORT 121
+#define BSM_ERRNO_EOPNOTSUPP 122
+#define BSM_ERRNO_EPFNOSUPPORT 123
+#define BSM_ERRNO_EAFNOSUPPORT 124
+#define BSM_ERRNO_EADDRINUSE 125
+#define BSM_ERRNO_EADDRNOTAVAIL 126
+#define BSM_ERRNO_ENETDOWN 127
+#define BSM_ERRNO_ENETUNREACH 128
+#define BSM_ERRNO_ENETRESET 129
+#define BSM_ERRNO_ECONNABORTED 130
+#define BSM_ERRNO_ECONNRESET 131
+#define BSM_ERRNO_ENOBUFS 132
+#define BSM_ERRNO_EISCONN 133
+#define BSM_ERRNO_ENOTCONN 134
+#define BSM_ERRNO_ESHUTDOWN 143
+#define BSM_ERRNO_ETOOMANYREFS 144
+#define BSM_ERRNO_ETIMEDOUT 145
+#define BSM_ERRNO_ECONNREFUSED 146
+#define BSM_ERRNO_EHOSTDOWN 147
+#define BSM_ERRNO_EHOSTUNREACH 148
+#define BSM_ERRNO_EALREADY 149
+#define BSM_ERRNO_EINPROGRESS 150
+#define BSM_ERRNO_ESTALE 151
+
+/*
+ * OpenBSM constants for error numbers not defined in Solaris. In the event
+ * that these errors are added to Solaris, we will deprecate the OpenBSM
+ * numbers in the same way we do for audit event constants.
+ *
+ * ELAST doesn't get a constant in the BSM space.
+ */
+#define BSM_ERRNO_EPROCLIM 190 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EBADRPC 191 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_ERPCMISMATCH 192 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EPROGUNAVAIL 193 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EPROGMISMATCH 194 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EPROCUNAVAIL 195 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EFTYPE 196 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EAUTH 197 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_ENEEDAUTH 198 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_ENOATTR 199 /* FreeBSD/Darwin-specific. */
+#define BSM_ERRNO_EDOOFUS 200 /* FreeBSD-specific. */
+#define BSM_ERRNO_EJUSTRETURN 201 /* FreeBSD-specific. */
+#define BSM_ERRNO_ENOIOCTL 202 /* FreeBSD-specific. */
+#define BSM_ERRNO_EDIRIOCTL 203 /* FreeBSD-specific. */
+#define BSM_ERRNO_EPWROFF 204 /* Darwin-specific. */
+#define BSM_ERRNO_EDEVERR 205 /* Darwin-specific. */
+#define BSM_ERRNO_EBADEXEC 206 /* Darwin-specific. */
+#define BSM_ERRNO_EBADARCH 207 /* Darwin-specific. */
+#define BSM_ERRNO_ESHLIBVERS 208 /* Darwin-specific. */
+#define BSM_ERRNO_EBADMACHO 209 /* Darwin-specific. */
+#define BSM_ERRNO_EPOLICY 210 /* Darwin-specific. */
+#define BSM_ERRNO_EDOTDOT 211 /* Linux-specific. */
+#define BSM_ERRNO_EUCLEAN 212 /* Linux-specific. */
+#define BSM_ERRNO_ENOTNAM 213 /* Linux(Xenix?)-specific. */
+#define BSM_ERRNO_ENAVAIL 214 /* Linux(Xenix?)-specific. */
+#define BSM_ERRNO_EISNAM 215 /* Linux(Xenix?)-specific. */
+#define BSM_ERRNO_EREMOTEIO 216 /* Linux-specific. */
+#define BSM_ERRNO_ENOMEDIUM 217 /* Linux-specific. */
+#define BSM_ERRNO_EMEDIUMTYPE 218 /* Linux-specific. */
+#define BSM_ERRNO_ENOKEY 219 /* Linux-specific. */
+#define BSM_ERRNO_EKEYEXPIRED 220 /* Linux-specific. */
+#define BSM_ERRNO_EKEYREVOKED 221 /* Linux-specific. */
+#define BSM_ERRNO_EKEYREJECTED 222 /* Linux-specific. */
+
+/*
+ * In the event that OpenBSM doesn't have a file representation of a local
+ * error number, use this.
+ */
+#define BSM_ERRNO_UNKNOWN 250 /* OpenBSM-specific. */
+
+#endif /* !_BSM_AUDIT_ERRNO_H_ */
diff --git a/sys/bsm/audit_internal.h b/sys/bsm/audit_internal.h
index dc583ab..b25c47f 100644
--- a/sys/bsm/audit_internal.h
+++ b/sys/bsm/audit_internal.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Apple Inc.
+ * Copyright (c) 2005-2008 Apple Inc.
* Copyright (c) 2005 SPARTA, Inc.
* All rights reserved.
*
@@ -30,7 +30,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.
*
- * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_internal.h#2
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_internal.h#5
* $FreeBSD$
*/
diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h
index a881d78..3276cac 100644
--- a/sys/bsm/audit_kevents.h
+++ b/sys/bsm/audit_kevents.h
@@ -26,7 +26,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.
*
- * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_kevents.h#3
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_kevents.h#4
* $FreeBSD$
*/
@@ -59,7 +59,6 @@
#define AUE_UMOUNT 12
#define AUE_JUNK 13 /* Solaris-specific. */
#define AUE_ACCESS 14
-#define AUE_CHECKUSERACCESS AUE_ACCESS /* Darwin-specific. */
#define AUE_KILL 15
#define AUE_STAT 16
#define AUE_LSTAT 17
@@ -561,7 +560,7 @@
#define AUE_ACCESS_EXTENDED 43162 /* Darwin. */
#define AUE_CHMOD_EXTENDED 43163 /* Darwin. */
#define AUE_FCHMOD_EXTENDED 43164 /* Darwin. */
-#define AUE_FSTAT_EXTENDED 43165 /* Dariwn. */
+#define AUE_FSTAT_EXTENDED 43165 /* Darwin. */
#define AUE_LSTAT_EXTENDED 43166 /* Darwin. */
#define AUE_MKDIR_EXTENDED 43167 /* Darwin. */
#define AUE_MKFIFO_EXTENDED 43168 /* Darwin. */
@@ -586,6 +585,8 @@
#define AUE_CAP_GETRIGHTS 43187 /* TrustedBSD. */
#define AUE_CAP_ENTER 43188 /* TrustedBSD. */
#define AUE_CAP_GETMODE 43189 /* TrustedBSD. */
+#define AUE_POSIX_SPAWN 43190 /* Darwin. */
+#define AUE_FSGETPATH 43191 /* Darwin. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
@@ -657,13 +658,42 @@
/*
* Possible desired future values based on review of BSD/Darwin system calls.
*/
+#define AUE_ACCESSEXTENDED AUE_NULL
+#define AUE_ATGETMSG AUE_NULL
+#define AUE_ATPUTMSG AUE_NULL
+#define AUE_ATSOCKET AUE_NULL
+#define AUE_ATPGETREQ AUE_NULL
+#define AUE_ATPGETRSP AUE_NULL
+#define AUE_ATPSNDREQ AUE_NULL
+#define AUE_ATPSNDRSP AUE_NULL
+#define AUE_BSDTHREADCREATE AUE_NULL
+#define AUE_BSDTHREADTERMINATE AUE_NULL
+#define AUE_BSDTHREADREGISTER AUE_NULL
+#define AUE_CHMODEXTENDED AUE_NULL
+#define AUE_CHUD AUE_NULL
+#define AUE_CSOPS AUE_NULL
#define AUE_DUP AUE_NULL
+#define AUE_FCHMODEXTENDED AUE_NULL
+#define AUE_FDATASYNC AUE_NULL
+#define AUE_FFSCTL AUE_NULL
+#define AUE_FGETATTRLIST AUE_NULL
+#define AUE_FGETXATTR AUE_NULL
+#define AUE_FLISTXATTR AUE_NULL
+#define AUE_FREMOVEXATTR AUE_NULL
#define AUE_FSCTL AUE_NULL
+#define AUE_FSETATTRLIST AUE_NULL
+#define AUE_FSETXATTR AUE_NULL
+#define AUE_FSTATEXTENDED AUE_NULL
+#define AUE_FSTATFS64 AUE_NULL
#define AUE_FSTATV AUE_NULL
+#define AUE_FSTAT64 AUE_NULL
+#define AUE_FSTAT64EXTENDED AUE_NULL
#define AUE_GCCONTROL AUE_NULL
+#define AUE_GETDIRENTRIES64 AUE_NULL
#define AUE_GETDTABLESIZE AUE_NULL
#define AUE_GETEGID AUE_NULL
#define AUE_GETEUID AUE_NULL
+#define AUE_GETFSSTAT64 AUE_NULL
#define AUE_GETGID AUE_NULL
#define AUE_GETGROUPS AUE_NULL
#define AUE_GETITIMER AUE_NULL
@@ -676,24 +706,53 @@
#define AUE_GETPRIORITY AUE_NULL
#define AUE_GETRLIMIT AUE_NULL
#define AUE_GETRUSAGE AUE_NULL
+#define AUE_GETSGROUPS AUE_NULL
#define AUE_GETSID AUE_NULL
#define AUE_GETSOCKNAME AUE_NULL
#define AUE_GETTIMEOFDAY AUE_NULL
+#define AUE_GETTID AUE_NULL
#define AUE_GETUID AUE_NULL
#define AUE_GETSOCKOPT AUE_NULL
-#define AUE_GTSOCKOPT AUE_GETSOCKOPT /* XXX: Typo in Darwin. */
+#define AUE_GETWGROUPS AUE_NULL
+#define AUE_GETXATTR AUE_NULL
+#define AUE_IDENTITYSVC AUE_NULL
+#define AUE_INITGROUPS AUE_NULL
+#define AUE_IOPOLICYSYS AUE_NULL
#define AUE_ISSETUGID AUE_NULL
+#define AUE_LIOLISTIO AUE_NULL
+#define AUE_LISTXATTR AUE_NULL
+#define AUE_LSTATEXTENDED AUE_NULL
#define AUE_LSTATV AUE_NULL
+#define AUE_LSTAT64 AUE_NULL
+#define AUE_LSTAT64EXTENDED AUE_NULL
#define AUE_MADVISE AUE_NULL
#define AUE_MINCORE AUE_NULL
#define AUE_MKCOMPLEX AUE_NULL
+#define AUE_MKDIREXTENDED AUE_NULL
+#define AUE_MKFIFOEXTENDED AUE_NULL
#define AUE_MODWATCH AUE_NULL
#define AUE_MSGCL AUE_NULL
#define AUE_MSYNC AUE_NULL
+#define AUE_OPENEXTENDED AUE_NULL
#define AUE_PREAD AUE_NULL
#define AUE_PWRITE AUE_NULL
#define AUE_PREADV AUE_NULL
+#define AUE_PROCINFO AUE_NULL
+#define AUE_PTHREADCANCELED AUE_NULL
+#define AUE_PTHREADCHDIR AUE_NULL
+#define AUE_PTHREADCONDBROADCAST AUE_NULL
+#define AUE_PTHREADCONDDESTORY AUE_NULL
+#define AUE_PTHREADCONDINIT AUE_NULL
+#define AUE_PTHREADCONDSIGNAL AUE_NULL
+#define AUE_PTHREADCONDWAIT AUE_NULL
+#define AUE_PTHREADFCHDIR AUE_NULL
+#define AUE_PTHREADMARK AUE_NULL
+#define AUE_PTHREADMUTEXDESTROY AUE_NULL
+#define AUE_PTHREADMUTEXINIT AUE_NULL
+#define AUE_PTHREADMUTEXTRYLOCK AUE_NULL
+#define AUE_PTHREADMUTEXUNLOCK AUE_NULL
#define AUE_PWRITEV AUE_NULL
+#define AUE_REMOVEXATTR AUE_NULL
#define AUE_SBRK AUE_NULL
#define AUE_SELECT AUE_NULL
#define AUE_SEMDESTROY AUE_NULL
@@ -702,7 +761,15 @@
#define AUE_SEMPOST AUE_NULL
#define AUE_SEMTRYWAIT AUE_NULL
#define AUE_SEMWAIT AUE_NULL
+#define AUE_SEMWAITSIGNAL AUE_NULL
#define AUE_SETITIMER AUE_NULL
+#define AUE_SETSGROUPS AUE_NULL
+#define AUE_SETTID AUE_NULL
+#define AUE_SETTIDWITHPID AUE_NULL
+#define AUE_SETWGROUPS AUE_NULL
+#define AUE_SETXATTR AUE_NULL
+#define AUE_SHAREDREGIONCHECK AUE_NULL
+#define AUE_SHAREDREGIONMAP AUE_NULL
#define AUE_SIGACTION AUE_NULL
#define AUE_SIGALTSTACK AUE_NULL
#define AUE_SIGPENDING AUE_NULL
@@ -711,11 +778,21 @@
#define AUE_SIGSUSPEND AUE_NULL
#define AUE_SIGWAIT AUE_NULL
#define AUE_SSTK AUE_NULL
+#define AUE_STACKSNAPSHOT AUE_NULL
+#define AUE_STATEXTENDED AUE_NULL
+#define AUE_STATFS64 AUE_NULL
#define AUE_STATV AUE_NULL
+#define AUE_STAT64 AUE_NULL
+#define AUE_STAT64EXTENDED AUE_NULL
#define AUE_SYNC AUE_NULL
#define AUE_SYSCALL AUE_NULL
#define AUE_TABLE AUE_NULL
+#define AUE_UMASKEXTENDED AUE_NULL
+#define AUE_VMPRESSUREMONITOR AUE_NULL
#define AUE_WAITEVENT AUE_NULL
+#define AUE_WAITID AUE_NULL
#define AUE_WATCHEVENT AUE_NULL
+#define AUE_WORKQOPEN AUE_NULL
+#define AUE_WORKQOPS AUE_NULL
#endif /* !_BSM_AUDIT_KEVENTS_H_ */
diff --git a/sys/bsm/audit_record.h b/sys/bsm/audit_record.h
index 186b4f5..5d9306a 100644
--- a/sys/bsm/audit_record.h
+++ b/sys/bsm/audit_record.h
@@ -26,7 +26,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.
*
- * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_record.h#3
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_record.h#9
* $FreeBSD$
*/
@@ -165,14 +165,11 @@
#define AUDIT_HEADER_VERSION_SOLARIS 2
#define AUDIT_HEADER_VERSION_TSOL25 3
#define AUDIT_HEADER_VERSION_TSOL 4
-#define AUDIT_HEADER_VERSION_OPENBSM 10
+#define AUDIT_HEADER_VERSION_OPENBSM10 10
+#define AUDIT_HEADER_VERSION_OPENBSM11 11
+#define AUDIT_HEADER_VERSION_OPENBSM AUDIT_HEADER_VERSION_OPENBSM11
-/*
- * BSM define is AUT_TRAILER_MAGIC; Apple BSM define is TRAILER_PAD_MAGIC; we
- * split the difference, will remove the Apple define for the next release.
- */
#define AUT_TRAILER_MAGIC 0xb105
-#define TRAILER_PAD_MAGIC AUT_TRAILER_MAGIC
/* BSM library calls */
@@ -183,6 +180,7 @@ struct in6_addr;
struct ip;
struct ipc_perm;
struct kevent;
+struct sockaddr;
struct sockaddr_in;
struct sockaddr_in6;
struct sockaddr_un;
@@ -209,6 +207,7 @@ token_t *au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod);
token_t *au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod);
token_t *au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod);
token_t *au_to_header64(int rec_size, au_event_t e_type, au_emod_t e_mod);
+token_t *au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod);
#endif
token_t *au_to_me(void);
@@ -252,15 +251,8 @@ token_t *au_to_return(char status, uint32_t ret);
token_t *au_to_return32(char status, uint32_t ret);
token_t *au_to_return64(char status, uint64_t ret);
token_t *au_to_seq(long audit_count);
-
-#if defined(_KERNEL) || defined(KERNEL)
-token_t *au_to_socket(struct socket *so);
-token_t *au_to_socket_ex_32(uint16_t lp, uint16_t rp, struct sockaddr *la,
- struct sockaddr *ta);
-token_t *au_to_socket_ex_128(uint16_t lp, uint16_t rp, struct sockaddr *la,
- struct sockaddr *ta);
-#endif
-
+token_t *au_to_socket_ex(u_short so_domain, u_short so_type,
+ struct sockaddr *sa_local, struct sockaddr *sa_remote);
token_t *au_to_sock_inet(struct sockaddr_in *so);
token_t *au_to_sock_inet32(struct sockaddr_in *so);
token_t *au_to_sock_inet128(struct sockaddr_in6 *so);
@@ -289,6 +281,17 @@ token_t *au_to_kevent(struct kevent *kev);
token_t *au_to_trailer(int rec_size);
token_t *au_to_zonename(const char *zonename);
+/*
+ * BSM library routines for converting between local and BSM constant spaces.
+ */
+int au_bsm_to_domain(u_short bsm_domain, int *local_domainp);
+int au_bsm_to_errno(u_char bsm_error, int *errorp);
+int au_bsm_to_socket_type(u_short bsm_socket_type,
+ int *local_socket_typep);
+u_short au_domain_to_bsm(int local_domain);
+u_char au_errno_to_bsm(int local_errno);
+u_short au_socket_type_to_bsm(int local_socket_type);
+
__END_DECLS
#endif /* ! _BSM_AUDIT_RECORD_H_ */
diff --git a/sys/bsm/audit_socket_type.h b/sys/bsm/audit_socket_type.h
new file mode 100644
index 0000000..6b6bac1
--- /dev/null
+++ b/sys/bsm/audit_socket_type.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_socket_type.h#1
+ * $FreeBSD$
+ */
+
+#ifndef _BSM_AUDIT_SOCKET_TYPE_H_
+#define _BSM_AUDIT_SOCKET_TYPE_H_
+
+/*
+ * BSM socket type constants.
+ */
+#define BSM_SOCK_DGRAM 1
+#define BSM_SOCK_STREAM 2
+#define BSM_SOCK_RAW 4
+#define BSM_SOCK_RDM 5
+#define BSM_SOCK_SEQPACKET 6
+
+#define BSM_SOCK_UNKNOWN 500
+
+#endif /* !_BSM_AUDIT_SOCKET_TYPE_H_ */
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 3abeed8..6292382 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -171,6 +171,10 @@ cam_periph_alloc(periph_ctor_t *periph_ctor,
break;
}
xpt_unlock_buses();
+ if (p_drv == NULL) {
+ printf("cam_periph_alloc: invalid periph name '%s'\n", name);
+ return (CAM_REQ_INVALID);
+ }
sim = xpt_path_sim(path);
path_id = xpt_path_path_id(path);
@@ -322,7 +326,6 @@ cam_periph_release(struct cam_periph *periph)
int
cam_periph_hold(struct cam_periph *periph, int priority)
{
- struct mtx *mtx;
int error;
/*
@@ -335,14 +338,11 @@ cam_periph_hold(struct cam_periph *periph, int priority)
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
return (ENXIO);
- mtx = periph->sim->mtx;
- mtx_assert(mtx, MA_OWNED);
- if (mtx == &Giant)
- mtx = NULL;
-
+ mtx_assert(periph->sim->mtx, MA_OWNED);
while ((periph->flags & CAM_PERIPH_LOCKED) != 0) {
periph->flags |= CAM_PERIPH_LOCK_WANTED;
- if ((error = msleep(periph, mtx, priority, "caplck", 0)) != 0) {
+ if ((error = mtx_sleep(periph, periph->sim->mtx, priority,
+ "caplck", 0)) != 0) {
cam_periph_release_locked(periph);
return (error);
}
@@ -763,7 +763,6 @@ union ccb *
cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
{
struct ccb_hdr *ccb_h;
- struct mtx *mtx;
mtx_assert(periph->sim->mtx, MA_OWNED);
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdgetccb\n"));
@@ -776,11 +775,8 @@ cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
&& (SLIST_FIRST(&periph->ccb_list)->pinfo.priority == priority))
break;
mtx_assert(periph->sim->mtx, MA_OWNED);
- if (periph->sim->mtx == &Giant)
- mtx = NULL;
- else
- mtx = periph->sim->mtx;
- msleep(&periph->ccb_list, mtx, PRIBIO, "cgticb", 0);
+ mtx_sleep(&periph->ccb_list, periph->sim->mtx, PRIBIO, "cgticb",
+ 0);
}
ccb_h = SLIST_FIRST(&periph->ccb_list);
@@ -791,17 +787,12 @@ cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
void
cam_periph_ccbwait(union ccb *ccb)
{
- struct mtx *mtx;
struct cam_sim *sim;
sim = xpt_path_sim(ccb->ccb_h.path);
- if (sim->mtx == &Giant)
- mtx = NULL;
- else
- mtx = sim->mtx;
if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX)
|| ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG))
- msleep(&ccb->ccb_h.cbfcnp, mtx, PRIBIO, "cbwait", 0);
+ mtx_sleep(&ccb->ccb_h.cbfcnp, sim->mtx, PRIBIO, "cbwait", 0);
}
int
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index f2a2d9d..4bf3338 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -2642,6 +2642,39 @@ xptbustraverse(struct cam_eb *start_bus, xpt_busfunc_t *tr_func, void *arg)
return(retval);
}
+int
+xpt_sim_opened(struct cam_sim *sim)
+{
+ struct cam_eb *bus;
+ struct cam_et *target;
+ struct cam_ed *device;
+ struct cam_periph *periph;
+
+ KASSERT(sim->refcount >= 1, ("sim->refcount >= 1"));
+ mtx_assert(sim->mtx, MA_OWNED);
+
+ mtx_lock(&xsoftc.xpt_topo_lock);
+ TAILQ_FOREACH(bus, &xsoftc.xpt_busses, links) {
+ if (bus->sim != sim)
+ continue;
+
+ TAILQ_FOREACH(target, &bus->et_entries, links) {
+ TAILQ_FOREACH(device, &target->ed_entries, links) {
+ SLIST_FOREACH(periph, &device->periphs,
+ periph_links) {
+ if (periph->refcount > 0) {
+ mtx_unlock(&xsoftc.xpt_topo_lock);
+ return (1);
+ }
+ }
+ }
+ }
+ }
+
+ mtx_unlock(&xsoftc.xpt_topo_lock);
+ return (0);
+}
+
static int
xpttargettraverse(struct cam_eb *bus, struct cam_et *start_target,
xpt_targetfunc_t *tr_func, void *arg)
@@ -4144,7 +4177,10 @@ xpt_path_string(struct cam_path *path, char *str, size_t str_len)
{
struct sbuf sb;
- mtx_assert(path->bus->sim->mtx, MA_OWNED);
+#ifdef INVARIANTS
+ if (path != NULL && path->bus != NULL && path->bus->sim != NULL)
+ mtx_assert(path->bus->sim->mtx, MA_OWNED);
+#endif
sbuf_new(&sb, str, str_len, 0);
@@ -4277,7 +4313,7 @@ xpt_release_ccb(union ccb *free_ccb)
* for this new bus and places it in the array of busses and assigns
* it a path_id. The path_id may be influenced by "hard wiring"
* information specified by the user. Once interrupt services are
- * availible, the bus will be probed.
+ * available, the bus will be probed.
*/
int32_t
xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
@@ -5158,6 +5194,11 @@ xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
/* Save some state for use while we probe for devices */
scan_info = (xpt_scan_bus_info *)
malloc(sizeof(xpt_scan_bus_info), M_CAMXPT, M_NOWAIT);
+ if (scan_info == NULL) {
+ request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ xpt_done(request_ccb);
+ return;
+ }
scan_info->request_ccb = request_ccb;
scan_info->cpi = &work_ccb->cpi;
@@ -5611,7 +5652,7 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
case PROBE_DV_EXIT:
{
scsi_test_unit_ready(csio,
- /*retries*/4,
+ /*retries*/10,
probedone,
MSG_SIMPLE_Q_TAG,
SSD_FULL_SIZE,
@@ -6104,7 +6145,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
}
xpt_release_ccb(done_ccb);
softc->action = PROBE_TUR_FOR_NEGOTIATION;
- xpt_schedule(periph, done_ccb->ccb_h.pinfo.priority);
+ xpt_schedule(periph, priority);
return;
}
@@ -6218,6 +6259,13 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
break;
}
case PROBE_TUR_FOR_NEGOTIATION:
+ if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ DELAY(500000);
+ if (cam_periph_error(done_ccb, 0, SF_RETRY_UA,
+ NULL) == ERESTART)
+ return;
+ }
+ /* FALLTHROUGH */
case PROBE_DV_EXIT:
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
diff --git a/sys/cam/cam_xpt_sim.h b/sys/cam/cam_xpt_sim.h
index d824093..e64c67c 100644
--- a/sys/cam/cam_xpt_sim.h
+++ b/sys/cam/cam_xpt_sim.h
@@ -45,6 +45,7 @@ void xpt_release_simq(struct cam_sim *sim, int run_queue);
u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count);
void xpt_release_devq(struct cam_path *path, u_int count,
int run_queue);
+int xpt_sim_opened(struct cam_sim *sim);
void xpt_done(union ccb *done_ccb);
#endif
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index f36e98b..b0c487d 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -3432,6 +3432,7 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data)
break;
case T_NODEVICE:
dtype = "Uninstalled";
+ break;
default:
dtype = "unknown";
break;
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 383d703..8eb3537 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -292,6 +292,9 @@ static struct periph_driver cddriver =
PERIPHDRIVER_DECLARE(cd, cddriver);
+#ifndef CD_DEFAULT_RETRY
+#define CD_DEFAULT_RETRY 4
+#endif
#ifndef CHANGER_MIN_BUSY_SECONDS
#define CHANGER_MIN_BUSY_SECONDS 5
#endif
@@ -299,11 +302,15 @@ PERIPHDRIVER_DECLARE(cd, cddriver);
#define CHANGER_MAX_BUSY_SECONDS 15
#endif
+static int cd_retry_count = CD_DEFAULT_RETRY;
static int changer_min_busy_seconds = CHANGER_MIN_BUSY_SECONDS;
static int changer_max_busy_seconds = CHANGER_MAX_BUSY_SECONDS;
SYSCTL_NODE(_kern_cam, OID_AUTO, cd, CTLFLAG_RD, 0, "CAM CDROM driver");
SYSCTL_NODE(_kern_cam_cd, OID_AUTO, changer, CTLFLAG_RD, 0, "CD Changer");
+SYSCTL_INT(_kern_cam_cd, OID_AUTO, retry_count, CTLFLAG_RW,
+ &cd_retry_count, 0, "Normal I/O retry count");
+TUNABLE_INT("kern.cam.cd.retry_count", &cd_retry_count);
SYSCTL_INT(_kern_cam_cd_changer, OID_AUTO, min_busy_seconds, CTLFLAG_RW,
&changer_min_busy_seconds, 0, "Minimum changer scheduling quantum");
TUNABLE_INT("kern.cam.cd.changer.min_busy_seconds", &changer_min_busy_seconds);
@@ -1454,7 +1461,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb)
devstat_start_transaction_bio(softc->disk->d_devstat, bp);
scsi_read_write(&start_ccb->csio,
- /*retries*/4,
+ /*retries*/cd_retry_count,
/* cbfcnp */ cddone,
MSG_SIMPLE_Q_TAG,
/* read */bp->bio_cmd == BIO_READ,
diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c
index ca4a365..892deac 100644
--- a/sys/cam/scsi/scsi_ch.c
+++ b/sys/cam/scsi/scsi_ch.c
@@ -262,9 +262,11 @@ chcleanup(struct cam_periph *periph)
softc = (struct ch_softc *)periph->softc;
+ xpt_print(periph->path, "removing device entry\n");
devstat_remove_entry(softc->device_stats);
+ cam_periph_unlock(periph);
destroy_dev(softc->dev);
- xpt_print(periph->path, "removing device entry\n");
+ cam_periph_lock(periph);
free(softc, M_DEVBUF);
}
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 1e47660..f6f0aa4 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -1021,7 +1021,6 @@ daasync(void *callback_arg, u_int32_t code,
case AC_FOUND_DEVICE:
{
struct ccb_getdev *cgd;
- struct cam_sim *sim;
cam_status status;
cgd = (struct ccb_getdev *)arg;
@@ -1038,7 +1037,6 @@ daasync(void *callback_arg, u_int32_t code,
* this device and start the probe
* process.
*/
- sim = xpt_path_sim(cgd->ccb_h.path);
status = cam_periph_alloc(daregister, daoninvalidate,
dacleanup, dastart,
"da", CAM_PERIPH_BIO,
diff --git a/sys/cam/scsi/scsi_low.c b/sys/cam/scsi/scsi_low.c
index 0f4fe27..57054a2 100644
--- a/sys/cam/scsi/scsi_low.c
+++ b/sys/cam/scsi/scsi_low.c
@@ -966,16 +966,16 @@ scsi_low_rescan_bus_cam(slp)
struct scsi_low_softc *slp;
{
struct cam_path *path;
- union ccb *ccb = xpt_alloc_ccb();
+ union ccb *ccb;
cam_status status;
- bzero(ccb, sizeof(union ccb));
-
status = xpt_create_path(&path, xpt_periph,
cam_sim_path(slp->sl_si.sim), -1, 0);
if (status != CAM_REQ_CMP)
return;
+ ccb = xpt_alloc_ccb();
+ bzero(ccb, sizeof(union ccb));
xpt_setup_ccb(&ccb->ccb_h, path, 5);
ccb->ccb_h.func_code = XPT_SCAN_BUS;
ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index 16ecec4..c60bb92 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -165,13 +165,12 @@ passcleanup(struct cam_periph *periph)
softc = (struct pass_softc *)periph->softc;
+ if (bootverbose)
+ xpt_print(periph->path, "removing device entry\n");
devstat_remove_entry(softc->device_stats);
-
+ cam_periph_unlock(periph);
destroy_dev(softc->dev);
-
- if (bootverbose) {
- xpt_print(periph->path, "removing device entry\n");
- }
+ cam_periph_lock(periph);
free(softc, M_DEVBUF);
}
@@ -299,8 +298,6 @@ passopen(struct cdev *dev, int flags, int fmt, struct thread *td)
struct pass_softc *softc;
int error;
- error = 0; /* default to no error */
-
periph = (struct cam_periph *)dev->si_drv1;
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
return (ENXIO);
diff --git a/sys/cam/scsi/scsi_pt.c b/sys/cam/scsi/scsi_pt.c
index d70972e..c41d5e9 100644
--- a/sys/cam/scsi/scsi_pt.c
+++ b/sys/cam/scsi/scsi_pt.c
@@ -342,11 +342,11 @@ ptdtor(struct cam_periph *periph)
softc = (struct pt_softc *)periph->softc;
+ xpt_print(periph->path, "removing device entry\n");
devstat_remove_entry(softc->device_stats);
-
+ cam_periph_unlock(periph);
destroy_dev(softc->dev);
-
- xpt_print(periph->path, "removing device entry\n");
+ cam_periph_lock(periph);
free(softc, M_DEVBUF);
}
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c
index b775cc1..ef76a90 100644
--- a/sys/cam/scsi/scsi_sa.c
+++ b/sys/cam/scsi/scsi_sa.c
@@ -1377,17 +1377,16 @@ sacleanup(struct cam_periph *periph)
softc = (struct sa_softc *)periph->softc;
+ xpt_print(periph->path, "removing device entry\n");
devstat_remove_entry(softc->device_stats);
-
+ cam_periph_unlock(periph);
destroy_dev(softc->devs.ctl_dev);
-
for (i = 0; i < SA_NUM_MODES; i++) {
destroy_dev(softc->devs.mode_devs[i].r_dev);
destroy_dev(softc->devs.mode_devs[i].nr_dev);
destroy_dev(softc->devs.mode_devs[i].er_dev);
}
-
- xpt_print(periph->path, "removing device entry\n");
+ cam_periph_lock(periph);
free(softc, M_SCSISA);
}
diff --git a/sys/cam/scsi/scsi_ses.c b/sys/cam/scsi/scsi_ses.c
index acd6e51..14bcc77 100644
--- a/sys/cam/scsi/scsi_ses.c
+++ b/sys/cam/scsi/scsi_ses.c
@@ -227,9 +227,10 @@ sescleanup(struct cam_periph *periph)
softc = (struct ses_softc *)periph->softc;
- destroy_dev(softc->ses_dev);
-
xpt_print(periph->path, "removing device entry\n");
+ cam_periph_unlock(periph);
+ destroy_dev(softc->ses_dev);
+ cam_periph_lock(periph);
free(softc, M_SCSISES);
}
diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c
index 6daf6ff..efaa43e 100644
--- a/sys/cam/scsi/scsi_sg.c
+++ b/sys/cam/scsi/scsi_sg.c
@@ -200,11 +200,12 @@ sgcleanup(struct cam_periph *periph)
struct sg_softc *softc;
softc = (struct sg_softc *)periph->softc;
+ if (bootverbose)
+ xpt_print(periph->path, "removing device entry\n");
devstat_remove_entry(softc->device_stats);
+ cam_periph_unlock(periph);
destroy_dev(softc->dev);
- if (bootverbose) {
- xpt_print(periph->path, "removing device entry\n");
- }
+ cam_periph_lock(periph);
free(softc, M_DEVBUF);
}
@@ -940,6 +941,7 @@ sg_scsiio_status(struct ccb_scsiio *csio, u_short *hoststat, u_short *drvstat)
case CAM_DEV_NOT_THERE:
*hoststat = DID_BAD_TARGET;
*drvstat = 0;
+ break;
case CAM_SEL_TIMEOUT:
*hoststat = DID_NO_CONNECT;
*drvstat = 0;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
index 86838df..5687522 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
@@ -494,7 +494,7 @@ zfs_init_fs(zfsvfs_t *zfsvfs, znode_t **zpp)
static uint64_t
zfs_expldev(dev_t dev)
{
- return (((uint64_t)umajor(dev) << NBITSMINOR64) | uminor(dev));
+ return (((uint64_t)major(dev) << NBITSMINOR64) | minor(dev));
}
/*
* Special cmpldev for ZFS private use.
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 2569ead..83fd67f 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2019,7 +2019,6 @@ freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
error = copyin(uap->name, name, uap->namelen * sizeof(int));
if (error)
return (error);
- mtx_lock(&Giant);
if (uap->oldlenp)
oldlen = fuword32(uap->oldlenp);
else
@@ -2028,12 +2027,10 @@ freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
uap->old, &oldlen, 1,
uap->new, uap->newlen, &j, SCTL_MASK32);
if (error && error != ENOMEM)
- goto done2;
+ return (error);
if (uap->oldlenp)
suword32(uap->oldlenp, j);
-done2:
- mtx_unlock(&Giant);
- return (error);
+ return (0);
}
int
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 09c22e3..bf2b10c 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -276,11 +276,17 @@ linprocfs_docpuinfo(PFS_FILL_ARGS)
sbuf_cat(sb, "flags\t\t:");
- if (!strcmp(cpu_vendor, "AuthenticAMD") && (class < 6)) {
- flags[16] = "fcmov";
- } else if (!strcmp(cpu_vendor, "CyrixInstead")) {
+#ifdef __i386__
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_AMD:
+ if (class < 6)
+ flags[16] = "fcmov";
+ break;
+ case CPU_VENDOR_CYRIX:
flags[24] = "cxmmx";
+ break;
}
+#endif
for (i = 0; i < 32; i++)
if (cpu_feature & (1 << i))
@@ -980,7 +986,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
error = 0;
break;
}
- if (last_timestamp + 1 != map->timestamp) {
+ if (last_timestamp != map->timestamp) {
/*
* Look again for the entry because the map was
* modified while it was unlocked. Specifically,
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 93f4297..bdbb5dd 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1682,7 +1682,6 @@ int
linux_sethostname(struct thread *td, struct linux_sethostname_args *args)
{
int name[2];
- int error;
#ifdef DEBUG
if (ldebug(sethostname))
@@ -1691,18 +1690,14 @@ linux_sethostname(struct thread *td, struct linux_sethostname_args *args)
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, 0, 0, 0, args->hostname,
- args->len, 0, 0);
- mtx_unlock(&Giant);
- return (error);
+ return (userland_sysctl(td, name, 2, 0, 0, 0, args->hostname,
+ args->len, 0, 0));
}
int
linux_setdomainname(struct thread *td, struct linux_setdomainname_args *args)
{
int name[2];
- int error;
#ifdef DEBUG
if (ldebug(setdomainname))
@@ -1711,11 +1706,8 @@ linux_setdomainname(struct thread *td, struct linux_setdomainname_args *args)
name[0] = CTL_KERN;
name[1] = KERN_NISDOMAINNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, 0, 0, 0, args->name,
- args->len, 0, 0);
- mtx_unlock(&Giant);
- return (error);
+ return (userland_sysctl(td, name, 2, 0, 0, 0, args->name,
+ args->len, 0, 0));
}
int
diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c
index c5f10af..5f1ce53 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -88,7 +88,7 @@ disk_foo(struct somestat *tbuf)
/* XXX this may not be quite right */
/* Map major number to 0 */
- tbuf.st_dev = uminor(buf->st_dev) & 0xf;
+ tbuf.st_dev = minor(buf->st_dev) & 0xf;
tbuf.st_rdev = buf->st_rdev & 0xff;
}
dev_relthread(dev);
@@ -156,7 +156,7 @@ newstat_copyout(struct stat *buf, void *ubuf)
struct l_newstat tbuf;
bzero(&tbuf, sizeof(tbuf));
- tbuf.st_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8);
+ tbuf.st_dev = minor(buf->st_dev) | (major(buf->st_dev) << 8);
tbuf.st_ino = buf->st_ino;
tbuf.st_mode = buf->st_mode;
tbuf.st_nlink = buf->st_nlink;
@@ -487,7 +487,7 @@ stat64_copyout(struct stat *buf, void *ubuf)
struct l_stat64 lbuf;
bzero(&lbuf, sizeof(lbuf));
- lbuf.st_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8);
+ lbuf.st_dev = minor(buf->st_dev) | (major(buf->st_dev) << 8);
lbuf.st_ino = buf->st_ino;
lbuf.st_mode = buf->st_mode;
lbuf.st_nlink = buf->st_nlink;
diff --git a/sys/compat/ndis/winx32_wrap.S b/sys/compat/ndis/winx32_wrap.S
index 065d409..c051504 100644
--- a/sys/compat/ndis/winx32_wrap.S
+++ b/sys/compat/ndis/winx32_wrap.S
@@ -369,7 +369,7 @@ ENTRY(x86_getfs)
ret
ENTRY(x86_setfs)
- movl 4(%esp),%fs
+ mov 4(%esp),%fs
ret
ENTRY(x86_gettid)
diff --git a/sys/compat/svr4/svr4_types.h b/sys/compat/svr4/svr4_types.h
index af801d8..e4f51b5 100644
--- a/sys/compat/svr4/svr4_types.h
+++ b/sys/compat/svr4/svr4_types.h
@@ -69,13 +69,13 @@ typedef struct timespec svr4_timestruc_t;
(((y) << 0) & 0x00ff)))
#define svr4_to_bsd_odev_t(d) makedev(svr4_omajor(d), svr4_ominor(d))
-#define bsd_to_svr4_odev_t(d) svr4_omakedev(umajor(d), uminor(d))
+#define bsd_to_svr4_odev_t(d) svr4_omakedev(major(d), minor(d))
#define svr4_major(x) ((int32_t)((((x) & 0xfffc0000) >> 18)))
#define svr4_minor(x) ((int32_t)((((x) & 0x0003ffff) >> 0)))
#define svr4_makedev(x,y) ((svr4_dev_t)((((x) << 18) & 0xfffc0000) | \
(((y) << 0) & 0x0003ffff)))
#define svr4_to_bsd_dev_t(d) makedev(svr4_major(d), svr4_minor(d))
-#define bsd_to_svr4_dev_t(d) svr4_makedev(umajor(d), uminor(d))
+#define bsd_to_svr4_dev_t(d) svr4_makedev(major(d), minor(d))
#endif /* !_SVR4_TYPES_H_ */
diff --git a/sys/conf/Makefile.arm b/sys/conf/Makefile.arm
index 98f7d0d..310c54d 100644
--- a/sys/conf/Makefile.arm
+++ b/sys/conf/Makefile.arm
@@ -73,7 +73,7 @@ FILES_CPU_FUNC = $S/$M/$M/cpufunc_asm_arm7tdmi.S \
$S/$M/$M/cpufunc_asm_sa1.S $S/$M/$M/cpufunc_asm_arm10.S \
$S/$M/$M/cpufunc_asm_xscale.S $S/$M/$M/cpufunc_asm.S \
$S/$M/$M/cpufunc_asm_xscale_c3.S $S/$M/$M/cpufunc_asm_armv5_ec.S \
- $S/$M/$M/cpufunc_asm_feroceon.S
+ $S/$M/$M/cpufunc_asm_sheeva.S
KERNEL_EXTRA=trampoline
KERNEL_EXTRA_INSTALL=kernel.gz.tramp
trampoline: ${KERNEL_KO}.tramp
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 6825dd4..2227f5e 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -633,6 +633,14 @@ options ALTQ_PRIQ # Priority Queueing
options ALTQ_NOPCC # Required if the TSC is unusable
options ALTQ_DEBUG
+# IP optional behaviour.
+# IP_NONLOCALBIND disables the check that bind() usually makes that the
+# address is one that is assigned to an interface on this machine.
+# It allows transparent proxies to pretend to be other machines.
+# How the packet GET to that machine is a problem solved elsewhere,
+# smart routers, ipfw fwd, etc.
+options IP_NONLOCALBIND # Allow impersonation for proxies.
+
# netgraph(4). Enable the base netgraph code with the NETGRAPH option.
# Individual node types can be enabled with the corresponding option
# listed below; however, this is not strictly necessary as netgraph
@@ -934,7 +942,12 @@ options HPFS #OS/2 File system
options MSDOSFS #MS DOS File System (FAT, FAT32)
options NFSSERVER #Network File System server
options NFSLOCKD #Network Lock Manager
-options NTFS #NT File System
+
+# NT File System. Read-mostly, see mount_ntfs(8) for details.
+# For a full read-write NTFS support consider sysutils/fusefs-ntfs
+# port/package.
+options NTFS
+
options NULLFS #NULL filesystem
# Broken (depends on NCP):
#options NWFS #NetWare filesystem
@@ -1362,6 +1375,10 @@ options SC_NO_SUSPEND_VTYSWITCH
# 0x80 Put the video card in the VESA 800x600 dots, 16 color mode
# 0x100 Probe for a keyboard device periodically if one is not present
+# Enable experimental features of the syscons terminal emulator (teken).
+options TEKEN_UTF8 # UTF-8 output handling
+options TEKEN_XTERM # xterm-style terminal emulation
+
#
# Optional devices:
#
@@ -1984,8 +2001,6 @@ device sound
# snd_ad1816: Analog Devices AD1816 ISA PnP/non-PnP.
# snd_als4000: Avance Logic ALS4000 PCI.
# snd_atiixp: ATI IXP 200/300/400 PCI.
-# snd_au88x0 Aureal Vortex 1/2/Advantage PCI. This driver
-# lacks support for playback and recording.
# snd_audiocs: Crystal Semiconductor CS4231 SBus/EBus. Only
# for sparc64.
# snd_cmi: CMedia CMI8338/CMI8738 PCI.
@@ -2004,7 +2019,7 @@ device sound
# snd_gusc: Gravis UltraSound ISA PnP/non-PnP.
# snd_hda: Intel High Definition Audio (Controller) and
# compatible.
-# snd_ich: Intel ICH PCI and some more audio controllers
+# snd_ich: Intel ICH AC'97 and some more audio controllers
# embedded in a chipset, for example nVidia
# nForce controllers.
# snd_maestro: ESS Technology Maestro-1/2x PCI.
@@ -2029,7 +2044,6 @@ device sound
device snd_ad1816
device snd_als4000
device snd_atiixp
-#device snd_au88x0
#device snd_audiocs
device snd_cmi
device snd_cs4281
diff --git a/sys/conf/files b/sys/conf/files
index a52729a..a5d9c58 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -75,6 +75,11 @@ pccarddevs.h standard \
compile-with "${AWK} -f $S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \
no-obj no-implicit-rule before-depend \
clean "pccarddevs.h"
+teken_state.h optional sc \
+ dependency "$S/dev/syscons/teken/gensequences $S/dev/syscons/teken/sequences" \
+ compile-with "${AWK} -f $S/dev/syscons/teken/gensequences $S/dev/syscons/teken/sequences > teken_state.h" \
+ no-obj no-implicit-rule before-depend \
+ clean "teken_state.h"
usbdevs.h optional usb \
dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \
compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h" \
@@ -1332,7 +1337,6 @@ dev/sound/isa/sbc.c optional snd_sbc isa
dev/sound/isa/sndbuf_dma.c optional sound isa
dev/sound/pci/als4000.c optional snd_als4000 pci
dev/sound/pci/atiixp.c optional snd_atiixp pci
-#dev/sound/pci/au88x0.c optional snd_au88x0 pci
dev/sound/pci/cmi.c optional snd_cmi pci
dev/sound/pci/cs4281.c optional snd_cs4281 pci
dev/sound/pci/csa.c optional snd_csa pci \
@@ -1424,7 +1428,6 @@ dev/syscons/logo/logo_saver.c optional logo_saver
dev/syscons/rain/rain_saver.c optional rain_saver
dev/syscons/schistory.c optional sc
dev/syscons/scmouse.c optional sc
-dev/syscons/scterm-dumb.c optional sc
dev/syscons/scterm.c optional sc
dev/syscons/scvidctl.c optional sc
dev/syscons/snake/snake_saver.c optional snake_saver
@@ -1606,6 +1609,7 @@ dev/usb2/wlan/usb2_wlan.c optional usb2_core usb2_wlan
#
# USB2 serial and parallel port drivers
#
+dev/usb2/serial/u3g2.c optional usb2_core usb2_serial usb2_serial_3g
dev/usb2/serial/uark2.c optional usb2_core usb2_serial usb2_serial_ark
dev/usb2/serial/ubsa2.c optional usb2_core usb2_serial usb2_serial_bsa
dev/usb2/serial/ubser2.c optional usb2_core usb2_serial usb2_serial_bser
@@ -2229,6 +2233,7 @@ net80211/ieee80211_rssadapt.c optional wlan_rssadapt
net80211/ieee80211_scan.c optional wlan
net80211/ieee80211_scan_sta.c optional wlan
net80211/ieee80211_sta.c optional wlan
+net80211/ieee80211_tdma.c optional wlan
net80211/ieee80211_wds.c optional wlan
net80211/ieee80211_xauth.c optional wlan_xauth
netatalk/aarp.c optional netatalk
@@ -2534,7 +2539,10 @@ rpc/rpcsec_gss/svc_rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi
security/audit/audit.c optional audit
security/audit/audit_arg.c optional audit
security/audit/audit_bsm.c optional audit
+security/audit/audit_bsm_domain.c optional audit
+security/audit/audit_bsm_errno.c optional audit
security/audit/audit_bsm_klib.c optional audit
+security/audit/audit_bsm_socket_type.c optional audit
security/audit/audit_bsm_token.c optional audit
security/audit/audit_pipe.c optional audit
security/audit/audit_syscalls.c standard
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 82ec801..b0b37ec 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -128,10 +128,14 @@ amd64/pci/pci_bus.c optional pci
amd64/pci/pci_cfgreg.c optional pci
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
+crypto/via/padlock.c optional padlock
+crypto/via/padlock_cipher.c optional padlock
+crypto/via/padlock_hash.c optional padlock
dev/acpica/acpi_if.m standard
-dev/agp/agp_amd64.c optional agp
-dev/agp/agp_i810.c optional agp
-dev/agp/agp_intel.c optional agp
+dev/agp/agp_amd64.c optional agp
+dev/agp/agp_i810.c optional agp
+dev/agp/agp_intel.c optional agp
+dev/agp/agp_via.c optional agp
dev/arcmsr/arcmsr.c optional arcmsr pci
dev/asmc/asmc.c optional asmc isa
dev/atkbdc/atkbd.c optional atkbd atkbdc
@@ -196,9 +200,10 @@ dev/sio/sio_pci.c optional sio pci
dev/sio/sio_puc.c optional sio puc
dev/speaker/spkr.c optional speaker
dev/syscons/apm/apm_saver.c optional apm_saver apm
-dev/syscons/scterm-sc.c optional sc
+dev/syscons/scterm-teken.c optional sc
dev/syscons/scvgarndr.c optional sc vga
dev/syscons/scvtb.c optional sc
+dev/syscons/teken/teken.c optional sc
dev/uart/uart_cpu_amd64.c optional uart
dev/wpi/if_wpi.c optional wpi
isa/atrtc.c standard
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 17076db..9a74ec6 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -118,15 +118,15 @@ crypto/via/padlock.c optional padlock
crypto/via/padlock_cipher.c optional padlock
crypto/via/padlock_hash.c optional padlock
dev/advansys/adv_isa.c optional adv isa
-dev/agp/agp_ali.c optional agp
-dev/agp/agp_amd.c optional agp
-dev/agp/agp_amd64.c optional agp
-dev/agp/agp_ati.c optional agp
-dev/agp/agp_i810.c optional agp
-dev/agp/agp_intel.c optional agp
+dev/agp/agp_ali.c optional agp
+dev/agp/agp_amd.c optional agp
+dev/agp/agp_amd64.c optional agp
+dev/agp/agp_ati.c optional agp
+dev/agp/agp_i810.c optional agp
+dev/agp/agp_intel.c optional agp
dev/agp/agp_nvidia.c optional agp
-dev/agp/agp_sis.c optional agp
-dev/agp/agp_via.c optional agp
+dev/agp/agp_sis.c optional agp
+dev/agp/agp_via.c optional agp
dev/aic/aic_isa.c optional aic isa
dev/arcmsr/arcmsr.c optional arcmsr pci
dev/ar/if_ar.c optional ar
@@ -220,10 +220,11 @@ dev/sio/sio_puc.c optional sio puc
dev/speaker/spkr.c optional speaker
dev/sr/if_sr_isa.c optional sr isa
dev/syscons/apm/apm_saver.c optional apm_saver apm
-dev/syscons/scterm-sc.c optional sc
+dev/syscons/scterm-teken.c optional sc
dev/syscons/scvesactl.c optional sc vga vesa
dev/syscons/scvgarndr.c optional sc vga
dev/syscons/scvtb.c optional sc
+dev/syscons/teken/teken.c optional sc
dev/uart/uart_cpu_i386.c optional uart
dev/acpica/acpi_if.m standard
dev/wpi/if_wpi.c optional wpi
diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64
index 6556fbb..c17acb2 100644
--- a/sys/conf/files.ia64
+++ b/sys/conf/files.ia64
@@ -57,9 +57,10 @@ dev/fb/fb.c optional fb | vga
dev/fb/vga.c optional vga
dev/hwpmc/hwpmc_ia64.c optional hwpmc
dev/kbd/kbd.c optional atkbd | sc | ukbd
-dev/syscons/scterm-sc.c optional sc
+dev/syscons/scterm-teken.c optional sc
dev/syscons/scvgarndr.c optional sc vga
dev/syscons/scvtb.c optional sc
+dev/syscons/teken/teken.c optional sc
dev/uart/uart_cpu_ia64.c optional uart
dev/acpica/acpi_if.m standard
ia64/acpica/OsdEnvironment.c optional acpi
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index f9b8487..8e728cc 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -77,13 +77,13 @@ bf_enc.o optional crypto | ipsec \
compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \
no-implicit-rule
crypto/des/arch/i386/des_enc.S optional crypto | ipsec | netsmb
-dev/agp/agp_ali.c optional agp
-dev/agp/agp_amd.c optional agp
-dev/agp/agp_i810.c optional agp
-dev/agp/agp_intel.c optional agp
+dev/agp/agp_ali.c optional agp
+dev/agp/agp_amd.c optional agp
+dev/agp/agp_i810.c optional agp
+dev/agp/agp_intel.c optional agp
dev/agp/agp_nvidia.c optional agp
-dev/agp/agp_sis.c optional agp
-dev/agp/agp_via.c optional agp
+dev/agp/agp_sis.c optional agp
+dev/agp/agp_via.c optional agp
dev/aic/aic_cbus.c optional aic isa
dev/ar/if_ar.c optional ar
dev/ar/if_ar_pci.c optional ar pci
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 901e36d..8b003e8 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -34,13 +34,20 @@ dev/ofw/ofw_if.m optional aim
dev/ofw/ofw_bus_subr.c optional aim
dev/ofw/ofw_console.c optional aim
dev/ofw/ofw_disk.c optional ofwd aim
+dev/ofw/ofw_iicbus.c optional iicbus aim
dev/ofw/ofw_standard.c optional aim
dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac
dev/quicc/quicc_bfe_ocp.c optional quicc mpc85xx
dev/scc/scc_bfe_macio.c optional scc powermac
+dev/sound/macio/aoa.c optional snd_davbus | snd_ai2s powermac
+dev/sound/macio/davbus.c optional snd_davbus powermac
+dev/sound/macio/i2s.c optional snd_ai2s powermac
+dev/sound/macio/snapper.c optional snd_ai2s iicbus powermac
+dev/sound/macio/tumbler.c optional snd_ai2s iicbus powermac
dev/syscons/scgfbrndr.c optional sc
-dev/syscons/scterm-sc.c optional sc
+dev/syscons/scterm-teken.c optional sc
dev/syscons/scvtb.c optional sc
+dev/syscons/teken/teken.c optional sc
dev/tsec/if_tsec.c optional tsec
dev/tsec/if_tsec_ocp.c optional tsec mpc85xx
dev/uart/uart_bus_ocp.c optional uart mpc85xx
@@ -83,7 +90,6 @@ powerpc/booke/interrupt.c optional e500
powerpc/booke/locore.S optional e500 no-obj
powerpc/booke/machdep.c optional e500
powerpc/booke/pmap.c optional e500
-powerpc/booke/support.S optional e500
powerpc/booke/swtch.S optional e500
powerpc/booke/trap.c optional e500
powerpc/booke/uio_machdep.c optional e500
@@ -112,6 +118,7 @@ powerpc/powermac/ata_dbdma.c optional powermac ata
powerpc/powermac/dbdma.c optional powermac pci
powerpc/powermac/grackle.c optional powermac pci
powerpc/powermac/hrowpic.c optional powermac pci
+powerpc/powermac/kiic.c optional powermac kiic
powerpc/powermac/macio.c optional powermac pci
powerpc/powermac/openpic_macio.c optional powermac pci
powerpc/powermac/pswitch.c optional powermac pswitch
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64
index 311027c..90c37a9 100644
--- a/sys/conf/files.sparc64
+++ b/sys/conf/files.sparc64
@@ -55,8 +55,9 @@ dev/pcf/pcf_ebus.c optional pcf ebus
dev/sound/sbus/cs4231.c optional snd_audiocs ebus | \
snd_audiocs sbus
dev/syscons/scgfbrndr.c optional sc
-dev/syscons/scterm-sc.c optional sc
+dev/syscons/scterm-teken.c optional sc
dev/syscons/scvtb.c optional sc
+dev/syscons/teken/teken.c optional sc
dev/uart/uart_cpu_sparc64.c optional uart
dev/uart/uart_kbd_sun.c optional uart sc
kern/syscalls.c optional ktr
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
index be31b9a..f0dd6fd 100644
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -217,21 +217,21 @@ kernel-install:
fi
.endif
mkdir -p ${DESTDIR}${KODIR}
- ${INSTALL} -p -m 555 -o root -g wheel ${KERNEL_KO} ${DESTDIR}${KODIR}
+ ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}
.if defined(DEBUG) && !defined(INSTALL_NODEBUG)
- ${INSTALL} -p -m 555 -o root -g wheel ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
+ ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
.endif
.if defined(KERNEL_EXTRA_INSTALL)
- ${INSTALL} -p -m 555 -o root -g wheel ${KERNEL_EXTRA_INSTALL} ${DESTDIR}${KODIR}
+ ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_EXTRA_INSTALL} ${DESTDIR}${KODIR}
.endif
kernel-reinstall:
@-chflags -R noschg ${DESTDIR}${KODIR}
- ${INSTALL} -p -m 555 -o root -g wheel ${KERNEL_KO} ${DESTDIR}${KODIR}
+ ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}
.if defined(DEBUG) && !defined(INSTALL_NODEBUG)
- ${INSTALL} -p -m 555 -o root -g wheel ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
+ ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
.endif
config.o env.o hints.o vers.o vnode_if.o:
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index dbb16c8..ee74a9e 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -25,6 +25,7 @@ COPTFLAGS?= -O
.else
. if defined(DEBUG)
_MINUS_O= -O
+CTFFLAGS+= -g
. else
_MINUS_O= -O2
. endif
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index 4fa4fde..e6253f5 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -89,10 +89,9 @@ CFLAGS+= -DKLD_MODULE
.if ${CC} == "icc"
NOSTDINC= -X
.else
-C_DIALECT= -std=c99
+CSTD= c99
NOSTDINC= -nostdinc
.endif
-CFLAGS+= ${C_DIALECT}
CFLAGS:= ${CFLAGS:N-I*} ${NOSTDINC} ${INCLMAGIC} ${CFLAGS:M-I*}
.if defined(KERNBUILDDIR)
CFLAGS+= -DHAVE_KERNEL_OPTION_HEADERS -include ${KERNBUILDDIR}/opt_global.h
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index e3b0030..f141a8c 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -91,6 +91,9 @@ for dir in /bin /usr/bin /usr/local/bin; do
if [ -x "${dir}/svnversion" ]; then
svnversion=${dir}/svnversion
SRCDIR=${d##*obj}
+ if [ -n "$MACHINE" ]; then
+ SRCDIR=${SRCDIR##/$MACHINE}
+ fi
SRCDIR=${SRCDIR%%/sys/*}
break
fi
diff --git a/sys/conf/options b/sys/conf/options
index c3a72a7..1649db9 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -36,7 +36,7 @@ AHC_TMODE_ENABLE opt_aic7xxx.h
AHC_DUMP_EEPROM opt_aic7xxx.h
AHC_DEBUG opt_aic7xxx.h
AHC_DEBUG_OPTS opt_aic7xxx.h
-AHC_REG_PRETTY_PRINT opt_aic7xxx.h
+AHC_REG_PRETTY_PRINT opt_aic7xxx.h
AHD_DEBUG opt_aic79xx.h
AHD_DEBUG_OPTS opt_aic79xx.h
AHD_TMODE_ENABLE opt_aic79xx.h
@@ -137,7 +137,7 @@ NSWBUF_MIN opt_swap.h
MBUF_PACKET_ZONE_DISABLE opt_global.h
PANIC_REBOOT_WAIT_TIME opt_panic.h
PPC_DEBUG opt_ppc.h
-PPC_PROBE_CHIPSET opt_ppc.h
+PPC_PROBE_CHIPSET opt_ppc.h
PPS_SYNC opt_ntp.h
PREEMPTION opt_sched.h
QUOTA
@@ -392,6 +392,7 @@ IPFIREWALL_VERBOSE opt_ipfw.h
IPFIREWALL_VERBOSE_LIMIT opt_ipfw.h
IPSEC opt_ipsec.h
IPSEC_DEBUG opt_ipsec.h
+IP_NONLOCALBIND opt_inet.h
IPSEC_FILTERTUNNEL opt_ipsec.h
IPSTEALTH
IPX
@@ -410,6 +411,7 @@ PPP_DEFLATE opt_ppp.h
PPP_FILTER opt_ppp.h
RADIX_MPATH opt_mpath.h
ROUTETABLES opt_route.h
+COMPAT_ROUTE_FLAGS opt_route.h
SLIP_IFF_OPTS opt_slip.h
TCPDEBUG
TCP_OFFLOAD_DISABLE opt_inet.h #Disable code to dispatch tcp offloading
@@ -422,13 +424,13 @@ XBONEHACK
#
SCTP opt_sctp.h
SCTP_DEBUG opt_sctp.h # Enable debug printfs
-SCTP_WITH_NO_CSUM opt_sctp.h # Use this at your peril
-SCTP_LOCK_LOGGING opt_sctp.h # Log to KTR lock activity
-SCTP_MBUF_LOGGING opt_sctp.h # Log to KTR general mbuf aloc/free
+SCTP_WITH_NO_CSUM opt_sctp.h # Use this at your peril
+SCTP_LOCK_LOGGING opt_sctp.h # Log to KTR lock activity
+SCTP_MBUF_LOGGING opt_sctp.h # Log to KTR general mbuf aloc/free
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_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.
#
#
#
@@ -724,6 +726,10 @@ SC_PIXEL_MODE opt_syscons.h
SC_RENDER_DEBUG opt_syscons.h
SC_TWOBUTTON_MOUSE opt_syscons.h
+# teken terminal emulator options
+TEKEN_UTF8 opt_teken.h
+TEKEN_XTERM opt_teken.h
+
# options for printf
PRINTF_BUFR_SIZE opt_printf.h
@@ -741,6 +747,7 @@ ATH_TXBUF opt_ath.h
ATH_RXBUF opt_ath.h
ATH_DIAGAPI opt_ath.h
ATH_TX99_DIAG opt_ath.h
+ATH_SUPPORT_TDMA opt_ath.h
# options for the Atheros hal
AH_SUPPORT_AR5416 opt_ah.h
@@ -755,7 +762,7 @@ AH_WRITE_EEPROM opt_ah.h
AH_PRIVATE_DIAG opt_ah.h
AH_NEED_DESC_SWAP opt_ah.h
AH_USE_INIPDGAIN opt_ah.h
-AH_SUPPORT_11D opt_ah.h
+AH_MAXCHAN opt_ah.h
# options for the Marvell 8335 wireless driver
MALO_DEBUG opt_malo.h
@@ -784,7 +791,20 @@ INTR_FILTER
IEEE80211_DEBUG opt_wlan.h
IEEE80211_DEBUG_REFCNT opt_wlan.h
IEEE80211_AMPDU_AGE opt_wlan.h
+IEEE80211_SUPPORT_TDMA opt_wlan.h
+
+# 802.11 TDMA support
+TDMA_SLOTLEN_DEFAULT opt_tdma.h
+TDMA_SLOTCNT_DEFAULT opt_tdma.h
+TDMA_BINTVAL_DEFAULT opt_tdma.h
+TDMA_TXRATE_11B_DEFAULT opt_tdma.h
+TDMA_TXRATE_11G_DEFAULT opt_tdma.h
+TDMA_TXRATE_11A_DEFAULT opt_tdma.h
# Virtualize the network stack
VIMAGE opt_global.h
VIMAGE_GLOBALS opt_global.h
+
+# Common Flash Interface (CFI) options
+CFI_SUPPORT_STRATAFLASH opt_cfi.h
+CFI_ARMEDANDDANGEROUS opt_cfi.h
diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
index 9a5e7dd..1e69363 100644
--- a/sys/conf/options.amd64
+++ b/sys/conf/options.amd64
@@ -37,6 +37,9 @@ VGA_NO_MODE_CHANGE opt_vga.h
VGA_SLOW_IOACCESS opt_vga.h
VGA_WIDTH90 opt_vga.h
+# AGP debugging support
+AGP_DEBUG opt_agp.h
+
ATKBD_DFLT_KEYMAP opt_atkbd.h
# -------------------------------
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index aebd884..45a1637 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -88,6 +88,9 @@ VGA_WIDTH90 opt_vga.h
VESA
VESA_DEBUG opt_vesa.h
+# AGP debugging support
+AGP_DEBUG opt_agp.h
+
PSM_DEBUG opt_psm.h
PSM_HOOKRESUME opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
diff --git a/sys/conf/options.ia64 b/sys/conf/options.ia64
index 11f2285..7a292ed 100644
--- a/sys/conf/options.ia64
+++ b/sys/conf/options.ia64
@@ -20,6 +20,9 @@ VGA_NO_MODE_CHANGE opt_vga.h
VGA_SLOW_IOACCESS opt_vga.h
VGA_WIDTH90 opt_vga.h
+# AGP debugging.
+AGP_DEBUG opt_agp.h
+
PSM_HOOKRESUME opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
diff --git a/sys/conf/options.mips b/sys/conf/options.mips
index 757993f..42e0263 100644
--- a/sys/conf/options.mips
+++ b/sys/conf/options.mips
@@ -48,7 +48,7 @@ CFE_CONSOLE opt_global.h
KERNPHYSADDR opt_global.h
KERNVIRTADDR opt_global.h
PHYSADDR opt_global.h
-SOFTFLOAT opt_global.h
+SOFTFLOAT opt_global.h
TARGET_OCTEON opt_global.h
TARGET_EMULATOR opt_ddb.h
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index 4912c42..837169b 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -96,6 +96,7 @@ DEV_NPX opt_npx.h
# Debugging
NPX_DEBUG opt_npx.h
STOP_NMI opt_cpu.h
+AGP_DEBUG opt_agp.h
# BPF just-in-time compiler
BPF_JITTER opt_bpf.h
diff --git a/sys/contrib/altq/altq/altq_subr.c b/sys/contrib/altq/altq/altq_subr.c
index a689fac..95ea81b 100644
--- a/sys/contrib/altq/altq/altq_subr.c
+++ b/sys/contrib/altq/altq/altq_subr.c
@@ -910,7 +910,7 @@ tsc_freq_changed(void *arg, const struct cf_level *level, int status)
if (status != 0)
return;
-#if (__FreeBSD_version >= 800050) && (defined(__amd64__) || defined(__i386__))
+#if (__FreeBSD_version >= 701102) && (defined(__amd64__) || defined(__i386__))
/* If TSC is P-state invariant, don't do anything. */
if (tsc_is_invariant)
return;
diff --git a/sys/crypto/via/padlock.c b/sys/crypto/via/padlock.c
index dc97a88..ccb0595 100644
--- a/sys/crypto/via/padlock.c
+++ b/sys/crypto/via/padlock.c
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rwlock.h>
#include <sys/malloc.h>
#include <sys/libkern.h>
-#if defined(__i386__) && !defined(PC98)
+#if defined(__amd64__) || (defined(__i386__) && !defined(PC98))
#include <machine/cpufunc.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
@@ -72,7 +72,7 @@ static int padlock_process(device_t, struct cryptop *crp, int hint __unused);
MALLOC_DEFINE(M_PADLOCK, "padlock_data", "PadLock Data");
static void
-padlock_identify(device_t *dev, device_t parent)
+padlock_identify(driver_t *drv, device_t parent)
{
/* NB: order 10 is so we get attached after h/w devices */
if (device_find_child(parent, "padlock", -1) == NULL &&
@@ -85,7 +85,7 @@ padlock_probe(device_t dev)
{
char capp[256];
-#if defined(__i386__) && !defined(PC98)
+#if defined(__amd64__) || (defined(__i386__) && !defined(PC98))
/* If there is no AES support, we has nothing to do here. */
if (!(via_feature_xcrypt & VIA_HAS_AES)) {
device_printf(dev, "No ACE support.\n");
diff --git a/sys/crypto/via/padlock_hash.c b/sys/crypto/via/padlock_hash.c
index 6c42103..ae43197 100644
--- a/sys/crypto/via/padlock_hash.c
+++ b/sys/crypto/via/padlock_hash.c
@@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/libkern.h>
#include <sys/endian.h>
-#if defined(__i386__) && !defined(PC98)
+#if defined(__amd64__) || (defined(__i386__) && !defined(PC98))
#include <machine/cpufunc.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
diff --git a/sys/dev/acpi_support/acpi_panasonic.c b/sys/dev/acpi_support/acpi_panasonic.c
index 2807baf..f922233 100644
--- a/sys/dev/acpi_support/acpi_panasonic.c
+++ b/sys/dev/acpi_support/acpi_panasonic.c
@@ -79,7 +79,7 @@ typedef int hkey_fn_t(ACPI_HANDLE, int, UINT32 *);
static int acpi_panasonic_probe(device_t dev);
static int acpi_panasonic_attach(device_t dev);
static int acpi_panasonic_detach(device_t dev);
-static void acpi_panasonic_shutdown(device_t dev);
+static int acpi_panasonic_shutdown(device_t dev);
static int acpi_panasonic_sysctl(SYSCTL_HANDLER_ARGS);
static ACPI_INTEGER acpi_panasonic_sinf(ACPI_HANDLE h, ACPI_INTEGER index);
static void acpi_panasonic_sset(ACPI_HANDLE h, ACPI_INTEGER index,
@@ -220,7 +220,7 @@ acpi_panasonic_detach(device_t dev)
return (0);
}
-static void
+static int
acpi_panasonic_shutdown(device_t dev)
{
struct acpi_panasonic_softc *sc;
@@ -230,6 +230,7 @@ acpi_panasonic_shutdown(device_t dev)
sc = device_get_softc(dev);
mute = 1;
hkey_sound_mute(sc->handle, HKEY_SET, &mute);
+ return (0);
}
static int
diff --git a/sys/dev/acpica/acpi_battery.c b/sys/dev/acpica/acpi_battery.c
index f289b2b..2e8c7a4 100644
--- a/sys/dev/acpica/acpi_battery.c
+++ b/sys/dev/acpica/acpi_battery.c
@@ -197,7 +197,7 @@ acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
* is 0 (due to some error reading the battery), skip this
* conversion.
*/
- if (bif->units == ACPI_BIF_UNITS_MA && bif->dvol != 0) {
+ if (bif->units == ACPI_BIF_UNITS_MA && bif->dvol != 0 && dev == NULL) {
bst[i].rate = (bst[i].rate * bif->dvol) / 1000;
bst[i].cap = (bst[i].cap * bif->dvol) / 1000;
bif->lfcap = (bif->lfcap * bif->dvol) / 1000;
diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c
index 2865dea..495ae20 100644
--- a/sys/dev/acpica/acpi_pcib_acpi.c
+++ b/sys/dev/acpica/acpi_pcib_acpi.c
@@ -68,10 +68,11 @@ static int acpi_pcib_read_ivar(device_t dev, device_t child,
int which, uintptr_t *result);
static int acpi_pcib_write_ivar(device_t dev, device_t child,
int which, uintptr_t value);
-static uint32_t acpi_pcib_read_config(device_t dev, int bus, int slot,
- int func, int reg, int bytes);
-static void acpi_pcib_write_config(device_t dev, int bus, int slot,
- int func, int reg, uint32_t data, int bytes);
+static uint32_t acpi_pcib_read_config(device_t dev, u_int bus,
+ u_int slot, u_int func, u_int reg, int bytes);
+static void acpi_pcib_write_config(device_t dev, u_int bus,
+ u_int slot, u_int func, u_int reg, uint32_t data,
+ int bytes);
static int acpi_pcib_acpi_route_interrupt(device_t pcib,
device_t dev, int pin);
static int acpi_pcib_alloc_msi(device_t pcib, device_t dev,
@@ -297,15 +298,15 @@ acpi_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
}
static uint32_t
-acpi_pcib_read_config(device_t dev, int bus, int slot, int func, int reg,
- int bytes)
+acpi_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
+ u_int reg, int bytes)
{
return (pci_cfgregread(bus, slot, func, reg, bytes));
}
static void
-acpi_pcib_write_config(device_t dev, int bus, int slot, int func, int reg,
- uint32_t data, int bytes)
+acpi_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+ u_int reg, uint32_t data, int bytes)
{
pci_cfgregwrite(bus, slot, func, reg, data, bytes);
}
diff --git a/sys/dev/adb/adb_kbd.c b/sys/dev/adb/adb_kbd.c
index 115b35d..22ab97d 100644
--- a/sys/dev/adb/adb_kbd.c
+++ b/sys/dev/adb/adb_kbd.c
@@ -72,6 +72,9 @@ struct adb_kbd_softc {
int have_led_control;
uint8_t buffer[8];
+#ifdef AKBD_EMULATE_ATKBD
+ uint8_t at_buffered_char[2];
+#endif
volatile int buffers;
struct callout sc_repeater;
@@ -105,6 +108,17 @@ static devclass_t adb_kbd_devclass;
DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
+#ifdef AKBD_EMULATE_ATKBD
+
+#define SCAN_PRESS 0x000
+#define SCAN_RELEASE 0x080
+#define SCAN_PREFIX_E0 0x100
+#define SCAN_PREFIX_E1 0x200
+#define SCAN_PREFIX_CTL 0x400
+#define SCAN_PREFIX_SHIFT 0x800
+#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
+ SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
+
static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
@@ -114,6 +128,47 @@ static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
+static int
+keycode2scancode(int keycode, int shift, int up)
+{
+ static const int scan[] = {
+ /* KP enter, right ctrl, KP divide */
+ 0x1c , 0x1d , 0x35 ,
+ /* print screen */
+ 0x37 | SCAN_PREFIX_SHIFT,
+ /* right alt, home, up, page up, left, right, end */
+ 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
+ /* down, page down, insert, delete */
+ 0x50, 0x51, 0x52, 0x53,
+ /* pause/break (see also below) */
+ 0x46,
+ /*
+ * MS: left window, right window, menu
+ * also Sun: left meta, right meta, compose
+ */
+ 0x5b, 0x5c, 0x5d,
+ /* Sun type 6 USB */
+ /* help, stop, again, props, undo, front, copy */
+ 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
+ /* open, paste, find, cut, audiomute, audiolower, audioraise */
+ 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
+ /* power */
+ 0x20
+ };
+ int scancode;
+
+ scancode = keycode;
+ if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0])))
+ scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
+ /* pause/break */
+ if ((keycode == 104) && !(shift & CTLS))
+ scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
+ if (shift & SHIFTS)
+ scancode &= ~SCAN_PREFIX_SHIFT;
+ return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
+}
+#endif
+
/* keyboard driver declaration */
static int akbd_configure(int flags);
static kbd_probe_t akbd_probe;
@@ -468,6 +523,13 @@ akbd_check(keyboard_t *kbd)
sc = (struct adb_kbd_softc *)(kbd);
mtx_lock(&sc->sc_mutex);
+#ifdef AKBD_EMULATE_ATKBD
+ if (sc->at_buffered_char[0]) {
+ mtx_unlock(&sc->sc_mutex);
+ return (TRUE);
+ }
+#endif
+
if (sc->buffers > 0) {
mtx_unlock(&sc->sc_mutex);
return (TRUE);
@@ -481,36 +543,89 @@ static u_int
akbd_read_char(keyboard_t *kbd, int wait)
{
struct adb_kbd_softc *sc;
- uint8_t adb_code, final_scancode;
+ uint16_t key;
+ uint8_t adb_code;
int i;
sc = (struct adb_kbd_softc *)(kbd);
mtx_lock(&sc->sc_mutex);
- if (!sc->buffers && wait)
- cv_wait(&sc->sc_cv,&sc->sc_mutex);
- if (!sc->buffers) {
- mtx_unlock(&sc->sc_mutex);
- return (0);
+#if defined(AKBD_EMULATE_ATKBD)
+ if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
+ key = sc->at_buffered_char[0];
+ if (key & SCAN_PREFIX) {
+ sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
+ key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
+ } else {
+ sc->at_buffered_char[0] = sc->at_buffered_char[1];
+ sc->at_buffered_char[1] = 0;
}
- adb_code = sc->buffer[0];
+ mtx_unlock(&sc->sc_mutex);
- for (i = 1; i < sc->buffers; i++)
- sc->buffer[i-1] = sc->buffer[i];
+ return (key);
+ }
+#endif
- sc->buffers--;
- mtx_unlock(&sc->sc_mutex);
+ if (!sc->buffers && wait)
+ cv_wait(&sc->sc_cv,&sc->sc_mutex);
+
+ if (!sc->buffers) {
+ mtx_unlock(&sc->sc_mutex);
+ return (0);
+ }
+
+ adb_code = sc->buffer[0];
+
+ for (i = 1; i < sc->buffers; i++)
+ sc->buffer[i-1] = sc->buffer[i];
+
+ sc->buffers--;
#ifdef AKBD_EMULATE_ATKBD
- final_scancode = adb_to_at_scancode_map[adb_code & 0x7f];
- final_scancode |= adb_code & 0x80;
+ key = adb_to_at_scancode_map[adb_code & 0x7f];
+ if (sc->sc_mode == K_CODE) {
+ /* Add the key-release bit */
+ key |= adb_code & 0x80;
+ } else if (sc->sc_mode == K_RAW) {
+ /*
+ * In the raw case, we have to emulate the gross
+ * variable-length AT keyboard thing. Since this code
+ * is copied from sunkbd, which is the same code
+ * as ukbd, it might be nice to have this centralized.
+ */
+
+ key = keycode2scancode(key,
+ 0, adb_code & 0x80);
+
+ if (key & SCAN_PREFIX) {
+ if (key & SCAN_PREFIX_CTL) {
+ sc->at_buffered_char[0] =
+ 0x1d | (key & SCAN_RELEASE);
+ sc->at_buffered_char[1] =
+ key & ~SCAN_PREFIX;
+ } else if (key & SCAN_PREFIX_SHIFT) {
+ sc->at_buffered_char[0] =
+ 0x2a | (key & SCAN_RELEASE);
+ sc->at_buffered_char[1] =
+ key & ~SCAN_PREFIX_SHIFT;
+ } else {
+ sc->at_buffered_char[0] =
+ key & ~SCAN_PREFIX;
+ sc->at_buffered_char[1] = 0;
+ }
+
+ key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
+ }
+ }
#else
- final_scancode = adb_code;
+ key = adb_code;
#endif
- return (final_scancode);
+ mtx_unlock(&sc->sc_mutex);
+
+ return (key);
}
static int
@@ -648,6 +763,20 @@ static int akbd_lock(keyboard_t *kbd, int lock)
static void akbd_clear_state(keyboard_t *kbd)
{
+ struct adb_kbd_softc *sc;
+
+ sc = (struct adb_kbd_softc *)(kbd);
+
+ mtx_lock(&sc->sc_mutex);
+
+ sc->buffers = 0;
+ callout_stop(&sc->sc_repeater);
+
+#if defined(AKBD_EMULATE_ATKBD)
+ sc->at_buffered_char[0] = 0;
+ sc->at_buffered_char[1] = 0;
+#endif
+ mtx_unlock(&sc->sc_mutex);
}
static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
diff --git a/sys/dev/adb/adb_mouse.c b/sys/dev/adb/adb_mouse.c
index bba38c2..f602f1c 100644
--- a/sys/dev/adb/adb_mouse.c
+++ b/sys/dev/adb/adb_mouse.c
@@ -46,7 +46,7 @@
#include "adb.h"
-#define CDEV_GET_SOFTC(x) devclass_get_softc(adb_mouse_devclass, minor(x) & 0x1f)
+#define CDEV_GET_SOFTC(x) (x)->si_drv1
static int adb_mouse_probe(device_t dev);
static int adb_mouse_attach(device_t dev);
@@ -236,6 +236,7 @@ adb_mouse_attach(device_t dev)
sc->cdev = make_dev(&ams_cdevsw, device_get_unit(dev),
UID_ROOT, GID_OPERATOR, 0644, "ams%d",
device_get_unit(dev));
+ sc->cdev->si_drv1 = sc;
adb_set_autopoll(dev,1);
diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c
index 345a01f..f6d8e42 100644
--- a/sys/dev/ae/if_ae.c
+++ b/sys/dev/ae/if_ae.c
@@ -105,7 +105,7 @@ static void ae_phy_init(ae_softc_t *sc);
static int ae_reset(ae_softc_t *sc);
static void ae_init(void *arg);
static int ae_init_locked(ae_softc_t *sc);
-static unsigned int ae_detach(device_t dev);
+static int ae_detach(device_t dev);
static int ae_miibus_readreg(device_t dev, int phy, int reg);
static int ae_miibus_writereg(device_t dev, int phy, int reg, int val);
static void ae_miibus_statchg(device_t dev);
@@ -746,7 +746,7 @@ ae_init_locked(ae_softc_t *sc)
return (0);
}
-static unsigned int
+static int
ae_detach(device_t dev)
{
struct ae_softc *sc;
diff --git a/sys/dev/agp/agp.c b/sys/dev/agp/agp.c
index 6d749ef..1e61871 100644
--- a/sys/dev/agp/agp.c
+++ b/sys/dev/agp/agp.c
@@ -27,6 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_agp.h"
#include "opt_bus.h"
#include <sys/param.h>
@@ -554,7 +555,7 @@ agp_generic_bind_memory(device_t dev, struct agp_memory *mem,
*/
m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i),
VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
- AGP_DPF("found page pa=%#x\n", VM_PAGE_TO_PHYS(m));
+ AGP_DPF("found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m));
}
VM_OBJECT_UNLOCK(mem->am_obj);
@@ -585,8 +586,8 @@ agp_generic_bind_memory(device_t dev, struct agp_memory *mem,
for (j = 0; j < PAGE_SIZE && i + j < mem->am_size;
j += AGP_PAGE_SIZE) {
vm_offset_t pa = VM_PAGE_TO_PHYS(m) + j;
- AGP_DPF("binding offset %#x to pa %#x\n",
- offset + i + j, pa);
+ AGP_DPF("binding offset %#jx to pa %#jx\n",
+ (uintmax_t)offset + i + j, (uintmax_t)pa);
error = AGP_BIND_PAGE(dev, offset + i + j, pa);
if (error) {
/*
diff --git a/sys/dev/agp/agp_amd64.c b/sys/dev/agp/agp_amd64.c
index 3269d5f..8151f48 100644
--- a/sys/dev/agp/agp_amd64.c
+++ b/sys/dev/agp/agp_amd64.c
@@ -167,14 +167,16 @@ agp_amd64_attach(device_t dev)
{
struct agp_amd64_softc *sc = device_get_softc(dev);
struct agp_gatt *gatt;
+ uint32_t devid;
int i, n, error;
- for (i = 0, n = 0; i < PCI_SLOTMAX && n < AMD64_MAX_MCTRL; i++)
- if (pci_cfgregread(0, i, 3, 0, 4) == 0x11031022) {
+ for (i = 0, n = 0; i < PCI_SLOTMAX && n < AMD64_MAX_MCTRL; i++) {
+ devid = pci_cfgregread(0, i, 3, 0, 4);
+ if (devid == 0x11031022 || devid == 0x12031022) {
sc->mctrl[n] = i;
n++;
}
-
+ }
if (n == 0)
return (ENXIO);
diff --git a/sys/dev/agp/agp_via.c b/sys/dev/agp/agp_via.c
index 9b8bbc8..dedc9da 100644
--- a/sys/dev/agp/agp_via.c
+++ b/sys/dev/agp/agp_via.c
@@ -85,8 +85,14 @@ agp_via_match(device_t dev)
return ("VIA 3296 (P4M800) host to PCI bridge");
case 0x03051106:
return ("VIA 82C8363 (Apollo KT133x/KM133) host to PCI bridge");
+ case 0x03141106:
+ return ("VIA 3314 (P4M800CE) host to PCI bridge");
case 0x03241106:
return ("VIA VT3324 (CX700) host to PCI bridge");
+ case 0x03271106:
+ return ("VIA 3327 (P4M890) host to PCI bridge");
+ case 0x03641106:
+ return ("VIA 3364 (P4M900) host to PCI bridge");
case 0x03911106:
return ("VIA 8371 (Apollo KX133) host to PCI bridge");
case 0x05011106:
@@ -168,7 +174,10 @@ agp_via_attach(device_t dev)
case 0x02591106:
case 0x02691106:
case 0x02961106:
+ case 0x03141106:
case 0x03241106:
+ case 0x03271106:
+ case 0x03641106:
case 0x31231106:
case 0x31681106:
case 0x31891106:
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index ae9fc09..1d22322 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -2989,7 +2989,7 @@ an_watchdog(struct ifnet *ifp)
return;
}
-void
+int
an_shutdown(device_t dev)
{
struct an_softc *sc;
@@ -2998,7 +2998,7 @@ an_shutdown(device_t dev)
an_stop(sc);
sc->an_gone = 1;
- return;
+ return 0;
}
void
diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h
index fb2d6a7..ec0ad2b 100644
--- a/sys/dev/an/if_anreg.h
+++ b/sys/dev/an/if_anreg.h
@@ -511,7 +511,7 @@ int an_alloc_aux_memory (device_t, int, int);
int an_alloc_irq (device_t, int, int);
int an_pci_probe (device_t);
int an_probe (device_t);
-void an_shutdown (device_t);
+int an_shutdown (device_t);
void an_resume (device_t);
int an_attach (struct an_softc *, int, int);
int an_detach (device_t);
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 203eb64..27d4210 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -182,13 +182,14 @@ ad_detach(device_t dev)
return 0;
}
-static void
+static int
ad_shutdown(device_t dev)
{
struct ata_device *atadev = device_get_softc(dev);
if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
+ return 0;
}
static int
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index c8ae79dc..7085460 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -434,7 +434,8 @@ ata_completed(void *context, int dummy)
printf("\n");
}
- if ((request->u.atapi.sense.key & ATA_SENSE_KEY_MASK ?
+ if (!request->result &&
+ (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK ?
request->u.atapi.sense.key & ATA_SENSE_KEY_MASK :
request->error))
request->result = EIO;
diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c
index d8f0b86..62e5251 100644
--- a/sys/dev/ata/atapi-cam.c
+++ b/sys/dev/ata/atapi-cam.c
@@ -91,7 +91,7 @@ struct atapi_hcb {
enum reinit_reason { BOOT_ATTACH, ATTACH, RESET };
/* Device methods */
-static void atapi_cam_identify(device_t *dev, device_t parent);
+static void atapi_cam_identify(driver_t *dev, device_t parent);
static int atapi_cam_probe(device_t dev);
static int atapi_cam_attach(device_t dev);
static int atapi_cam_detach(device_t dev);
@@ -144,7 +144,7 @@ MODULE_DEPEND(atapicam, ata, 1, 1, 1);
MODULE_DEPEND(atapicam, cam, 1, 1, 1);
static void
-atapi_cam_identify(device_t *dev, device_t parent)
+atapi_cam_identify(driver_t *driver, device_t parent)
{
struct atapi_xpt_softc *scp =
malloc (sizeof (struct atapi_xpt_softc), M_ATACAM, M_NOWAIT|M_ZERO);
@@ -254,6 +254,10 @@ atapi_cam_detach(device_t dev)
struct atapi_xpt_softc *scp = device_get_softc(dev);
mtx_lock(&scp->state_lock);
+ if (xpt_sim_opened(scp->sim)) {
+ mtx_unlock(&scp->state_lock);
+ return (EBUSY);
+ }
xpt_freeze_simq(scp->sim, 1 /*count*/);
scp->flags |= DETACHING;
mtx_unlock(&scp->state_lock);
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index abd1db4..5d6208f 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -143,13 +143,14 @@ acd_detach(device_t dev)
return 0;
}
-static void
+static int
acd_shutdown(device_t dev)
{
struct ata_device *atadev = device_get_softc(dev);
if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
+ return 0;
}
static int
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index 7b3c8b7..e9f3021 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -132,13 +132,14 @@ afd_detach(device_t dev)
return 0;
}
-static void
+static int
afd_shutdown(device_t dev)
{
struct ata_device *atadev = device_get_softc(dev);
if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
+ return 0;
}
static int
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index 947bacf..734f012 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -175,13 +175,14 @@ ast_detach(device_t dev)
return 0;
}
-static void
+static int
ast_shutdown(device_t dev)
{
struct ata_device *atadev = device_get_softc(dev);
if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
+ return 0;
}
static int
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 668ace7..c1eac72 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -78,6 +78,15 @@ ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
return AH_NULL;
}
+/*
+ * Return the mask of available modes based on the hardware capabilities.
+ */
+u_int
+ath_hal_getwirelessmodes(struct ath_hal*ah)
+{
+ return ath_hal_getWirelessModes(ah);
+}
+
/* linker set of registered RF backends */
OS_SET_DECLARE(ah_rfs, struct ath_hal_rf);
@@ -152,8 +161,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
kbps = rates->info[rateix].rateKbps;
/*
* index can be invalid duting dynamic Turbo transitions.
+ * XXX
*/
- if(kbps == 0) return 0;
+ if (kbps == 0)
+ return 0;
switch (rates->info[rateix].phy) {
case IEEE80211_T_CCK:
@@ -187,8 +198,8 @@ ath_hal_computetxtime(struct ath_hal *ah,
#define OFDM_PLCP_BITS_QUARTER 22
#define OFDM_SYMBOL_TIME_QUARTER 16
- if (AH_PRIVATE(ah)->ah_curchan &&
- IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ if (AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
+ IEEE80211_IS_CHAN_QUARTER(AH_PRIVATE(ah)->ah_curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
HALASSERT(bitsPerSymbol != 0);
@@ -197,8 +208,8 @@ ath_hal_computetxtime(struct ath_hal *ah,
txTime = OFDM_SIFS_TIME_QUARTER
+ OFDM_PREAMBLE_TIME_QUARTER
+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
- } else if (AH_PRIVATE(ah)->ah_curchan &&
- IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ } else if (AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
+ IEEE80211_IS_CHAN_HALF(AH_PRIVATE(ah)->ah_curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
HALASSERT(bitsPerSymbol != 0);
@@ -252,71 +263,6 @@ ath_hal_computetxtime(struct ath_hal *ah,
return txTime;
}
-static __inline int
-mapgsm(u_int freq, u_int flags)
-{
- freq *= 10;
- if (flags & CHANNEL_QUARTER)
- freq += 5;
- else if (flags & CHANNEL_HALF)
- freq += 10;
- else
- freq += 20;
- return (freq - 24220) / 5;
-}
-
-static __inline int
-mappsb(u_int freq, u_int flags)
-{
- return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
-}
-
-/*
- * Convert GHz frequency to IEEE channel number.
- */
-int
-ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
-{
- if (flags & CHANNEL_2GHZ) { /* 2GHz band */
- if (freq == 2484)
- return 14;
- if (freq < 2484) {
- if (ath_hal_isgsmsku(ah))
- return mapgsm(freq, flags);
- return ((int)freq - 2407) / 5;
- } else
- return 15 + ((freq - 2512) / 20);
- } else if (flags & CHANNEL_5GHZ) {/* 5Ghz band */
- if (ath_hal_ispublicsafetysku(ah) &&
- IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
- return mappsb(freq, flags);
- } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
- return (freq - 4000) / 5;
- } else {
- return (freq - 5000) / 5;
- }
- } else { /* either, guess */
- if (freq == 2484)
- return 14;
- if (freq < 2484) {
- if (ath_hal_isgsmsku(ah))
- return mapgsm(freq, flags);
- return ((int)freq - 2407) / 5;
- }
- if (freq < 5000) {
- if (ath_hal_ispublicsafetysku(ah) &&
- IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
- return mappsb(freq, flags);
- } else if (freq > 4900) {
- return (freq - 4000) / 5;
- } else {
- return 15 + ((freq - 2512) / 20);
- }
- }
- return (freq - 5000) / 5;
- }
-}
-
typedef enum {
WIRELESS_MODE_11a = 0,
WIRELESS_MODE_TURBO = 1,
@@ -328,15 +274,15 @@ typedef enum {
} WIRELESS_MODE;
static WIRELESS_MODE
-ath_hal_chan2wmode(struct ath_hal *ah, const HAL_CHANNEL *chan)
+ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
- if (IS_CHAN_CCK(chan))
+ if (IEEE80211_IS_CHAN_B(chan))
return WIRELESS_MODE_11b;
- if (IS_CHAN_G(chan))
+ if (IEEE80211_IS_CHAN_G(chan))
return WIRELESS_MODE_11g;
- if (IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_108G(chan))
return WIRELESS_MODE_108g;
- if (IS_CHAN_TURBO(chan))
+ if (IEEE80211_IS_CHAN_TURBO(chan))
return WIRELESS_MODE_TURBO;
return WIRELESS_MODE_11a;
}
@@ -350,17 +296,17 @@ static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 };
u_int
ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
{
- const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
u_int clks;
/* NB: ah_curchan may be null when called attach time */
if (c != AH_NULL) {
clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
- if (IS_CHAN_HT40(c))
+ if (IEEE80211_IS_CHAN_HT40(c))
clks <<= 1;
- else if (IS_CHAN_HALF_RATE(c))
+ else if (IEEE80211_IS_CHAN_HALF(c))
clks >>= 1;
- else if (IS_CHAN_QUARTER_RATE(c))
+ else if (IEEE80211_IS_CHAN_QUARTER(c))
clks >>= 2;
} else
clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
@@ -370,17 +316,17 @@ ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
u_int
ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
{
- const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
u_int usec;
/* NB: ah_curchan may be null when called attach time */
if (c != AH_NULL) {
usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
- if (IS_CHAN_HT40(c))
+ if (IEEE80211_IS_CHAN_HT40(c))
usec >>= 1;
- else if (IS_CHAN_HALF_RATE(c))
+ else if (IEEE80211_IS_CHAN_HALF(c))
usec <<= 1;
- else if (IS_CHAN_QUARTER_RATE(c))
+ else if (IEEE80211_IS_CHAN_QUARTER(c))
usec <<= 2;
} else
usec = clks / CLOCK_RATE[WIRELESS_MODE_11b];
@@ -505,11 +451,7 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
}
return HAL_ENOTSUPP;
case HAL_CAP_11D:
-#ifdef AH_SUPPORT_11D
return HAL_OK;
-#else
- return HAL_ENOTSUPP;
-#endif
case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */
return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_HT:
@@ -764,7 +706,7 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 };
* implement the ah_getChanNoise method.
*/
int16_t
-ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan)
+ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
HAL_CHANNEL_INTERNAL *ichan;
@@ -772,7 +714,7 @@ ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan)
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
return 0;
}
if (ichan->rawNoiseFloor == 0) {
@@ -811,8 +753,8 @@ ath_hal_process_noisefloor(struct ath_hal *ah)
c = &AH_PRIVATE(ah)->ah_channels[i];
if (c->rawNoiseFloor >= 0)
continue;
- mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) c);
- HALASSERT(mode < WIRELESS_MODE_MAX);
+ /* XXX can't identify proper mode */
+ mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g;
nf = c->rawNoiseFloor + NOISE_FLOOR[mode] +
ath_hal_getNfAdjust(ah, c);
if (IS_CHAN_5GHZ(c)) {
@@ -838,9 +780,8 @@ ath_hal_process_noisefloor(struct ath_hal *ah)
/* Apply correction factor */
c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) +
(IS_CHAN_5GHZ(c) ? correct5 : correct2);
- HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u/0x%x raw nf %d adjust %d\n",
- c->channel, c->channelFlags, c->rawNoiseFloor,
- c->noiseFloorAdjust);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n",
+ c->channel, c->rawNoiseFloor, c->noiseFloorAdjust);
}
}
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index 52d6607..f39db8c 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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.h,v 1.15 2008/11/15 03:43:50 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AH_H_
@@ -63,6 +63,8 @@ typedef enum {
HAL_ENOTSUPP = 13, /* Hardware revision not supported */
HAL_ESELFTEST = 14, /* Hardware self-test failed */
HAL_EINPROGRESS = 15, /* Operation incomplete */
+ HAL_EEBADREG = 16, /* EEPROM invalid regulatory contents */
+ HAL_EEBADCC = 17, /* EEPROM invalid country code */
} HAL_STATUS;
typedef enum {
@@ -362,64 +364,8 @@ typedef enum {
HAL_RFGAIN_NEED_CHANGE = 2
} HAL_RFGAIN;
-/*
- * Channels are specified by frequency.
- */
-typedef struct {
- uint32_t channelFlags; /* see below */
- uint16_t channel; /* setting in Mhz */
- uint8_t privFlags;
- int8_t maxRegTxPower; /* max regulatory tx power in dBm */
- int8_t maxTxPower; /* max true tx power in 0.5 dBm */
- int8_t minTxPower; /* min true tx power in 0.5 dBm */
-} HAL_CHANNEL;
-
-/* channelFlags */
-#define CHANNEL_CW_INT 0x00002 /* CW interference detected on channel */
-#define CHANNEL_TURBO 0x00010 /* Turbo Channel */
-#define CHANNEL_CCK 0x00020 /* CCK channel */
-#define CHANNEL_OFDM 0x00040 /* OFDM channel */
-#define CHANNEL_2GHZ 0x00080 /* 2 GHz spectrum channel */
-#define CHANNEL_5GHZ 0x00100 /* 5 GHz spectrum channel */
-#define CHANNEL_PASSIVE 0x00200 /* Only passive scan allowed in the channel */
-#define CHANNEL_DYN 0x00400 /* dynamic CCK-OFDM channel */
-#define CHANNEL_STURBO 0x02000 /* Static turbo, no 11a-only usage */
-#define CHANNEL_HALF 0x04000 /* Half rate channel */
-#define CHANNEL_QUARTER 0x08000 /* Quarter rate channel */
-#define CHANNEL_HT20 0x10000 /* 11n 20MHZ channel */
-#define CHANNEL_HT40PLUS 0x20000 /* 11n 40MHZ channel w/ ext chan above */
-#define CHANNEL_HT40MINUS 0x40000 /* 11n 40MHZ channel w/ ext chan below */
-
-/* privFlags */
-#define CHANNEL_INTERFERENCE 0x01 /* Software use: channel interference
- used for as AR as well as RADAR
- interference detection */
-#define CHANNEL_DFS 0x02 /* DFS required on channel */
-#define CHANNEL_4MS_LIMIT 0x04 /* 4msec packet limit on this channel */
-#define CHANNEL_DFS_CLEAR 0x08 /* if channel has been checked for DFS */
-
-#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
-#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
-#define CHANNEL_PUREG (CHANNEL_2GHZ|CHANNEL_OFDM)
-#ifdef notdef
-#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_DYN)
-#else
-#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
-#endif
-#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define CHANNEL_ST (CHANNEL_T|CHANNEL_STURBO)
-#define CHANNEL_108G (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define CHANNEL_108A CHANNEL_T
-#define CHANNEL_G_HT20 (CHANNEL_G|CHANNEL_HT20)
-#define CHANNEL_A_HT20 (CHANNEL_A|CHANNEL_HT20)
-#define CHANNEL_G_HT40PLUS (CHANNEL_G|CHANNEL_HT40PLUS)
-#define CHANNEL_G_HT40MINUS (CHANNEL_G|CHANNEL_HT40MINUS)
-#define CHANNEL_A_HT40PLUS (CHANNEL_A|CHANNEL_HT40PLUS)
-#define CHANNEL_A_HT40MINUS (CHANNEL_A|CHANNEL_HT40MINUS)
-#define CHANNEL_ALL \
- (CHANNEL_OFDM | CHANNEL_CCK| CHANNEL_2GHZ | CHANNEL_5GHZ | \
- CHANNEL_TURBO | CHANNEL_HT20 | CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)
-#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL &~ CHANNEL_TURBO)
+typedef uint16_t HAL_CTRY_CODE; /* country code */
+typedef uint16_t HAL_REG_DOMAIN; /* regulatory domain code */
#define HAL_ANTENNA_MIN_MODE 0
#define HAL_ANTENNA_FIXED_A 1
@@ -434,14 +380,6 @@ typedef struct {
uint32_t beacons;
} HAL_MIB_STATS;
-typedef uint16_t HAL_CTRY_CODE; /* country code */
-typedef uint16_t HAL_REG_DOMAIN; /* regulatory domain code */
-
-enum {
- CTRY_DEBUG = 0x1ff, /* debug country code */
- CTRY_DEFAULT = 0 /* default country code */
-};
-
enum {
HAL_MODE_11A = 0x001, /* 11a channels */
HAL_MODE_TURBO = 0x002, /* 11a turbo-only channels */
@@ -630,6 +568,7 @@ typedef struct {
struct ath_desc;
struct ath_tx_status;
struct ath_rx_status;
+struct ieee80211_channel;
/*
* Hardware Access Layer (HAL) API.
@@ -665,16 +604,18 @@ struct ath_hal {
/* Reset functions */
HAL_BOOL __ahdecl(*ah_reset)(struct ath_hal *, HAL_OPMODE,
- HAL_CHANNEL *, HAL_BOOL bChannelChange,
- HAL_STATUS *status);
+ struct ieee80211_channel *,
+ HAL_BOOL bChannelChange, HAL_STATUS *status);
HAL_BOOL __ahdecl(*ah_phyDisable)(struct ath_hal *);
HAL_BOOL __ahdecl(*ah_disable)(struct ath_hal *);
void __ahdecl(*ah_setPCUConfig)(struct ath_hal *);
- HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, HAL_CHANNEL *,
- HAL_BOOL *);
- HAL_BOOL __ahdecl(*ah_perCalibrationN)(struct ath_hal *, HAL_CHANNEL *,
- u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
- HAL_BOOL __ahdecl(*ah_resetCalValid)(struct ath_hal *, HAL_CHANNEL *);
+ HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*,
+ struct ieee80211_channel *, HAL_BOOL *);
+ HAL_BOOL __ahdecl(*ah_perCalibrationN)(struct ath_hal *,
+ struct ieee80211_channel *, u_int chainMask,
+ HAL_BOOL longCal, HAL_BOOL *isCalDone);
+ HAL_BOOL __ahdecl(*ah_resetCalValid)(struct ath_hal *,
+ const struct ieee80211_channel *);
HAL_BOOL __ahdecl(*ah_setTxPowerLimit)(struct ath_hal *, uint32_t);
/* Transmit functions */
@@ -735,7 +676,8 @@ struct ath_hal {
struct ath_desc *next, uint64_t tsf,
struct ath_rx_status *);
void __ahdecl(*ah_rxMonitor)(struct ath_hal *,
- const HAL_NODE_STATS *, HAL_CHANNEL *);
+ const HAL_NODE_STATS *,
+ const struct ieee80211_channel *);
void __ahdecl(*ah_procMibEvent)(struct ath_hal *,
const HAL_NODE_STATS *);
@@ -804,7 +746,8 @@ struct ath_hal {
HAL_BOOL __ahdecl(*ah_setPowerMode)(struct ath_hal*,
HAL_POWER_MODE mode, int setChip);
HAL_POWER_MODE __ahdecl(*ah_getPowerMode)(struct ath_hal*);
- int16_t __ahdecl(*ah_getChanNoise)(struct ath_hal *, HAL_CHANNEL *);
+ int16_t __ahdecl(*ah_getChanNoise)(struct ath_hal *,
+ const struct ieee80211_channel *);
/* Beacon Management Functions */
void __ahdecl(*ah_setBeaconTimers)(struct ath_hal*,
@@ -847,53 +790,64 @@ extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS* status);
/*
- * Return a list of channels available for use with the hardware.
- * The list is based on what the hardware is capable of, the specified
- * country code, the modeSelect mask, and whether or not outdoor
- * channels are to be permitted.
+ * Regulatory interfaces. Drivers should use ath_hal_init_channels to
+ * request a set of channels for a particular country code and/or
+ * regulatory domain. If CTRY_DEFAULT and SKU_NONE are specified then
+ * this list is constructed according to the contents of the EEPROM.
+ * ath_hal_getchannels acts similarly but does not alter the operating
+ * state; this can be used to collect information for a particular
+ * regulatory configuration. Finally ath_hal_set_channels installs a
+ * channel list constructed outside the driver. The HAL will adopt the
+ * channel list and setup internal state according to the specified
+ * regulatory configuration (e.g. conformance test limits).
*
- * The channel list is returned in the supplied array. maxchans
- * defines the maximum size of this array. nchans contains the actual
- * number of channels returned. If a problem occurred or there were
- * no channels that met the criteria then AH_FALSE is returned.
+ * For all interfaces the channel list is returned in the supplied array.
+ * maxchans defines the maximum size of this array. nchans contains the
+ * actual number of channels returned. If a problem occurred then a
+ * status code != HAL_OK is returned.
*/
-extern HAL_BOOL __ahdecl ath_hal_init_channels(struct ath_hal *,
- HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
- uint8_t *regclassids, u_int maxregids, u_int *nregids,
- HAL_CTRY_CODE cc, u_int modeSelect,
- HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels);
+struct ieee80211_channel;
/*
- * Calibrate noise floor data following a channel scan or similar.
- * This must be called prior retrieving noise floor data.
+ * Return a list of channels according to the specified regulatory.
*/
-extern void __ahdecl ath_hal_process_noisefloor(struct ath_hal *ah);
+extern HAL_STATUS __ahdecl ath_hal_getchannels(struct ath_hal *,
+ struct ieee80211_channel *chans, u_int maxchans, int *nchans,
+ u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
+ HAL_BOOL enableExtendedChannels);
/*
- * Return bit mask of wireless modes supported by the hardware.
+ * Return a list of channels and install it as the current operating
+ * regulatory list.
*/
-extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*, HAL_CTRY_CODE);
+extern HAL_STATUS __ahdecl ath_hal_init_channels(struct ath_hal *,
+ struct ieee80211_channel *chans, u_int maxchans, int *nchans,
+ u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN rd,
+ HAL_BOOL enableExtendedChannels);
/*
- * Calculate the transmit duration of a frame.
+ * Install the list of channels as the current operating regulatory
+ * and setup related state according to the country code and sku.
*/
-extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *,
- const HAL_RATE_TABLE *rates, uint32_t frameLen,
- uint16_t rateix, HAL_BOOL shortPreamble);
+extern HAL_STATUS __ahdecl ath_hal_set_channels(struct ath_hal *,
+ struct ieee80211_channel *chans, int nchans,
+ HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn);
/*
- * Return if device is public safety.
+ * Calibrate noise floor data following a channel scan or similar.
+ * This must be called prior retrieving noise floor data.
*/
-extern HAL_BOOL __ahdecl ath_hal_ispublicsafetysku(struct ath_hal *);
+extern void __ahdecl ath_hal_process_noisefloor(struct ath_hal *ah);
/*
- * Return if device is operating in 900 MHz band.
+ * Return bit mask of wireless modes supported by the hardware.
*/
-extern HAL_BOOL ath_hal_isgsmsku(struct ath_hal *);
+extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*);
/*
- * Convert between IEEE channel number and channel frequency
- * using the specified channel flags; e.g. CHANNEL_2GHZ.
+ * Calculate the transmit duration of a frame.
*/
-extern int __ahdecl ath_hal_mhz2ieee(struct ath_hal *, u_int mhz, u_int flags);
+extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *,
+ const HAL_RATE_TABLE *rates, uint32_t frameLen,
+ uint16_t rateix, HAL_BOOL shortPreamble);
#endif /* _ATH_AH_H_ */
diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h
index 9feb295..6f7a60a 100644
--- a/sys/dev/ath/ath_hal/ah_internal.h
+++ b/sys/dev/ath/ath_hal/ah_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -27,6 +27,8 @@
#define AH_MIN(a,b) ((a)<(b)?(a):(b))
#define AH_MAX(a,b) ((a)>(b)?(a):(b))
+#include <net80211/_ieee80211.h>
+
#ifndef NBBY
#define NBBY 8 /* number of bits/byte */
#endif
@@ -108,32 +110,44 @@ OS_DATA_SET(ah_rfs, _name##_rf)
struct ath_hal_rf *ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode);
/*
- * Internal form of a HAL_CHANNEL. Note that the structure
- * must be defined such that you can cast references to a
- * HAL_CHANNEL so don't shuffle the first two members.
+ * Maximum number of internal channels. Entries are per unique
+ * frequency so this might be need to be increased to handle all
+ * usage cases; typically no more than 32 are really needed but
+ * dynamically allocating the data structures is a bit painful
+ * right now.
+ */
+#ifndef AH_MAXCHAN
+#define AH_MAXCHAN 96
+#endif
+
+/*
+ * Internal per-channel state. These are found
+ * using ic_devdata in the ieee80211_channel.
*/
typedef struct {
- uint32_t channelFlags;
- uint16_t channel; /* NB: must be first for casting */
+ uint16_t channel; /* h/w frequency, NB: may be mapped */
uint8_t privFlags;
- int8_t maxRegTxPower;
- int8_t maxTxPower;
- int8_t minTxPower; /* as above... */
-
- HAL_BOOL bssSendHere;
- uint8_t gainI;
- HAL_BOOL iqCalValid;
- uint8_t calValid; /* bitmask of cal types */
+#define CHANNEL_IQVALID 0x01 /* IQ calibration valid */
+#define CHANNEL_ANI_INIT 0x02 /* ANI state initialized */
+#define CHANNEL_ANI_SETUP 0x04 /* ANI state setup */
+ uint8_t calValid; /* bitmask of cal types */
int8_t iCoff;
int8_t qCoff;
int16_t rawNoiseFloor;
int16_t noiseFloorAdjust;
- int8_t antennaMax;
- uint32_t regDmnFlags; /* Flags for channel use in reg */
- uint32_t conformanceTestLimit; /* conformance test limit from reg domain */
- uint16_t mainSpur; /* cached spur value for this cahnnel */
+ uint16_t mainSpur; /* cached spur value for this channel */
} HAL_CHANNEL_INTERNAL;
+/* channel requires noise floor check */
+#define CHANNEL_NFCREQUIRED IEEE80211_CHAN_PRIV0
+
+/* all full-width channels */
+#define IEEE80211_CHAN_ALLFULL \
+ (IEEE80211_CHAN_ALL - (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER))
+#define IEEE80211_CHAN_ALLTURBOFULL \
+ (IEEE80211_CHAN_ALLTURBO - \
+ (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER))
+
typedef struct {
uint32_t halChanSpreadSupport : 1,
halSleepAfterBeaconBroken : 1,
@@ -189,6 +203,8 @@ typedef struct {
uint8_t halNumAntCfg5GHz;
} HAL_CAPABILITIES;
+struct regDomain;
+
/*
* The ``private area'' follows immediately after the ``public area''
* in the data structure returned by ath_hal_attach. Private data are
@@ -228,7 +244,7 @@ struct ath_hal_private {
uint32_t gpio, uint32_t val);
void (*ah_gpioSetIntr)(struct ath_hal*, u_int, uint32_t);
HAL_BOOL (*ah_getChipPowerLimits)(struct ath_hal *,
- HAL_CHANNEL *, uint32_t);
+ struct ieee80211_channel *);
int16_t (*ah_getNfAdjust)(struct ath_hal *,
const HAL_CHANNEL_INTERNAL*);
void (*ah_getNoiseFloor)(struct ath_hal *,
@@ -255,8 +271,8 @@ struct ath_hal_private {
uint16_t ah_analog5GhzRev; /* 2GHz radio revision */
uint16_t ah_analog2GhzRev; /* 5GHz radio revision */
-
HAL_OPMODE ah_opmode; /* operating mode from reset */
+ const struct ieee80211_channel *ah_curchan;/* operating channel */
HAL_CAPABILITIES ah_caps; /* device capabilities */
uint32_t ah_diagreg; /* user-specified AR_DIAG_SW */
int16_t ah_powerLimit; /* tx power cap */
@@ -267,14 +283,13 @@ struct ath_hal_private {
/*
* State for regulatory domain handling.
*/
- HAL_REG_DOMAIN ah_currentRD; /* Current regulatory domain */
- HAL_CTRY_CODE ah_countryCode; /* current country code */
- HAL_CHANNEL_INTERNAL ah_channels[256]; /* calculated channel list */
- u_int ah_nchan; /* valid channels in list */
- HAL_CHANNEL_INTERNAL *ah_curchan; /* current channel */
+ HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */
+ HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */
+ u_int ah_nchan; /* valid items in ah_channels */
+ const struct regDomain *ah_rd2GHz; /* reg state for 2G band */
+ const struct regDomain *ah_rd5GHz; /* reg state for 5G band */
uint8_t ah_coverageClass; /* coverage class */
- HAL_BOOL ah_regdomainUpdate; /* regdomain is updated? */
/*
* RF Silent handling; setup according to the EEPROM.
*/
@@ -307,8 +322,8 @@ struct ath_hal_private {
AH_PRIVATE(_ah)->ah_gpioGet(_ah, _gpio, _val)
#define ath_hal_gpioSetIntr(_ah, _gpio, _ilevel) \
AH_PRIVATE(_ah)->ah_gpioSetIntr(_ah, _gpio, _ilevel)
-#define ath_hal_getpowerlimits(_ah, _chans, _nchan) \
- AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chans, _nchan)
+#define ath_hal_getpowerlimits(_ah, _chan) \
+ AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chan)
#define ath_hal_getNfAdjust(_ah, _c) \
AH_PRIVATE(_ah)->ah_getNfAdjust(_ah, _c)
#define ath_hal_getNoiseFloor(_ah, _nfArray) \
@@ -327,38 +342,22 @@ struct ath_hal_private {
#define ath_hal_eepromDiag(_ah, _request, _a, _asize, _r, _rsize) \
AH_PRIVATE(_ah)->ah_eepromDiag(_ah, _request, _a, _asize, _r, _rsize)
-#if !defined(_NET_IF_IEEE80211_H_) && !defined(_NET80211__IEEE80211_H_)
+#ifndef _NET_IF_IEEE80211_H_
/*
* Stuff that would naturally come from _ieee80211.h
*/
#define IEEE80211_ADDR_LEN 6
-#define IEEE80211_WEP_KEYLEN 5 /* 40bit */
#define IEEE80211_WEP_IVLEN 3 /* 24bit */
#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */
#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */
#define IEEE80211_CRC_LEN 4
-#define IEEE80211_MTU 1500
#define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \
(IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN))
-
-enum {
- IEEE80211_T_DS, /* direct sequence spread spectrum */
- IEEE80211_T_FH, /* frequency hopping */
- IEEE80211_T_OFDM, /* frequency division multiplexing */
- IEEE80211_T_TURBO, /* high rate DS */
- IEEE80211_T_HT, /* HT - full GI */
-};
-#define IEEE80211_T_CCK IEEE80211_T_DS /* more common nomenclatur */
#endif /* _NET_IF_IEEE80211_H_ */
-/* NB: these are defined privately until XR support is announced */
-enum {
- ATHEROS_T_XR = IEEE80211_T_HT+1, /* extended range */
-};
-
#define HAL_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
#define INIT_AIFS 2
@@ -411,43 +410,11 @@ typedef enum {
#define HAL_BIN_WIDTH_TURBO_100HZ 6250
#define HAL_MAX_BINS_ALLOWED 28
-/*
- * A = 5GHZ|OFDM
- * T = 5GHZ|OFDM|TURBO
- *
- * IS_CHAN_A(T) will return TRUE. This is probably
- * not the default behavior we want. We should migrate to a better mask --
- * perhaps CHANNEL_ALL.
- *
- * For now, IS_CHAN_G() masks itself with CHANNEL_108G.
- *
- */
-
-#define IS_CHAN_A(_c) (((_c)->channelFlags & CHANNEL_A) == CHANNEL_A)
-#define IS_CHAN_B(_c) (((_c)->channelFlags & CHANNEL_B) == CHANNEL_B)
-#define IS_CHAN_G(_c) (((_c)->channelFlags & (CHANNEL_108G|CHANNEL_G)) == CHANNEL_G)
-#define IS_CHAN_108G(_c)(((_c)->channelFlags & CHANNEL_108G) == CHANNEL_108G)
-#define IS_CHAN_T(_c) (((_c)->channelFlags & CHANNEL_T) == CHANNEL_T)
-#define IS_CHAN_PUREG(_c) \
- (((_c)->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG)
-
-#define IS_CHAN_TURBO(_c) (((_c)->channelFlags & CHANNEL_TURBO) != 0)
-#define IS_CHAN_CCK(_c) (((_c)->channelFlags & CHANNEL_CCK) != 0)
-#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
-#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
-#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
-#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
-#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+#define IS_CHAN_5GHZ(_c) ((_c)->channel > 4900)
+#define IS_CHAN_2GHZ(_c) (!IS_CHAN_5GHZ(_c))
#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
-#define CHANNEL_HT40 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)
-#define CHANNEL_HT (CHANNEL_HT20 | CHANNEL_HT40)
-#define IS_CHAN_HT(_c) (((_c)->channelFlags & CHANNEL_HT) != 0)
-#define IS_CHAN_HT20(_c) (((_c)->channelFlags & CHANNEL_HT) == CHANNEL_HT20)
-#define IS_CHAN_HT40(_c) (((_c)->channelFlags & CHANNEL_HT40) != 0)
-
/*
* Deduce if the host cpu has big- or litt-endian byte order.
*/
@@ -486,37 +453,6 @@ isBigEndian(void)
#define OS_REG_CLR_BIT(_a, _r, _f) \
OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) &~ (_f))
-/*
- * Regulatory domain support.
- */
-
-/*
- * Return the max allowed antenna gain based on the current
- * regulatory domain.
- */
-extern u_int ath_hal_getantennareduction(struct ath_hal *,
- HAL_CHANNEL *, u_int twiceGain);
-/*
- * Return the test group for the specific channel based on
- * the current regulator domain.
- */
-extern u_int ath_hal_getctl(struct ath_hal *, HAL_CHANNEL *);
-/*
- * Return whether or not a noise floor check is required
- * based on the current regulatory domain for the specified
- * channel.
- */
-extern u_int ath_hal_getnfcheckrequired(struct ath_hal *, HAL_CHANNEL *);
-
-/*
- * Map a public channel definition to the corresponding
- * internal data structure. This implicitly specifies
- * whether or not the specified channel is ok to use
- * based on the current regulatory domain constraints.
- */
-extern HAL_CHANNEL_INTERNAL *ath_hal_checkchannel(struct ath_hal *,
- const HAL_CHANNEL *);
-
/* system-configurable parameters */
extern int ath_hal_dma_beacon_response_time; /* in TU's */
extern int ath_hal_sw_beacon_response_time; /* in TU's */
@@ -575,6 +511,57 @@ extern void ath_hal_assert_failed(const char* filename,
#define HALASSERT(_x)
#endif /* AH_ASSERT */
+/*
+ * Regulatory domain support.
+ */
+
+/*
+ * Return the max allowed antenna gain and apply any regulatory
+ * domain specific changes.
+ */
+u_int ath_hal_getantennareduction(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, u_int twiceGain);
+
+/*
+ * Return the test group for the specific channel based on
+ * the current regulatory setup.
+ */
+u_int ath_hal_getctl(struct ath_hal *, const struct ieee80211_channel *);
+
+/*
+ * Map a public channel definition to the corresponding
+ * internal data structure. This implicitly specifies
+ * whether or not the specified channel is ok to use
+ * based on the current regulatory domain constraints.
+ */
+#ifndef AH_DEBUG
+static OS_INLINE HAL_CHANNEL_INTERNAL *
+ath_hal_checkchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
+{
+ HAL_CHANNEL_INTERNAL *cc;
+
+ HALASSERT(c->ic_devdata < AH_PRIVATE(ah)->ah_nchan);
+ cc = &AH_PRIVATE(ah)->ah_channels[c->ic_devdata];
+ HALASSERT(c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c));
+ return cc;
+}
+#else
+/* NB: non-inline version that checks state */
+HAL_CHANNEL_INTERNAL *ath_hal_checkchannel(struct ath_hal *,
+ const struct ieee80211_channel *);
+#endif /* AH_DEBUG */
+
+/*
+ * Return the h/w frequency for a channel. This may be
+ * different from ic_freq if this is a GSM device that
+ * takes 2.4GHz frequencies and down-converts them.
+ */
+static OS_INLINE uint16_t
+ath_hal_gethwchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
+{
+ return ath_hal_checkchannel(ah, c)->channel;
+}
+
/*
* Convert between microseconds and core system clocks.
*/
@@ -733,7 +720,7 @@ extern void ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt);
/*
* Common routine for implementing getChanNoise api.
*/
-extern int16_t ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan);
+int16_t ath_hal_getChanNoise(struct ath_hal *, const struct ieee80211_channel *);
/*
* Initialization support.
diff --git a/sys/dev/ath/ath_hal/ah_regdomain.c b/sys/dev/ath/ath_hal/ah_regdomain.c
index d021c28..814b9ab 100644
--- a/sys/dev/ath/ath_hal/ah_regdomain.c
+++ b/sys/dev/ath/ath_hal/ah_regdomain.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2006 Atheros Communications, Inc.
* All rights reserved.
*
@@ -15,11 +15,15 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: ah_regdomain.c,v 1.24 2008/11/27 22:29:27 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
#include "ah.h"
+
+#include <net80211/_ieee80211.h>
+#include <net80211/ieee80211_regdomain.h>
+
#include "ah_internal.h"
#include "ah_eeprom.h"
#include "ah_devid.h"
@@ -34,10 +38,6 @@
#define HAL_MODE_11A_TURBO HAL_MODE_108A
#define HAL_MODE_11G_TURBO HAL_MODE_108G
-/* 10MHz is half the 11A bandwidth used to determine upper edge freq
- of the outdoor channel */
-#define HALF_MAXCHANBW 10
-
/*
* BMLEN defines the size of the bitmask used to hold frequency
* band specifications. Note this must agree with the BM macro
@@ -74,160 +74,11 @@ typedef uint64_t chanbmask_t[BMLEN];
W0(_fg) | W0(_fh) , \
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
W1(_fg) | W1(_fh) }
-
-/*
- * Country/Region Codes
- * Numbering from ISO 3166
- */
-enum {
- CTRY_ALBANIA = 8, /* Albania */
- CTRY_ALGERIA = 12, /* Algeria */
- CTRY_ARGENTINA = 32, /* Argentina */
- CTRY_ARMENIA = 51, /* Armenia */
- CTRY_AUSTRALIA = 36, /* Australia */
- CTRY_AUSTRIA = 40, /* Austria */
- CTRY_AZERBAIJAN = 31, /* Azerbaijan */
- CTRY_BAHRAIN = 48, /* Bahrain */
- CTRY_BELARUS = 112, /* Belarus */
- CTRY_BELGIUM = 56, /* Belgium */
- CTRY_BELIZE = 84, /* Belize */
- CTRY_BOLIVIA = 68, /* Bolivia */
- CTRY_BRAZIL = 76, /* Brazil */
- CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */
- CTRY_BULGARIA = 100, /* Bulgaria */
- CTRY_CANADA = 124, /* Canada */
- CTRY_CHILE = 152, /* Chile */
- CTRY_CHINA = 156, /* People's Republic of China */
- CTRY_COLOMBIA = 170, /* Colombia */
- CTRY_COSTA_RICA = 188, /* Costa Rica */
- CTRY_CROATIA = 191, /* Croatia */
- CTRY_CYPRUS = 196,
- CTRY_CZECH = 203, /* Czech Republic */
- CTRY_DENMARK = 208, /* Denmark */
- CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
- CTRY_ECUADOR = 218, /* Ecuador */
- CTRY_EGYPT = 818, /* Egypt */
- CTRY_EL_SALVADOR = 222, /* El Salvador */
- CTRY_ESTONIA = 233, /* Estonia */
- CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */
- CTRY_FINLAND = 246, /* Finland */
- CTRY_FRANCE = 250, /* France */
- CTRY_FRANCE2 = 255, /* France2 */
- CTRY_GEORGIA = 268, /* Georgia */
- CTRY_GERMANY = 276, /* Germany */
- CTRY_GREECE = 300, /* Greece */
- CTRY_GUATEMALA = 320, /* Guatemala */
- CTRY_HONDURAS = 340, /* Honduras */
- CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */
- CTRY_HUNGARY = 348, /* Hungary */
- CTRY_ICELAND = 352, /* Iceland */
- CTRY_INDIA = 356, /* India */
- CTRY_INDONESIA = 360, /* Indonesia */
- CTRY_IRAN = 364, /* Iran */
- CTRY_IRAQ = 368, /* Iraq */
- CTRY_IRELAND = 372, /* Ireland */
- CTRY_ISRAEL = 376, /* Israel */
- CTRY_ITALY = 380, /* Italy */
- CTRY_JAMAICA = 388, /* Jamaica */
- CTRY_JAPAN = 392, /* Japan */
- CTRY_JAPAN1 = 393, /* Japan (JP1) */
- CTRY_JAPAN2 = 394, /* Japan (JP0) */
- CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
- CTRY_JAPAN4 = 396, /* Japan (JE1) */
- CTRY_JAPAN5 = 397, /* Japan (JE2) */
- CTRY_JAPAN6 = 399, /* Japan (JP6) */
-
- CTRY_JAPAN7 = 4007, /* Japan (J7) */
- CTRY_JAPAN8 = 4008, /* Japan (J8) */
- CTRY_JAPAN9 = 4009, /* Japan (J9) */
-
- CTRY_JAPAN10 = 4010, /* Japan (J10) */
- CTRY_JAPAN11 = 4011, /* Japan (J11) */
- CTRY_JAPAN12 = 4012, /* Japan (J12) */
-
- CTRY_JAPAN13 = 4013, /* Japan (J13) */
- CTRY_JAPAN14 = 4014, /* Japan (J14) */
- CTRY_JAPAN15 = 4015, /* Japan (J15) */
-
- CTRY_JAPAN16 = 4016, /* Japan (J16) */
- CTRY_JAPAN17 = 4017, /* Japan (J17) */
- CTRY_JAPAN18 = 4018, /* Japan (J18) */
-
- CTRY_JAPAN19 = 4019, /* Japan (J19) */
- CTRY_JAPAN20 = 4020, /* Japan (J20) */
- CTRY_JAPAN21 = 4021, /* Japan (J21) */
-
- CTRY_JAPAN22 = 4022, /* Japan (J22) */
- CTRY_JAPAN23 = 4023, /* Japan (J23) */
- CTRY_JAPAN24 = 4024, /* Japan (J24) */
-
- CTRY_JORDAN = 400, /* Jordan */
- CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
- CTRY_KENYA = 404, /* Kenya */
- CTRY_KOREA_NORTH = 408, /* North Korea */
- CTRY_KOREA_ROC = 410, /* South Korea */
- CTRY_KOREA_ROC2 = 411, /* South Korea */
- CTRY_KOREA_ROC3 = 412, /* South Korea */
- CTRY_KUWAIT = 414, /* Kuwait */
- CTRY_LATVIA = 428, /* Latvia */
- CTRY_LEBANON = 422, /* Lebanon */
- CTRY_LIBYA = 434, /* Libya */
- CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */
- CTRY_LITHUANIA = 440, /* Lithuania */
- CTRY_LUXEMBOURG = 442, /* Luxembourg */
- CTRY_MACAU = 446, /* Macau */
- CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */
- CTRY_MALAYSIA = 458, /* Malaysia */
- CTRY_MALTA = 470, /* Malta */
- CTRY_MEXICO = 484, /* Mexico */
- CTRY_MONACO = 492, /* Principality of Monaco */
- CTRY_MOROCCO = 504, /* Morocco */
- CTRY_NETHERLANDS = 528, /* Netherlands */
- CTRY_NEW_ZEALAND = 554, /* New Zealand */
- CTRY_NICARAGUA = 558, /* Nicaragua */
- CTRY_NORWAY = 578, /* Norway */
- CTRY_OMAN = 512, /* Oman */
- CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */
- CTRY_PANAMA = 591, /* Panama */
- CTRY_PARAGUAY = 600, /* Paraguay */
- CTRY_PERU = 604, /* Peru */
- CTRY_PHILIPPINES = 608, /* Republic of the Philippines */
- CTRY_POLAND = 616, /* Poland */
- CTRY_PORTUGAL = 620, /* Portugal */
- CTRY_PUERTO_RICO = 630, /* Puerto Rico */
- CTRY_QATAR = 634, /* Qatar */
- CTRY_ROMANIA = 642, /* Romania */
- CTRY_RUSSIA = 643, /* Russia */
- CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */
- CTRY_SINGAPORE = 702, /* Singapore */
- CTRY_SLOVAKIA = 703, /* Slovak Republic */
- CTRY_SLOVENIA = 705, /* Slovenia */
- CTRY_SOUTH_AFRICA = 710, /* South Africa */
- CTRY_SPAIN = 724, /* Spain */
- CTRY_SR9 = 5000, /* Ubiquiti SR9 (900MHz/GSM) */
- CTRY_SWEDEN = 752, /* Sweden */
- CTRY_SWITZERLAND = 756, /* Switzerland */
- CTRY_SYRIA = 760, /* Syria */
- CTRY_TAIWAN = 158, /* Taiwan */
- CTRY_THAILAND = 764, /* Thailand */
- CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */
- CTRY_TUNISIA = 788, /* Tunisia */
- CTRY_TURKEY = 792, /* Turkey */
- CTRY_UAE = 784, /* U.A.E. */
- CTRY_UKRAINE = 804, /* Ukraine */
- CTRY_UNITED_KINGDOM = 826, /* United Kingdom */
- CTRY_UNITED_STATES = 840, /* United States */
- CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/
- CTRY_URUGUAY = 858, /* Uruguay */
- CTRY_UZBEKISTAN = 860, /* Uzbekistan */
- CTRY_VENEZUELA = 862, /* Venezuela */
- CTRY_VIET_NAM = 704, /* Viet Nam */
- CTRY_XR9 = 5001, /* Ubiquiti XR9 (900MHz/GSM) */
- CTRY_GZ901 = 5002, /* Zcomax GZ-901 (900MHz/GSM) */
- CTRY_YEMEN = 887, /* Yemen */
- CTRY_ZIMBABWE = 716 /* Zimbabwe */
-};
-
+#define BM9(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi) \
+ { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
+ W0(_fg) | W0(_fh) | W0(_fi) , \
+ W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
+ W1(_fg) | W1(_fh) | W1(_fi) }
/*
* Mask to check whether a domain is a multidomain or a single domain
@@ -299,9 +150,9 @@ enum {
APL2_ETSIC = 0x56, /* Venezuela */
APL5_WORLD = 0x58, /* Chile */
APL6_WORLD = 0x5B, /* Singapore */
- APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
- APL8_WORLD = 0x5D, /* Malaysia 5GHz */
- APL9_WORLD = 0x5E, /* Korea 5GHz */
+ APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
+ APL8_WORLD = 0x5D, /* Malaysia 5GHz */
+ APL9_WORLD = 0x5E, /* Korea 5GHz */
/*
* World mode SKUs
@@ -407,9 +258,6 @@ enum {
NULL1 = 0x0198,
WORLD = 0x0199,
- SR9_WORLD = 0x0298,
- XR9_WORLD = 0x0299,
- GZ901_WORLD = 0x029a,
DEBUG_REG_DMN = 0x01ff,
};
@@ -429,12 +277,11 @@ enum { /* conformance test limits */
*/
enum {
NO_REQ = 0x00000000, /* NB: must be zero */
- DISALLOW_ADHOC_11A = 0x00000001,
- DISALLOW_ADHOC_11A_TURB = 0x00000002,
- NEED_NFC = 0x00000004,
- ADHOC_PER_11D = 0x00000008, /* Start Ad-Hoc mode */
- ADHOC_NO_11A = 0x00000010,
- LIMIT_FRAME_4MS = 0x00000020, /* 4msec limit on frame length*/
+ DISALLOW_ADHOC_11A = 0x00000001, /* adhoc not allowed in 5GHz */
+ DISALLOW_ADHOC_11A_TURB = 0x00000002, /* not allowed w/ 5GHz turbo */
+ NEED_NFC = 0x00000004, /* need noise floor check */
+ ADHOC_PER_11D = 0x00000008, /* must receive 11d beacon */
+ LIMIT_FRAME_4MS = 0x00000020, /* 4msec tx burst limit */
NO_HOSTAP = 0x00000040, /* No HOSTAP mode opereation */
};
@@ -466,7 +313,7 @@ enum {
* THE following table is the mapping of regdomain pairs specified by
* an 8 bit regdomain value to the individual unitary reg domains
*/
-typedef struct {
+typedef struct regDomainPair {
HAL_REG_DOMAIN regDmnEnum; /* 16 bit reg domain pair */
HAL_REG_DOMAIN regDmn5GHz; /* 5GHz reg domain */
HAL_REG_DOMAIN regDmn2GHz; /* 2GHz reg domain */
@@ -486,44 +333,44 @@ typedef struct {
} REG_DMN_PAIR_MAPPING;
static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
- {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
-
- {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {FCC5_FCCB, FCC5, FCCB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
-
- {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
-
- {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
-
- {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
-
- {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, },
+ {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+
+ {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC5_FCCB, FCC5, FCCB, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+
+ {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+
+ {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+
+ {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+
+ {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN },
{MKK1_MKKB, MKK1, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN1 },
@@ -536,19 +383,19 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
{MKK2_MKKA, MKK2, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN3 },
/* MKK3 */
- {MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, 0 },
+ {MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, CTRY_DEFAULT },
{MKK3_MKKB, MKK3, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN7 },
- {MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
+ {MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_DEFAULT },
{MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 },
{MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 },
- {MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, 0 },
+ {MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_DEFAULT },
/* MKK4 */
{MKK4_MKKB, MKK4, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 },
- {MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
+ {MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_DEFAULT },
{MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 },
{MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 },
- {MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, 0 },
+ {MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_DEFAULT },
/* MKK5 */
{MKK5_MKKB, MKK5, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN13 },
@@ -570,24 +417,21 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
{MKK8_MKKA2,MKK8, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 },
{MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 },
- {MKK9_MKKA, MKK9, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, 0 },
- {MKK10_MKKA, MKK10, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, 0 },
+ {MKK9_MKKA, MKK9, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_DEFAULT },
+ {MKK10_MKKA, MKK10, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_DEFAULT },
/* These are super domains */
- {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
- {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
- {SR9_WORLD, NULL1, SR9_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_SR9 },
- {XR9_WORLD, NULL1, XR9_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_XR9 },
- {GZ901_WORLD, NULL1, GZ901_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_GZ901 },
+ {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
+ {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
};
/*
@@ -597,171 +441,152 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
*/
#define DEF_REGDMN FCC1_FCCA
-#define DEF_DMN_5 FCC1
-#define DEF_DMN_2 FCCA
#define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000
-#define SUPER_DOMAIN_MASK 0x0fff
-#define COUNTRY_CODE_MASK 0x3fff
-
-#define YES AH_TRUE
-#define NO AH_FALSE
typedef struct {
HAL_CTRY_CODE countryCode;
HAL_REG_DOMAIN regDmnEnum;
- HAL_BOOL allow11g;
- HAL_BOOL allow11aTurbo;
- HAL_BOOL allow11gTurbo;
- HAL_BOOL allow11ng20;
- HAL_BOOL allow11ng40;
- HAL_BOOL allow11na20;
- HAL_BOOL allow11na40;
- uint16_t outdoorChanStart;
} COUNTRY_CODE_TO_ENUM_RD;
static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
- {CTRY_DEBUG, NO_ENUMRD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_DEFAULT, DEF_REGDMN, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_ALBANIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 },
- {CTRY_ALGERIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 },
- {CTRY_ARGENTINA, APL3_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_ARMENIA, ETSI4_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_AUSTRALIA, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_AUSTRIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_AZERBAIJAN, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_BAHRAIN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_BELARUS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_BELGIUM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_BELIZE, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_BOLIVIA, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_BRAZIL, FCC3_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_BULGARIA, ETSI6_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_CANADA, FCC2_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_CHILE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_CHINA, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_COLOMBIA, FCC1_FCCA, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_COSTA_RICA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_CROATIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_CYPRUS, ETSI1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_CZECH, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_DENMARK, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_ECUADOR, NULL1_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_EGYPT, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_EL_SALVADOR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_ESTONIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_FINLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_FRANCE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_FRANCE2, ETSI3_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_GEORGIA, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_GERMANY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_GREECE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_GUATEMALA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_GZ901, GZ901_WORLD, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_HONDURAS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_HONG_KONG, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_HUNGARY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_ICELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_INDIA, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_INDONESIA, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_IRAN, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_IRELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_ISRAEL, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_ITALY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_JAPAN, MKK1_MKKA, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_JAPAN1, MKK1_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN2, MKK1_FCCA, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN3, MKK2_MKKA, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN4, MKK1_MKKA1, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN5, MKK1_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN6, MKK1_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JAPAN7, MKK3_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN8, MKK3_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN9, MKK3_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JAPAN10, MKK4_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN11, MKK4_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN12, MKK4_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JAPAN13, MKK5_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN14, MKK5_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN15, MKK5_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JAPAN16, MKK6_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN17, MKK6_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN18, MKK6_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JAPAN19, MKK7_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN20, MKK7_MKKA2, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_JAPAN21, MKK7_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JAPAN22, MKK8_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN23, MKK8_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_JAPAN24, MKK8_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
-
- {CTRY_JORDAN, APL4_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_KAZAKHSTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_KOREA_NORTH, APL2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_KOREA_ROC, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_KOREA_ROC2, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_KOREA_ROC3, APL9_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_KUWAIT, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_LATVIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_LEBANON, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_LIECHTENSTEIN,ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_LITHUANIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_LUXEMBOURG, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_MACAU, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_MACEDONIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_MALAYSIA, APL8_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
- {CTRY_MALTA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_MEXICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_MONACO, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_MOROCCO, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_NETHERLANDS, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_NEW_ZEALAND, FCC2_ETSIC, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_NORWAY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_OMAN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_PAKISTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_PANAMA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_PERU, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_PHILIPPINES, FCC3_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_POLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_PORTUGAL, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_PUERTO_RICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_QATAR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_ROMANIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_RUSSIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_SAUDI_ARABIA,FCC2_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_SINGAPORE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_SLOVAKIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_SLOVENIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_SOUTH_AFRICA,FCC3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_SPAIN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_SR9, SR9_WORLD, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_SWEDEN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_SWITZERLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
- {CTRY_SYRIA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_TAIWAN, APL3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_THAILAND, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_TUNISIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_TURKEY, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_UKRAINE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_UAE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_UNITED_KINGDOM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_UNITED_STATES, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 5825 },
- {CTRY_UNITED_STATES_FCC49,FCC4_FCCA,YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_URUGUAY, FCC1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_UZBEKISTAN, FCC3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
- {CTRY_VENEZUELA, APL2_ETSIC, YES, NO, YES, YES,YES, YES, NO, 7000 },
- {CTRY_VIET_NAM, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_XR9, XR9_WORLD, YES, NO, NO, NO, NO, NO, NO, 7000 },
- {CTRY_YEMEN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
- {CTRY_ZIMBABWE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }
+ { CTRY_DEBUG, NO_ENUMRD },
+ { CTRY_DEFAULT, DEF_REGDMN },
+ { CTRY_ALBANIA, NULL1_WORLD },
+ { CTRY_ALGERIA, NULL1_WORLD },
+ { CTRY_ARGENTINA, APL3_WORLD },
+ { CTRY_ARMENIA, ETSI4_WORLD },
+ { CTRY_AUSTRALIA, FCC2_WORLD },
+ { CTRY_AUSTRIA, ETSI1_WORLD },
+ { CTRY_AZERBAIJAN, ETSI4_WORLD },
+ { CTRY_BAHRAIN, APL6_WORLD },
+ { CTRY_BELARUS, NULL1_WORLD },
+ { CTRY_BELGIUM, ETSI1_WORLD },
+ { CTRY_BELIZE, APL1_ETSIC },
+ { CTRY_BOLIVIA, APL1_ETSIC },
+ { CTRY_BRAZIL, FCC3_WORLD },
+ { CTRY_BRUNEI_DARUSSALAM,APL1_WORLD },
+ { CTRY_BULGARIA, ETSI6_WORLD },
+ { CTRY_CANADA, FCC2_FCCA },
+ { CTRY_CHILE, APL6_WORLD },
+ { CTRY_CHINA, APL1_WORLD },
+ { CTRY_COLOMBIA, FCC1_FCCA },
+ { CTRY_COSTA_RICA, NULL1_WORLD },
+ { CTRY_CROATIA, ETSI3_WORLD },
+ { CTRY_CYPRUS, ETSI1_WORLD },
+ { CTRY_CZECH, ETSI1_WORLD },
+ { CTRY_DENMARK, ETSI1_WORLD },
+ { CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA },
+ { CTRY_ECUADOR, NULL1_WORLD },
+ { CTRY_EGYPT, ETSI3_WORLD },
+ { CTRY_EL_SALVADOR, NULL1_WORLD },
+ { CTRY_ESTONIA, ETSI1_WORLD },
+ { CTRY_FINLAND, ETSI1_WORLD },
+ { CTRY_FRANCE, ETSI1_WORLD },
+ { CTRY_FRANCE2, ETSI3_WORLD },
+ { CTRY_GEORGIA, ETSI4_WORLD },
+ { CTRY_GERMANY, ETSI1_WORLD },
+ { CTRY_GREECE, ETSI1_WORLD },
+ { CTRY_GUATEMALA, FCC1_FCCA },
+ { CTRY_HONDURAS, NULL1_WORLD },
+ { CTRY_HONG_KONG, FCC2_WORLD },
+ { CTRY_HUNGARY, ETSI1_WORLD },
+ { CTRY_ICELAND, ETSI1_WORLD },
+ { CTRY_INDIA, APL6_WORLD },
+ { CTRY_INDONESIA, APL1_WORLD },
+ { CTRY_IRAN, APL1_WORLD },
+ { CTRY_IRELAND, ETSI1_WORLD },
+ { CTRY_ISRAEL, NULL1_WORLD },
+ { CTRY_ITALY, ETSI1_WORLD },
+ { CTRY_JAPAN, MKK1_MKKA },
+ { CTRY_JAPAN1, MKK1_MKKB },
+ { CTRY_JAPAN2, MKK1_FCCA },
+ { CTRY_JAPAN3, MKK2_MKKA },
+ { CTRY_JAPAN4, MKK1_MKKA1 },
+ { CTRY_JAPAN5, MKK1_MKKA2 },
+ { CTRY_JAPAN6, MKK1_MKKC },
+
+ { CTRY_JAPAN7, MKK3_MKKB },
+ { CTRY_JAPAN8, MKK3_MKKA2 },
+ { CTRY_JAPAN9, MKK3_MKKC },
+
+ { CTRY_JAPAN10, MKK4_MKKB },
+ { CTRY_JAPAN11, MKK4_MKKA2 },
+ { CTRY_JAPAN12, MKK4_MKKC },
+
+ { CTRY_JAPAN13, MKK5_MKKB },
+ { CTRY_JAPAN14, MKK5_MKKA2 },
+ { CTRY_JAPAN15, MKK5_MKKC },
+
+ { CTRY_JAPAN16, MKK6_MKKB },
+ { CTRY_JAPAN17, MKK6_MKKA2 },
+ { CTRY_JAPAN18, MKK6_MKKC },
+
+ { CTRY_JAPAN19, MKK7_MKKB },
+ { CTRY_JAPAN20, MKK7_MKKA2 },
+ { CTRY_JAPAN21, MKK7_MKKC },
+
+ { CTRY_JAPAN22, MKK8_MKKB },
+ { CTRY_JAPAN23, MKK8_MKKA2 },
+ { CTRY_JAPAN24, MKK8_MKKC },
+
+ { CTRY_JORDAN, APL4_WORLD },
+ { CTRY_KAZAKHSTAN, NULL1_WORLD },
+ { CTRY_KOREA_NORTH, APL2_WORLD },
+ { CTRY_KOREA_ROC, APL2_WORLD },
+ { CTRY_KOREA_ROC2, APL2_WORLD },
+ { CTRY_KOREA_ROC3, APL9_WORLD },
+ { CTRY_KUWAIT, NULL1_WORLD },
+ { CTRY_LATVIA, ETSI1_WORLD },
+ { CTRY_LEBANON, NULL1_WORLD },
+ { CTRY_LIECHTENSTEIN,ETSI1_WORLD },
+ { CTRY_LITHUANIA, ETSI1_WORLD },
+ { CTRY_LUXEMBOURG, ETSI1_WORLD },
+ { CTRY_MACAU, FCC2_WORLD },
+ { CTRY_MACEDONIA, NULL1_WORLD },
+ { CTRY_MALAYSIA, APL8_WORLD },
+ { CTRY_MALTA, ETSI1_WORLD },
+ { CTRY_MEXICO, FCC1_FCCA },
+ { CTRY_MONACO, ETSI4_WORLD },
+ { CTRY_MOROCCO, NULL1_WORLD },
+ { CTRY_NETHERLANDS, ETSI1_WORLD },
+ { CTRY_NEW_ZEALAND, FCC2_ETSIC },
+ { CTRY_NORWAY, ETSI1_WORLD },
+ { CTRY_OMAN, APL6_WORLD },
+ { CTRY_PAKISTAN, NULL1_WORLD },
+ { CTRY_PANAMA, FCC1_FCCA },
+ { CTRY_PERU, APL1_WORLD },
+ { CTRY_PHILIPPINES, FCC3_WORLD },
+ { CTRY_POLAND, ETSI1_WORLD },
+ { CTRY_PORTUGAL, ETSI1_WORLD },
+ { CTRY_PUERTO_RICO, FCC1_FCCA },
+ { CTRY_QATAR, NULL1_WORLD },
+ { CTRY_ROMANIA, NULL1_WORLD },
+ { CTRY_RUSSIA, NULL1_WORLD },
+ { CTRY_SAUDI_ARABIA,FCC2_WORLD },
+ { CTRY_SINGAPORE, APL6_WORLD },
+ { CTRY_SLOVAKIA, ETSI1_WORLD },
+ { CTRY_SLOVENIA, ETSI1_WORLD },
+ { CTRY_SOUTH_AFRICA,FCC3_WORLD },
+ { CTRY_SPAIN, ETSI1_WORLD },
+ { CTRY_SWEDEN, ETSI1_WORLD },
+ { CTRY_SWITZERLAND, ETSI1_WORLD },
+ { CTRY_SYRIA, NULL1_WORLD },
+ { CTRY_TAIWAN, APL3_FCCA },
+ { CTRY_THAILAND, NULL1_WORLD },
+ { CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD },
+ { CTRY_TUNISIA, ETSI3_WORLD },
+ { CTRY_TURKEY, ETSI3_WORLD },
+ { CTRY_UKRAINE, NULL1_WORLD },
+ { CTRY_UAE, NULL1_WORLD },
+ { CTRY_UNITED_KINGDOM, ETSI1_WORLD },
+ { CTRY_UNITED_STATES, FCC1_FCCA },
+ { CTRY_UNITED_STATES_FCC49,FCC4_FCCA },
+ { CTRY_URUGUAY, FCC1_WORLD },
+ { CTRY_UZBEKISTAN, FCC3_FCCA },
+ { CTRY_VENEZUELA, APL2_ETSIC },
+ { CTRY_VIET_NAM, NULL1_WORLD },
+ { CTRY_ZIMBABWE, NULL1_WORLD }
};
/* Bit masks for DFS per regdomain */
@@ -800,136 +625,134 @@ typedef struct {
if corresponding bit is set */
uint64_t usePassScan; /* Use Passive Scan in the RegDomain
if corresponding bit is set */
- uint8_t regClassId; /* Regulatory class id */
} REG_DMN_FREQ_BAND;
/*
* 5GHz 11A channel tags
*/
static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
- { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 },
+ { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_4915_4925 0
- { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 },
+ { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_4935_4945 AFTER(F1_4915_4925)
- { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 },
+ { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2 },
#define F1_4920_4980 AFTER(F1_4935_4945)
- { 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0 },
+ { 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC },
#define F1_4942_4987 AFTER(F1_4920_4980)
- { 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0 },
+ { 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC },
#define F1_4945_4985 AFTER(F1_4942_4987)
- { 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0 },
+ { 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC },
#define F1_4950_4980 AFTER(F1_4945_4985)
- { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 },
+ { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_5035_5040 AFTER(F1_4950_4980)
- { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2 },
+ { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2 },
#define F1_5040_5080 AFTER(F1_5035_5040)
- { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 },
+ { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_5055_5055 AFTER(F1_5040_5080)
- { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F1_5120_5240 AFTER(F1_5055_5055)
- { 5120, 5240, 5, 6, 10, 10, NO_DFS, NO_PSCAN, 0 },
+ { 5120, 5240, 5, 6, 10, 10, NO_DFS, NO_PSCAN },
#define F2_5120_5240 AFTER(F1_5120_5240)
- { 5120, 5240, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0 },
+ { 5120, 5240, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define F3_5120_5240 AFTER(F2_5120_5240)
- { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 },
+ { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2 },
#define F1_5170_5230 AFTER(F3_5120_5240)
- { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 },
+ { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2 },
#define F2_5170_5230 AFTER(F1_5170_5230)
- { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
+ { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F1_5180_5240 AFTER(F2_5170_5230)
- { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC, 1 },
+ { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC },
#define F2_5180_5240 AFTER(F1_5180_5240)
- { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
+ { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F3_5180_5240 AFTER(F2_5180_5240)
- { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
+ { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F4_5180_5240 AFTER(F3_5180_5240)
- { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
+ { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F5_5180_5240 AFTER(F4_5180_5240)
- { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0 },
+ { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC },
#define F6_5180_5240 AFTER(F5_5180_5240)
- { 5180, 5240, 17, 6, 20, 10, NO_DFS, PSCAN_FCC, 1 },
+ { 5180, 5240, 17, 6, 20, 10, NO_DFS, PSCAN_FCC },
#define F7_5180_5240 AFTER(F6_5180_5240)
- { 5180, 5240, 17, 6, 20, 5, NO_DFS, PSCAN_FCC, 1 },
+ { 5180, 5240, 17, 6, 20, 5, NO_DFS, PSCAN_FCC },
#define F8_5180_5240 AFTER(F7_5180_5240)
+ { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
- { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
#define F1_5180_5320 AFTER(F8_5180_5240)
+ { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI },
- { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 },
#define F1_5240_5280 AFTER(F1_5180_5320)
+ { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
- { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
#define F1_5260_5280 AFTER(F1_5240_5280)
+ { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
- { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
#define F1_5260_5320 AFTER(F1_5260_5280)
-
- { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 },
+ { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 },
#define F2_5260_5320 AFTER(F1_5260_5320)
- { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
+ { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F3_5260_5320 AFTER(F2_5260_5320)
- { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
+ { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F4_5260_5320 AFTER(F3_5260_5320)
- { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },
+ { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F5_5260_5320 AFTER(F4_5260_5320)
- { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F6_5260_5320 AFTER(F5_5260_5320)
- { 5260, 5320, 23, 6, 20, 10, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
+ { 5260, 5320, 23, 6, 20, 10, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F7_5260_5320 AFTER(F6_5260_5320)
- { 5260, 5320, 23, 6, 20, 5, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
+ { 5260, 5320, 23, 6, 20, 5, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F8_5260_5320 AFTER(F7_5260_5320)
- { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
+ { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
#define F1_5260_5700 AFTER(F8_5260_5320)
- { 5260, 5700, 5, 6, 10, 10, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
+ { 5260, 5700, 5, 6, 10, 10, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
#define F2_5260_5700 AFTER(F1_5260_5700)
- { 5260, 5700, 5, 6, 5, 5, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
+ { 5260, 5700, 5, 6, 5, 5, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
#define F3_5260_5700 AFTER(F2_5260_5700)
- { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },
+ { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F1_5280_5320 AFTER(F3_5260_5700)
- { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
+ { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
#define F1_5500_5620 AFTER(F1_5280_5320)
- { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4 },
+ { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F1_5500_5700 AFTER(F1_5500_5620)
- { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
+ { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
#define F2_5500_5700 AFTER(F1_5500_5700)
- { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
+ { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
#define F3_5500_5700 AFTER(F2_5500_5700)
- { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 },
+ { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC },
#define F4_5500_5700 AFTER(F3_5500_5700)
- { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F1_5745_5805 AFTER(F4_5500_5700)
- { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F2_5745_5805 AFTER(F1_5745_5805)
- { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
+ { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
#define F3_5745_5805 AFTER(F2_5745_5805)
- { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F1_5745_5825 AFTER(F3_5745_5805)
- { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F2_5745_5825 AFTER(F1_5745_5825)
- { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F3_5745_5825 AFTER(F2_5745_5825)
- { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F4_5745_5825 AFTER(F3_5745_5825)
- { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3 },
+ { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F5_5745_5825 AFTER(F4_5745_5825)
- { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F6_5745_5825 AFTER(F5_5745_5825)
- { 5745, 5825, 5, 6, 10, 10, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 5, 6, 10, 10, NO_DFS, NO_PSCAN },
#define F7_5745_5825 AFTER(F6_5745_5825)
- { 5745, 5825, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0 },
+ { 5745, 5825, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define F8_5745_5825 AFTER(F7_5745_5825)
- { 5745, 5825, 30, 6, 20, 10, NO_DFS, NO_PSCAN, 3 },
+ { 5745, 5825, 30, 6, 20, 10, NO_DFS, NO_PSCAN },
#define F9_5745_5825 AFTER(F8_5745_5825)
- { 5745, 5825, 30, 6, 20, 5, NO_DFS, NO_PSCAN, 3 },
+ { 5745, 5825, 30, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F10_5745_5825 AFTER(F9_5745_5825)
/*
@@ -937,25 +760,25 @@ static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
* All WWR domains have no power limit, instead use the card's CTL
* or max power settings.
*/
- { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
+ { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W1_4920_4980 AFTER(F10_5745_5825)
- { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
+ { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W1_5040_5080 AFTER(W1_4920_4980)
- { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
+ { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5170_5230 AFTER(W1_5040_5080)
- { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
+ { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5180_5240 AFTER(W1_5170_5230)
- { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
+ { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5260_5320 AFTER(W1_5180_5240)
- { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
+ { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W1_5745_5825 AFTER(W1_5260_5320)
- { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
+ { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5500_5700 AFTER(W1_5745_5825)
- { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define W2_5260_5320 AFTER(W1_5500_5700)
- { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
+ { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define W2_5180_5240 AFTER(W2_5260_5320)
- { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
+ { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W2_5825_5825 AFTER(W2_5180_5240)
};
@@ -963,66 +786,66 @@ static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
* 5GHz Turbo (dynamic & static) tags
*/
static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
- { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5130_5210 0
- { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
+ { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5250_5330 AFTER(T1_5130_5210)
- { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5370_5490 AFTER(T1_5250_5330)
- { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
+ { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5530_5650 AFTER(T1_5370_5490)
- { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5150_5190 AFTER(T1_5530_5650)
- { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
+ { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5230_5310 AFTER(T1_5150_5190)
- { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5350_5470 AFTER(T1_5230_5310)
- { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
+ { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5510_5670 AFTER(T1_5350_5470)
- { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5200_5240 AFTER(T1_5510_5670)
- { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T2_5200_5240 AFTER(T1_5200_5240)
- { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5210_5210 AFTER(T2_5200_5240)
- { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN },
#define T2_5210_5210 AFTER(T1_5210_5210)
- { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5280_5280 AFTER(T2_5210_5210)
- { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T2_5280_5280 AFTER(T1_5280_5280)
- { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5250_5250 AFTER(T2_5280_5280)
- { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5290_5290 AFTER(T1_5250_5250)
- { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5250_5290 AFTER(T1_5290_5290)
- { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T2_5250_5290 AFTER(T1_5250_5290)
- { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
+ { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5540_5660 AFTER(T2_5250_5290)
- { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5760_5800 AFTER(T1_5540_5660)
- { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T2_5760_5800 AFTER(T1_5760_5800)
- { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5765_5805 AFTER(T2_5760_5800)
/*
* Below are the WWR frequencies
*/
- { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
+ { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define WT1_5210_5250 AFTER(T1_5765_5805)
- { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
+ { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define WT1_5290_5290 AFTER(WT1_5210_5250)
- { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
+ { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define WT1_5540_5660 AFTER(WT1_5290_5290)
- { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0},
+ { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR },
#define WT1_5760_5800 AFTER(WT1_5540_5660)
};
@@ -1030,67 +853,67 @@ static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
* 2GHz 11b channel tags
*/
static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
- { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2312_2372 0
- { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F2_2312_2372 AFTER(F1_2312_2372)
- { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2412_2472 AFTER(F2_2312_2372)
- { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
+ { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA },
#define F2_2412_2472 AFTER(F1_2412_2472)
- { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F3_2412_2472 AFTER(F2_2412_2472)
- { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2412_2462 AFTER(F3_2412_2472)
- { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
+ { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA },
#define F2_2412_2462 AFTER(F1_2412_2462)
- { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2432_2442 AFTER(F2_2412_2462)
- { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2457_2472 AFTER(F1_2432_2442)
- { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
+ { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA },
#define F1_2467_2472 AFTER(F1_2457_2472)
- { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2484_2484 AFTER(F1_2467_2472)
- { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
+ { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2 },
#define F2_2484_2484 AFTER(F1_2484_2484)
- { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2512_2732 AFTER(F2_2484_2484)
/*
* WWR have powers opened up to 20dBm.
* Limits should often come from CTL/Max powers
*/
- { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2312_2372 AFTER(F1_2512_2732)
- { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2412_2412 AFTER(W1_2312_2372)
- { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2417_2432 AFTER(W1_2412_2412)
- { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2437_2442 AFTER(W1_2417_2432)
- { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2447_2457 AFTER(W1_2437_2442)
- { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2462_2462 AFTER(W1_2447_2457)
- { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+ { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define W1_2467_2467 AFTER(W1_2462_2462)
- { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+ { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define W2_2467_2467 AFTER(W1_2467_2467)
- { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+ { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define W1_2472_2472 AFTER(W2_2467_2467)
- { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+ { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define W2_2472_2472 AFTER(W1_2472_2472)
- { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+ { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define W1_2484_2484 AFTER(W2_2472_2472)
- { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+ { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define W2_2484_2484 AFTER(W1_2484_2484)
};
@@ -1098,112 +921,89 @@ static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
* 2GHz 11g channel tags
*/
static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
- { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2312_2372 0
- { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G2_2312_2372 AFTER(G1_2312_2372)
- { 2312, 2372, 5, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G3_2312_2372 AFTER(G2_2312_2372)
- { 2312, 2372, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G4_2312_2372 AFTER(G3_2312_2372)
- { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2412_2472 AFTER(G4_2312_2372)
- { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
+ { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G },
#define G2_2412_2472 AFTER(G1_2412_2472)
- { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G3_2412_2472 AFTER(G2_2412_2472)
- { 2412, 2472, 5, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2472, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G4_2412_2472 AFTER(G3_2412_2472)
- { 2412, 2472, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2472, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G5_2412_2472 AFTER(G4_2412_2472)
- { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2412_2462 AFTER(G5_2412_2472)
- { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
+ { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G },
#define G2_2412_2462 AFTER(G1_2412_2462)
- { 2412, 2462, 27, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2462, 27, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G3_2412_2462 AFTER(G2_2412_2462)
- { 2412, 2462, 27, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2462, 27, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G4_2412_2462 AFTER(G3_2412_2462)
- { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2432_2442 AFTER(G4_2412_2462)
- { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2457_2472 AFTER(G1_2432_2442)
- { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2512_2732 AFTER(G1_2457_2472)
- { 2512, 2732, 5, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
+ { 2512, 2732, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G2_2512_2732 AFTER(G1_2512_2732)
- { 2512, 2732, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
+ { 2512, 2732, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G3_2512_2732 AFTER(G2_2512_2732)
- { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0 },
+ { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA },
#define G1_2467_2472 AFTER(G3_2512_2732)
/*
* WWR open up the power to 20dBm
*/
- { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2312_2372 AFTER(G1_2467_2472)
- { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2412_2412 AFTER(WG1_2312_2372)
- { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2417_2432 AFTER(WG1_2412_2412)
- { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2437_2442 AFTER(WG1_2417_2432)
- { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2447_2457 AFTER(WG1_2437_2442)
- { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+ { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2462_2462 AFTER(WG1_2447_2457)
- { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+ { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define WG1_2467_2467 AFTER(WG1_2462_2462)
- { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+ { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define WG2_2467_2467 AFTER(WG1_2467_2467)
- { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+ { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define WG1_2472_2472 AFTER(WG2_2467_2467)
- { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+ { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define WG2_2472_2472 AFTER(WG1_2472_2472)
-
- /*
- * Mapping for 900MHz cards like Ubiquiti SR9 and XR9
- * and ZComax GZ-901.
- */
- { 2422, 2437, 30, 0, 5, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S1_907_922_5 AFTER(WG2_2472_2472)
- { 2422, 2437, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S1_907_922_10 AFTER(S1_907_922_5)
- { 2427, 2432, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S1_912_917 AFTER(S1_907_922_10)
- { 2427, 2442, 30, 0, 5, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S2_907_922_5 AFTER(S1_912_917)
- { 2427, 2442, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S2_907_922_10 AFTER(S2_907_922_5)
- { 2432, 2437, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S2_912_917 AFTER(S2_907_922_10)
- { 2452, 2467, 30, 0, 5, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S1_908_923_5 AFTER(S2_912_917)
- { 2457, 2467, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S1_913_918_10 AFTER(S1_908_923_5)
- { 2457, 2467, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
-#define S1_913_918 AFTER(S1_913_918_10)
};
/*
* 2GHz Dynamic turbo tags
*/
static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
- { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_2312_2372 0
- { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_2437_2437 AFTER(T1_2312_2372)
- { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T2_2437_2437 AFTER(T1_2437_2437)
- { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0},
+ { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR },
#define T3_2437_2437 AFTER(T2_2437_2437)
- { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
+ { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_2512_2732 AFTER(T3_2437_2437)
};
@@ -1231,9 +1031,18 @@ static REG_DOMAIN regDomains[] = {
{.regDmnEnum = DEBUG_REG_DMN,
.conformanceTestLimit = FCC,
.dfsMask = DFS_FCC3,
- .chan11a = BM3(F1_5120_5240, F1_5260_5700, F1_5745_5825),
- .chan11a_half = BM3(F2_5120_5240, F2_5260_5700, F7_5745_5825),
- .chan11a_quarter = BM3(F3_5120_5240, F3_5260_5700, F8_5745_5825),
+ .chan11a = BM4(F1_4950_4980,
+ F1_5120_5240,
+ F1_5260_5700,
+ F1_5745_5825),
+ .chan11a_half = BM4(F1_4945_4985,
+ F2_5120_5240,
+ F2_5260_5700,
+ F7_5745_5825),
+ .chan11a_quarter = BM4(F1_4942_4987,
+ F3_5120_5240,
+ F3_5260_5700,
+ F8_5745_5825),
.chan11a_turbo = BM8(T1_5130_5210,
T1_5250_5330,
T1_5370_5490,
@@ -1410,7 +1219,7 @@ static REG_DOMAIN regDomains[] = {
.pscan = PSCAN_MKK2,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(F1_4920_4980, F1_5040_5080, F1_5170_5230),
- .chan11a_half = BM4(F1_4915_4925,
+ .chan11a_half = BM4(F1_4915_4925,
F1_4935_4945,
F1_5035_5040,
F1_5055_5055),
@@ -1695,7 +1504,7 @@ static REG_DOMAIN regDomains[] = {
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
- .flags = ADHOC_NO_11A,
+ .flags = DISALLOW_ADHOC_11A,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
@@ -1723,7 +1532,7 @@ static REG_DOMAIN regDomains[] = {
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
- .flags = ADHOC_NO_11A,
+ .flags = DISALLOW_ADHOC_11A,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
@@ -1781,7 +1590,7 @@ static REG_DOMAIN regDomains[] = {
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
- .flags = ADHOC_NO_11A,
+ .flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W2_5260_5320,
W2_5180_5240,
F2_5745_5805,
@@ -1805,7 +1614,7 @@ static REG_DOMAIN regDomains[] = {
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
- .flags = ADHOC_NO_11A,
+ .flags = DISALLOW_ADHOC_11A,
.chan11a = BM3(W1_5260_5320, W2_5180_5240, F6_5745_5825),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
@@ -1827,7 +1636,7 @@ static REG_DOMAIN regDomains[] = {
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
- .flags = ADHOC_NO_11A,
+ .flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W1_5260_5320,
W1_5180_5240,
W1_5745_5825,
@@ -1851,7 +1660,7 @@ static REG_DOMAIN regDomains[] = {
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
- .flags = ADHOC_NO_11A,
+ .flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W1_5260_5320,
W1_5180_5240,
W1_5745_5825,
@@ -1872,30 +1681,6 @@ static REG_DOMAIN regDomains[] = {
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
- {.regDmnEnum = SR9_WORLD,
- .conformanceTestLimit = NO_CTL,
- .pscan = PSCAN_FCC | PSCAN_FCC_T,
- .chan11g = BM1(S1_912_917),
- .chan11g_half = BM1(S1_907_922_10),
- .chan11g_quarter = BM1(S1_907_922_5),
- },
-
- {.regDmnEnum = XR9_WORLD,
- .conformanceTestLimit = NO_CTL,
- .pscan = PSCAN_FCC | PSCAN_FCC_T,
- .chan11g = BM1(S2_912_917),
- .chan11g_half = BM1(S2_907_922_10),
- .chan11g_quarter = BM1(S2_907_922_5),
- },
-
- {.regDmnEnum = GZ901_WORLD,
- .conformanceTestLimit = NO_CTL,
- .pscan = PSCAN_FCC | PSCAN_FCC_T,
- .chan11g = BM1(S1_913_918),
- .chan11g_half = BM1(S1_913_918_10),
- .chan11g_quarter = BM1(S1_908_923_5),
- },
-
{.regDmnEnum = NULL1,
.conformanceTestLimit = NO_CTL,
}
@@ -1907,44 +1692,33 @@ struct cmode {
};
static const struct cmode modes[] = {
- { HAL_MODE_TURBO, CHANNEL_ST}, /* NB: 11a Static Turbo */
- { HAL_MODE_11A, CHANNEL_A},
- { HAL_MODE_11B, CHANNEL_B},
- { HAL_MODE_11G, CHANNEL_G},
- { HAL_MODE_11G_TURBO, CHANNEL_108G},
- { HAL_MODE_11A_TURBO, CHANNEL_108A},
- { HAL_MODE_11A_QUARTER_RATE, CHANNEL_A | CHANNEL_QUARTER},
- { HAL_MODE_11A_HALF_RATE, CHANNEL_A | CHANNEL_HALF},
- { HAL_MODE_11G_QUARTER_RATE, CHANNEL_G | CHANNEL_QUARTER},
- { HAL_MODE_11G_HALF_RATE, CHANNEL_G | CHANNEL_HALF},
- { HAL_MODE_11NG_HT20, CHANNEL_G_HT20},
- { HAL_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
- { HAL_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
- { HAL_MODE_11NA_HT20, CHANNEL_A_HT20},
- { HAL_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
- { HAL_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
+ { HAL_MODE_TURBO, IEEE80211_CHAN_ST },
+ { HAL_MODE_11A, IEEE80211_CHAN_A },
+ { HAL_MODE_11B, IEEE80211_CHAN_B },
+ { HAL_MODE_11G, IEEE80211_CHAN_G },
+ { HAL_MODE_11G_TURBO, IEEE80211_CHAN_108G },
+ { HAL_MODE_11A_TURBO, IEEE80211_CHAN_108A },
+ { HAL_MODE_11A_QUARTER_RATE,
+ IEEE80211_CHAN_A | IEEE80211_CHAN_QUARTER },
+ { HAL_MODE_11A_HALF_RATE,
+ IEEE80211_CHAN_A | IEEE80211_CHAN_HALF },
+ { HAL_MODE_11G_QUARTER_RATE,
+ IEEE80211_CHAN_G | IEEE80211_CHAN_QUARTER },
+ { HAL_MODE_11G_HALF_RATE,
+ IEEE80211_CHAN_G | IEEE80211_CHAN_HALF },
+ { HAL_MODE_11NG_HT20, IEEE80211_CHAN_G | IEEE80211_CHAN_HT20 },
+ { HAL_MODE_11NG_HT40PLUS,
+ IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U },
+ { HAL_MODE_11NG_HT40MINUS,
+ IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D },
+ { HAL_MODE_11NA_HT20, IEEE80211_CHAN_A | IEEE80211_CHAN_HT20 },
+ { HAL_MODE_11NA_HT40PLUS,
+ IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U },
+ { HAL_MODE_11NA_HT40MINUS,
+ IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D },
};
-static int
-chansort(const void *a, const void *b)
-{
-#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
- const HAL_CHANNEL_INTERNAL *ca = a;
- const HAL_CHANNEL_INTERNAL *cb = b;
-
- return (ca->channel == cb->channel) ?
- (ca->channelFlags & CHAN_FLAGS) -
- (cb->channelFlags & CHAN_FLAGS) :
- ca->channel - cb->channel;
-#undef CHAN_FLAGS
-}
-typedef int ath_hal_cmp_t(const void *, const void *);
-static void ath_hal_sort(void *a, size_t n, size_t es, ath_hal_cmp_t *cmp);
-static COUNTRY_CODE_TO_ENUM_RD* findCountry(HAL_CTRY_CODE countryCode);
-static HAL_BOOL getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, uint16_t channelFlag, REG_DOMAIN *rd);
-
-
-static uint16_t
+static OS_INLINE uint16_t
getEepromRD(struct ath_hal *ah)
{
return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
@@ -1992,220 +1766,45 @@ isEepromValid(struct ath_hal *ah)
}
/*
- * Returns whether or not the specified country code
- * is allowed by the EEPROM setting
- */
-static HAL_BOOL
-isCountryCodeValid(struct ath_hal *ah, HAL_CTRY_CODE cc)
-{
- uint16_t rd;
-
- /* Default setting requires no checks */
- if (cc == CTRY_DEFAULT)
- return AH_TRUE;
-#ifdef AH_DEBUG_COUNTRY
- if (cc == CTRY_DEBUG)
- return AH_TRUE;
-#endif
- rd = getEepromRD(ah);
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM regdomain 0x%x\n",
- __func__, rd);
-
- if (rd & COUNTRY_ERD_FLAG) {
- /* EEP setting is a country - config shall match */
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: EEPROM setting is country code %u\n", __func__,
- rd &~ COUNTRY_ERD_FLAG);
- return (cc == (rd & ~COUNTRY_ERD_FLAG));
- } else if (rd == DEBUG_REG_DMN || rd == NO_ENUMRD) {
- /* Set to Debug or AllowAnyCountry mode - allow any setting */
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: rd %d allowed\n",
- __func__, rd);
- return AH_TRUE;
-#ifdef AH_SUPPORT_11D
- } else if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) {
- int i;
- for (i=0; i < N(allCountries); i++) {
- if (cc == allCountries[i].countryCode)
- return AH_TRUE;
- }
-#endif
- } else {
- int i;
- for (i = 0; i < N(allCountries); i++) {
- if (cc == allCountries[i].countryCode &&
- allCountries[i].regDmnEnum == rd)
- return AH_TRUE;
- }
- }
- return AH_FALSE;
-}
-
-/*
- * Return the mask of available modes based on the hardware
- * capabilities and the specified country code and reg domain.
- */
-static u_int
-ath_hal_getwmodesnreg(struct ath_hal *ah,
- const COUNTRY_CODE_TO_ENUM_RD *country, const REG_DOMAIN *rd5GHz)
-{
-#define HAL_MODE_11G_ALL \
- (HAL_MODE_11G | HAL_MODE_11G_TURBO | HAL_MODE_11G_QUARTER_RATE | \
- HAL_MODE_11G_HALF_RATE)
-#define HAL_MODE_11A_ALL \
- (HAL_MODE_11A | HAL_MODE_11A_TURBO | HAL_MODE_TURBO | \
- HAL_MODE_11A_QUARTER_RATE | HAL_MODE_11A_HALF_RATE)
- u_int modesAvail;
-
- /* Get modes that HW is capable of */
- modesAvail = ath_hal_getWirelessModes(ah);
-
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: wireless modes 0x%x cc %u rd %u\n",
- __func__, modesAvail, country->countryCode, country->regDmnEnum);
-
- /* Check country regulations for allowed modes */
- if (!country->allow11g && (modesAvail & HAL_MODE_11G_ALL)) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow all 11g\n", __func__);
- modesAvail &= ~HAL_MODE_11G_ALL;
- }
- if (isChanBitMaskZero(rd5GHz->chan11a) &&
- (modesAvail & HAL_MODE_11A_ALL)) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow all 11a\n", __func__);
- modesAvail &= ~HAL_MODE_11A_ALL;
- }
- if ((modesAvail & (HAL_MODE_11A_TURBO | HAL_MODE_TURBO)) &&
- !country->allow11aTurbo) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11aTurbo\n", __func__);
- modesAvail &= ~(HAL_MODE_11A_TURBO | HAL_MODE_TURBO);
- }
- if ((modesAvail & HAL_MODE_11G_TURBO) && !country->allow11gTurbo) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11gTurbo\n", __func__);
- modesAvail &= ~HAL_MODE_11G_TURBO;
- }
-
- /* Check 11n operation */
- if ((modesAvail & HAL_MODE_11NG_HT20) && !country->allow11ng20) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11g HT20\n", __func__);
- modesAvail &= ~HAL_MODE_11NG_HT20;
- }
- if ((modesAvail & HAL_MODE_11NA_HT20) && !country->allow11na20) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11a HT20\n", __func__);
- modesAvail &= ~HAL_MODE_11NA_HT20;
- }
- if ((modesAvail & HAL_MODE_11NG_HT40PLUS) && !country->allow11ng40) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11g HT40+\n", __func__);
- modesAvail &= ~HAL_MODE_11NG_HT40PLUS;
- }
- if ((modesAvail & HAL_MODE_11NG_HT40MINUS) && !country->allow11ng40) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11g HT40-\n", __func__);
- modesAvail &= ~HAL_MODE_11NG_HT40MINUS;
- }
- if ((modesAvail & HAL_MODE_11NA_HT40PLUS) && !country->allow11na40) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11a HT40+\n", __func__);
- modesAvail &= ~HAL_MODE_11NA_HT40PLUS;
- }
- if ((modesAvail & HAL_MODE_11NA_HT40MINUS) && !country->allow11na40) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: disallow 11a HT40-\n", __func__);
- modesAvail &= ~HAL_MODE_11NA_HT40MINUS;
- }
-
- return modesAvail;
-#undef HAL_MODE_11A_ALL
-#undef HAL_MODE_11G_ALL
-}
-
-/*
- * Return the mask of available modes based on the hardware
- * capabilities and the specified country code.
- */
-
-u_int
-ath_hal_getwirelessmodes(struct ath_hal *ah, HAL_CTRY_CODE cc)
-{
- COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
- u_int mode = 0;
- REG_DOMAIN rd;
-
- country = findCountry(cc);
- if (country != AH_NULL) {
- if (getWmRD(ah, country, ~CHANNEL_2GHZ, &rd))
- mode = ath_hal_getwmodesnreg(ah, country, &rd);
- }
- return mode;
-}
-
-/*
- * Return if device is public safety.
+ * Find the pointer to the country element in the country table
+ * corresponding to the country code
*/
-HAL_BOOL
-ath_hal_ispublicsafetysku(struct ath_hal *ah)
+static COUNTRY_CODE_TO_ENUM_RD*
+findCountry(HAL_CTRY_CODE countryCode)
{
- uint16_t rd = getEepromRD(ah);
+ int i;
- switch (rd) {
- case FCC4_FCCA:
- case CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG:
- return AH_TRUE;
- case DEBUG_REG_DMN:
- case NO_ENUMRD:
- if (AH_PRIVATE(ah)->ah_countryCode == CTRY_UNITED_STATES_FCC49)
- return AH_TRUE;
- break;
+ for (i = 0; i < N(allCountries); i++) {
+ if (allCountries[i].countryCode == countryCode)
+ return &allCountries[i];
}
- return AH_FALSE;
+ return AH_NULL;
}
-/*
- * Return if device is actually operating in 900 MHz band.
- */
-HAL_BOOL
-ath_hal_isgsmsku(struct ath_hal *ah)
+static REG_DOMAIN *
+findRegDmn(int regDmn)
{
- uint16_t rd = getEepromRD(ah);
+ int i;
- switch (rd) {
- case SR9_WORLD:
- case XR9_WORLD:
- case GZ901_WORLD:
- case CTRY_SR9 | COUNTRY_ERD_FLAG:
- case CTRY_XR9 | COUNTRY_ERD_FLAG:
- case CTRY_GZ901 | COUNTRY_ERD_FLAG:
- return AH_TRUE;
- case DEBUG_REG_DMN:
- case NO_ENUMRD:
- return AH_PRIVATE(ah)->ah_countryCode == CTRY_SR9
- || AH_PRIVATE(ah)->ah_countryCode == CTRY_XR9
- || AH_PRIVATE(ah)->ah_countryCode == CTRY_GZ901
- ;
+ for (i = 0; i < N(regDomains); i++) {
+ if (regDomains[i].regDmnEnum == regDmn)
+ return &regDomains[i];
}
- return AH_FALSE;
+ return AH_NULL;
}
-/*
- * Find the pointer to the country element in the country table
- * corresponding to the country code
- */
-static COUNTRY_CODE_TO_ENUM_RD*
-findCountry(HAL_CTRY_CODE countryCode)
+static REG_DMN_PAIR_MAPPING *
+findRegDmnPair(int regDmnPair)
{
int i;
- for (i = 0; i < N(allCountries); i++) {
- if (allCountries[i].countryCode == countryCode)
- return &allCountries[i];
+ if (regDmnPair != NO_ENUMRD) {
+ for (i = 0; i < N(regDomainPairs); i++) {
+ if (regDomainPairs[i].regDmnEnum == regDmnPair)
+ return &regDomainPairs[i];
+ }
}
- return AH_NULL; /* Not found */
+ return AH_NULL;
}
/*
@@ -2214,14 +1813,13 @@ findCountry(HAL_CTRY_CODE countryCode)
static HAL_CTRY_CODE
getDefaultCountry(struct ath_hal *ah)
{
+ REG_DMN_PAIR_MAPPING *regpair;
uint16_t rd;
- int i;
rd = getEepromRD(ah);
if (rd & COUNTRY_ERD_FLAG) {
- COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
+ COUNTRY_CODE_TO_ENUM_RD *country;
uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
-
country = findCountry(cc);
if (country != AH_NULL)
return cc;
@@ -2229,247 +1827,174 @@ getDefaultCountry(struct ath_hal *ah)
/*
* Check reg domains that have only one country
*/
- for (i = 0; i < N(regDomainPairs); i++)
- if (regDomainPairs[i].regDmnEnum == rd) {
- if (regDomainPairs[i].singleCC != 0)
- return regDomainPairs[i].singleCC;
- else
- i = N(regDomainPairs);
- }
- return CTRY_DEFAULT;
+ regpair = findRegDmnPair(rd);
+ return (regpair != AH_NULL) ? regpair->singleCC : CTRY_DEFAULT;
}
static HAL_BOOL
-isValidRegDmn(int regDmn, REG_DOMAIN *rd)
-{
- int i;
-
- for (i = 0; i < N(regDomains); i++) {
- if (regDomains[i].regDmnEnum == regDmn) {
- if (rd != AH_NULL) {
- OS_MEMCPY(rd, &regDomains[i],
- sizeof(REG_DOMAIN));
- }
- return AH_TRUE;
- }
- }
- return AH_FALSE;
-}
-
-static HAL_BOOL
-isValidRegDmnPair(int regDmnPair)
+IS_BIT_SET(int bit, const uint64_t bitmask[])
{
- int i;
+ int byteOffset, bitnum;
+ uint64_t val;
- if (regDmnPair == NO_ENUMRD)
- return AH_FALSE;
- for (i = 0; i < N(regDomainPairs); i++) {
- if (regDomainPairs[i].regDmnEnum == regDmnPair)
- return AH_TRUE;
- }
- return AH_FALSE;
+ byteOffset = bit/64;
+ bitnum = bit - byteOffset*64;
+ val = ((uint64_t) 1) << bitnum;
+ return (bitmask[byteOffset] & val) != 0;
}
-/*
- * Return the Wireless Mode Regulatory Domain based
- * on the country code and the wireless mode.
- */
-static HAL_BOOL
-getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
- uint16_t channelFlag, REG_DOMAIN *rd)
+static HAL_STATUS
+getregstate(struct ath_hal *ah, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
+ COUNTRY_CODE_TO_ENUM_RD **pcountry,
+ REG_DOMAIN **prd2GHz, REG_DOMAIN **prd5GHz)
{
- int regDmn;
- REG_DMN_PAIR_MAPPING *regPair;
- uint64_t flags;
+ COUNTRY_CODE_TO_ENUM_RD *country;
+ REG_DOMAIN *rd5GHz, *rd2GHz;
- if (country->countryCode == CTRY_DEFAULT) {
- uint16_t rdnum = getEepromRD(ah);
+ if (cc == CTRY_DEFAULT && regDmn == SKU_NONE) {
+ /*
+ * Validate the EEPROM setting and setup defaults
+ */
+ if (!isEepromValid(ah)) {
+ /*
+ * Don't return any channels if the EEPROM has an
+ * invalid regulatory domain/country code setting.
+ */
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: invalid EEPROM contents\n",__func__);
+ return HAL_EEBADREG;
+ }
- if ((rdnum & COUNTRY_ERD_FLAG) == 0) {
- if (isValidRegDmn(rdnum, AH_NULL) ||
- isValidRegDmnPair(rdnum))
- regDmn = rdnum;
- else
- regDmn = country->regDmnEnum;
- } else
- regDmn = country->regDmnEnum;
- } else
+ cc = getDefaultCountry(ah);
+ country = findCountry(cc);
+ if (country == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "NULL Country!, cc %d\n", cc);
+ return HAL_EEBADCC;
+ }
regDmn = country->regDmnEnum;
- regPair = AH_NULL;
- flags = NO_REQ;
- if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
- int i;
-
- for (i = 0; i < N(regDomainPairs); i++) {
- if (regDomainPairs[i].regDmnEnum == regDmn) {
- regPair = &regDomainPairs[i];
- break;
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM cc %u rd 0x%x\n",
+ __func__, cc, regDmn);
+
+ if (country->countryCode == CTRY_DEFAULT) {
+ /*
+ * Check EEPROM; SKU may be for a country, single
+ * domain, or multiple domains (WWR).
+ */
+ uint16_t rdnum = getEepromRD(ah);
+ if ((rdnum & COUNTRY_ERD_FLAG) == 0 &&
+ (findRegDmn(rdnum) != AH_NULL ||
+ findRegDmnPair(rdnum) != AH_NULL)) {
+ regDmn = rdnum;
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: EEPROM rd 0x%x\n", __func__, rdnum);
}
}
- if (regPair == AH_NULL) {
+ } else {
+ country = findCountry(cc);
+ if (country == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: Failed to find reg domain pair %u\n",
- __func__, regDmn);
- return AH_FALSE;
- }
- if (channelFlag & CHANNEL_2GHZ) {
- regDmn = regPair->regDmn2GHz;
- flags = regPair->flags2GHz;
- } else {
- regDmn = regPair->regDmn5GHz;
- flags = regPair->flags5GHz;
+ "unknown country, cc %d\n", cc);
+ return HAL_EINVAL;
}
+ if (regDmn == SKU_NONE)
+ regDmn = country->regDmnEnum;
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u rd 0x%x\n",
+ __func__, cc, regDmn);
}
/*
- * We either started with a unitary reg domain or we've found the
- * unitary reg domain of the pair
+ * Setup per-band state.
*/
- if (isValidRegDmn(regDmn, rd)) {
- if (regPair != AH_NULL)
- rd->pscan &= regPair->pscanMask;
- if ((country->regDmnEnum & MULTI_DOMAIN_MASK) == 0 &&
- flags != NO_REQ)
- rd->flags = flags;
- return AH_TRUE;
+ if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
+ REG_DMN_PAIR_MAPPING *regpair = findRegDmnPair(regDmn);
+ if (regpair == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: no reg domain pair %u for country %u\n",
+ __func__, regDmn, country->countryCode);
+ return HAL_EINVAL;
+ }
+ rd5GHz = findRegDmn(regpair->regDmn5GHz);
+ if (rd5GHz == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: no 5GHz reg domain %u for country %u\n",
+ __func__, regpair->regDmn5GHz, country->countryCode);
+ return HAL_EINVAL;
+ }
+ rd2GHz = findRegDmn(regpair->regDmn2GHz);
+ if (rd2GHz == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: no 2GHz reg domain %u for country %u\n",
+ __func__, regpair->regDmn2GHz, country->countryCode);
+ return HAL_EINVAL;
+ }
} else {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: Failed to find unitary reg domain %u\n", __func__,
- country->regDmnEnum);
- return AH_FALSE;
- }
-}
-
-static HAL_BOOL
-IS_BIT_SET(int bit, const uint64_t bitmask[])
-{
- int byteOffset, bitnum;
- uint64_t val;
-
- byteOffset = bit/64;
- bitnum = bit - byteOffset*64;
- val = ((uint64_t) 1) << bitnum;
- return (bitmask[byteOffset] & val) != 0;
-}
-
-/* Add given regclassid into regclassids array upto max of maxregids */
-static void
-ath_add_regclassid(uint8_t *regclassids, u_int maxregids,
- u_int *nregids, uint8_t regclassid)
-{
- int i;
-
- /* Is regclassid valid? */
- if (regclassid == 0)
- return;
-
- for (i = 0; i < maxregids; i++) {
- if (regclassids[i] == regclassid) /* already present */
- return;
- if (regclassids[i] == 0) { /* free slot */
- regclassids[i] = regclassid;
- (*nregids)++;
- return;
+ rd5GHz = rd2GHz = findRegDmn(regDmn);
+ if (rd2GHz == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: no unitary reg domain %u for country %u\n",
+ __func__, regDmn, country->countryCode);
+ return HAL_EINVAL;
}
}
+ if (pcountry != AH_NULL)
+ *pcountry = country;
+ *prd2GHz = rd2GHz;
+ *prd5GHz = rd5GHz;
+ return HAL_OK;
}
/*
- * Setup the channel list based on the information in the EEPROM and
- * any supplied country code. Note that we also do a bunch of EEPROM
- * verification here and setup certain regulatory-related access
- * control data used later on.
+ * Construct the channel list for the specified regulatory config.
*/
-
-HAL_BOOL
-ath_hal_init_channels(struct ath_hal *ah,
- HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
- uint8_t *regclassids, u_int maxregids, u_int *nregids,
- HAL_CTRY_CODE cc, u_int modeSelect,
- HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels)
+static HAL_STATUS
+getchannels(struct ath_hal *ah,
+ struct ieee80211_channel chans[], u_int maxchans, int *nchans,
+ u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
+ HAL_BOOL enableExtendedChannels,
+ COUNTRY_CODE_TO_ENUM_RD **pcountry,
+ REG_DOMAIN **prd2GHz, REG_DOMAIN **prd5GHz)
{
#define CHANNEL_HALF_BW 10
#define CHANNEL_QUARTER_BW 5
+#define HAL_MODE_11A_ALL \
+ (HAL_MODE_11A | HAL_MODE_11A_TURBO | HAL_MODE_TURBO | \
+ HAL_MODE_11A_QUARTER_RATE | HAL_MODE_11A_HALF_RATE)
+ REG_DOMAIN *rd5GHz, *rd2GHz;
u_int modesAvail;
- uint16_t maxChan;
- COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
- REG_DOMAIN rd5GHz, rd2GHz;
const struct cmode *cm;
- HAL_CHANNEL_INTERNAL *ichans = &AH_PRIVATE(ah)->ah_channels[0];
+ struct ieee80211_channel *ic;
int next, b;
- uint8_t ctl;
-
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u mode 0x%x%s%s\n",
- __func__, cc, modeSelect, enableOutdoor? " Enable outdoor" : " ",
- enableExtendedChannels ? " Enable ecm" : "");
-
- /*
- * Validate the EEPROM setting and setup defaults
- */
- if (!isEepromValid(ah)) {
- /*
- * Don't return any channels if the EEPROM has an
- * invalid regulatory domain/country code setting.
- */
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: invalid EEPROM contents\n",__func__);
- return AH_FALSE;
- }
-
- AH_PRIVATE(ah)->ah_countryCode = getDefaultCountry(ah);
+ HAL_STATUS status;
-#ifndef AH_SUPPORT_11D
- if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT) {
-#endif
- /*
- * We now have enough state to validate any country code
- * passed in by the caller.
- */
- if (!isCountryCodeValid(ah, cc)) {
- /* NB: Atheros silently ignores invalid country codes */
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: invalid country code %d\n", __func__, cc);
- return AH_FALSE;
- }
- AH_PRIVATE(ah)->ah_countryCode = cc & COUNTRY_CODE_MASK;
-#ifndef AH_SUPPORT_11D
- }
-#endif
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u regDmn 0x%x mode 0x%x%s\n",
+ __func__, cc, regDmn, modeSelect,
+ enableExtendedChannels ? " ecm" : "");
- /* Get pointers to the country element and the reg domain elements */
- country = findCountry(AH_PRIVATE(ah)->ah_countryCode);
-
- if (country == AH_NULL) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "NULL Country!, cc= %d\n",
- AH_PRIVATE(ah)->ah_countryCode);
- return AH_FALSE;
- }
+ status = getregstate(ah, cc, regDmn, pcountry, &rd2GHz, &rd5GHz);
+ if (status != HAL_OK)
+ return status;
- if (!getWmRD(ah, country, ~CHANNEL_2GHZ, &rd5GHz)) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: no unitary 5GHz regdomain for country %u\n",
- __func__, AH_PRIVATE(ah)->ah_countryCode);
- return AH_FALSE;
- }
- if (!getWmRD(ah, country, CHANNEL_2GHZ, &rd2GHz)) {
+ /* get modes that HW is capable of */
+ modesAvail = ath_hal_getWirelessModes(ah);
+ /* optimize work below if no 11a channels */
+ if (isChanBitMaskZero(rd5GHz->chan11a) &&
+ (modesAvail & HAL_MODE_11A_ALL)) {
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: no unitary 2GHz regdomain for country %u\n",
- __func__, AH_PRIVATE(ah)->ah_countryCode);
- return AH_FALSE;
+ "%s: disallow all 11a\n", __func__);
+ modesAvail &= ~HAL_MODE_11A_ALL;
}
- modesAvail = ath_hal_getwmodesnreg(ah, country, &rd5GHz);
- maxChan = !enableOutdoor ? country->outdoorChanStart : 7000;
-
- if (maxchans > N(AH_PRIVATE(ah)->ah_channels))
- maxchans = N(AH_PRIVATE(ah)->ah_channels);
next = 0;
+ ic = &chans[0];
for (cm = modes; cm < &modes[N(modes)]; cm++) {
uint16_t c, c_hi, c_lo;
uint64_t *channelBM = AH_NULL;
- REG_DOMAIN *rd = AH_NULL;
REG_DMN_FREQ_BAND *fband = AH_NULL,*freqs;
int low_adj, hi_adj, channelSep, lastc;
+ uint32_t rdflags;
+ uint64_t dfsMask;
+ uint64_t pscan;
if ((cm->mode & modeSelect) == 0) {
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
@@ -2492,10 +2017,22 @@ ath_hal_init_channels(struct ath_hal *ah,
}
switch (cm->mode) {
case HAL_MODE_TURBO:
- rd = &rd5GHz;
- channelBM = rd->chan11a_turbo;
+ case HAL_MODE_11A_TURBO:
+ rdflags = rd5GHz->flags;
+ dfsMask = rd5GHz->dfsMask;
+ pscan = rd5GHz->pscan;
+ if (cm->mode == HAL_MODE_TURBO)
+ channelBM = rd5GHz->chan11a_turbo;
+ else
+ channelBM = rd5GHz->chan11a_dyn_turbo;
freqs = &regDmn5GhzTurboFreq[0];
- ctl = rd->conformanceTestLimit | CTL_TURBO;
+ break;
+ case HAL_MODE_11G_TURBO:
+ rdflags = rd2GHz->flags;
+ dfsMask = rd2GHz->dfsMask;
+ pscan = rd2GHz->pscan;
+ channelBM = rd2GHz->chan11g_turbo;
+ freqs = &regDmn2Ghz11gTurboFreq[0];
break;
case HAL_MODE_11A:
case HAL_MODE_11A_HALF_RATE:
@@ -2503,49 +2040,39 @@ ath_hal_init_channels(struct ath_hal *ah,
case HAL_MODE_11NA_HT20:
case HAL_MODE_11NA_HT40PLUS:
case HAL_MODE_11NA_HT40MINUS:
- rd = &rd5GHz;
+ rdflags = rd5GHz->flags;
+ dfsMask = rd5GHz->dfsMask;
+ pscan = rd5GHz->pscan;
if (cm->mode == HAL_MODE_11A_HALF_RATE)
- channelBM = rd->chan11a_half;
+ channelBM = rd5GHz->chan11a_half;
else if (cm->mode == HAL_MODE_11A_QUARTER_RATE)
- channelBM = rd->chan11a_quarter;
+ channelBM = rd5GHz->chan11a_quarter;
else
- channelBM = rd->chan11a;
+ channelBM = rd5GHz->chan11a;
freqs = &regDmn5GhzFreq[0];
- ctl = rd->conformanceTestLimit;
break;
case HAL_MODE_11B:
- rd = &rd2GHz;
- channelBM = rd->chan11b;
- freqs = &regDmn2GhzFreq[0];
- ctl = rd->conformanceTestLimit | CTL_11B;
- break;
case HAL_MODE_11G:
case HAL_MODE_11G_HALF_RATE:
case HAL_MODE_11G_QUARTER_RATE:
case HAL_MODE_11NG_HT20:
case HAL_MODE_11NG_HT40PLUS:
case HAL_MODE_11NG_HT40MINUS:
- rd = &rd2GHz;
+ rdflags = rd2GHz->flags;
+ dfsMask = rd2GHz->dfsMask;
+ pscan = rd2GHz->pscan;
if (cm->mode == HAL_MODE_11G_HALF_RATE)
- channelBM = rd->chan11g_half;
+ channelBM = rd2GHz->chan11g_half;
else if (cm->mode == HAL_MODE_11G_QUARTER_RATE)
- channelBM = rd->chan11g_quarter;
+ channelBM = rd2GHz->chan11g_quarter;
+ else if (cm->mode == HAL_MODE_11B)
+ channelBM = rd2GHz->chan11b;
else
- channelBM = rd->chan11g;
- freqs = &regDmn2Ghz11gFreq[0];
- ctl = rd->conformanceTestLimit | CTL_11G;
- break;
- case HAL_MODE_11G_TURBO:
- rd = &rd2GHz;
- channelBM = rd->chan11g_turbo;
- freqs = &regDmn2Ghz11gTurboFreq[0];
- ctl = rd->conformanceTestLimit | CTL_108G;
- break;
- case HAL_MODE_11A_TURBO:
- rd = &rd5GHz;
- channelBM = rd->chan11a_dyn_turbo;
- freqs = &regDmn5GhzTurboFreq[0];
- ctl = rd->conformanceTestLimit | CTL_108G;
+ channelBM = rd2GHz->chan11g;
+ if (cm->mode == HAL_MODE_11B)
+ freqs = &regDmn2GhzFreq[0];
+ else
+ freqs = &regDmn2Ghz11gFreq[0];
break;
default:
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
@@ -2571,26 +2098,15 @@ ath_hal_init_channels(struct ath_hal *ah,
fband = &freqs[b];
lastc = 0;
- ath_add_regclassid(regclassids, maxregids,
- nregids, fband->regClassId);
-
for (c = fband->lowChannel + low_adj;
c <= fband->highChannel + hi_adj;
c += fband->channelSep) {
- HAL_CHANNEL_INTERNAL icv;
-
if (!(c_lo <= c && c <= c_hi)) {
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
"%s: c %u out of range [%u..%u]\n",
__func__, c, c_lo, c_hi);
continue;
}
- if (((c+fband->channelSep)/2) > (maxChan+HALF_MAXCHANBW)) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: c %u > maxChan %u\n",
- __func__, c, maxChan);
- continue;
- }
if (next >= maxchans){
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
"%s: too many channels for channel table\n",
@@ -2600,14 +2116,14 @@ ath_hal_init_channels(struct ath_hal *ah,
if ((fband->usePassScan & IS_ECM_CHAN) &&
!enableExtendedChannels) {
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "Skipping ecm channel\n");
+ "skip ecm channel\n");
continue;
}
- /* XXX needs to be in ath_hal_checkchannel */
- if ((rd->flags & NO_HOSTAP) &&
- (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP)) {
+ if ((fband->useDfs & dfsMask) &&
+ (cm->flags & IEEE80211_CHAN_HT40)) {
+ /* NB: DFS and HT40 don't mix */
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "Skipping HOSTAP channel\n");
+ "skip HT40 chan, DFS required\n");
continue;
}
/*
@@ -2617,245 +2133,288 @@ ath_hal_init_channels(struct ath_hal *ah,
if (lastc && channelSep &&
(c-lastc) < channelSep)
continue;
-
- OS_MEMZERO(&icv, sizeof(icv));
- icv.channel = c;
- icv.channelFlags = cm->flags;
- icv.maxRegTxPower = fband->powerDfs;
- icv.antennaMax = fband->antennaMax;
- icv.regDmnFlags = rd->flags;
- icv.conformanceTestLimit = ctl;
- if (fband->usePassScan & rd->pscan)
- icv.channelFlags |= CHANNEL_PASSIVE;
- else
- icv.channelFlags &= ~CHANNEL_PASSIVE;
lastc = c;
- if (fband->useDfs & rd->dfsMask) {
- /* DFS and HT40 don't mix */
- if (cm->mode == HAL_MODE_11NA_HT40PLUS ||
- cm->mode == HAL_MODE_11NA_HT40MINUS)
- continue;
- icv.privFlags = CHANNEL_DFS;
- } else
- icv.privFlags = 0;
- if (rd->flags & LIMIT_FRAME_4MS)
- icv.privFlags |= CHANNEL_4MS_LIMIT;
-
- ichans[next++] = icv;
+
+ OS_MEMZERO(ic, sizeof(*ic));
+ ic->ic_freq = c;
+ ic->ic_flags = cm->flags;
+ ic->ic_maxregpower = fband->powerDfs;
+ ath_hal_getpowerlimits(ah, ic);
+ ic->ic_maxantgain = fband->antennaMax;
+ if (fband->usePassScan & pscan)
+ ic->ic_flags |= IEEE80211_CHAN_PASSIVE;
+ if (fband->useDfs & dfsMask)
+ ic->ic_flags |= IEEE80211_CHAN_DFS;
+ if (IEEE80211_IS_CHAN_5GHZ(ic) &&
+ (rdflags & DISALLOW_ADHOC_11A))
+ ic->ic_flags |= IEEE80211_CHAN_NOADHOC;
+ if (IEEE80211_IS_CHAN_TURBO(ic) &&
+ (rdflags & DISALLOW_ADHOC_11A_TURB))
+ ic->ic_flags |= IEEE80211_CHAN_NOADHOC;
+ if (rdflags & NO_HOSTAP)
+ ic->ic_flags |= IEEE80211_CHAN_NOHOSTAP;
+ if (rdflags & LIMIT_FRAME_4MS)
+ ic->ic_flags |= IEEE80211_CHAN_4MSXMIT;
+ if (rdflags & NEED_NFC)
+ ic->ic_flags |= CHANNEL_NFCREQUIRED;
+
+ ic++, next++;
}
}
}
done:
- if (next != 0) {
- int i;
-
- /* XXX maxchans set above so this cannot happen? */
- if (next > N(AH_PRIVATE(ah)->ah_channels)) {
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
- "%s: too many channels %u; truncating to %u\n",
- __func__, next,
- (int) N(AH_PRIVATE(ah)->ah_channels));
- next = N(AH_PRIVATE(ah)->ah_channels);
- }
-
- /*
- * Keep a private copy of the channel list so we can
- * constrain future requests to only these channels
- */
- ath_hal_sort(ichans, next, sizeof(HAL_CHANNEL_INTERNAL),
- chansort);
- AH_PRIVATE(ah)->ah_nchan = next;
-
- /*
- * Copy the channel list to the public channel list
- */
- for (i = 0; i < next; i++) {
- chans[i].channel = ichans[i].channel;
- chans[i].channelFlags = ichans[i].channelFlags;
- chans[i].privFlags = ichans[i].privFlags;
- chans[i].maxRegTxPower = ichans[i].maxRegTxPower;
- }
- /*
- * Retrieve power limits.
- */
- ath_hal_getpowerlimits(ah, chans, next);
- for (i = 0; i < next; i++) {
- ichans[i].maxTxPower = chans[i].maxTxPower;
- ichans[i].minTxPower = chans[i].minTxPower;
- }
- }
*nchans = next;
- /* XXX copy private setting to public area */
- ah->ah_countryCode = AH_PRIVATE(ah)->ah_countryCode;
- return (next != 0);
+ /* NB: pcountry set above by getregstate */
+ if (prd2GHz != AH_NULL)
+ *prd2GHz = rd2GHz;
+ if (prd5GHz != AH_NULL)
+ *prd5GHz = rd5GHz;
+ return HAL_OK;
+#undef HAL_MODE_11A_ALL
#undef CHANNEL_HALF_BW
#undef CHANNEL_QUARTER_BW
}
/*
- * Return whether or not the specified channel is ok to use
- * based on the current regulatory domain constraints and
- * DFS interference.
+ * Retrieve a channel list without affecting runtime state.
*/
-HAL_CHANNEL_INTERNAL *
-ath_hal_checkchannel(struct ath_hal *ah, const HAL_CHANNEL *c)
+HAL_STATUS
+ath_hal_getchannels(struct ath_hal *ah,
+ struct ieee80211_channel chans[], u_int maxchans, int *nchans,
+ u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
+ HAL_BOOL enableExtendedChannels)
{
-#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
- HAL_CHANNEL_INTERNAL *base, *cc;
- /* NB: be wary of user-specified channel flags */
- int flags = c->channelFlags & CHAN_FLAGS;
- int n, lim, d;
+ return getchannels(ah, chans, maxchans, nchans, modeSelect,
+ cc, regDmn, enableExtendedChannels, AH_NULL, AH_NULL, AH_NULL);
+}
- /*
- * Check current channel to avoid the lookup.
- */
- cc = AH_PRIVATE(ah)->ah_curchan;
- if (cc != AH_NULL && cc->channel == c->channel &&
- (cc->channelFlags & CHAN_FLAGS) == flags) {
- if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
- (cc->channelFlags & CHANNEL_DFS))
- return AH_NULL;
- else
- return cc;
- }
+/*
+ * Handle frequency mapping from 900Mhz range to 2.4GHz range
+ * for GSM radios. This is done when we need the h/w frequency
+ * and the channel is marked IEEE80211_CHAN_GSM.
+ */
+static int
+ath_hal_mapgsm(int sku, int freq)
+{
+ if (sku == SKU_XR9)
+ return 1520 + freq;
+ if (sku == SKU_GZ901)
+ return 1544 + freq;
+ if (sku == SKU_SR9)
+ return 3344 - freq;
+ HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
+ "%s: cannot map freq %u unknown gsm sku %u\n",
+ __func__, freq, sku);
+ return freq;
+}
- /* binary search based on known sorting order */
- base = AH_PRIVATE(ah)->ah_channels;
- n = AH_PRIVATE(ah)->ah_nchan;
- /* binary search based on known sorting order */
- for (lim = n; lim != 0; lim >>= 1) {
- cc = &base[lim>>1];
- d = c->channel - cc->channel;
- if (d == 0) {
- if ((cc->channelFlags & CHAN_FLAGS) == flags) {
- if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
- (cc->channelFlags & CHANNEL_DFS))
- return AH_NULL;
- else
- return cc;
+/*
+ * Setup the internal/private channel state given a table of
+ * net80211 channels. We collapse entries for the same frequency
+ * and record the frequency for doing noise floor processing
+ * where we don't have net80211 channel context.
+ */
+static HAL_BOOL
+assignPrivateChannels(struct ath_hal *ah,
+ struct ieee80211_channel chans[], int nchans, int sku)
+{
+ HAL_CHANNEL_INTERNAL *ic;
+ int i, j, next, freq;
+
+ next = 0;
+ for (i = 0; i < nchans; i++) {
+ struct ieee80211_channel *c = &chans[i];
+ for (j = i-1; j >= 0; j--)
+ if (chans[j].ic_freq == c->ic_freq) {
+ c->ic_devdata = chans[j].ic_devdata;
+ break;
}
- d = flags - (cc->channelFlags & CHAN_FLAGS);
- }
- if (d > 0) {
- base = cc + 1;
- lim--;
+ if (j < 0) {
+ /* new entry, assign a private channel entry */
+ if (next >= N(AH_PRIVATE(ah)->ah_channels)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: too many channels, max %zu\n",
+ __func__, N(AH_PRIVATE(ah)->ah_channels));
+ return AH_FALSE;
+ }
+ /*
+ * Handle frequency mapping for 900MHz devices.
+ * The hardware uses 2.4GHz frequencies that are
+ * down-converted. The 802.11 layer uses the
+ * true frequencies.
+ */
+ freq = IEEE80211_IS_CHAN_GSM(c) ?
+ ath_hal_mapgsm(sku, c->ic_freq) : c->ic_freq;
+
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
+ "%s: private[%3u] %u/0x%x -> channel %u\n",
+ __func__, next, c->ic_freq, c->ic_flags, freq);
+
+ ic = &AH_PRIVATE(ah)->ah_channels[next];
+ /*
+ * NB: This clears privFlags which means ancillary
+ * code like ANI and IQ calibration will be
+ * restarted and re-setup any per-channel state.
+ */
+ OS_MEMZERO(ic, sizeof(*ic));
+ ic->channel = freq;
+ c->ic_devdata = next;
+ next++;
}
}
- HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: no match for %u/0x%x\n",
- __func__, c->channel, c->channelFlags);
- return AH_NULL;
-#undef CHAN_FLAGS
+ AH_PRIVATE(ah)->ah_nchan = next;
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: %u public, %u private channels\n",
+ __func__, nchans, next);
+ return AH_TRUE;
}
/*
- * Return the max allowed antenna gain and apply any regulatory
- * domain specific changes.
- *
- * NOTE: a negative reduction is possible in RD's that only
- * measure radiated power (e.g., ETSI) which would increase
- * that actual conducted output power (though never beyond
- * the calibrated target power).
+ * Setup the channel list based on the information in the EEPROM.
*/
-u_int
-ath_hal_getantennareduction(struct ath_hal *ah, HAL_CHANNEL *chan, u_int twiceGain)
+HAL_STATUS
+ath_hal_init_channels(struct ath_hal *ah,
+ struct ieee80211_channel chans[], u_int maxchans, int *nchans,
+ u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
+ HAL_BOOL enableExtendedChannels)
{
- HAL_CHANNEL_INTERNAL *ichan=AH_NULL;
- int8_t antennaMax;
-
- if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
- antennaMax = twiceGain - ichan->antennaMax*2;
- return (antennaMax < 0) ? 0 : antennaMax;
- } else {
- /* Failed to find the correct index - may be a debug channel */
- return 0;
- }
+ COUNTRY_CODE_TO_ENUM_RD *country;
+ REG_DOMAIN *rd5GHz, *rd2GHz;
+ HAL_STATUS status;
+
+ status = getchannels(ah, chans, maxchans, nchans, modeSelect,
+ cc, regDmn, enableExtendedChannels, &country, &rd2GHz, &rd5GHz);
+ if (status == HAL_OK &&
+ assignPrivateChannels(ah, chans, *nchans, AH_PRIVATE(ah)->ah_currentRD)) {
+ AH_PRIVATE(ah)->ah_rd2GHz = rd2GHz;
+ AH_PRIVATE(ah)->ah_rd5GHz = rd5GHz;
+
+ ah->ah_countryCode = country->countryCode;
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u\n",
+ __func__, ah->ah_countryCode);
+ } else
+ status = HAL_EINVAL;
+ return status;
}
+/*
+ * Set the channel list.
+ */
+HAL_STATUS
+ath_hal_set_channels(struct ath_hal *ah,
+ struct ieee80211_channel chans[], int nchans,
+ HAL_CTRY_CODE cc, HAL_REG_DOMAIN rd)
+{
+ COUNTRY_CODE_TO_ENUM_RD *country;
+ REG_DOMAIN *rd5GHz, *rd2GHz;
+ HAL_STATUS status;
-/* XXX - maybe move ctl decision into channel set area or
- into the tables so no decision is needed in the code */
-
-#define isWwrSKU(_ah) \
- ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
- getEepromRD(_ah) == WORLD)
+ switch (rd) {
+ case SKU_SR9:
+ case SKU_XR9:
+ case SKU_GZ901:
+ /*
+ * Map 900MHz sku's. The frequencies will be mapped
+ * according to the sku to compensate for the down-converter.
+ * We use the FCC for these sku's as the mapped channel
+ * list is known compatible (will need to change if/when
+ * vendors do different mapping in different locales).
+ */
+ status = getregstate(ah, CTRY_DEFAULT, SKU_FCC,
+ &country, &rd2GHz, &rd5GHz);
+ break;
+ default:
+ status = getregstate(ah, cc, rd,
+ &country, &rd2GHz, &rd5GHz);
+ rd = AH_PRIVATE(ah)->ah_currentRD;
+ break;
+ }
+ if (status == HAL_OK && assignPrivateChannels(ah, chans, nchans, rd)) {
+ AH_PRIVATE(ah)->ah_rd2GHz = rd2GHz;
+ AH_PRIVATE(ah)->ah_rd5GHz = rd5GHz;
+ ah->ah_countryCode = country->countryCode;
+ HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u\n",
+ __func__, ah->ah_countryCode);
+ } else
+ status = HAL_EINVAL;
+ return status;
+}
+#ifdef AH_DEBUG
/*
- * Return the test group from the specified channel from
- * the regulatory table.
- *
- * TODO: CTL for 11B CommonMode when regulatory domain is unknown
+ * Return the internal channel corresponding to a public channel.
+ * NB: normally this routine is inline'd (see ah_internal.h)
*/
-u_int
-ath_hal_getctl(struct ath_hal *ah, HAL_CHANNEL *chan)
+HAL_CHANNEL_INTERNAL *
+ath_hal_checkchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
{
- u_int ctl = NO_CTL;
- HAL_CHANNEL_INTERNAL *ichan;
-
- /* Special CTL to signify WWR SKU without a known country */
- if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
- if (IS_CHAN_B(chan)) {
- ctl = SD_NO_CTL | CTL_11B;
- } else if (IS_CHAN_G(chan)) {
- ctl = SD_NO_CTL | CTL_11G;
- } else if (IS_CHAN_108G(chan)) {
- ctl = SD_NO_CTL | CTL_108G;
- } else if (IS_CHAN_T(chan)) {
- ctl = SD_NO_CTL | CTL_TURBO;
- } else {
- ctl = SD_NO_CTL | CTL_11A;
- }
+ HAL_CHANNEL_INTERNAL *cc = &AH_PRIVATE(ah)->ah_channels[c->ic_devdata];
+
+ if (c->ic_devdata < AH_PRIVATE(ah)->ah_nchan &&
+ (c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c)))
+ return cc;
+ if (c->ic_devdata >= AH_PRIVATE(ah)->ah_nchan) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: bad mapping, devdata %u nchans %u\n",
+ __func__, c->ic_devdata, AH_PRIVATE(ah)->ah_nchan);
+ HALASSERT(c->ic_devdata < AH_PRIVATE(ah)->ah_nchan);
} else {
- if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
- ctl = ichan->conformanceTestLimit;
- /* limit 11G OFDM power */
- if (IS_CHAN_PUREG(chan) &&
- (ctl & CTL_MODE_M) == CTL_11B)
- ctl = (ctl &~ CTL_MODE_M) | CTL_11G;
- }
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: no match for %u/0x%x devdata %u channel %u\n",
+ __func__, c->ic_freq, c->ic_flags, c->ic_devdata,
+ cc->channel);
+ HALASSERT(c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c));
}
- return ctl;
+ return AH_NULL;
}
+#endif /* AH_DEBUG */
+
+#define isWwrSKU(_ah) \
+ ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
+ getEepromRD(_ah) == WORLD)
/*
- * Return whether or not a noise floor check is required in
- * the current regulatory domain for the specified channel.
+ * Return the test group for the specific channel based on
+ * the current regulatory setup.
*/
-HAL_BOOL
-ath_hal_getnfcheckrequired(struct ath_hal *ah, HAL_CHANNEL *chan)
+u_int
+ath_hal_getctl(struct ath_hal *ah, const struct ieee80211_channel *c)
{
- HAL_CHANNEL_INTERNAL *ichan;
-
- if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL)
- return ((ichan->regDmnFlags & NEED_NFC) ? AH_TRUE : AH_FALSE);
- return AH_FALSE;
+ u_int ctl;
+
+ if (AH_PRIVATE(ah)->ah_rd2GHz == AH_PRIVATE(ah)->ah_rd5GHz ||
+ (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)))
+ ctl = SD_NO_CTL;
+ else if (IEEE80211_IS_CHAN_2GHZ(c))
+ ctl = AH_PRIVATE(ah)->ah_rd2GHz->conformanceTestLimit;
+ else
+ ctl = AH_PRIVATE(ah)->ah_rd5GHz->conformanceTestLimit;
+ if (IEEE80211_IS_CHAN_B(c))
+ return ctl | CTL_11B;
+ if (IEEE80211_IS_CHAN_G(c))
+ return ctl | CTL_11G;
+ if (IEEE80211_IS_CHAN_108G(c))
+ return ctl | CTL_108G;
+ if (IEEE80211_IS_CHAN_TURBO(c))
+ return ctl | CTL_TURBO;
+ if (IEEE80211_IS_CHAN_A(c))
+ return ctl | CTL_11A;
+ return ctl;
}
/*
- * Insertion sort.
+ * Return the max allowed antenna gain and apply any regulatory
+ * domain specific changes.
+ *
+ * NOTE: a negative reduction is possible in RD's that only
+ * measure radiated power (e.g., ETSI) which would increase
+ * that actual conducted output power (though never beyond
+ * the calibrated target power).
*/
-#define swap(_a, _b, _size) { \
- uint8_t *s = _b; \
- int i = _size; \
- do { \
- uint8_t tmp = *_a; \
- *_a++ = *s; \
- *s++ = tmp; \
- } while (--i); \
- _a -= _size; \
-}
-
-static void
-ath_hal_sort(void *a, size_t n, size_t size, ath_hal_cmp_t *cmp)
+u_int
+ath_hal_getantennareduction(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, u_int twiceGain)
{
- uint8_t *aa = a;
- uint8_t *ai, *t;
-
- for (ai = aa+size; --n >= 1; ai += size)
- for (t = ai; t > aa; t -= size) {
- uint8_t *u = t - size;
- if (cmp(u, t) <= 0)
- break;
- swap(u, t, size);
- }
+ int8_t antennaMax = twiceGain - chan->ic_maxantgain*2;
+ return (antennaMax < 0) ? 0 : antennaMax;
}
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210.h b/sys/dev/ath/ath_hal/ar5210/ar5210.h
index 857cf3c..5156e74 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210.h
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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.h,v 1.8 2008/11/11 02:40:13 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AR5210_H_
#define _ATH_AR5210_H_
@@ -128,20 +128,21 @@ struct ath_hal;
extern void ar5210Detach(struct ath_hal *ah);
extern HAL_BOOL ar5210Reset(struct ath_hal *, HAL_OPMODE,
- HAL_CHANNEL *, HAL_BOOL bChannelChange, HAL_STATUS *);
+ struct ieee80211_channel *, HAL_BOOL bChannelChange, HAL_STATUS *);
extern void ar5210SetPCUConfig(struct ath_hal *);
extern HAL_BOOL ar5210PhyDisable(struct ath_hal *);
extern HAL_BOOL ar5210Disable(struct ath_hal *);
-extern HAL_BOOL ar5210ChipReset(struct ath_hal *, HAL_CHANNEL *);
-extern HAL_BOOL ar5210PerCalibration(struct ath_hal *, HAL_CHANNEL *, HAL_BOOL *);
-extern HAL_BOOL ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
+extern HAL_BOOL ar5210ChipReset(struct ath_hal *, struct ieee80211_channel *);
+extern HAL_BOOL ar5210PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL *);
+extern HAL_BOOL ar5210PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
-extern HAL_BOOL ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
+extern HAL_BOOL ar5210ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *);
extern int16_t ar5210GetNoiseFloor(struct ath_hal *);
extern int16_t ar5210GetNfAdjust(struct ath_hal *,
const HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5210SetTxPowerLimit(struct ath_hal *, uint32_t limit);
-extern HAL_BOOL ar5210SetTransmitPower(struct ath_hal *, HAL_CHANNEL *);
+extern HAL_BOOL ar5210SetTransmitPower(struct ath_hal *,
+ const struct ieee80211_channel *);
extern HAL_BOOL ar5210CalNoiseFloor(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5210ResetDma(struct ath_hal *, HAL_OPMODE);
@@ -273,6 +274,7 @@ extern HAL_INT ar5210SetInterrupts(struct ath_hal *, HAL_INT ints);
extern const HAL_RATE_TABLE *ar5210GetRateTable(struct ath_hal *, u_int mode);
extern HAL_BOOL ar5210AniControl(struct ath_hal *, HAL_ANI_CMD, int );
-extern void ar5210AniPoll(struct ath_hal *, const HAL_NODE_STATS *, HAL_CHANNEL *);
+extern void ar5210AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
+ const struct ieee80211_channel *);
extern void ar5210MibEvent(struct ath_hal *, const HAL_NODE_STATS *);
#endif /* _ATH_AR5210_H_ */
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
index ba75526..555c14c 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_attach.c,v 1.9 2008/11/11 02:40:13 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -31,12 +31,11 @@
static HAL_BOOL ar5210GetChannelEdges(struct ath_hal *,
uint16_t flags, uint16_t *low, uint16_t *high);
static HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah,
- HAL_CHANNEL *chans, uint32_t nchans);
+ struct ieee80211_channel *chan);
static const struct ath_hal_private ar5210hal = {{
.ah_magic = AR5210_MAGIC,
.ah_abi = HAL_ABI_VERSION,
- .ah_countryCode = CTRY_DEFAULT,
.ah_getRateTable = ar5210GetRateTable,
.ah_detach = ar5210Detach,
@@ -303,7 +302,7 @@ static HAL_BOOL
ar5210GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high)
{
- if (flags & CHANNEL_5GHZ) {
+ if (flags & IEEE80211_CHAN_5GHZ) {
*low = 5120;
*high = 5430;
return AH_TRUE;
@@ -313,20 +312,14 @@ ar5210GetChannelEdges(struct ath_hal *ah,
}
static HAL_BOOL
-ar5210GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
+ar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
{
- HAL_CHANNEL *chan;
- int i;
-
/* XXX fill in, this is just a placeholder */
- for (i = 0; i < nchans; i++) {
- chan = &chans[i];
- HALDEBUG(ah, HAL_DEBUG_ATTACH,
- "%s: no min/max power for %u/0x%x\n",
- __func__, chan->channel, chan->channelFlags);
- chan->maxTxPower = AR5210_MAX_RATE_POWER;
- chan->minTxPower = 0;
- }
+ HALDEBUG(ah, HAL_DEBUG_ATTACH,
+ "%s: no min/max power for %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ chan->ic_maxpower = AR5210_MAX_RATE_POWER;
+ chan->ic_minpower = 0;
return AH_TRUE;
}
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_misc.c b/sys/dev/ath/ath_hal/ar5210/ar5210_misc.c
index a673917..bdd58ac 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_misc.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_misc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_misc.c,v 1.6 2008/11/27 22:29:37 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -561,7 +561,8 @@ ar5210AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
}
void
-ar5210AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, HAL_CHANNEL *chan)
+ar5210AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
+ const struct ieee80211_channel *chan)
{
}
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c b/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c
index 40c6768..dd35e2b 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_reset.c,v 1.8 2008/11/11 17:25:16 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -55,7 +55,7 @@ static const uint8_t ar5k0007_pwrSettings[17] = {
static HAL_BOOL ar5210SetResetReg(struct ath_hal *,
uint32_t resetMask, u_int delay);
-static HAL_BOOL ar5210SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+static HAL_BOOL ar5210SetChannel(struct ath_hal *, struct ieee80211_channel *);
static void ar5210SetOperatingMode(struct ath_hal *, int opmode);
/*
@@ -68,7 +68,8 @@ static void ar5210SetOperatingMode(struct ath_hal *, int opmode);
*/
HAL_BOOL
ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
+ struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
+ HAL_STATUS *status)
{
#define N(a) (sizeof (a) /sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
@@ -81,10 +82,10 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HALDEBUG(ah, HAL_DEBUG_RESET,
"%s: opmode %u channel %u/0x%x %s channel\n", __func__,
- opmode, chan->channel, chan->channelFlags,
+ opmode, chan->ic_freq, chan->ic_flags,
bChannelChange ? "change" : "same");
- if ((chan->channelFlags & CHANNEL_5GHZ) == 0) {
+ if (!IEEE80211_IS_CHAN_5GHZ(chan)) {
/* Only 11a mode */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: channel not 5Ghz\n", __func__);
FAIL(HAL_EINVAL);
@@ -96,7 +97,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
switch (opmode) {
@@ -232,17 +233,13 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
(OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) |
(ee->ee_antenna & 0x3));
- if (!ar5210SetChannel(ah, ichan)) {
+ if (!ar5210SetChannel(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n",
__func__);
FAIL(HAL_EIO);
}
- if (bChannelChange) {
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
- }
+ if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
+ chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
/* Activate the PHY */
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ENABLE);
@@ -256,7 +253,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Perform noise floor calibration and set status */
if (!ar5210CalNoiseFloor(ah, ichan)) {
- chan->channelFlags |= CHANNEL_CW_INT;
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: noise floor calibration failed\n", __func__);
FAIL(HAL_EIO);
@@ -296,7 +293,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
return AH_TRUE;
bad:
- if (*status)
+ if (status != AH_NULL)
*status = ecode;
return AH_FALSE;
#undef FAIL
@@ -385,19 +382,20 @@ ar5210Disable(struct ath_hal *ah)
* Places the hardware into reset and then pulls it out of reset
*/
HAL_BOOL
-ar5210ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5210ChipReset(struct ath_hal *ah, struct ieee80211_channel *chan)
{
#define AR_RC_HW (AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC)
HALDEBUG(ah, HAL_DEBUG_RESET, "%s turbo %s\n", __func__,
- chan && IS_CHAN_TURBO(chan) ? "enabled" : "disabled");
+ chan && IEEE80211_IS_CHAN_TURBO(chan) ?
+ "enabled" : "disabled");
if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
return AH_FALSE;
/* Place chip in turbo before reset to cleanly reset clocks */
OS_REG_WRITE(ah, AR_PHY_FRCTL,
- chan && IS_CHAN_TURBO(chan) ? AR_PHY_TURBO_MODE : 0);
+ chan && IEEE80211_IS_CHAN_TURBO(chan) ? AR_PHY_TURBO_MODE : 0);
/*
* Reset the HW.
@@ -444,7 +442,8 @@ enum {
* changes.
*/
HAL_BOOL
-ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
+ar5210PerCalibrationN(struct ath_hal *ah,
+ struct ieee80211_channel *chan, u_int chainMask,
HAL_BOOL longCal, HAL_BOOL *isCalDone)
{
uint32_t regBeacon;
@@ -452,12 +451,8 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
HAL_CHANNEL_INTERNAL *ichan;
ichan = ath_hal_checkchannel(ah, chan);
- if (ichan == AH_NULL) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ if (ichan == AH_NULL)
return AH_FALSE;
- }
/* Disable tx and rx */
OS_REG_WRITE(ah, AR_DIAG_SW,
OS_REG_READ(ah, AR_DIAG_SW) | (AR_DIAG_SW_DIS_TX | AR_DIAG_SW_DIS_RX));
@@ -475,7 +470,7 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
OS_DELAY(10);
/* Change Channel to relock synth */
- if (!ar5210SetChannel(ah, ichan))
+ if (!ar5210SetChannel(ah, chan))
return AH_FALSE;
/* wait for the synthesizer lock to stabilize */
@@ -551,7 +546,7 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
"%s: Performing 2nd Noise Cal\n", __func__);
OS_DELAY(5000);
if (!ar5210CalNoiseFloor(ah, ichan))
- chan->channelFlags |= CHANNEL_CW_INT;
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
}
/* Clear tx and rx disable bit */
@@ -567,13 +562,14 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
}
HAL_BOOL
-ar5210PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
+ar5210PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
+ HAL_BOOL *isIQdone)
{
return ar5210PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
}
HAL_BOOL
-ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5210ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
return AH_TRUE;
}
@@ -729,8 +725,10 @@ ar5210SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
* Get TXPower values and set them in the radio
*/
static HAL_BOOL
-setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
+setupPowerSettings(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ uint8_t cp[17])
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
uint8_t gainFRD, gainF36, gainF48, gainF54;
uint8_t dBmRD, dBm36, dBm48, dBm54, dontcare;
@@ -741,9 +739,9 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
cp[15] = (ee->ee_biasCurrents >> 4) & 0x7;
cp[16] = ee->ee_biasCurrents & 0x7;
- if (chan->channel < 5170 || chan->channel > 5320) {
+ if (freq < 5170 || freq > 5320) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -763,7 +761,7 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
#endif
return AH_FALSE;
}
- group = ((chan->channel - 5170) / 10);
+ group = ((freq - 5170) / 10);
if (group > 11) {
/* Pull 5.29 into the 5.27 group */
@@ -829,7 +827,7 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
* vectors (as determined by the mode), and station configuration
*/
HAL_BOOL
-ar5210SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5210SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
static const uint32_t pwr_regs_start[17] = {
@@ -917,12 +915,13 @@ ar5210SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
* or by disabling the AGC.
*/
static HAL_BOOL
-ar5210SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5210SetChannel(struct ath_hal *ah, struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t data;
/* Set the Channel */
- data = ath_hal_reverseBits((chan->channel - 5120)/10, 5);
+ data = ath_hal_reverseBits((freq - 5120)/10, 5);
data = (data << 1) | 0x41;
OS_REG_WRITE(ah, AR_PHY(0x27), data);
OS_REG_WRITE(ah, AR_PHY(0x30), 0);
@@ -949,7 +948,7 @@ ar5210GetNoiseFloor(struct ath_hal *ah)
* Returns: TRUE for a successful noise floor calibration; else FALSE
*/
HAL_BOOL
-ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
{
int32_t nf, nfLoops;
@@ -980,10 +979,10 @@ ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
if (nf > NORMAL_NF_THRESH) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Bad noise cal %d\n",
__func__, nf);
- chan->rawNoiseFloor = 0;
+ ichan->rawNoiseFloor = 0;
return AH_FALSE;
}
- chan->rawNoiseFloor = nf;
+ ichan->rawNoiseFloor = nf;
return AH_TRUE;
}
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c b/sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c
index 7ce9c83..63cd9fd 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_xmit.c,v 1.5 2008/11/10 04:08:02 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -154,7 +154,7 @@ HAL_BOOL
ar5210ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5210 *ahp = AH5210(ah);
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin;
@@ -177,7 +177,7 @@ ar5210ResetTxQueue(struct ath_hal *ah, u_int q)
return AH_TRUE;
/* Set turbo mode / base mode parameters on or off */
- if (IS_CHAN_TURBO(chan)) {
+ if (IEEE80211_IS_CHAN_TURBO(chan)) {
OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME_TURBO);
OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT_TURBO);
OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY_TURBO);
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211.h b/sys/dev/ath/ath_hal/ar5211/ar5211.h
index e71d78c..b9aad1e 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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.h,v 1.8 2008/11/10 22:08:47 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AR5211_H_
#define _ATH_AR5211_H_
@@ -123,7 +123,6 @@ struct ath_hal_5211 {
HAL_ANT_SETTING ah_diversityControl; /* antenna setting */
uint32_t ah_calibrationTime;
HAL_BOOL ah_bIQCalibration;
- HAL_CHANNEL ah_curchan; /* XXX */
int ah_rfgainState;
uint32_t ah_tx6PowerInHalfDbm; /* power output for 6Mb tx */
uint32_t ah_staId1Defaults; /* STA_ID1 default settings */
@@ -150,19 +149,21 @@ extern struct ath_hal *ar5211Attach(uint16_t, HAL_SOFTC,
extern void ar5211Detach(struct ath_hal *);
extern HAL_BOOL ar5211Reset(struct ath_hal *, HAL_OPMODE,
- HAL_CHANNEL *, HAL_BOOL bChannelChange, HAL_STATUS *);
+ struct ieee80211_channel *, HAL_BOOL bChannelChange,
+ HAL_STATUS *);
extern HAL_BOOL ar5211PhyDisable(struct ath_hal *);
extern HAL_BOOL ar5211Disable(struct ath_hal *);
-extern HAL_BOOL ar5211ChipReset(struct ath_hal *, uint16_t);
-extern HAL_BOOL ar5211PerCalibration(struct ath_hal *, HAL_CHANNEL *, HAL_BOOL *);
-extern HAL_BOOL ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
+extern HAL_BOOL ar5211ChipReset(struct ath_hal *,
+ const struct ieee80211_channel *);
+extern HAL_BOOL ar5211PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL *);
+extern HAL_BOOL ar5211PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
-extern HAL_BOOL ar5211ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
+extern HAL_BOOL ar5211ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *);
extern HAL_BOOL ar5211SetTxPowerLimit(struct ath_hal *, uint32_t limit);
-extern HAL_BOOL ar5211SetTransmitPower(struct ath_hal *, HAL_CHANNEL *);
-extern HAL_BOOL ar5211CalNoiseFloor(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+extern HAL_BOOL ar5211CalNoiseFloor(struct ath_hal *,
+ const struct ieee80211_channel *);
extern HAL_BOOL ar5211SetAntennaSwitchInternal(struct ath_hal *,
- HAL_ANT_SETTING, const HAL_CHANNEL *);
+ HAL_ANT_SETTING, const struct ieee80211_channel *);
extern int16_t ar5211GetNfAdjust(struct ath_hal *,
const HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5211ResetDma(struct ath_hal *, HAL_OPMODE);
@@ -303,6 +304,7 @@ extern HAL_INT ar5211SetInterrupts(struct ath_hal *, HAL_INT ints);
extern const HAL_RATE_TABLE *ar5211GetRateTable(struct ath_hal *, u_int mode);
extern HAL_BOOL ar5211AniControl(struct ath_hal *, HAL_ANI_CMD, int );
-extern void ar5211AniPoll(struct ath_hal *, const HAL_NODE_STATS *, HAL_CHANNEL *);
+extern void ar5211AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
+ const struct ieee80211_channel *);
extern void ar5211MibEvent(struct ath_hal *, const HAL_NODE_STATS *);
#endif /* _ATH_AR5211_H_ */
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
index 74b139b..8164ca4 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_attach.c,v 1.11 2008/11/27 22:29:52 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -31,12 +31,11 @@
static HAL_BOOL ar5211GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high);
static HAL_BOOL ar5211GetChipPowerLimits(struct ath_hal *ah,
- HAL_CHANNEL *chans, uint32_t nchans);
+ struct ieee80211_channel *chan);
static const struct ath_hal_private ar5211hal = {{
.ah_magic = AR5211_MAGIC,
.ah_abi = HAL_ABI_VERSION,
- .ah_countryCode = CTRY_DEFAULT,
.ah_getRateTable = ar5211GetRateTable,
.ah_detach = ar5211Detach,
@@ -232,7 +231,7 @@ ar5211Attach(uint16_t devid, HAL_SOFTC sc,
ahp->ah_acktimeout = (u_int) -1;
ahp->ah_ctstimeout = (u_int) -1;
- if (!ar5211ChipReset(ah, AH_FALSE)) { /* reset chip */
+ if (!ar5211ChipReset(ah, AH_NULL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
@@ -420,12 +419,13 @@ static HAL_BOOL
ar5211GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high)
{
- if (flags & CHANNEL_5GHZ) {
+ if (flags & IEEE80211_CHAN_5GHZ) {
*low = 4920;
*high = 6100;
return AH_TRUE;
}
- if (flags & CHANNEL_2GHZ && ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) {
+ if (flags & IEEE80211_CHAN_2GHZ &&
+ ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) {
*low = 2312;
*high = 2732;
return AH_TRUE;
@@ -434,20 +434,14 @@ ar5211GetChannelEdges(struct ath_hal *ah,
}
static HAL_BOOL
-ar5211GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
+ar5211GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
{
- HAL_CHANNEL *chan;
- int i;
-
/* XXX fill in, this is just a placeholder */
- for (i = 0; i < nchans; i++) {
- chan = &chans[i];
- HALDEBUG(ah, HAL_DEBUG_ATTACH,
- "%s: no min/max power for %u/0x%x\n",
- __func__, chan->channel, chan->channelFlags);
- chan->maxTxPower = MAX_RATE_POWER;
- chan->minTxPower = 0;
- }
+ HALDEBUG(ah, HAL_DEBUG_ATTACH,
+ "%s: no min/max power for %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ chan->ic_maxpower = MAX_RATE_POWER;
+ chan->ic_minpower = 0;
return AH_TRUE;
}
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c b/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
index 5197212..81d29b8 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_misc.c,v 1.7 2008/11/27 22:29:52 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -564,7 +564,8 @@ ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
}
void
-ar5211AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, HAL_CHANNEL *chan)
+ar5211AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
+ const struct ieee80211_channel *chan)
{
}
@@ -603,8 +604,7 @@ ar5211GetAntennaSwitch(struct ath_hal *ah)
HAL_BOOL
ar5211SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
{
- const HAL_CHANNEL *chan =
- (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
if (chan == AH_NULL) {
AH5211(ah)->ah_diversityControl = settings;
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c b/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c
index 6646a4d..1ed6214 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_reset.c,v 1.9 2008/11/27 22:29:52 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -105,17 +105,23 @@ const static CHAN_INFO_2GHZ chan2GHzData[] = {
#define NUM_RATES 8
static HAL_BOOL ar5211SetResetReg(struct ath_hal *ah, uint32_t resetMask);
-static HAL_BOOL ar5211SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+static HAL_BOOL ar5211SetChannel(struct ath_hal *,
+ const struct ieee80211_channel *);
static int16_t ar5211RunNoiseFloor(struct ath_hal *,
uint8_t runTime, int16_t startingNF);
-static HAL_BOOL ar5211IsNfGood(struct ath_hal *, HAL_CHANNEL_INTERNAL *chan);
-static HAL_BOOL ar5211SetRf6and7(struct ath_hal *, HAL_CHANNEL *chan);
-static HAL_BOOL ar5211SetBoardValues(struct ath_hal *, HAL_CHANNEL *chan);
+static HAL_BOOL ar5211IsNfGood(struct ath_hal *,
+ struct ieee80211_channel *chan);
+static HAL_BOOL ar5211SetRf6and7(struct ath_hal *,
+ const struct ieee80211_channel *chan);
+static HAL_BOOL ar5211SetBoardValues(struct ath_hal *,
+ const struct ieee80211_channel *chan);
static void ar5211SetPowerTable(struct ath_hal *,
PCDACS_EEPROM *pSrcStruct, uint16_t channel);
+static HAL_BOOL ar5211SetTransmitPower(struct ath_hal *,
+ const struct ieee80211_channel *);
static void ar5211SetRateTable(struct ath_hal *,
RD_EDGES_POWER *pRdEdgesPower, TRGT_POWER_INFO *pPowerInfo,
- uint16_t numChannels, HAL_CHANNEL *chan);
+ uint16_t numChannels, const struct ieee80211_channel *chan);
static uint16_t ar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue,
const PCDACS_EEPROM *pSrcStruct);
static HAL_BOOL ar5211FindValueInList(uint16_t channel, uint16_t pcdacValue,
@@ -147,7 +153,8 @@ static void ar5211SetOperatingMode(struct ath_hal *, int opmode);
*/
HAL_BOOL
ar5211Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
+ struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
+ HAL_STATUS *status)
{
uint32_t softLedCfg, softLedState;
#define N(a) (sizeof (a) /sizeof (a[0]))
@@ -167,34 +174,16 @@ uint32_t softLedCfg, softLedState;
HALDEBUG(ah, HAL_DEBUG_RESET,
"%s: opmode %u channel %u/0x%x %s channel\n",
- __func__, opmode, chan->channel, chan->channelFlags,
+ __func__, opmode, chan->ic_freq, chan->ic_flags,
bChannelChange ? "change" : "same");
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
-#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
- if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan,CHANNEL_5GHZ)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
- if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
-#undef IS
/*
* Map public channel to private.
*/
ichan = ath_hal_checkchannel(ah, chan);
- if (ichan == AH_NULL) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ if (ichan == AH_NULL)
FAIL(HAL_EINVAL);
- }
switch (opmode) {
case HAL_M_STA:
case HAL_M_IBSS:
@@ -236,10 +225,8 @@ uint32_t softLedCfg, softLedState;
for (i = 0; i < AR_NUM_DCU; i++)
saveFrameSeqCount[i] = OS_REG_READ(ah, AR_DSEQNUM(i));
}
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
+ if (!IEEE80211_IS_CHAN_DFS(chan))
+ chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
}
/*
@@ -259,33 +246,36 @@ uint32_t softLedCfg, softLedState;
softLedCfg = OS_REG_READ(ah, AR_GPIOCR);
softLedState = OS_REG_READ(ah, AR_GPIODO);
- if (!ar5211ChipReset(ah, chan->channelFlags)) {
+ if (!ar5211ChipReset(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
FAIL(HAL_EIO);
}
/* Setup the indices for the next set of register array writes */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- modesIndex = 1;
- freqIndex = 1;
- break;
- case CHANNEL_T:
- modesIndex = 2;
- freqIndex = 1;
- break;
- case CHANNEL_B:
- modesIndex = 3;
- freqIndex = 2;
- break;
- case CHANNEL_PUREG:
- modesIndex = 4;
- freqIndex = 2;
- break;
- default:
- /* Ah, a new wireless mode */
- HALASSERT(0);
- break;
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
+ freqIndex = 1;
+ if (IEEE80211_IS_CHAN_TURBO(chan))
+ modesIndex = 2;
+ else if (IEEE80211_IS_CHAN_A(chan))
+ modesIndex = 1;
+ else {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: invalid channel %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ FAIL(HAL_EINVAL);
+ }
+ } else {
+ freqIndex = 2;
+ if (IEEE80211_IS_CHAN_B(chan))
+ modesIndex = 3;
+ else if (IEEE80211_IS_CHAN_PUREG(chan))
+ modesIndex = 4;
+ else {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: invalid channel %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ FAIL(HAL_EINVAL);
+ }
}
/* Set correct Baseband to analog shift setting to access analog chips. */
@@ -297,12 +287,12 @@ uint32_t softLedCfg, softLedState;
/* Write parameters specific to AR5211 */
if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU) {
- if (IS_CHAN_2GHZ(chan) &&
+ if (IEEE80211_IS_CHAN_2GHZ(chan) &&
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1) {
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint32_t ob2GHz, db2GHz;
- if (IS_CHAN_CCK(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
ob2GHz = ee->ee_ob2GHz[0];
db2GHz = ee->ee_db2GHz[0];
} else {
@@ -437,14 +427,15 @@ uint32_t softLedCfg, softLedState;
/* Setup board specific options for EEPROM version 3 */
ar5211SetBoardValues(ah, chan);
- if (!ar5211SetChannel(ah, ichan)) {
+ if (!ar5211SetChannel(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n",
__func__);
FAIL(HAL_EIO);
}
/* Activate the PHY */
- if (AH_PRIVATE(ah)->ah_devid == AR5211_FPGA11B && IS_CHAN_2GHZ(chan))
+ if (AH_PRIVATE(ah)->ah_devid == AR5211_FPGA11B &&
+ IEEE80211_IS_CHAN_2GHZ(chan))
OS_REG_WRITE(ah, 0xd808, 0x502); /* required for FPGA */
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
@@ -454,7 +445,7 @@ uint32_t softLedCfg, softLedState;
* Value is in 100ns increments.
*/
data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_M;
- if (IS_CHAN_CCK(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
synthDelay = (4 * data) / 22;
} else {
synthDelay = data / 10;
@@ -473,9 +464,9 @@ uint32_t softLedCfg, softLedState;
(void) ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
/* Perform noise floor and set status */
- if (!ar5211CalNoiseFloor(ah, ichan)) {
- if (!IS_CHAN_CCK(chan))
- chan->channelFlags |= CHANNEL_CW_INT;
+ if (!ar5211CalNoiseFloor(ah, chan)) {
+ if (!IEEE80211_IS_CHAN_CCK(chan))
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: noise floor calibration failed\n", __func__);
FAIL(HAL_EIO);
@@ -552,7 +543,7 @@ uint32_t softLedCfg, softLedState;
return AH_TRUE;
bad:
- if (*status)
+ if (status != AH_NULL)
*status = ecode;
return AH_FALSE;
#undef FAIL
@@ -599,49 +590,31 @@ ar5211Disable(struct ath_hal *ah)
* us in the correct mode and we cannot check the hwchannel flags.
*/
HAL_BOOL
-ar5211ChipReset(struct ath_hal *ah, uint16_t channelFlags)
+ar5211ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
if (!ar5211SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
return AH_FALSE;
- /* Set CCK and Turbo modes correctly */
- switch (channelFlags & CHANNEL_ALL) {
- case CHANNEL_2GHZ|CHANNEL_CCK:
- case CHANNEL_2GHZ|CHANNEL_CCK|CHANNEL_TURBO:
- OS_REG_WRITE(ah, AR_PHY_TURBO, 0);
- OS_REG_WRITE(ah, AR5211_PHY_MODE,
- AR5211_PHY_MODE_CCK | AR5211_PHY_MODE_RF2GHZ);
- OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_44);
- /* Wait for the PLL to settle */
- OS_DELAY(DELAY_PLL_SETTLE);
- break;
- case CHANNEL_2GHZ|CHANNEL_OFDM:
- case CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO:
- OS_REG_WRITE(ah, AR_PHY_TURBO, 0);
- if (AH_PRIVATE(ah)->ah_devid == AR5211_DEVID) {
- OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_40);
- OS_DELAY(DELAY_PLL_SETTLE);
+ /* NB: called from attach with chan null */
+ if (chan != AH_NULL) {
+ /* Set CCK and Turbo modes correctly */
+ OS_REG_WRITE(ah, AR_PHY_TURBO, IEEE80211_IS_CHAN_TURBO(chan) ?
+ AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT : 0);
+ if (IEEE80211_IS_CHAN_B(chan)) {
OS_REG_WRITE(ah, AR5211_PHY_MODE,
- AR5211_PHY_MODE_OFDM | AR5211_PHY_MODE_RF2GHZ);
- }
- break;
- case CHANNEL_A:
- case CHANNEL_T:
- if (channelFlags & CHANNEL_TURBO) {
- OS_REG_WRITE(ah, AR_PHY_TURBO,
- AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT);
- } else { /* 5 GHZ OFDM Mode */
- OS_REG_WRITE(ah, AR_PHY_TURBO, 0);
- }
- if (AH_PRIVATE(ah)->ah_devid == AR5211_DEVID) {
+ AR5211_PHY_MODE_CCK | AR5211_PHY_MODE_RF2GHZ);
+ OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_44);
+ /* Wait for the PLL to settle */
+ OS_DELAY(DELAY_PLL_SETTLE);
+ } else if (AH_PRIVATE(ah)->ah_devid == AR5211_DEVID) {
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_40);
OS_DELAY(DELAY_PLL_SETTLE);
OS_REG_WRITE(ah, AR5211_PHY_MODE,
- AR5211_PHY_MODE_OFDM | AR5211_PHY_MODE_RF5GHZ);
+ AR5211_PHY_MODE_OFDM | (IEEE80211_IS_CHAN_2GHZ(chan) ?
+ AR5211_PHY_MODE_RF2GHZ :
+ AR5211_PHY_MODE_RF5GHZ));
}
- break;
}
- /* NB: else no flags set - must be attach calling - do nothing */
/*
* Reset the HW - PCI must be reset after the rest of the
@@ -664,8 +637,8 @@ ar5211ChipReset(struct ath_hal *ah, uint16_t channelFlags)
* changes.
*/
HAL_BOOL
-ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
- HAL_BOOL longCal, HAL_BOOL *isCalDone)
+ar5211PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
+ u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone)
{
struct ath_hal_5211 *ahp = AH5211(ah);
HAL_CHANNEL_INTERNAL *ichan;
@@ -679,7 +652,7 @@ ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
/* IQ calibration in progress. Check to see if it has finished. */
@@ -733,22 +706,21 @@ ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
if (longCal) {
/* Perform noise floor and set status */
- if (!ar5211IsNfGood(ah, ichan)) {
+ if (!ar5211IsNfGood(ah, chan)) {
/* report up and clear internal state */
- chan->channelFlags |= CHANNEL_CW_INT;
- ichan->channelFlags &= ~CHANNEL_CW_INT;
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
return AH_FALSE;
}
- if (!ar5211CalNoiseFloor(ah, ichan)) {
+ if (!ar5211CalNoiseFloor(ah, chan)) {
/*
* Delay 5ms before retrying the noise floor
* just to make sure, as we are in an error
* condition here.
*/
OS_DELAY(5000);
- if (!ar5211CalNoiseFloor(ah, ichan)) {
- if (!IS_CHAN_CCK(chan))
- chan->channelFlags |= CHANNEL_CW_INT;
+ if (!ar5211CalNoiseFloor(ah, chan)) {
+ if (!IEEE80211_IS_CHAN_CCK(chan))
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
return AH_FALSE;
}
}
@@ -758,13 +730,14 @@ ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
}
HAL_BOOL
-ar5211PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
+ar5211PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
+ HAL_BOOL *isIQdone)
{
return ar5211PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
}
HAL_BOOL
-ar5211ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5211ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
/* XXX */
return AH_TRUE;
@@ -810,13 +783,13 @@ ar5211SetResetReg(struct ath_hal *ah, uint32_t resetMask)
* or by disabling the AGC.
*/
static HAL_BOOL
-ar5211SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5211SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t refClk, reg32, data2111;
int16_t chan5111, chanIEEE;
- chanIEEE = ath_hal_mhz2ieee(ah, chan->channel, chan->channelFlags);
- if (IS_CHAN_2GHZ(chan)) {
+ chanIEEE = chan->ic_ieee;
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
const CHAN_INFO_2GHZ* ci =
&chan2GHzData[chanIEEE + CI_2GHZ_INDEX_CORRECTION];
@@ -903,7 +876,7 @@ ar5211RunNoiseFloor(struct ath_hal *ah, uint8_t runTime, int16_t startingNF)
if (i >= 60) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF with runTime %d failed to end on channel %d\n",
- runTime, AH_PRIVATE(ah)->ah_curchan->channel);
+ runTime, AH_PRIVATE(ah)->ah_curchan->ic_freq);
HALDEBUG(ah, HAL_DEBUG_NFCAL,
" PHY NF Reg state: 0x%x\n",
OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
@@ -917,23 +890,24 @@ ar5211RunNoiseFloor(struct ath_hal *ah, uint8_t runTime, int16_t startingNF)
}
static HAL_BOOL
-getNoiseFloorThresh(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, int16_t *nft)
+getNoiseFloorThresh(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ int16_t *nft)
{
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
*nft = ee->ee_noiseFloorThresh[0];
break;
- case CHANNEL_CCK|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_B:
*nft = ee->ee_noiseFloorThresh[1];
break;
- case CHANNEL_OFDM|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_PUREG:
*nft = ee->ee_noiseFloorThresh[2];
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
return AH_TRUE;
@@ -945,8 +919,9 @@ getNoiseFloorThresh(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, int16_t *nft
* Returns: TRUE if the NF is good
*/
static HAL_BOOL
-ar5211IsNfGood(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5211IsNfGood(struct ath_hal *ah, struct ieee80211_channel *chan)
{
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
int16_t nf, nfThresh;
if (!getNoiseFloorThresh(ah, chan, &nfThresh))
@@ -964,9 +939,9 @@ ar5211IsNfGood(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* happens it indicates a problem regardless
* of the band.
*/
- chan->channelFlags |= CHANNEL_CW_INT;
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
}
- chan->rawNoiseFloor = nf;
+ ichan->rawNoiseFloor = nf;
return (nf <= nfThresh);
}
@@ -980,13 +955,14 @@ ar5211IsNfGood(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* Returns: TRUE for a successful noise floor calibration; else FALSE
*/
HAL_BOOL
-ar5211CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5211CalNoiseFloor(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
/* Check for Carrier Wave interference in MKK regulatory zone */
if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_OAHU &&
- ath_hal_getnfcheckrequired(ah, (HAL_CHANNEL *) chan)) {
+ (chan->ic_flags & CHANNEL_NFCREQUIRED)) {
static const uint8_t runtime[3] = { 0, 2, 7 };
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
int16_t nf, nfThresh;
int i;
@@ -1003,9 +979,9 @@ ar5211CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
"%s: run failed with %u > threshold %u "
"(runtime %u)\n", __func__,
nf, nfThresh, runtime[i]);
- chan->rawNoiseFloor = 0;
+ ichan->rawNoiseFloor = 0;
} else
- chan->rawNoiseFloor = nf;
+ ichan->rawNoiseFloor = nf;
}
return (i <= N(runtime));
} else {
@@ -1054,9 +1030,10 @@ ar5211GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
* REQUIRES: Access to the analog device
*/
static HAL_BOOL
-ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5211SetRf6and7(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ath_hal_5211 *ahp = AH5211(ah);
uint16_t rfXpdGain, rfPloSel, rfPwdXpd;
@@ -1064,25 +1041,25 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
uint16_t freqIndex;
int i;
- freqIndex = (chan->channelFlags & CHANNEL_2GHZ) ? 2 : 1;
+ freqIndex = IEEE80211_IS_CHAN_2GHZ(chan) ? 2 : 1;
/*
* TODO: This array mode correspondes with the index used
* during the read.
* For readability, this should be changed to an enum or #define
*/
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A:
- if (chan->channel > 4000 && chan->channel < 5260) {
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
+ if (freq > 4000 && freq < 5260) {
tempOB = ee->ee_ob1;
tempDB = ee->ee_db1;
- } else if (chan->channel >= 5260 && chan->channel < 5500) {
+ } else if (freq >= 5260 && freq < 5500) {
tempOB = ee->ee_ob2;
tempDB = ee->ee_db2;
- } else if (chan->channel >= 5500 && chan->channel < 5725) {
+ } else if (freq >= 5500 && freq < 5725) {
tempOB = ee->ee_ob3;
tempDB = ee->ee_db3;
- } else if (chan->channel >= 5725) {
+ } else if (freq >= 5725) {
tempOB = ee->ee_ob4;
tempDB = ee->ee_db4;
} else {
@@ -1104,14 +1081,14 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
(ar5211Rf6n7[21][freqIndex] & ~0x08) |
(ee->ee_cornerCal.gSel << 3);
break;
- case CHANNEL_CCK|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_B:
tempOB = ee->ee_obFor24;
tempDB = ee->ee_dbFor24;
rfXpdGain = ee->ee_xgain[1];
rfPloSel = ee->ee_xpd[1];
rfPwdXpd = !ee->ee_xpd[1];
break;
- case CHANNEL_OFDM|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_PUREG:
tempOB = ee->ee_obFor24g;
tempDB = ee->ee_dbFor24g;
rfXpdGain = ee->ee_xgain[2];
@@ -1120,7 +1097,7 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -1160,7 +1137,7 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
HAL_BOOL
ar5211SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
- const HAL_CHANNEL *chan)
+ const struct ieee80211_channel *chan)
{
#define ANT_SWITCH_TABLE1 0x9960
#define ANT_SWITCH_TABLE2 0x9964
@@ -1169,13 +1146,13 @@ ar5211SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
uint32_t antSwitchA, antSwitchB;
int ix;
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A: ix = 0; break;
- case CHANNEL_B: ix = 1; break;
- case CHANNEL_PUREG: ix = 2; break;
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A: ix = 0; break;
+ case IEEE80211_CHAN_B: ix = 1; break;
+ case IEEE80211_CHAN_PUREG: ix = 2; break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -1223,27 +1200,27 @@ ar5211SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
* given the channel value
*/
static HAL_BOOL
-ar5211SetBoardValues(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5211SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ath_hal_5211 *ahp = AH5211(ah);
int arrayMode, falseDectectBackoff;
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
arrayMode = 0;
OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
AR_PHY_FRAME_CTL_TX_CLIP, ee->ee_cornerCal.clip);
break;
- case CHANNEL_CCK|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_B:
arrayMode = 1;
break;
- case CHANNEL_OFDM|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_PUREG:
arrayMode = 2;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -1295,10 +1272,11 @@ ar5211SetBoardValues(struct ath_hal *ah, HAL_CHANNEL *chan)
falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;
if (AH_PRIVATE(ah)->ah_eeversion < AR_EEPROM_VER3_3) {
if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&
- IS_CHAN_OFDM(chan))
+ IEEE80211_IS_CHAN_OFDM(chan))
falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;
} else {
- uint32_t remainder = chan->channel % 32;
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
+ uint32_t remainder = freq % 32;
if (remainder && (remainder < 10 || remainder > 22))
falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];
@@ -1331,9 +1309,10 @@ ar5211SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
* Sets the transmit power in the baseband for the given
* operating channel and mode.
*/
-HAL_BOOL
-ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
+static HAL_BOOL
+ar5211SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
TRGT_POWER_INFO *pi;
RD_EDGES_POWER *rep;
@@ -1342,22 +1321,22 @@ ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
int i;
/* setup the pcdac struct to point to the correct info, based on mode */
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
eepromPcdacs.numChannels = ee->ee_numChannels11a;
eepromPcdacs.pChannelList= ee->ee_channels11a;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11a;
nchan = ee->ee_numTargetPwr_11a;
pi = ee->ee_trgtPwr_11a;
break;
- case CHANNEL_OFDM|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_PUREG:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList= ee->ee_channels11g;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11g;
nchan = ee->ee_numTargetPwr_11g;
pi = ee->ee_trgtPwr_11g;
break;
- case CHANNEL_CCK|CHANNEL_2GHZ:
+ case IEEE80211_CHAN_B:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList= ee->ee_channels11b;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11b;
@@ -1366,11 +1345,11 @@ ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
- ar5211SetPowerTable(ah, &eepromPcdacs, chan->channel);
+ ar5211SetPowerTable(ah, &eepromPcdacs, freq);
rep = AH_NULL;
/* Match CTL to EEPROM value */
@@ -1392,7 +1371,8 @@ ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
* table for writing into the hardware.
*/
void
-ar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct, uint16_t channel)
+ar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct,
+ uint16_t channel)
{
static FULL_PCDAC_STRUCT pcdacStruct;
static uint16_t pcdacTable[PWR_TABLE_SIZE];
@@ -1509,11 +1489,12 @@ ar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct, uint16_t chan
* Set the transmit power in the baseband for the given
* operating channel and mode.
*/
-void
+static void
ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
- HAL_CHANNEL *chan)
+ const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ath_hal_5211 *ahp = AH5211(ah);
static uint16_t ratesArray[NUM_RATES];
@@ -1534,9 +1515,9 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
int8_t twiceAntennaGain, twiceAntennaReduction = 0;
pRatesPower = ratesArray;
- twiceMaxRDPower = chan->maxRegTxPower * 2;
+ twiceMaxRDPower = chan->ic_maxregpower * 2;
- if (IS_CHAN_5GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
twiceAntennaGain = ee->ee_antennaGainMax[0];
} else {
twiceAntennaGain = ee->ee_antennaGainMax[1];
@@ -1553,7 +1534,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
}
numEdges = i;
- ar5211GetLowerUpperValues(chan->channel, tempChannelList,
+ ar5211GetLowerUpperValues(freq, tempChannelList,
numEdges, &lowerChannel, &upperChannel);
/* Get the index for this channel */
for (i = 0; i < numEdges; i++)
@@ -1562,7 +1543,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
HALASSERT(i != numEdges);
if ((lowerChannel == upperChannel &&
- lowerChannel == chan->channel) ||
+ lowerChannel == freq) ||
pRdEdgesPower[i].flag) {
twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
HALASSERT(twiceMaxEdgePower > 0);
@@ -1573,7 +1554,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
for (i = 0; i < numChannels; i++)
tempChannelList[i] = pPowerInfo[i].testChannel;
- ar5211GetLowerUpperValues(chan->channel, tempChannelList,
+ ar5211GetLowerUpperValues(freq, tempChannelList,
numChannels, &lowerChannel, &upperChannel);
/* get the index for the channel */
@@ -1587,7 +1568,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
}
for (i = 0; i < NUM_RATES; i++) {
- if (IS_CHAN_OFDM(chan)) {
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
/* power for rates 6,9,12,18,24 is all the same */
if (i < 5) {
lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;
@@ -1627,7 +1608,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
}
}
- twicePower = ar5211GetInterpolatedValue(chan->channel,
+ twicePower = ar5211GetInterpolatedValue(freq,
lowerChannel, upperChannel, lowerPower, upperPower, 0);
/* Reduce power by band edge restrictions */
@@ -1639,7 +1620,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
* this unless specially configured. Then we limit
* power only for non-AP operation.
*/
- if (IS_CHAN_TURBO(chan) &&
+ if (IEEE80211_IS_CHAN_TURBO(chan) &&
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1
#ifdef AH_ENABLE_AP_SUPPORT
&& AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
@@ -1669,14 +1650,14 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
#ifdef AH_DEBUG
HALDEBUG(ah, HAL_DEBUG_RESET,
"%s: final output power setting %d MHz:\n",
- __func__, chan->channel);
+ __func__, chan->ic_freq);
HALDEBUG(ah, HAL_DEBUG_RESET,
"6 Mb %d dBm, MaxRD: %d dBm, MaxEdge %d dBm\n",
scaledPower / 2, twiceMaxRDPower / 2, twiceMaxEdgePower / 2);
HALDEBUG(ah, HAL_DEBUG_RESET, "TPC Scale %d dBm - Ant Red %d dBm\n",
tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale] * 2,
twiceAntennaReduction / 2);
- if (IS_CHAN_TURBO(chan) &&
+ if (IEEE80211_IS_CHAN_TURBO(chan) &&
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1)
HALDEBUG(ah, HAL_DEBUG_RESET, "Max Turbo %d dBm\n",
ee->ee_turbo2WMaxPower5);
@@ -1709,7 +1690,8 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
* Get or interpolate the pcdac value from the calibrated data
*/
uint16_t
-ar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue, const PCDACS_EEPROM *pSrcStruct)
+ar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue,
+ const PCDACS_EEPROM *pSrcStruct)
{
uint16_t powerValue;
uint16_t lFreq, rFreq; /* left and right frequency values */
@@ -1940,11 +1922,11 @@ ar5211InitializeGainValues(struct ath_hal *ah)
static HAL_BOOL
ar5211InvalidGainReadback(struct ath_hal *ah, GAIN_VALUES *gv)
{
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
uint32_t gStep, g;
uint32_t L1, L2, L3, L4;
- if (IS_CHAN_CCK(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
gStep = 0x18;
L1 = 0;
L2 = gStep + 4;
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c b/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c
index 7f75bd0..5d70564 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_xmit.c,v 1.6 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -233,7 +233,7 @@ HAL_BOOL
ar5211ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5211 *ahp = AH5211(ah);
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin, chanCwMin, value;
@@ -254,7 +254,7 @@ ar5211ResetTxQueue(struct ath_hal *ah, u_int q)
* Select cwmin according to channel type.
* NB: chan can be NULL during attach
*/
- if (chan && IS_CHAN_B(chan))
+ if (chan && IEEE80211_IS_CHAN_B(chan))
chanCwMin = INIT_CWMIN_11B;
else
chanCwMin = INIT_CWMIN;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2316.c b/sys/dev/ath/ath_hal/ar5212/ar2316.c
index c724a95..9bfc482 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2316.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2316.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar2316.c,v 1.9 2008/11/15 22:15:46 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -88,28 +88,29 @@ ar2316WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar2316SetChannel(struct ath_hal *ah, struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- if (chan->channel < 4800) {
+ if (freq < 4800) {
uint32_t txctl;
- if (((chan->channel - 2192) % 5) == 0) {
- channelSel = ((chan->channel - 672) * 2 - 3040)/10;
+ if (((freq - 2192) % 5) == 0) {
+ channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
- } else if (((chan->channel - 2224) % 5) == 0) {
- channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
+ } else if (((freq - 2224) % 5) == 0) {
+ channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -117,7 +118,7 @@ ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -125,21 +126,21 @@ ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
- } else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
+ } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 20 << 2), 8);
+ ((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
- } else if ((chan->channel % 10) == 0) {
+ } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 10 << 1), 8);
+ ((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
- } else if ((chan->channel % 5) == 0) {
+ } else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
- (chan->channel - 4800) / 5, 8);
+ (freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -161,7 +162,8 @@ ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar2316SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
+ar2316SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@@ -174,27 +176,18 @@ ar2316SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
struct ar2316State *priv = AR2316(ah);
int regWrites = 0;
- HALDEBUG(ah, HAL_DEBUG_RFPARAM,
- "%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
- __func__, chan->channel, chan->channelFlags, modesIndex);
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv != AH_NULL);
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_B:
+ if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
- break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ } else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- return AH_FALSE;
}
/* Bank 1 Write */
@@ -507,7 +500,8 @@ ar2316getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar2316SetPowerTable(struct ath_hal *ah,
- int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *minPower, int16_t *maxPower,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
struct ath_hal_5212 *ahp = AH5212(ah);
@@ -524,11 +518,11 @@ ar2316SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
- __func__, chan->channel,chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: illegal mode\n", __func__);
@@ -646,9 +640,11 @@ ar2316GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2316 *data)
}
static HAL_BOOL
-ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar2316GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
+ uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2316 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2316 *data=AH_NULL;
@@ -657,9 +653,9 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@@ -673,9 +669,9 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
- if ((chan->channel < data[0].channelValue) ||
- (chan->channel > data[numChannels-1].channelValue)) {
- if (chan->channel < data[0].channelValue) {
+ if ((freq < data[0].channelValue) ||
+ (freq > data[numChannels-1].channelValue)) {
+ if (freq < data[0].channelValue) {
*maxPow = ar2316GetMaxPower(ah, &data[0]);
*minPow = ar2316GetMinPower(ah, &data[0]);
return(AH_TRUE);
@@ -687,19 +683,19 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
- for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
+ for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2316GetMaxPower(ah, &data[i]) - ar2316GetMaxPower(ah, &data[last]);
- *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
+ *maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2316GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2316GetMinPower(ah, &data[i]) - ar2316GetMinPower(ah, &data[last]);
- *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
+ *minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2316GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
- if (chan->channel == data[i].channelValue) {
+ if (freq == data[i].channelValue) {
*maxPow = ar2316GetMaxPower(ah, &data[i]);
*minPow = ar2316GetMinPower(ah, &data[i]);
return(AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2317.c b/sys/dev/ath/ath_hal/ar5212/ar2317.c
index c83cff0..fdf88e3 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2317.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2317.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar2317.c,v 1.8 2008/11/15 22:15:46 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -79,22 +79,23 @@ ar2317WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar2317SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar2317SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- if (chan->channel < 4800) {
+ if (freq < 4800) {
uint32_t txctl;
- channelSel = chan->channel - 2272 ;
+ channelSel = freq - 2272 ;
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -102,21 +103,21 @@ ar2317SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
- } else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
+ } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 20 << 2), 8);
+ ((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
- } else if ((chan->channel % 10) == 0) {
+ } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 10 << 1), 8);
+ ((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
- } else if ((chan->channel % 5) == 0) {
+ } else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
- (chan->channel - 4800) / 5, 8);
+ (freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -138,7 +139,9 @@ ar2317SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar2317SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
+ar2317SetRfRegs(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@@ -151,27 +154,18 @@ ar2317SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
struct ar2317State *priv = AR2317(ah);
int regWrites = 0;
- HALDEBUG(ah, HAL_DEBUG_RFPARAM,
- "%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
- __func__, chan->channel, chan->channelFlags, modesIndex);
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv);
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_B:
+ if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
- break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ } else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- return AH_FALSE;
}
/* Bank 1 Write */
@@ -484,7 +478,8 @@ ar2317getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar2317SetPowerTable(struct ath_hal *ah,
- int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *minPower, int16_t *maxPower,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
struct ath_hal_5212 *ahp = AH5212(ah);
@@ -501,11 +496,11 @@ ar2317SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
- __func__, chan->channel,chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: illegal mode\n", __func__);
@@ -625,9 +620,11 @@ ar2317GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2317 *data)
}
static HAL_BOOL
-ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar2317GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
+ uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2317 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2317 *data=AH_NULL;
@@ -636,9 +633,9 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@@ -652,9 +649,9 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
- if ((chan->channel < data[0].channelValue) ||
- (chan->channel > data[numChannels-1].channelValue)) {
- if (chan->channel < data[0].channelValue) {
+ if ((freq < data[0].channelValue) ||
+ (freq > data[numChannels-1].channelValue)) {
+ if (freq < data[0].channelValue) {
*maxPow = ar2317GetMaxPower(ah, &data[0]);
*minPow = ar2317GetMinPower(ah, &data[0]);
return(AH_TRUE);
@@ -666,19 +663,19 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
- for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
+ for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2317GetMaxPower(ah, &data[i]) - ar2317GetMaxPower(ah, &data[last]);
- *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
+ *maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2317GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2317GetMinPower(ah, &data[i]) - ar2317GetMinPower(ah, &data[last]);
- *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
+ *minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2317GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
- if (chan->channel == data[i].channelValue) {
+ if (freq == data[i].channelValue) {
*maxPow = ar2317GetMaxPower(ah, &data[i]);
*minPow = ar2317GetMinPower(ah, &data[i]);
return(AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2413.c b/sys/dev/ath/ath_hal/ar5212/ar2413.c
index a9e4686..e069444 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2413.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2413.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar2413.c,v 1.8 2008/11/15 22:15:46 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -75,29 +75,29 @@ ar2413WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar2413SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
- uint16_t freq;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- if (chan->channel < 4800) {
+ if (freq < 4800) {
uint32_t txctl;
- if (((chan->channel - 2192) % 5) == 0) {
- channelSel = ((chan->channel - 672) * 2 - 3040)/10;
+ if (((freq - 2192) % 5) == 0) {
+ channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
- } else if (((chan->channel - 2224) % 5) == 0) {
- channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
+ } else if (((freq - 2224) % 5) == 0) {
+ channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -105,7 +105,7 @@ ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -113,26 +113,26 @@ ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
- } else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
- freq = chan->channel - 2; /* Align to even 5MHz raster */
+ } else if (((freq % 5) == 2) && (freq <= 5435)) {
+ freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
- } else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
+ } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 20 << 2), 8);
+ ((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
- } else if ((chan->channel % 10) == 0) {
+ } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 10 << 1), 8);
+ ((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
- } else if ((chan->channel % 5) == 0) {
+ } else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
- (chan->channel - 4800) / 5, 8);
+ (freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -155,7 +155,9 @@ ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar2413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
+ar2413SetRfRegs(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@@ -168,27 +170,18 @@ ar2413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
struct ar2413State *priv = AR2413(ah);
int regWrites = 0;
- HALDEBUG(ah, HAL_DEBUG_RFPARAM,
- "%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
- __func__, chan->channel, chan->channelFlags, modesIndex);
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv);
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_B:
+ if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
- break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ } else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- return AH_FALSE;
}
/* Bank 1 Write */
@@ -501,9 +494,11 @@ ar2413getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar2413SetPowerTable(struct ath_hal *ah,
- int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *minPower, int16_t *maxPower,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
@@ -518,11 +513,11 @@ ar2413SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
- __func__, chan->channel,chan->channelFlags);
+ __func__, freq, chan->ic_flags);
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: illegal mode\n", __func__);
@@ -533,7 +528,7 @@ ar2413SetPowerTable(struct ath_hal *ah,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
numPdGainsUsed = ar2413getGainBoundariesAndPdadcsForPowers(ah,
- chan->channel, pRawDataset, pdGainOverlap_t2,
+ freq, pRawDataset, pdGainOverlap_t2,
&minCalPower2413_t2,gainBoundaries, rfXpdGain, pdadcValues);
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
@@ -640,9 +635,11 @@ ar2413GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
}
static HAL_BOOL
-ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar2413GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
+ uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2413 *data = AH_NULL;
@@ -651,9 +648,9 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@@ -667,9 +664,9 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
- if ((chan->channel < data[0].channelValue) ||
- (chan->channel > data[numChannels-1].channelValue)) {
- if (chan->channel < data[0].channelValue) {
+ if ((freq < data[0].channelValue) ||
+ (freq > data[numChannels-1].channelValue)) {
+ if (freq < data[0].channelValue) {
*maxPow = ar2413GetMaxPower(ah, &data[0]);
*minPow = ar2413GetMinPower(ah, &data[0]);
return(AH_TRUE);
@@ -681,19 +678,19 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
- for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
+ for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2413GetMaxPower(ah, &data[i]) - ar2413GetMaxPower(ah, &data[last]);
- *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
+ *maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2413GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2413GetMinPower(ah, &data[i]) - ar2413GetMinPower(ah, &data[last]);
- *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
+ *minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2413GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
- if (chan->channel == data[i].channelValue) {
+ if (freq == data[i].channelValue) {
*maxPow = ar2413GetMaxPower(ah, &data[i]);
*minPow = ar2413GetMinPower(ah, &data[i]);
return(AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar2425.c b/sys/dev/ath/ath_hal/ar5212/ar2425.c
index adb41b5..8d29474 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar2425.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar2425.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar2425.c,v 1.8 2008/11/16 21:33:05 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -82,24 +82,24 @@ ar2425WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar2425SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar2425SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
- uint16_t freq;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- if (chan->channel < 4800) {
+ if (freq < 4800) {
uint32_t txctl;
- channelSel = chan->channel - 2272;
+ channelSel = freq - 2272;
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
// Enable channel spreading for channel 14
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -108,26 +108,26 @@ ar2425SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
- } else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
- freq = chan->channel - 2; /* Align to even 5MHz raster */
+ } else if (((freq % 5) == 2) && (freq <= 5435)) {
+ freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
- } else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
+ } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 20 << 2), 8);
+ ((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
- } else if ((chan->channel % 10) == 0) {
+ } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 10 << 1), 8);
+ ((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
- } else if ((chan->channel % 5) == 0) {
+ } else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
- (chan->channel - 4800) / 5, 8);
+ (freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -149,7 +149,9 @@ ar2425SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
+ar2425SetRfRegs(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@@ -162,27 +164,18 @@ ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
uint16_t ob2GHz = 0, db2GHz = 0;
int regWrites = 0;
- HALDEBUG(ah, HAL_DEBUG_RFPARAM,
- "==>%s:chan 0x%x flag 0x%x modesIndex 0x%x\n",
- __func__, chan->channel, chan->channelFlags, modesIndex);
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv);
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_B:
+ if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
- break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ } else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- return AH_FALSE;
}
/* Bank 1 Write */
@@ -501,9 +494,11 @@ ar2425getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
/* Same as 2413 set power table */
static HAL_BOOL
ar2425SetPowerTable(struct ath_hal *ah,
- int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *minPower, int16_t *maxPower,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
@@ -514,11 +509,11 @@ ar2425SetPowerTable(struct ath_hal *ah,
uint32_t i, reg32, regoffset;
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s:chan 0x%x flag 0x%x\n",
- __func__, chan->channel,chan->channelFlags);
+ __func__, freq, chan->ic_flags);
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s:illegal mode\n", __func__);
@@ -528,7 +523,7 @@ ar2425SetPowerTable(struct ath_hal *ah,
pdGainOverlap_t2 = (uint16_t) SM(OS_REG_READ(ah, AR_PHY_TPCRG5),
AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
- ar2425getGainBoundariesAndPdadcsForPowers(ah, chan->channel,
+ ar2425getGainBoundariesAndPdadcsForPowers(ah, freq,
pRawDataset, pdGainOverlap_t2,&minCalPower2413_t2,gainBoundaries,
rfXpdGain, pdadcValues);
@@ -603,9 +598,11 @@ ar2425GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
static
HAL_BOOL
-ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
- int16_t *maxPow, int16_t *minPow)
+ar2425GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ int16_t *maxPow, int16_t *minPow)
{
+ uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2413 *data = AH_NULL;
@@ -614,9 +611,9 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@@ -630,9 +627,9 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
- if ((chan->channel < data[0].channelValue) ||
- (chan->channel > data[numChannels-1].channelValue)) {
- if (chan->channel < data[0].channelValue) {
+ if ((freq < data[0].channelValue) ||
+ (freq > data[numChannels-1].channelValue)) {
+ if (freq < data[0].channelValue) {
*maxPow = ar2425GetMaxPower(ah, &data[0]);
*minPow = ar2425GetMinPower(ah, &data[0]);
return(AH_TRUE);
@@ -644,19 +641,19 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
- for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
+ for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2425GetMaxPower(ah, &data[i]) - ar2425GetMaxPower(ah, &data[last]);
- *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
+ *maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2425GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2425GetMinPower(ah, &data[i]) - ar2425GetMinPower(ah, &data[last]);
- *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
+ *minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2425GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
- if (chan->channel == data[i].channelValue) {
+ if (freq == data[i].channelValue) {
*maxPow = ar2425GetMaxPower(ah, &data[i]);
*minPow = ar2425GetMinPower(ah, &data[i]);
return(AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5111.c b/sys/dev/ath/ath_hal/ar5212/ar5111.c
index f009ebe..f9fd3f3 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5111.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5111.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -74,9 +74,10 @@ ar5111WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar5111SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5111SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define CI_2GHZ_INDEX_CORRECTION 19
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t refClk, reg32, data2111;
int16_t chan5111, chanIEEE;
@@ -140,10 +141,10 @@ ar5111SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
{ 1, 0x46, 180 } /* 2732 26 */
};
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- chanIEEE = ath_hal_mhz2ieee(ah, chan->channel, chan->channelFlags);
- if (IS_CHAN_2GHZ(chan)) {
+ chanIEEE = chan->ic_ieee;
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
const CHAN_INFO_2GHZ* ci =
&chan2GHzData[chanIEEE + CI_2GHZ_INDEX_CORRECTION];
uint32_t txctl;
@@ -153,7 +154,7 @@ ar5111SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
| (ci->refClkSel << 4);
chan5111 = ci->channel5111;
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -214,9 +215,10 @@ ar5111GetRfBank(struct ath_hal *ah, int bank)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
+ar5111SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t rfXpdGainFixed, rfPloSel, rfPwdXpd, gainI;
@@ -224,20 +226,22 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
uint32_t ob2GHz, db2GHz, rfReg[N(ar5212Bank6_5111)];
int i, regWrites = 0;
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
+
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_T:
- if (4000 < chan->channel && chan->channel < 5260) {
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
+ if (4000 < freq && freq < 5260) {
tempOB = ee->ee_ob1;
tempDB = ee->ee_db1;
- } else if (5260 <= chan->channel && chan->channel < 5500) {
+ } else if (5260 <= freq && freq < 5500) {
tempOB = ee->ee_ob2;
tempDB = ee->ee_db2;
- } else if (5500 <= chan->channel && chan->channel < 5725) {
+ } else if (5500 <= freq && freq < 5725) {
tempOB = ee->ee_ob3;
tempDB = ee->ee_db3;
- } else if (chan->channel >= 5725) {
+ } else if (freq >= 5725) {
tempOB = ee->ee_ob4;
tempDB = ee->ee_db4;
} else {
@@ -251,7 +255,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
rfPwdXpd = !ee->ee_xpd[headerInfo11A];
gainI = ee->ee_gainI[headerInfo11A];
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
tempOB = ee->ee_obFor24;
tempDB = ee->ee_dbFor24;
ob2GHz = ee->ee_ob2GHz[0];
@@ -262,7 +266,8 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
rfPwdXpd = !ee->ee_xpd[headerInfo11B];
gainI = ee->ee_gainI[headerInfo11B];
break;
- case CHANNEL_G:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_PUREG: /* NB: really 108G */
tempOB = ee->ee_obFor24g;
tempDB = ee->ee_dbFor24g;
ob2GHz = ee->ee_ob2GHz[1];
@@ -275,7 +280,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -285,7 +290,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
/* Bank 0 Write */
for (i = 0; i < N(ar5212Bank0_5111); i++)
rfReg[i] = ar5212Bank0_5111[i][modesIndex];
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212ModifyRfBuffer(rfReg, ob2GHz, 3, 119, 0);
ar5212ModifyRfBuffer(rfReg, db2GHz, 3, 122, 0);
}
@@ -303,7 +308,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
/* Bank 6 Write */
for (i = 0; i < N(ar5212Bank6_5111); i++)
rfReg[i] = ar5212Bank6_5111[i][modesIndex];
- if (IS_CHAN_A(chan)) { /* NB: CHANNEL_A | CHANNEL_T */
+ if (IEEE80211_IS_CHAN_A(chan)) { /* NB: CHANNEL_A | CHANNEL_T */
ar5212ModifyRfBuffer(rfReg, ee->ee_cornerCal.pd84, 1, 51, 3);
ar5212ModifyRfBuffer(rfReg, ee->ee_cornerCal.pd90, 1, 45, 3);
}
@@ -320,11 +325,11 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5212ModifyRfBuffer(rfReg, gainI, 6, 29, 0);
ar5212ModifyRfBuffer(rfReg, rfPloSel, 1, 4, 0);
- if (IS_CHAN_QUARTER_RATE(chan) || IS_CHAN_HALF_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_QUARTER(chan) || IEEE80211_IS_CHAN_HALF(chan)) {
uint32_t rfWaitI, rfWaitS, rfMaxTime;
rfWaitS = 0x1f;
- rfWaitI = (IS_CHAN_HALF_RATE(chan)) ? 0x10 : 0x1f;
+ rfWaitI = (IEEE80211_IS_CHAN_HALF(chan)) ? 0x10 : 0x1f;
rfMaxTime = 3;
ar5212ModifyRfBuffer(rfReg, rfWaitS, 5, 19, 0);
ar5212ModifyRfBuffer(rfReg, rfWaitI, 5, 24, 0);
@@ -383,9 +388,11 @@ interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
*/
static HAL_BOOL
ar5111SetPowerTable(struct ath_hal *ah,
- int16_t *pMinPower, int16_t *pMaxPower, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *pMinPower, int16_t *pMaxPower,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
FULL_PCDAC_STRUCT pcdacStruct;
@@ -404,27 +411,27 @@ ar5111SetPowerTable(struct ath_hal *ah,
PCDACS_EEPROM eepromPcdacs;
/* setup the pcdac struct to point to the correct info, based on mode */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_T:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLTURBOFULL) {
+ case IEEE80211_CHAN_A:
+ case IEEE80211_CHAN_ST:
eepromPcdacs.numChannels = ee->ee_numChannels11a;
eepromPcdacs.pChannelList = ee->ee_channels11a;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11a;
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList = ee->ee_channels11b;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11b;
break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_108G:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList = ee->ee_channels11g;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -444,7 +451,7 @@ ar5111SetPowerTable(struct ath_hal *ah,
/* Fill out the power values for this channel */
for (j = 0; j < pcdacStruct.numPcdacValues; j++ )
- pScaledUpDbm[j] = ar5212GetScaledPower(chan->channel,
+ pScaledUpDbm[j] = ar5212GetScaledPower(freq,
pPcdacValues[j], pSrcStruct);
/* Now scale the pcdac values to fit in the 64 entry power table */
@@ -617,7 +624,8 @@ ar5212GetLowerUpperPcdacs(uint16_t pcdac, uint16_t channel,
}
static HAL_BOOL
-ar5111GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar5111GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
/* XXX - Get 5111 power limits! */
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5112.c b/sys/dev/ath/ath_hal/ar5212/ar5112.c
index b124b1a..c1920b9 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5112.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5112.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5112.c,v 1.7 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -75,29 +75,29 @@ ar5112WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar5112SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5112SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
- uint16_t freq;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- if (chan->channel < 4800) {
+ if (freq < 4800) {
uint32_t txctl;
- if (((chan->channel - 2192) % 5) == 0) {
- channelSel = ((chan->channel - 672) * 2 - 3040)/10;
+ if (((freq - 2192) % 5) == 0) {
+ channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
- } else if (((chan->channel - 2224) % 5) == 0) {
- channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
+ } else if (((freq - 2224) % 5) == 0) {
+ channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -105,7 +105,7 @@ ar5112SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -113,26 +113,26 @@ ar5112SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
- } else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
- freq = chan->channel - 2; /* Align to even 5MHz raster */
+ } else if (((freq % 5) == 2) && (freq <= 5435)) {
+ freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
- } else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
+ } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 20 << 2), 8);
+ ((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
- } else if ((chan->channel % 10) == 0) {
+ } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 10 << 1), 8);
+ ((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
- } else if ((chan->channel % 5) == 0) {
+ } else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
- (chan->channel - 4800) / 5, 8);
+ (freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -175,7 +175,8 @@ ar5112GetRfBank(struct ath_hal *ah, int bank)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
+ar5112SetRfRegs(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
@@ -183,6 +184,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
for (i = 0; i < N(ar5212Bank##_ix##_5112); i++) \
(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_5112[i][_col];\
} while (0)
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t rfXpdSel, gainI;
@@ -194,20 +196,22 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
HALASSERT(priv);
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
+
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_T:
- if (chan->channel > 4000 && chan->channel < 5260) {
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
+ if (freq > 4000 && freq < 5260) {
ob5GHz = ee->ee_ob1;
db5GHz = ee->ee_db1;
- } else if (chan->channel >= 5260 && chan->channel < 5500) {
+ } else if (freq >= 5260 && freq < 5500) {
ob5GHz = ee->ee_ob2;
db5GHz = ee->ee_db2;
- } else if (chan->channel >= 5500 && chan->channel < 5725) {
+ } else if (freq >= 5500 && freq < 5725) {
ob5GHz = ee->ee_ob3;
db5GHz = ee->ee_db3;
- } else if (chan->channel >= 5725) {
+ } else if (freq >= 5725) {
ob5GHz = ee->ee_ob4;
db5GHz = ee->ee_db4;
} else {
@@ -216,14 +220,14 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
rfXpdSel = ee->ee_xpd[headerInfo11A];
gainI = ee->ee_gainI[headerInfo11A];
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
ob2GHz = ee->ee_ob2GHz[0];
db2GHz = ee->ee_db2GHz[0];
rfXpdSel = ee->ee_xpd[headerInfo11B];
gainI = ee->ee_gainI[headerInfo11B];
break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_PUREG: /* NB: really 108G */
ob2GHz = ee->ee_ob2GHz[1];
db2GHz = ee->ee_ob2GHz[1];
rfXpdSel = ee->ee_xpd[headerInfo11G];
@@ -231,7 +235,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -252,7 +256,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdGain[0], 2, 270, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdGain[1], 2, 257, 0);
- if (IS_CHAN_OFDM(chan)) {
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
ar5212ModifyRfBuffer(priv->Bank6Data,
gv->currStep->paramVal[GP_PWD_138], 1, 168, 3);
ar5212ModifyRfBuffer(priv->Bank6Data,
@@ -268,7 +272,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
}
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz, 3, 287, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz, 3, 290, 0);
} else {
@@ -296,18 +300,18 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
/* Setup Bank 7 Setup */
RF_BANK_SETUP(priv, 7, modesIndex);
- if (IS_CHAN_OFDM(chan))
+ if (IEEE80211_IS_CHAN_OFDM(chan))
ar5212ModifyRfBuffer(priv->Bank7Data,
gv->currStep->paramVal[GP_MIXGAIN_OVR], 2, 37, 0);
ar5212ModifyRfBuffer(priv->Bank7Data, gainI, 6, 14, 0);
/* Adjust params for Derby TX power control */
- if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) {
uint32_t rfDelay, rfPeriod;
rfDelay = 0xf;
- rfPeriod = (IS_CHAN_HALF_RATE(chan)) ? 0x8 : 0xf;
+ rfPeriod = (IEEE80211_IS_CHAN_HALF(chan)) ? 0x8 : 0xf;
ar5212ModifyRfBuffer(priv->Bank7Data, rfDelay, 4, 58, 0);
ar5212ModifyRfBuffer(priv->Bank7Data, rfPeriod, 4, 70, 0);
}
@@ -338,9 +342,11 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
*/
static HAL_BOOL
ar5112SetPowerTable(struct ath_hal *ah,
- int16_t *pPowerMin, int16_t *pPowerMax, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *pPowerMin, int16_t *pPowerMax,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint32_t numXpdGain = IS_RADX112_REV2(ah) ? 2 : 1;
@@ -367,24 +373,24 @@ ar5112SetPowerTable(struct ath_hal *ah,
uint16_t xgainList[2];
uint16_t xpdMask;
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_T:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLTURBOFULL) {
+ case IEEE80211_CHAN_A:
+ case IEEE80211_CHAN_ST:
pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11A];
xpdGainMask = ee->ee_xgain[headerInfo11A];
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11B];
xpdGainMask = ee->ee_xgain[headerInfo11B];
break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_108G:
pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11G];
xpdGainMask = ee->ee_xgain[headerInfo11G];
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown channel flags 0x%x\n",
- __func__, chan->channelFlags & CHANNEL_ALL);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -416,7 +422,7 @@ ar5112SetPowerTable(struct ath_hal *ah,
}
}
- ar5212GetLowerUpperIndex(chan->channel, &pPowerExpn->pChannels[0],
+ ar5212GetLowerUpperIndex(freq, &pPowerExpn->pChannels[0],
pPowerExpn->numChannels, &chan_idx_L, &chan_idx_R);
kk = 0;
@@ -474,7 +480,7 @@ ar5112SetPowerTable(struct ath_hal *ah,
if (xgainList[1] == 0xDEAD) {
for (jj = 0; jj < 64; jj++) {
pwr_table0[jj] = interpolate_signed(
- chan->channel, chan_L, chan_R,
+ freq, chan_L, chan_R,
powTableLXPD[0][jj], powTableLXPD[kk][jj]);
}
Pmin = getPminAndPcdacTableFromPowerTable(&pwr_table0[0],
@@ -487,10 +493,10 @@ ar5112SetPowerTable(struct ath_hal *ah,
} else {
for (jj = 0; jj < 64; jj++) {
pwr_table0[jj] = interpolate_signed(
- chan->channel, chan_L, chan_R,
+ freq, chan_L, chan_R,
powTableLXPD[0][jj], powTableLXPD[kk][jj]);
pwr_table1[jj] = interpolate_signed(
- chan->channel, chan_L, chan_R,
+ freq, chan_L, chan_R,
powTableHXPD[0][jj], powTableHXPD[kk][jj]);
}
if (numXpdGain == 2) {
@@ -757,9 +763,11 @@ ar5112GetMinPower(struct ath_hal *ah, const EXPN_DATA_PER_CHANNEL_5112 *data)
}
static HAL_BOOL
-ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar5112GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
+ uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
int numChannels=0,i,last;
int totalD, totalF,totalMin;
@@ -767,16 +775,16 @@ ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
const EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL;
*maxPow = 0;
- if (IS_CHAN_A(chan)) {
+ if (IEEE80211_IS_CHAN_A(chan)) {
powerArray = ee->ee_modePowerArray5112;
data = powerArray[headerInfo11A].pDataPerChannel;
numChannels = powerArray[headerInfo11A].numChannels;
- } else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) {
+ } else if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan)) {
/* XXX - is this correct? Should we also use the same power for turbo G? */
powerArray = ee->ee_modePowerArray5112;
data = powerArray[headerInfo11G].pDataPerChannel;
numChannels = powerArray[headerInfo11G].numChannels;
- } else if (IS_CHAN_B(chan)) {
+ } else if (IEEE80211_IS_CHAN_B(chan)) {
powerArray = ee->ee_modePowerArray5112;
data = powerArray[headerInfo11B].pDataPerChannel;
numChannels = powerArray[headerInfo11B].numChannels;
@@ -789,9 +797,9 @@ ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
- if ((chan->channel < data[0].channelValue) ||
- (chan->channel > data[numChannels-1].channelValue)) {
- if (chan->channel < data[0].channelValue) {
+ if ((freq < data[0].channelValue) ||
+ (freq > data[numChannels-1].channelValue)) {
+ if (freq < data[0].channelValue) {
*maxPow = data[0].maxPower_t4;
*minPow = ar5112GetMinPower(ah, &data[0]);
return(AH_TRUE);
@@ -804,18 +812,18 @@ ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
/* Linearly interpolate the power value now */
for (last=0,i=0;
- (i<numChannels) && (chan->channel > data[i].channelValue);
+ (i<numChannels) && (freq > data[i].channelValue);
last=i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = data[i].maxPower_t4 - data[last].maxPower_t4;
- *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD);
+ *maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD);
totalMin = ar5112GetMinPower(ah,&data[i]) - ar5112GetMinPower(ah, &data[last]);
- *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar5112GetMinPower(ah, &data[last])*totalD)/totalD);
+ *minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) + ar5112GetMinPower(ah, &data[last])*totalD)/totalD);
return (AH_TRUE);
} else {
- if (chan->channel == data[i].channelValue) {
+ if (freq == data[i].channelValue) {
*maxPow = data[i].maxPower_t4;
*minPow = ar5112GetMinPower(ah, &data[i]);
return(AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h
index 6645b76..86a8674 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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.h,v 1.16 2008/11/22 07:42:00 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AR5212_H_
#define _ATH_AR5212_H_
@@ -122,7 +122,6 @@ typedef struct {
uint32_t targetGain;
uint32_t loTrig;
uint32_t hiTrig;
- uint32_t gainFCorrection;
uint32_t active;
const GAIN_OPTIMIZATION_STEP *currStep;
} GAIN_VALUES;
@@ -133,16 +132,18 @@ typedef struct RfHalFuncs {
void (*rfDetach)(struct ath_hal *ah);
void (*writeRegs)(struct ath_hal *,
- u_int modeIndex, u_int freqIndex, int regWrites);
+ u_int modeIndex, u_int freqIndex, int regWrites);
uint32_t *(*getRfBank)(struct ath_hal *ah, int bank);
- HAL_BOOL (*setChannel)(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+ HAL_BOOL (*setChannel)(struct ath_hal *,
+ const struct ieee80211_channel *);
HAL_BOOL (*setRfRegs)(struct ath_hal *,
- HAL_CHANNEL_INTERNAL *, uint16_t modesIndex,
+ const struct ieee80211_channel *, uint16_t modesIndex,
uint16_t *rfXpdGain);
HAL_BOOL (*setPowerTable)(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower,
- HAL_CHANNEL_INTERNAL *, uint16_t *rfXpdGain);
- HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah, HAL_CHANNEL *,
+ const struct ieee80211_channel *, uint16_t *rfXpdGain);
+ HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah,
+ const const struct ieee80211_channel *,
int16_t *maxPow, int16_t *minPow);
int16_t (*getNfAdjust)(struct ath_hal *, const HAL_CHANNEL_INTERNAL*);
} RF_HAL_FUNCS;
@@ -186,8 +187,6 @@ struct ar5212AniState {
uint32_t listenTime;
/* NB: intentionally ordered so data exported to user space is first */
- HAL_CHANNEL c;
- HAL_BOOL isSetup; /* has state to do a restore */
uint32_t txFrameCount; /* Last txFrameCount */
uint32_t rxFrameCount; /* Last rx Frame count */
uint32_t cycleCount; /* Last cycleCount
@@ -319,7 +318,7 @@ struct ath_hal_5212 {
struct ar5212AniParams ah_aniParams24; /* 2.4GHz parameters */
struct ar5212AniParams ah_aniParams5; /* 5GHz parameters */
struct ar5212AniState *ah_curani; /* cached last reference */
- struct ar5212AniState ah_ani[64]; /* per-channel state */
+ struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */
/*
* Transmit power state. Note these are maintained
@@ -395,16 +394,17 @@ struct ath_hal_5212 {
*/
#define SAVE_CCK(_ah, _chan, _flag) do { \
if ((IS_2425(_ah) || IS_2417(_ah)) && \
- (((_chan)->channelFlags) & CHANNEL_CCK)) { \
- (_chan)->channelFlags &= ~CHANNEL_CCK; \
- (_chan)->channelFlags |= CHANNEL_OFDM; \
+ (((_chan)->ic_flags) & IEEE80211_CHAN_CCK)) { \
+ (_chan)->ic_flags &= ~IEEE80211_CHAN_CCK; \
+ (_chan)->ic_flags |= IEEE80211_CHAN_DYN; \
(_flag) = AH_TRUE; \
- } \
+ } else \
+ (_flag) = AH_FALSE; \
} while (0)
#define RESTORE_CCK(_ah, _chan, _flag) do { \
- if ((IS_2425(_ah) || IS_2417(_ah)) && (_flag) == AH_TRUE) {\
- (_chan)->channelFlags &= ~CHANNEL_OFDM; \
- (_chan)->channelFlags |= CHANNEL_CCK; \
+ if ((_flag) && (IS_2425(_ah) || IS_2417(_ah))) { \
+ (_chan)->ic_flags &= ~IEEE80211_CHAN_DYN; \
+ (_chan)->ic_flags |= IEEE80211_CHAN_CCK; \
} \
} while (0)
@@ -525,26 +525,32 @@ extern HAL_STATUS ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *,
struct ath_rx_status *);
extern HAL_BOOL ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status);
-extern HAL_BOOL ar5212SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+ struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
+ HAL_STATUS *status);
+extern HAL_BOOL ar5212SetChannel(struct ath_hal *,
+ const struct ieee80211_channel *);
extern void ar5212SetOperatingMode(struct ath_hal *ah, int opmode);
extern HAL_BOOL ar5212PhyDisable(struct ath_hal *ah);
extern HAL_BOOL ar5212Disable(struct ath_hal *ah);
-extern HAL_BOOL ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *);
-extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan,
- HAL_BOOL *isIQdone);
-extern HAL_BOOL ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
- u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
-extern HAL_BOOL ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
+extern HAL_BOOL ar5212ChipReset(struct ath_hal *ah,
+ const struct ieee80211_channel *);
+extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah,
+ struct ieee80211_channel *chan, HAL_BOOL *isIQdone);
+extern HAL_BOOL ar5212PerCalibrationN(struct ath_hal *ah,
+ struct ieee80211_channel *chan, u_int chainMask,
+ HAL_BOOL longCal, HAL_BOOL *isCalDone);
+extern HAL_BOOL ar5212ResetCalValid(struct ath_hal *ah,
+ const struct ieee80211_channel *);
extern int16_t ar5212GetNoiseFloor(struct ath_hal *ah);
extern void ar5212InitNfCalHistBuffer(struct ath_hal *);
extern int16_t ar5212GetNfHistMid(const int16_t calData[]);
-extern void ar5212SetSpurMitigation(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+extern void ar5212SetSpurMitigation(struct ath_hal *,
+ const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetAntennaSwitchInternal(struct ath_hal *ah,
- HAL_ANT_SETTING settings, const HAL_CHANNEL_INTERNAL *ichan);
+ HAL_ANT_SETTING settings, const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
extern HAL_BOOL ar5212GetChipPowerLimits(struct ath_hal *ah,
- HAL_CHANNEL *chans, uint32_t nchans);
+ struct ieee80211_channel *chan);
extern void ar5212InitializeGainValues(struct ath_hal *);
extern HAL_RFGAIN ar5212GetRfgain(struct ath_hal *ah);
extern void ar5212RequestRfgain(struct ath_hal *);
@@ -597,7 +603,7 @@ extern void ar5212AniPhyErrReport(struct ath_hal *ah,
const struct ath_rx_status *rs);
extern void ar5212ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar5212AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
- HAL_CHANNEL *);
-extern void ar5212AniReset(struct ath_hal *, HAL_CHANNEL_INTERNAL *,
+ const struct ieee80211_channel *);
+extern void ar5212AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int);
#endif /* _ATH_AR5212_H_ */
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c b/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
index bef9c28e..14a26e9 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -99,43 +99,6 @@ disableAniMIBCounters(struct ath_hal *ah)
}
/*
- * This routine returns the index into the aniState array that
- * corresponds to the channel in *chan. If no match is found and the
- * array is still not fully utilized, a new entry is created for the
- * channel. We assume the attach function has already initialized the
- * ah_ani values and only the channel field needs to be set.
- */
-static int
-ar5212GetAniChannelIndex(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
-{
-#define N(a) (sizeof(a) / sizeof(a[0]))
- struct ath_hal_5212 *ahp = AH5212(ah);
- int i;
-
- for (i = 0; i < N(ahp->ah_ani); i++) {
- struct ar5212AniState *asp = &ahp->ah_ani[i];
- if (asp->c.channel == chan->channel)
- return i;
- if (asp->c.channel == 0) {
- asp->c.channel = chan->channel;
- asp->c.channelFlags = chan->channelFlags;
- asp->c.privFlags = chan->privFlags;
- asp->isSetup = AH_FALSE;
- if (IS_CHAN_2GHZ(chan))
- asp->params = &ahp->ah_aniParams24;
- else
- asp->params = &ahp->ah_aniParams5;
- return i;
- }
- }
- /* XXX statistic */
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "No more channel states left. Using channel 0\n");
- return 0; /* XXX gotta return something valid */
-#undef N
-}
-
-/*
* Return the current ANI state of the channel we're on
*/
struct ar5212AniState *
@@ -421,7 +384,7 @@ static void
ar5212AniOfdmErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@@ -504,8 +467,7 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
* weak signal detection and zero firstepLevel to
* maximize CCK sensitivity
*/
- /* XXX can optimize */
- if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
if (!aniState->ofdmWeakSigDetectOff) {
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: rssi %d OWSD off\n",
@@ -532,7 +494,7 @@ static void
ar5212AniCckErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@@ -572,7 +534,8 @@ ar5212AniCckErrTrigger(struct ath_hal *ah)
* CCK sensitivity in 11b/g mode.
*/
/* XXX can optimize */
- if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_B(chan) ||
+ IEEE80211_IS_CHAN_G(chan)) {
if (aniState->firstepLevel > 0) {
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: rssi %d zero ST (was %u)\n",
@@ -613,31 +576,35 @@ ar5212AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
/*
* Restore/reset the ANI parameters and reset the statistics.
* This routine must be called for every channel change.
- *
- * NOTE: This is where ah_curani is set; other ani code assumes
- * it is setup to reflect the current channel.
*/
void
-ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
+ar5212AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_OPMODE opmode, int restore)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- struct ar5212AniState *aniState;
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
+ /* XXX bounds check ic_devdata */
+ struct ar5212AniState *aniState = &ahp->ah_ani[chan->ic_devdata];
uint32_t rxfilter;
- int index;
- index = ar5212GetAniChannelIndex(ah, chan);
- aniState = &ahp->ah_ani[index];
+ if ((ichan->privFlags & CHANNEL_ANI_INIT) == 0) {
+ OS_MEMZERO(aniState, sizeof(*aniState));
+ if (IEEE80211_IS_CHAN_2GHZ(chan))
+ aniState->params = &ahp->ah_aniParams24;
+ else
+ aniState->params = &ahp->ah_aniParams5;
+ ichan->privFlags |= CHANNEL_ANI_INIT;
+ HALASSERT((ichan->privFlags & CHANNEL_ANI_SETUP) == 0);
+ }
ahp->ah_curani = aniState;
#if 0
- ath_hal_printf(ah,"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
- __func__, chan->channel, chan->channelFlags, restore,
- aniState->isSetup, opmode);
+ ath_hal_printf(ah,"%s: chan %u/0x%x restore %d opmode %u%s\n",
+ __func__, chan->ic_freq, chan->ic_flags, restore, opmode,
+ ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#else
- HALDEBUG(ah, HAL_DEBUG_ANI,
- "%s: chan %u/0x%x restore %d setup %d opmode %u\n",
- __func__, chan->channel, chan->channelFlags, restore,
- aniState->isSetup, opmode);
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: chan %u/0x%x restore %d opmode %u%s\n",
+ __func__, chan->ic_freq, chan->ic_flags, restore, opmode,
+ ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#endif
OS_MARK(ah, AH_MARK_ANI_RESET, opmode);
@@ -659,7 +626,7 @@ ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* XXX if ANI follows hardware, we don't care what mode we're
* XXX in, we should keep the ani parameters
*/
- if (restore && aniState->isSetup) {
+ if (restore && (ichan->privFlags & CHANNEL_ANI_SETUP)) {
ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel);
ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
@@ -677,7 +644,7 @@ ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
AH_TRUE);
ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
- aniState->isSetup = AH_TRUE;
+ ichan->privFlags |= CHANNEL_ANI_SETUP;
}
ar5212AniRestart(ah, aniState);
@@ -953,7 +920,7 @@ updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
*/
void
ar5212AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
- HAL_CHANNEL *chan)
+ const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
index 5c51af8..da6a79e 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_attach.c,v 1.18 2008/11/19 22:10:42 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -32,7 +32,6 @@
static const struct ath_hal_private ar5212hal = {{
.ah_magic = AR5212_MAGIC,
.ah_abi = HAL_ABI_VERSION,
- .ah_countryCode = CTRY_DEFAULT,
.ah_getRateTable = ar5212GetRateTable,
.ah_detach = ar5212Detach,
@@ -653,12 +652,12 @@ HAL_BOOL
ar5212GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high)
{
- if (flags & CHANNEL_5GHZ) {
+ if (flags & IEEE80211_CHAN_5GHZ) {
*low = 4915;
*high = 6100;
return AH_TRUE;
}
- if ((flags & CHANNEL_2GHZ) &&
+ if ((flags & IEEE80211_CHAN_2GHZ) &&
(ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) ||
ath_hal_eepromGetFlag(ah, AR_EEP_GMODE))) {
*low = 2312;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
index 637f94e..09af7cb 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -34,8 +34,6 @@
#define AR_NUM_GPIO 6 /* 6 GPIO pins */
#define AR_GPIOD_MASK 0x0000002F /* GPIO data reg r/w mask */
-extern void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
-
void
ar5212GetMacAddress(struct ath_hal *ah, uint8_t *mac)
{
@@ -294,12 +292,12 @@ ar5212ResetTsf(struct ath_hal *ah)
void
ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *rs)
{
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
uint32_t reg;
uint8_t xset;
int i;
- if (chan == AH_NULL || !IS_CHAN_CCK(chan))
+ if (chan == AH_NULL || !IEEE80211_IS_CHAN_CCK(chan))
return;
xset = 0;
for (i = 0; i < rs->rs_count; i++) {
@@ -423,15 +421,15 @@ HAL_BOOL
ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- const HAL_CHANNEL_INTERNAL *ichan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
- if (!ahp->ah_phyPowerOn || ichan == AH_NULL) {
+ if (!ahp->ah_phyPowerOn || chan == AH_NULL) {
/* PHY powered off, just stash settings */
ahp->ah_antControl = setting;
ahp->ah_diversity = (setting == HAL_ANT_VARIABLE);
return AH_TRUE;
}
- return ar5212SetAntennaSwitchInternal(ah, setting, ichan);
+ return ar5212SetAntennaSwitchInternal(ah, setting, chan);
}
HAL_BOOL
@@ -592,7 +590,7 @@ ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
return;
/* Don't apply coverage class to non A channels */
- if (!IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
+ if (!IEEE80211_IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
return;
/* Get core clock rate */
@@ -601,10 +599,10 @@ ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
/* Compute EIFS */
slot = coverageclass * 3 * clkRate;
eifs = coverageclass * 6 * clkRate;
- if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ if (IEEE80211_IS_CHAN_HALF(AH_PRIVATE(ah)->ah_curchan)) {
slot += IFS_SLOT_HALF_RATE;
eifs += IFS_EIFS_HALF_RATE;
- } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(AH_PRIVATE(ah)->ah_curchan)) {
slot += IFS_SLOT_QUARTER_RATE;
eifs += IFS_EIFS_QUARTER_RATE;
} else { /* full rate */
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
index fcf5e72..1c29a86 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_reset.c,v 1.20 2008/11/27 22:30:00 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -34,24 +34,32 @@
static HAL_BOOL ar5212SetResetReg(struct ath_hal *, uint32_t resetMask);
/* NB: public for 5312 use */
-HAL_BOOL ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *);
-HAL_BOOL ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *);
-int16_t ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
-HAL_BOOL ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
-void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
+HAL_BOOL ar5212IsSpurChannel(struct ath_hal *,
+ const struct ieee80211_channel *);
+HAL_BOOL ar5212ChannelChange(struct ath_hal *,
+ const struct ieee80211_channel *);
+int16_t ar5212GetNf(struct ath_hal *, struct ieee80211_channel *);
+HAL_BOOL ar5212SetBoardValues(struct ath_hal *,
+ const struct ieee80211_channel *);
+void ar5212SetDeltaSlope(struct ath_hal *,
+ const struct ieee80211_channel *);
HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
static HAL_BOOL ar5212SetRateTable(struct ath_hal *,
- HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit,
+ const struct ieee80211_channel *, int16_t tpcScaleReduction,
+ int16_t powerLimit,
HAL_BOOL commit, int16_t *minPower, int16_t *maxPower);
static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta);
-static void ar5212GetTargetPowers(struct ath_hal *, HAL_CHANNEL *,
+static void ar5212GetTargetPowers(struct ath_hal *,
+ const struct ieee80211_channel *,
const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
TRGT_POWER_INFO *pNewPower);
static uint16_t ar5212GetMaxEdgePower(uint16_t channel,
const RD_EDGES_POWER *pRdEdgesPower);
-void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
-void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
+void ar5212SetRateDurationTable(struct ath_hal *,
+ const struct ieee80211_channel *);
+void ar5212SetIFSTiming(struct ath_hal *,
+ const struct ieee80211_channel *);
/* NB: public for RF backend use */
void ar5212GetLowerUpperValues(uint16_t value,
@@ -97,7 +105,8 @@ write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
*/
HAL_BOOL
ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
+ struct ieee80211_channel *chan,
+ HAL_BOOL bChannelChange, HAL_STATUS *status)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
@@ -116,26 +125,11 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
int8_t twiceAntennaGain, twiceAntennaReduction;
uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
HAL_BOOL isBmode = AH_FALSE;
- HAL_BOOL ichan_isBmode = AH_FALSE;
HALASSERT(ah->ah_magic == AR5212_MAGIC);
ee = AH_PRIVATE(ah)->ah_eeprom;
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
-#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
- if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
- if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
-#undef IS
/* Bring out of sleep mode */
if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
@@ -148,12 +142,8 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* Map public channel to private.
*/
ichan = ath_hal_checkchannel(ah, chan);
- if (ichan == AH_NULL) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ if (ichan == AH_NULL)
FAIL(HAL_EINVAL);
- }
switch (opmode) {
case HAL_M_STA:
case HAL_M_IBSS:
@@ -168,7 +158,6 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3);
- SAVE_CCK(ah, ichan, ichan_isBmode);
SAVE_CCK(ah, chan, isBmode);
/* Preserve certain DMA hardware registers on a channel change */
@@ -215,13 +204,13 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
*/
if (bChannelChange &&
(AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
- (chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
- ((chan->channelFlags & CHANNEL_ALL) ==
- (AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) {
+ (chan->ic_freq != AH_PRIVATE(ah)->ah_curchan->ic_freq) &&
+ ((chan->ic_flags & IEEE80211_CHAN_ALLTURBO) ==
+ (AH_PRIVATE(ah)->ah_curchan->ic_flags & IEEE80211_CHAN_ALLTURBO))) {
if (ar5212ChannelChange(ah, chan)) {
/* If ChannelChange completed - skip the rest of reset */
/* XXX ani? */
- return AH_TRUE;
+ goto done;
}
}
}
@@ -258,31 +247,32 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
/* Setup the indices for the next set of register array writes */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- modesIndex = 1;
- freqIndex = 1;
- break;
- case CHANNEL_T:
- modesIndex = 2;
- freqIndex = 1;
- break;
- case CHANNEL_B:
- modesIndex = 3;
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
freqIndex = 2;
- break;
- case CHANNEL_PUREG:
- modesIndex = 4;
- freqIndex = 2;
- break;
- case CHANNEL_108G:
- modesIndex = 5;
- freqIndex = 2;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- FAIL(HAL_EINVAL);
+ if (IEEE80211_IS_CHAN_108G(chan))
+ modesIndex = 5;
+ else if (IEEE80211_IS_CHAN_G(chan))
+ modesIndex = 4;
+ else if (IEEE80211_IS_CHAN_B(chan))
+ modesIndex = 3;
+ else {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: invalid channel %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ FAIL(HAL_EINVAL);
+ }
+ } else {
+ freqIndex = 1;
+ if (IEEE80211_IS_CHAN_TURBO(chan))
+ modesIndex = 2;
+ else if (IEEE80211_IS_CHAN_A(chan))
+ modesIndex = 1;
+ else {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: invalid channel %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ FAIL(HAL_EINVAL);
+ }
}
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -297,7 +287,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
- if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) {
ar5212SetIFSTiming(ah, chan);
if (IS_5413(ah)) {
/*
@@ -319,7 +309,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AR_PHY_ADC_CTL_OFF_PWDADC);
/* TX_PWR_ADJ */
- if (chan->channel == 2484) {
+ if (ichan->channel == 2484) {
cckOfdmPwrDelta = SCALE_OC_DELTA(
ee->ee_cckOfdmPwrDelta -
ee->ee_scaledCh14FilterCckDelta);
@@ -328,7 +318,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
ee->ee_cckOfdmPwrDelta);
}
- if (IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_G(chan)) {
OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
SM((ee->ee_cckOfdmPwrDelta*-1),
AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
@@ -365,8 +355,8 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
if (IS_5413(ah) || IS_2417(ah)) {
- uint32_t newReg=1;
- if (IS_DISABLE_FAST_ADC_CHAN(chan->channel))
+ uint32_t newReg = 1;
+ if (IS_DISABLE_FAST_ADC_CHAN(ichan->channel))
newReg = 0;
/* As it's a clock changing register, only write when the value needs to be changed */
if (OS_REG_READ(ah, AR_PHY_FAST_ADC) != newReg)
@@ -374,29 +364,29 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
/* Setup the transmit power values. */
- if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
+ if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
FAIL(HAL_EIO);
}
/* Write the analog registers */
- if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) {
+ if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
__func__);
FAIL(HAL_EIO);
}
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
- if (IS_CHAN_OFDM(chan)) {
- if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
- (!IS_CHAN_B(chan)))
- ar5212SetSpurMitigation(ah, ichan);
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
+ if (IS_5413(ah) ||
+ AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
+ ar5212SetSpurMitigation(ah, chan);
ar5212SetDeltaSlope(ah, chan);
}
/* Setup board specific options for EEPROM version 3 */
- if (!ar5212SetBoardValues(ah, ichan)) {
+ if (!ar5212SetBoardValues(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error setting board options\n", __func__);
FAIL(HAL_EIO);
@@ -439,7 +429,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
- if (!ar5212SetChannel(ah, ichan))
+ if (!ar5212SetChannel(ah, chan))
FAIL(HAL_EIO);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -450,10 +440,9 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Set Tx frame start to tx data start delay */
if (IS_RAD5112_ANY(ah) &&
- (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
- IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
+ (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
txFrm2TxDStart =
- (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
+ IEEE80211_IS_CHAN_HALF(chan) ?
TX_FRAME_D_START_HALF_RATE:
TX_FRAME_D_START_QUARTER_RATE;
OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
@@ -482,7 +471,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* Value is in 100ns increments.
*/
synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
- if (IS_CHAN_CCK(chan)) {
+ if (IEEE80211_IS_CHAN_B(chan)) {
synthDelay = (4 * synthDelay) / 22;
} else {
synthDelay /= 10;
@@ -498,9 +487,9 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* extra BASE_ACTIVATE_DELAY usecs to ensure this condition
* does not happen.
*/
- if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
- } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
} else {
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
@@ -524,7 +513,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
| AR_PHY_AGC_CONTROL_CAL
| AR_PHY_AGC_CONTROL_NF);
- if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
+ if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
@@ -605,7 +594,7 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
SM(0, AR_NOACK_BYTE_OFFSET));
/* Get Antenna Gain reduction */
- if (IS_CHAN_5GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
} else {
ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
@@ -616,27 +605,27 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* TPC for self-generated frames */
ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK);
- if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
- ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
+ if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > chan->ic_maxpower)
+ ackTpcPow = chan->ic_maxpower+ahp->ah_txPowerIndexOffset;
- if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
- ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
+ if (ackTpcPow > (2*chan->ic_maxregpower - twiceAntennaReduction))
+ ackTpcPow = (2*chan->ic_maxregpower - twiceAntennaReduction)
+ ahp->ah_txPowerIndexOffset;
ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS);
- if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
- ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
+ if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > chan->ic_maxpower)
+ ctsTpcPow = chan->ic_maxpower+ahp->ah_txPowerIndexOffset;
- if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
- ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
+ if (ctsTpcPow > (2*chan->ic_maxregpower - twiceAntennaReduction))
+ ctsTpcPow = (2*chan->ic_maxregpower - twiceAntennaReduction)
+ ahp->ah_txPowerIndexOffset;
chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP);
- if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
- chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
+ if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > chan->ic_maxpower)
+ chirpTpcPow = chan->ic_maxpower+ahp->ah_txPowerIndexOffset;
- if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
- chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
+ if (chirpTpcPow > (2*chan->ic_maxregpower - twiceAntennaReduction))
+ chirpTpcPow = (2*chan->ic_maxregpower - twiceAntennaReduction)
+ ahp->ah_txPowerIndexOffset;
if (ackTpcPow > 63)
@@ -667,32 +656,24 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
-
- if (bChannelChange) {
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
- chan->maxRegTxPower = ichan->maxRegTxPower;
- chan->maxTxPower = ichan->maxTxPower;
- chan->minTxPower = ichan->minTxPower;
- }
+#if 0
+done:
+#endif
+ if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
+ chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
- RESTORE_CCK(ah, ichan, ichan_isBmode);
RESTORE_CCK(ah, chan, isBmode);
OS_MARK(ah, AH_MARK_RESET_DONE, 0);
return AH_TRUE;
bad:
- if (ichan != AH_NULL)
- RESTORE_CCK(ah, ichan, ichan_isBmode);
RESTORE_CCK(ah, chan, isBmode);
OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
- if (*status)
+ if (status != AH_NULL)
*status = ecode;
return AH_FALSE;
#undef FAIL
@@ -703,7 +684,7 @@ bad:
* Call the rf backend to change the channel.
*/
HAL_BOOL
-ar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5212SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
@@ -720,7 +701,7 @@ ar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* time, the function returns false as a reset is necessary
*/
HAL_BOOL
-ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212ChannelChange(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t ulCount;
uint32_t data, synthDelay, qnum;
@@ -754,7 +735,7 @@ ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
return AH_FALSE;
/* Change the synth */
- if (!ar5212SetChannel(ah, ichan))
+ if (!ar5212SetChannel(ah, chan))
return AH_FALSE;
/*
@@ -762,7 +743,7 @@ ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
* Read the phy active delay register. Value is in 100ns increments.
*/
data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
- if (IS_CHAN_CCK(ichan)) {
+ if (IEEE80211_IS_CHAN_B(chan)) {
synthDelay = (4 * data) / 22;
} else {
synthDelay = data / 10;
@@ -770,17 +751,17 @@ ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
/* Setup the transmit power values. */
- if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
+ if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
return AH_FALSE;
}
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
- if (IS_CHAN_OFDM(ichan)) {
- if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
- (!IS_CHAN_B(chan)))
- ar5212SetSpurMitigation(ah, ichan);
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
+ if (IS_5413(ah) ||
+ AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
+ ar5212SetSpurMitigation(ah, chan);
ar5212SetDeltaSlope(ah, chan);
}
@@ -789,14 +770,6 @@ ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
/* Start Noise Floor Cal */
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
- chan->maxRegTxPower = ichan->maxRegTxPower;
- chan->maxTxPower = ichan->maxTxPower;
- chan->minTxPower = ichan->minTxPower;
return AH_TRUE;
}
@@ -860,10 +833,10 @@ ar5212Disable(struct ath_hal *ah)
* WARNING: The order of the PLL and mode registers must be correct.
*/
HAL_BOOL
-ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
- OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
+ OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
/*
* Reset the HW - PCI must be reset after the rest of the
@@ -895,48 +868,47 @@ ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
if (IS_5413(ah)) { /* NB: =>'s 5424 also */
rfMode = AR_PHY_MODE_AR5112;
- if (IS_CHAN_HALF_RATE(chan))
+ if (IEEE80211_IS_CHAN_HALF(chan))
rfMode |= AR_PHY_MODE_HALF;
- else if (IS_CHAN_QUARTER_RATE(chan))
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
rfMode |= AR_PHY_MODE_QUARTER;
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
+ if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44_5112;
else
phyPLL = AR_PHY_PLL_CTL_40_5413;
} else if (IS_RAD5111(ah)) {
rfMode = AR_PHY_MODE_AR5111;
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
+ if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44;
else
phyPLL = AR_PHY_PLL_CTL_40;
- if (IS_CHAN_HALF_RATE(chan))
+ if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL = AR_PHY_PLL_CTL_HALF;
- else if (IS_CHAN_QUARTER_RATE(chan))
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL = AR_PHY_PLL_CTL_QUARTER;
} else { /* 5112, 2413, 2316, 2317 */
rfMode = AR_PHY_MODE_AR5112;
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
+ if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44_5112;
else
phyPLL = AR_PHY_PLL_CTL_40_5112;
- if (IS_CHAN_HALF_RATE(chan))
+ if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL |= AR_PHY_PLL_CTL_HALF;
- else if (IS_CHAN_QUARTER_RATE(chan))
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
}
- if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
- IS_CHAN_G(chan)))
+ if (IEEE80211_IS_CHAN_G(chan))
rfMode |= AR_PHY_MODE_DYNAMIC;
- else if (IS_CHAN_OFDM(chan))
+ else if (IEEE80211_IS_CHAN_OFDM(chan))
rfMode |= AR_PHY_MODE_OFDM;
else
rfMode |= AR_PHY_MODE_CCK;
- if (IS_CHAN_5GHZ(chan))
+ if (IEEE80211_IS_CHAN_5GHZ(chan))
rfMode |= AR_PHY_MODE_RF5GHZ;
else
rfMode |= AR_PHY_MODE_RF2GHZ;
- turbo = IS_CHAN_TURBO(chan) ?
+ turbo = IEEE80211_IS_CHAN_TURBO(chan) ?
(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
/*
@@ -946,7 +918,7 @@ ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
* mode bit is set
* - Turbo cannot be set at the same time as CCK or DYNAMIC
*/
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
if (curPhyPLL != phyPLL) {
@@ -972,8 +944,9 @@ ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
* changes.
*/
HAL_BOOL
-ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
- HAL_BOOL longCal, HAL_BOOL *isCalDone)
+ar5212PerCalibrationN(struct ath_hal *ah,
+ struct ieee80211_channel *chan,
+ u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone)
{
#define IQ_CAL_TRIES 10
struct ath_hal_5212 *ahp = AH5212(ah);
@@ -981,19 +954,17 @@ ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
int32_t qCoff, qCoffDenom;
int32_t iqCorrMeas, iCoff, iCoffDenom;
uint32_t powerMeasQ, powerMeasI;
- HAL_BOOL ichan_isBmode = AH_FALSE;
HAL_BOOL isBmode = AH_FALSE;
- OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
+ OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq);
*isCalDone = AH_FALSE;
ichan = ath_hal_checkchannel(ah, chan);
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
- SAVE_CCK(ah, ichan, ichan_isBmode);
SAVE_CCK(ah, chan, isBmode);
if (ahp->ah_bIQCalibration == IQ_CAL_DONE ||
@@ -1019,11 +990,16 @@ ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
if (powerMeasI && powerMeasQ)
break;
/* Do we really need this??? */
- OS_REG_WRITE (ah, AR_PHY_TIMING_CTRL4,
- OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) |
- AR_PHY_TIMING_CTRL4_DO_IQCAL);
+ OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
+ AR_PHY_TIMING_CTRL4_DO_IQCAL);
} while (++i < IQ_CAL_TRIES);
+ HALDEBUG(ah, HAL_DEBUG_PERCAL,
+ "%s: IQ cal finished: %d tries\n", __func__, i);
+ HALDEBUG(ah, HAL_DEBUG_PERCAL,
+ "%s: powerMeasI %u powerMeasQ %u iqCorrMeas %d\n",
+ __func__, powerMeasI, powerMeasQ, iqCorrMeas);
+
/*
* Prescale these values to remove 64-bit operation
* requirement at the loss of a little precision.
@@ -1050,19 +1026,7 @@ ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
}
HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "****************** MISGATED IQ CAL! *******************\n");
- HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "time = %d, i = %d, \n", OS_GETUPTIME(ah), i);
- HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "powerMeasI = 0x%08x\n", powerMeasI);
- HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "powerMeasQ = 0x%08x\n", powerMeasQ);
- HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "iqCorrMeas = 0x%08x\n", iqCorrMeas);
- HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "iCoff = %d\n", iCoff);
- HALDEBUG(ah, HAL_DEBUG_PERCAL,
- "qCoff = %d\n", qCoff);
+ "%s: iCoff %d qCoff %d\n", __func__, iCoff, qCoff);
/* Write values and enable correction */
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
@@ -1073,12 +1037,13 @@ ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
ahp->ah_bIQCalibration = IQ_CAL_DONE;
- ichan->iqCalValid = AH_TRUE;
+ ichan->privFlags |= CHANNEL_IQVALID;
ichan->iCoff = iCoff;
ichan->qCoff = qCoff;
}
- } else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE &&
- !ichan->iqCalValid) {
+ } else if (!IEEE80211_IS_CHAN_B(chan) &&
+ ahp->ah_bIQCalibration == IQ_CAL_DONE &&
+ (ichan->privFlags & CHANNEL_IQVALID) == 0) {
/*
* Start IQ calibration if configured channel has changed.
* Use a magic number of 15 based on default value.
@@ -1094,20 +1059,14 @@ ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
if (longCal) {
/* Check noise floor results */
- ar5212GetNf(ah, ichan);
-
- if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) {
+ ar5212GetNf(ah, chan);
+ if (!IEEE80211_IS_CHAN_CWINT(chan)) {
/* Perform cal for 5Ghz channels and any OFDM on 5112 */
- if (IS_CHAN_5GHZ(chan) ||
- (IS_RAD5112(ah) && IS_CHAN_OFDM(chan)))
+ if (IEEE80211_IS_CHAN_5GHZ(chan) ||
+ (IS_RAD5112(ah) && IEEE80211_IS_CHAN_OFDM(chan)))
ar5212RequestRfgain(ah);
- } else {
- /* report up and clear internal state */
- chan->channelFlags |= CHANNEL_CW_INT;
- ichan->channelFlags &= ~CHANNEL_CW_INT;
}
}
- RESTORE_CCK(ah, ichan, ichan_isBmode);
RESTORE_CCK(ah, chan, isBmode);
return AH_TRUE;
@@ -1115,15 +1074,25 @@ ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
}
HAL_BOOL
-ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
+ar5212PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
+ HAL_BOOL *isIQdone)
{
return ar5212PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
}
HAL_BOOL
-ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
- /* XXX */
+ HAL_CHANNEL_INTERNAL *ichan;
+
+ ichan = ath_hal_checkchannel(ah, chan);
+ if (ichan == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: invalid channel %u/0x%x; no mapping\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ return AH_FALSE;
+ }
+ ichan->privFlags &= ~CHANNEL_IQVALID;
return AH_TRUE;
}
@@ -1181,26 +1150,28 @@ ar5212GetNoiseFloor(struct ath_hal *ah)
}
static HAL_BOOL
-getNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
+getNoiseFloorThresh(struct ath_hal *ah, const struct ieee80211_channel *chan,
int16_t *nft)
{
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
HALASSERT(ah->ah_magic == AR5212_MAGIC);
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
*nft = ee->ee_noiseFloorThresh[headerInfo11A];
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
*nft = ee->ee_noiseFloorThresh[headerInfo11B];
break;
- case CHANNEL_PUREG:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_PUREG: /* NB: really 108G */
*nft = ee->ee_noiseFloorThresh[headerInfo11G];
break;
default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: invalid channel flags %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
return AH_TRUE;
@@ -1260,18 +1231,19 @@ ar5212GetNfHistMid(const int16_t calData[AR512_NF_CAL_HIST_MAX])
* Read the NF and check it against the noise floor threshhold
*/
int16_t
-ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5212GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212NfCalHist *h = &ahp->ah_nfCalHist;
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
int16_t nf, nfThresh;
int32_t val;
if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: NF did not complete in calibration window\n", __func__);
- chan->rawNoiseFloor = h->privNF; /* most recent value */
- return chan->rawNoiseFloor;
+ ichan->rawNoiseFloor = h->privNF; /* most recent value */
+ return ichan->rawNoiseFloor;
}
/*
@@ -1288,7 +1260,7 @@ ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* happens it indicates a problem regardless
* of the band.
*/
- chan->channelFlags |= CHANNEL_CW_INT;
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
nf = 0;
}
} else
@@ -1342,7 +1314,7 @@ ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
- return (chan->rawNoiseFloor = nf);
+ return (ichan->rawNoiseFloor = nf);
}
/*
@@ -1379,7 +1351,7 @@ ar5212SetCompRegs(struct ath_hal *ah)
HAL_BOOL
ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
- const HAL_CHANNEL_INTERNAL *chan)
+ const struct ieee80211_channel *chan)
{
#define ANT_SWITCH_TABLE1 AR_PHY(88)
#define ANT_SWITCH_TABLE2 AR_PHY(89)
@@ -1387,25 +1359,30 @@ ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint32_t antSwitchA, antSwitchB;
int ix;
- HAL_BOOL isBmode = AH_FALSE;
- /* NB: need local copy for SAVE/RESTORE 'cuz chan is const */
- HAL_CHANNEL_INTERNAL ichan = *chan;
HALASSERT(ah->ah_magic == AR5212_MAGIC);
HALASSERT(ahp->ah_phyPowerOn);
- SAVE_CCK(ah, &ichan, isBmode);
- switch (ichan.channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A: ix = 0; break;
- case CHANNEL_B: ix = 1; break;
- case CHANNEL_PUREG: ix = 2; break;
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
+ ix = 0;
+ break;
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_PUREG: /* NB: 108G */
+ ix = 2;
+ break;
+ case IEEE80211_CHAN_B:
+ if (IS_2425(ah) || IS_2417(ah)) {
+ /* NB: Nala/Swan: 11b is handled using 11g */
+ ix = 2;
+ } else
+ ix = 1;
+ break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, ichan.channelFlags);
- RESTORE_CCK(ah, &ichan, isBmode);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
- RESTORE_CCK(ah, &ichan, isBmode);
antSwitchA = ee->ee_antennaControl[1][ix]
| (ee->ee_antennaControl[2][ix] << 6)
@@ -1460,13 +1437,14 @@ ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
}
HAL_BOOL
-ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212IsSpurChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
- uint32_t clockFreq =
- ((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32);
- return ( ((chan->channel % clockFreq) != 0)
- && (((chan->channel % clockFreq) < 10)
- || (((chan->channel) % clockFreq) > 22)) );
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
+ uint32_t clockFreq =
+ ((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32);
+ return ( ((freq % clockFreq) != 0)
+ && (((freq % clockFreq) < 10)
+ || (((freq) % clockFreq) > 22)) );
}
/*
@@ -1474,7 +1452,7 @@ ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan)
* given the channel value.
*/
HAL_BOOL
-ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5212SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define NO_FALSE_DETECT_BACKOFF 2
#define CB22_FALSE_DETECT_BACKOFF 6
@@ -1484,32 +1462,33 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
int arrayMode, falseDectectBackoff;
- int is2GHz = IS_CHAN_2GHZ(chan);
+ int is2GHz = IEEE80211_IS_CHAN_2GHZ(chan);
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
int8_t adcDesiredSize, pgaDesiredSize;
uint16_t switchSettling, txrxAtten, rxtxMargin;
int iCoff, qCoff;
HALASSERT(ah->ah_magic == AR5212_MAGIC);
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_T:
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLTURBOFULL) {
+ case IEEE80211_CHAN_A:
+ case IEEE80211_CHAN_ST:
arrayMode = headerInfo11A;
if (!IS_RAD5112_ANY(ah) && !IS_2413(ah) && !IS_5413(ah))
OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
AR_PHY_FRAME_CTL_TX_CLIP,
ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]);
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
arrayMode = headerInfo11B;
break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_108G:
arrayMode = headerInfo11G;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -1524,7 +1503,7 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
(ee->ee_noiseFloorThresh[arrayMode] & 0x1FF)
| (1 << 9));
- if (ee->ee_version >= AR_EEPROM_VER5_0 && IS_CHAN_TURBO(chan)) {
+ if (ee->ee_version >= AR_EEPROM_VER5_0 && IEEE80211_IS_CHAN_TURBO(chan)) {
switchSettling = ee->ee_switchSettlingTurbo[is2GHz];
adcDesiredSize = ee->ee_adcDesiredSizeTurbo[is2GHz];
pgaDesiredSize = ee->ee_pgaDesiredSizeTurbo[is2GHz];
@@ -1565,18 +1544,17 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
if (ee->ee_version < AR_EEPROM_VER3_3) {
/* XXX magic number */
if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&
- IS_CHAN_OFDM(chan))
+ IEEE80211_IS_CHAN_OFDM(chan))
falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;
} else {
- if (ar5212IsSpurChannel(ah, (HAL_CHANNEL *)chan)) {
+ if (ar5212IsSpurChannel(ah, chan))
falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];
- }
}
AR_PHY_BIS(ah, 73, 0xFFFFFF01, (falseDectectBackoff << 1) & 0xFE);
- if (chan->iqCalValid) {
- iCoff = chan->iCoff;
- qCoff = chan->qCoff;
+ if (ichan->privFlags & CHANNEL_IQVALID) {
+ iCoff = ichan->iCoff;
+ qCoff = ichan->qCoff;
} else {
iCoff = ee->ee_iqCalI[is2GHz];
qCoff = ee->ee_iqCalQ[is2GHz];
@@ -1591,7 +1569,7 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
if (ee->ee_version >= AR_EEPROM_VER4_1) {
- if (!IS_CHAN_108G(chan) || ee->ee_version >= AR_EEPROM_VER5_0)
+ if (!IEEE80211_IS_CHAN_108G(chan) || ee->ee_version >= AR_EEPROM_VER5_0)
OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
AR_PHY_GAIN_2GHZ_RXTX_MARGIN, rxtxMargin);
}
@@ -1612,7 +1590,8 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
*/
void
-ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
+ar5212SetSpurMitigation(struct ath_hal *ah,
+ const struct ieee80211_channel *chan)
{
uint32_t pilotMask[2] = {0, 0}, binMagMask[4] = {0, 0, 0 , 0};
uint16_t i, finalSpur, curChanAsSpur, binWidth = 0, spurDetectWidth, spurChan;
@@ -1621,7 +1600,8 @@ ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
static const uint16_t magMapFor4[4] = {1, 2, 2, 1};
static const uint16_t magMapFor3[3] = {1, 2, 1};
const uint16_t *pMagMap;
- HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan);
+ HAL_BOOL is2GHz = IEEE80211_IS_CHAN_2GHZ(chan);
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
uint32_t val;
#define CHAN_TO_SPUR(_f, _freq) ( ((_freq) - ((_f) ? 2300 : 4900)) * 10 )
@@ -1643,7 +1623,7 @@ ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
*/
finalSpur = AR_NO_SPUR;
spurDetectWidth = HAL_SPUR_CHAN_WIDTH;
- if (IS_CHAN_TURBO(ichan))
+ if (IEEE80211_IS_CHAN_TURBO(chan))
spurDetectWidth *= 2;
/* Decide if any spur affects the current channel */
@@ -1698,23 +1678,22 @@ ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
* spurDeltaPhase is (spurOffsetIn100KHz / chipFrequencyIn100KHz) << 21
* spurFreqSd is (spurOffsetIn100KHz / sampleFrequencyIn100KHz) << 11
*/
- switch (ichan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A: /* Chip Frequency & sampleFrequency are 40 MHz */
- spurDeltaPhase = (spurOffset << 17) / 25;
+ if (IEEE80211_IS_CHAN_TURBO(chan)) {
+ /* Chip Frequency & sampleFrequency are 80 MHz */
+ spurDeltaPhase = (spurOffset << 16) / 25;
spurFreqSd = spurDeltaPhase >> 10;
- binWidth = HAL_BIN_WIDTH_BASE_100HZ;
- break;
- case CHANNEL_G: /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */
+ binWidth = HAL_BIN_WIDTH_TURBO_100HZ;
+ } else if (IEEE80211_IS_CHAN_G(chan)) {
+ /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */
spurFreqSd = (spurOffset << 8) / 55;
spurDeltaPhase = (spurOffset << 17) / 25;
binWidth = HAL_BIN_WIDTH_BASE_100HZ;
- break;
- case CHANNEL_T: /* Chip Frequency & sampleFrequency are 80 MHz */
- case CHANNEL_108G:
- spurDeltaPhase = (spurOffset << 16) / 25;
+ } else {
+ HALASSERT(!IEEE80211_IS_CHAN_B(chan));
+ /* Chip Frequency & sampleFrequency are 40 MHz */
+ spurDeltaPhase = (spurOffset << 17) / 25;
spurFreqSd = spurDeltaPhase >> 10;
- binWidth = HAL_BIN_WIDTH_TURBO_100HZ;
- break;
+ binWidth = HAL_BIN_WIDTH_BASE_100HZ;
}
/* Compute Pilot Mask */
@@ -1791,20 +1770,21 @@ ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
* Required for OFDM operation.
*/
void
-ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define COEF_SCALE_S 24
#define INIT_CLOCKMHZSCALED 0x64000000
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
unsigned long coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man;
unsigned long clockMhzScaled = INIT_CLOCKMHZSCALED;
- if (IS_CHAN_TURBO(chan))
+ if (IEEE80211_IS_CHAN_TURBO(chan))
clockMhzScaled *= 2;
/* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
/* scale for selected channel bandwidth */
- if (IS_CHAN_HALF_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
clockMhzScaled = clockMhzScaled >> 1;
- } else if (IS_CHAN_QUARTER_RATE(chan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
clockMhzScaled = clockMhzScaled >> 2;
}
@@ -1812,7 +1792,7 @@ ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan)
* ALGO -> coef = 1e8/fcarrier*fclock/40;
* scaled coef to provide precision for this floating calculation
*/
- coef_scaled = clockMhzScaled / chan->channel;
+ coef_scaled = clockMhzScaled / freq;
/*
* ALGO -> coef_exp = 14-floor(log2(coef));
@@ -1850,15 +1830,14 @@ ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan)
HAL_BOOL
ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
{
+ /* XXX blech, construct local writable copy */
+ struct ieee80211_channel dummy = *AH_PRIVATE(ah)->ah_curchan;
uint16_t dummyXpdGains[2];
- HAL_BOOL ret, isBmode = AH_FALSE;
+ HAL_BOOL isBmode;
- SAVE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
+ SAVE_CCK(ah, &dummy, isBmode);
AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
- ret = ar5212SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan,
- dummyXpdGains);
- RESTORE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
- return ret;
+ return ar5212SetTransmitPower(ah, &dummy, dummyXpdGains);
}
/*
@@ -1866,8 +1845,8 @@ ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
* operating channel and mode.
*/
HAL_BOOL
-ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
- uint16_t *rfXpdGain)
+ar5212SetTransmitPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
{
#define POW_OFDM(_r, _s) (((0 & 1)<< ((_s)+6)) | (((_r) & 0x3f) << (_s)))
#define POW_CCK(_r, _s) (((_r) & 0x3f) << (_s))
@@ -1875,6 +1854,7 @@ ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
static const uint16_t tpcScaleReductionTable[5] =
{ 0, 3, 6, 9, MAX_RATE_POWER };
struct ath_hal_5212 *ahp = AH5212(ah);
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
int16_t minPower, maxPower, tpcInDb, powerLimit;
int i;
@@ -1889,7 +1869,7 @@ ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
else
tpcInDb = 0;
- if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
+ if (!ar5212SetRateTable(ah, chan, tpcInDb, powerLimit,
AH_TRUE, &minPower, &maxPower)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set rate table\n",
__func__);
@@ -1924,10 +1904,10 @@ ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* Removed with revised chipset
*/
if (AH_PRIVATE(ah)->ah_phyRev < AR_PHY_CHIP_ID_REV_2 &&
- IS_CHAN_G(chan)) {
+ IEEE80211_IS_CHAN_G(chan)) {
uint16_t cckOfdmPwrDelta;
- if (chan->channel == 2484)
+ if (freq == 2484)
cckOfdmPwrDelta = SCALE_OC_DELTA(
ee->ee_cckOfdmPwrDelta -
ee->ee_scaledCh14FilterCckDelta);
@@ -1994,11 +1974,12 @@ ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* operating channel and mode.
*/
static HAL_BOOL
-ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
- int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit,
- int16_t *pMinPower, int16_t *pMaxPower)
+ar5212SetRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit,
+ int16_t *pMinPower, int16_t *pMaxPower)
{
struct ath_hal_5212 *ahp = AH5212(ah);
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t *rpow = ahp->ah_ratesArray;
uint16_t twiceMaxEdgePower = MAX_RATE_POWER;
@@ -2014,7 +1995,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
HALASSERT(ah->ah_magic == AR5212_MAGIC);
- twiceMaxRDPower = chan->maxRegTxPower * 2;
+ twiceMaxRDPower = chan->ic_maxregpower * 2;
*pMaxPower = -MAX_RATE_POWER;
*pMinPower = MAX_RATE_POWER;
@@ -2028,7 +2009,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
if (ee->ee_ctl[i] == cfgCtl ||
cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
- twiceMinEdgePower = ar5212GetMaxEdgePower(chan->channel, rep);
+ twiceMinEdgePower = ar5212GetMaxEdgePower(freq, rep);
if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
/* Find the minimum of all CTL edge powers that apply to this channel */
twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
@@ -2039,7 +2020,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
}
}
- if (IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_G(chan)) {
/* Check for a CCK CTL for 11G CCK powers */
cfgCtl = (cfgCtl & ~CTL_MODE_M) | CTL_11B;
for (i = 0; i < ee->ee_numCtls; i++) {
@@ -2050,7 +2031,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
if (ee->ee_ctl[i] == cfgCtl ||
cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
- twiceMinEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep);
+ twiceMinEdgePowerCck = ar5212GetMaxEdgePower(freq, rep);
if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
/* Find the minimum of all CTL edge powers that apply to this channel */
twiceMaxEdgePowerCck = AH_MIN(twiceMaxEdgePowerCck, twiceMinEdgePowerCck);
@@ -2066,7 +2047,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Get Antenna Gain reduction */
- if (IS_CHAN_5GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
} else {
ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
@@ -2074,9 +2055,9 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
twiceAntennaReduction =
ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
- if (IS_CHAN_OFDM(chan)) {
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
/* Get final OFDM target powers */
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11g,
ee->ee_numTargetPwr_11g, &targetPowerOfdm);
} else {
@@ -2095,7 +2076,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
* this unless specially configured. Then we limit
* power only for non-AP operation.
*/
- if (IS_CHAN_TURBO(chan)
+ if (IEEE80211_IS_CHAN_TURBO(chan)
#ifdef AH_ENABLE_AP_SUPPORT
&& AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
#endif
@@ -2112,7 +2093,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
* constraint on 2.4GHz channels.
*/
if (ee->ee_version >= AR_EEPROM_VER4_0 &&
- IS_CHAN_2GHZ(chan))
+ IEEE80211_IS_CHAN_2GHZ(chan))
scaledPower = AH_MIN(scaledPower,
ee->ee_turbo2WMaxPower2);
}
@@ -2136,7 +2117,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
if (ee->ee_version >= AR_EEPROM_VER4_0) {
/* Setup XR target power from EEPROM */
- rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ?
+ rpow[15] = AH_MIN(scaledPower, IEEE80211_IS_CHAN_2GHZ(chan) ?
ee->ee_xrTargetPower2 : ee->ee_xrTargetPower5);
} else {
/* XR uses 6mb power */
@@ -2156,11 +2137,11 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
"TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
__func__, twiceMaxRDPower, ee->ee_turbo2WMaxPower5,
twiceMaxEdgePower, tpcScaleReduction * 2,
- chan->channel, chan->channelFlags,
+ chan->ic_freq, chan->ic_flags,
maxAvailPower, targetPowerOfdm.twicePwr6_24, *pMaxPower);
}
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
/* Get final CCK target powers */
ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11b,
ee->ee_numTargetPwr_11b, &targetPowerCck);
@@ -2200,7 +2181,7 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
"%s: cck: MaxRD: %d MaxCTL: %d "
"TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
__func__, twiceMaxRDPower, twiceMaxEdgePowerCck,
- tpcScaleReduction * 2, chan->channel, chan->channelFlags,
+ tpcScaleReduction * 2, chan->ic_freq, chan->ic_flags,
maxAvailPower, targetPowerCck.twicePwr6_24, *pMaxPower);
}
if (commit) {
@@ -2211,32 +2192,31 @@ ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
}
HAL_BOOL
-ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
+ar5212GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
+#if 0
static const uint16_t tpcScaleReductionTable[5] =
{ 0, 3, 6, 9, MAX_RATE_POWER };
- int16_t minPower, maxPower, tpcInDb, powerLimit;
- HAL_CHANNEL *chan;
- int i;
+ int16_t tpcInDb, powerLimit;
+#endif
+ int16_t minPower, maxPower;
/*
* Get Pier table max and min powers.
*/
- for (i = 0; i < nchans; i++) {
- chan = &chans[i];
- if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
- /* NB: rf code returns 1/4 dBm units, convert */
- chan->maxTxPower = maxPower / 2;
- chan->minTxPower = minPower / 2;
- } else {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: no min/max power for %u/0x%x\n",
- __func__, chan->channel, chan->channelFlags);
- chan->maxTxPower = MAX_RATE_POWER;
- chan->minTxPower = 0;
- }
+ if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
+ /* NB: rf code returns 1/4 dBm units, convert */
+ chan->ic_maxpower = maxPower / 2;
+ chan->ic_minpower = minPower / 2;
+ } else {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: no min/max power for %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ chan->ic_maxpower = MAX_RATE_POWER;
+ chan->ic_minpower = 0;
}
+#if 0
/*
* Now adjust to reflect any global scale and/or CTL's.
* (XXX is that correct?)
@@ -2246,25 +2226,19 @@ ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans
tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
else
tpcInDb = 0;
- for (i=0; i<nchans; i++) {
- chan = &chans[i];
- if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
- AH_FALSE, &minPower, &maxPower)) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: unable to find max/min power\n",__func__);
- return AH_FALSE;
- }
- if (maxPower < chan->maxTxPower)
- chan->maxTxPower = maxPower;
- if (minPower < chan->minTxPower)
- chan->minTxPower = minPower;
- }
-#ifdef AH_DEBUG
- for (i=0; i<nchans; i++) {
- HALDEBUG(ah, HAL_DEBUG_RESET,
- "Chan %d: MaxPow = %d MinPow = %d\n",
- chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);
+ if (!ar5212SetRateTable(ah, chan, tpcInDb, powerLimit,
+ AH_FALSE, &minPower, &maxPower)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: unable to find max/min power\n",__func__);
+ return AH_FALSE;
}
+ if (maxPower < chan->ic_maxpower)
+ chan->ic_maxpower = maxPower;
+ if (minPower < chan->ic_minpower)
+ chan->ic_minpower = minPower;
+ HALDEBUG(ah, HAL_DEBUG_RESET,
+ "Chan %d: MaxPow = %d MinPow = %d\n",
+ chan->ic_freq, chan->ic_maxpower, chans->ic_minpower);
#endif
return AH_TRUE;
}
@@ -2434,10 +2408,11 @@ interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
* channel, and number of channels
*/
static void
-ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar5212GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan,
const TRGT_POWER_INFO *powInfo,
uint16_t numChannels, TRGT_POWER_INFO *pNewPower)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
/* temp array for holding target power channels */
uint16_t tempChannelList[NUM_TEST_FREQUENCIES];
uint16_t clo, chi, ixlo, ixhi;
@@ -2447,7 +2422,7 @@ ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,
for (i = 0; i < numChannels; i++)
tempChannelList[i] = powInfo[i].testChannel;
- ar5212GetLowerUpperValues(chan->channel, tempChannelList,
+ ar5212GetLowerUpperValues(freq, tempChannelList,
numChannels, &clo, &chi);
/* Get the indices for the channel */
@@ -2466,13 +2441,13 @@ ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,
* Get the lower and upper channels, target powers,
* and interpolate between them.
*/
- pNewPower->twicePwr6_24 = interpolate(chan->channel, clo, chi,
+ pNewPower->twicePwr6_24 = interpolate(freq, clo, chi,
powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);
- pNewPower->twicePwr36 = interpolate(chan->channel, clo, chi,
+ pNewPower->twicePwr36 = interpolate(freq, clo, chi,
powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);
- pNewPower->twicePwr48 = interpolate(chan->channel, clo, chi,
+ pNewPower->twicePwr48 = interpolate(freq, clo, chi,
powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);
- pNewPower->twicePwr54 = interpolate(chan->channel, clo, chi,
+ pNewPower->twicePwr54 = interpolate(freq, clo, chi,
powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);
}
@@ -2576,19 +2551,20 @@ ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits,
* by the turbo ratetable only
*/
void
-ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212SetRateDurationTable(struct ath_hal *ah,
+ const struct ieee80211_channel *chan)
{
const HAL_RATE_TABLE *rt;
int i;
/* NB: band doesn't matter for 1/2 and 1/4 rate */
- if (IS_CHAN_HALF_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
rt = ar5212GetRateTable(ah, HAL_MODE_11A_HALF_RATE);
- } else if (IS_CHAN_QUARTER_RATE(chan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
rt = ar5212GetRateTable(ah, HAL_MODE_11A_QUARTER_RATE);
} else {
rt = ar5212GetRateTable(ah,
- IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_11G);
+ IEEE80211_IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_11G);
}
for (i = 0; i < rt->rateCount; ++i)
@@ -2597,7 +2573,7 @@ ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
ath_hal_computetxtime(ah, rt,
WLAN_CTRL_FRAME_SIZE,
rt->info[i].controlRate, AH_FALSE));
- if (!IS_CHAN_TURBO(chan)) {
+ if (!IEEE80211_IS_CHAN_TURBO(chan)) {
/* 11g Table is used to cover the CCK rates. */
rt = ar5212GetRateTable(ah, HAL_MODE_11G);
for (i = 0; i < rt->rateCount; ++i) {
@@ -2628,14 +2604,15 @@ ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
* + IFS params: slot, eifs, misc etc.
*/
void
-ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5212SetIFSTiming(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec;
- HALASSERT(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan));
+ HALASSERT(IEEE80211_IS_CHAN_HALF(chan) ||
+ IEEE80211_IS_CHAN_QUARTER(chan));
refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32;
- if (IS_CHAN_HALF_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
slot = IFS_SLOT_HALF_RATE;
rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_rfgain.c b/sys/dev/ath/ath_hal/ar5212/ar5212_rfgain.c
index 8448ed7..f9fbc9c 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_rfgain.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_rfgain.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_rfgain.c,v 1.2 2008/11/19 21:23:01 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -239,34 +239,36 @@ ar5212AdjustGain(struct ath_hal *ah, GAIN_VALUES *gv)
/*
* Read rf register to determine if gainF needs correction
*/
-static void
+static uint32_t
ar5212GetGainFCorrection(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- GAIN_VALUES *gv = &ahp->ah_gainValues;
+ uint32_t correction;
HALASSERT(IS_RADX112_REV2(ah));
- gv->gainFCorrection = 0;
+ correction = 0;
if (ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0) == 1) {
+ const GAIN_VALUES *gv = &ahp->ah_gainValues;
uint32_t mixGain = gv->currStep->paramVal[0];
uint32_t gainStep =
ar5212GetRfField(ar5212GetRfBank(ah, 7), 4, 32, 0);
switch (mixGain) {
case 0 :
- gv->gainFCorrection = 0;
+ correction = 0;
break;
case 1 :
- gv->gainFCorrection = gainStep;
+ correction = gainStep;
break;
case 2 :
- gv->gainFCorrection = 2 * gainStep - 5;
+ correction = 2 * gainStep - 5;
break;
case 3 :
- gv->gainFCorrection = 2 * gainStep;
+ correction = 2 * gainStep;
break;
}
}
+ return correction;
}
/*
@@ -280,7 +282,8 @@ ar5212GetRfgain(struct ath_hal *ah)
GAIN_VALUES *gv = &ahp->ah_gainValues;
uint32_t rddata, probeType;
- if (!gv->active)
+ /* NB: beware of touching the BB when PHY is powered down */
+ if (!gv->active || !ahp->ah_phyPowerOn)
return HAL_RFGAIN_INACTIVE;
if (ahp->ah_rfgainState == HAL_RFGAIN_READ_REQUESTED) {
@@ -302,9 +305,9 @@ ar5212GetRfgain(struct ath_hal *ah)
gv->currGain += PHY_PROBE_CCK_CORRECTION;
}
if (IS_RADX112_REV2(ah)) {
- ar5212GetGainFCorrection(ah);
- if (gv->currGain >= gv->gainFCorrection)
- gv->currGain -= gv->gainFCorrection;
+ uint32_t correct = ar5212GetGainFCorrection(ah);
+ if (gv->currGain >= correct)
+ gv->currGain -= correct;
else
gv->currGain = 0;
}
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
index 8b4f85c..2af68b9 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_xmit.c,v 1.7 2008/11/10 04:08:03 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -263,7 +263,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin, chanCwMin, value, qmisc, dmisc;
@@ -286,7 +286,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
* Select cwmin according to channel type.
* NB: chan can be NULL during attach
*/
- if (chan && IS_CHAN_B(chan))
+ if (chan && IEEE80211_IS_CHAN_B(chan))
chanCwMin = INIT_CWMIN_11B;
else
chanCwMin = INIT_CWMIN;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5413.c b/sys/dev/ath/ath_hal/ar5212/ar5413.c
index ecf8538..88ecdf2 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5413.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5413.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5413.c,v 1.8 2008/11/15 22:15:46 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -75,29 +75,29 @@ ar5413WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5413SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
- uint16_t freq;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
- if (chan->channel < 4800) {
+ if (freq < 4800) {
uint32_t txctl;
- if (((chan->channel - 2192) % 5) == 0) {
- channelSel = ((chan->channel - 672) * 2 - 3040)/10;
+ if (((freq - 2192) % 5) == 0) {
+ channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
- } else if (((chan->channel - 2224) % 5) == 0) {
- channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
+ } else if (((freq - 2224) % 5) == 0) {
+ channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -105,7 +105,7 @@ ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
- if (chan->channel == 2484) {
+ if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@@ -113,26 +113,26 @@ ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
- } else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
- freq = chan->channel - 2; /* Align to even 5MHz raster */
+ } else if (((freq % 5) == 2) && (freq <= 5435)) {
+ freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
- } else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
+ } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 20 << 2), 8);
+ ((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
- } else if ((chan->channel % 10) == 0) {
+ } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
- ((chan->channel - 4800) / 10 << 1), 8);
+ ((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
- } else if ((chan->channel % 5) == 0) {
+ } else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
- (chan->channel - 4800) / 5, 8);
+ (freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
- __func__, chan->channel);
+ __func__, freq);
return AH_FALSE;
}
@@ -154,7 +154,9 @@ ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
+ar5413SetRfRegs(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@@ -162,50 +164,49 @@ ar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_5413[i][_col];\
} while (0)
struct ath_hal_5212 *ahp = AH5212(ah);
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t ob5GHz = 0, db5GHz = 0;
uint16_t ob2GHz = 0, db2GHz = 0;
struct ar5413State *priv = AR5413(ah);
int regWrites = 0;
- HALDEBUG(ah, HAL_DEBUG_RFPARAM,
- "%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
- __func__, chan->channel, chan->channelFlags, modesIndex);
+ HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
+ __func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv != AH_NULL);
/* Setup rf parameters */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_T:
- if (chan->channel > 4000 && chan->channel < 5260) {
+ switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
+ case IEEE80211_CHAN_A:
+ if (freq > 4000 && freq < 5260) {
ob5GHz = ee->ee_ob1;
db5GHz = ee->ee_db1;
- } else if (chan->channel >= 5260 && chan->channel < 5500) {
+ } else if (freq >= 5260 && freq < 5500) {
ob5GHz = ee->ee_ob2;
db5GHz = ee->ee_db2;
- } else if (chan->channel >= 5500 && chan->channel < 5725) {
+ } else if (freq >= 5500 && freq < 5725) {
ob5GHz = ee->ee_ob3;
db5GHz = ee->ee_db3;
- } else if (chan->channel >= 5725) {
+ } else if (freq >= 5725) {
ob5GHz = ee->ee_ob4;
db5GHz = ee->ee_db4;
} else {
/* XXX else */
}
break;
- case CHANNEL_B:
+ case IEEE80211_CHAN_B:
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
break;
- case CHANNEL_G:
- case CHANNEL_108G:
+ case IEEE80211_CHAN_G:
+ case IEEE80211_CHAN_PUREG: /* NB: really 108G */
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
+ __func__, chan->ic_flags);
return AH_FALSE;
}
@@ -222,7 +223,7 @@ ar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
RF_BANK_SETUP(priv, 6, modesIndex);
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz, 3, 241, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz, 3, 238, 0);
@@ -537,10 +538,12 @@ ar5413getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar5413SetPowerTable(struct ath_hal *ah,
- int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
+ int16_t *minPower, int16_t *maxPower,
+ const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
struct ath_hal_5212 *ahp = AH5212(ah);
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
uint16_t pdGainOverlap_t2;
@@ -554,14 +557,14 @@ ar5413SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
- __func__, chan->channel,chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
- HALASSERT(IS_CHAN_5GHZ(chan));
+ HALASSERT(IEEE80211_IS_CHAN_5GHZ(chan));
pRawDataset = &ee->ee_rawDataset2413[headerInfo11A];
}
@@ -569,7 +572,7 @@ ar5413SetPowerTable(struct ath_hal *ah,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
numPdGainsUsed = ar5413getGainBoundariesAndPdadcsForPowers(ah,
- chan->channel, pRawDataset, pdGainOverlap_t2,
+ freq, pRawDataset, pdGainOverlap_t2,
&minCalPower5413_t2,gainBoundaries, rfXpdGain, pdadcValues);
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
@@ -676,9 +679,11 @@ ar5413GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
}
static HAL_BOOL
-ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar5413GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
+ uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2413 *data=AH_NULL;
@@ -687,12 +692,12 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
- if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
+ if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
- else if (IS_CHAN_B(chan))
+ else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
- HALASSERT(IS_CHAN_5GHZ(chan));
+ HALASSERT(IEEE80211_IS_CHAN_5GHZ(chan));
pRawDataset = &ee->ee_rawDataset2413[headerInfo11A];
}
@@ -705,9 +710,9 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
- if ((chan->channel < data[0].channelValue) ||
- (chan->channel > data[numChannels-1].channelValue)) {
- if (chan->channel < data[0].channelValue) {
+ if ((freq < data[0].channelValue) ||
+ (freq > data[numChannels-1].channelValue)) {
+ if (freq < data[0].channelValue) {
*maxPow = ar5413GetMaxPower(ah, &data[0]);
*minPow = ar5413GetMinPower(ah, &data[0]);
return(AH_TRUE);
@@ -719,19 +724,19 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
- for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
+ for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar5413GetMaxPower(ah, &data[i]) - ar5413GetMaxPower(ah, &data[last]);
- *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
+ *maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar5413GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar5413GetMinPower(ah, &data[i]) - ar5413GetMinPower(ah, &data[last]);
- *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
+ *minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar5413GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
- if (chan->channel == data[i].channelValue) {
+ if (freq == data[i].channelValue) {
*maxPow = ar5413GetMaxPower(ah, &data[i]);
*minPow = ar5413GetMinPower(ah, &data[i]);
return(AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312.h b/sys/dev/ath/ath_hal/ar5312/ar5312.h
index 4943891..210e744 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312.h
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -60,8 +60,10 @@ extern void ar5312SetupClock(struct ath_hal *ah, HAL_OPMODE opmode);
extern void ar5312RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode);
extern void ar5312DumpState(struct ath_hal *ah);
extern HAL_BOOL ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status);
-extern HAL_BOOL ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan);
+ struct ieee80211_channel *chan,
+ HAL_BOOL bChannelChange, HAL_STATUS *status);
+extern HAL_BOOL ar5312ChipReset(struct ath_hal *ah,
+ struct ieee80211_channel *chan);
extern HAL_BOOL ar5312SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
int setChip);
extern HAL_BOOL ar5312PhyDisable(struct ath_hal *ah);
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c b/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
index 6c0bb0a..dda3faf 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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_reset.c,v 1.10 2008/11/22 07:41:37 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -34,15 +34,21 @@
#define BASE_ACTIVATE_DELAY 100 /* 100 usec */
#define PLL_SETTLE_DELAY 300 /* 300 usec */
-extern int16_t ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
-extern void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
+extern int16_t ar5212GetNf(struct ath_hal *, const struct ieee80211_channel *);
+extern void ar5212SetRateDurationTable(struct ath_hal *,
+ const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
-extern void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
-extern HAL_BOOL ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
-extern void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
-extern HAL_BOOL ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *);
-extern HAL_BOOL ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *);
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
+extern void ar5212SetDeltaSlope(struct ath_hal *,
+ const struct ieee80211_channel *);
+extern HAL_BOOL ar5212SetBoardValues(struct ath_hal *,
+ const struct ieee80211_channel *);
+extern void ar5212SetIFSTiming(struct ath_hal *,
+ const struct ieee80211_channel *);
+extern HAL_BOOL ar5212IsSpurChannel(struct ath_hal *,
+ const struct ieee80211_channel *);
+extern HAL_BOOL ar5212ChannelChange(struct ath_hal *,
+ const struct ieee80211_channel *);
static HAL_BOOL ar5312SetResetReg(struct ath_hal *, uint32_t resetMask);
@@ -81,7 +87,8 @@ write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
*/
HAL_BOOL
ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
+ struct ieee80211_channel *chan,
+ HAL_BOOL bChannelChange, HAL_STATUS *status)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
@@ -102,20 +109,6 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
ee = AH_PRIVATE(ah)->ah_eeprom;
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
-#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
- if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
- if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
-#undef IS
/*
* Map public channel to private.
*/
@@ -123,7 +116,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
switch (opmode) {
@@ -176,10 +169,10 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* -the modes of the previous and requested channel are the same - some ugly code for XR
*/
if (bChannelChange &&
- (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
- (chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
- ((chan->channelFlags & CHANNEL_ALL) ==
- (AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) {
+ AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
+ (chan->ic_freq != AH_PRIVATE(ah)->ah_curchan->ic_freq) &&
+ ((chan->ic_flags & IEEE80211_CHAN_ALLTURBO) ==
+ (AH_PRIVATE(ah)->ah_curchan->ic_flags & IEEE80211_CHAN_ALLTURBO))) {
if (ar5212ChannelChange(ah, chan))
/* If ChannelChange completed - skip the rest of reset */
return AH_TRUE;
@@ -217,31 +210,13 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
/* Setup the indices for the next set of register array writes */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- modesIndex = 1;
- freqIndex = 1;
- break;
- case CHANNEL_T:
- modesIndex = 2;
- freqIndex = 1;
- break;
- case CHANNEL_B:
- modesIndex = 3;
- freqIndex = 2;
- break;
- case CHANNEL_PUREG:
- modesIndex = 4;
- freqIndex = 2;
- break;
- case CHANNEL_108G:
- modesIndex = 5;
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
freqIndex = 2;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- FAIL(HAL_EINVAL);
+ modesIndex = IEEE80211_IS_CHAN_108G(chan) ? 5 :
+ IEEE80211_IS_CHAN_G(chan) ? 4 : 3;
+ } else {
+ freqIndex = 1;
+ modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1;
}
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -256,9 +231,8 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
- if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))
ar5212SetIFSTiming(ah, chan);
- }
/* Overwrite INI values for revised chipsets */
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
@@ -276,7 +250,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta);
}
- if (IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_G(chan)) {
OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
SM((ee->ee_cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
SM((cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
@@ -315,18 +289,18 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
SM(0x16, AR_PHY_SIGMA_DELTA_FILT1) |
SM(0, AR_PHY_SIGMA_DELTA_ADC_CLIP));
- if (IS_CHAN_2GHZ(chan))
+ if (IEEE80211_IS_CHAN_2GHZ(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F);
/* CCK Short parameter adjustment in 11B mode */
- if (IS_CHAN_B(chan))
+ if (IEEE80211_IS_CHAN_B(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_CCK_RXCTRL4, AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT, 12);
/* Set ADC/DAC select values */
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04);
/* Increase 11A AGC Settling */
- if ((chan->channelFlags & CHANNEL_ALL) == CHANNEL_A)
+ if (IEEE80211_IS_CHAN_A(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_AGC, 32);
} else {
/* Set ADC/DAC select values */
@@ -334,29 +308,29 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
/* Setup the transmit power values. */
- if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
+ if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
FAIL(HAL_EIO);
}
/* Write the analog registers */
- if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) {
+ if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
__func__);
FAIL(HAL_EIO);
}
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
- if (IS_CHAN_OFDM(chan)) {
- if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
- (!IS_CHAN_B(chan)))
- ar5212SetSpurMitigation(ah, ichan);
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
+ if (IS_5413(ah) ||
+ AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
+ ar5212SetSpurMitigation(ah, chan);
ar5212SetDeltaSlope(ah, chan);
}
/* Setup board specific options for EEPROM version 3 */
- if (!ar5212SetBoardValues(ah, ichan)) {
+ if (!ar5212SetBoardValues(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error setting board options\n", __func__);
FAIL(HAL_EIO);
@@ -396,7 +370,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
- if (!ar5212SetChannel(ah, ichan))
+ if (!ar5212SetChannel(ah, chan))
FAIL(HAL_EIO);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -407,10 +381,9 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Set Tx frame start to tx data start delay */
if (IS_RAD5112_ANY(ah) &&
- (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
- IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
+ (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
txFrm2TxDStart =
- (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
+ IEEE80211_IS_CHAN_HALF(chan) ?
TX_FRAME_D_START_HALF_RATE:
TX_FRAME_D_START_QUARTER_RATE;
OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
@@ -445,7 +418,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* Value is in 100ns increments.
*/
synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
- if (IS_CHAN_CCK(chan)) {
+ if (IEEE80211_IS_CHAN_B(chan)) {
synthDelay = (4 * synthDelay) / 22;
} else {
synthDelay /= 10;
@@ -461,9 +434,9 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* extra BASE_ACTIVATE_DELAY usecs to ensure this condition
* does not happen.
*/
- if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
- } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
} else {
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
@@ -487,7 +460,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
| AR_PHY_AGC_CONTROL_CAL
| AR_PHY_AGC_CONTROL_NF);
- if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
+ if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
@@ -583,12 +556,8 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
- if (bChannelChange) {
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
- }
+ if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
+ chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
@@ -597,7 +566,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
return AH_TRUE;
bad:
OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
- if (*status)
+ if (status != AH_NULL)
*status = ecode;
return AH_FALSE;
#undef FAIL
@@ -639,10 +608,10 @@ ar5312Disable(struct ath_hal *ah)
* WARNING: The order of the PLL and mode registers must be correct.
*/
HAL_BOOL
-ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5312ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
- OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
+ OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
/*
* Reset the HW
@@ -683,50 +652,49 @@ ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
if (IS_RAD5112_ANY(ah)) {
rfMode = AR_PHY_MODE_AR5112;
if (!IS_5315(ah)) {
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
phyPLL = AR_PHY_PLL_CTL_44_5312;
} else {
- if (IS_CHAN_HALF_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
phyPLL = AR_PHY_PLL_CTL_40_5312_HALF;
- } else if (IS_CHAN_QUARTER_RATE(chan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
phyPLL = AR_PHY_PLL_CTL_40_5312_QUARTER;
} else {
phyPLL = AR_PHY_PLL_CTL_40_5312;
}
}
} else {
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
+ if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44_5112;
else
phyPLL = AR_PHY_PLL_CTL_40_5112;
- if (IS_CHAN_HALF_RATE(chan))
+ if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL |= AR_PHY_PLL_CTL_HALF;
- else if (IS_CHAN_QUARTER_RATE(chan))
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
}
} else {
rfMode = AR_PHY_MODE_AR5111;
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
+ if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44;
else
phyPLL = AR_PHY_PLL_CTL_40;
- if (IS_CHAN_HALF_RATE(chan))
+ if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL = AR_PHY_PLL_CTL_HALF;
- else if (IS_CHAN_QUARTER_RATE(chan))
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL = AR_PHY_PLL_CTL_QUARTER;
}
- if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
- IS_CHAN_G(chan)))
+ if (IEEE80211_IS_CHAN_G(chan))
rfMode |= AR_PHY_MODE_DYNAMIC;
- else if (IS_CHAN_OFDM(chan))
+ else if (IEEE80211_IS_CHAN_OFDM(chan))
rfMode |= AR_PHY_MODE_OFDM;
else
rfMode |= AR_PHY_MODE_CCK;
- if (IS_CHAN_5GHZ(chan))
+ if (IEEE80211_IS_CHAN_5GHZ(chan))
rfMode |= AR_PHY_MODE_RF5GHZ;
else
rfMode |= AR_PHY_MODE_RF2GHZ;
- turbo = IS_CHAN_TURBO(chan) ?
+ turbo = IEEE80211_IS_CHAN_TURBO(chan) ?
(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
/*
@@ -736,7 +704,7 @@ ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
* mode bit is set
* - Turbo cannot be set at the same time as CCK or DYNAMIC
*/
- if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
if (curPhyPLL != phyPLL) {
diff --git a/sys/dev/ath/ath_hal/ar5416/ar2133.c b/sys/dev/ath/ath_hal/ar5416/ar2133.c
index 5d90b6e..eb175a1 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar2133.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar2133.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar2133.c,v 1.13 2008/11/11 00:11:30 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -46,14 +46,8 @@ struct ar2133State {
#define ar5416ModifyRfBuffer ar5212ModifyRfBuffer /*XXX*/
-extern void ar5416ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
- uint32_t numBits, uint32_t firstBit, uint32_t column);
-HAL_BOOL ar2133GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL
- *chans, uint32_t nchans);
-
-static HAL_BOOL ar2133GetChannelMaxMinPower(struct ath_hal *, HAL_CHANNEL *,
- int16_t *maxPow,int16_t *minPow);
-int16_t ar2133GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c);
+void ar5416ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
+ uint32_t numBits, uint32_t firstBit, uint32_t column);
static void
ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
@@ -69,7 +63,7 @@ ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
-ar2133SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
@@ -78,9 +72,9 @@ ar2133SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
uint16_t freq;
CHAN_CENTERS centers;
- OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
+ OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq);
- ar5416GetChannelCenters(ah, chan, &centers);
+ ar5416GetChannelCenters(ah, chan, &centers);
freq = centers.synth_center;
if (freq < 4800) {
@@ -169,7 +163,7 @@ ar2133GetRfBank(struct ath_hal *ah, int bank)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
-ar2133SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
+ar2133SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
struct ar2133State *priv = AR2133(ah);
@@ -193,7 +187,7 @@ ar2133SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ath_hal_ini_bank_setup(priv->Bank6Data, &AH5416(ah)->ah_ini_bank6, modesIndex);
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5416ModifyRfBuffer(priv->Bank6Data,
ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 3, 197, 0);
ar5416ModifyRfBuffer(priv->Bank6Data,
@@ -233,7 +227,7 @@ ar2133SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
static HAL_BOOL
ar2133SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax,
- HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain)
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
{
return AH_TRUE;
}
@@ -267,8 +261,9 @@ ar2133GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data)
#endif
static HAL_BOOL
-ar2133GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan, int16_t *maxPow,
- int16_t *minPow)
+ar2133GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ int16_t *maxPow, int16_t *minPow)
{
#if 0
struct ath_hal_5212 *ahp = AH5212(ah);
@@ -390,7 +385,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
* Adjust NF based on statistical values for 5GHz frequencies.
* Stubbed:Not used by Fowl
*/
-int16_t
+static int16_t
ar2133GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
{
return 0;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h
index 34e76b9..20714e8 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5416.h,v 1.19 2008/11/11 21:38:13 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AR5416_H_
#define _ATH_AR5416_H_
@@ -92,7 +92,8 @@ extern void ar5416Detach(struct ath_hal *ah);
extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah);
#define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \
- (IS_CHAN_5GHZ(_c) && ath_hal_eepromGetFlag(ah, AR_EEP_FSTCLK_5G))
+ (IEEE80211_IS_CHAN_5GHZ(_c) && \
+ ath_hal_eepromGetFlag(ah, AR_EEP_FSTCLK_5G))
extern void ar5416AniAttach(struct ath_hal *, const struct ar5212AniParams *,
const struct ar5212AniParams *, HAL_BOOL ena);
@@ -102,8 +103,8 @@ extern HAL_BOOL ar5416AniSetParams(struct ath_hal *,
const struct ar5212AniParams *, const struct ar5212AniParams *);
extern void ar5416ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar5416AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
- HAL_CHANNEL *);
-extern void ar5416AniReset(struct ath_hal *, HAL_CHANNEL_INTERNAL *,
+ const struct ieee80211_channel *);
+extern void ar5416AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int);
extern void ar5416SetBeaconTimers(struct ath_hal *, const HAL_BEACON_TIMERS *);
@@ -160,17 +161,19 @@ extern HAL_STATUS ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *,
struct ath_rx_status *);
extern HAL_BOOL ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status);
+ struct ieee80211_channel *chan,
+ HAL_BOOL bChannelChange, HAL_STATUS *status);
extern HAL_BOOL ar5416PhyDisable(struct ath_hal *ah);
extern HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah);
extern HAL_BOOL ar5416Disable(struct ath_hal *ah);
-extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *);
+extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah,
+ const struct ieee80211_channel *);
extern HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type);
extern HAL_BOOL ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
extern HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah,
- HAL_CHANNEL *chans, uint32_t nchans);
+ struct ieee80211_channel *chan);
extern void ar5416GetChannelCenters(struct ath_hal *,
- HAL_CHANNEL_INTERNAL *chan, CHAN_CENTERS *centers);
+ const struct ieee80211_channel *chan, CHAN_CENTERS *centers);
extern HAL_BOOL ar5416StopTxDma(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
index 59bfb20..6134a20 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5416_ani.c,v 1.1 2008/11/11 20:46:06 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -102,43 +102,6 @@ disableAniMIBCounters(struct ath_hal *ah)
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, 0);
}
-/*
- * This routine returns the index into the aniState array that
- * corresponds to the channel in *chan. If no match is found and the
- * array is still not fully utilized, a new entry is created for the
- * channel. We assume the attach function has already initialized the
- * ah_ani values and only the channel field needs to be set.
- */
-static int
-ar5416GetAniChannelIndex(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
-{
-#define N(a) (sizeof(a) / sizeof(a[0]))
- struct ath_hal_5212 *ahp = AH5212(ah);
- int i;
-
- for (i = 0; i < N(ahp->ah_ani); i++) {
- struct ar5212AniState *asp = &ahp->ah_ani[i];
- if (asp->c.channel == chan->channel)
- return i;
- if (asp->c.channel == 0) {
- asp->c.channel = chan->channel;
- asp->c.channelFlags = chan->channelFlags;
- asp->c.privFlags = chan->privFlags;
- asp->isSetup = AH_FALSE;
- if (IS_CHAN_2GHZ(chan))
- asp->params = &ahp->ah_aniParams24;
- else
- asp->params = &ahp->ah_aniParams5;
- return i;
- }
- }
- /* XXX statistic */
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "No more channel states left. Using channel 0\n");
- return 0; /* XXX gotta return something valid */
-#undef N
-}
-
static void
setPhyErrBase(struct ath_hal *ah, struct ar5212AniParams *params)
{
@@ -374,7 +337,7 @@ static void
ar5416AniOfdmErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@@ -441,8 +404,7 @@ ar5416AniOfdmErrTrigger(struct ath_hal *ah)
* weak signal detection and zero firstepLevel to
* maximize CCK sensitivity
*/
- /* XXX can optimize */
- if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
if (!aniState->ofdmWeakSigDetectOff)
ar5416AniControl(ah,
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -460,7 +422,7 @@ static void
ar5416AniCckErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
+ const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@@ -493,8 +455,7 @@ ar5416AniCckErrTrigger(struct ath_hal *ah)
* Beacon rssi is low, zero firstep level to maximize
* CCK sensitivity in 11b/g mode.
*/
- /* XXX can optimize */
- if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
if (aniState->firstepLevel > 0)
ar5416AniControl(ah,
HAL_ANI_FIRSTEP_LEVEL, 0);
@@ -536,26 +497,33 @@ ar5416AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
* it is setup to reflect the current channel.
*/
void
-ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
+ar5416AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_OPMODE opmode, int restore)
{
struct ath_hal_5212 *ahp = AH5212(ah);
- struct ar5212AniState *aniState;
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
+ /* XXX bounds check ic_devdata */
+ struct ar5212AniState *aniState = &ahp->ah_ani[chan->ic_devdata];
uint32_t rxfilter;
- int index;
- index = ar5416GetAniChannelIndex(ah, chan);
- aniState = &ahp->ah_ani[index];
+ if ((ichan->privFlags & CHANNEL_ANI_INIT) == 0) {
+ OS_MEMZERO(aniState, sizeof(*aniState));
+ if (IEEE80211_IS_CHAN_2GHZ(chan))
+ aniState->params = &ahp->ah_aniParams24;
+ else
+ aniState->params = &ahp->ah_aniParams5;
+ ichan->privFlags |= CHANNEL_ANI_INIT;
+ HALASSERT((ichan->privFlags & CHANNEL_ANI_SETUP) == 0);
+ }
ahp->ah_curani = aniState;
#if 0
- ath_hal_printf(ah,"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
- __func__, chan->channel, chan->channelFlags, restore,
- aniState->isSetup, opmode);
+ ath_hal_printf(ah,"%s: chan %u/0x%x restore %d opmode %u%s\n",
+ __func__, chan->ic_freq, chan->ic_flags, restore, opmode,
+ ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#else
- HALDEBUG(ah, HAL_DEBUG_ANI,
- "%s: chan %u/0x%x restore %d setup %d opmode %u\n",
- __func__, chan->channel, chan->channelFlags, restore,
- aniState->isSetup, opmode);
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: chan %u/0x%x restore %d opmode %u%s\n",
+ __func__, chan->ic_freq, chan->ic_flags, restore, opmode,
+ ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#endif
OS_MARK(ah, AH_MARK_ANI_RESET, opmode);
@@ -577,7 +545,7 @@ ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* XXX if ANI follows hardware, we don't care what mode we're
* XXX in, we should keep the ani parameters
*/
- if (restore && aniState->isSetup) {
+ if (restore && (ichan->privFlags & CHANNEL_ANI_SETUP)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel);
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
@@ -595,7 +563,7 @@ ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
AH_TRUE);
ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
- aniState->isSetup = AH_TRUE;
+ ichan->privFlags |= CHANNEL_ANI_SETUP;
}
ar5416AniRestart(ah, aniState);
@@ -831,7 +799,7 @@ updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
*/
void
ar5416AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
- HAL_CHANNEL *chan)
+ const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
index 49db049..712f7e0 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5416_cal.c,v 1.7 2008/11/11 17:43:23 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -32,26 +32,27 @@
#define NUM_NOISEFLOOR_READINGS 6 /* 3 chains * (ctl + ext) */
static void ar5416StartNFCal(struct ath_hal *ah);
-static void ar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *);
-static int16_t ar5416GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+static void ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
+static int16_t ar5416GetNf(struct ath_hal *, struct ieee80211_channel *);
/*
* Determine if calibration is supported by device and channel flags
*/
static OS_INLINE HAL_BOOL
-ar5416IsCalSupp(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_CAL_TYPE calType)
+ar5416IsCalSupp(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ HAL_CAL_TYPE calType)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
switch (calType & cal->suppCals) {
case IQ_MISMATCH_CAL:
/* Run IQ Mismatch for non-CCK only */
- return !IS_CHAN_B(chan);
+ return !IEEE80211_IS_CHAN_B(chan);
case ADC_GAIN_CAL:
case ADC_DC_CAL:
/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
- return !IS_CHAN_B(chan) &&
- !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan));
+ return !IEEE80211_IS_CHAN_B(chan) &&
+ !(IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan));
}
return AH_FALSE;
}
@@ -164,7 +165,7 @@ ar5416RunInitCals(struct ath_hal *ah, int init_cal_count)
* Initialize Calibration infrastructure.
*/
HAL_BOOL
-ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CHANNEL_INTERNAL *ichan;
@@ -279,7 +280,7 @@ ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan)
* Reset the calibration valid bit in channel.
*/
HAL_BOOL
-ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
@@ -292,7 +293,7 @@ ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
/*
@@ -312,8 +313,8 @@ ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
HALDEBUG(ah, HAL_DEBUG_PERCAL,
"%s: Resetting Cal %d state for channel %u/0x%x\n",
- __func__, currCal->calData->calType, chan->channel,
- chan->channelFlags);
+ __func__, currCal->calData->calType, chan->ic_freq,
+ chan->ic_flags);
/* Disable cal validity in channel */
ichan->calValid &= ~currCal->calData->calType;
@@ -384,14 +385,14 @@ ar5416DoCalibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
* Internal interface to schedule periodic calibration work.
*/
HAL_BOOL
-ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
+ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int rxchainmask, HAL_BOOL longcal, HAL_BOOL *isCalDone)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CAL_LIST *currCal = cal->cal_curr;
HAL_CHANNEL_INTERNAL *ichan;
- OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
+ OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq);
*isCalDone = AH_TRUE;
@@ -400,7 +401,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ __func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
@@ -432,7 +433,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
* Get the value from the previous NF cal
* and update the history buffer.
*/
- ar5416GetNf(ah, ichan);
+ ar5416GetNf(ah, chan);
/*
* Load the NF from history buffer of the current channel.
@@ -443,12 +444,6 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
/* start NF calibration, without updating BB NF register*/
ar5416StartNFCal(ah);
-
- if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
- /* report up and clear internal state */
- chan->channelFlags |= CHANNEL_CW_INT;
- ichan->channelFlags &= ~CHANNEL_CW_INT;
- }
}
return AH_TRUE;
}
@@ -458,7 +453,8 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
* changes.
*/
HAL_BOOL
-ar5416PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
+ar5416PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
+ HAL_BOOL *isIQdone)
{
struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
@@ -478,29 +474,19 @@ ar5416PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
static HAL_BOOL
ar5416GetEepromNoiseFloorThresh(struct ath_hal *ah,
- const HAL_CHANNEL_INTERNAL *chan, int16_t *nft)
+ const struct ieee80211_channel *chan, int16_t *nft)
{
- switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
- case CHANNEL_A:
- case CHANNEL_A_HT20:
- case CHANNEL_A_HT40PLUS:
- case CHANNEL_A_HT40MINUS:
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_5, nft);
- break;
- case CHANNEL_B:
- case CHANNEL_G:
- case CHANNEL_G_HT20:
- case CHANNEL_G_HT40PLUS:
- case CHANNEL_G_HT40MINUS:
+ return AH_TRUE;
+ }
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_2, nft);
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- return AH_FALSE;
+ return AH_TRUE;
}
- return AH_TRUE;
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
+ __func__, chan->ic_flags);
+ return AH_FALSE;
}
static void
@@ -512,7 +498,7 @@ ar5416StartNFCal(struct ath_hal *ah)
}
static void
-ar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
static const uint32_t ar5416_cca_regs[] = {
AR_PHY_CCA,
@@ -624,7 +610,7 @@ ar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray)
* Read the NF and check it against the noise floor threshhold
*/
static int16_t
-ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
{
int16_t nf, nfThresh;
@@ -635,6 +621,7 @@ ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
} else {
/* Finished NF cal, check against threshold */
int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 };
+ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
/* TODO - enhance for multiple chains and ext ch */
ath_hal_getNoiseFloor(ah, nfarray);
@@ -650,14 +637,14 @@ ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* happens it indicates a problem regardless
* of the band.
*/
- chan->channelFlags |= CHANNEL_CW_INT;
+ chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
nf = 0;
}
} else {
nf = 0;
}
ar5416UpdateNFHistBuff(AH5416(ah)->ah_cal.nfCalHist, nfarray);
- chan->rawNoiseFloor = nf;
+ ichan->rawNoiseFloor = nf;
}
return nf;
}
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h
index 1240029..e77f300 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5416_cal.h,v 1.3 2008/11/11 17:43:23 sam Exp $
+ * $FreeBSD$
*/
#ifndef _ATH_AR5416_CAL_H_
#define _ATH_AR5416_CAL_H_
@@ -102,12 +102,13 @@ struct ar5416PerCal {
} \
} while (0)
-HAL_BOOL ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan);
-HAL_BOOL ar5416PerCalibration(struct ath_hal *, HAL_CHANNEL *,
+HAL_BOOL ar5416InitCal(struct ath_hal *, const struct ieee80211_channel *);
+HAL_BOOL ar5416PerCalibration(struct ath_hal *, struct ieee80211_channel *,
HAL_BOOL *isIQdone);
-HAL_BOOL ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
+HAL_BOOL ar5416PerCalibrationN(struct ath_hal *, struct ieee80211_channel *,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
-HAL_BOOL ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
+HAL_BOOL ar5416ResetCalValid(struct ath_hal *,
+ const struct ieee80211_channel *);
void ar5416IQCalCollect(struct ath_hal *ah);
void ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains);
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
index 74ba497..b017017 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5416_reset.c,v 1.27 2008/11/27 22:30:08 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
@@ -43,53 +43,53 @@
#define RTC_PLL_SETTLE_DELAY 1000 /* 1 ms */
static void ar5416InitDMA(struct ath_hal *ah);
-static void ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan);
+static void ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *);
static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode);
static void ar5416InitQoS(struct ath_hal *ah);
static void ar5416InitUserSettings(struct ath_hal *ah);
static HAL_BOOL ar5416SetTransmitPower(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
#if 0
-static HAL_BOOL ar5416ChannelChange(struct ath_hal *, HAL_CHANNEL *);
+static HAL_BOOL ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *);
#endif
-static void ar5416SetDeltaSlope(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
-static void ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan);
+static void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel *);
+static void ar5416SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan);
#ifdef AH_SUPPORT_AR9280
-static void ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan);
+static void ar9280SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan);
#endif
static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah);
static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type);
-static void ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan);
-static HAL_BOOL ar5416SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
+static void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan);
+static HAL_BOOL ar5416SetBoardValues(struct ath_hal *, const struct ieee80211_channel *);
static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah,
struct ar5416eeprom *pEepData,
- HAL_CHANNEL_INTERNAL *chan, int16_t *ratesArray,
+ const struct ieee80211_channel *chan, int16_t *ratesArray,
uint16_t cfgCtl, uint16_t AntennaReduction,
uint16_t twiceMaxRegulatoryPower,
uint16_t powerLimit);
static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah,
struct ar5416eeprom *pEepData,
- HAL_CHANNEL_INTERNAL *chan,
+ const struct ieee80211_channel *chan,
int16_t *pTxPowerIndexOffset);
static uint16_t ar5416GetMaxEdgePower(uint16_t freq,
CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz);
static void ar5416GetTargetPowers(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_HT *powInfo,
+ const struct ieee80211_channel *chan, CAL_TARGET_POWER_HT *powInfo,
uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower,
uint16_t numRates, HAL_BOOL isHt40Target);
static void ar5416GetTargetPowersLeg(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, CAL_TARGET_POWER_LEG *powInfo,
+ const struct ieee80211_channel *chan, CAL_TARGET_POWER_LEG *powInfo,
uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower,
uint16_t numRates, HAL_BOOL isExtTarget);
static int16_t interpolate(uint16_t target, uint16_t srcLeft,
uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
-static void ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan);
+static void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan);
static void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet,
+ const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet,
uint8_t * bChans, uint16_t availPiers,
uint16_t tPdGainOverlap, int16_t *pMinCalPower,
uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
@@ -110,7 +110,8 @@ static HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,
*/
HAL_BOOL
ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
- HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
+ struct ieee80211_channel *chan,
+ HAL_BOOL bChannelChange, HAL_STATUS *status)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
@@ -127,20 +128,6 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
-#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
- if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
- if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
- __func__, chan->channel, chan->channelFlags);
- FAIL(HAL_EINVAL);
- }
-#undef IS
/* Bring out of sleep mode */
if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
@@ -153,16 +140,8 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* Map public channel to private.
*/
ichan = ath_hal_checkchannel(ah, chan);
- if (ichan == AH_NULL) {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: invalid channel %u/0x%x; no mapping\n",
- __func__, chan->channel, chan->channelFlags);
+ if (ichan == AH_NULL)
FAIL(HAL_EINVAL);
- } else {
- HALDEBUG(ah, HAL_DEBUG_RESET,
- "%s: Ch=%u Max=%d Min=%d\n",__func__,
- ichan->channel, ichan->maxTxPower, ichan->minTxPower);
- }
switch (opmode) {
case HAL_M_STA:
case HAL_M_IBSS:
@@ -220,37 +199,21 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Setup the indices for the next set of register array writes */
/* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
- switch (chan->channelFlags & CHANNEL_ALL) {
- case CHANNEL_A:
- case CHANNEL_A_HT20:
- modesIndex = 1;
- freqIndex = 1;
- break;
- case CHANNEL_T:
- case CHANNEL_A_HT40PLUS:
- case CHANNEL_A_HT40MINUS:
- modesIndex = 2;
- freqIndex = 1;
- break;
- case CHANNEL_PUREG:
- case CHANNEL_G_HT20:
- case CHANNEL_B: /* treat as channel G , no B mode suport in owl */
- modesIndex = 4;
- freqIndex = 2;
- break;
- case CHANNEL_G_HT40PLUS:
- case CHANNEL_G_HT40MINUS:
- modesIndex = 3;
- freqIndex = 2;
- break;
- case CHANNEL_108G:
- modesIndex = 5;
- freqIndex = 2;
- break;
- default:
- HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
- __func__, chan->channelFlags);
- FAIL(HAL_EINVAL);
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
+ freqIndex = 2;
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ modesIndex = 3;
+ else if (IEEE80211_IS_CHAN_108G(chan))
+ modesIndex = 5;
+ else
+ modesIndex = 4;
+ } else {
+ freqIndex = 1;
+ if (IEEE80211_IS_CHAN_HT40(chan) ||
+ IEEE80211_IS_CHAN_TURBO(chan))
+ modesIndex = 2;
+ else
+ modesIndex = 1;
}
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -264,7 +227,7 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
#if 0
/* NB: only required for Sowl */
- ar5416EepromSetAddac(ah, ichan);
+ ar5416EepromSetAddac(ah, chan);
#endif
regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1,
regWrites);
@@ -285,7 +248,7 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* XXX Merlin 100us delay for shift registers */
regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_common, 1, regWrites);
/* Setup 11n MAC/Phy mode registers */
- ar5416Set11nRegs(ah,chan);
+ ar5416Set11nRegs(ah, chan);
/* XXX updated regWrites? */
ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
#ifdef AH_SUPPORT_AR9280
@@ -332,32 +295,32 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask);
/* Setup the transmit power values. */
- if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) {
+ if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
FAIL(HAL_EIO);
}
/* Write the analog registers */
- if (!ahp->ah_rfHal->setRfRegs(ah, ichan, freqIndex, rfXpdGain)) {
+ if (!ahp->ah_rfHal->setRfRegs(ah, chan, freqIndex, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: ar5212SetRfRegs failed\n", __func__);
FAIL(HAL_EIO);
}
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
- if (IS_CHAN_OFDM(chan)|| IS_CHAN_HT(chan))
- ar5416SetDeltaSlope(ah, ichan);
+ if (IEEE80211_IS_CHAN_OFDM(chan)|| IEEE80211_IS_CHAN_HT(chan))
+ ar5416SetDeltaSlope(ah, chan);
#ifdef AH_SUPPORT_AR9280
if (AR_SREV_MERLIN_10_OR_LATER(ah))
- ar9280SpurMitigate(ah, ichan);
+ ar9280SpurMitigate(ah, chan);
else
#endif
- ar5416SpurMitigate(ah, ichan);
+ ar5416SpurMitigate(ah, chan);
/* Setup board specific options for EEPROM version 3 */
- if (!ar5416SetBoardValues(ah, ichan)) {
+ if (!ar5416SetBoardValues(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error setting board options\n", __func__);
FAIL(HAL_EIO);
@@ -394,7 +357,7 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
- if (!ar5212SetChannel(ah, ichan))
+ if (!ar5212SetChannel(ah, chan))
FAIL(HAL_EIO);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -453,15 +416,8 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
- if (bChannelChange) {
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
- chan->maxRegTxPower = ichan->maxRegTxPower;
- chan->maxTxPower = ichan->maxTxPower;
- chan->minTxPower = ichan->minTxPower;
- }
+ if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
+ chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
@@ -470,7 +426,7 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
return AH_TRUE;
bad:
OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
- if (*status)
+ if (status != AH_NULL)
*status = ecode;
return AH_FALSE;
#undef FAIL
@@ -485,7 +441,7 @@ bad:
* time, the function returns false as a reset is necessary
*/
HAL_BOOL
-ar5416ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan)
{
uint32_t ulCount;
uint32_t data, synthDelay, qnum;
@@ -520,11 +476,11 @@ ar5416ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */
/* Change the synth */
- if (!ar5212SetChannel(ah, ichan))
+ if (!ar5212SetChannel(ah, chan))
return AH_FALSE;
/* Setup the transmit power values. */
- if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) {
+ if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
return AH_FALSE;
@@ -548,27 +504,20 @@ ar5416ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
- if (IS_CHAN_OFDM(ichan)|| IS_CHAN_HT(chan)) {
- if (ahp->ah_eeprom.ee_version >= AR_EEPROM_VER5_3 &&
- !IS_CHAN_B(chan))
- ar5212SetSpurMitigation(ah, ichan);
- ar5416SetDeltaSlope(ah, ichan);
+ if (IEEE80211_IS_CHAN_OFDM(ichan)|| IEEE80211_IS_CHAN_HT(chan)) {
+ HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3);
+ ar5212SetSpurMitigation(ah, chan);
+ ar5416SetDeltaSlope(ah, chan);
}
/* XXX spur mitigation for Melin */
- /* Copy over internal channel flags to public hal channel */
-
- if (!(ichan->privFlags & CHANNEL_DFS))
- ichan->privFlags &= ~CHANNEL_INTERFERENCE;
- chan->channelFlags = ichan->channelFlags;
- chan->privFlags = ichan->privFlags;
- chan->maxRegTxPower = ichan->maxRegTxPower;
- chan->maxTxPower = ichan->maxTxPower;
- chan->minTxPower = ichan->minTxPower;
- AH_PRIVATE(ah)->ah_curchan->ah_channel_time=0;
- AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar5212GetTsf64(ah);
- ar5212TxEnable(ah,AH_TRUE);
+ if (!IEEE80211_IS_CHAN_DFS(chan))
+ chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
+
+ ichan->channel_time = 0;
+ ichan->tsf_last = ar5212GetTsf64(ah);
+ ar5212TxEnable(ah, AH_TRUE);
return AH_TRUE;
}
#endif
@@ -609,7 +558,7 @@ ar5416InitDMA(struct ath_hal *ah)
}
static void
-ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t synthDelay;
@@ -619,7 +568,7 @@ ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan)
* Value is in 100ns increments.
*/
synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
- if (IS_CHAN_CCK(chan)) {
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
synthDelay = (4 * synthDelay) / 22;
} else {
synthDelay /= 10;
@@ -627,7 +576,7 @@ ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan)
/* Turn on PLL on 5416 */
HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n",
- __func__, IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz");
+ __func__, IEEE80211_IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz");
ar5416InitPLL(ah, chan);
/* Activate the PHY (includes baseband activate and synthesizer on) */
@@ -639,9 +588,9 @@ ar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan)
* extra BASE_ACTIVATE_DELAY usecs to ensure this condition
* does not happen.
*/
- if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
- } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
} else {
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
@@ -673,10 +622,9 @@ ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode)
ahp->ah_maskReg |= AR_IMR_MIB;
OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
/* Enable bus errors that are OR'd to set the HIUERR bit */
-
#if 0
OS_REG_WRITE(ah, AR_IMR_S2,
- OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST);
+ OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST);
#endif
}
@@ -731,11 +679,11 @@ ar5416InitUserSettings(struct ath_hal *ah)
* Places the hardware into reset and then pulls it out of reset
*/
HAL_BOOL
-ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t rfMode = 0;
- OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
+ OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
/*
* Warm reset is optimistic.
*/
@@ -762,14 +710,14 @@ ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
*/
if (chan != AH_NULL) {
/* treat channel B as channel G , no B mode suport in owl */
- rfMode |= (IS_CHAN_G(chan) || IS_CHAN_B(chan)) ?
+ rfMode |= IEEE80211_IS_CHAN_CCK(chan) ?
AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
/* phy mode bits for 5GHz channels require Fast Clock */
rfMode |= AR_PHY_MODE_DYNAMIC
| AR_PHY_MODE_DYN_CCK_DISABLE;
} else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) {
- rfMode |= (IS_CHAN_5GHZ(chan)) ?
+ rfMode |= IEEE80211_IS_CHAN_5GHZ(chan) ?
AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
}
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
@@ -811,7 +759,7 @@ ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled,
}
void
-ar5416SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5416SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define INIT_CLOCKMHZSCALED 0x64000000
uint32_t coef_scaled, ds_coef_exp, ds_coef_man;
@@ -819,13 +767,13 @@ ar5416SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
CHAN_CENTERS centers;
- if (IS_CHAN_TURBO(chan))
+ if (IEEE80211_IS_CHAN_TURBO(chan))
clockMhzScaled *= 2;
/* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
/* scale for selected channel bandwidth */
- if (IS_CHAN_HALF_RATE(chan)) {
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
clockMhzScaled = clockMhzScaled >> 1;
- } else if (IS_CHAN_QUARTER_RATE(chan)) {
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
clockMhzScaled = clockMhzScaled >> 2;
}
@@ -835,14 +783,14 @@ ar5416SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
*/
ar5416GetChannelCenters(ah, chan, &centers);
coef_scaled = clockMhzScaled / centers.synth_center;
-
+
ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
-
+
/*
* For Short GI,
* scaled coeff is 9/10 that of normal coeff
@@ -866,8 +814,9 @@ ar5416SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
#define SPUR_RSSI_THRESH 40
static void
-ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5416SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 };
static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
@@ -888,7 +837,7 @@ ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
int8_t mask_amt;
int tmp_mask;
int cur_bb_spur;
- HAL_BOOL is2GHz = IS_CHAN_2GHZ(chan);
+ HAL_BOOL is2GHz = IEEE80211_IS_CHAN_2GHZ(chan);
OS_MEMZERO(mask_m, sizeof(mask_m));
OS_MEMZERO(mask_p, sizeof(mask_p));
@@ -901,7 +850,7 @@ ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz);
if (AR_NO_SPUR == cur_bb_spur)
break;
- cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+ cur_bb_spur = cur_bb_spur - (freq * 10);
if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
bb_spur = cur_bb_spur;
break;
@@ -938,7 +887,7 @@ ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* in 11A mode the denominator of spur_freq_sd should be 40 and
* it should be 44 in 11G
*/
- denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+ denominator = IEEE80211_IS_CHAN_2GHZ(chan) ? 440 : 400;
spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
@@ -1111,7 +1060,7 @@ ar5416SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
#define AR_SPUR_FEEQ_BOUND_HT20 10
static void
-ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
+ar9280SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 };
@@ -1136,12 +1085,12 @@ ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
int8_t mask_amt;
int tmp_mask;
int cur_bb_spur;
- HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan);
+ HAL_BOOL is2GHz = IEEE80211_IS_CHAN_2GHZ(chan);
OS_MEMZERO(&mask_m, sizeof(int8_t) * 123);
OS_MEMZERO(&mask_p, sizeof(int8_t) * 123);
- ar5416GetChannelCenters(ah, ichan, &centers);
+ ar5416GetChannelCenters(ah, chan, &centers);
freq = centers.synth_center;
/*
@@ -1212,7 +1161,7 @@ ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
OS_REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
/* Pick control or extn channel to cancel the spur */
- if (IS_CHAN_HT40(ichan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
if (bb_spur < 0) {
spur_subchannel_sd = 1;
bb_spur_off = bb_spur + 10;
@@ -1229,7 +1178,7 @@ ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
* spur_delta_phase = bb_spur/40 * 2**21 for static ht20,
* /80 for dyn2040.
*/
- if (IS_CHAN_HT40(ichan))
+ if (IEEE80211_IS_CHAN_HT40(chan))
spur_delta_phase = ((bb_spur * 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
else
spur_delta_phase = ((bb_spur * 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
@@ -1238,7 +1187,7 @@ ar9280SpurMitigate(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
* in 11A mode the denominator of spur_freq_sd should be 40 and
* it should be 44 in 11G
*/
- denominator = IS_CHAN_2GHZ(ichan) ? 44 : 40;
+ denominator = IEEE80211_IS_CHAN_2GHZ(ichan) ? 44 : 40;
spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
@@ -1426,37 +1375,29 @@ ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
}
HAL_BOOL
-ar5416GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
+ar5416GetChipPowerLimits(struct ath_hal *ah,
+ struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
int16_t minPower, maxPower;
- HAL_CHANNEL *chan;
- int i;
/*
* Get Pier table max and min powers.
*/
- for (i = 0; i < nchans; i++) {
- chan = &chans[i];
- if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
- /* NB: rf code returns 1/4 dBm units, convert */
- chan->maxTxPower = maxPower / 2;
- chan->minTxPower = minPower / 2;
- } else {
- HALDEBUG(ah, HAL_DEBUG_ANY,
- "%s: no min/max power for %u/0x%x\n",
- __func__, chan->channel, chan->channelFlags);
- chan->maxTxPower = AR5416_MAX_RATE_POWER;
- chan->minTxPower = 0;
- }
- }
-#ifdef AH_DEBUG
- for (i=0; i<nchans; i++) {
- HALDEBUG(ah, HAL_DEBUG_RESET,
- "Chan %d: MaxPow = %d MinPow = %d\n",
- chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);
+ if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
+ /* NB: rf code returns 1/4 dBm units, convert */
+ chan->ic_maxpower = maxPower / 2;
+ chan->ic_minpower = minPower / 2;
+ } else {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: no min/max power for %u/0x%x\n",
+ __func__, chan->ic_freq, chan->ic_flags);
+ chan->ic_maxpower = AR5416_MAX_RATE_POWER;
+ chan->ic_minpower = 0;
}
-#endif
+ HALDEBUG(ah, HAL_DEBUG_RESET,
+ "Chan %d: MaxPow = %d MinPow = %d\n",
+ chan->ic_freq, chan->ic_maxpower, chan->ic_minpower);
return AH_TRUE;
}
@@ -1481,7 +1422,8 @@ typedef enum Ar5416_Rates {
* operating channel and mode.
*/
static HAL_BOOL
-ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain)
+ar5416SetTransmitPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
{
#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
#define N(a) (sizeof (a) / sizeof (a[0]))
@@ -1505,13 +1447,13 @@ ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t
/* Setup info for the actual eeprom */
ath_hal_memzero(ratesArray, sizeof(ratesArray));
- cfgCtl = ath_hal_getctl(ah, (HAL_CHANNEL *)chan);
- powerLimit = chan->maxRegTxPower * 2;
- twiceAntennaReduction = chan->antennaMax;
+ cfgCtl = ath_hal_getctl(ah, chan);
+ powerLimit = chan->ic_maxregpower * 2;
+ twiceAntennaReduction = chan->ic_maxantgain;
twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
- pModal = &pEepData->modalHeader[IS_CHAN_2GHZ(chan)];
+ pModal = &pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)];
HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n",
- __func__,chan->channel, cfgCtl );
+ __func__,chan->ic_freq, cfgCtl );
if (IS_EEP_MINOR_V2(ah)) {
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
@@ -1534,11 +1476,11 @@ ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t
maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]);
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
maxPower = AH_MAX(maxPower, ratesArray[rate1l]);
}
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]);
}
@@ -1574,7 +1516,7 @@ ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t
| POW_SM(ratesArray[rate24mb], 0)
);
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
/* Write the CCK power per rate set */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
POW_SM(ratesArray[rate2s], 24)
@@ -1608,7 +1550,7 @@ ar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t
| POW_SM(ratesArray[rateHt20_4], 0)
);
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
/* Write the HT40 power per rate set */
/* Correct PAR difference between HT40 and HT20/LEGACY */
OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
@@ -1812,62 +1754,56 @@ ar5416SetReset(struct ath_hal *ah, int type)
#endif
static void
-ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t pll;
- if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
+ if (AR_SREV_MERLIN_20(ah) && chan != AH_NULL) {
+ /*
+ * PLL WAR for Merlin 2.0/2.1
+ * When doing fast clock, set PLL to 0x142c
+ * Else, set PLL to 0x2850 to prevent reset-to-reset variation
+ */
+ pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850;
+ } else if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
-
- if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) {
- pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
- } else if (chan && IS_CHAN_QUARTER_RATE(chan)) {
- pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
- }
- if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) {
- pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV);
-
- /*
- * PLL WAR for Merlin 2.0/2.1
- * When doing fast clock, set PLL to 0x142c
- * Else, set PLL to 0x2850 to prevent reset-to-reset variation
- */
- if (AR_SREV_MERLIN_20(ah)) {
- if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
- pll = 0x142c;
- } else {
- pll = 0x2850;
- }
- }
- } else {
+ if (chan != AH_NULL) {
+ if (IEEE80211_IS_CHAN_HALF(chan))
+ pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
+ pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
+ else if (IEEE80211_IS_CHAN_5GHZ(chan))
+ pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV);
+ else
+ pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
+ } else
pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
- }
} else if (AR_SREV_SOWL_10_OR_LATER(ah)) {
pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
-
- if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) {
- pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
- } else if (chan && IS_CHAN_QUARTER_RATE(chan)) {
- pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
- }
- if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) {
- pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV);
- } else {
+ if (chan != AH_NULL) {
+ if (IEEE80211_IS_CHAN_HALF(chan))
+ pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
+ pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
+ else if (IEEE80211_IS_CHAN_5GHZ(chan))
+ pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV);
+ else
+ pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV);
+ } else
pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV);
- }
} else {
pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
-
- if (chan != AH_NULL && IS_CHAN_HALF_RATE(chan)) {
- pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
- } else if (chan != AH_NULL && IS_CHAN_QUARTER_RATE(chan)) {
- pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
- }
- if (chan != AH_NULL && IS_CHAN_5GHZ(chan)) {
- pll |= SM(0xa, AR_RTC_PLL_DIV);
- } else {
+ if (chan != AH_NULL) {
+ if (IEEE80211_IS_CHAN_HALF(chan))
+ pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+ else if (IEEE80211_IS_CHAN_QUARTER(chan))
+ pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+ else if (IEEE80211_IS_CHAN_5GHZ(chan))
+ pll |= SM(0xa, AR_RTC_PLL_DIV);
+ else
+ pll |= SM(0xb, AR_RTC_PLL_DIV);
+ } else
pll |= SM(0xb, AR_RTC_PLL_DIV);
- }
}
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
@@ -1885,7 +1821,7 @@ ar5416InitPLL(struct ath_hal *ah, HAL_CHANNEL *chan)
* given the channel value.
*/
static HAL_BOOL
-ar5416SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
+ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
const struct ar5416eeprom *eep = &ee->ee_base;
@@ -1894,9 +1830,10 @@ ar5416SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
uint8_t txRxAttenLocal; /* workaround for eeprom versions <= 14.2 */
HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
- pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+ pModal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)];
- txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; /* workaround for eeprom versions <= 14.2 */
+ /* NB: workaround for eeprom versions <= 14.2 */
+ txRxAttenLocal = IEEE80211_IS_CHAN_2GHZ(chan) ? 23 : 44;
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
@@ -1968,7 +1905,7 @@ ar5416SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
}
if (IS_EEP_MINOR_V3(ah)) {
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
/* Overwrite switch settling with HT40 value */
OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
}
@@ -2012,7 +1949,7 @@ ar5416SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
*/
static HAL_BOOL
ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
- HAL_CHANNEL_INTERNAL *chan,
+ const struct ieee80211_channel *chan,
int16_t *ratesArray, uint16_t cfgCtl,
uint16_t AntennaReduction,
uint16_t twiceMaxRegulatoryPower,
@@ -2050,29 +1987,30 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
/* Compute TxPower reduction due to Antenna Gain */
- twiceLargestAntenna = AH_MAX(AH_MAX(pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]),
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+ twiceLargestAntenna = AH_MAX(AH_MAX(
+ pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+ pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]),
+ pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
#if 0
/* Turn it back on if we need to calculate per chain antenna gain reduction */
/* Use only if the expected gain > 6dbi */
/* Chain 0 is always used */
- twiceLargestAntenna = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0];
+ twiceLargestAntenna = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0];
/* Look at antenna gains of Chains 1 and 2 if the TX mask is set */
if (ahp->ah_tx_chainmask & 0x2)
twiceLargestAntenna = AH_MAX(twiceLargestAntenna,
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+ pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
if (ahp->ah_tx_chainmask & 0x4)
twiceLargestAntenna = AH_MAX(twiceLargestAntenna,
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+ pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
#endif
twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0);
/* XXX setup for 5212 use (really used?) */
ath_hal_eepromSet(ah,
- IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5,
+ IEEE80211_IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5,
twiceLargestAntenna);
/*
@@ -2087,10 +2025,10 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
case 1:
break;
case 2:
- scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain;
+ scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain;
break;
case 3:
- scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain;
+ scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain;
break;
default:
return AH_FALSE; /* Unsupported number of chains */
@@ -2099,7 +2037,7 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
scaledPower = AH_MAX(0, scaledPower);
/* Get target powers from EEPROM - our baseline for TX Power */
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
/* Setup for CTL modes */
numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */
pCtlMode = ctlModesFor11g;
@@ -2111,7 +2049,7 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20,
AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */
ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40,
@@ -2132,7 +2070,7 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT20,
AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */
ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT40,
@@ -2152,9 +2090,8 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
*
*/
for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-
HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
- (pCtlMode[ctlMode] == CTL_2GHT40);
+ (pCtlMode[ctlMode] == CTL_2GHT40);
if (isHt40CtlMode) {
freq = centers.ctl_center;
} else if (pCtlMode[ctlMode] & EXT_ADDITIVE) {
@@ -2174,7 +2111,7 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
rep = &(pEepData->ctlData[i]);
twiceMinEdgePower = ar5416GetMaxEdgePower(freq,
rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1],
- IS_CHAN_2GHZ(chan));
+ IEEE80211_IS_CHAN_2GHZ(chan));
if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
/* Find the minimum of all CTL edge powers that apply to this channel */
twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
@@ -2235,20 +2172,20 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
}
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rate1l] = targetPowerCck.tPow2x[0];
ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
}
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
}
ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
}
}
@@ -2321,7 +2258,7 @@ ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2G
* channel, and number of channels
*/
static void
-ar5416GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
+ar5416GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan,
CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels,
CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates,
HAL_BOOL isHt40Target)
@@ -2336,22 +2273,22 @@ ar5416GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
freq = isHt40Target ? centers.synth_center : centers.ctl_center;
/* Copy the target powers into the temp channel list */
- if (freq <= fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+ if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
matchIndex = 0;
} else {
for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) {
+ if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
matchIndex = i;
break;
- } else if ((freq < fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) &&
- (freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan))))
+ } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) &&
+ (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))))
{
lowIndex = i - 1;
break;
}
}
if ((matchIndex == -1) && (lowIndex == -1)) {
- HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan)));
+ HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)));
matchIndex = i - 1;
}
}
@@ -2364,8 +2301,8 @@ ar5416GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* Get the lower and upper channels, target powers,
* and interpolate between them.
*/
- clo = fbin2freq(powInfo[lowIndex].bChannel, IS_CHAN_2GHZ(chan));
- chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IS_CHAN_2GHZ(chan));
+ clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
+ chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
for (i = 0; i < numRates; i++) {
pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi,
@@ -2381,7 +2318,7 @@ ar5416GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
*/
static void
ar5416GetTargetPowersLeg(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan,
+ const struct ieee80211_channel *chan,
CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels,
CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates,
HAL_BOOL isExtTarget)
@@ -2396,22 +2333,22 @@ ar5416GetTargetPowersLeg(struct ath_hal *ah,
freq = (isExtTarget) ? centers.ext_center :centers.ctl_center;
/* Copy the target powers into the temp channel list */
- if (freq <= fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+ if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
matchIndex = 0;
} else {
for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) {
+ if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
matchIndex = i;
break;
- } else if ((freq < fbin2freq(powInfo[i].bChannel, IS_CHAN_2GHZ(chan))) &&
- (freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan))))
+ } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) &&
+ (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))))
{
lowIndex = i - 1;
break;
}
}
if ((matchIndex == -1) && (lowIndex == -1)) {
- HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IS_CHAN_2GHZ(chan)));
+ HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)));
matchIndex = i - 1;
}
}
@@ -2424,8 +2361,8 @@ ar5416GetTargetPowersLeg(struct ath_hal *ah,
* Get the lower and upper channels, target powers,
* and interpolate between them.
*/
- clo = fbin2freq(powInfo[lowIndex].bChannel, IS_CHAN_2GHZ(chan));
- chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IS_CHAN_2GHZ(chan));
+ clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
+ chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
for (i = 0; i < numRates; i++) {
pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi,
@@ -2442,7 +2379,8 @@ ar5416GetTargetPowersLeg(struct ath_hal *ah,
* linear voltage to power level table.
*/
static HAL_BOOL
-ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, HAL_CHANNEL_INTERNAL *chan, int16_t *pTxPowerIndexOffset)
+ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
+ const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
{
CAL_DATA_PER_FREQ *pRawDataset;
uint8_t *pCalBChans = AH_NULL;
@@ -2457,15 +2395,15 @@ ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, HAL_CH
ath_hal_memzero(xpdGainValues, sizeof(xpdGainValues));
- xpdMask = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].xpdGain;
+ xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain;
if (IS_EEP_MINOR_V2(ah)) {
- pdGainOverlap_t2 = pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pdGainOverlap;
+ pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap;
} else {
pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
}
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
pCalBChans = pEepData->calFreqPier2G;
numPiers = AR5416_NUM_2G_CAL_PIERS;
} else {
@@ -2505,7 +2443,7 @@ ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, HAL_CH
}
if (pEepData->baseEepHeader.txMask & (1 << i)) {
- if (IS_CHAN_2GHZ(chan)) {
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
pRawDataset = pEepData->calPierData2G[i];
} else {
pRawDataset = pEepData->calPierData5G[i];
@@ -2567,7 +2505,8 @@ ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, HAL_CH
*/
static void
ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet,
+ const struct ieee80211_channel *chan,
+ CAL_DATA_PER_FREQ *pRawDataSet,
uint8_t * bChans, uint16_t availPiers,
uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries,
uint8_t * pPDADCValues, uint16_t numXpdGains)
@@ -2606,7 +2545,7 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
}
/* Find pier indexes around the current channel */
- match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+ match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
bChans, numPiers, &idxL, &idxR);
if (match) {
@@ -2637,7 +2576,7 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
/* Interpolate the final vpd */
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
- vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+ vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));
}
}
@@ -2830,12 +2769,12 @@ interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
}
static void
-ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan)
+ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t phymode;
HAL_HT_MACMODE macmode; /* MAC - 20/40 mode */
- if (!IS_CHAN_HT(chan))
+ if (!IEEE80211_IS_CHAN_HT(chan))
return;
/* Enable 11n HT, 20 MHz */
@@ -2843,11 +2782,11 @@ ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan)
| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
/* Configure baseband for dynamic 20/40 operation */
- if (IS_CHAN_HT40(chan)) {
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
phymode |= AR_PHY_FC_DYN2040_EN | AR_PHY_FC_SHORT_GI_40;
/* Configure control (primary) channel at +-10MHz */
- if ((chan->channelFlags & CHANNEL_HT40PLUS))
+ if (IEEE80211_IS_CHAN_HT40U(chan))
phymode |= AR_PHY_FC_DYN2040_PRI_CH;
#if 0
/* Configure 20/25 spacing */
@@ -2873,23 +2812,25 @@ ar5416Set11nRegs(struct ath_hal *ah, HAL_CHANNEL *chan)
void
ar5416GetChannelCenters(struct ath_hal *ah,
- HAL_CHANNEL_INTERNAL *chan, CHAN_CENTERS *centers)
+ const struct ieee80211_channel *chan, CHAN_CENTERS *centers)
{
- centers->ctl_center = chan->channel;
- centers->synth_center = chan->channel;
+ uint16_t freq = ath_hal_gethwchannel(ah, chan);
+
+ centers->ctl_center = freq;
+ centers->synth_center = freq;
/*
* In 20/40 phy mode, the center frequency is
* "between" the control and extension channels.
*/
- if (chan->channelFlags & CHANNEL_HT40PLUS) {
+ if (IEEE80211_IS_CHAN_HT40U(chan)) {
centers->synth_center += HT40_CHANNEL_CENTER_SHIFT;
centers->ext_center =
centers->synth_center + HT40_CHANNEL_CENTER_SHIFT;
- } else if (chan->channelFlags & CHANNEL_HT40MINUS) {
+ } else if (IEEE80211_IS_CHAN_HT40D(chan)) {
centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT;
centers->ext_center =
centers->synth_center - HT40_CHANNEL_CENTER_SHIFT;
} else {
- centers->ext_center = chan->channel;
+ centers->ext_center = freq;
}
}
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
index a0e2f14..e82474b 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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: ar5416_xmit.c,v 1.9 2008/11/27 22:30:08 sam Exp $
+ * $FreeBSD$
*/
#include "opt_ah.h"
diff --git a/sys/dev/ath/ath_rate/amrr/amrr.c b/sys/dev/ath/ath_rate/amrr/amrr.c
index ba99177..88e71e6 100644
--- a/sys/dev/ath/ath_rate/amrr/amrr.c
+++ b/sys/dev/ath/ath_rate/amrr/amrr.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
-#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -434,29 +433,3 @@ ath_rate_detach(struct ath_ratectrl *arc)
free(asc, M_DEVBUF);
}
-
-/*
- * Module glue.
- */
-static int
-amrr_modevent(module_t mod, int type, void *unused)
-{
- switch (type) {
- case MOD_LOAD:
- if (bootverbose)
- printf("ath_rate: <AMRR rate control algorithm> version 0.1\n");
- return 0;
- case MOD_UNLOAD:
- return 0;
- }
- return EINVAL;
-}
-
-static moduledata_t amrr_mod = {
- "ath_rate",
- amrr_modevent,
- 0
-};
-DECLARE_MODULE(ath_rate, amrr_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
-MODULE_VERSION(ath_rate, 1);
-MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c
index 96f8db9..22811c4 100644
--- a/sys/dev/ath/ath_rate/onoe/onoe.c
+++ b/sys/dev/ath/ath_rate/onoe/onoe.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
-#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -403,29 +402,3 @@ ath_rate_detach(struct ath_ratectrl *arc)
free(osc, M_DEVBUF);
}
-
-/*
- * Module glue.
- */
-static int
-onoe_modevent(module_t mod, int type, void *unused)
-{
- switch (type) {
- case MOD_LOAD:
- if (bootverbose)
- printf("ath_rate: <Atsushi Onoe's rate control algorithm>\n");
- return 0;
- case MOD_UNLOAD:
- return 0;
- }
- return EINVAL;
-}
-
-static moduledata_t onoe_mod = {
- "ath_rate",
- onoe_modevent,
- 0
-};
-DECLARE_MODULE(ath_rate, onoe_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
-MODULE_VERSION(ath_rate, 1);
-MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c
index 48aedf5..b51b45f 100644
--- a/sys/dev/ath/ath_rate/sample/sample.c
+++ b/sys/dev/ath/ath_rate/sample/sample.c
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
-#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -755,23 +754,18 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
sn->static_rix = -1;
if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
/*
- * A fixed rate is to be used; ic_fixed_rate is the
- * IEEE code for this rate (sans basic bit). Convert this
- * to the index into the negotiated rate set for
- * the node.
+ * A fixed rate is to be used; ucastrate is the IEEE code
+ * for this rate (sans basic bit). Check this against the
+ * negotiated rate set for the node. Note the fixed rate
+ * may not be available for various reasons so we only
+ * setup the static rate index if the lookup is successful.
+ * XXX handle MCS
*/
- /* NB: the rate set is assumed sorted */
- srate = ni->ni_rates.rs_nrates - 1;
- for (; srate >= 0 && RATE(srate) != tp->ucastrate; srate--)
- ;
- /*
- * The fixed rate may not be available due to races
- * and mode settings. Also orphaned nodes created in
- * adhoc mode may not have any rate set so this lookup
- * can fail.
- */
- if (srate >= 0)
- sn->static_rix = sc->sc_rixmap[srate];
+ for (srate = ni->ni_rates.rs_nrates - 1; srate >= 0; srate--)
+ if (RATE(srate) == tp->ucastrate) {
+ sn->static_rix = sc->sc_rixmap[tp->ucastrate];
+ break;
+ }
}
/*
@@ -993,29 +987,3 @@ ath_rate_detach(struct ath_ratectrl *arc)
free(ssc, M_DEVBUF);
}
-
-/*
- * Module glue.
- */
-static int
-sample_modevent(module_t mod, int type, void *unused)
-{
- switch (type) {
- case MOD_LOAD:
- if (bootverbose)
- printf("ath_rate: version 1.9 <SampleRate bit-rate selection algorithm>\n");
- return 0;
- case MOD_UNLOAD:
- return 0;
- }
- return EINVAL;
-}
-
-static moduledata_t sample_mod = {
- "ath_rate",
- sample_modevent,
- 0
-};
-DECLARE_MODULE(ath_rate, sample_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
-MODULE_VERSION(ath_rate, 1);
-MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 006e712..c9a9801 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -68,6 +68,10 @@ __FBSDID("$FreeBSD$");
#include <net/if_llc.h>
#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
+#ifdef ATH_SUPPORT_TDMA
+#include <net80211/ieee80211_tdma.h>
+#endif
#include <net/bpf.h>
@@ -113,9 +117,6 @@ CTASSERT(ATH_BCBUF <= 8);
((((u_int8_t *)(p))[0] ) | (((u_int8_t *)(p))[1] << 8) | \
(((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)))
-#define CTRY_XR9 5001 /* Ubiquiti XR9 */
-#define CTRY_GZ901 5002 /* ZComax GZ-901 */
-
static struct ieee80211vap *ath_vap_create(struct ieee80211com *,
const char name[IFNAMSIZ], int unit, int opmode,
int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
@@ -202,7 +203,7 @@ static void ath_newassoc(struct ieee80211_node *, int);
static int ath_setregdomain(struct ieee80211com *,
struct ieee80211_regdomain *, int,
struct ieee80211_channel []);
-static void ath_getradiocaps(struct ieee80211com *, int *,
+static void ath_getradiocaps(struct ieee80211com *, int, int *,
struct ieee80211_channel []);
static int ath_getchannels(struct ath_softc *);
static void ath_led_event(struct ath_softc *, int);
@@ -216,6 +217,50 @@ static int ath_raw_xmit(struct ieee80211_node *,
static void ath_bpfattach(struct ath_softc *);
static void ath_announce(struct ath_softc *);
+#ifdef ATH_SUPPORT_TDMA
+static void ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
+ u_int32_t bintval);
+static void ath_tdma_bintvalsetup(struct ath_softc *sc,
+ const struct ieee80211_tdma_state *tdma);
+static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
+static void ath_tdma_update(struct ieee80211_node *ni,
+ const struct ieee80211_tdma_param *tdma);
+static void ath_tdma_beacon_send(struct ath_softc *sc,
+ struct ieee80211vap *vap);
+
+static __inline void
+ath_hal_setcca(struct ath_hal *ah, int ena)
+{
+ /*
+ * NB: fill me in; this is not provided by default because disabling
+ * CCA in most locales violates regulatory.
+ */
+}
+
+static __inline int
+ath_hal_getcca(struct ath_hal *ah)
+{
+ u_int32_t diag;
+ if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK)
+ return 1;
+ return ((diag & 0x500000) == 0);
+}
+
+#define TDMA_EP_MULTIPLIER (1<<10) /* pow2 to optimize out * and / */
+#define TDMA_LPF_LEN 6
+#define TDMA_DUMMY_MARKER 0x127
+#define TDMA_EP_MUL(x, mul) ((x) * (mul))
+#define TDMA_IN(x) (TDMA_EP_MUL((x), TDMA_EP_MULTIPLIER))
+#define TDMA_LPF(x, y, len) \
+ ((x != TDMA_DUMMY_MARKER) ? (((x) * ((len)-1) + (y)) / (len)) : (y))
+#define TDMA_SAMPLE(x, y) do { \
+ x = TDMA_LPF((x), TDMA_IN(y), TDMA_LPF_LEN); \
+} while (0)
+#define TDMA_EP_RND(x,mul) \
+ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define TDMA_AVG(x) TDMA_EP_RND(x, TDMA_EP_MULTIPLIER)
+#endif /* ATH_SUPPORT_TDMA */
+
SYSCTL_DECL(_hw_ath);
/* XXX validate sysctl values */
@@ -260,6 +305,8 @@ enum {
ATH_DEBUG_LED = 0x00100000, /* led management */
ATH_DEBUG_FF = 0x00200000, /* fast frames */
ATH_DEBUG_DFS = 0x00400000, /* DFS processing */
+ ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */
+ ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */
ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
ATH_DEBUG_ANY = 0xffffffff
@@ -612,10 +659,15 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
if (ath_hal_hasfastframes(ah))
ic->ic_caps |= IEEE80211_C_FF;
- wmodes = ath_hal_getwirelessmodes(ah, ic->ic_regdomain.country);
+ wmodes = ath_hal_getwirelessmodes(ah);
if (wmodes & (HAL_MODE_108G|HAL_MODE_TURBO))
ic->ic_caps |= IEEE80211_C_TURBOP;
-
+#ifdef ATH_SUPPORT_TDMA
+ if (ath_hal_macversion(ah) > 0x78) {
+ ic->ic_caps |= IEEE80211_C_TDMA; /* capable of TDMA */
+ ic->ic_tdma_update = ath_tdma_update;
+ }
+#endif
/*
* Indicate we need the 802.11 header padded to a
* 32-bit boundary for 4-address and QoS frames.
@@ -824,10 +876,9 @@ ath_vap_create(struct ieee80211com *ic,
*/
flags |= IEEE80211_CLONE_NOBEACONS;
}
- if (flags & IEEE80211_CLONE_NOBEACONS) {
- sc->sc_swbmiss = 1;
+ if (flags & IEEE80211_CLONE_NOBEACONS)
ic_opmode = IEEE80211_M_HOSTAP;
- } else
+ else
ic_opmode = opmode;
break;
case IEEE80211_M_IBSS:
@@ -840,7 +891,13 @@ ath_vap_create(struct ieee80211com *ic,
needbeacon = 1;
break;
case IEEE80211_M_AHDEMO:
+#ifdef ATH_SUPPORT_TDMA
+ if (flags & IEEE80211_CLONE_TDMA) {
+ needbeacon = 1;
+ flags |= IEEE80211_CLONE_NOBEACONS;
+ }
/* fall thru... */
+#endif
case IEEE80211_M_MONITOR:
if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) {
/* XXX not right for monitor mode */
@@ -959,6 +1016,18 @@ ath_vap_create(struct ieee80211com *ic,
sc->sc_opmode = HAL_M_STA;
break;
case IEEE80211_M_AHDEMO:
+#ifdef ATH_SUPPORT_TDMA
+ if (vap->iv_caps & IEEE80211_C_TDMA) {
+ sc->sc_tdma = 1;
+ /* NB: disable tsf adjust */
+ sc->sc_stagbeacons = 0;
+ }
+ /*
+ * NB: adhoc demo mode is a pseudo mode; to the hal it's
+ * just ap mode.
+ */
+ /* fall thru... */
+#endif
case IEEE80211_M_HOSTAP:
sc->sc_opmode = HAL_M_HOSTAP;
break;
@@ -975,6 +1044,12 @@ ath_vap_create(struct ieee80211com *ic,
*/
ath_hal_settsfadjust(sc->sc_ah, sc->sc_stagbeacons);
}
+ if (flags & IEEE80211_CLONE_NOBEACONS) {
+ /*
+ * Enable s/w beacon miss handling.
+ */
+ sc->sc_swbmiss = 1;
+ }
ATH_UNLOCK(sc);
/* complete setup */
@@ -1047,6 +1122,13 @@ ath_vap_delete(struct ieee80211vap *vap)
}
if (vap->iv_opmode != IEEE80211_M_WDS)
sc->sc_nvaps--;
+#ifdef ATH_SUPPORT_TDMA
+ /* TDMA operation ceases when the last vap is destroyed */
+ if (sc->sc_tdma && sc->sc_nvaps == 0) {
+ sc->sc_tdma = 0;
+ sc->sc_swbmiss = 0;
+ }
+#endif
ATH_UNLOCK(sc);
free(avp, M_80211_VAP);
@@ -1119,7 +1201,7 @@ ath_resume(struct ath_softc *sc)
* Must reset the chip before we reload the
* keycache as we were powered down on suspend.
*/
- ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status);
+ ath_hal_reset(ah, sc->sc_opmode, sc->sc_curchan, AH_FALSE, &status);
ath_reset_keycache(sc);
if (sc->sc_resume_up) {
if (ic->ic_opmode == IEEE80211_M_STA) {
@@ -1198,7 +1280,20 @@ ath_intr(void *arg)
* this is too slow to meet timing constraints
* under load.
*/
- ath_beacon_proc(sc, 0);
+#ifdef ATH_SUPPORT_TDMA
+ if (sc->sc_tdma) {
+ if (sc->sc_tdmaswba == 0) {
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211vap *vap =
+ TAILQ_FIRST(&ic->ic_vaps);
+ ath_tdma_beacon_send(sc, vap);
+ sc->sc_tdmaswba =
+ vap->iv_tdma->tdma_bintval;
+ } else
+ sc->sc_tdmaswba--;
+ } else
+#endif
+ ath_beacon_proc(sc, 0);
}
if (status & HAL_INT_RXEOL) {
/*
@@ -1326,56 +1421,6 @@ ath_bmiss_proc(void *arg, int pending)
}
/*
- * Convert net80211 channel to a HAL channel with the flags
- * constrained to reflect the current operating mode and
- * the frequency possibly mapped for GSM channels.
- */
-static void
-ath_mapchan(const struct ieee80211com *ic,
- HAL_CHANNEL *hc, const struct ieee80211_channel *chan)
-{
-#define N(a) (sizeof(a) / sizeof(a[0]))
- static const u_int modeflags[IEEE80211_MODE_MAX] = {
- 0, /* IEEE80211_MODE_AUTO */
- CHANNEL_A, /* IEEE80211_MODE_11A */
- CHANNEL_B, /* IEEE80211_MODE_11B */
- CHANNEL_PUREG, /* IEEE80211_MODE_11G */
- 0, /* IEEE80211_MODE_FH */
- CHANNEL_108A, /* IEEE80211_MODE_TURBO_A */
- CHANNEL_108G, /* IEEE80211_MODE_TURBO_G */
- CHANNEL_ST, /* IEEE80211_MODE_STURBO_A */
- CHANNEL_A, /* IEEE80211_MODE_11NA */
- CHANNEL_PUREG, /* IEEE80211_MODE_11NG */
- };
- enum ieee80211_phymode mode = ieee80211_chan2mode(chan);
-
- KASSERT(mode < N(modeflags), ("unexpected phy mode %u", mode));
- KASSERT(modeflags[mode] != 0, ("mode %u undefined", mode));
- hc->channelFlags = modeflags[mode];
- if (IEEE80211_IS_CHAN_HALF(chan))
- hc->channelFlags |= CHANNEL_HALF;
- if (IEEE80211_IS_CHAN_QUARTER(chan))
- hc->channelFlags |= CHANNEL_QUARTER;
- if (IEEE80211_IS_CHAN_HT20(chan))
- hc->channelFlags |= CHANNEL_HT20;
- if (IEEE80211_IS_CHAN_HT40D(chan))
- hc->channelFlags |= CHANNEL_HT40MINUS;
- if (IEEE80211_IS_CHAN_HT40U(chan))
- hc->channelFlags |= CHANNEL_HT40PLUS;
-
- if (IEEE80211_IS_CHAN_GSM(chan)) {
- if (ic->ic_regdomain.country == CTRY_XR9)
- hc->channel = 1520 + chan->ic_freq;
- else if (ic->ic_regdomain.country == CTRY_GZ901)
- hc->channel = 1544 + chan->ic_freq;
- else
- hc->channel = 3344 - chan->ic_freq;
- } else
- hc->channel = chan->ic_freq;
-#undef N
-}
-
-/*
* Handle TKIP MIC setup to deal hardware that doesn't do MIC
* calcs together with WME. If necessary disable the crypto
* hardware and mark the 802.11 state so keys will be setup
@@ -1424,9 +1469,8 @@ ath_init(void *arg)
* be followed by initialization of the appropriate bits
* and then setup of the interrupt mask.
*/
- ath_mapchan(ic, &sc->sc_curchan, ic->ic_curchan);
ath_settkipmic(sc);
- if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) {
+ if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_FALSE, &status)) {
if_printf(ifp, "unable to reset hardware; hal status %u\n",
status);
ATH_UNLOCK(sc);
@@ -1558,18 +1602,12 @@ ath_reset(struct ifnet *ifp)
struct ath_hal *ah = sc->sc_ah;
HAL_STATUS status;
- /*
- * Convert to a HAL channel description with the flags
- * constrained to reflect the current operating mode.
- */
- ath_mapchan(ic, &sc->sc_curchan, ic->ic_curchan);
-
ath_hal_intrset(ah, 0); /* disable interrupts */
ath_draintxq(sc); /* stop xmit side */
ath_stoprecv(sc); /* stop recv side */
ath_settkipmic(sc); /* configure TKIP MIC handling */
/* NB: indicate channel change so we do a full reset */
- if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_TRUE, &status))
+ if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_TRUE, &status))
if_printf(ifp, "%s: unable to reset hardware; hal status %u\n",
__func__, status);
sc->sc_diversity = ath_hal_getdiversity(ah);
@@ -1581,8 +1619,14 @@ ath_reset(struct ifnet *ifp)
* might change as a result.
*/
ath_chan_change(sc, ic->ic_curchan);
- if (sc->sc_beacons)
- ath_beacon_config(sc, NULL); /* restart beacons */
+ if (sc->sc_beacons) {
+#ifdef ATH_SUPPORT_TDMA
+ if (sc->sc_tdma)
+ ath_tdma_config(sc, NULL);
+ else
+#endif
+ ath_beacon_config(sc, NULL); /* restart beacons */
+ }
ath_hal_intrset(ah, sc->sc_imask);
ath_start(ifp); /* restart xmit */
@@ -1688,7 +1732,7 @@ ath_ff_stageq_flush(struct ath_softc *sc, struct ath_txq *txq,
}
ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
}
}
@@ -1829,7 +1873,7 @@ ath_ff_check(struct ath_softc *sc, struct ath_txq *txq,
* Return bfstaged to the free list.
*/
ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bfstaged, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bfstaged, bf_list);
ATH_TXBUF_UNLOCK(sc);
return m; /* ready to go */
@@ -1902,7 +1946,7 @@ ath_ff_check(struct ath_softc *sc, struct ath_txq *txq,
}
ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bfstaged, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bfstaged, bf_list);
ATH_TXBUF_UNLOCK(sc);
} else {
#if 0
@@ -1925,6 +1969,45 @@ ath_ff_check(struct ath_softc *sc, struct ath_txq *txq,
return m;
}
+static struct ath_buf *
+_ath_getbuf_locked(struct ath_softc *sc)
+{
+ struct ath_buf *bf;
+
+ ATH_TXBUF_LOCK_ASSERT(sc);
+
+ bf = STAILQ_FIRST(&sc->sc_txbuf);
+ if (bf != NULL && (bf->bf_flags & ATH_BUF_BUSY) == 0)
+ STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
+ else
+ bf = NULL;
+ if (bf == NULL) {
+ DPRINTF(sc, ATH_DEBUG_XMIT, "%s: %s\n", __func__,
+ STAILQ_FIRST(&sc->sc_txbuf) == NULL ?
+ "out of xmit buffers" : "xmit buffer busy");
+ sc->sc_stats.ast_tx_nobuf++;
+ }
+ return bf;
+}
+
+static struct ath_buf *
+ath_getbuf(struct ath_softc *sc)
+{
+ struct ath_buf *bf;
+
+ ATH_TXBUF_LOCK(sc);
+ bf = _ath_getbuf_locked(sc);
+ if (bf == NULL) {
+ struct ifnet *ifp = sc->sc_ifp;
+
+ DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__);
+ sc->sc_stats.ast_tx_qstop++;
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ }
+ ATH_TXBUF_UNLOCK(sc);
+ return bf;
+}
+
/*
* Cleanup driver resources when we run out of buffers
* while processing fragments; return the tx buffers
@@ -1941,7 +2024,7 @@ ath_txfrag_cleanup(struct ath_softc *sc,
STAILQ_FOREACH_SAFE(bf, frags, bf_list, next) {
/* NB: bf assumed clean */
STAILQ_REMOVE_HEAD(frags, bf_list);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ieee80211_node_decref(ni);
}
}
@@ -1960,12 +2043,11 @@ ath_txfrag_setup(struct ath_softc *sc, ath_bufhead *frags,
ATH_TXBUF_LOCK(sc);
for (m = m0->m_nextpkt; m != NULL; m = m->m_nextpkt) {
- bf = STAILQ_FIRST(&sc->sc_txbuf);
+ bf = _ath_getbuf_locked(sc);
if (bf == NULL) { /* out of buffers, cleanup */
ath_txfrag_cleanup(sc, frags, ni);
break;
}
- STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
ieee80211_node_incref(ni);
STAILQ_INSERT_TAIL(frags, bf, bf_list);
}
@@ -1992,23 +2074,14 @@ ath_start(struct ifnet *ifp)
/*
* Grab a TX buffer and associated resources.
*/
- ATH_TXBUF_LOCK(sc);
- bf = STAILQ_FIRST(&sc->sc_txbuf);
- if (bf != NULL)
- STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
- ATH_TXBUF_UNLOCK(sc);
- if (bf == NULL) {
- DPRINTF(sc, ATH_DEBUG_XMIT, "%s: out of xmit buffers\n",
- __func__);
- sc->sc_stats.ast_tx_qstop++;
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ bf = ath_getbuf(sc);
+ if (bf == NULL)
break;
- }
IFQ_DEQUEUE(&ifp->if_snd, m);
if (m == NULL) {
ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
break;
}
@@ -2082,7 +2155,7 @@ ath_start(struct ifnet *ifp)
bf->bf_m = NULL;
bf->bf_node = NULL;
ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ath_txfrag_cleanup(sc, &frags, ni);
ATH_TXBUF_UNLOCK(sc);
if (ni != NULL)
@@ -3270,6 +3343,7 @@ ath_bstuck_proc(void *arg, int pending)
if_printf(ifp, "stuck beacon; resetting (bmiss count %u)\n",
sc->sc_bmisscount);
+ sc->sc_stats.ast_bstuck++;
ath_reset(ifp);
}
@@ -3742,13 +3816,11 @@ ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
struct ieee80211com *ic = ni->ni_ic;
struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
- HAL_CHANNEL hchan;
*rssi = ic->ic_node_getrssi(ni);
- if (ni->ni_chan != IEEE80211_CHAN_ANYC) {
- ath_mapchan(ic, &hchan, ni->ni_chan);
- *noise = ath_hal_getchannoise(ah, &hchan);
- } else
+ if (ni->ni_chan != IEEE80211_CHAN_ANYC)
+ *noise = ath_hal_getchannoise(ah, ni->ni_chan);
+ else
*noise = -95; /* nominally correct */
}
@@ -3938,9 +4010,11 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
#ifdef AH_SUPPORT_AR5416
sc->sc_rx_th.wr_chan_flags &= ~CHAN_HT;
if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */
+ struct ieee80211com *ic = ifp->if_l2com;
+
if ((rs->rs_flags & HAL_RX_2040) == 0)
sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
- else if (sc->sc_curchan.channelFlags & CHANNEL_HT40PLUS)
+ else if (IEEE80211_IS_CHAN_HT40U(ic->ic_curchan))
sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U;
else
sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D;
@@ -4003,7 +4077,7 @@ ath_rx_proc(void *arg, int npending)
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
ngood = 0;
- nf = ath_hal_getchannoise(ah, &sc->sc_curchan);
+ nf = ath_hal_getchannoise(ah, sc->sc_curchan);
sc->sc_stats.ast_rx_noise = nf;
tsf = ath_hal_gettsf64(ah);
do {
@@ -4215,6 +4289,9 @@ rx_accept:
/*
* Sending station is known, dispatch directly.
*/
+#ifdef ATH_SUPPORT_TDMA
+ sc->sc_tdmars = rs;
+#endif
type = ieee80211_input(ni, m,
rs->rs_rssi, nf, rs->rs_tstamp);
ieee80211_free_node(ni);
@@ -4266,7 +4343,7 @@ rx_next:
} while (ath_rxbuf_init(sc, bf) == 0);
/* rx signal state monitoring */
- ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
+ ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan);
if (ngood)
sc->sc_lastrx = tsf;
@@ -4387,10 +4464,48 @@ ath_txq_update(struct ath_softc *sc, int ac)
HAL_TXQ_INFO qi;
ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
- qi.tqi_aifs = wmep->wmep_aifsn;
- qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
- qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
- qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
+#ifdef ATH_SUPPORT_TDMA
+ if (sc->sc_tdma) {
+ /*
+ * AIFS is zero so there's no pre-transmit wait. The
+ * burst time defines the slot duration and is configured
+ * via sysctl. The QCU is setup to not do post-xmit
+ * back off, lockout all lower-priority QCU's, and fire
+ * off the DMA beacon alert timer which is setup based
+ * on the slot configuration.
+ */
+ qi.tqi_qflags = HAL_TXQ_TXOKINT_ENABLE
+ | HAL_TXQ_TXERRINT_ENABLE
+ | HAL_TXQ_TXURNINT_ENABLE
+ | HAL_TXQ_TXEOLINT_ENABLE
+ | HAL_TXQ_DBA_GATED
+ | HAL_TXQ_BACKOFF_DISABLE
+ | HAL_TXQ_ARB_LOCKOUT_GLOBAL
+ ;
+ qi.tqi_aifs = 0;
+ /* XXX +dbaprep? */
+ qi.tqi_readyTime = sc->sc_tdmaslotlen;
+ qi.tqi_burstTime = qi.tqi_readyTime;
+ } else {
+#endif
+ qi.tqi_qflags = HAL_TXQ_TXOKINT_ENABLE
+ | HAL_TXQ_TXERRINT_ENABLE
+ | HAL_TXQ_TXDESCINT_ENABLE
+ | HAL_TXQ_TXURNINT_ENABLE
+ ;
+ qi.tqi_aifs = wmep->wmep_aifsn;
+ qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
+ qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
+ qi.tqi_readyTime = 0;
+ qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
+#ifdef ATH_SUPPORT_TDMA
+ }
+#endif
+
+ DPRINTF(sc, ATH_DEBUG_RESET,
+ "%s: Q%u qflags 0x%x aifs %u cwmin %u cwmax %u burstTime %u\n",
+ __func__, txq->axq_qnum, qi.tqi_qflags,
+ qi.tqi_aifs, qi.tqi_cwmin, qi.tqi_cwmax, qi.tqi_burstTime);
if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
if_printf(ifp, "unable to update hardware queue "
@@ -4570,13 +4685,71 @@ ath_tx_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
* to avoid possible races.
*/
ATH_TXQ_LOCK(txq);
+ KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0,
+ ("busy status 0x%x", bf->bf_flags));
if (txq->axq_qnum != ATH_TXQ_SWQ) {
+#ifdef ATH_SUPPORT_TDMA
+ int qbusy;
+
+ ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
+ qbusy = ath_hal_txqenabled(ah, txq->axq_qnum);
+ if (txq->axq_link == NULL) {
+ /*
+ * Be careful writing the address to TXDP. If
+ * the tx q is enabled then this write will be
+ * ignored. Normally this is not an issue but
+ * when tdma is in use and the q is beacon gated
+ * this race can occur. If the q is busy then
+ * defer the work to later--either when another
+ * packet comes along or when we prepare a beacon
+ * frame at SWBA.
+ */
+ if (!qbusy) {
+ ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+ txq->axq_flags &= ~ATH_TXQ_PUTPENDING;
+ DPRINTF(sc, ATH_DEBUG_XMIT,
+ "%s: TXDP[%u] = %p (%p) depth %d\n",
+ __func__, txq->axq_qnum,
+ (caddr_t)bf->bf_daddr, bf->bf_desc,
+ txq->axq_depth);
+ } else {
+ txq->axq_flags |= ATH_TXQ_PUTPENDING;
+ DPRINTF(sc, ATH_DEBUG_TDMA | ATH_DEBUG_XMIT,
+ "%s: Q%u busy, defer enable\n", __func__,
+ txq->axq_qnum);
+ }
+ } else {
+ *txq->axq_link = bf->bf_daddr;
+ DPRINTF(sc, ATH_DEBUG_XMIT,
+ "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
+ txq->axq_qnum, txq->axq_link,
+ (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
+ if ((txq->axq_flags & ATH_TXQ_PUTPENDING) && !qbusy) {
+ /*
+ * The q was busy when we previously tried
+ * to write the address of the first buffer
+ * in the chain. Since it's not busy now
+ * handle this chore. We are certain the
+ * buffer at the front is the right one since
+ * axq_link is NULL only when the buffer list
+ * is/was empty.
+ */
+ ath_hal_puttxbuf(ah, txq->axq_qnum,
+ STAILQ_FIRST(&txq->axq_q)->bf_daddr);
+ txq->axq_flags &= ~ATH_TXQ_PUTPENDING;
+ DPRINTF(sc, ATH_DEBUG_TDMA | ATH_DEBUG_XMIT,
+ "%s: Q%u restarted\n", __func__,
+ txq->axq_qnum);
+ }
+ }
+#else
ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
if (txq->axq_link == NULL) {
ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
DPRINTF(sc, ATH_DEBUG_XMIT,
- "%s: TXDP[%u] = %p (%p) depth %d\n", __func__,
- txq->axq_qnum, (caddr_t)bf->bf_daddr, bf->bf_desc,
+ "%s: TXDP[%u] = %p (%p) depth %d\n",
+ __func__, txq->axq_qnum,
+ (caddr_t)bf->bf_daddr, bf->bf_desc,
txq->axq_depth);
} else {
*txq->axq_link = bf->bf_daddr;
@@ -4585,6 +4758,7 @@ ath_tx_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
txq->axq_qnum, txq->axq_link,
(caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
}
+#endif /* ATH_SUPPORT_TDMA */
txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
ath_hal_txstart(ah, txq->axq_qnum);
} else {
@@ -4819,6 +4993,15 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
}
if (flags & HAL_TXDESC_NOACK) /* NB: avoid double counting */
sc->sc_stats.ast_tx_noack++;
+#ifdef ATH_SUPPORT_TDMA
+ if (sc->sc_tdma && (flags & HAL_TXDESC_NOACK) == 0) {
+ DPRINTF(sc, ATH_DEBUG_TDMA,
+ "%s: discard frame, ACK required w/ TDMA\n", __func__);
+ sc->sc_stats.ast_tdma_ack++;
+ ath_freetx(m0);
+ return EIO;
+ }
+#endif
/*
* If 802.11g protection is enabled, determine whether
@@ -5017,7 +5200,7 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
struct ath_hal *ah = sc->sc_ah;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct ath_buf *bf;
+ struct ath_buf *bf, *last;
struct ath_desc *ds, *ds0;
struct ath_tx_status *ts;
struct ieee80211_node *ni;
@@ -5052,7 +5235,18 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
break;
}
ATH_TXQ_REMOVE_HEAD(txq, bf_list);
+#ifdef ATH_SUPPORT_TDMA
+ if (txq->axq_depth > 0) {
+ /*
+ * More frames follow. Mark the buffer busy
+ * so it's not re-used while the hardware may
+ * still re-read the link field in the descriptor.
+ */
+ bf->bf_flags |= ATH_BUF_BUSY;
+ } else
+#else
if (txq->axq_depth == 0)
+#endif
txq->axq_link = NULL;
ATH_TXQ_UNLOCK(txq);
@@ -5128,6 +5322,9 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
bf->bf_node = NULL;
ATH_TXBUF_LOCK(sc);
+ last = STAILQ_LAST(&sc->sc_txbuf, ath_buf, bf_list);
+ if (last != NULL)
+ last->bf_flags &= ~ATH_BUF_BUSY;
STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
}
@@ -5250,6 +5447,11 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
* NB: this assumes output has been stopped and
* we do not need to block ath_tx_proc
*/
+ ATH_TXBUF_LOCK(sc);
+ bf = STAILQ_LAST(&sc->sc_txbuf, ath_buf, bf_list);
+ if (bf != NULL)
+ bf->bf_flags &= ~ATH_BUF_BUSY;
+ ATH_TXBUF_UNLOCK(sc);
for (ix = 0;; ix++) {
ATH_TXQ_LOCK(txq);
bf = STAILQ_FIRST(&txq->axq_q);
@@ -5284,6 +5486,7 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
}
m_freem(bf->bf_m);
bf->bf_m = NULL;
+ bf->bf_flags &= ~ATH_BUF_BUSY;
ATH_TXBUF_LOCK(sc);
STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
@@ -5435,6 +5638,7 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
mode = ieee80211_chan2mode(chan);
if (mode != sc->sc_curmode)
ath_setcurmode(sc, mode);
+ sc->sc_curchan = chan;
sc->sc_rx_th.wr_chan_flags = htole32(chan->ic_flags);
sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags;
@@ -5458,27 +5662,12 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ath_hal *ah = sc->sc_ah;
- HAL_CHANNEL hchan;
- /*
- * Convert to a HAL channel description with
- * the flags constrained to reflect the current
- * operating mode.
- */
- ath_mapchan(ic, &hchan, chan);
-
- DPRINTF(sc, ATH_DEBUG_RESET,
- "%s: %u (%u MHz, hal flags 0x%x) -> %u (%u MHz, hal flags 0x%x)\n",
- __func__,
- ath_hal_mhz2ieee(ah, sc->sc_curchan.channel,
- sc->sc_curchan.channelFlags),
- sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
- ath_hal_mhz2ieee(ah, hchan.channel, hchan.channelFlags),
- hchan.channel, hchan.channelFlags);
- if (hchan.channel != sc->sc_curchan.channel ||
- hchan.channelFlags != sc->sc_curchan.channelFlags) {
+ DPRINTF(sc, ATH_DEBUG_RESET, "%s: %u (%u MHz, flags 0x%x)\n",
+ __func__, ieee80211_chan2ieee(ic, chan),
+ chan->ic_freq, chan->ic_flags);
+ if (chan != sc->sc_curchan) {
HAL_STATUS status;
-
/*
* To switch channels clear any pending DMA operations;
* wait long enough for the RX fifo to drain, reset the
@@ -5488,15 +5677,13 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
ath_hal_intrset(ah, 0); /* disable interrupts */
ath_draintxq(sc); /* clear pending tx frames */
ath_stoprecv(sc); /* turn off frame recv */
- if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status)) {
+ if (!ath_hal_reset(ah, sc->sc_opmode, chan, AH_TRUE, &status)) {
if_printf(ifp, "%s: unable to reset "
- "channel %u (%u Mhz, flags 0x%x hal flags 0x%x), "
- "hal status %u\n", __func__,
- ieee80211_chan2ieee(ic, chan), chan->ic_freq,
- chan->ic_flags, hchan.channelFlags, status);
+ "channel %u (%u Mhz, flags 0x%x), hal status %u\n",
+ __func__, ieee80211_chan2ieee(ic, chan),
+ chan->ic_freq, chan->ic_flags, status);
return EIO;
}
- sc->sc_curchan = hchan;
sc->sc_diversity = ath_hal_getdiversity(ah);
/*
@@ -5532,9 +5719,12 @@ ath_calibrate(void *arg)
struct ath_softc *sc = arg;
struct ath_hal *ah = sc->sc_ah;
struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
HAL_BOOL longCal, isCalDone;
int nextcal;
+ if (ic->ic_flags & IEEE80211_F_SCAN) /* defer, off channel */
+ goto restart;
longCal = (ticks - sc->sc_lastlongcal >= ath_longcalinterval*hz);
if (longCal) {
sc->sc_stats.ast_per_cal++;
@@ -5553,12 +5743,12 @@ ath_calibrate(void *arg)
* reset the data collection state so we start fresh.
*/
if (sc->sc_resetcal) {
- (void) ath_hal_calreset(ah, &sc->sc_curchan);
+ (void) ath_hal_calreset(ah, sc->sc_curchan);
sc->sc_lastcalreset = ticks;
sc->sc_resetcal = 0;
}
}
- if (ath_hal_calibrateN(ah, &sc->sc_curchan, longCal, &isCalDone)) {
+ if (ath_hal_calibrateN(ah, sc->sc_curchan, longCal, &isCalDone)) {
if (longCal) {
/*
* Calibrate noise floor data again in case of change.
@@ -5568,10 +5758,11 @@ ath_calibrate(void *arg)
} else {
DPRINTF(sc, ATH_DEBUG_ANY,
"%s: calibration of channel %u failed\n",
- __func__, sc->sc_curchan.channel);
+ __func__, sc->sc_curchan->ic_freq);
sc->sc_stats.ast_per_calfail++;
}
if (!isCalDone) {
+restart:
/*
* Use a shorter interval to potentially collect multiple
* data samples required to complete calibration. Once
@@ -5760,6 +5951,12 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ni->ni_capinfo, ieee80211_chan2ieee(ic, ic->ic_curchan));
switch (vap->iv_opmode) {
+#ifdef ATH_SUPPORT_TDMA
+ case IEEE80211_M_AHDEMO:
+ if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
+ break;
+ /* fall thru... */
+#endif
case IEEE80211_M_HOSTAP:
case IEEE80211_M_IBSS:
/*
@@ -5788,7 +5985,12 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ni->ni_tstamp.tsf != 0) {
sc->sc_syncbeacon = 1;
} else if (!sc->sc_beacons) {
- ath_beacon_config(sc, vap);
+#ifdef ATH_SUPPORT_TDMA
+ if (vap->iv_caps & IEEE80211_C_TDMA)
+ ath_tdma_config(sc, vap);
+ else
+#endif
+ ath_beacon_config(sc, vap);
sc->sc_beacons = 1;
}
break;
@@ -5851,6 +6053,9 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
taskqueue_block(sc->sc_tq);
sc->sc_beacons = 0;
}
+#ifdef ATH_SUPPORT_TDMA
+ ath_hal_setcca(ah, AH_TRUE);
+#endif
}
bad:
return error;
@@ -5912,188 +6117,42 @@ ath_newassoc(struct ieee80211_node *ni, int isnew)
}
static int
-getchannels(struct ath_softc *sc, int *nchans, struct ieee80211_channel chans[],
- int cc, int ecm, int outdoor)
-{
- struct ath_hal *ah = sc->sc_ah;
- HAL_CHANNEL *halchans;
- int i, nhalchans, error;
-
- DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: cc %u outdoor %u ecm %u\n",
- __func__, cc, outdoor, ecm);
-
- halchans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
- M_TEMP, M_NOWAIT | M_ZERO);
- if (halchans == NULL) {
- device_printf(sc->sc_dev,
- "%s: unable to allocate channel table\n", __func__);
- return ENOMEM;
- }
- error = 0;
- if (!ath_hal_init_channels(ah, halchans, IEEE80211_CHAN_MAX, &nhalchans,
- NULL, 0, NULL, cc, HAL_MODE_ALL, outdoor, ecm)) {
- u_int32_t rd;
- (void) ath_hal_getregdomain(ah, &rd);
- device_printf(sc->sc_dev, "ath_hal_init_channels failed, "
- "rd %d cc %u outdoor %u ecm %u\n", rd, cc, outdoor, ecm);
- error = EINVAL;
- goto done;
- }
- if (nchans == NULL) /* no table requested */
- goto done;
-
- /*
- * Convert HAL channels to ieee80211 ones.
- */
- for (i = 0; i < nhalchans; i++) {
- HAL_CHANNEL *c = &halchans[i];
- struct ieee80211_channel *ichan = &chans[i];
-
- ichan->ic_ieee = ath_hal_mhz2ieee(ah, c->channel,
- c->channelFlags);
- if (bootverbose)
- device_printf(sc->sc_dev, "hal channel %u/%x -> %u "
- "maxpow %d minpow %d maxreg %d\n",
- c->channel, c->channelFlags, ichan->ic_ieee,
- c->maxTxPower, c->minTxPower, c->maxRegTxPower);
- ichan->ic_freq = c->channel;
-
- if ((c->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG) {
- /*
- * Except for AR5211, HAL's PUREG means mixed
- * DSSS and OFDM.
- */
- ichan->ic_flags = c->channelFlags &~ CHANNEL_PUREG;
- ichan->ic_flags |= IEEE80211_CHAN_G;
- } else {
- ichan->ic_flags = c->channelFlags;
- }
-
- if (ath_hal_isgsmsku(ah)) {
- /*
- * Remap to true frequencies: Ubiquiti XR9 cards use a
- * frequency mapping different from their SR9 cards.
- * We define special country codes to deal with this.
- */
- if (cc == CTRY_XR9)
- ichan->ic_freq = ichan->ic_freq - 1520;
- else if (cc == CTRY_GZ901)
- ichan->ic_freq = ichan->ic_freq - 1544;
- else
- ichan->ic_freq = 3344 - ichan->ic_freq;
- ichan->ic_flags |= IEEE80211_CHAN_GSM;
- ichan->ic_ieee = ieee80211_mhz2ieee(ichan->ic_freq,
- ichan->ic_flags);
- }
- ichan->ic_maxregpower = c->maxRegTxPower; /* dBm */
- /* XXX: old hal's don't provide maxTxPower for some parts */
- ichan->ic_maxpower = (c->maxTxPower != 0) ?
- c->maxTxPower : 2*c->maxRegTxPower; /* 1/2 dBm */
- ichan->ic_minpower = c->minTxPower; /* 1/2 dBm */
- }
- *nchans = nhalchans;
-done:
- free(halchans, M_TEMP);
- return error;
-}
-
-/* XXX hard to include ieee80211_regdomain.h right now */
-#define SKU_DEBUG 0x1ff
-
-static void
-ath_maprd(const struct ieee80211_regdomain *rd,
- u_int32_t *ath_rd, u_int32_t *ath_cc)
-{
- /* map SKU's to Atheros sku's */
- switch (rd->regdomain) {
- case SKU_DEBUG:
- if (rd->country == 0) {
- *ath_rd = 0;
- *ath_cc = CTRY_DEBUG;
- return;
- }
- break;
- }
- *ath_rd = rd->regdomain;
- *ath_cc = rd->country;
-}
-
-static int
-ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
+ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *reg,
int nchans, struct ieee80211_channel chans[])
{
struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
- u_int32_t ord, regdomain, cc;
- int error;
+ HAL_STATUS status;
- (void) ath_hal_getregdomain(ah, &ord);
- ath_maprd(rd, &regdomain, &cc);
DPRINTF(sc, ATH_DEBUG_REGDOMAIN,
- "%s: rd %u cc %u location %c ecm %u (mapped rd %u cc %u)\n",
- __func__, rd->regdomain, rd->country, rd->location, rd->ecm,
- regdomain, cc);
- ath_hal_setregdomain(ah, regdomain);
-
- error = getchannels(sc, &nchans, chans, cc,
- rd->ecm ? AH_TRUE : AH_FALSE,
- rd->location != 'I' ? AH_TRUE : AH_FALSE);
- if (error != 0) {
- /*
- * Restore previous state.
- */
- ath_hal_setregdomain(ah, ord);
- (void) getchannels(sc, NULL, NULL, ic->ic_regdomain.country,
- ic->ic_regdomain.ecm ? AH_TRUE : AH_FALSE,
- ic->ic_regdomain.location != 'I' ? AH_TRUE : AH_FALSE);
- return error;
+ "%s: rd %u cc %u location %c%s\n",
+ __func__, reg->regdomain, reg->country, reg->location,
+ reg->ecm ? " ecm" : "");
+
+ status = ath_hal_set_channels(ah, chans, nchans,
+ reg->country, reg->regdomain);
+ if (status != HAL_OK) {
+ DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: failed, status %u\n",
+ __func__, status);
+ return EINVAL; /* XXX */
}
return 0;
}
static void
ath_getradiocaps(struct ieee80211com *ic,
- int *nchans, struct ieee80211_channel chans[])
+ int maxchans, int *nchans, struct ieee80211_channel chans[])
{
struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
- u_int32_t ord;
- (void) ath_hal_getregdomain(ah, &ord);
+ DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: use rd %u cc %d\n",
+ __func__, SKU_DEBUG, CTRY_DEFAULT);
- DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: use rd %u cc %d, ord %u\n",
- __func__, 0, CTRY_DEBUG, ord);
+ /* XXX check return */
+ (void) ath_hal_getchannels(ah, chans, maxchans, nchans,
+ HAL_MODE_ALL, CTRY_DEFAULT, SKU_DEBUG, AH_TRUE);
- ath_hal_setregdomain(ah, 0);
- /* XXX not quite right but close enough for now */
- getchannels(sc, nchans, chans, CTRY_DEBUG, AH_TRUE, AH_FALSE);
-
- /* NB: restore previous state */
- ath_hal_setregdomain(ah, ord);
- (void) getchannels(sc, NULL, NULL, ic->ic_regdomain.country,
- ic->ic_regdomain.ecm ? AH_TRUE : AH_FALSE,
- ic->ic_regdomain.location != 'I' ? AH_TRUE : AH_FALSE);
-}
-
-static void
-ath_mapsku(u_int32_t ath_rd, u_int32_t ath_cc, struct ieee80211_regdomain *rd)
-{
- rd->isocc[0] = ' '; /* XXX don't know */
- rd->isocc[1] = ' ';
-
- /* map Atheros sku's to SKU's */
- switch (ath_rd) {
- case 0:
- if (ath_cc == CTRY_DEBUG) {
- rd->regdomain = SKU_DEBUG;
- rd->country = 0;
- return;
- }
- break;
- }
- /* XXX net80211 types too small */
- rd->regdomain = (uint16_t) ath_rd;
- rd->country = (uint16_t) ath_cc;
}
static int
@@ -6102,33 +6161,35 @@ ath_getchannels(struct ath_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ath_hal *ah = sc->sc_ah;
- int error;
+ HAL_STATUS status;
/*
- * Convert HAL channels to ieee80211 ones.
+ * Collect channel set based on EEPROM contents.
*/
- error = getchannels(sc, &ic->ic_nchans, ic->ic_channels,
- CTRY_DEFAULT, AH_TRUE, AH_FALSE);
- (void) ath_hal_getregdomain(ah, &sc->sc_eerd);
- ath_hal_getcountrycode(ah, &sc->sc_eecc); /* NB: cannot fail */
- if (error) {
+ status = ath_hal_init_channels(ah, ic->ic_channels, IEEE80211_CHAN_MAX,
+ &ic->ic_nchans, HAL_MODE_ALL, CTRY_DEFAULT, SKU_NONE, AH_TRUE);
+ if (status != HAL_OK) {
if_printf(ifp, "%s: unable to collect channel list from hal, "
- "error %d\n", __func__, error);
- if (error == EINVAL) {
- if_printf(ifp, "%s: regdomain likely %u country code %u\n",
- __func__, sc->sc_eerd, sc->sc_eecc);
- }
- return error;
+ "status %d\n", __func__, status);
+ return EINVAL;
}
+ (void) ath_hal_getregdomain(ah, &sc->sc_eerd);
+ ath_hal_getcountrycode(ah, &sc->sc_eecc); /* NB: cannot fail */
+ /* XXX map Atheros sku's to net80211 SKU's */
+ /* XXX net80211 types too small */
+ ic->ic_regdomain.regdomain = (uint16_t) sc->sc_eerd;
+ ic->ic_regdomain.country = (uint16_t) sc->sc_eecc;
+ ic->ic_regdomain.isocc[0] = ' '; /* XXX don't know */
+ ic->ic_regdomain.isocc[1] = ' ';
+
ic->ic_regdomain.ecm = 1;
ic->ic_regdomain.location = 'I';
- ath_mapsku(sc->sc_eerd, sc->sc_eecc, &ic->ic_regdomain);
DPRINTF(sc, ATH_DEBUG_REGDOMAIN,
- "%s: eeprom rd %u cc %u (mapped rd %u cc %u) location %c ecm %u\n",
+ "%s: eeprom rd %u cc %u (mapped rd %u cc %u) location %c%s\n",
__func__, sc->sc_eerd, sc->sc_eecc,
ic->ic_regdomain.regdomain, ic->ic_regdomain.country,
- ic->ic_regdomain.location, ic->ic_regdomain.ecm);
+ ic->ic_regdomain.location, ic->ic_regdomain.ecm ? " ecm" : "");
return 0;
}
@@ -6500,6 +6561,10 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sc->sc_stats.ast_rx_packets = ifp->if_ipackets;
sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi);
sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi);
+#ifdef ATH_SUPPORT_TDMA
+ sc->sc_stats.ast_tdma_tsfadjp = TDMA_AVG(sc->sc_avgtsfdeltap);
+ sc->sc_stats.ast_tdma_tsfadjm = TDMA_AVG(sc->sc_avgtsfdeltam);
+#endif
rt = sc->sc_currates;
/* XXX HT rates */
sc->sc_stats.ast_tx_rate =
@@ -6876,6 +6941,24 @@ ath_sysctlattach(struct ath_softc *sc)
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
"mask of error frames to pass when monitoring");
+#ifdef ATH_SUPPORT_TDMA
+ if (ath_hal_macversion(ah) > 0x78) {
+ sc->sc_tdmadbaprep = 2;
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
+ "TDMA DBA preparation time");
+ sc->sc_tdmaswbaprep = 10;
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
+ "TDMA SWBA preparation time");
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "guardtime", CTLFLAG_RW, &sc->sc_tdmaguard, 0,
+ "TDMA slot guard time");
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "superframe", CTLFLAG_RD, &sc->sc_tdmabintval, 0,
+ "TDMA calculated super frame");
+ }
+#endif
}
static void
@@ -7116,6 +7199,10 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
struct ath_buf *bf;
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
+ DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, %s", __func__,
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ?
+ "!running" : "invalid");
+ sc->sc_stats.ast_tx_raw_fail++;
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -7123,16 +7210,9 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
/*
* Grab a TX buffer and associated resources.
*/
- ATH_TXBUF_LOCK(sc);
- bf = STAILQ_FIRST(&sc->sc_txbuf);
- if (bf != NULL)
- STAILQ_REMOVE_HEAD(&sc->sc_txbuf, bf_list);
- ATH_TXBUF_UNLOCK(sc);
+ bf = ath_getbuf(sc);
if (bf == NULL) {
- DPRINTF(sc, ATH_DEBUG_XMIT, "%s: out of xmit buffers\n",
- __func__);
- sc->sc_stats.ast_tx_qstop++;
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ /* NB: ath_getbuf handles stat+msg */
ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
@@ -7162,7 +7242,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
bad:
ifp->if_oerrors++;
ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+ STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
ieee80211_free_node(ni);
return EIO; /* XXX */
@@ -7177,7 +7257,7 @@ ath_announce(struct ath_softc *sc)
#define HAL_MODE_DUALBAND (HAL_MODE_11A|HAL_MODE_11B)
struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
- u_int modes, cc;
+ u_int modes;
if_printf(ifp, "mac %d.%d phy %d.%d",
ah->ah_macVersion, ah->ah_macRev,
@@ -7187,8 +7267,7 @@ ath_announce(struct ath_softc *sc)
* to avoid falsely printing revs for inoperable parts.
* Dual-band radio revs are returned in the 5Ghz rev number.
*/
- ath_hal_getcountrycode(ah, &cc);
- modes = ath_hal_getwirelessmodes(ah, cc);
+ modes = ath_hal_getwirelessmodes(ah);
if ((modes & HAL_MODE_DUALBAND) == HAL_MODE_DUALBAND) {
if (ah->ah_analog5GhzRev && ah->ah_analog2GhzRev)
printf(" 5ghz radio %d.%d 2ghz radio %d.%d",
@@ -7220,3 +7299,364 @@ ath_announce(struct ath_softc *sc)
if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
#undef HAL_MODE_DUALBAND
}
+
+#ifdef ATH_SUPPORT_TDMA
+static __inline uint32_t
+ath_hal_getnexttbtt(struct ath_hal *ah)
+{
+#define AR_TIMER0 0x8028
+ return OS_REG_READ(ah, AR_TIMER0);
+}
+
+static __inline void
+ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta)
+{
+ /* XXX handle wrap/overflow */
+ OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta);
+}
+
+static void
+ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt, u_int32_t bintval)
+{
+ struct ath_hal *ah = sc->sc_ah;
+ HAL_BEACON_TIMERS bt;
+
+ bt.bt_intval = bintval | HAL_BEACON_ENA;
+ bt.bt_nexttbtt = nexttbtt;
+ bt.bt_nextdba = (nexttbtt<<3) - sc->sc_tdmadbaprep;
+ bt.bt_nextswba = (nexttbtt<<3) - sc->sc_tdmaswbaprep;
+ bt.bt_nextatim = nexttbtt+1;
+ ath_hal_beaconsettimers(ah, &bt);
+}
+
+/*
+ * Calculate the beacon interval. This is periodic in the
+ * superframe for the bss. We assume each station is configured
+ * identically wrt transmit rate so the guard time we calculate
+ * above will be the same on all stations. Note we need to
+ * factor in the xmit time because the hardware will schedule
+ * a frame for transmit if the start of the frame is within
+ * the burst time. When we get hardware that properly kills
+ * frames in the PCU we can reduce/eliminate the guard time.
+ *
+ * Roundup to 1024 is so we have 1 TU buffer in the guard time
+ * to deal with the granularity of the nexttbtt timer. 11n MAC's
+ * with 1us timer granularity should allow us to reduce/eliminate
+ * this.
+ */
+static void
+ath_tdma_bintvalsetup(struct ath_softc *sc,
+ const struct ieee80211_tdma_state *tdma)
+{
+ /* copy from vap state (XXX check all vaps have same value?) */
+ sc->sc_tdmaslotlen = tdma->tdma_slotlen;
+ sc->sc_tdmabintcnt = tdma->tdma_bintval;
+
+ sc->sc_tdmabintval = roundup((sc->sc_tdmaslotlen+sc->sc_tdmaguard) *
+ tdma->tdma_slotcnt, 1024);
+ sc->sc_tdmabintval >>= 10; /* TSF -> TU */
+ if (sc->sc_tdmabintval & 1)
+ sc->sc_tdmabintval++;
+
+ if (tdma->tdma_slot == 0) {
+ /*
+ * Only slot 0 beacons; other slots respond.
+ */
+ sc->sc_imask |= HAL_INT_SWBA;
+ sc->sc_tdmaswba = 0; /* beacon immediately */
+ } else {
+ /* XXX all vaps must be slot 0 or slot !0 */
+ sc->sc_imask &= ~HAL_INT_SWBA;
+ }
+}
+
+/*
+ * Max 802.11 overhead. This assumes no 4-address frames and
+ * the encapsulation done by ieee80211_encap (llc). We also
+ * include potential crypto overhead.
+ */
+#define IEEE80211_MAXOVERHEAD \
+ (sizeof(struct ieee80211_qosframe) \
+ + sizeof(struct llc) \
+ + IEEE80211_ADDR_LEN \
+ + IEEE80211_WEP_IVLEN \
+ + IEEE80211_WEP_KIDLEN \
+ + IEEE80211_WEP_CRCLEN \
+ + IEEE80211_WEP_MICLEN \
+ + IEEE80211_CRC_LEN)
+
+/*
+ * Setup initially for tdma operation. Start the beacon
+ * timers and enable SWBA if we are slot 0. Otherwise
+ * we wait for slot 0 to arrive so we can sync up before
+ * starting to transmit.
+ */
+static void
+ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
+{
+ struct ath_hal *ah = sc->sc_ah;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ const struct ieee80211_txparam *tp;
+ const struct ieee80211_tdma_state *tdma = NULL;
+ int rix;
+
+ if (vap == NULL) {
+ vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
+ if (vap == NULL) {
+ if_printf(ifp, "%s: no vaps?\n", __func__);
+ return;
+ }
+ }
+ tp = vap->iv_bss->ni_txparms;
+ /*
+ * Calculate the guard time for each slot. This is the
+ * time to send a maximal-size frame according to the
+ * fixed/lowest transmit rate. Note that the interface
+ * mtu does not include the 802.11 overhead so we must
+ * tack that on (ath_hal_computetxtime includes the
+ * preamble and plcp in it's calculation).
+ */
+ tdma = vap->iv_tdma;
+ if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
+ rix = ath_tx_findrix(sc->sc_currates, tp->ucastrate);
+ else
+ rix = ath_tx_findrix(sc->sc_currates, tp->mcastrate);
+ /* XXX short preamble assumed */
+ sc->sc_tdmaguard = ath_hal_computetxtime(ah, sc->sc_currates,
+ ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE);
+
+ ath_hal_intrset(ah, 0);
+
+ ath_beaconq_config(sc); /* setup h/w beacon q */
+ ath_hal_setcca(ah, AH_FALSE); /* disable CCA */
+ ath_tdma_bintvalsetup(sc, tdma); /* calculate beacon interval */
+ ath_tdma_settimers(sc, sc->sc_tdmabintval,
+ sc->sc_tdmabintval | HAL_BEACON_RESET_TSF);
+ sc->sc_syncbeacon = 0;
+
+ sc->sc_avgtsfdeltap = TDMA_DUMMY_MARKER;
+ sc->sc_avgtsfdeltam = TDMA_DUMMY_MARKER;
+
+ ath_hal_intrset(ah, sc->sc_imask);
+
+ DPRINTF(sc, ATH_DEBUG_TDMA, "%s: slot %u len %uus cnt %u "
+ "bsched %u guard %uus bintval %u TU dba prep %u\n", __func__,
+ tdma->tdma_slot, tdma->tdma_slotlen, tdma->tdma_slotcnt,
+ tdma->tdma_bintval, sc->sc_tdmaguard, sc->sc_tdmabintval,
+ sc->sc_tdmadbaprep);
+}
+
+/*
+ * Update tdma operation. Called from the 802.11 layer
+ * when a beacon is received from the TDMA station operating
+ * in the slot immediately preceding us in the bss. Use
+ * the rx timestamp for the beacon frame to update our
+ * beacon timers so we follow their schedule. Note that
+ * by using the rx timestamp we implicitly include the
+ * propagation delay in our schedule.
+ */
+static void
+ath_tdma_update(struct ieee80211_node *ni,
+ const struct ieee80211_tdma_param *tdma)
+{
+#define TSF_TO_TU(_h,_l) \
+ ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
+#define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10)
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_hal *ah = sc->sc_ah;
+ const HAL_RATE_TABLE *rt = sc->sc_currates;
+ u_int64_t tsf, rstamp, nextslot;
+ u_int32_t txtime, nextslottu, timer0;
+ int32_t tudelta, tsfdelta;
+ const struct ath_rx_status *rs;
+ int rix;
+
+ sc->sc_stats.ast_tdma_update++;
+
+ /*
+ * Check for and adopt configuration changes.
+ */
+ if (isset(ATH_VAP(vap)->av_boff.bo_flags, IEEE80211_BEACON_TDMA)) {
+ const struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ ath_tdma_bintvalsetup(sc, ts);
+
+ DPRINTF(sc, ATH_DEBUG_TDMA,
+ "%s: adopt slot %u slotcnt %u slotlen %u us "
+ "bintval %u TU\n", __func__,
+ ts->tdma_slot, ts->tdma_slotcnt, ts->tdma_slotlen,
+ sc->sc_tdmabintval);
+
+ ath_beaconq_config(sc);
+ /* XXX right? */
+ ath_hal_intrset(ah, sc->sc_imask);
+ /* NB: beacon timers programmed below */
+ }
+
+ /* extend rx timestamp to 64 bits */
+ tsf = ath_hal_gettsf64(ah);
+ rstamp = ath_extend_tsf(ni->ni_rstamp, tsf);
+ /*
+ * The rx timestamp is set by the hardware on completing
+ * reception (at the point where the rx descriptor is DMA'd
+ * to the host). To find the start of our next slot we
+ * must adjust this time by the time required to send
+ * the packet just received.
+ */
+ rs = sc->sc_tdmars;
+ rix = rt->rateCodeToIndex[rs->rs_rate];
+ txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix,
+ rt->info[rix].shortPreamble);
+ /* NB: << 9 is to cvt to TU and /2 */
+ nextslot = (rstamp - txtime) + (sc->sc_tdmabintval << 9);
+ nextslottu = TSF_TO_TU(nextslot>>32, nextslot) & HAL_BEACON_PERIOD;
+
+ /*
+ * TIMER0 is the h/w's idea of NextTBTT (in TU's). Convert
+ * to usecs and calculate the difference between what the
+ * other station thinks and what we have programmed. This
+ * lets us figure how to adjust our timers to match. The
+ * adjustments are done by pulling the TSF forward and possibly
+ * rewriting the beacon timers.
+ */
+ timer0 = ath_hal_getnexttbtt(ah);
+ tsfdelta = (int32_t)((nextslot % TU_TO_TSF(HAL_BEACON_PERIOD+1)) - TU_TO_TSF(timer0));
+
+ DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
+ "tsfdelta %d avg +%d/-%d\n", tsfdelta,
+ TDMA_AVG(sc->sc_avgtsfdeltap), TDMA_AVG(sc->sc_avgtsfdeltam));
+
+ if (tsfdelta < 0) {
+ TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
+ TDMA_SAMPLE(sc->sc_avgtsfdeltam, -tsfdelta);
+ tsfdelta = -tsfdelta % 1024;
+ nextslottu++;
+ } else if (tsfdelta > 0) {
+ TDMA_SAMPLE(sc->sc_avgtsfdeltap, tsfdelta);
+ TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
+ tsfdelta = 1024 - (tsfdelta % 1024);
+ nextslottu++;
+ } else {
+ TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
+ TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
+ }
+ tudelta = nextslottu - timer0;
+
+ /*
+ * Copy sender's timetstamp into tdma ie so they can
+ * calculate roundtrip time. We submit a beacon frame
+ * below after any timer adjustment. The frame goes out
+ * at the next TBTT so the sender can calculate the
+ * roundtrip by inspecting the tdma ie in our beacon frame.
+ *
+ * NB: This tstamp is subtlely preserved when
+ * IEEE80211_BEACON_TDMA is marked (e.g. when the
+ * slot position changes) because ieee80211_add_tdma
+ * skips over the data.
+ */
+ memcpy(ATH_VAP(vap)->av_boff.bo_tdma +
+ __offsetof(struct ieee80211_tdma_param, tdma_tstamp),
+ &ni->ni_tstamp.data, 8);
+#if 0
+ DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
+ "tsf %llu nextslot %llu (%d, %d) nextslottu %u timer0 %u (%d)\n",
+ (unsigned long long) tsf, (unsigned long long) nextslot,
+ (int)(nextslot - tsf), tsfdelta,
+ nextslottu, timer0, tudelta);
+#endif
+ /*
+ * Adjust the beacon timers only when pulling them forward
+ * or when going back by less than the beacon interval.
+ * Negative jumps larger than the beacon interval seem to
+ * cause the timers to stop and generally cause instability.
+ * This basically filters out jumps due to missed beacons.
+ */
+ if (tudelta != 0 && (tudelta > 0 || -tudelta < sc->sc_tdmabintval)) {
+ ath_tdma_settimers(sc, nextslottu, sc->sc_tdmabintval);
+ sc->sc_stats.ast_tdma_timers++;
+ }
+ if (tsfdelta > 0) {
+ ath_hal_adjusttsf(ah, tsfdelta);
+ sc->sc_stats.ast_tdma_tsf++;
+ }
+ ath_tdma_beacon_send(sc, vap); /* prepare response */
+#undef TU_TO_TSF
+#undef TSF_TO_TU
+}
+
+/*
+ * Transmit a beacon frame at SWBA. Dynamic updates
+ * to the frame contents are done as needed.
+ */
+static void
+ath_tdma_beacon_send(struct ath_softc *sc, struct ieee80211vap *vap)
+{
+ struct ath_hal *ah = sc->sc_ah;
+ struct ath_buf *bf;
+ int otherant;
+
+ /*
+ * Check if the previous beacon has gone out. If
+ * not don't try to post another, skip this period
+ * and wait for the next. Missed beacons indicate
+ * a problem and should not occur. If we miss too
+ * many consecutive beacons reset the device.
+ */
+ if (ath_hal_numtxpending(ah, sc->sc_bhalq) != 0) {
+ sc->sc_bmisscount++;
+ DPRINTF(sc, ATH_DEBUG_BEACON,
+ "%s: missed %u consecutive beacons\n",
+ __func__, sc->sc_bmisscount);
+ if (sc->sc_bmisscount > 3) /* NB: 3 is a guess */
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_bstucktask);
+ return;
+ }
+ if (sc->sc_bmisscount != 0) {
+ DPRINTF(sc, ATH_DEBUG_BEACON,
+ "%s: resume beacon xmit after %u misses\n",
+ __func__, sc->sc_bmisscount);
+ sc->sc_bmisscount = 0;
+ }
+
+ /*
+ * Check recent per-antenna transmit statistics and flip
+ * the default antenna if noticeably more frames went out
+ * on the non-default antenna.
+ * XXX assumes 2 anntenae
+ */
+ if (!sc->sc_diversity) {
+ otherant = sc->sc_defant & 1 ? 2 : 1;
+ if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 2)
+ ath_setdefantenna(sc, otherant);
+ sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0;
+ }
+
+ bf = ath_beacon_generate(sc, vap);
+ if (bf != NULL) {
+ /*
+ * Stop any current dma and put the new frame on the queue.
+ * This should never fail since we check above that no frames
+ * are still pending on the queue.
+ */
+ if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) {
+ DPRINTF(sc, ATH_DEBUG_ANY,
+ "%s: beacon queue %u did not stop?\n",
+ __func__, sc->sc_bhalq);
+ /* NB: the HAL still stops DMA, so proceed */
+ }
+ ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
+ ath_hal_txstart(ah, sc->sc_bhalq);
+
+ sc->sc_stats.ast_be_xmit++; /* XXX per-vap? */
+
+ /*
+ * Record local TSF for our last send for use
+ * in arbitrating slot collisions.
+ */
+ vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
+ }
+}
+#endif /* ATH_SUPPORT_TDMA */
diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c
index 34808a1..4a66da7 100644
--- a/sys/dev/ath/if_ath_pci.c
+++ b/sys/dev/ath/if_ath_pci.c
@@ -254,4 +254,3 @@ DRIVER_MODULE(if_ath, pci, ath_pci_driver, ath_devclass, 0, 0);
DRIVER_MODULE(if_ath, cardbus, ath_pci_driver, ath_devclass, 0, 0);
MODULE_VERSION(if_ath, 1);
MODULE_DEPEND(if_ath, wlan, 1, 1, 1); /* 802.11 media layer */
-MODULE_DEPEND(if_ath, ath_rate, 1, 1, 1); /* rate control algorithm */
diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h
index 1c737a4..538c1a2 100644
--- a/sys/dev/ath/if_athioctl.h
+++ b/sys/dev/ath/if_athioctl.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -109,7 +109,15 @@ struct ath_stats {
u_int32_t ast_ff_flush; /* fast frames flushed from staging q */
u_int32_t ast_tx_qfull; /* tx dropped 'cuz of queue limit */
int8_t ast_rx_noise; /* rx noise floor */
- u_int32_t ast_pad[22];
+ u_int32_t ast_tx_nobuf; /* tx dropped 'cuz no ath buffer */
+ u_int32_t ast_tdma_update;/* TDMA slot timing updates */
+ u_int32_t ast_tdma_timers;/* TDMA slot update set beacon timers */
+ u_int32_t ast_tdma_tsf; /* TDMA slot update set TSF */
+ u_int16_t ast_tdma_tsfadjp;/* TDMA slot adjust+ (usec, smoothed)*/
+ u_int16_t ast_tdma_tsfadjm;/* TDMA slot adjust- (usec, smoothed)*/
+ u_int32_t ast_tdma_ack; /* TDMA tx failed 'cuz ACK required */
+ u_int32_t ast_tx_raw_fail;/* raw tx failed 'cuz h/w down */
+ u_int32_t ast_pad[15];
};
#define SIOCGATHSTATS _IOWR('i', 137, struct ifreq)
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 0f08eec..4b3325c 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -109,7 +109,8 @@ struct ath_buf {
TAILQ_ENTRY(ath_buf) bf_stagelist; /* stage queue list */
u_int32_t bf_age; /* age when placed on stageq */
int bf_nseg;
- int bf_txflags; /* tx descriptor flags */
+ uint16_t bf_txflags; /* tx descriptor flags */
+ uint16_t bf_flags; /* status flags (below) */
struct ath_desc *bf_desc; /* virtual addr of desc */
struct ath_desc_status bf_status; /* tx/rx status */
bus_addr_t bf_daddr; /* physical addr of desc */
@@ -122,6 +123,8 @@ struct ath_buf {
};
typedef STAILQ_HEAD(, ath_buf) ath_bufhead;
+#define ATH_BUF_BUSY 0x00000002 /* (tx) desc owned by h/w */
+
/*
* DMA state for tx/rx descriptors.
*/
@@ -148,6 +151,8 @@ struct ath_descdma {
struct ath_txq {
u_int axq_qnum; /* hardware q number */
#define ATH_TXQ_SWQ (HAL_NUM_TX_QUEUES+1) /* qnum for s/w only queue */
+ u_int axq_flags;
+#define ATH_TXQ_PUTPENDING 0x0001 /* ath_hal_puttxbuf pending */
u_int axq_depth; /* queue depth (stat only) */
u_int axq_intrcnt; /* interrupt count */
u_int32_t *axq_link; /* link ptr in last TX desc */
@@ -249,6 +254,7 @@ struct ath_softc {
sc_stagbeacons:1,/* use staggered beacons */
sc_wmetkipmic:1,/* can do WME+TKIP MIC */
sc_resume_up: 1,/* on resume, start all vaps */
+ sc_tdma : 1,/* TDMA in use */
sc_resetcal : 1;/* reset cal state next trip */
uint32_t sc_eerd; /* regdomain from EEPROM */
uint32_t sc_eecc; /* country code from EEPROM */
@@ -261,7 +267,7 @@ struct ath_softc {
HAL_OPMODE sc_opmode; /* current operating mode */
u_int16_t sc_curtxpow; /* current tx power limit */
u_int16_t sc_curaid; /* current association id */
- HAL_CHANNEL sc_curchan; /* current h/w channel */
+ struct ieee80211_channel *sc_curchan; /* current installed channel */
u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */
struct {
@@ -338,6 +344,18 @@ struct ath_softc {
int sc_lastlongcal; /* last long cal completed */
int sc_lastcalreset;/* last cal reset done */
HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */
+#ifdef ATH_SUPPORT_TDMA
+ u_int sc_tdmadbaprep; /* TDMA DBA prep time */
+ u_int sc_tdmaswbaprep;/* TDMA SWBA prep time */
+ u_int sc_tdmaswba; /* TDMA SWBA counter */
+ u_int32_t sc_tdmabintval; /* TDMA beacon interval (TU) */
+ u_int32_t sc_tdmaguard; /* TDMA guard time (usec) */
+ u_int sc_tdmaslotlen; /* TDMA slot length (usec) */
+ u_int sc_tdmabintcnt; /* TDMA beacon intvl (slots) */
+ struct ath_rx_status *sc_tdmars; /* TDMA status of last rx */
+ u_int32_t sc_avgtsfdeltap;/* TDMA slot adjust (+) */
+ u_int32_t sc_avgtsfdeltam;/* TDMA slot adjust (-) */
+#endif
};
#define ATH_LOCK_INIT(_sc) \
@@ -375,6 +393,8 @@ void ath_intr(void *);
((*(_ah)->ah_detach)((_ah)))
#define ath_hal_reset(_ah, _opmode, _chan, _outdoor, _pstatus) \
((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_outdoor), (_pstatus)))
+#define ath_hal_macversion(_ah) \
+ (((_ah)->ah_macVersion << 4) | ((_ah)->ah_macRev))
#define ath_hal_getratetable(_ah, _mode) \
((*(_ah)->ah_getRateTable)((_ah), (_mode)))
#define ath_hal_getmac(_ah, _mac) \
@@ -417,8 +437,10 @@ void ath_intr(void *);
((*(_ah)->ah_waitForBeaconDone)((_ah), (_bf)->bf_daddr))
#define ath_hal_putrxbuf(_ah, _bufaddr) \
((*(_ah)->ah_setRxDP)((_ah), (_bufaddr)))
+/* NB: common across all chips */
+#define AR_TSF_L32 0x804c /* MAC local clock lower 32 bits */
#define ath_hal_gettsf32(_ah) \
- ((*(_ah)->ah_getTsf32)((_ah)))
+ OS_REG_READ(_ah, AR_TSF_L32)
#define ath_hal_gettsf64(_ah) \
((*(_ah)->ah_getTsf64)((_ah)))
#define ath_hal_resettsf(_ah) \
@@ -455,6 +477,8 @@ void ath_intr(void *);
((*(_ah)->ah_beaconInit)((_ah), (_nextb), (_bperiod)))
#define ath_hal_beaconreset(_ah) \
((*(_ah)->ah_resetStationBeaconTimers)((_ah)))
+#define ath_hal_beaconsettimers(_ah, _bt) \
+ ((*(_ah)->ah_setBeaconTimers)((_ah), (_bt)))
#define ath_hal_beacontimers(_ah, _bs) \
((*(_ah)->ah_setStationBeaconTimers)((_ah), (_bs)))
#define ath_hal_setassocid(_ah, _bss, _associd) \
@@ -486,6 +510,10 @@ void ath_intr(void *);
((*(_ah)->ah_getTxQueueProps)((_ah), (_q), (_qi)))
#define ath_hal_settxqueueprops(_ah, _q, _qi) \
((*(_ah)->ah_setTxQueueProps)((_ah), (_q), (_qi)))
+/* NB: common across all chips */
+#define AR_Q_TXE 0x0840 /* MAC Transmit Queue enable */
+#define ath_hal_txqenabled(_ah, _qnum) \
+ (OS_REG_READ(_ah, AR_Q_TXE) & (1<<(_qnum)))
#define ath_hal_getrfgain(_ah) \
((*(_ah)->ah_getRfGain)((_ah)))
#define ath_hal_getdefantenna(_ah) \
diff --git a/sys/dev/atkbdc/atkbdc_isa.c b/sys/dev/atkbdc/atkbdc_isa.c
index 4f535db..975d299 100644
--- a/sys/dev/atkbdc/atkbdc_isa.c
+++ b/sys/dev/atkbdc/atkbdc_isa.c
@@ -47,8 +47,8 @@ __FBSDID("$FreeBSD$");
static int atkbdc_isa_probe(device_t dev);
static int atkbdc_isa_attach(device_t dev);
-static device_t atkbdc_isa_add_child(device_t bus, int order, char *name,
- int unit);
+static device_t atkbdc_isa_add_child(device_t bus, int order, const char *name,
+ int unit);
static device_method_t atkbdc_isa_methods[] = {
DEVMETHOD(device_probe, atkbdc_isa_probe),
@@ -227,7 +227,7 @@ atkbdc_isa_attach(device_t dev)
}
static device_t
-atkbdc_isa_add_child(device_t bus, int order, char *name, int unit)
+atkbdc_isa_add_child(device_t bus, int order, const char *name, int unit)
{
atkbdc_device_t *ivar;
device_t child;
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index ff78453..8385b6e 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -106,6 +106,10 @@ static struct bce_type bce_devs[] = {
"HP NC370T Multifunction Gigabit Server Adapter" },
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3106,
"HP NC370i Multifunction Gigabit Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3070,
+ "HP NC380T PCIe DP Multifunc Gig Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x1709,
+ "HP NC371i Multifunction Gigabit Server Adapter" },
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, PCI_ANY_ID, PCI_ANY_ID,
"Broadcom NetXtreme II BCM5706 1000Base-T" },
@@ -116,18 +120,38 @@ static struct bce_type bce_devs[] = {
"Broadcom NetXtreme II BCM5706 1000Base-SX" },
/* BCM5708C controllers and OEM boards. */
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7037,
+ "HP NC373T PCIe Multifunction Gig Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7038,
+ "HP NC373i Multifunction Gigabit Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7045,
+ "HP NC374m PCIe Multifunction Adapter" },
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708, PCI_ANY_ID, PCI_ANY_ID,
"Broadcom NetXtreme II BCM5708 1000Base-T" },
/* BCM5708S controllers and OEM boards. */
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x1706,
+ "HP NC373m Multifunction Gigabit Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703b,
+ "HP NC373i Multifunction Gigabit Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703d,
+ "HP NC373F PCIe Multifunc Giga Server Adapter" },
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, PCI_ANY_ID, PCI_ANY_ID,
"Broadcom NetXtreme II BCM5708 1000Base-SX" },
/* BCM5709C controllers and OEM boards. */
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7055,
+ "HP NC382i DP Multifunction Gigabit Server Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7059,
+ "HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709, PCI_ANY_ID, PCI_ANY_ID,
"Broadcom NetXtreme II BCM5709 1000Base-T" },
/* BCM5709S controllers and OEM boards. */
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x171d,
+ "HP NC382m DP 1GbE Multifunction BL-c Adapter" },
+ { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x7056,
+ "HP NC382i DP Multifunction Gigabit Server Adapter" },
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, PCI_ANY_ID, PCI_ANY_ID,
"Broadcom NetXtreme II BCM5709 1000Base-SX" },
@@ -2886,7 +2910,6 @@ bce_dma_alloc(device_t dev)
{
struct bce_softc *sc;
int i, error, rc = 0;
- bus_addr_t busaddr;
bus_size_t max_size, max_seg_size;
int max_segments;
@@ -2955,7 +2978,7 @@ bce_dma_alloc(device_t dev)
sc->status_block,
BCE_STATUS_BLK_SZ,
bce_dma_map_addr,
- &busaddr,
+ &sc->status_block_paddr,
BUS_DMA_NOWAIT);
if (error) {
@@ -2965,7 +2988,6 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- sc->status_block_paddr = busaddr;
DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
__FUNCTION__, (uintmax_t) sc->status_block_paddr);
@@ -3009,7 +3031,7 @@ bce_dma_alloc(device_t dev)
sc->stats_block,
BCE_STATS_BLK_SZ,
bce_dma_map_addr,
- &busaddr,
+ &sc->stats_block_paddr,
BUS_DMA_NOWAIT);
if(error) {
@@ -3019,7 +3041,6 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- sc->stats_block_paddr = busaddr;
DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
__FUNCTION__, (uintmax_t) sc->stats_block_paddr);
@@ -3077,7 +3098,7 @@ bce_dma_alloc(device_t dev)
sc->ctx_block[i],
BCM_PAGE_SIZE,
bce_dma_map_addr,
- &busaddr,
+ &sc->ctx_paddr[i],
BUS_DMA_NOWAIT);
if (error) {
@@ -3087,7 +3108,6 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- sc->ctx_paddr[i] = busaddr;
DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
__FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
}
@@ -3133,7 +3153,7 @@ bce_dma_alloc(device_t dev)
sc->tx_bd_chain[i],
BCE_TX_CHAIN_PAGE_SZ,
bce_dma_map_addr,
- &busaddr,
+ &sc->tx_bd_chain_paddr[i],
BUS_DMA_NOWAIT);
if (error) {
@@ -3143,7 +3163,6 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- sc->tx_bd_chain_paddr[i] = busaddr;
DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
__FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
}
@@ -3231,7 +3250,7 @@ bce_dma_alloc(device_t dev)
sc->rx_bd_chain[i],
BCE_RX_CHAIN_PAGE_SZ,
bce_dma_map_addr,
- &busaddr,
+ &sc->rx_bd_chain_paddr[i],
BUS_DMA_NOWAIT);
if (error) {
@@ -3241,7 +3260,6 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- sc->rx_bd_chain_paddr[i] = busaddr;
DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
__FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
}
@@ -3328,7 +3346,7 @@ bce_dma_alloc(device_t dev)
sc->pg_bd_chain[i],
BCE_PG_CHAIN_PAGE_SZ,
bce_dma_map_addr,
- &busaddr,
+ &sc->pg_bd_chain_paddr[i],
BUS_DMA_NOWAIT);
if (error) {
@@ -3338,7 +3356,6 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- sc->pg_bd_chain_paddr[i] = busaddr;
DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
__FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
}
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 557e735..335200b 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -348,7 +348,7 @@ static void bge_init_locked(struct bge_softc *);
static void bge_init(void *);
static void bge_stop(struct bge_softc *);
static void bge_watchdog(struct bge_softc *);
-static void bge_shutdown(device_t);
+static int bge_shutdown(device_t);
static int bge_ifmedia_upd_locked(struct ifnet *);
static int bge_ifmedia_upd(struct ifnet *);
static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -4280,17 +4280,18 @@ bge_stop(struct bge_softc *sc)
* Stop all chip I/O so that the kernel's probe routines don't
* get confused by errant DMAs when rebooting.
*/
-static void
+static int
bge_shutdown(device_t dev)
{
struct bge_softc *sc;
sc = device_get_softc(dev);
-
BGE_LOCK(sc);
bge_stop(sc);
bge_reset(sc);
BGE_UNLOCK(sc);
+
+ return (0);
}
static int
diff --git a/sys/dev/bm/if_bm.c b/sys/dev/bm/if_bm.c
index b9bddb5..1bb07b2 100644
--- a/sys/dev/bm/if_bm.c
+++ b/sys/dev/bm/if_bm.c
@@ -81,7 +81,7 @@ MODULE_DEPEND(bm, miibus, 1, 1, 1);
static int bm_probe (device_t);
static int bm_attach (device_t);
static int bm_detach (device_t);
-static void bm_shutdown (device_t);
+static int bm_shutdown (device_t);
static void bm_start (struct ifnet *);
static void bm_start_locked (struct ifnet *);
@@ -654,7 +654,7 @@ bm_detach(device_t dev)
return (0);
}
-static void
+static int
bm_shutdown(device_t dev)
{
struct bm_softc *sc;
@@ -664,6 +664,8 @@ bm_shutdown(device_t dev)
BM_LOCK(sc);
bm_stop(sc);
BM_UNLOCK(sc);
+
+ return (0);
}
static void
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c
index 8d9a72f..6a0e1a9 100644
--- a/sys/dev/cardbus/cardbus.c
+++ b/sys/dev/cardbus/cardbus.c
@@ -143,7 +143,7 @@ cardbus_device_setup_regs(pcicfgregs *cfg)
* Some cards power up with garbage in their BARs. This
* code clears all that junk out.
*/
- for (i = 0; i < PCI_MAX_BAR_0; i++)
+ for (i = 0; i < PCIR_MAX_BAR_0; i++)
pci_write_config(dev, PCIR_BAR(i), 0, 4);
cfg->intline =
@@ -207,7 +207,7 @@ cardbus_attach_card(device_t cbdev)
}
if (cardattached > 0)
return (0);
- POWER_DISABLE_SOCKET(brdev, cbdev);
+/* POWER_DISABLE_SOCKET(brdev, cbdev); */
return (ENOENT);
}
@@ -269,6 +269,7 @@ cardbus_driver_added(device_t cbdev, driver_t *driver)
}
if (i > 0 && i == numdevs)
POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev);
+ /* XXX Should I wait for power to become good? */
for (i = 0; i < numdevs; i++) {
dev = devlist[i];
if (device_get_state(dev) != DS_NOTPRESENT)
diff --git a/sys/dev/cardbus/cardbus_device.c b/sys/dev/cardbus/cardbus_device.c
index 50e2e98..f39ffb0 100644
--- a/sys/dev/cardbus/cardbus_device.c
+++ b/sys/dev/cardbus/cardbus_device.c
@@ -98,12 +98,10 @@ static int
cardbus_device_buffer_cis(device_t parent, device_t child,
struct cis_buffer *cbp)
{
- struct cardbus_softc *sc;
struct tuple_callbacks cb[] = {
{CISTPL_GENERIC, "GENERIC", cardbus_build_cis}
};
- sc = device_get_softc(parent);
return (cardbus_parse_cis(parent, child, cb, cbp));
}
diff --git a/sys/dev/cfi/cfi_bus_ixp4xx.c b/sys/dev/cfi/cfi_bus_ixp4xx.c
new file mode 100644
index 0000000..8db431b
--- /dev/null
+++ b/sys/dev/cfi/cfi_bus_ixp4xx.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2009 Roelof Jonkman, Carlson Wireless Inc.
+ * Copyright (c) 2009 Sam Leffler, Errno Consulting
+ * 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/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/cfi/cfi_var.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+static int
+cfi_ixp4xx_probe(device_t dev)
+{
+ struct cfi_softc *sc = device_get_softc(dev);
+ /*
+ * NB: we assume the boot loader sets up EXP_TIMING_CS0_OFFSET
+ * according to the flash on the board. If it does not then it
+ * can be done here.
+ */
+ if (bootverbose) {
+ struct ixp425_softc *sa =
+ device_get_softc(device_get_parent(dev));
+ device_printf(dev, "EXP_TIMING_CS0_OFFSET 0x%x\n",
+ EXP_BUS_READ_4(sa, EXP_TIMING_CS0_OFFSET));
+ }
+ sc->sc_width = 2; /* NB: don't probe interface width */
+ return cfi_probe(dev);
+}
+
+static device_method_t cfi_ixp4xx_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, cfi_ixp4xx_probe),
+ DEVMETHOD(device_attach, cfi_attach),
+ DEVMETHOD(device_detach, cfi_detach),
+
+ {0, 0}
+};
+
+static driver_t cfi_ixp4xx_driver = {
+ cfi_driver_name,
+ cfi_ixp4xx_methods,
+ sizeof(struct cfi_softc),
+};
+DRIVER_MODULE (cfi, ixp, cfi_ixp4xx_driver, cfi_devclass, 0, 0);
diff --git a/sys/dev/cfi/cfi_core.c b/sys/dev/cfi/cfi_core.c
index 4df3190..a31db5c 100644
--- a/sys/dev/cfi/cfi_core.c
+++ b/sys/dev/cfi/cfi_core.c
@@ -30,6 +30,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_cfi.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -70,7 +72,6 @@ cfi_read(struct cfi_softc *sc, u_int ofs)
val = ~0;
break;
}
-
return (val);
}
@@ -150,11 +151,16 @@ cfi_probe(device_t dev)
sc->sc_tag = rman_get_bustag(sc->sc_res);
sc->sc_handle = rman_get_bushandle(sc->sc_res);
- sc->sc_width = 1;
- while (sc->sc_width <= 4) {
- if (cfi_read_qry(sc, CFI_QRY_IDENT) == 'Q')
- break;
- sc->sc_width <<= 1;
+ if (sc->sc_width == 0) {
+ sc->sc_width = 1;
+ while (sc->sc_width <= 4) {
+ if (cfi_read_qry(sc, CFI_QRY_IDENT) == 'Q')
+ break;
+ sc->sc_width <<= 1;
+ }
+ } else if (cfi_read_qry(sc, CFI_QRY_IDENT) != 'Q') {
+ error = ENXIO;
+ goto out;
}
if (sc->sc_width > 4) {
error = ENXIO;
@@ -295,10 +301,10 @@ cfi_detach(device_t dev)
}
static int
-cfi_wait_ready(struct cfi_softc *sc, u_int timeout)
+cfi_wait_ready(struct cfi_softc *sc, u_int ofs, u_int timeout)
{
int done, error;
- uint32_t st0, st;
+ uint32_t st0 = 0, st = 0;
done = 0;
error = 0;
@@ -310,21 +316,27 @@ cfi_wait_ready(struct cfi_softc *sc, u_int timeout)
switch (sc->sc_cmdset) {
case CFI_VEND_INTEL_ECS:
case CFI_VEND_INTEL_SCS:
- st = cfi_read(sc, sc->sc_wrofs);
- done = (st & 0x80);
+ st = cfi_read(sc, ofs);
+ done = (st & CFI_INTEL_STATUS_WSMS);
if (done) {
- if (st & 0x02)
+ /* NB: bit 0 is reserved */
+ st &= ~(CFI_INTEL_XSTATUS_RSVD |
+ CFI_INTEL_STATUS_WSMS |
+ CFI_INTEL_STATUS_RSVD);
+ if (st & CFI_INTEL_STATUS_DPS)
error = EPERM;
- else if (st & 0x10)
+ else if (st & CFI_INTEL_STATUS_PSLBS)
error = EIO;
- else if (st & 0x20)
+ else if (st & CFI_INTEL_STATUS_ECLBS)
error = ENXIO;
+ else if (st)
+ error = EACCES;
}
break;
case CFI_VEND_AMD_SCS:
case CFI_VEND_AMD_ECS:
- st0 = cfi_read(sc, sc->sc_wrofs);
- st = cfi_read(sc, sc->sc_wrofs);
+ st0 = cfi_read(sc, ofs);
+ st = cfi_read(sc, ofs);
done = ((st & 0x40) == (st0 & 0x40)) ? 1 : 0;
break;
}
@@ -332,7 +344,7 @@ cfi_wait_ready(struct cfi_softc *sc, u_int timeout)
if (!done && !error)
error = ETIMEDOUT;
if (error)
- printf("\nerror=%d\n", error);
+ printf("\nerror=%d (st 0x%x st0 0x%x)\n", error, st, st0);
return (error);
}
@@ -364,7 +376,7 @@ cfi_write_block(struct cfi_softc *sc)
/* Better safe than sorry... */
return (ENODEV);
}
- error = cfi_wait_ready(sc, sc->sc_erase_timeout);
+ error = cfi_wait_ready(sc, sc->sc_wrofs, sc->sc_erase_timeout);
if (error)
goto out;
@@ -406,7 +418,7 @@ cfi_write_block(struct cfi_softc *sc)
intr_restore(intr);
- error = cfi_wait_ready(sc, sc->sc_write_timeout);
+ error = cfi_wait_ready(sc, sc->sc_wrofs, sc->sc_write_timeout);
if (error)
goto out;
}
@@ -417,3 +429,155 @@ cfi_write_block(struct cfi_softc *sc)
cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
return (error);
}
+
+#ifdef CFI_SUPPORT_STRATAFLASH
+/*
+ * Intel StrataFlash Protection Register Support.
+ *
+ * The memory includes a 128-bit Protection Register that can be
+ * used for security. There are two 64-bit segments; one is programmed
+ * at the factory with a unique 64-bit number which is immutable.
+ * The other segment is left blank for User (OEM) programming.
+ * The User/OEM segment is One Time Programmable (OTP). It can also
+ * be locked to prevent any firther writes by setting bit 0 of the
+ * Protection Lock Register (PLR). The PLR can written only once.
+ */
+
+static uint16_t
+cfi_get16(struct cfi_softc *sc, int off)
+{
+ uint16_t v = bus_space_read_2(sc->sc_tag, sc->sc_handle, off<<1);
+ return v;
+}
+
+#ifdef CFI_ARMEDANDDANGEROUS
+static void
+cfi_put16(struct cfi_softc *sc, int off, uint16_t v)
+{
+ bus_space_write_2(sc->sc_tag, sc->sc_handle, off<<1, v);
+}
+#endif
+
+/*
+ * Read the factory-defined 64-bit segment of the PR.
+ */
+int
+cfi_intel_get_factory_pr(struct cfi_softc *sc, uint64_t *id)
+{
+ if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
+ return EOPNOTSUPP;
+ KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
+
+ cfi_write(sc, 0, CFI_INTEL_READ_ID);
+ *id = ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(0)))<<48 |
+ ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(1)))<<32 |
+ ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(2)))<<16 |
+ ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(3)));
+ cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
+ return 0;
+}
+
+/*
+ * Read the User/OEM 64-bit segment of the PR.
+ */
+int
+cfi_intel_get_oem_pr(struct cfi_softc *sc, uint64_t *id)
+{
+ if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
+ return EOPNOTSUPP;
+ KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
+
+ cfi_write(sc, 0, CFI_INTEL_READ_ID);
+ *id = ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(4)))<<48 |
+ ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(5)))<<32 |
+ ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(6)))<<16 |
+ ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(7)));
+ cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
+ return 0;
+}
+
+/*
+ * Write the User/OEM 64-bit segment of the PR.
+ * XXX should allow writing individual words/bytes
+ */
+int
+cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t id)
+{
+#ifdef CFI_ARMEDANDDANGEROUS
+ register_t intr;
+ int i, error;
+#endif
+
+ if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
+ return EOPNOTSUPP;
+ KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
+
+#ifdef CFI_ARMEDANDDANGEROUS
+ for (i = 7; i >= 4; i--, id >>= 16) {
+ intr = intr_disable();
+ cfi_write(sc, 0, CFI_INTEL_PP_SETUP);
+ cfi_put16(sc, CFI_INTEL_PR(i), id&0xffff);
+ intr_restore(intr);
+ error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS,
+ sc->sc_write_timeout);
+ if (error)
+ break;
+ }
+ cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
+ return error;
+#else
+ device_printf(sc->sc_dev, "%s: OEM PR not set, "
+ "CFI_ARMEDANDDANGEROUS not configured\n", __func__);
+ return ENXIO;
+#endif
+}
+
+/*
+ * Read the contents of the Protection Lock Register.
+ */
+int
+cfi_intel_get_plr(struct cfi_softc *sc, uint32_t *plr)
+{
+ if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
+ return EOPNOTSUPP;
+ KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
+
+ cfi_write(sc, 0, CFI_INTEL_READ_ID);
+ *plr = cfi_get16(sc, CFI_INTEL_PLR);
+ cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
+ return 0;
+}
+
+/*
+ * Write the Protection Lock Register to lock down the
+ * user-settable segment of the Protection Register.
+ * NOTE: this operation is not reversible.
+ */
+int
+cfi_intel_set_plr(struct cfi_softc *sc)
+{
+#ifdef CFI_ARMEDANDDANGEROUS
+ register_t intr;
+ int error;
+#endif
+ if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
+ return EOPNOTSUPP;
+ KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));
+
+#ifdef CFI_ARMEDANDDANGEROUS
+ /* worthy of console msg */
+ device_printf(sc->sc_dev, "set PLR\n");
+ intr = intr_disable();
+ cfi_write(sc, 0, CFI_INTEL_PP_SETUP);
+ cfi_put16(sc, CFI_INTEL_PLR, 0xFFFD);
+ intr_restore(intr);
+ error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, sc->sc_write_timeout);
+ cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
+ return error;
+#else
+ device_printf(sc->sc_dev, "%s: PLR not set, "
+ "CFI_ARMEDANDDANGEROUS not configured\n", __func__);
+ return ENXIO;
+#endif
+}
+#endif /* CFI_SUPPORT_STRATAFLASH */
diff --git a/sys/dev/cfi/cfi_dev.c b/sys/dev/cfi/cfi_dev.c
index aad1de2..89069cb 100644
--- a/sys/dev/cfi/cfi_dev.c
+++ b/sys/dev/cfi/cfi_dev.c
@@ -30,6 +30,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_cfi.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -252,26 +254,47 @@ cfi_devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
int error;
u_char val;
- if (cmd != CFIOCQRY)
- return (ENOIOCTL);
-
sc = dev->si_drv1;
+ error = 0;
- error = (sc->sc_writing) ? cfi_block_finish(sc) : 0;
- if (error)
- return (error);
-
- rq = (struct cfiocqry *)data;
-
- if (rq->offset >= sc->sc_size / sc->sc_width)
- return (ESPIPE);
- if (rq->offset + rq->count > sc->sc_size / sc->sc_width)
- return (ENOSPC);
-
- while (!error && rq->count--) {
- val = cfi_read_qry(sc, rq->offset++);
- error = copyout(&val, rq->buffer++, 1);
+ switch (cmd) {
+ case CFIOCQRY:
+ if (sc->sc_writing) {
+ error = cfi_block_finish(sc);
+ if (error)
+ break;
+ }
+ rq = (struct cfiocqry *)data;
+ if (rq->offset >= sc->sc_size / sc->sc_width)
+ return (ESPIPE);
+ if (rq->offset + rq->count > sc->sc_size / sc->sc_width)
+ return (ENOSPC);
+
+ while (!error && rq->count--) {
+ val = cfi_read_qry(sc, rq->offset++);
+ error = copyout(&val, rq->buffer++, 1);
+ }
+ break;
+#ifdef CFI_SUPPORT_STRATAFLASH
+ case CFIOCGFACTORYPR:
+ error = cfi_intel_get_factory_pr(sc, (uint64_t *)data);
+ break;
+ case CFIOCGOEMPR:
+ error = cfi_intel_get_oem_pr(sc, (uint64_t *)data);
+ break;
+ case CFIOCSOEMPR:
+ error = cfi_intel_set_oem_pr(sc, *(uint64_t *)data);
+ break;
+ case CFIOCGPLR:
+ error = cfi_intel_get_plr(sc, (uint32_t *)data);
+ break;
+ case CFIOCSPLR:
+ error = cfi_intel_set_plr(sc);
+ break;
+#endif /* CFI_SUPPORT_STRATAFLASH */
+ default:
+ error = ENOIOCTL;
+ break;
}
-
return (error);
}
diff --git a/sys/dev/cfi/cfi_reg.h b/sys/dev/cfi/cfi_reg.h
index fe4d730..d492678 100644
--- a/sys/dev/cfi/cfi_reg.h
+++ b/sys/dev/cfi/cfi_reg.h
@@ -104,6 +104,28 @@ struct cfi_qry {
#define CFI_BCS_CONFIRM 0xd0
#define CFI_BCS_READ_ARRAY 0xff
+/* Intel commands. */
+#define CFI_INTEL_READ_ID 0x90 /* Read Identifier */
+#define CFI_INTEL_PP_SETUP 0xc0 /* Protection Program Setup */
+
+/* NB: these are addresses for 16-bit accesses */
+#define CFI_INTEL_PLR 0x80 /* Protection Lock Register */
+#define CFI_INTEL_PR(n) (0x81+(n)) /* Protection Register */
+
+/* Status register definitions */
+#define CFI_INTEL_STATUS_WSMS 0x0080 /* Write Machine Status */
+#define CFI_INTEL_STATUS_ESS 0x0040 /* Erase Suspend Status */
+#define CFI_INTEL_STATUS_ECLBS 0x0020 /* Erase and Clear Lock-Bit Status */
+#define CFI_INTEL_STATUS_PSLBS 0x0010 /* Program and Set Lock-Bit Status */
+#define CFI_INTEL_STATUS_VPENS 0x0008 /* Programming Voltage Status */
+#define CFI_INTEL_STATUS_PSS 0x0004 /* Program Suspend Status */
+#define CFI_INTEL_STATUS_DPS 0x0002 /* Device Protect Status */
+#define CFI_INTEL_STATUS_RSVD 0x0001 /* reserved */
+
+/* eXtended Status register definitions */
+#define CFI_INTEL_XSTATUS_WBS 0x8000 /* Write Buffer Status */
+#define CFI_INTEL_XSTATUS_RSVD 0x7f00 /* reserved */
+
/* AMD commands. */
#define CFI_AMD_BLOCK_ERASE 0x30
#define CFI_AMD_UNLOCK_ACK 0x55
diff --git a/sys/dev/cfi/cfi_var.h b/sys/dev/cfi/cfi_var.h
index 5c99702..d2a778b 100644
--- a/sys/dev/cfi/cfi_var.h
+++ b/sys/dev/cfi/cfi_var.h
@@ -74,4 +74,11 @@ uint32_t cfi_read(struct cfi_softc *, u_int);
uint8_t cfi_read_qry(struct cfi_softc *, u_int);
int cfi_write_block(struct cfi_softc *);
+#ifdef CFI_SUPPORT_STRATAFLASH
+int cfi_intel_get_factory_pr(struct cfi_softc *sc, uint64_t *);
+int cfi_intel_get_oem_pr(struct cfi_softc *sc, uint64_t *);
+int cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t);
+int cfi_intel_get_plr(struct cfi_softc *sc, uint32_t *);
+int cfi_intel_set_plr(struct cfi_softc *sc);
+#endif /* CFI_SUPPORT_STRATAFLASH */
#endif /* _DEV_CFI_VAR_H_ */
diff --git a/sys/dev/dcons/dcons_crom.c b/sys/dev/dcons/dcons_crom.c
index 0b2b707..ee263e9 100644
--- a/sys/dev/dcons/dcons_crom.c
+++ b/sys/dev/dcons/dcons_crom.c
@@ -205,7 +205,10 @@ dcons_crom_attach(device_t dev)
return (-1);
#else
struct dcons_crom_softc *sc;
+ int error;
+ if (dcons_conf->buf == NULL)
+ return (ENXIO);
sc = (struct dcons_crom_softc *) device_get_softc(dev);
sc->fd.fc = device_get_ivars(dev);
sc->fd.dev = dev;
@@ -213,7 +216,7 @@ dcons_crom_attach(device_t dev)
sc->fd.post_busreset = (void *) dcons_crom_post_busreset;
/* map dcons buffer */
- bus_dma_tag_create(
+ error = bus_dma_tag_create(
/*parent*/ sc->fd.fc->dmat,
/*alignment*/ sizeof(u_int32_t),
/*boundary*/ 0,
@@ -229,10 +232,16 @@ dcons_crom_attach(device_t dev)
/*lockarg*/&Giant,
#endif
&sc->dma_tag);
- bus_dmamap_create(sc->dma_tag, BUS_DMA_COHERENT, &sc->dma_map);
- bus_dmamap_load(sc->dma_tag, sc->dma_map,
+ if (error != 0)
+ return (error);
+ error = bus_dmamap_create(sc->dma_tag, BUS_DMA_COHERENT, &sc->dma_map);
+ if (error != 0)
+ return (error);
+ error = bus_dmamap_load(sc->dma_tag, sc->dma_map,
(void *)dcons_conf->buf, dcons_conf->size,
dmamap_cb, sc, 0);
+ if (error != 0)
+ return (error);
sc->ehand = EVENTHANDLER_REGISTER(dcons_poll, dcons_crom_poll,
(void *)sc, 0);
return (0);
diff --git a/sys/dev/dcons/dcons_os.c b/sys/dev/dcons/dcons_os.c
index 466f7a0..f4d4181 100644
--- a/sys/dev/dcons/dcons_os.c
+++ b/sys/dev/dcons/dcons_os.c
@@ -336,6 +336,8 @@ dcons_drv_init(int stage)
*/
dg.buf = (struct dcons_buf *) contigmalloc(dg.size,
M_DEVBUF, 0, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
+ if (dg.buf == NULL)
+ return (-1);
dcons_init(dg.buf, dg.size, sc);
}
@@ -400,8 +402,8 @@ dcons_modevent(module_t mode, int type, void *data)
switch (type) {
case MOD_LOAD:
ret = dcons_drv_init(1);
- dcons_attach();
if (ret == 0) {
+ dcons_attach();
dcons_cnprobe(&dcons_consdev);
dcons_cninit(&dcons_consdev);
cnadd(&dcons_consdev);
@@ -409,13 +411,15 @@ dcons_modevent(module_t mode, int type, void *data)
break;
case MOD_UNLOAD:
printf("dcons: unload\n");
- callout_stop(&dcons_callout);
- cnremove(&dcons_consdev);
- dcons_detach(DCONS_CON);
- dcons_detach(DCONS_GDB);
- dg.buf->magic = 0;
-
- contigfree(dg.buf, DCONS_BUF_SIZE, M_DEVBUF);
+ if (drv_init == 1) {
+ callout_stop(&dcons_callout);
+ cnremove(&dcons_consdev);
+ dcons_detach(DCONS_CON);
+ dcons_detach(DCONS_GDB);
+ dg.buf->magic = 0;
+
+ contigfree(dg.buf, DCONS_BUF_SIZE, M_DEVBUF);
+ }
break;
case MOD_SHUTDOWN:
diff --git a/sys/dev/digi/con.CX-IBM.h b/sys/dev/digi/con.CX-IBM.h
deleted file mode 100644
index b0c9db3..0000000
--- a/sys/dev/digi/con.CX-IBM.h
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*-
- * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
- * based on work by Slawa Olhovchenkov
- * 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$
- */
-
-const u_char con_CX_IBM[] = {
- 0x43, 0x58, 0x03, 0x00, 0x00, 0x08, 0xbf, 0x08, 0x00, 0x11, 0x60, 0x4d, 0x00,
- 0x00, 0x00, 0x00, 0xe9, 0x8d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x78, 0x63,
- 0x6f, 0x6e, 0x2e, 0x62, 0x69, 0x6e, 0x20, 0x20, 0x33, 0x2e, 0x34, 0x20, 0x20,
- 0x30, 0x36, 0x2f, 0x30, 0x33, 0x2f, 0x39, 0x37, 0x20, 0x4f, 0x45, 0x4d, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74,
- 0x20, 0x28, 0x43, 0x29, 0x20, 0x31, 0x39, 0x38, 0x39, 0x2d, 0x31, 0x39, 0x39,
- 0x37, 0x2c, 0x20, 0x44, 0x69, 0x67, 0x69, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2c, 0x20, 0x41, 0x6c, 0x6c,
- 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72,
- 0x76, 0x65, 0x64, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x01, 0x09, 0x01, 0x06,
- 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01,
- 0x06, 0x01, 0x06, 0x01, 0xa5, 0x08, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06,
- 0x01, 0x0c, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01,
- 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0x06,
- 0x01, 0x06, 0x01, 0x06, 0x01, 0x54, 0x54, 0x39, 0x77, 0x3e, 0x38, 0x3e, 0x73,
- 0x39, 0x73, 0x39, 0x79, 0x3f, 0x3f, 0x06, 0x3f, 0x5b, 0x3f, 0x4f, 0x3f, 0x66,
- 0x3f, 0x6d, 0x3f, 0x7d, 0x3f, 0x07, 0x3f, 0x7f, 0x3f, 0x67, 0x3f, 0x3f, 0x06,
- 0x06, 0x06, 0x5b, 0x06, 0x4f, 0x06, 0x66, 0x06, 0x6d, 0x06, 0x7d, 0x06, 0x54,
- 0x06, 0x54, 0x5b, 0x54, 0x4f, 0x54, 0x66, 0x54, 0x6d, 0x54, 0x7d, 0x54, 0x07,
- 0x54, 0x7f, 0xe8, 0xf7, 0x00, 0xe8, 0xf4, 0x00, 0xe5, 0x58, 0xe8, 0xef, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xa3, 0x10, 0x60, 0x89, 0x1e, 0x12, 0x60,
- 0x89, 0x0e, 0x14, 0x60, 0x89, 0x16, 0x16, 0x60, 0x89, 0x36, 0x18, 0x60, 0x89,
- 0x3e, 0x1a, 0x60, 0x89, 0x2e, 0x1c, 0x60, 0x89, 0x26, 0x1e, 0x60, 0x8c, 0xc8,
- 0xa3, 0x20, 0x60, 0x8c, 0xd8, 0xa3, 0x22, 0x60, 0x8c, 0xd0, 0xa3, 0x24, 0x60,
- 0x8c, 0xc0, 0xa3, 0x26, 0x60, 0x8b, 0xec, 0x8b, 0x46, 0x00, 0xa3, 0x0a, 0x60,
- 0x8b, 0x46, 0x02, 0xa3, 0x0c, 0x60, 0x8b, 0x46, 0x04, 0xa3, 0x0e, 0x60, 0x8b,
- 0x2e, 0x1c, 0x60, 0xa1, 0x10, 0x60, 0xb8, 0x00, 0x20, 0x8e, 0xc0, 0xbb, 0x40,
- 0x03, 0x26, 0xc6, 0x07, 0x00, 0x33, 0xc0, 0x8b, 0x1e, 0x0c, 0x60, 0xb9, 0x00,
- 0x80, 0xe2, 0xfe, 0x93, 0xa3, 0x00, 0xf1, 0xeb, 0xf5, 0xb8, 0x00, 0x00, 0x8e,
- 0xc0, 0x8b, 0xf0, 0x8b, 0xf8, 0x2e, 0x8b, 0x9c, 0x88, 0x00, 0x83, 0xc6, 0x02,
- 0x26, 0x89, 0x1d, 0x26, 0x8c, 0x4d, 0x02, 0x83, 0xc7, 0x04, 0x81, 0xff, 0x80,
- 0x00, 0x72, 0xe8, 0x26, 0xc7, 0x05, 0x06, 0x01, 0x26, 0x8c, 0x4d, 0x02, 0x83,
- 0xc7, 0x04, 0x81, 0xff, 0x00, 0x04, 0x72, 0xee, 0xc3, 0xfa, 0xfc, 0x8c, 0xc8,
- 0x8e, 0xd8, 0x8e, 0xd0, 0xf7, 0xd8, 0x05, 0x00, 0x20, 0xc1, 0xe0, 0x04, 0x8b,
- 0xe0, 0xe8, 0xb7, 0xff, 0xb8, 0x00, 0x01, 0x8e, 0xc0, 0x33, 0xff, 0xb9, 0x00,
- 0x80, 0x33, 0xc0, 0xf3, 0xab, 0x8c, 0xc8, 0x8e, 0xc0, 0xbf, 0x00, 0x50, 0xb9,
- 0x00, 0x20, 0x2b, 0xc8, 0xc1, 0xe1, 0x04, 0x2b, 0xcf, 0xd1, 0xe9, 0x33, 0xc0,
- 0xf3, 0xab, 0xb8, 0x00, 0x00, 0xba, 0xfe, 0xff, 0xef, 0xb8, 0xfd, 0x1f, 0xb8,
- 0xfc, 0x1f, 0xe7, 0xa2, 0xb8, 0x00, 0x40, 0xe7, 0x56, 0x33, 0xc0, 0xe7, 0x50,
- 0xb8, 0x00, 0x40, 0xe7, 0x5e, 0xb8, 0xfe, 0xff, 0xe7, 0x5a, 0xe7, 0x5c, 0x33,
- 0xc0, 0xe7, 0x58, 0xb8, 0x07, 0xe0, 0xe7, 0x5e, 0xb8, 0x00, 0x40, 0xe7, 0x66,
- 0x33, 0xc0, 0xe7, 0x60, 0xb8, 0x13, 0x00, 0xe7, 0x38, 0xb8, 0x11, 0x00, 0xe7,
- 0x3a, 0xe7, 0x3c, 0xb8, 0x02, 0x00, 0xe7, 0x32, 0xb8, 0xfd, 0x00, 0xe7, 0x28,
- 0x33, 0xc0, 0xe7, 0x2c, 0xfb, 0xb8, 0x00, 0xf0, 0x8e, 0xc0, 0x26, 0x8b, 0x1e,
- 0xfe, 0xff, 0x89, 0x1e, 0x03, 0x5a, 0xbd, 0x00, 0x00, 0xe8, 0x5b, 0x3e, 0xe8,
- 0xbe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x46,
- 0x02, 0x8b, 0xd8, 0x81, 0xe3, 0x0f, 0x0f, 0x33, 0xc3, 0x86, 0xdf, 0x0b, 0xc3,
- 0x8b, 0xd8, 0x81, 0xe3, 0x33, 0x33, 0x33, 0xc3, 0xc1, 0xc3, 0x04, 0x0b, 0xc3,
- 0x8b, 0xd8, 0x81, 0xe3, 0x55, 0x55, 0x33, 0xc3, 0xc1, 0xc3, 0x02, 0x0b, 0xc3,
- 0xd1, 0xc0, 0x8b, 0xe9, 0xc3, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xb8, 0xff, 0x20,
- 0xe7, 0xfe, 0x2e, 0xff, 0x1e, 0x32, 0x08, 0x8b, 0xcd, 0x8b, 0xec, 0xfa, 0x8a,
- 0x46, 0x02, 0xa2, 0x00, 0xf2, 0x32, 0xe4, 0xa0, 0x00, 0xf2, 0xfb, 0x8b, 0xe9,
- 0xc3, 0x8b, 0xcd, 0x8b, 0xec, 0xfa, 0x8a, 0x46, 0x02, 0xa2, 0x00, 0xf2, 0x8a,
- 0x46, 0x04, 0x8b, 0xe9, 0xa2, 0x00, 0xf2, 0xfb, 0xc3, 0x8b, 0xcd, 0x8b, 0xec,
- 0xfa, 0x8a, 0x46, 0x02, 0xa2, 0x04, 0xf2, 0x8a, 0x46, 0x04, 0x8b, 0xe9, 0xa2,
- 0x04, 0xf2, 0xfb, 0xc3, 0xfa, 0xc6, 0x06, 0x00, 0xf2, 0x07, 0x8a, 0x26, 0x00,
- 0xf2, 0xc6, 0x06, 0x00, 0xf2, 0x06, 0xa0, 0x00, 0xf2, 0xa3, 0x28, 0x60, 0xc6,
- 0x06, 0x00, 0xf2, 0x01, 0xa0, 0x00, 0xf2, 0x8a, 0x26, 0x00, 0xf2, 0xa3, 0x2a,
- 0x60, 0xfb, 0xc3, 0xfb, 0x60, 0x1e, 0x06, 0x8c, 0xd0, 0x8e, 0xd8, 0xc6, 0x06,
- 0x00, 0xf2, 0x03, 0x90, 0x90, 0xa0, 0x00, 0xf2, 0x0a, 0xc0, 0x75, 0x04, 0xff,
- 0x06, 0x01, 0x5a, 0x83, 0x2e, 0x2c, 0x60, 0x01, 0x73, 0x1c, 0xc6, 0x06, 0x00,
- 0xf2, 0x03, 0x90, 0x90, 0xa0, 0x00, 0xf2, 0xa8, 0x08, 0x75, 0x09, 0xa8, 0x20,
- 0x74, 0x0d, 0xe8, 0x03, 0x35, 0xeb, 0xe9, 0xe8, 0x7a, 0x34, 0xeb, 0xe4, 0xe8,
- 0x1b, 0xf9, 0xff, 0x06, 0x2c, 0x60, 0xfa, 0xb8, 0x00, 0x80, 0xe7, 0x22, 0x83,
- 0x3e, 0x48, 0xb0, 0x00, 0x74, 0x09, 0xc7, 0x06, 0xf2, 0xc3, 0x01, 0x00, 0xeb,
- 0x1f, 0x90, 0xc7, 0x06, 0x48, 0xb0, 0x01, 0x00, 0xc7, 0x06, 0xf2, 0xc3, 0x00,
- 0x00, 0xfb, 0xe8, 0x25, 0x32, 0xfa, 0x83, 0x3e, 0xf2, 0xc3, 0x00, 0x75, 0xee,
- 0xc7, 0x06, 0x48, 0xb0, 0x00, 0x00, 0x07, 0x1f, 0x61, 0xcf, 0x55, 0x8b, 0xec,
- 0x8b, 0x5e, 0x04, 0xba, 0xc4, 0x00, 0xb1, 0x1f, 0xfa, 0xe5, 0xc8, 0x3d, 0x32,
- 0x00, 0x77, 0x0e, 0xb8, 0x64, 0xb2, 0xe7, 0xca, 0xed, 0x03, 0xd8, 0x8b, 0xc3,
- 0xef, 0xeb, 0x11, 0x90, 0xb8, 0x64, 0xb2, 0xe7, 0xca, 0xed, 0x03, 0xd8, 0x8b,
- 0xc3, 0xef, 0xb8, 0x66, 0xb2, 0xe7, 0xca, 0xfb, 0x8b, 0xc3, 0x5d, 0xc3, 0x55,
- 0x8b, 0xec, 0x8b, 0x5e, 0x04, 0xb8, 0x64, 0xb2, 0xfa, 0xb1, 0x1f, 0xd2, 0xc5,
- 0xe7, 0xca, 0xe5, 0xc4, 0x2b, 0xd8, 0x8b, 0xc3, 0x4b, 0x81, 0xfb, 0x88, 0x13,
- 0x77, 0x07, 0xe7, 0xc8, 0xb8, 0x66, 0xb2, 0xe7, 0xca, 0xfb, 0x5d, 0xc3, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x09, 0x00, 0x06, 0x17, 0x04, 0x59, 0x03, 0x00, 0x03,
- 0x40, 0x02, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00, 0x40, 0x00, 0x30, 0x00, 0x18,
- 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x06,
- 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x40, 0x02, 0x80, 0x01, 0x01, 0x00, 0x60,
- 0x00, 0x04, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03, 0x00,
- 0x1f, 0x3f, 0x7f, 0xff, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0xc1, 0x15, 0xdd, 0x15, 0x7c, 0x16,
- 0xa3, 0x15, 0xb5, 0x15, 0xe2, 0x16, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48,
- 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15,
- 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48,
- 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15,
- 0x48, 0x15, 0x48, 0x15, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x02, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15,
- 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95,
- 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15,
- 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95,
- 0x15, 0x95, 0x15, 0x10, 0x15, 0x1e, 0x15, 0x2c, 0x15, 0x3a, 0x15, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x45,
- 0x1d, 0x60, 0x1d, 0xfc, 0x1d, 0x27, 0x1d, 0x39, 0x1d, 0x65, 0x1e, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c,
- 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x41, 0x1f, 0x41, 0x1f,
- 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41,
- 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f,
- 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41,
- 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0xe1, 0x1c, 0x93, 0x1f, 0x93, 0x1f, 0x93,
- 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f,
- 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93,
- 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f,
- 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0xef, 0x1c, 0xfd, 0x1c, 0x0b,
- 0x1d, 0x19, 0x1d, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c,
- 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c,
- 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x8a, 0x5c, 0x50, 0xf6, 0xc3, 0x0e, 0x75, 0x21, 0xf6, 0xc3, 0x40, 0x75,
- 0x08, 0xf6, 0xc3, 0x10, 0x74, 0x0a, 0xff, 0x64, 0x04, 0x8b, 0x5c, 0x02, 0x89,
- 0x1c, 0xff, 0xe3, 0x80, 0x7c, 0x49, 0x00, 0x74, 0x1a, 0xc7, 0x04, 0xaa, 0x18,
- 0xe9, 0x3d, 0x04, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc3, 0x02, 0x75,
- 0x40, 0xf6, 0xc3, 0x08, 0x75, 0x14, 0xeb, 0x61, 0x90, 0xc7, 0x04, 0x8b, 0x14,
- 0x8b, 0x6c, 0x20, 0xc6, 0x46, 0x02, 0x01, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24,
- 0xf6, 0xc4, 0x20, 0x74, 0x1f, 0x80, 0x64, 0x50, 0xf7, 0xf6, 0x44, 0x51, 0x02,
- 0x74, 0x0f, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x09, 0x8a, 0x44, 0x5d, 0x88, 0x46,
- 0x00, 0xe9, 0xb1, 0x03, 0x8a, 0x44, 0x5c, 0x88, 0x46, 0x00, 0xe9, 0xa8, 0x03,
- 0x80, 0x4c, 0x67, 0x02, 0xf6, 0x44, 0x50, 0x04, 0x75, 0x1e, 0x83, 0x7c, 0x24,
- 0xff, 0x74, 0x15, 0x8b, 0x1e, 0xbc, 0x59, 0x2b, 0x5c, 0x26, 0x81, 0xfb, 0xe8,
- 0x03, 0x77, 0x08, 0x80, 0x66, 0x06, 0xbf, 0x80, 0x64, 0x50, 0xfd, 0xe9, 0x80,
- 0x03, 0xf6, 0xc4, 0x40, 0x74, 0x1a, 0x80, 0x4c, 0x67, 0x02, 0x80, 0x4e, 0x06,
- 0x40, 0x8b, 0x5c, 0x24, 0x03, 0x1e, 0xbc, 0x59, 0x89, 0x5c, 0x26, 0x80, 0x64,
- 0x50, 0xfb, 0x80, 0x4c, 0x50, 0x02, 0xe9, 0x5e, 0x03, 0xf6, 0x44, 0x2a, 0x01,
- 0x75, 0x03, 0xe9, 0x09, 0x04, 0xb0, 0x27, 0xeb, 0x42, 0x90, 0xf6, 0x44, 0x2a,
- 0x01, 0x75, 0x03, 0xe9, 0xfb, 0x03, 0xb0, 0x28, 0xeb, 0x34, 0x90, 0xf6, 0x44,
- 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xed, 0x03, 0xb0, 0x21, 0xeb, 0x26, 0x90, 0xf6,
- 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xdf, 0x03, 0xb0, 0x29, 0xeb, 0x18, 0x90,
- 0xf6, 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xd1, 0x03, 0xb0, 0x5e, 0xeb, 0x0a,
- 0x90, 0xf6, 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xc3, 0x03, 0x88, 0x44, 0x61,
- 0xb0, 0x5c, 0x88, 0x46, 0x00, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0x69, 0x15,
- 0xc7, 0x44, 0x02, 0x69, 0x15, 0xe9, 0xf7, 0x02, 0x8b, 0x6c, 0x20, 0x8a, 0x66,
- 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x1e, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a,
- 0x44, 0x53, 0x75, 0x13, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c,
- 0x83, 0x44, 0x30, 0x02, 0x8a, 0x44, 0x61, 0xe9, 0x85, 0x03, 0xe9, 0xcb, 0x02,
- 0xf6, 0x44, 0x2a, 0x02, 0x75, 0x03, 0xe9, 0x76, 0x03, 0x2c, 0x20, 0xe9, 0x71,
- 0x03, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x40, 0x75, 0x03, 0xe9, 0xb1, 0x02,
- 0xbb, 0x7f, 0x00, 0xe9, 0x7d, 0x01, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x80,
- 0x75, 0xf1, 0xe9, 0x9f, 0x02, 0x88, 0x46, 0x00, 0xf7, 0x44, 0x30, 0xff, 0xff,
- 0x74, 0x03, 0xff, 0x4c, 0x30, 0xf6, 0x44, 0x2b, 0x20, 0x75, 0x03, 0xe9, 0x89,
- 0x02, 0xbb, 0x02, 0x00, 0xe9, 0x55, 0x01, 0xb3, 0x18, 0x22, 0x5c, 0x2b, 0x75,
- 0x12, 0x88, 0x46, 0x00, 0x8b, 0x5c, 0x30, 0x83, 0xc3, 0x08, 0x80, 0xe3, 0xf8,
- 0x89, 0x5c, 0x30, 0xe9, 0x6a, 0x02, 0x80, 0xfb, 0x18, 0x75, 0x53, 0xb0, 0x20,
- 0x88, 0x46, 0x00, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01,
- 0x5c, 0x30, 0x4b, 0x74, 0x3c, 0x89, 0x5c, 0x32, 0x80, 0x4c, 0x50, 0x40, 0xc7,
- 0x44, 0x02, 0x22, 0x16, 0xc7, 0x04, 0x22, 0x16, 0xe9, 0x3e, 0x02, 0x8b, 0x6c,
- 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x1e, 0x8a, 0x46, 0x0c, 0x22,
- 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x13, 0xb0, 0x20, 0x88, 0x46, 0x00, 0xff,
- 0x4c, 0x32, 0x75, 0x09, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c,
- 0xe9, 0x12, 0x02, 0x88, 0x46, 0x00, 0x80, 0xfb, 0x08, 0x75, 0x14, 0x8b, 0x5c,
- 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30, 0x83, 0xfb, 0x05,
- 0x7c, 0xe4, 0xe9, 0xc8, 0x00, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07,
- 0x43, 0x01, 0x5c, 0x30, 0xbb, 0x02, 0x00, 0xe9, 0xb6, 0x00, 0xf6, 0x44, 0x2a,
- 0x20, 0x75, 0x47, 0xf6, 0x44, 0x2a, 0x04, 0x74, 0x46, 0xf6, 0x44, 0x2a, 0x10,
- 0x74, 0x07, 0xf7, 0x44, 0x30, 0xff, 0xff, 0x74, 0x34, 0xb0, 0x0d, 0x88, 0x46,
- 0x00, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xaa, 0x16, 0xc7, 0x44, 0x02, 0xaa,
- 0x16, 0xe9, 0xb6, 0x01, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20,
- 0x74, 0x24, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x19,
- 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0xb0, 0x0a, 0xeb, 0x27,
- 0x90, 0xb0, 0x0a, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x01, 0x75, 0x03, 0xe9,
- 0x84, 0x01, 0xbb, 0x05, 0x00, 0xeb, 0x51, 0x90, 0xf6, 0x44, 0x2a, 0x08, 0x75,
- 0xe6, 0xf6, 0x44, 0x2a, 0x10, 0x74, 0x06, 0x83, 0x7c, 0x30, 0x00, 0x74, 0x0f,
- 0x88, 0x46, 0x00, 0xb3, 0x06, 0x22, 0x5c, 0x2b, 0x75, 0x08, 0xc7, 0x44, 0x30,
- 0x00, 0x00, 0xe9, 0x5a, 0x01, 0x80, 0xfb, 0x02, 0x75, 0x14, 0x8b, 0x5c, 0x30,
- 0xc1, 0xeb, 0x04, 0x83, 0xc3, 0x03, 0x83, 0xfb, 0x06, 0x72, 0x14, 0xbb, 0x06,
- 0x00, 0xeb, 0x0f, 0x90, 0x80, 0xfb, 0x04, 0x75, 0x06, 0xbb, 0x05, 0x00, 0xeb,
- 0x04, 0x90, 0xbb, 0x09, 0x00, 0xc7, 0x44, 0x30, 0x00, 0x00, 0xf6, 0x44, 0x2a,
- 0x40, 0x74, 0x4d, 0x83, 0xfb, 0x20, 0x77, 0x48, 0xc1, 0xeb, 0x02, 0x74, 0x03,
- 0xbb, 0x01, 0x00, 0x43, 0x89, 0x5c, 0x32, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x44,
- 0x02, 0x59, 0x17, 0xc7, 0x04, 0x59, 0x17, 0xe9, 0x07, 0x01, 0x8b, 0x6c, 0x20,
- 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x1e, 0x8a, 0x46, 0x0c, 0x22, 0x44,
- 0x52, 0x3a, 0x44, 0x53, 0x75, 0x13, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75,
- 0x0b, 0x8a, 0x44, 0x60, 0x88, 0x46, 0x00, 0xff, 0x4c, 0x32, 0x74, 0x4d, 0xe9,
- 0xdb, 0x00, 0x83, 0xc3, 0x06, 0xc1, 0xe3, 0x04, 0x89, 0x5c, 0x32, 0x80, 0x4c,
- 0x50, 0x40, 0xc7, 0x44, 0x02, 0x9e, 0x17, 0xc7, 0x04, 0x9e, 0x17, 0xe9, 0xc2,
- 0x00, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x40, 0x74, 0x10, 0x8b,
- 0x1e, 0xbc, 0x59, 0x01, 0x5c, 0x32, 0xc7, 0x44, 0x02, 0xbc, 0x17, 0xc7, 0x04,
- 0xbc, 0x17, 0xe9, 0xa4, 0x00, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x1e,
- 0xbc, 0x59, 0x2b, 0x5c, 0x32, 0x81, 0xfb, 0xe8, 0x03, 0x77, 0xea, 0x80, 0x64,
- 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0xe9, 0x85, 0x00, 0x90, 0xc7, 0x04,
- 0xe0, 0x17, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x75,
- 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0x60, 0x8a, 0x46, 0x0c, 0x22, 0x44,
- 0x52, 0x3a, 0x44, 0x53, 0x75, 0x62, 0x8e, 0x44, 0x08, 0x26, 0x8a, 0x05, 0x47,
- 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x8a, 0xd8, 0x22, 0x5c, 0x62, 0x32,
- 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7, 0x44, 0x10, 0x80, 0x7c, 0x53, 0x00, 0x75,
- 0xbc, 0xc7, 0x04, 0x24, 0x18, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4,
- 0x20, 0x74, 0x31, 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0x1c, 0x8e, 0x44,
- 0x08, 0x26, 0x8a, 0x05, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x8a,
- 0xd8, 0x22, 0x5c, 0x62, 0x32, 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7, 0x44, 0x10,
- 0xf6, 0xc4, 0x40, 0x74, 0x08, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x44, 0x14,
- 0xf6, 0xc4, 0x01, 0x75, 0x51, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x90, 0xc7,
- 0x04, 0x70, 0x18, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74,
- 0x24, 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0x46, 0x8a, 0x46, 0x0c, 0x22,
- 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x11, 0x8e, 0x44, 0x08, 0x26, 0x8a, 0x05,
- 0x47, 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x88, 0x46, 0x00, 0xf6, 0xc4,
- 0x01, 0x75, 0x12, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x8b, 0x6c, 0x20, 0x8a,
- 0x66, 0x0a, 0xf6, 0xc4, 0x01, 0x74, 0x70, 0x90, 0xc6, 0x44, 0x49, 0x64, 0x8b,
- 0x7c, 0x12, 0x8e, 0x44, 0x10, 0x8a, 0x46, 0x00, 0x23, 0x44, 0x34, 0xff, 0x64,
- 0x06, 0xf6, 0xc4, 0x40, 0x74, 0x3a, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x44,
- 0x14, 0xeb, 0x30, 0x90, 0x90, 0x80, 0x7c, 0x53, 0x00, 0x75, 0x8c, 0xc7, 0x04,
- 0xe4, 0x18, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x19,
- 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0xd2, 0x8e, 0x44, 0x08, 0x26, 0x8a,
- 0x05, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x88, 0x46, 0x00, 0xf6,
- 0xc4, 0x01, 0x75, 0xa9, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x90, 0xff, 0x44,
- 0x30, 0x88, 0x46, 0x00, 0xf6, 0xc4, 0x01, 0x75, 0x97, 0x81, 0xc6, 0x80, 0x00,
- 0xff, 0x24, 0xfe, 0x4c, 0x49, 0x74, 0x06, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24,
- 0xc7, 0x04, 0x8b, 0x14, 0xc6, 0x46, 0x02, 0x01, 0x81, 0xc6, 0x80, 0x00, 0xff,
- 0x24, 0xb3, 0x1c, 0x22, 0x5c, 0x51, 0x75, 0x1a, 0xf6, 0x44, 0x29, 0x04, 0x74,
- 0x1c, 0xf6, 0x44, 0x29, 0x20, 0x75, 0x26, 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x18,
- 0xc7, 0x44, 0x06, 0x8f, 0x1a, 0xe9, 0x30, 0x01, 0xf6, 0xc3, 0x04, 0x75, 0x30,
- 0xeb, 0x27, 0x90, 0xc7, 0x44, 0x06, 0x99, 0x1a, 0xe9, 0x2a, 0x01, 0xc7, 0x44,
- 0x06, 0x8a, 0x1a, 0xe9, 0x13, 0x01, 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x08, 0xc7,
- 0x44, 0x06, 0xe3, 0x19, 0xeb, 0x5f, 0x90, 0xc7, 0x44, 0x06, 0xde, 0x19, 0xeb,
- 0x52, 0x90, 0x80, 0x64, 0x51, 0xf7, 0xe9, 0x05, 0x01, 0x80, 0x64, 0x53, 0xfc,
- 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0x80, 0x64, 0x54, 0xfb, 0xc7,
- 0x04, 0x44, 0x14, 0x80, 0x64, 0x51, 0xfb, 0xf6, 0x44, 0x29, 0x40, 0x75, 0x7e,
- 0x3a, 0x44, 0x5d, 0x74, 0x79, 0x3a, 0x44, 0x5c, 0x74, 0x74, 0xf6, 0x44, 0x29,
- 0x20, 0x74, 0x0a, 0x3a, 0x44, 0x5a, 0x74, 0x69, 0x3a, 0x44, 0x5b, 0x74, 0x64,
- 0xf6, 0x44, 0x5e, 0xff, 0x74, 0x09, 0x3a, 0x44, 0x5e, 0x75, 0x04, 0x80, 0x4c,
- 0x51, 0x08, 0xe9, 0xbb, 0x00, 0x3a, 0x44, 0x5e, 0x74, 0x73, 0x3a, 0x44, 0x5c,
- 0x74, 0x4e, 0x3a, 0x44, 0x5d, 0x74, 0x75, 0x3a, 0x44, 0x5a, 0x74, 0x08, 0x3a,
- 0x44, 0x5b, 0x74, 0x1e, 0xe9, 0x9f, 0x00, 0xf6, 0x44, 0x53, 0x02, 0x74, 0x0a,
- 0x80, 0x64, 0x53, 0xfd, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x3a, 0x44, 0x5b,
- 0x74, 0x06, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x80, 0x4c, 0x53, 0x02, 0xc7,
- 0x04, 0x44, 0x14, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x0d, 0x80, 0x4c, 0x51, 0x04,
- 0xc7, 0x44, 0x06, 0x3e, 0x19, 0xeb, 0x7a, 0x90, 0x90, 0x81, 0xc6, 0x80, 0x00,
- 0xff, 0x24, 0xf6, 0x44, 0x53, 0x01, 0x74, 0x12, 0x80, 0x64, 0x53, 0xfe, 0x80,
- 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0xc7, 0x04, 0x44, 0x14, 0xeb, 0xe2,
- 0x3a, 0x44, 0x5d, 0x74, 0x0f, 0xeb, 0xdb, 0x90, 0x80, 0x4c, 0x51, 0x08, 0xc7,
- 0x44, 0x06, 0x3e, 0x19, 0xeb, 0x38, 0x90, 0xf6, 0x44, 0x53, 0x01, 0x75, 0x40,
- 0x80, 0x4c, 0x53, 0x01, 0x80, 0x4c, 0x54, 0x04, 0x80, 0x4c, 0x58, 0x04, 0xc7,
- 0x04, 0x44, 0x14, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x2a, 0x80, 0x4c, 0x51, 0x04,
- 0xc7, 0x44, 0x06, 0x3e, 0x19, 0xeb, 0x1f, 0x90, 0x3a, 0x44, 0x5e, 0x74, 0xc7,
- 0x3a, 0x44, 0x5c, 0x74, 0xa2, 0x3a, 0x44, 0x5d, 0x74, 0xc9, 0x3d, 0xff, 0x00,
- 0x73, 0x20, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x74, 0x89,
- 0x7c, 0x12, 0x2b, 0x7c, 0x14, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x1c, 0x73,
- 0x57, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x90, 0x0a, 0xe4, 0x75, 0x20, 0xb3,
- 0x0c, 0x22, 0x5c, 0x28, 0x80, 0xfb, 0x08, 0x75, 0xd2, 0xaa, 0x81, 0xe7, 0xff,
- 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x46, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c,
- 0x14, 0x74, 0x3b, 0xeb, 0xc6, 0xf6, 0xc4, 0x10, 0x75, 0x7d, 0xf6, 0xc4, 0x02,
- 0x74, 0x0e, 0x80, 0x4c, 0x4f, 0x80, 0xfe, 0x44, 0x59, 0xf6, 0xc4, 0x04, 0x75,
- 0x02, 0xeb, 0xa4, 0xff, 0x06, 0xca, 0x59, 0xf6, 0x44, 0x28, 0x04, 0x75, 0xa4,
- 0xf6, 0x44, 0x28, 0x08, 0x75, 0x79, 0x32, 0xc0, 0xeb, 0x90, 0xf6, 0x44, 0x51,
- 0x02, 0x74, 0x1f, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x4f, 0x4f, 0x4f, 0x81,
- 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x12, 0x80, 0x4c, 0x59, 0x01, 0x80, 0x4c, 0x4f,
- 0x80, 0x80, 0x4c, 0x66, 0x01, 0xe9, 0x75, 0xff, 0x80, 0x4c, 0x51, 0x02, 0x8a,
- 0x44, 0x54, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46, 0x08,
- 0x08, 0x44, 0x58, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x10, 0x80, 0x4c, 0x54, 0x08,
- 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50, 0x08, 0xc7, 0x04, 0x44, 0x14, 0x81,
- 0xc6, 0x80, 0x00, 0xff, 0x24, 0x80, 0x4c, 0x66, 0x80, 0xf6, 0x44, 0x28, 0x01,
- 0x75, 0x0a, 0xf6, 0x44, 0x28, 0x02, 0x74, 0x07, 0x80, 0x4c, 0x4f, 0x01, 0xe9,
- 0x2d, 0xff, 0x32, 0xc0, 0xf6, 0x44, 0x28, 0x08, 0x74, 0x23, 0x26, 0xc6, 0x05,
- 0xff, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x22, 0xf6, 0x44,
- 0x29, 0x80, 0x75, 0x02, 0x32, 0xe4, 0x26, 0x88, 0x25, 0x47, 0x81, 0xe7, 0xff,
- 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x10, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c,
- 0x14, 0x74, 0x09, 0xe9, 0xf5, 0xfe, 0xe9, 0x66, 0xff, 0xe9, 0x62, 0xff, 0xe9,
- 0x5e, 0xff, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x4c, 0x44, 0x83, 0xc1,
- 0xb0, 0x72, 0x21, 0x8b, 0x54, 0x46, 0x8a, 0x5c, 0x50, 0xf6, 0xc3, 0x0e, 0x75,
- 0x2e, 0xf6, 0xc3, 0x40, 0x75, 0x1b, 0xf6, 0xc3, 0x10, 0x74, 0x1d, 0xf6, 0xc3,
- 0x01, 0x75, 0x0a, 0xc7, 0x04, 0xcb, 0x1f, 0xe9, 0xf1, 0x03, 0xe9, 0x1d, 0x04,
- 0xc7, 0x04, 0x83, 0x1c, 0xe9, 0x9f, 0x00, 0xc7, 0x04, 0xcd, 0x1c, 0xff, 0x64,
- 0x02, 0xc7, 0x04, 0x19, 0x20, 0xe9, 0x16, 0x04, 0xf6, 0xc3, 0x02, 0x75, 0x2d,
- 0xf6, 0xc3, 0x08, 0x75, 0x03, 0xeb, 0x50, 0x90, 0x80, 0x64, 0x50, 0xf7, 0xf6,
- 0x44, 0x51, 0x02, 0x74, 0x0c, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x06, 0x8a, 0x44,
- 0x5d, 0xeb, 0x04, 0x90, 0x8a, 0x44, 0x5c, 0x88, 0x46, 0x00, 0x03, 0xca, 0x72,
- 0x02, 0xeb, 0x9b, 0xe9, 0xd6, 0x03, 0x80, 0x4c, 0x67, 0x02, 0xf6, 0x44, 0x50,
- 0x04, 0x75, 0x20, 0x83, 0x7c, 0x24, 0xff, 0x74, 0x15, 0x8b, 0x1e, 0xbc, 0x59,
- 0x2b, 0x5c, 0x26, 0x81, 0xfb, 0xe8, 0x03, 0x77, 0x08, 0x80, 0x66, 0x06, 0xbf,
- 0x80, 0x64, 0x50, 0xfd, 0x33, 0xc9, 0xe9, 0xac, 0x03, 0xf6, 0xc4, 0x40, 0x74,
- 0x1a, 0x80, 0x4c, 0x67, 0x02, 0x80, 0x4e, 0x06, 0x40, 0x8b, 0x5c, 0x24, 0x03,
- 0x1e, 0xbc, 0x59, 0x89, 0x5c, 0x26, 0x80, 0x64, 0x50, 0xfb, 0x80, 0x4c, 0x50,
- 0x02, 0x33, 0xc9, 0xe9, 0x88, 0x03, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b,
- 0x4c, 0x44, 0x83, 0xc1, 0xb0, 0x72, 0x39, 0x8b, 0x54, 0x46, 0x8b, 0x7c, 0x0c,
- 0x3b, 0x7c, 0x0a, 0x74, 0x24, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44,
- 0x53, 0x75, 0x21, 0x8e, 0x44, 0x08, 0x26, 0x8a, 0x05, 0x47, 0x81, 0xe7, 0xff,
- 0x07, 0x8a, 0xd8, 0x22, 0x5c, 0x62, 0x32, 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7,
- 0x44, 0x12, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x19, 0x20, 0x33, 0xc9, 0xe9,
- 0x3e, 0x03, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x4c, 0x44, 0x83, 0xc1,
- 0xb0, 0x72, 0xef, 0x8b, 0x54, 0x46, 0xff, 0x64, 0x02, 0xf6, 0x44, 0x2a, 0x01,
- 0x75, 0x03, 0xe9, 0xaf, 0x02, 0xb0, 0x27, 0xe9, 0x58, 0x02, 0xf6, 0x44, 0x2a,
- 0x01, 0x75, 0x03, 0xe9, 0xa1, 0x02, 0xb0, 0x28, 0xe9, 0x4a, 0x02, 0xf6, 0x44,
- 0x2a, 0x01, 0x75, 0x03, 0xe9, 0x93, 0x02, 0xb0, 0x21, 0xe9, 0x3c, 0x02, 0xf6,
- 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0x85, 0x02, 0xb0, 0x29, 0xe9, 0x2e, 0x02,
- 0xf6, 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0x77, 0x02, 0xb0, 0x5e, 0xe9, 0x20,
- 0x02, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x40, 0x75, 0x03, 0xe9, 0x6c, 0x02,
- 0xbb, 0x7f, 0x00, 0xe9, 0x7c, 0x01, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x80,
- 0x75, 0xf1, 0xe9, 0x5a, 0x02, 0x88, 0x46, 0x00, 0x83, 0x7c, 0x30, 0x00, 0x74,
- 0x03, 0xff, 0x4c, 0x30, 0xf6, 0x44, 0x2b, 0x20, 0x75, 0x03, 0xe9, 0x45, 0x02,
- 0xbb, 0x02, 0x00, 0xe9, 0x55, 0x01, 0xb3, 0x18, 0x22, 0x5c, 0x2b, 0x75, 0x12,
- 0x88, 0x46, 0x00, 0x8b, 0x5c, 0x30, 0x83, 0xc3, 0x08, 0x80, 0xe3, 0xf8, 0x89,
- 0x5c, 0x30, 0xe9, 0x26, 0x02, 0x80, 0xfb, 0x18, 0x75, 0x50, 0x8b, 0x5c, 0x30,
- 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30, 0x89, 0x5c, 0x32, 0xc6,
- 0x46, 0x00, 0x20, 0xff, 0x4c, 0x32, 0x74, 0x30, 0x03, 0xca, 0x73, 0xf3, 0x80,
- 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7, 0x44, 0x02, 0xaa, 0x1d, 0xe9,
- 0x5e, 0x02, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x14,
- 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0x8e, 0x44, 0x08, 0x8b,
- 0x7c, 0x0c, 0xeb, 0xc7, 0xe9, 0xd6, 0x01, 0x33, 0xc9, 0xe9, 0x3d, 0x02, 0x88,
- 0x46, 0x00, 0x80, 0xfb, 0x08, 0x75, 0x14, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83,
- 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30, 0x83, 0xfb, 0x05, 0x7c, 0xdf, 0xe9, 0xcb,
- 0x00, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30,
- 0xbb, 0x02, 0x00, 0xe9, 0xb9, 0x00, 0xf6, 0x44, 0x2a, 0x20, 0x75, 0x1a, 0xf6,
- 0x44, 0x2a, 0x04, 0x74, 0x4a, 0xf6, 0x44, 0x2a, 0x10, 0x74, 0x06, 0x83, 0x7c,
- 0x30, 0x00, 0x74, 0x08, 0xc6, 0x46, 0x00, 0x0d, 0x03, 0xca, 0x72, 0x05, 0xb0,
- 0x0a, 0xeb, 0x57, 0x90, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7,
- 0x44, 0x02, 0x31, 0x1e, 0xe9, 0xd7, 0x01, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52,
- 0x3a, 0x44, 0x53, 0x75, 0x11, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89,
- 0x1c, 0x8e, 0x44, 0x08, 0x8b, 0x7c, 0x0c, 0xeb, 0xcf, 0x33, 0xc9, 0xe9, 0xb9,
- 0x01, 0xc6, 0x46, 0x00, 0x0a, 0xf6, 0x44, 0x2b, 0x01, 0x75, 0x03, 0xe9, 0x40,
- 0x01, 0xbb, 0x05, 0x00, 0xeb, 0x51, 0x90, 0xf6, 0x44, 0x2a, 0x08, 0x75, 0xe7,
- 0xf6, 0x44, 0x2a, 0x10, 0x74, 0x06, 0x83, 0x7c, 0x30, 0x00, 0x74, 0x0f, 0x88,
- 0x46, 0x00, 0xb3, 0x06, 0x22, 0x5c, 0x2b, 0x75, 0x08, 0xc7, 0x44, 0x30, 0x00,
- 0x00, 0xe9, 0x16, 0x01, 0x80, 0xfb, 0x02, 0x75, 0x14, 0x8b, 0x5c, 0x30, 0xc1,
- 0xeb, 0x04, 0x83, 0xc3, 0x03, 0x83, 0xfb, 0x06, 0x72, 0x14, 0xbb, 0x06, 0x00,
- 0xeb, 0x0f, 0x90, 0x80, 0xfb, 0x04, 0x75, 0x06, 0xbb, 0x05, 0x00, 0xeb, 0x04,
- 0x90, 0xbb, 0x09, 0x00, 0xc7, 0x44, 0x30, 0x00, 0x00, 0xf6, 0x44, 0x2a, 0x40,
- 0x74, 0x54, 0x83, 0xfb, 0x20, 0x77, 0x4f, 0xc1, 0xeb, 0x02, 0x74, 0x03, 0xbb,
- 0x01, 0x00, 0x43, 0x89, 0x5c, 0x32, 0x03, 0xca, 0x72, 0x0e, 0x8a, 0x44, 0x60,
- 0x88, 0x46, 0x00, 0xff, 0x4c, 0x32, 0x75, 0xf1, 0xe9, 0xc1, 0x00, 0x80, 0x4c,
- 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7, 0x44, 0x02, 0xee, 0x1e, 0xe9, 0x1a,
- 0x01, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x11, 0x80,
- 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0x8e, 0x44, 0x08, 0x8b, 0x7c,
- 0x0c, 0xeb, 0xc6, 0x33, 0xc9, 0xe9, 0xfc, 0x00, 0x83, 0xc3, 0x06, 0xc1, 0xe3,
- 0x03, 0x89, 0x5c, 0x32, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7,
- 0x44, 0x02, 0x2e, 0x1f, 0x03, 0xca, 0x72, 0x02, 0x33, 0xc9, 0xe9, 0xda, 0x00,
- 0xff, 0x4c, 0x32, 0x75, 0x09, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89,
- 0x1c, 0x33, 0xc9, 0xe9, 0xca, 0x00, 0xf6, 0x44, 0x2a, 0x01, 0x74, 0x52, 0x88,
- 0x44, 0x61, 0xb0, 0x5c, 0x88, 0x46, 0x00, 0x83, 0x44, 0x30, 0x02, 0x03, 0xca,
- 0x72, 0x06, 0x8a, 0x44, 0x61, 0xeb, 0x40, 0x90, 0x80, 0x4c, 0x50, 0x40, 0xc7,
- 0x04, 0xcd, 0x1c, 0xc7, 0x44, 0x02, 0x6d, 0x1f, 0xe9, 0x9b, 0x00, 0x8a, 0x46,
- 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x11, 0x80, 0x64, 0x50, 0xbf,
- 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0x8e, 0x44, 0x08, 0x8b, 0x7c, 0x0c, 0xeb, 0xce,
- 0x33, 0xc9, 0xeb, 0x7e, 0x90, 0x2c, 0x20, 0xeb, 0x07, 0x90, 0xf6, 0x44, 0x2a,
- 0x02, 0x75, 0xf5, 0xff, 0x44, 0x30, 0x88, 0x46, 0x00, 0x03, 0xca, 0x72, 0x65,
- 0x3b, 0x7c, 0x0a, 0x74, 0x5e, 0x26, 0x8a, 0x05, 0x47, 0x81, 0xe7, 0xff, 0x07,
- 0x8a, 0xd8, 0x22, 0x5c, 0x62, 0x32, 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7, 0x44,
- 0x12, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x19, 0x20, 0x33, 0xc9, 0xeb, 0x41,
- 0x90, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x4c, 0x44, 0x83, 0xc1, 0xb0,
- 0x72, 0x32, 0x8b, 0x54, 0x46, 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0xda,
- 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x17, 0x8e, 0x44,
- 0x08, 0x26, 0x8a, 0x05, 0x88, 0x46, 0x00, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x03,
- 0xca, 0x72, 0x07, 0x3b, 0x7c, 0x0a, 0x75, 0xec, 0x33, 0xc9, 0x89, 0x7c, 0x0c,
- 0x89, 0x4c, 0x44, 0xf6, 0xc4, 0x01, 0x75, 0x17, 0x81, 0xc6, 0x80, 0x00, 0xff,
- 0x24, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x01, 0x75, 0x06, 0x81,
- 0xc6, 0x80, 0x00, 0xff, 0x24, 0x8b, 0x7c, 0x12, 0x8e, 0x44, 0x10, 0x8a, 0x46,
- 0x00, 0x23, 0x44, 0x34, 0xff, 0x64, 0x06, 0xb3, 0x0c, 0x22, 0x5c, 0x51, 0x75,
- 0x40, 0xf6, 0x44, 0x29, 0x04, 0x74, 0x14, 0xf6, 0x44, 0x29, 0x20, 0x75, 0x1e,
- 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x10, 0xc7, 0x44, 0x06, 0x6a, 0x21, 0xe9, 0x10,
- 0x01, 0xc7, 0x44, 0x06, 0x74, 0x21, 0xe9, 0x12, 0x01, 0xc7, 0x44, 0x06, 0x65,
- 0x21, 0xe9, 0xfb, 0x00, 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x08, 0xc7, 0x44, 0x06,
- 0xd6, 0x20, 0xeb, 0x5f, 0x90, 0xc7, 0x44, 0x06, 0xd1, 0x20, 0xeb, 0x52, 0x90,
- 0xf6, 0xc3, 0x04, 0x75, 0x07, 0x80, 0x64, 0x51, 0xf7, 0xe9, 0xe8, 0x00, 0x80,
- 0x64, 0x53, 0xfc, 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0x80, 0x64,
- 0x51, 0xfb, 0xf6, 0x44, 0x29, 0x40, 0x75, 0x2c, 0x3a, 0x44, 0x5d, 0x74, 0x27,
- 0x3a, 0x44, 0x5c, 0x74, 0x22, 0xf6, 0x44, 0x29, 0x20, 0x74, 0x0a, 0x3a, 0x44,
- 0x5a, 0x74, 0x17, 0x3a, 0x44, 0x5b, 0x74, 0x12, 0x80, 0x7c, 0x5e, 0x00, 0x74,
- 0x09, 0x3a, 0x44, 0x5e, 0x75, 0x04, 0x80, 0x4c, 0x51, 0x08, 0xe9, 0xa6, 0x00,
- 0xe9, 0xb2, 0x00, 0x3a, 0x44, 0x5e, 0x74, 0x5f, 0x3a, 0x44, 0x5c, 0x74, 0x3d,
- 0x3a, 0x44, 0x5d, 0x74, 0x61, 0x3a, 0x44, 0x5a, 0x74, 0x08, 0x3a, 0x44, 0x5b,
- 0x74, 0x18, 0xe9, 0x87, 0x00, 0xf6, 0x44, 0x53, 0x02, 0x74, 0x07, 0x80, 0x64,
- 0x53, 0xfd, 0xe9, 0x89, 0x00, 0x3a, 0x44, 0x5b, 0x74, 0x03, 0xe9, 0x81, 0x00,
- 0x80, 0x4c, 0x53, 0x02, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x09, 0x80, 0x4c, 0x51,
- 0x04, 0xc7, 0x44, 0x06, 0x39, 0x20, 0xeb, 0x6c, 0x90, 0xf6, 0x44, 0x53, 0x01,
- 0x74, 0x0f, 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0x80, 0x64, 0x53,
- 0xfe, 0xeb, 0x57, 0x90, 0x3a, 0x44, 0x5d, 0x74, 0x0f, 0xeb, 0x4f, 0x90, 0x80,
- 0x4c, 0x51, 0x08, 0xc7, 0x44, 0x06, 0x39, 0x20, 0xeb, 0x34, 0x90, 0xf6, 0x44,
- 0x53, 0x01, 0x75, 0x1b, 0x80, 0x4c, 0x53, 0x01, 0x80, 0x4c, 0x54, 0x04, 0x80,
- 0x4c, 0x58, 0x04, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x09, 0x80, 0x4c, 0x51, 0x04,
- 0xc7, 0x44, 0x06, 0x39, 0x20, 0xeb, 0x1f, 0x90, 0x3a, 0x44, 0x5e, 0x74, 0xcb,
- 0x3a, 0x44, 0x5c, 0x74, 0xa9, 0x3a, 0x44, 0x5d, 0x74, 0xcd, 0x3d, 0xff, 0x00,
- 0x73, 0x3b, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x55, 0x8a,
- 0x66, 0x0a, 0xf6, 0xc4, 0x01, 0x74, 0x0e, 0x8a, 0x46, 0x00, 0x23, 0x44, 0x34,
- 0xff, 0x64, 0x06, 0x0a, 0x66, 0x0a, 0xeb, 0xf2, 0xf6, 0x46, 0x04, 0x01, 0x74,
- 0xf5, 0x89, 0x7c, 0x12, 0x2b, 0x7c, 0x14, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c,
- 0x1c, 0x73, 0x63, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x0a, 0xe4, 0x75, 0x23,
- 0xb3, 0x0c, 0x22, 0x5c, 0x28, 0x80, 0xfb, 0x08, 0x75, 0xb7, 0xaa, 0x81, 0xe7,
- 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x53, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b,
- 0x7c, 0x14, 0x74, 0x48, 0xeb, 0xab, 0xeb, 0x45, 0x90, 0xf6, 0xc4, 0x10, 0x75,
- 0x28, 0xf6, 0xc4, 0x02, 0x74, 0x0e, 0x80, 0x4c, 0x4f, 0x80, 0xfe, 0x44, 0x59,
- 0xf6, 0xc4, 0x04, 0x75, 0x02, 0xeb, 0x86, 0xff, 0x06, 0xca, 0x59, 0xf6, 0x44,
- 0x28, 0x04, 0x75, 0x0e, 0xf6, 0x44, 0x28, 0x08, 0x75, 0x0b, 0x32, 0xc0, 0xe9,
- 0x71, 0xff, 0xeb, 0x5f, 0x90, 0xe9, 0x75, 0xff, 0xeb, 0x7c, 0x90, 0xf6, 0x44,
- 0x51, 0x02, 0x74, 0x1f, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x4f, 0x4f, 0x4f,
- 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x12, 0x80, 0x4c, 0x59, 0x01, 0x80, 0x4c,
- 0x4f, 0x80, 0x80, 0x4c, 0x66, 0x01, 0xe9, 0x4d, 0xff, 0x80, 0x4c, 0x51, 0x02,
- 0x8a, 0x44, 0x54, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46,
- 0x08, 0x08, 0x44, 0x58, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x12, 0x80, 0x4c, 0x54,
- 0x08, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50, 0x08, 0x8b, 0x1e, 0x40, 0x60,
- 0x89, 0x1c, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0xff, 0x06, 0xcc, 0x59, 0x80,
- 0x4c, 0x66, 0x80, 0xf6, 0x44, 0x28, 0x01, 0x75, 0x0a, 0xf6, 0x44, 0x28, 0x02,
- 0x74, 0x07, 0x80, 0x4c, 0x4f, 0x01, 0xe9, 0xff, 0xfe, 0x32, 0xc0, 0xf6, 0x44,
- 0x28, 0x08, 0x74, 0x23, 0x26, 0xc6, 0x05, 0xff, 0x47, 0x81, 0xe7, 0xff, 0x07,
- 0x3b, 0x7c, 0x14, 0x74, 0x22, 0xf6, 0x44, 0x29, 0x80, 0x75, 0x02, 0x32, 0xe4,
- 0x26, 0x88, 0x25, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x10,
- 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x09, 0xe9, 0xc7, 0xfe,
- 0xe9, 0x60, 0xff, 0xe9, 0x5c, 0xff, 0xe9, 0x58, 0xff, 0x50, 0x55, 0x36, 0x8a,
- 0x26, 0x00, 0xf3, 0xbd, 0x80, 0x53, 0xeb, 0x1b, 0x90, 0x50, 0x55, 0x36, 0x8a,
- 0x26, 0x01, 0xf3, 0xbd, 0x80, 0x57, 0xeb, 0x0e, 0x90, 0xbd, 0x80, 0x57, 0x0a,
- 0xe4, 0x75, 0x06, 0x81, 0xed, 0x00, 0x04, 0x8a, 0xe0, 0xf6, 0xc4, 0xf0, 0x75,
- 0x07, 0x81, 0xed, 0x00, 0x02, 0xc0, 0xe4, 0x04, 0xf6, 0xc4, 0xc0, 0x75, 0x08,
- 0x81, 0xed, 0x00, 0x01, 0x02, 0xe4, 0x02, 0xe4, 0x78, 0x04, 0x81, 0xed, 0x80,
- 0x00, 0xc7, 0x46, 0x00, 0x44, 0x14, 0xc6, 0x46, 0x49, 0x01, 0x8b, 0x6e, 0x20,
- 0xc6, 0x46, 0x02, 0x00, 0x36, 0xa1, 0x00, 0xf3, 0x0b, 0xc0, 0x75, 0xbc, 0xb8,
- 0x00, 0x80, 0xe7, 0x22, 0x5d, 0x58, 0xcf, 0x50, 0x36, 0x83, 0x06, 0xbc, 0x59,
- 0x02, 0x36, 0xff, 0x06, 0xd6, 0xc3, 0x36, 0x81, 0x3e, 0xd6, 0xc3, 0x88, 0x13,
- 0x73, 0x04, 0x33, 0xc0, 0xe7, 0x58, 0xb8, 0x00, 0x80, 0xe7, 0x22, 0x58, 0xcf,
- 0x60, 0x1e, 0x06, 0x8c, 0xd0, 0x8e, 0xd8, 0xfb, 0xbe, 0x00, 0x50, 0xff, 0x24,
- 0xfa, 0xb8, 0x08, 0x00, 0xe7, 0x22, 0xb8, 0x00, 0xe0, 0xe7, 0x66, 0xff, 0x0e,
- 0x3e, 0x60, 0x75, 0x22, 0xc7, 0x06, 0x3e, 0x60, 0x04, 0x00, 0x8b, 0x36, 0x30,
- 0x60, 0x8b, 0x6c, 0x20, 0x8a, 0x46, 0x0c, 0x32, 0x44, 0x54, 0x24, 0xf0, 0x30,
- 0x44, 0x54, 0x08, 0x44, 0x58, 0x03, 0x74, 0x1e, 0x89, 0x36, 0x30, 0x60, 0x07,
- 0x1f, 0x61, 0xcf, 0x60, 0x1e, 0x06, 0x8c, 0xd0, 0x8e, 0xd8, 0xff, 0x06, 0xd6,
- 0xc3, 0x81, 0x3e, 0xd6, 0xc3, 0xa0, 0x05, 0x73, 0x04, 0x33, 0xc0, 0xe7, 0x58,
- 0xb8, 0xfe, 0xff, 0xe7, 0x52, 0xb8, 0x08, 0x00, 0xe7, 0x22, 0xe5, 0x58, 0xa3,
- 0xc0, 0x59, 0x83, 0x06, 0xbc, 0x59, 0x00, 0x81, 0x2e, 0x3c, 0x60, 0xe8, 0x03,
- 0x73, 0x0a, 0xff, 0x06, 0xbc, 0x59, 0x81, 0x06, 0x3c, 0x60, 0xa0, 0x05, 0xbe,
- 0x00, 0x50, 0xff, 0x24, 0x8b, 0x36, 0x30, 0x60, 0x8b, 0x6c, 0x20, 0x8a, 0x46,
- 0x0c, 0x32, 0x44, 0x54, 0x24, 0xf0, 0x30, 0x44, 0x54, 0x08, 0x44, 0x58, 0x03,
- 0x74, 0x1e, 0x89, 0x36, 0x30, 0x60, 0xe5, 0x50, 0x8b, 0xd8, 0xc1, 0xe8, 0x02,
- 0x03, 0xd8, 0x89, 0x1e, 0xc2, 0x59, 0xa1, 0xbe, 0x59, 0x2b, 0xd8, 0xc1, 0xfb,
- 0x02, 0x03, 0xc3, 0x3d, 0xc0, 0x03, 0x77, 0x03, 0xb8, 0xc0, 0x03, 0xa3, 0xbe,
- 0x59, 0x3d, 0x00, 0x05, 0x77, 0x03, 0xb8, 0x00, 0x05, 0xe7, 0x52, 0x8b, 0xd8,
- 0xa3, 0xc4, 0x59, 0xe5, 0x50, 0x3b, 0xc3, 0x72, 0x0e, 0x89, 0x1e, 0xc6, 0x59,
- 0xa3, 0xc8, 0x59, 0x33, 0xc0, 0xe7, 0x50, 0xe9, 0x74, 0xff, 0x07, 0x1f, 0x61,
- 0xcf, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x89, 0x3e, 0x32, 0x60,
- 0x8b, 0x56, 0x06, 0x03, 0xd7, 0x89, 0x16, 0x34, 0x60, 0xc7, 0x06, 0x4a, 0x60,
- 0x4c, 0x60, 0x8c, 0xda, 0x8e, 0xc2, 0x80, 0x3e, 0x6c, 0x60, 0x00, 0x74, 0x33,
- 0xb8, 0xf4, 0xb3, 0xab, 0xb8, 0xc3, 0x95, 0xab, 0xbe, 0x6c, 0x60, 0xb9, 0x0a,
- 0x00, 0xf3, 0xa4, 0x32, 0xdb, 0x86, 0x1e, 0x6c, 0x60, 0x80, 0xfb, 0x02, 0x74,
- 0x18, 0x8b, 0x0e, 0x74, 0x60, 0x8b, 0x36, 0x70, 0x60, 0xa1, 0x71, 0x60, 0x81,
- 0xe6, 0xff, 0x00, 0xc1, 0xe0, 0x04, 0x8e, 0xd8, 0xf3, 0xa4, 0x8e, 0xda, 0xeb,
- 0x41, 0x90, 0xc7, 0x44, 0x2e, 0x00, 0x00, 0xb0, 0xb0, 0x02, 0x44, 0x65, 0xb4,
- 0x01, 0x89, 0x05, 0xb8, 0xff, 0x07, 0x89, 0x45, 0x02, 0x83, 0xc7, 0x04, 0xeb,
- 0x36, 0x90, 0xb0, 0xc0, 0x02, 0x44, 0x65, 0xfa, 0x32, 0xe4, 0x86, 0x64, 0x4f,
- 0x89, 0x05, 0x8a, 0x44, 0x57, 0x32, 0x44, 0x58, 0x88, 0x44, 0x57, 0x88, 0x45,
- 0x02, 0x32, 0x44, 0x54, 0x88, 0x44, 0x58, 0xfb, 0x83, 0xc7, 0x03, 0xeb, 0x18,
- 0x90, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00, 0x50, 0x8b, 0x54, 0x2e, 0x83, 0xfa,
- 0x00, 0x75, 0xb1, 0x8a, 0x44, 0x4f, 0x0a, 0x44, 0x58, 0x75, 0xc3, 0x8b, 0x44,
- 0x38, 0x8b, 0x5c, 0x0a, 0x2b, 0x5c, 0x0c, 0x81, 0xe3, 0xff, 0x07, 0x75, 0x0c,
- 0x3b, 0x44, 0x3a, 0x74, 0x18, 0xf6, 0x44, 0x50, 0x16, 0x74, 0x3d, 0x43, 0x2b,
- 0xc3, 0x8b, 0xd8, 0x2b, 0x5c, 0x3a, 0xba, 0xff, 0x07, 0xc1, 0xea, 0x02, 0x3b,
- 0xda, 0x77, 0x2b, 0x8b, 0x5c, 0x42, 0x8b, 0x44, 0x3c, 0x2b, 0x44, 0x3e, 0x25,
- 0xff, 0xff, 0x2b, 0xd8, 0x8b, 0x44, 0x12, 0x2b, 0x44, 0x14, 0x25, 0xff, 0x07,
- 0x3b, 0xc3, 0x72, 0x02, 0x8b, 0xc3, 0x3d, 0x00, 0x00, 0x75, 0x1b, 0x81, 0xc6,
- 0x80, 0x00, 0xe2, 0x9c, 0xeb, 0x46, 0x90, 0xb3, 0xa0, 0x02, 0x5c, 0x65, 0x88,
- 0x1d, 0x89, 0x45, 0x01, 0x89, 0x44, 0x3a, 0x83, 0xc7, 0x03, 0xeb, 0xc3, 0x3d,
- 0xf4, 0x01, 0x72, 0x03, 0xb8, 0xf4, 0x01, 0x89, 0x44, 0x40, 0x57, 0x8b, 0x1e,
- 0x4a, 0x60, 0x81, 0xfb, 0x4c, 0x60, 0x74, 0x13, 0x8b, 0x7f, 0xfe, 0x3b, 0x45,
- 0x40, 0x73, 0x0b, 0x89, 0x3f, 0x83, 0xeb, 0x02, 0x81, 0xfb, 0x4c, 0x60, 0x75,
- 0xed, 0x89, 0x37, 0x83, 0x06, 0x4a, 0x60, 0x02, 0x5f, 0xeb, 0xb2, 0x8b, 0x0e,
- 0x4a, 0x60, 0x81, 0xe9, 0x4c, 0x60, 0xd1, 0xe9, 0x74, 0x09, 0xa1, 0x34, 0x60,
- 0x2b, 0xc7, 0x2b, 0xc1, 0x7f, 0x03, 0xe9, 0xfb, 0x00, 0xa3, 0x36, 0x60, 0xc7,
- 0x06, 0x38, 0x60, 0x00, 0x00, 0xbb, 0x4c, 0x60, 0x8b, 0x37, 0x83, 0x3e, 0x36,
- 0x60, 0x00, 0x74, 0x2f, 0x8b, 0x44, 0x40, 0x2b, 0x06, 0x38, 0x60, 0xf7, 0xe1,
- 0x3b, 0x06, 0x36, 0x60, 0x77, 0x0d, 0x29, 0x06, 0x36, 0x60, 0x8b, 0x44, 0x40,
- 0xa3, 0x38, 0x60, 0xeb, 0x14, 0x90, 0x33, 0xd2, 0xa1, 0x36, 0x60, 0x48, 0xf7,
- 0xf1, 0x40, 0x01, 0x06, 0x38, 0x60, 0xc7, 0x06, 0x36, 0x60, 0x00, 0x00, 0x51,
- 0x8b, 0x0e, 0x38, 0x60, 0x8a, 0x44, 0x65, 0x83, 0xf9, 0x08, 0x77, 0x10, 0x8a,
- 0xe1, 0xfe, 0xcc, 0xc0, 0xe4, 0x04, 0x80, 0xc4, 0x00, 0x02, 0xc4, 0xaa, 0xeb,
- 0x15, 0x90, 0x81, 0xf9, 0xff, 0x00, 0x77, 0x08, 0x0c, 0x80, 0x8a, 0xe1, 0xab,
- 0xeb, 0x07, 0x90, 0x0c, 0x90, 0xaa, 0x8b, 0xc1, 0xab, 0x51, 0x8b, 0x44, 0x14,
- 0xba, 0xff, 0x07, 0x42, 0x2b, 0xd0, 0x8e, 0x5c, 0x10, 0x3b, 0xca, 0x72, 0x0d,
- 0x2b, 0xca, 0x96, 0x87, 0xca, 0xf3, 0xa4, 0x8b, 0xf0, 0x33, 0xc0, 0x8b, 0xca,
- 0x96, 0xf3, 0xa4, 0x96, 0x8c, 0xc1, 0x8e, 0xd9, 0xfa, 0x59, 0x01, 0x4c, 0x3c,
- 0x89, 0x44, 0x14, 0xf6, 0x44, 0x51, 0x02, 0x74, 0x47, 0x8b, 0x44, 0x12, 0x2b,
- 0x44, 0x14, 0x25, 0xff, 0x07, 0x3b, 0x44, 0x1a, 0x77, 0x39, 0x80, 0x64, 0x51,
- 0xfd, 0x55, 0x8b, 0x6c, 0x20, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x17, 0x80, 0x64,
- 0x54, 0xf7, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50, 0x08, 0xa0, 0x2f, 0x60,
- 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0x8a, 0x44, 0x54, 0xf6, 0xd0,
- 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46, 0x08, 0x08, 0x44,
- 0x58, 0x5d, 0xfb, 0x83, 0xc3, 0x02, 0x59, 0x49, 0x74, 0x03, 0xe9, 0x11, 0xff,
- 0x2b, 0x3e, 0x32, 0x60, 0x8b, 0xc7, 0x5f, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x89, 0x3e, 0x32, 0x60, 0x8b, 0x56, 0x06, 0x03,
- 0xd7, 0x89, 0x16, 0x34, 0x60, 0xc6, 0x06, 0x77, 0x60, 0x00, 0x3b, 0x3e, 0x34,
- 0x60, 0x73, 0x1c, 0x8a, 0x25, 0x8b, 0xf0, 0x81, 0xe6, 0x00, 0x0f, 0xd1, 0xee,
- 0x81, 0xc6, 0x00, 0x50, 0x8a, 0xdc, 0x81, 0xe3, 0xf0, 0x00, 0xc1, 0xeb, 0x03,
- 0x2e, 0xff, 0xa7, 0xec, 0x26, 0x74, 0x06, 0xb8, 0x0e, 0x00, 0xeb, 0x03, 0x90,
- 0x33, 0xc0, 0x5f, 0x5e, 0x5d, 0xc3, 0x0d, 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x0d,
- 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x1a, 0x27, 0x25, 0x27,
- 0x96, 0x27, 0xac, 0x27, 0x9b, 0x28, 0x9b, 0x28, 0x9b, 0x28, 0xc9, 0x27, 0xc3,
- 0x8a, 0xcc, 0xc0, 0xe9, 0x04, 0x83, 0xe1, 0x07, 0x41, 0x47, 0xeb, 0x12, 0x90,
- 0x8a, 0x4d, 0x01, 0x32, 0xed, 0x83, 0xc7, 0x02, 0xeb, 0x07, 0x90, 0x8b, 0x4d,
- 0x01, 0x83, 0xc7, 0x03, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x74, 0x04, 0x03, 0xf9,
- 0xeb, 0x86, 0x01, 0x4c, 0x38, 0x8b, 0x5c, 0x0a, 0x8b, 0x54, 0x0c, 0x2b, 0xd3,
- 0x4a, 0x81, 0xe2, 0xff, 0x07, 0x3b, 0xca, 0x76, 0x05, 0xb8, 0x0d, 0x00, 0xeb,
- 0x99, 0x8e, 0x44, 0x08, 0xba, 0xff, 0x07, 0x42, 0x2b, 0xd3, 0x3b, 0xca, 0x72,
- 0x12, 0x2b, 0xca, 0x87, 0xf7, 0x87, 0xfb, 0x87, 0xca, 0xf3, 0xa4, 0x87, 0xfb,
- 0x87, 0xf7, 0x8b, 0xca, 0x33, 0xdb, 0x87, 0xf7, 0x87, 0xfb, 0xf3, 0xa4, 0x87,
- 0xfb, 0x87, 0xf7, 0x89, 0x5c, 0x0a, 0xf6, 0x44, 0x50, 0x10, 0x75, 0x12, 0x80,
- 0x4c, 0x50, 0x10, 0x8b, 0x6c, 0x20, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1,
- 0x40, 0x60, 0x89, 0x04, 0xe9, 0x26, 0xff, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x75,
- 0x09, 0x8b, 0x6c, 0x20, 0x8b, 0x45, 0x01, 0x89, 0x44, 0x3e, 0x83, 0xc7, 0x03,
- 0xe9, 0x10, 0xff, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x75, 0x10, 0x8b, 0x6c, 0x20,
- 0x8a, 0x5d, 0x01, 0x83, 0xe3, 0x0f, 0xd0, 0xe3, 0x2e, 0xff, 0xa7, 0xa1, 0x28,
- 0x83, 0xc7, 0x04, 0xe9, 0xf3, 0xfe, 0x80, 0x3d, 0xf4, 0x74, 0x5f, 0x80, 0x3d,
- 0xfe, 0x74, 0x48, 0x80, 0x3d, 0xff, 0x74, 0x46, 0x80, 0x3d, 0xf0, 0x75, 0x0b,
- 0xc6, 0x06, 0x77, 0x60, 0x00, 0x83, 0xc7, 0x01, 0xe9, 0xd4, 0xfe, 0x80, 0x3d,
- 0xf1, 0x75, 0x0b, 0xc6, 0x06, 0x77, 0x60, 0x01, 0x83, 0xc7, 0x01, 0xe9, 0xc4,
- 0xfe, 0x80, 0x3d, 0xf2, 0x75, 0x0b, 0xc6, 0x06, 0x77, 0x60, 0x02, 0x83, 0xc7,
- 0x01, 0xe9, 0xb4, 0xfe, 0x80, 0x3d, 0xf3, 0x75, 0x0b, 0xc6, 0x06, 0x77, 0x60,
- 0x03, 0x83, 0xc7, 0x01, 0xe9, 0xa4, 0xfe, 0xe9, 0x80, 0x00, 0xe9, 0xc8, 0xfe,
- 0x83, 0xc7, 0x01, 0xe9, 0x98, 0xfe, 0x83, 0xc7, 0x04, 0x03, 0x7d, 0x08, 0xe9,
- 0x8f, 0xfe, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x75, 0xf0, 0x80, 0x3d, 0xff, 0x75,
- 0x04, 0x47, 0xe9, 0x7f, 0xfe, 0x81, 0x3d, 0xf4, 0xb3, 0x75, 0x13, 0x81, 0x7d,
- 0x02, 0xc3, 0x95, 0x75, 0x0c, 0x83, 0xc7, 0x04, 0x8b, 0x4d, 0x08, 0x81, 0xf9,
- 0x80, 0x00, 0x76, 0x06, 0xb8, 0x0c, 0x00, 0xe9, 0x8c, 0xfe, 0x8c, 0xd8, 0x8e,
- 0xc0, 0x8b, 0xf7, 0xbf, 0x6c, 0x60, 0xb9, 0x0a, 0x00, 0xf3, 0xa4, 0x80, 0x3e,
- 0x6c, 0x60, 0x02, 0x75, 0x1b, 0x8b, 0x0e, 0x74, 0x60, 0x8b, 0x3e, 0x70, 0x60,
- 0xa1, 0x71, 0x60, 0x81, 0xe7, 0xff, 0x00, 0xc1, 0xe0, 0x04, 0x8e, 0xc0, 0xfa,
- 0xf3, 0xa4, 0xfb, 0xeb, 0x0b, 0x90, 0x80, 0x3e, 0x6c, 0x60, 0x04, 0x75, 0x03,
- 0xe8, 0xa0, 0xdf, 0x8b, 0xfe, 0xe9, 0x21, 0xfe, 0xb8, 0x0a, 0x00, 0xe9, 0x47,
- 0xfe, 0x26, 0x29, 0xe1, 0x29, 0xed, 0x29, 0x09, 0x2a, 0x25, 0x2a, 0x5b, 0x2a,
- 0x02, 0x2b, 0x4e, 0x2b, 0xf2, 0x2b, 0xa3, 0x2b, 0x24, 0x2c, 0x70, 0x2c, 0x36,
- 0x2c, 0x7f, 0x2c, 0x8e, 0x2c, 0x94, 0x2c, 0xfa, 0xe8, 0xd5, 0x03, 0xfb, 0x8b,
- 0x55, 0x02, 0xeb, 0x62, 0x90, 0xfa, 0x80, 0x4c, 0x53, 0x01, 0x80, 0x4c, 0x54,
- 0x04, 0x80, 0x4c, 0x58, 0x04, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0x8b, 0x1e,
- 0x40, 0x60, 0x89, 0x1c, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x0b, 0x80, 0x4c, 0x51,
- 0x04, 0x8b, 0x1e, 0x46, 0x60, 0x89, 0x5c, 0x06, 0xfb, 0xeb, 0x38, 0x90, 0xfa,
- 0x80, 0x64, 0x53, 0xfe, 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0xa0,
- 0x2f, 0x60, 0x88, 0x46, 0x02, 0x8b, 0x1e, 0x40, 0x60, 0x89, 0x1c, 0x80, 0x64,
- 0x51, 0xfb, 0xfb, 0xeb, 0x1b, 0x90, 0x80, 0x4c, 0x4f, 0x40, 0xfb, 0x83, 0xc7,
- 0x04, 0xe9, 0x96, 0xfd, 0x8a, 0x45, 0x02, 0xa8, 0x01, 0x75, 0x94, 0xa8, 0x40,
- 0x75, 0x9b, 0xa8, 0x80, 0x75, 0xc5, 0xa8, 0x10, 0x75, 0x0e, 0xa8, 0x20, 0x75,
- 0x57, 0xa8, 0x02, 0x75, 0xda, 0x83, 0xc7, 0x04, 0xe9, 0x75, 0xfd, 0xfa, 0xf6,
- 0x44, 0x51, 0x02, 0x75, 0x40, 0x8b, 0x44, 0x12, 0x2b, 0x44, 0x14, 0x25, 0xff,
- 0x07, 0x3b, 0x44, 0x1a, 0x72, 0x32, 0x80, 0x4c, 0x51, 0x02, 0xf6, 0x44, 0x29,
- 0x10, 0x74, 0x17, 0x80, 0x4c, 0x54, 0x08, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74,
- 0x50, 0x08, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04,
- 0x8a, 0x44, 0x54, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46,
- 0x08, 0x08, 0x44, 0x58, 0x8a, 0x45, 0x02, 0xfb, 0xeb, 0xa5, 0xfa, 0xf6, 0x44,
- 0x51, 0x02, 0x74, 0x42, 0x8b, 0x44, 0x12, 0x2b, 0x44, 0x14, 0x25, 0xff, 0x07,
- 0x3b, 0x44, 0x1c, 0x77, 0xe5, 0x80, 0x64, 0x51, 0xfd, 0xf6, 0x44, 0x29, 0x10,
- 0x74, 0x17, 0x80, 0x64, 0x54, 0xf7, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50,
- 0x08, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0x8a,
- 0x44, 0x54, 0xf6, 0xd0, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30,
- 0x46, 0x08, 0x08, 0x44, 0x58, 0xfb, 0xe9, 0x5c, 0xff, 0x8b, 0x45, 0x02, 0x89,
- 0x44, 0x42, 0x83, 0xc7, 0x04, 0xe9, 0xcf, 0xfc, 0x8b, 0x45, 0x02, 0x51, 0x52,
- 0x33, 0xd2, 0xb9, 0x00, 0x08, 0xf7, 0xe1, 0xb9, 0x00, 0x80, 0xf7, 0xf1, 0x5a,
- 0x59, 0x89, 0x44, 0x1a, 0x83, 0xc7, 0x04, 0xe9, 0xb3, 0xfc, 0x8b, 0x45, 0x02,
- 0x51, 0x52, 0x33, 0xd2, 0xb9, 0x00, 0x08, 0xf7, 0xe1, 0xb9, 0x00, 0x80, 0xf7,
- 0xf1, 0x5a, 0x59, 0x89, 0x44, 0x1c, 0x83, 0xc7, 0x04, 0xe9, 0x97, 0xfc, 0xfa,
- 0x8b, 0x44, 0x38, 0x2b, 0x45, 0x02, 0x8b, 0x5c, 0x0a, 0x2b, 0x5c, 0x0c, 0x81,
- 0xe3, 0xff, 0x07, 0x3b, 0xc3, 0x73, 0x1a, 0xf7, 0xd8, 0x03, 0x44, 0x0a, 0x25,
- 0xff, 0x07, 0x89, 0x44, 0x0c, 0x80, 0x64, 0x50, 0xbf, 0xa0, 0x2f, 0x60, 0x88,
- 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0x61,
- 0xfc, 0x8b, 0x5d, 0x02, 0x88, 0x5c, 0x2c, 0x88, 0x7c, 0x2d, 0x8b, 0xcb, 0x83,
- 0xe3, 0x0f, 0x03, 0xdb, 0xf6, 0xc5, 0x04, 0x75, 0x08, 0x2e, 0x8b, 0x9f, 0x00,
- 0x10, 0xeb, 0x06, 0x90, 0x2e, 0x8b, 0x9f, 0x20, 0x10, 0x8a, 0xe1, 0x80, 0xe4,
- 0x30, 0xc0, 0xec, 0x04, 0x8a, 0xc4, 0x04, 0x07, 0xf6, 0xc1, 0x40, 0x74, 0x05,
- 0x80, 0xcc, 0x04, 0xfe, 0xc0, 0xf6, 0xc5, 0x01, 0x74, 0x0d, 0x80, 0xcc, 0x08,
- 0xfe, 0xc0, 0xf6, 0xc5, 0x02, 0x75, 0x03, 0x80, 0xcc, 0x10, 0xf6, 0xc5, 0x08,
- 0x74, 0x03, 0x80, 0xcc, 0x20, 0xfa, 0x80, 0x4e, 0x06, 0x80, 0xc6, 0x46, 0x00,
- 0xff, 0xc6, 0x46, 0x02, 0xff, 0x88, 0x5e, 0x00, 0x88, 0x7e, 0x02, 0x32, 0x66,
- 0x06, 0x80, 0xe4, 0xbf, 0x30, 0x66, 0x06, 0x32, 0xe4, 0xf7, 0xe3, 0x80, 0xe1,
- 0x30, 0x80, 0xf9, 0x30, 0x74, 0x08, 0x3d, 0x1e, 0x00, 0x7d, 0x03, 0xb8, 0x1e,
- 0x00, 0x89, 0x44, 0x46, 0x8a, 0xd9, 0x83, 0xe3, 0x30, 0xc0, 0xeb, 0x04, 0x2e,
- 0x8a, 0x87, 0x40, 0x10, 0x88, 0x44, 0x62, 0xf6, 0x44, 0x28, 0x20, 0x74, 0x02,
- 0x24, 0x7f, 0x88, 0x44, 0x34, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0xba, 0xfb, 0x8b,
- 0x5d, 0x02, 0xfa, 0x8a, 0x44, 0x29, 0x32, 0xc7, 0xa8, 0x10, 0x74, 0x15, 0xf6,
- 0x44, 0x51, 0x02, 0x74, 0x0f, 0x80, 0x74, 0x50, 0x08, 0xa0, 0x2f, 0x60, 0x88,
- 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0x88, 0x5c, 0x28, 0x88, 0x7c, 0x29,
- 0xfb, 0xb4, 0x1a, 0xf6, 0xc3, 0x10, 0x74, 0x03, 0x80, 0xcc, 0x04, 0x8a, 0x44,
- 0x62, 0xf6, 0xc3, 0x20, 0x74, 0x02, 0x24, 0x7f, 0x89, 0x44, 0x34, 0xa1, 0x46,
- 0x60, 0x89, 0x44, 0x06, 0x83, 0xc7, 0x04, 0xe9, 0x6e, 0xfb, 0x8b, 0x45, 0x02,
- 0xfa, 0x88, 0x44, 0x2a, 0x88, 0x64, 0x2b, 0x0b, 0xc0, 0x75, 0x0e, 0x80, 0x64,
- 0x50, 0xfe, 0x8b, 0x1e, 0x42, 0x60, 0x89, 0x5c, 0x04, 0xeb, 0x17, 0x90, 0xf6,
- 0x44, 0x50, 0x01, 0x75, 0x10, 0x80, 0x4c, 0x50, 0x01, 0x8b, 0x1e, 0x44, 0x60,
- 0x89, 0x5c, 0x04, 0xc7, 0x44, 0x30, 0x00, 0x00, 0xfb, 0xa8, 0x80, 0x75, 0x07,
- 0xc6, 0x44, 0x60, 0x00, 0xeb, 0x05, 0x90, 0xc6, 0x44, 0x60, 0x7f, 0xfa, 0xa0,
- 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xfb, 0x83, 0xc7,
- 0x04, 0xe9, 0x19, 0xfb, 0x8b, 0x5d, 0x02, 0x8b, 0xd3, 0xfa, 0x88, 0x5c, 0x5f,
- 0x88, 0x7c, 0x69, 0x8a, 0x44, 0x52, 0x8a, 0x64, 0x53, 0x8a, 0xfb, 0x33, 0xc3,
- 0x25, 0x0f, 0x0f, 0x33, 0xc3, 0x88, 0x44, 0x52, 0x88, 0x64, 0x53, 0xa0, 0x2f,
- 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xf6, 0xd3, 0x22, 0x5c,
- 0x68, 0xf6, 0x44, 0x51, 0x02, 0x75, 0x02, 0x0a, 0xdf, 0x32, 0x5c, 0x54, 0x80,
- 0xe3, 0x0f, 0x30, 0x5c, 0x54, 0x30, 0x5e, 0x08, 0x08, 0x5c, 0x58, 0xfb, 0x83,
- 0xc7, 0x04, 0xe9, 0xca, 0xfa, 0x8a, 0x5d, 0x02, 0x88, 0x5c, 0x68, 0x8a, 0xc3,
- 0x8a, 0x7c, 0x5f, 0x8a, 0xe7, 0xfa, 0x32, 0x46, 0x08, 0x80, 0xe4, 0x0f, 0xf6,
- 0xd4, 0x22, 0xc4, 0x30, 0x46, 0x08, 0x32, 0x5c, 0x54, 0xf6, 0xd7, 0x22, 0xdf,
- 0x80, 0xe3, 0x0f, 0x30, 0x5c, 0x54, 0x08, 0x5c, 0x58, 0xfb, 0x83, 0xc7, 0x04,
- 0xe9, 0x98, 0xfa, 0x8a, 0x45, 0x02, 0x88, 0x44, 0x5e, 0xa1, 0x46, 0x60, 0x89,
- 0x44, 0x06, 0x83, 0xc7, 0x04, 0xe9, 0x86, 0xfa, 0xff, 0x44, 0x38, 0x8b, 0x45,
- 0x02, 0x3d, 0x00, 0x00, 0x74, 0x24, 0x3d, 0xff, 0xff, 0x74, 0x06, 0xbb, 0x0a,
- 0x00, 0xf7, 0xe3, 0xfa, 0x89, 0x44, 0x24, 0x80, 0x4c, 0x50, 0x04, 0xa0, 0x2f,
- 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xfb, 0x83, 0xc7, 0x04,
- 0xe9, 0x57, 0xfa, 0x8b, 0x44, 0x24, 0xbb, 0x0a, 0x00, 0xf7, 0xe3, 0xfa, 0xeb,
- 0xdf, 0x8b, 0x45, 0x02, 0x88, 0x44, 0x5c, 0x88, 0x64, 0x5d, 0x83, 0xc7, 0x04,
- 0xe9, 0x3d, 0xfa, 0x8b, 0x45, 0x02, 0x88, 0x44, 0x5a, 0x88, 0x64, 0x5b, 0x83,
- 0xc7, 0x04, 0xe9, 0x2e, 0xfa, 0x83, 0xc7, 0x04, 0xe9, 0x28, 0xfa, 0xb8, 0x0b,
- 0x00, 0xe9, 0x4e, 0xfa, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xa1, 0x46, 0x60, 0x89,
- 0x44, 0x06, 0xc7, 0x44, 0x02, 0x00, 0x02, 0xa1, 0x42, 0x60, 0x89, 0x44, 0x04,
- 0x33, 0xc0, 0x89, 0x44, 0x0a, 0x89, 0x44, 0x0c, 0x89, 0x44, 0x12, 0x89, 0x44,
- 0x14, 0x89, 0x44, 0x18, 0x89, 0x44, 0x1a, 0xc7, 0x44, 0x1c, 0xff, 0xff, 0x89,
- 0x44, 0x24, 0x88, 0x44, 0x28, 0x88, 0x64, 0x29, 0x88, 0x44, 0x2a, 0x88, 0x64,
- 0x2b, 0xc6, 0x44, 0x2c, 0x3d, 0x88, 0x64, 0x2d, 0xc7, 0x44, 0x2e, 0x02, 0x00,
- 0xc7, 0x44, 0x34, 0xff, 0x0a, 0x89, 0x44, 0x38, 0x89, 0x44, 0x3a, 0x89, 0x44,
- 0x3c, 0x89, 0x44, 0x3e, 0x89, 0x44, 0x40, 0x89, 0x44, 0x44, 0xc7, 0x44, 0x46,
- 0x78, 0x00, 0x88, 0x44, 0x4b, 0x88, 0x44, 0x4c, 0x88, 0x44, 0x4d, 0x88, 0x44,
- 0x4e, 0x88, 0x44, 0x4f, 0x88, 0x44, 0x50, 0x88, 0x44, 0x51, 0x88, 0x44, 0x52,
- 0x88, 0x44, 0x53, 0x88, 0x44, 0x54, 0x88, 0x44, 0x58, 0x88, 0x44, 0x56, 0x88,
- 0x44, 0x57, 0x88, 0x44, 0x58, 0x88, 0x44, 0x59, 0x88, 0x44, 0x64, 0xc6, 0x44,
- 0x5c, 0x11, 0xc6, 0x44, 0x5d, 0x13, 0x88, 0x44, 0x5e, 0x88, 0x44, 0x5f, 0x88,
- 0x44, 0x60, 0x88, 0x44, 0x61, 0xc6, 0x44, 0x62, 0xff, 0x88, 0x44, 0x69, 0x88,
- 0x44, 0x66, 0x88, 0x44, 0x67, 0x8b, 0x6c, 0x20, 0xc6, 0x46, 0x06, 0x80, 0xc6,
- 0x46, 0x00, 0x0c, 0xc6, 0x46, 0x02, 0x00, 0xc6, 0x46, 0x06, 0x03, 0xa1, 0x48,
- 0x60, 0x88, 0x46, 0x04, 0x88, 0x66, 0x04, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02,
- 0xc6, 0x46, 0x08, 0x00, 0x8a, 0x46, 0x04, 0x8a, 0x46, 0x00, 0x8a, 0x46, 0x0a,
- 0x8a, 0x46, 0x0c, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x0e, 0x3e, 0xc4,
- 0xbe, 0x00, 0x50, 0x33, 0xc0, 0xfa, 0x89, 0x44, 0x24, 0xc7, 0x44, 0x2e, 0x02,
- 0x00, 0x89, 0x44, 0x38, 0x89, 0x44, 0x3a, 0x89, 0x44, 0x3c, 0x89, 0x44, 0x3e,
- 0x89, 0x44, 0x0a, 0x89, 0x44, 0x0c, 0x89, 0x44, 0x42, 0x88, 0x44, 0x64, 0xfb,
- 0x81, 0xc6, 0x80, 0x00, 0xe2, 0xd8, 0x5f, 0x5e, 0x5d, 0xc3, 0x8b, 0x0e, 0x3e,
- 0xc4, 0xbe, 0x00, 0x50, 0x33, 0xc0, 0x89, 0x44, 0x0a, 0x89, 0x44, 0x0c, 0x89,
- 0x44, 0x12, 0x89, 0x44, 0x14, 0x81, 0xc6, 0x80, 0x00, 0xe2, 0xee, 0x8b, 0xfe,
- 0xbb, 0x00, 0x10, 0xb8, 0x10, 0x00, 0x8b, 0xd0, 0xb3, 0x00, 0x8b, 0x0e, 0x3e,
- 0xc4, 0xbe, 0x00, 0x50, 0x2b, 0xda, 0x72, 0x27, 0x89, 0x44, 0x16, 0x81, 0xc6,
- 0x80, 0x00, 0xe2, 0xf3, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00, 0x50, 0x2b, 0xda,
- 0x72, 0x13, 0x89, 0x44, 0x0e, 0x81, 0xc6, 0x80, 0x00, 0xe2, 0xf3, 0x8b, 0xd0,
- 0x03, 0xc0, 0x81, 0xfa, 0x00, 0x04, 0x72, 0xce, 0x8c, 0xcf, 0x8b, 0x0e, 0x3e,
- 0xc4, 0xa1, 0x3e, 0xc4, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x00, 0x50, 0x03, 0xd8,
- 0x8b, 0xf3, 0x81, 0xee, 0x80, 0x00, 0x8b, 0x44, 0x16, 0x2b, 0xf8, 0x89, 0x7c,
- 0x10, 0xc1, 0xe0, 0x04, 0x48, 0x89, 0x44, 0x16, 0xe2, 0xeb, 0x8b, 0x0e, 0x3e,
- 0xc4, 0xa1, 0x3e, 0xc4, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x00, 0x50, 0x03, 0xd8,
- 0x8b, 0xf3, 0x81, 0xee, 0x80, 0x00, 0x8b, 0x44, 0x0e, 0x2b, 0xf8, 0x89, 0x7c,
- 0x08, 0xc1, 0xe0, 0x04, 0x48, 0x89, 0x44, 0x0e, 0xe2, 0xeb, 0xc3, 0x55, 0x56,
- 0x57, 0x33, 0xc0, 0x8e, 0xc0, 0xbd, 0x00, 0xf0, 0xc6, 0x46, 0x04, 0x01, 0xf6,
- 0x46, 0x04, 0x80, 0x75, 0x61, 0xc7, 0x06, 0x40, 0x60, 0x44, 0x14, 0xc7, 0x06,
- 0x46, 0x60, 0x3e, 0x19, 0xc7, 0x06, 0x42, 0x60, 0xda, 0x18, 0xc7, 0x06, 0x44,
- 0x60, 0x1a, 0x18, 0x26, 0xc7, 0x06, 0x20, 0x00, 0x2b, 0x23, 0x26, 0xc7, 0x06,
- 0x4c, 0x00, 0x4b, 0x23, 0x26, 0xc7, 0x06, 0x34, 0x00, 0xc5, 0x22, 0x26, 0xc7,
- 0x06, 0x38, 0x00, 0xd2, 0x22, 0xc7, 0x06, 0x00, 0x58, 0x58, 0x23, 0xc6, 0x06,
- 0x2f, 0x60, 0x00, 0xc6, 0x06, 0x2e, 0x60, 0x00, 0xb8, 0x00, 0x00, 0xa3, 0x48,
- 0x60, 0xb8, 0x66, 0x0e, 0xe7, 0x52, 0xb8, 0x05, 0xe0, 0xe7, 0x56, 0xb8, 0xf0,
- 0x00, 0xe7, 0x62, 0xb8, 0x00, 0xe0, 0xe7, 0x66, 0xe9, 0x98, 0x00, 0xc7, 0x06,
- 0x3e, 0xc4, 0x00, 0x00, 0xbd, 0x00, 0xf0, 0xb0, 0x00, 0x88, 0x46, 0x0e, 0x83,
- 0xc5, 0x10, 0xfe, 0xc0, 0x3c, 0x10, 0x7c, 0xf4, 0xbd, 0x00, 0xf0, 0xb0, 0x00,
- 0x8a, 0x5e, 0x0e, 0x3a, 0xd8, 0x75, 0x04, 0xff, 0x06, 0x3e, 0xc4, 0x83, 0xc5,
- 0x10, 0xfe, 0xc0, 0x3c, 0x10, 0x7c, 0xec, 0x83, 0x3e, 0x3e, 0xc4, 0x08, 0x7f,
- 0x09, 0xc7, 0x06, 0x3e, 0xc4, 0x08, 0x00, 0xeb, 0x0a, 0x90, 0xc7, 0x06, 0x3e,
- 0xc4, 0x10, 0x00, 0xeb, 0x01, 0x90, 0xc7, 0x06, 0x40, 0x60, 0xbc, 0x1b, 0xc7,
- 0x06, 0x46, 0x60, 0x39, 0x20, 0xc7, 0x06, 0x42, 0x60, 0xcb, 0x1f, 0xc7, 0x06,
- 0x44, 0x60, 0x83, 0x1c, 0xa1, 0x3e, 0xc4, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x00,
- 0x00, 0x03, 0xd8, 0x03, 0x1e, 0x00, 0x50, 0xc7, 0x87, 0x00, 0x50, 0xd1, 0x23,
- 0x26, 0xc7, 0x06, 0x20, 0x00, 0x8f, 0x23, 0xc6, 0x06, 0x2f, 0x60, 0x01, 0xc6,
- 0x06, 0x2e, 0x60, 0x60, 0xb8, 0x01, 0x07, 0xa3, 0x48, 0x60, 0xb8, 0x70, 0x0f,
- 0xe7, 0x52, 0xb8, 0x05, 0xe0, 0xe7, 0x56, 0xe8, 0x46, 0xfe, 0xbe, 0x00, 0x50,
- 0x89, 0x36, 0x30, 0x60, 0xba, 0x00, 0xf0, 0xb3, 0x00, 0x88, 0x5c, 0x48, 0x88,
- 0x5c, 0x65, 0xfe, 0xc3, 0x89, 0x54, 0x20, 0x83, 0xc2, 0x10, 0xc7, 0x44, 0x1e,
- 0x80, 0x00, 0xe8, 0x00, 0xfd, 0x81, 0xc6, 0x80, 0x00, 0xa1, 0x3e, 0xc4, 0x69,
- 0xc0, 0x80, 0x00, 0xb9, 0x00, 0x50, 0x03, 0xc8, 0x3b, 0xf1, 0x72, 0xd6, 0xa1,
- 0x3e, 0xc4, 0x48, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x1e, 0x00, 0x03, 0xd8, 0xa1,
- 0x3e, 0xc4, 0x48, 0x6b, 0xc0, 0x80, 0x89, 0x87, 0x00, 0x50, 0x5f, 0x5e, 0x5d,
- 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x57, 0x56, 0xe8, 0xf9, 0x1a, 0x8b, 0xf0, 0x8a,
- 0x1e, 0x08, 0xc4, 0x2a, 0xff, 0xc1, 0xe3, 0x02, 0x8b, 0x38, 0x03, 0xf3, 0x8b,
- 0x5c, 0x02, 0x8b, 0x07, 0x48, 0x48, 0x89, 0x46, 0xfe, 0xeb, 0x76, 0x8a, 0x05,
- 0x47, 0x2a, 0xe4, 0x8b, 0xf0, 0x8b, 0xc2, 0x2d, 0x10, 0x00, 0x3d, 0x05, 0x00,
- 0x77, 0x1b, 0xd1, 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0x08, 0x30, 0x90, 0x14, 0x30,
- 0x2a, 0x30, 0x36, 0x30, 0x64, 0x30, 0x42, 0x30, 0x52, 0x30, 0xba, 0x0c, 0x00,
- 0x8b, 0x76, 0xfe, 0x8b, 0xc6, 0x8b, 0xda, 0x88, 0x87, 0xe0, 0x59, 0x56, 0x53,
- 0xe8, 0x2e, 0xd8, 0xeb, 0x13, 0x90, 0xba, 0x0d, 0x00, 0x8a, 0x46, 0xff, 0x2a,
- 0xe4, 0x8b, 0xf0, 0xeb, 0xe4, 0x56, 0x6a, 0x05, 0xe8, 0x2e, 0xd8, 0x83, 0xc4,
- 0x04, 0xeb, 0x23, 0x90, 0xbb, 0x40, 0xf3, 0x8a, 0x07, 0x24, 0xf7, 0x8b, 0xce,
- 0x0a, 0xc1, 0x88, 0x07, 0xeb, 0x13, 0x90, 0x0b, 0xf6, 0x74, 0x08, 0xbb, 0x40,
- 0xf3, 0x80, 0x0f, 0x80, 0xeb, 0x06, 0xbb, 0x40, 0xf3, 0x80, 0x27, 0x7f, 0x8a,
- 0x15, 0x47, 0x2a, 0xf6, 0x81, 0xfa, 0xff, 0x00, 0x74, 0x03, 0xe9, 0x7c, 0xff,
- 0x5e, 0x5f, 0xc9, 0xc3, 0xbb, 0x00, 0xf2, 0x8a, 0x07, 0xa2, 0x38, 0xc4, 0x68,
- 0xc0, 0x00, 0x6a, 0x09, 0xe8, 0xcf, 0xd7, 0x83, 0xc4, 0x04, 0x68, 0x64, 0xb2,
- 0x68, 0xca, 0x00, 0xe8, 0xaf, 0x1a, 0x83, 0xc4, 0x04, 0x6a, 0x01, 0x68, 0xc6,
- 0x00, 0xe8, 0xa4, 0x1a, 0x83, 0xc4, 0x04, 0xb8, 0x28, 0x62, 0x80, 0xc4, 0x10,
- 0x50, 0x68, 0xc4, 0x00, 0xe8, 0x94, 0x1a, 0x83, 0xc4, 0x04, 0x6a, 0x02, 0x68,
- 0xc2, 0x00, 0xe8, 0x89, 0x1a, 0x83, 0xc4, 0x04, 0x68, 0x02, 0x02, 0x68, 0xc0,
- 0x00, 0xe8, 0x7d, 0x1a, 0x83, 0xc4, 0x04, 0x68, 0xa0, 0x0f, 0x68, 0xc8, 0x00,
- 0xe8, 0x71, 0x1a, 0x83, 0xc4, 0x04, 0x68, 0xa4, 0x96, 0x68, 0xda, 0x00, 0xe8,
- 0x65, 0x1a, 0x83, 0xc4, 0x04, 0x6a, 0x01, 0x68, 0xd2, 0x00, 0xe8, 0x5a, 0x1a,
- 0x83, 0xc4, 0x04, 0xb8, 0xdc, 0xc3, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xd0, 0x00,
- 0xe8, 0x4a, 0x1a, 0x83, 0xc4, 0x04, 0x6a, 0x02, 0x68, 0xd6, 0x00, 0xe8, 0x3f,
- 0x1a, 0x83, 0xc4, 0x04, 0x68, 0x02, 0x02, 0x68, 0xd4, 0x00, 0xe8, 0x33, 0x1a,
- 0x83, 0xc4, 0x04, 0x6a, 0x05, 0x68, 0xd8, 0x00, 0xe8, 0x28, 0x1a, 0x83, 0xc4,
- 0x04, 0xe8, 0xab, 0xfe, 0x68, 0x66, 0xb2, 0x68, 0xca, 0x00, 0xe8, 0x19, 0x1a,
- 0x83, 0xc4, 0x04, 0xa0, 0xe3, 0x59, 0x0c, 0x01, 0x2a, 0xe4, 0x50, 0x6a, 0x03,
- 0xe8, 0x1d, 0xd7, 0x83, 0xc4, 0x04, 0xc3, 0xc8, 0x04, 0x00, 0x00, 0x57, 0x56,
- 0x8b, 0x7e, 0x04, 0x8b, 0x76, 0x08, 0x8b, 0xdf, 0x8e, 0x46, 0x06, 0x4b, 0x26,
- 0x80, 0x38, 0xff, 0x75, 0x01, 0x4e, 0x8d, 0x44, 0xfd, 0xa3, 0x22, 0xc4, 0xf7,
- 0xd8, 0xa3, 0x12, 0xc4, 0xa1, 0x22, 0xc4, 0xa3, 0xec, 0xc3, 0x26, 0x8a, 0x05,
- 0xc0, 0xe8, 0x04, 0xa2, 0x06, 0xc4, 0xa2, 0x00, 0x5a, 0x2a, 0xe4, 0x8b, 0xf0,
- 0x8b, 0xdf, 0x26, 0x8a, 0x40, 0x03, 0xa2, 0x08, 0xc4, 0xe8, 0xf4, 0xfe, 0xe8,
- 0x47, 0x19, 0x89, 0x46, 0xfc, 0xa0, 0x08, 0xc4, 0x2a, 0xe4, 0x8b, 0xf0, 0xc1,
- 0xe6, 0x02, 0x8b, 0x5e, 0xfc, 0x8b, 0x58, 0x02, 0x8b, 0x47, 0x02, 0xa3, 0x2a,
- 0xc4, 0xc7, 0x06, 0x30, 0xc4, 0x72, 0x06, 0x2b, 0xc0, 0xa3, 0x26, 0xc4, 0xa3,
- 0x28, 0xc4, 0xa3, 0x2c, 0xc4, 0xa3, 0x2e, 0xc4, 0xc7, 0x06, 0x20, 0x62, 0xff,
- 0xff, 0x8b, 0xf8, 0xeb, 0x5c, 0xc4, 0x5e, 0x04, 0x26, 0x8a, 0x59, 0x02, 0x2a,
- 0xff, 0xc1, 0xe3, 0x02, 0x03, 0x5e, 0xfc, 0x8b, 0x77, 0x02, 0x8b, 0x5f, 0x02,
- 0x8b, 0x47, 0x02, 0x01, 0x06, 0x26, 0xc4, 0x8b, 0x44, 0x04, 0x01, 0x06, 0x28,
- 0xc4, 0xa1, 0x30, 0xc4, 0x39, 0x44, 0x06, 0x73, 0x06, 0x8b, 0x44, 0x06, 0xa3,
- 0x30, 0xc4, 0xa1, 0x2c, 0xc4, 0x39, 0x44, 0x08, 0x76, 0x06, 0x8b, 0x44, 0x08,
- 0xa3, 0x2c, 0xc4, 0xa1, 0x2e, 0xc4, 0x39, 0x44, 0x0a, 0x76, 0x06, 0x8b, 0x44,
- 0x0a, 0xa3, 0x2e, 0xc4, 0xa1, 0x20, 0x62, 0x39, 0x44, 0x0c, 0x73, 0x06, 0x8b,
- 0x44, 0x0c, 0xa3, 0x20, 0x62, 0x47, 0x39, 0x3e, 0x22, 0xc4, 0x73, 0x9e, 0x5e,
- 0x5f, 0xc9, 0xc3, 0x56, 0xc6, 0x06, 0x08, 0xc4, 0xff, 0xb8, 0x90, 0x60, 0xa3,
- 0x50, 0xc4, 0xa3, 0xb2, 0xc3, 0xa3, 0x4a, 0xb0, 0xb8, 0x28, 0x62, 0xa3, 0x36,
- 0xc4, 0xa3, 0x34, 0xc4, 0xc7, 0x06, 0x48, 0xc4, 0x44, 0xc4, 0xc7, 0x06, 0x14,
- 0xc4, 0x26, 0x62, 0xc7, 0x06, 0xf4, 0xc3, 0x09, 0x00, 0xc6, 0x06, 0x07, 0xc4,
- 0x01, 0xbe, 0x4e, 0xb0, 0xeb, 0x09, 0x90, 0x8d, 0x84, 0x76, 0x06, 0x89, 0x04,
- 0x8b, 0xf0, 0x81, 0xfe, 0x3a, 0xbd, 0x75, 0xf2, 0xb8, 0x4e, 0xb0, 0x89, 0x04,
- 0xa3, 0xfa, 0xc3, 0xa3, 0xf6, 0xc3, 0xa3, 0xf8, 0xc3, 0xc7, 0x06, 0xf2, 0xc3,
- 0x01, 0x00, 0x5e, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x06, 0x04, 0x59, 0x01, 0x83,
- 0x16, 0x06, 0x59, 0x00, 0x83, 0x3e, 0x48, 0xb0, 0x00, 0x74, 0x07, 0xf6, 0x06,
- 0x16, 0xc4, 0x01, 0x74, 0x08, 0x68, 0x3c, 0x03, 0xe8, 0x61, 0xcf, 0x8b, 0xe5,
- 0xa0, 0xe6, 0xc3, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0x96, 0x18, 0x8b, 0xe5, 0x80,
- 0x0e, 0x16, 0xc4, 0x01, 0x8b, 0x46, 0x04, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xd0,
- 0x00, 0xe8, 0x82, 0x18, 0x8b, 0xe5, 0xff, 0x76, 0x06, 0x68, 0xd8, 0x00, 0xe8,
- 0x77, 0x18, 0x8b, 0xe5, 0x68, 0xa6, 0x96, 0x68, 0xda, 0x00, 0xe8, 0x6c, 0x18,
- 0x8b, 0xe5, 0xa0, 0x4c, 0xc4, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0x60, 0x18, 0x8b,
- 0x46, 0x04, 0xa3, 0x3a, 0xc4, 0x8b, 0x46, 0x06, 0xa3, 0xda, 0xc3, 0x8b, 0x0e,
- 0xbc, 0x59, 0x03, 0x0e, 0x2a, 0xc4, 0x89, 0x0e, 0x1a, 0xc4, 0x05, 0x04, 0x00,
- 0x01, 0x06, 0x24, 0x62, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x56, 0x06,
- 0x8b, 0x76, 0x04, 0xa0, 0x06, 0xc4, 0x0c, 0xf8, 0xc0, 0xe0, 0x04, 0x08, 0x04,
- 0xb8, 0xc3, 0xa5, 0x2b, 0x04, 0x2b, 0xc2, 0x89, 0x44, 0x02, 0x52, 0x56, 0xe8,
- 0x59, 0xff, 0x83, 0xc4, 0x04, 0x5e, 0xc9, 0xc3, 0x90, 0x56, 0x8b, 0x36, 0x26,
- 0x62, 0x83, 0x3c, 0x04, 0x74, 0x09, 0x68, 0x6e, 0x03, 0xe8, 0xc4, 0xce, 0x83,
- 0xc4, 0x02, 0x83, 0x3e, 0x40, 0xc4, 0x00, 0x74, 0x09, 0x68, 0x70, 0x03, 0xe8,
- 0xb4, 0xce, 0x83, 0xc4, 0x02, 0x89, 0x36, 0x40, 0xc4, 0xff, 0x74, 0x06, 0xff,
- 0x74, 0x04, 0xe8, 0x22, 0xff, 0x83, 0xc4, 0x04, 0x8b, 0x44, 0x02, 0xa3, 0x26,
- 0x62, 0x0b, 0xc0, 0x75, 0x06, 0xc7, 0x06, 0x14, 0xc4, 0x26, 0x62, 0x5e, 0xc3,
- 0x90, 0xc8, 0x04, 0x00, 0x00, 0x56, 0xa0, 0xf4, 0xc3, 0x24, 0x09, 0x3c, 0x09,
- 0x75, 0x2e, 0xc6, 0x06, 0xdc, 0xc3, 0x05, 0xa0, 0x07, 0xc4, 0xa2, 0xdd, 0xc3,
- 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8, 0x6f, 0xff, 0x83, 0xc4, 0x04, 0x80, 0x26,
- 0xf4, 0xc3, 0xf7, 0x80, 0x0e, 0xf4, 0xc3, 0x04, 0xa1, 0xbc, 0x59, 0x03, 0x06,
- 0x28, 0xc4, 0xa3, 0xfc, 0xc3, 0x5e, 0xc9, 0xc3, 0x90, 0xf6, 0x06, 0xf4, 0xc3,
- 0x10, 0x75, 0x03, 0xe9, 0x90, 0x00, 0xc6, 0x06, 0xdc, 0xc3, 0x06, 0xc6, 0x06,
- 0xdd, 0xc3, 0x00, 0x81, 0x3e, 0x03, 0x5a, 0xc0, 0x08, 0x72, 0x14, 0x81, 0x3e,
- 0x03, 0x5a, 0xcf, 0x08, 0x77, 0x0c, 0xc7, 0x46, 0xfc, 0x21, 0x04, 0xc7, 0x46,
- 0xfe, 0x02, 0x00, 0xeb, 0x3c, 0x81, 0x3e, 0x03, 0x5a, 0xd0, 0x08, 0x72, 0x10,
- 0x81, 0x3e, 0x03, 0x5a, 0xdf, 0x08, 0x77, 0x08, 0xc7, 0x46, 0xfc, 0x22, 0x14,
- 0xeb, 0xe2, 0x90, 0x81, 0x3e, 0x03, 0x5a, 0x00, 0x08, 0x72, 0x14, 0x81, 0x3e,
- 0x03, 0x5a, 0x3f, 0x08, 0x77, 0x0c, 0xc7, 0x46, 0xfc, 0x01, 0x04, 0xc7, 0x46,
- 0xfe, 0x00, 0x00, 0xeb, 0x08, 0x2b, 0xc0, 0x89, 0x46, 0xfe, 0x89, 0x46, 0xfc,
- 0x8a, 0x46, 0xfc, 0xa2, 0xe0, 0xc3, 0x8b, 0x46, 0xfc, 0x8a, 0xc4, 0xa2, 0xe1,
- 0xc3, 0x8a, 0x46, 0xfe, 0xa2, 0xe2, 0xc3, 0x8a, 0x46, 0xff, 0xa2, 0xe3, 0xc3,
- 0x6a, 0x08, 0x68, 0xdc, 0xc3, 0xe8, 0xc6, 0xfe, 0x83, 0xc4, 0x04, 0x80, 0x26,
- 0xf4, 0xc3, 0x0f, 0x5e, 0xc9, 0xc3, 0x90, 0xa0, 0xf4, 0xc3, 0x24, 0x0a, 0x3c,
- 0x0a, 0x75, 0x09, 0xa2, 0xdc, 0xc3, 0xa0, 0x0c, 0xc4, 0xe9, 0x2e, 0xff, 0xf6,
- 0x06, 0xf4, 0xc3, 0x60, 0x74, 0x3d, 0xa0, 0xf4, 0xc3, 0x25, 0x20, 0x00, 0x3d,
- 0x01, 0x00, 0x1a, 0xc0, 0x24, 0xfe, 0x04, 0x0b, 0xa2, 0xdc, 0xc3, 0xa0, 0x0c,
- 0xc4, 0xa2, 0xdd, 0xc3, 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8, 0x81, 0xfe, 0x83,
- 0xc4, 0x04, 0x80, 0x26, 0xf4, 0xc3, 0x1f, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a,
- 0xc4, 0x74, 0x03, 0xe9, 0xaa, 0x00, 0x80, 0x26, 0xf4, 0xc3, 0xf7, 0x5e, 0xc9,
- 0xc3, 0x90, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a, 0xc4, 0x74, 0x7d, 0x8b, 0x36,
- 0xf8, 0xc3, 0xc6, 0x44, 0x04, 0x07, 0xa0, 0x0a, 0xc4, 0xc0, 0xe0, 0x04, 0x02,
- 0x06, 0x0c, 0xc4, 0x88, 0x44, 0x05, 0xff, 0x74, 0x02, 0x8d, 0x44, 0x04, 0x50,
- 0xe8, 0x3c, 0xfe, 0x83, 0xc4, 0x04, 0xf6, 0x06, 0xf4, 0xc3, 0x04, 0x75, 0x0f,
- 0x80, 0x0e, 0xf4, 0xc3, 0x04, 0xa1, 0xbc, 0x59, 0x03, 0x06, 0x28, 0xc4, 0xa3,
- 0xfc, 0xc3, 0xa0, 0x0a, 0xc4, 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x0a, 0xc4, 0x8b,
- 0x04, 0xa3, 0xf8, 0xc3, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a, 0xc4, 0x75, 0x25,
- 0x80, 0x26, 0xf4, 0xc3, 0xf7, 0x80, 0x0e, 0xf5, 0xc3, 0x02, 0xa1, 0x30, 0xc4,
- 0x39, 0x44, 0x02, 0x72, 0x07, 0x8b, 0x16, 0x2c, 0xc4, 0xeb, 0x05, 0x90, 0x8b,
- 0x16, 0x2e, 0xc4, 0x03, 0x16, 0xbc, 0x59, 0x89, 0x16, 0xfe, 0xc3, 0x80, 0x26,
- 0xf4, 0xc3, 0x7f, 0x5e, 0xc9, 0xc3, 0xc6, 0x06, 0xdc, 0xc3, 0x08, 0xa0, 0x0c,
- 0xc4, 0xa2, 0xdd, 0xc3, 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8, 0xcb, 0xfd, 0x83,
- 0xc4, 0x04, 0x80, 0x26, 0xf4, 0xc3, 0x77, 0x5e, 0xc9, 0xc3, 0xf6, 0x06, 0x16,
- 0xc4, 0x01, 0x75, 0x4f, 0xf6, 0x06, 0xf4, 0xc3, 0x78, 0x74, 0x2e, 0xf6, 0x06,
- 0x16, 0xc4, 0x08, 0x75, 0x27, 0x83, 0x3e, 0x26, 0x62, 0x00, 0x74, 0x07, 0x83,
- 0x3e, 0x4a, 0xc4, 0x00, 0x7c, 0x19, 0xe8, 0x0a, 0xfe, 0xa1, 0x12, 0xc4, 0xb9,
- 0x01, 0x00, 0x2b, 0x0e, 0x22, 0xc4, 0x01, 0x0e, 0x4a, 0xc4, 0x39, 0x06, 0x4a,
- 0xc4, 0x7d, 0x1c, 0xeb, 0x17, 0x83, 0x3e, 0x26, 0x62, 0x00, 0x74, 0x13, 0xe8,
- 0xa4, 0xfd, 0xa1, 0xec, 0xc3, 0xff, 0x06, 0x4a, 0xc4, 0x39, 0x06, 0x4a, 0xc4,
- 0x7e, 0x03, 0xa3, 0x4a, 0xc4, 0xc3, 0x90, 0x56, 0x2a, 0xc0, 0xa2, 0x0b, 0xc4,
- 0xa2, 0x0a, 0xc4, 0xa2, 0x09, 0xc4, 0xa1, 0xf6, 0xc3, 0xa3, 0xfa, 0xc3, 0xa3,
- 0xf8, 0xc3, 0x8b, 0x36, 0x44, 0xc4, 0xeb, 0x08, 0x90, 0xc7, 0x04, 0x03, 0x00,
- 0x8b, 0x74, 0x02, 0x0b, 0xf6, 0x75, 0xf5, 0xc6, 0x06, 0x0c, 0xc4, 0x00, 0x5e,
- 0xc3, 0x55, 0x8b, 0xec, 0xe8, 0xcc, 0xff, 0x8a, 0x46, 0x04, 0xa2, 0x07, 0xc4,
- 0x83, 0x26, 0xf4, 0xc3, 0x10, 0x81, 0x0e, 0xf4, 0xc3, 0x09, 0x01, 0xe8, 0x60,
- 0xff, 0xc9, 0xc3, 0x56, 0x83, 0x06, 0x28, 0x59, 0x01, 0x83, 0x16, 0x2a, 0x59,
- 0x00, 0x8b, 0x1e, 0xb2, 0xc3, 0x8b, 0xf3, 0xc7, 0x04, 0x04, 0x00, 0x8b, 0x36,
- 0x14, 0xc4, 0x89, 0x1c, 0x8d, 0x47, 0x02, 0xa3, 0x14, 0xc4, 0x5e, 0xc3, 0x90,
- 0xc8, 0x08, 0x00, 0x00, 0x57, 0x56, 0x8b, 0x3e, 0xb2, 0xc3, 0x8b, 0x75, 0x04,
- 0x8b, 0xde, 0x8a, 0x07, 0x25, 0x0f, 0x00, 0x2d, 0x05, 0x00, 0x3d, 0x06, 0x00,
- 0x76, 0x03, 0xe9, 0xb3, 0x00, 0xd1, 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0x30, 0x36,
- 0x90, 0x3e, 0x36, 0x98, 0x36, 0xc8, 0x36, 0x12, 0x37, 0x12, 0x37, 0x26, 0x37,
- 0x12, 0x37, 0x83, 0x7d, 0x06, 0x04, 0x74, 0x03, 0xe9, 0xd1, 0x00, 0x83, 0x06,
- 0x8c, 0x59, 0x01, 0x83, 0x16, 0x8e, 0x59, 0x00, 0xf6, 0x06, 0xf4, 0xc3, 0x01,
- 0x74, 0x24, 0x83, 0x3e, 0x18, 0xc4, 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18, 0xc4,
- 0x80, 0x26, 0xf4, 0xc3, 0xfa, 0xf6, 0x06, 0xf4, 0xc3, 0x08, 0x74, 0x16, 0x80,
- 0x26, 0xf4, 0xc3, 0xf7, 0x80, 0x0e, 0xf4, 0xc3, 0x10, 0xeb, 0x0a, 0x90, 0xe8,
- 0x1b, 0xff, 0xc7, 0x06, 0xf4, 0xc3, 0x10, 0x01, 0x80, 0x0e, 0xf5, 0xc3, 0x02,
- 0xa1, 0xbc, 0x59, 0xa3, 0xfe, 0xc3, 0x80, 0x26, 0x16, 0xc4, 0xf7, 0xe9, 0x63,
- 0x02, 0x83, 0x7d, 0x06, 0x04, 0x75, 0x7a, 0xf6, 0x06, 0xf4, 0xc3, 0x01, 0x74,
- 0x13, 0x83, 0x3e, 0x18, 0xc4, 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18, 0xc4, 0x80,
- 0x26, 0xf4, 0xc3, 0xf2, 0xeb, 0xce, 0x90, 0x83, 0x06, 0xac, 0x59, 0x01, 0x83,
- 0x16, 0xae, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0xeb, 0xc8, 0x83, 0x7d, 0x06,
- 0x04, 0x72, 0x4a, 0x81, 0x7d, 0x06, 0x72, 0x06, 0x77, 0x43, 0x80, 0x26, 0x16,
- 0xc4, 0xf7, 0xf6, 0x06, 0xf4, 0xc3, 0x01, 0x74, 0x03, 0xe9, 0x17, 0x02, 0x8a,
- 0x44, 0x01, 0x24, 0x0f, 0x88, 0x46, 0xfd, 0x8a, 0x0e, 0x09, 0xc4, 0x2a, 0xed,
- 0x2a, 0xc1, 0x24, 0x0f, 0x8a, 0x16, 0x0a, 0xc4, 0x2a, 0xd1, 0x80, 0xe2, 0x0f,
- 0x3a, 0xc2, 0x7e, 0x2b, 0x83, 0x06, 0x80, 0x59, 0x01, 0x83, 0x16, 0x82, 0x59,
- 0x00, 0x6a, 0x03, 0xe9, 0x52, 0x01, 0x83, 0x7d, 0x06, 0x04, 0x74, 0xc2, 0x83,
- 0x06, 0x7c, 0x59, 0x01, 0x83, 0x16, 0x7e, 0x59, 0x00, 0xe9, 0x6e, 0x01, 0x90,
- 0x83, 0x7d, 0x06, 0x04, 0x75, 0xec, 0xeb, 0xa7, 0x89, 0x76, 0xf8, 0x8a, 0x46,
- 0xfd, 0x38, 0x06, 0x09, 0xc4, 0x75, 0x03, 0xe9, 0x89, 0x00, 0x83, 0x3e, 0x18,
- 0xc4, 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18, 0xc4, 0x8b, 0x36, 0xf6, 0xc3, 0xa0,
- 0x09, 0xc4, 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x09, 0xc4, 0x8b, 0x34, 0x8a, 0x46,
- 0xfd, 0x38, 0x06, 0x09, 0xc4, 0x75, 0xeb, 0x8b, 0xd6, 0x89, 0x16, 0xf6, 0xc3,
- 0xf6, 0x06, 0xf4, 0xc3, 0x02, 0x75, 0x58, 0xa0, 0x0a, 0xc4, 0x38, 0x06, 0x09,
- 0xc4, 0x75, 0x07, 0x80, 0x26, 0xf4, 0xc3, 0xfb, 0xeb, 0x1a, 0xf6, 0x06, 0xf4,
- 0xc3, 0x04, 0x75, 0x09, 0x68, 0x63, 0x05, 0xe8, 0x75, 0xca, 0x83, 0xc4, 0x02,
- 0xa1, 0xbc, 0x59, 0x03, 0x06, 0x28, 0xc4, 0xa3, 0xfc, 0xc3, 0xa0, 0x0b, 0xc4,
- 0x38, 0x06, 0x0a, 0xc4, 0x75, 0x25, 0xf6, 0x06, 0xf5, 0xc3, 0x02, 0x75, 0x1e,
- 0x2a, 0x06, 0x09, 0xc4, 0x24, 0x0f, 0x3c, 0x03, 0x7c, 0x09, 0x68, 0x6e, 0x05,
- 0xe8, 0x48, 0xca, 0x83, 0xc4, 0x02, 0x80, 0x0e, 0xf5, 0xc3, 0x02, 0xa1, 0xbc,
- 0x59, 0xa3, 0xfe, 0xc3, 0x8b, 0x5e, 0xf8, 0x8a, 0x07, 0x25, 0x0f, 0x00, 0x2d,
- 0x07, 0x00, 0x74, 0x17, 0x48, 0x48, 0x75, 0x03, 0xe9, 0x94, 0x00, 0x48, 0x75,
- 0x03, 0xe9, 0xbc, 0x00, 0x48, 0x75, 0x03, 0xe9, 0xc8, 0x00, 0xe9, 0x12, 0x01,
- 0x90, 0x8a, 0x47, 0x01, 0xc0, 0xe8, 0x04, 0x88, 0x46, 0xff, 0x3a, 0x06, 0x0c,
- 0xc4, 0x75, 0x45, 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x0c, 0xc4, 0xf6, 0x06, 0xf4,
- 0xc3, 0x80, 0x75, 0x1d, 0x81, 0x3e, 0x20, 0x62, 0xe8, 0x03, 0x73, 0x15, 0x80,
- 0x0e, 0xf4, 0xc3, 0x80, 0xa1, 0x28, 0xc4, 0xc1, 0xe8, 0x03, 0x03, 0x06, 0xbc,
- 0x59, 0xa3, 0x02, 0xc4, 0xeb, 0x06, 0x90, 0x80, 0x0e, 0xf4, 0xc3, 0x88, 0xc7,
- 0x05, 0x02, 0x00, 0x8b, 0x1e, 0x48, 0xc4, 0x89, 0x3f, 0x8d, 0x45, 0x02, 0xa3,
- 0x48, 0xc4, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x8a, 0x46, 0xff, 0x2a, 0x06, 0x0c,
- 0xc4, 0x24, 0x0f, 0x3c, 0x05, 0x7d, 0x0d, 0xff, 0x06, 0xd8, 0xc3, 0x80, 0x0e,
- 0xf4, 0xc3, 0x40, 0x5e, 0x5f, 0xc9, 0xc3, 0x83, 0x06, 0x84, 0x59, 0x01, 0x83,
- 0x16, 0x86, 0x59, 0x00, 0x6a, 0x04, 0xe8, 0x61, 0xfd, 0x83, 0xc4, 0x02, 0x5e,
- 0x5f, 0xc9, 0xc3, 0xf6, 0x06, 0xf4, 0xc3, 0x02, 0x75, 0x14, 0xa0, 0x0b, 0xc4,
- 0x38, 0x06, 0x0a, 0xc4, 0x74, 0x0b, 0x81, 0x26, 0xf4, 0xc3, 0xfb, 0xfd, 0x80,
- 0x0e, 0xf4, 0xc3, 0x0a, 0x83, 0x06, 0xb0, 0x59, 0x01, 0x83, 0x16, 0xb2, 0x59,
- 0x00, 0xff, 0x06, 0xd8, 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x80, 0x0e, 0xf4,
- 0xc3, 0x20, 0x83, 0x06, 0xb4, 0x59, 0x01, 0x83, 0x16, 0xb6, 0x59, 0x00, 0xeb,
- 0xe6, 0x90, 0xf6, 0x06, 0xf4, 0xc3, 0x02, 0x75, 0x0d, 0x83, 0x06, 0xac, 0x59,
- 0x01, 0x83, 0x16, 0xae, 0x59, 0x00, 0xeb, 0xd2, 0x90, 0x83, 0x3e, 0x18, 0xc4,
- 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18, 0xc4, 0x80, 0x26, 0xf4, 0xc3, 0xf1, 0xa0,
- 0x09, 0xc4, 0xa2, 0x0a, 0xc4, 0x8b, 0x0e, 0xf6, 0xc3, 0x89, 0x0e, 0xf8, 0xc3,
- 0x3a, 0x06, 0x0b, 0xc4, 0x75, 0x10, 0x80, 0x0e, 0xf5, 0xc3, 0x02, 0xa1, 0xbc,
- 0x59, 0xa3, 0xfe, 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x80, 0x0e, 0xf4, 0xc3,
- 0x08, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0xc8, 0x06, 0x00, 0x00, 0x57, 0x56, 0x8b,
- 0x3e, 0xb2, 0xc3, 0x83, 0x3d, 0x01, 0x74, 0x09, 0x68, 0x12, 0x06, 0xe8, 0xeb,
- 0xc8, 0x83, 0xc4, 0x02, 0x83, 0x3e, 0x20, 0xc4, 0x00, 0x74, 0x17, 0xff, 0x36,
- 0x20, 0xc4, 0xff, 0x36, 0x1e, 0xc4, 0x68, 0x28, 0x62, 0xe8, 0xbd, 0x11, 0x83,
- 0xc4, 0x06, 0xc7, 0x06, 0x20, 0xc4, 0x00, 0x00, 0x8b, 0x75, 0x04, 0x8b, 0x55,
- 0x06, 0x83, 0x3e, 0x24, 0xc4, 0x00, 0x74, 0x17, 0x39, 0x16, 0x24, 0xc4, 0x77,
- 0x09, 0xc7, 0x06, 0x24, 0xc4, 0x00, 0x00, 0xe9, 0xc5, 0x01, 0x29, 0x16, 0x24,
- 0xc4, 0xe9, 0xbe, 0x01, 0x90, 0x89, 0x56, 0xfc, 0x83, 0x3e, 0xba, 0x59, 0x00,
- 0x74, 0x46, 0x68, 0xe8, 0x03, 0xe8, 0x98, 0x11, 0x83, 0xc4, 0x02, 0x3b, 0x06,
- 0xba, 0x59, 0x73, 0x37, 0x83, 0x06, 0x9c, 0x59, 0x01, 0x83, 0x16, 0x9e, 0x59,
- 0x00, 0x6a, 0x02, 0xe8, 0x80, 0x11, 0x83, 0xc4, 0x02, 0x89, 0x46, 0xfe, 0x6a,
- 0x08, 0xe8, 0x75, 0x11, 0x83, 0xc4, 0x02, 0x6a, 0x02, 0x89, 0x46, 0xfa, 0xe8,
- 0x6a, 0x11, 0x83, 0xc4, 0x02, 0x8b, 0xc8, 0xc0, 0xe1, 0x02, 0x8a, 0x46, 0xfa,
- 0xd2, 0xe0, 0x8b, 0x5e, 0xfe, 0x30, 0x00, 0x8a, 0x04, 0x25, 0x0f, 0x00, 0x48,
- 0x3d, 0x0a, 0x00, 0x77, 0x1f, 0xd1, 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0xbe, 0x39,
- 0x90, 0xea, 0x39, 0x7a, 0x3a, 0x7a, 0x3a, 0x9e, 0x3a, 0xc0, 0x3a, 0xc0, 0x3a,
- 0xc0, 0x3a, 0xc0, 0x3a, 0xc0, 0x3a, 0xc0, 0x3a, 0xc0, 0x3a, 0x83, 0x06, 0x78,
- 0x59, 0x01, 0x83, 0x16, 0x7a, 0x59, 0x00, 0x83, 0x06, 0x18, 0xc4, 0x02, 0xff,
- 0x06, 0xd8, 0xc3, 0xe9, 0x2d, 0x01, 0x8b, 0x56, 0xfc, 0x8b, 0xda, 0x80, 0x78,
- 0xff, 0xff, 0x75, 0x01, 0x4a, 0x83, 0xfa, 0x04, 0x7d, 0x03, 0xe9, 0x92, 0x00,
- 0x83, 0xfa, 0x0c, 0x7e, 0x03, 0xe9, 0x8a, 0x00, 0x80, 0x7c, 0x01, 0x01, 0x75,
- 0x03, 0xe8, 0x27, 0xce, 0x8a, 0x04, 0xc0, 0xe8, 0x04, 0x2a, 0xe4, 0x40, 0x8a,
- 0x0e, 0x06, 0xc4, 0x2a, 0xed, 0x3b, 0xc1, 0x7e, 0x05, 0x80, 0x04, 0x10, 0xeb,
- 0x11, 0xa0, 0x06, 0xc4, 0xfe, 0xc0, 0xc0, 0xe0, 0x04, 0x8a, 0x0c, 0x80, 0xe1,
- 0x0f, 0x0a, 0xc1, 0x88, 0x04, 0xa0, 0x08, 0xc4, 0x8a, 0x1c, 0xc0, 0xeb, 0x04,
- 0x2a, 0xff, 0x38, 0x40, 0x03, 0x74, 0x6a, 0xa0, 0xe6, 0xc3, 0x98, 0x50, 0x6a,
- 0x28, 0xe8, 0xf1, 0x10, 0x83, 0xc4, 0x04, 0x80, 0x0e, 0x16, 0xc4, 0x04, 0xe8,
- 0x43, 0x01, 0xc7, 0x06, 0x18, 0xc4, 0x00, 0x00, 0xa1, 0xbc, 0x59, 0x05, 0x10,
- 0x27, 0xa3, 0x1c, 0xc4, 0xa0, 0x4c, 0xc4, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xcd,
- 0x10, 0x83, 0xc4, 0x04, 0xeb, 0x37, 0x90, 0x8b, 0x56, 0xfc, 0x83, 0xfa, 0x04,
- 0x75, 0x09, 0x80, 0x7c, 0x03, 0xff, 0x75, 0x03, 0xba, 0x03, 0x00, 0x83, 0xfa,
- 0x03, 0x74, 0x20, 0x83, 0x06, 0x7c, 0x59, 0x01, 0x83, 0x16, 0x7e, 0x59, 0x00,
- 0xe9, 0x41, 0xff, 0x90, 0x8b, 0x56, 0xfc, 0x83, 0xfa, 0x0c, 0x72, 0xea, 0x8b,
- 0x44, 0x0a, 0x05, 0x0c, 0x00, 0x3b, 0xc2, 0x75, 0xe0, 0xa1, 0xbc, 0x59, 0x05,
- 0x10, 0x27, 0xa3, 0x1c, 0xc4, 0x80, 0x0e, 0x16, 0xc4, 0x08, 0xeb, 0x54, 0xb8,
- 0xc3, 0xa5, 0x2b, 0x44, 0x02, 0x2b, 0x04, 0x8b, 0xc8, 0x3b, 0x45, 0x06, 0x74,
- 0x2b, 0x83, 0x3e, 0xba, 0x59, 0x00, 0x75, 0x24, 0x83, 0x06, 0x6c, 0x59, 0x01,
- 0x83, 0x16, 0x6e, 0x59, 0x00, 0x83, 0x06, 0x18, 0xc4, 0x02, 0x39, 0x4d, 0x06,
- 0x73, 0x2d, 0x81, 0xf9, 0x72, 0x06, 0x77, 0x27, 0x2b, 0x4d, 0x06, 0x89, 0x0e,
- 0x24, 0xc4, 0xeb, 0x1e, 0x90, 0xa1, 0xbc, 0x59, 0x05, 0x10, 0x27, 0xa3, 0x1c,
- 0xc4, 0x8a, 0x04, 0xc0, 0xe8, 0x04, 0x3a, 0x06, 0x06, 0xc4, 0x75, 0x06, 0xe8,
- 0xf7, 0xfa, 0xeb, 0x04, 0x90, 0xe8, 0xcd, 0xfa, 0x83, 0x3d, 0x01, 0x75, 0x04,
- 0xc7, 0x05, 0x00, 0x00, 0x83, 0xc7, 0x08, 0x81, 0xff, 0x20, 0x62, 0x75, 0x03,
- 0xbf, 0x90, 0x60, 0x89, 0x3e, 0xb2, 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x55, 0x8b,
- 0xec, 0x83, 0x06, 0x24, 0x59, 0x01, 0x83, 0x16, 0x26, 0x59, 0x00, 0xc7, 0x06,
- 0xf2, 0xc3, 0x00, 0x00, 0xeb, 0x04, 0x90, 0xe8, 0xb3, 0xfd, 0x8b, 0x1e, 0xb2,
- 0xc3, 0x83, 0x3f, 0x01, 0x74, 0xf4, 0xe8, 0xe9, 0xf9, 0xc9, 0xc3, 0x90, 0x83,
- 0x3e, 0x48, 0xb0, 0x00, 0x74, 0x09, 0x68, 0x20, 0x07, 0xe8, 0x97, 0xc6, 0x83,
- 0xc4, 0x02, 0xc7, 0x06, 0x48, 0xb0, 0x01, 0x00, 0xc3, 0x90, 0x83, 0x3e, 0x48,
- 0xb0, 0x01, 0x74, 0x14, 0x68, 0x2d, 0x07, 0xe8, 0x7f, 0xc6, 0x83, 0xc4, 0x02,
- 0xeb, 0x09, 0xc7, 0x06, 0x48, 0xb0, 0x01, 0x00, 0xe8, 0xa5, 0xff, 0xc7, 0x06,
- 0x48, 0xb0, 0x00, 0x00, 0x83, 0x3e, 0xf2, 0xc3, 0x00, 0x75, 0xea, 0xc3, 0x90,
- 0x57, 0x56, 0x8b, 0x1e, 0x50, 0xc4, 0xeb, 0x11, 0x83, 0x3f, 0x00, 0x75, 0x12,
- 0x83, 0xc3, 0x08, 0x81, 0xfb, 0x20, 0x62, 0x72, 0x03, 0xbb, 0x90, 0x60, 0x39,
- 0x1e, 0xb2, 0xc3, 0x75, 0xe9, 0x89, 0x1e, 0x50, 0xc4, 0x3b, 0x1e, 0x4a, 0xb0,
- 0x75, 0x05, 0xa1, 0x34, 0xc4, 0xeb, 0x03, 0x8b, 0x47, 0x04, 0xa3, 0x36, 0xc4,
- 0x39, 0x06, 0x34, 0xc4, 0x72, 0x50, 0x81, 0x3e, 0x34, 0xc4, 0xa4, 0xa0, 0x73,
- 0x06, 0xbf, 0x48, 0xb0, 0xeb, 0x47, 0x90, 0xb8, 0xac, 0xb0, 0x2b, 0x06, 0x34,
- 0xc4, 0x8b, 0x0e, 0x36, 0xc4, 0x81, 0xe9, 0x28, 0x62, 0x3b, 0xc1, 0x7f, 0xe7,
- 0xf6, 0x06, 0x16, 0xc4, 0x06, 0x75, 0x22, 0xb8, 0x28, 0x62, 0x2b, 0x06, 0x34,
- 0xc4, 0x50, 0xe8, 0x16, 0xcd, 0x83, 0xc4, 0x02, 0x8b, 0xf0, 0x81, 0xee, 0x00,
- 0x10, 0xa1, 0x34, 0xc4, 0xa3, 0x1e, 0xc4, 0x81, 0xee, 0x28, 0x62, 0x89, 0x36,
- 0x20, 0xc4, 0xc7, 0x06, 0x34, 0xc4, 0x28, 0x62, 0x8b, 0x3e, 0x36, 0xc4, 0x81,
- 0xff, 0x28, 0x62, 0x72, 0x06, 0x81, 0xff, 0x48, 0xb0, 0x76, 0x09, 0x68, 0x7f,
- 0x07, 0xe8, 0xc2, 0xc5, 0x83, 0xc4, 0x02, 0xa1, 0x34, 0xc4, 0x05, 0x04, 0x00,
- 0x2b, 0xf8, 0x81, 0xff, 0xa0, 0x0f, 0x72, 0x05, 0xbf, 0xa0, 0x0f, 0xeb, 0x0a,
- 0x83, 0x06, 0x44, 0x59, 0x01, 0x83, 0x16, 0x46, 0x59, 0x00, 0xf6, 0x06, 0x16,
- 0xc4, 0x06, 0x75, 0x13, 0xa1, 0x34, 0xc4, 0x03, 0xc7, 0x80, 0xc4, 0x10, 0x50,
- 0xe8, 0xe6, 0xcc, 0x83, 0xc4, 0x02, 0x5e, 0x5f, 0xc3, 0x90, 0xf6, 0x06, 0x16,
- 0xc4, 0x04, 0x74, 0x07, 0x68, 0x80, 0x00, 0x6a, 0x09, 0xeb, 0x17, 0xa0, 0xe3,
- 0x59, 0x2a, 0xe4, 0x50, 0x6a, 0x03, 0xe8, 0xc4, 0xcb, 0x83, 0xc4, 0x04, 0xa0,
- 0xef, 0x59, 0x25, 0xfb, 0x00, 0x50, 0x6a, 0x0f, 0xe8, 0xb5, 0xcb, 0x83, 0xc4,
- 0x04, 0x68, 0x64, 0xb2, 0x68, 0xca, 0x00, 0xe8, 0x95, 0x0e, 0x83, 0xc4, 0x04,
- 0xbe, 0x06, 0x00, 0xeb, 0x10, 0x6a, 0x01, 0xe8, 0x88, 0xcb, 0x83, 0xc4, 0x02,
- 0xbb, 0x02, 0xf2, 0x8a, 0x07, 0xa2, 0x38, 0xc4, 0xbb, 0x00, 0xf2, 0xc6, 0x07,
- 0x30, 0x4e, 0x75, 0xe7, 0xa1, 0x34, 0xc4, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xc4,
- 0x00, 0xe8, 0x67, 0x0e, 0x83, 0xc4, 0x04, 0x57, 0x68, 0xc8, 0x00, 0xe8, 0x5d,
- 0x0e, 0x83, 0xc4, 0x04, 0xf6, 0x06, 0x16, 0xc4, 0x04, 0x74, 0x2a, 0xe8, 0xd9,
- 0xf2, 0x80, 0x26, 0x16, 0xc4, 0xf8, 0x83, 0x3e, 0x40, 0xc4, 0x00, 0x74, 0x0e,
- 0x8b, 0x1e, 0x40, 0xc4, 0xc7, 0x07, 0x00, 0x00, 0xc7, 0x06, 0x40, 0xc4, 0x00,
- 0x00, 0x83, 0x06, 0x94, 0x59, 0x01, 0x83, 0x16, 0x96, 0x59, 0x00, 0xeb, 0x1e,
- 0x90, 0xa0, 0xef, 0x59, 0x2a, 0xe4, 0x50, 0x6a, 0x0f, 0xe8, 0x32, 0xcb, 0x83,
- 0xc4, 0x04, 0x80, 0x26, 0x16, 0xc4, 0xfd, 0x83, 0x06, 0x90, 0x59, 0x01, 0x83,
- 0x16, 0x92, 0x59, 0x00, 0x83, 0xff, 0x14, 0x72, 0x0c, 0x68, 0x66, 0xb2, 0x68,
- 0xca, 0x00, 0xe8, 0xfe, 0x0d, 0x83, 0xc4, 0x04, 0xa0, 0xe3, 0x59, 0x0c, 0x01,
- 0x2a, 0xe4, 0x50, 0x6a, 0x03, 0xe8, 0x02, 0xcb, 0x83, 0xc4, 0x04, 0x5e, 0x5f,
- 0xc3, 0x90, 0xbb, 0x00, 0xf2, 0xf6, 0x07, 0x40, 0x74, 0x38, 0xf6, 0x06, 0x16,
- 0xc4, 0x01, 0x74, 0x31, 0x68, 0xd8, 0x00, 0xe8, 0xc7, 0x0d, 0x83, 0xc4, 0x02,
- 0x0b, 0xc0, 0x75, 0x16, 0x80, 0x26, 0x16, 0xc4, 0xfe, 0x39, 0x06, 0x40, 0xc4,
- 0x74, 0x19, 0x8b, 0x1e, 0x40, 0xc4, 0x89, 0x07, 0xa3, 0x40, 0xc4, 0xeb, 0x0e,
- 0x83, 0x06, 0x68, 0x59, 0x01, 0x83, 0x16, 0x6a, 0x59, 0x00, 0xff, 0x06, 0xd8,
- 0xc3, 0xbb, 0x00, 0xf2, 0xf6, 0x07, 0x80, 0x74, 0x21, 0x83, 0x06, 0x60, 0x59,
- 0x01, 0x83, 0x16, 0x62, 0x59, 0x00, 0x68, 0xc4, 0x00, 0xe8, 0x84, 0x0d, 0x83,
- 0xc4, 0x02, 0x2b, 0x06, 0x34, 0xc4, 0x3d, 0x00, 0x10, 0x74, 0x05, 0x80, 0x0e,
- 0x16, 0xc4, 0x02, 0xbb, 0x00, 0xf2, 0xc6, 0x07, 0x10, 0xf6, 0x06, 0x16, 0xc4,
- 0x06, 0x74, 0x03, 0xe8, 0xcb, 0xfd, 0x83, 0x06, 0x00, 0x59, 0x01, 0x83, 0x16,
- 0x02, 0x59, 0x00, 0xc3, 0x55, 0x8b, 0xec, 0x57, 0x56, 0x2b, 0xff, 0xe8, 0x97,
- 0xca, 0xf6, 0x06, 0x29, 0x60, 0x80, 0x74, 0x03, 0xe9, 0xe4, 0x01, 0xf6, 0x06,
- 0x29, 0x60, 0x40, 0x75, 0x03, 0xe9, 0xa2, 0x01, 0x8b, 0x36, 0x28, 0x60, 0x81,
- 0xe6, 0xff, 0x3f, 0x80, 0x36, 0x2a, 0x60, 0x86, 0xf7, 0x06, 0x2a, 0x60, 0xee,
- 0x80, 0x74, 0x03, 0xe9, 0xbc, 0x00, 0x83, 0x3e, 0xb8, 0x59, 0x00, 0x74, 0x1b,
- 0x6a, 0x64, 0xe8, 0xe2, 0x0c, 0x83, 0xc4, 0x02, 0x3b, 0x06, 0xb8, 0x59, 0x73,
- 0x0d, 0x83, 0x06, 0x98, 0x59, 0x01, 0x83, 0x16, 0x9a, 0x59, 0x00, 0xe9, 0x88,
- 0x00, 0x8d, 0x44, 0x02, 0x01, 0x06, 0x3c, 0xc4, 0xa1, 0x34, 0xc4, 0x2d, 0x28,
- 0x62, 0x3b, 0x06, 0x20, 0xc4, 0x72, 0x07, 0x8b, 0x1e, 0x34, 0xc4, 0xeb, 0x0d,
- 0x90, 0x8b, 0x1e, 0x34, 0xc4, 0x81, 0xeb, 0x28, 0x62, 0x03, 0x1e, 0x1e, 0xc4,
- 0x8a, 0x0f, 0x2a, 0xed, 0x8b, 0xd1, 0x83, 0xe2, 0x0f, 0x83, 0xfa, 0x05, 0x7c,
- 0x05, 0x83, 0xfa, 0x0b, 0x7e, 0x05, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0x8b, 0x16,
- 0x4a, 0xb0, 0x8b, 0xda, 0x83, 0x3f, 0x00, 0x75, 0x35, 0xc7, 0x07, 0x01, 0x00,
- 0xa1, 0x34, 0xc4, 0x89, 0x47, 0x04, 0x8d, 0x44, 0xfe, 0x89, 0x47, 0x06, 0xc7,
- 0x47, 0x02, 0x00, 0x00, 0x83, 0xc2, 0x08, 0x81, 0xfa, 0x20, 0x62, 0x75, 0x03,
- 0xba, 0x90, 0x60, 0xa1, 0x4a, 0xb0, 0x39, 0x06, 0x50, 0xc4, 0x75, 0x04, 0x89,
- 0x16, 0x50, 0xc4, 0x89, 0x16, 0x4a, 0xb0, 0xeb, 0x0f, 0x90, 0x83, 0x06, 0x70,
- 0x59, 0x01, 0x83, 0x16, 0x72, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0x01, 0x36,
- 0x34, 0xc4, 0xbb, 0x00, 0xf2, 0xc6, 0x07, 0x30, 0x47, 0xe9, 0x15, 0xff, 0xf6,
- 0x06, 0x2b, 0x60, 0x80, 0x74, 0x0a, 0x83, 0x06, 0x64, 0x59, 0x01, 0x83, 0x16,
- 0x66, 0x59, 0x00, 0xf6, 0x06, 0x2a, 0x60, 0x80, 0x74, 0x0a, 0x83, 0x06, 0x54,
- 0x59, 0x01, 0x83, 0x16, 0x56, 0x59, 0x00, 0xf6, 0x06, 0x2a, 0x60, 0x40, 0x74,
- 0x0a, 0x83, 0x06, 0x58, 0x59, 0x01, 0x83, 0x16, 0x5a, 0x59, 0x00, 0xf6, 0x06,
- 0x2a, 0x60, 0x20, 0x74, 0x0a, 0x83, 0x06, 0x50, 0x59, 0x01, 0x83, 0x16, 0x52,
- 0x59, 0x00, 0xf6, 0x06, 0x2a, 0x60, 0x0e, 0x74, 0x0a, 0x83, 0x06, 0x5c, 0x59,
- 0x01, 0x83, 0x16, 0x5e, 0x59, 0x00, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0xff, 0x06,
- 0xd8, 0xc3, 0x0b, 0xff, 0x74, 0x08, 0xc7, 0x06, 0x32, 0xc4, 0x00, 0x00, 0xeb,
- 0x16, 0xff, 0x06, 0x32, 0xc4, 0x83, 0x3e, 0x32, 0xc4, 0x14, 0x72, 0x0b, 0xc7,
- 0x06, 0x32, 0xc4, 0x00, 0x00, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0x83, 0xff, 0x05,
- 0x76, 0x03, 0xbf, 0x05, 0x00, 0xc1, 0xe7, 0x02, 0x83, 0x85, 0x08, 0x59, 0x01,
- 0x83, 0x95, 0x0a, 0x59, 0x00, 0x68, 0xc4, 0x00, 0xe8, 0xcb, 0x0b, 0x83, 0xc4,
- 0x02, 0x8b, 0xf0, 0x81, 0xee, 0x00, 0x10, 0x39, 0x36, 0x34, 0xc4, 0x74, 0x72,
- 0x3b, 0x36, 0x34, 0xc4, 0x73, 0x12, 0x83, 0x06, 0x40, 0x59, 0x01, 0x83, 0x16,
- 0x42, 0x59, 0x00, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0xeb, 0x5b, 0x90, 0x83, 0x06,
- 0x38, 0x59, 0x01, 0x83, 0x16, 0x3a, 0x59, 0x00, 0xeb, 0x4e, 0xf6, 0x06, 0x2a,
- 0x60, 0x80, 0x74, 0x0a, 0x83, 0x06, 0x3c, 0x59, 0x01, 0x83, 0x16, 0x3e, 0x59,
- 0x00, 0xf6, 0x06, 0x2a, 0x60, 0x20, 0x75, 0x03, 0xe9, 0x75, 0xff, 0x83, 0x06,
- 0x4c, 0x59, 0x01, 0x83, 0x16, 0x4e, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0x80,
- 0x0e, 0x16, 0xc4, 0x02, 0xbb, 0x00, 0xf2, 0xc6, 0x07, 0x30, 0xe9, 0x59, 0xff,
- 0x90, 0x83, 0x06, 0x48, 0x59, 0x01, 0x83, 0x16, 0x4a, 0x59, 0x00, 0xff, 0x06,
- 0xd8, 0xc3, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0xe9, 0x42, 0xff, 0xe8, 0xaf, 0xfb,
- 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x83, 0x06, 0xa0, 0x59, 0x01, 0x83, 0x16, 0xa2,
- 0x59, 0x00, 0x83, 0x06, 0x18, 0xc4, 0x02, 0xff, 0x06, 0xd8, 0xc3, 0xf6, 0x06,
- 0xf4, 0xc3, 0x01, 0x74, 0x08, 0x80, 0x0e, 0xf4, 0xc3, 0x08, 0xeb, 0x24, 0x90,
- 0xf6, 0x06, 0xf4, 0xc3, 0x02, 0x75, 0xf1, 0xa0, 0x0a, 0xc4, 0x38, 0x06, 0x09,
- 0xc4, 0x75, 0x09, 0x68, 0x1a, 0x09, 0xe8, 0xd4, 0xc1, 0x83, 0xc4, 0x02, 0x80,
- 0x0e, 0xf4, 0xc3, 0x0a, 0x80, 0x26, 0xf5, 0xc3, 0xfd, 0xe9, 0x06, 0xf5, 0xc8,
- 0x02, 0x00, 0x00, 0x57, 0x56, 0xf6, 0x06, 0xf5, 0xc3, 0x01, 0x74, 0x14, 0xe8,
- 0x38, 0xed, 0xe8, 0x0d, 0xfb, 0x80, 0x26, 0xf5, 0xc3, 0xfe, 0xe8, 0x1d, 0xfb,
- 0xc7, 0x06, 0x0e, 0xc4, 0x00, 0x00, 0x83, 0x3e, 0x44, 0xc4, 0x00, 0x74, 0x6b,
- 0xe8, 0xf5, 0xfa, 0x8b, 0x36, 0x44, 0xc4, 0x0b, 0xf6, 0x74, 0x57, 0x8b, 0x44,
- 0x02, 0xa3, 0x44, 0xc4, 0x0b, 0xc0, 0x75, 0x06, 0xc7, 0x06, 0x48, 0xc4, 0x44,
- 0xc4, 0x83, 0x06, 0x34, 0x59, 0x01, 0x83, 0x16, 0x36, 0x59, 0x00, 0x8b, 0x7e,
- 0xfe, 0x83, 0x3c, 0x02, 0x75, 0x1c, 0xe8, 0xe0, 0xfa, 0x8b, 0x44, 0x06, 0x2d,
- 0x04, 0x00, 0x50, 0x8b, 0x44, 0x04, 0x05, 0x04, 0x00, 0x50, 0xe8, 0xfd, 0xe5,
- 0x83, 0xc4, 0x04, 0x8b, 0xf8, 0xe8, 0xaf, 0xfa, 0xc7, 0x04, 0x00, 0x00, 0x0b,
- 0xff, 0x74, 0x11, 0x83, 0x06, 0x88, 0x59, 0x01, 0x83, 0x16, 0x8a, 0x59, 0x00,
- 0x57, 0xe8, 0x05, 0xf5, 0x83, 0xc4, 0x02, 0xe8, 0xab, 0xfa, 0xc7, 0x06, 0x0e,
- 0xc4, 0x00, 0x00, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x57, 0x56, 0xa0, 0x0b, 0xc4,
- 0x2a, 0x06, 0x09, 0xc4, 0x24, 0x0f, 0x3c, 0x03, 0x7c, 0x09, 0x80, 0x26, 0xf5,
- 0xc3, 0xfd, 0x5e, 0x5f, 0xc3, 0x90, 0x8b, 0x3e, 0xfa, 0xc3, 0xe8, 0x81, 0xfa,
- 0xff, 0x36, 0x30, 0xc4, 0x8d, 0x45, 0x08, 0x50, 0xe8, 0x38, 0xe3, 0x83, 0xc4,
- 0x04, 0x8b, 0xf0, 0xe8, 0x56, 0xfa, 0x81, 0xfe, 0x72, 0x06, 0x76, 0x09, 0x68,
- 0xab, 0x09, 0xe8, 0xee, 0xc0, 0x83, 0xc4, 0x02, 0xf6, 0x06, 0xf5, 0xc3, 0x01,
- 0x75, 0x7b, 0x0b, 0xf6, 0x75, 0x2c, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x00, 0xc4,
- 0x3d, 0x00, 0x40, 0x72, 0x20, 0xa1, 0xbc, 0x59, 0x05, 0x0a, 0x00, 0xa3, 0xfe,
- 0xc3, 0xf6, 0x06, 0xf4, 0xc3, 0x80, 0x74, 0x5b, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0x02, 0xc4, 0x3d, 0x00, 0x40, 0x73, 0x4f, 0xeb, 0x45, 0x90, 0x90, 0x83, 0x06,
- 0x30, 0x59, 0x01, 0x83, 0x16, 0x32, 0x59, 0x00, 0x80, 0x26, 0xf5, 0xc3, 0xfd,
- 0x8d, 0x44, 0x04, 0x89, 0x45, 0x02, 0x8b, 0x05, 0xa3, 0xfa, 0xc3, 0xa0, 0x0b,
- 0xc4, 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x0b, 0xc4, 0xa1, 0xbc, 0x59, 0xa3, 0x00,
- 0xc4, 0x0b, 0xf6, 0x74, 0x08, 0x81, 0x3e, 0x20, 0x62, 0xe8, 0x03, 0x73, 0x06,
- 0x81, 0x06, 0x00, 0xc4, 0x88, 0x13, 0xf6, 0x06, 0xf4, 0xc3, 0x03, 0x75, 0x08,
- 0x80, 0x0e, 0xf4, 0xc3, 0x08, 0xe8, 0xab, 0xf3, 0x5e, 0x5f, 0xc3, 0x55, 0x8b,
- 0xec, 0x2b, 0xc0, 0xa3, 0xb8, 0x59, 0xa3, 0xba, 0x59, 0xe8, 0x7a, 0xf0, 0x2b,
- 0xdb, 0x8e, 0xc3, 0xbb, 0x40, 0x08, 0x26, 0x8a, 0x07, 0x2a, 0xe4, 0x50, 0x06,
- 0x68, 0x30, 0x08, 0xe8, 0x80, 0xef, 0x83, 0xc4, 0x06, 0x80, 0x0e, 0x16, 0xc4,
- 0x08, 0xc7, 0x06, 0x1c, 0xc4, 0x10, 0x27, 0xe8, 0x9b, 0xec, 0xe8, 0xe4, 0x01,
- 0xa1, 0x03, 0x5a, 0x25, 0xf0, 0x0f, 0x3d, 0xd0, 0x08, 0x74, 0x1d, 0xa1, 0x03,
- 0x5a, 0x80, 0xe4, 0x0f, 0x3d, 0x00, 0x04, 0x72, 0x0b, 0xa1, 0x03, 0x5a, 0x80,
- 0xe4, 0x0f, 0x3d, 0x3f, 0x04, 0x76, 0x07, 0xc6, 0x06, 0x4d, 0xc4, 0x00, 0xeb,
- 0x05, 0xc6, 0x06, 0x4d, 0xc4, 0x01, 0xa0, 0x2e, 0x60, 0x0c, 0x9c, 0xa2, 0xe6,
- 0xc3, 0xa0, 0x2e, 0x60, 0x0c, 0x8c, 0xa2, 0x4c, 0xc4, 0x98, 0x50, 0x6a, 0x28,
- 0xe8, 0x2d, 0x09, 0x83, 0xc4, 0x04, 0xa1, 0x0e, 0xc4, 0x01, 0x06, 0x52, 0xc4,
- 0xc7, 0x06, 0x0e, 0xc4, 0x01, 0x00, 0x83, 0x06, 0x20, 0x59, 0x01, 0x83, 0x16,
- 0x22, 0x59, 0x00, 0xc7, 0x06, 0xd6, 0xc3, 0x00, 0x00, 0xe8, 0x05, 0xfe, 0xa1,
- 0xbc, 0x59, 0x2b, 0x06, 0xf0, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x72, 0x83, 0x06,
- 0xf0, 0xc3, 0x14, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x22, 0x62, 0x3d, 0x00, 0x40,
- 0x73, 0x5b, 0x83, 0x06, 0x22, 0x62, 0x64, 0xa1, 0x52, 0xc4, 0x2b, 0x06, 0x46,
- 0xc4, 0x99, 0x33, 0xc2, 0x2b, 0xc2, 0xc1, 0xf8, 0x02, 0x33, 0xc2, 0x2b, 0xc2,
- 0x01, 0x06, 0x46, 0xc4, 0xa1, 0xd4, 0xc3, 0x39, 0x06, 0x46, 0xc4, 0x76, 0x06,
- 0xa1, 0x46, 0xc4, 0xa3, 0xd4, 0xc3, 0xa1, 0x3c, 0xc4, 0x2b, 0x06, 0x24, 0x62,
- 0x1b, 0xc9, 0xf7, 0xd1, 0x23, 0xc1, 0x03, 0x06, 0x24, 0x62, 0x2b, 0x06, 0x10,
- 0xc4, 0x99, 0x33, 0xc2, 0x2b, 0xc2, 0xc1, 0xf8, 0x02, 0x33, 0xc2, 0x2b, 0xc2,
- 0x01, 0x06, 0x10, 0xc4, 0x2b, 0xc0, 0xa3, 0x52, 0xc4, 0xa3, 0x24, 0x62, 0xa3,
- 0x3c, 0xc4, 0xe8, 0xe6, 0x03, 0xe8, 0x87, 0xfd, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0xfc, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x33, 0xe8, 0x98, 0xf8, 0xa1, 0xbc, 0x59,
- 0x2b, 0x06, 0xfc, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x1e, 0xa1, 0xbc, 0x59, 0x05,
- 0xf4, 0x01, 0xa3, 0xfc, 0xc3, 0xf6, 0x06, 0xf4, 0xc3, 0x04, 0x74, 0x08, 0x80,
- 0x26, 0xf4, 0xc3, 0xfb, 0xe8, 0x0c, 0xfd, 0xc7, 0x06, 0x0e, 0xc4, 0x00, 0x00,
- 0xe8, 0x83, 0xf8, 0xe8, 0x48, 0xfd, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0xfe, 0xc3,
- 0x3d, 0x00, 0x40, 0x73, 0x40, 0xe8, 0x59, 0xf8, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0xfe, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x2b, 0xa1, 0xbc, 0x59, 0x05, 0xf4, 0x01,
- 0xa3, 0xfe, 0xc3, 0xa0, 0xf5, 0xc3, 0x24, 0x03, 0x3c, 0x02, 0x75, 0x13, 0xf6,
- 0x06, 0xf4, 0xc3, 0x01, 0x74, 0x09, 0x68, 0x8b, 0x0a, 0xe8, 0xd2, 0xbe, 0x83,
- 0xc4, 0x02, 0xe8, 0xa0, 0xfd, 0xc7, 0x06, 0x0e, 0xc4, 0x00, 0x00, 0xe8, 0x37,
- 0xf8, 0xe8, 0xfc, 0xfc, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x4c, 0xb0, 0x3d, 0x00,
- 0x40, 0x72, 0x03, 0xe9, 0xc8, 0xfe, 0x83, 0x06, 0x4c, 0xb0, 0x64, 0xf6, 0x06,
- 0x16, 0xc4, 0x01, 0x74, 0x0c, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x1a, 0xc4, 0x3d,
- 0x00, 0x40, 0x72, 0x23, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x1c, 0xc4, 0x3d, 0x00,
- 0x40, 0x72, 0x17, 0x68, 0xc8, 0x00, 0xe8, 0xbd, 0x07, 0x83, 0xc4, 0x02, 0x0b,
- 0xc0, 0x74, 0x0a, 0x83, 0x3e, 0x18, 0xc4, 0x14, 0x73, 0x03, 0xe9, 0x8d, 0xfe,
- 0xa0, 0xe6, 0xc3, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xad, 0x07, 0x83, 0xc4, 0x04,
- 0x80, 0x0e, 0x16, 0xc4, 0x04, 0xe8, 0xff, 0xf7, 0xc7, 0x06, 0x18, 0xc4, 0x00,
- 0x00, 0xa1, 0xbc, 0x59, 0x05, 0x10, 0x27, 0xa3, 0x1c, 0xc4, 0xa0, 0x4c, 0xc4,
- 0xe9, 0x59, 0xfe, 0xbb, 0x00, 0xf1, 0xc7, 0x07, 0x00, 0x00, 0xbb, 0x80, 0xf1,
- 0xc7, 0x07, 0xff, 0xff, 0xc7, 0x06, 0xea, 0xc3, 0x01, 0x00, 0xc3, 0x90, 0xbb,
- 0x00, 0xf1, 0x8a, 0x67, 0x01, 0x25, 0x00, 0xc0, 0xa3, 0x42, 0xc4, 0xa1, 0x78,
- 0x60, 0x39, 0x06, 0x42, 0xc4, 0x74, 0x57, 0x81, 0x3e, 0x42, 0xc4, 0x00, 0xc0,
- 0x75, 0x15, 0x3d, 0x00, 0x40, 0x74, 0x05, 0x3d, 0x00, 0x80, 0x75, 0x0b, 0x31,
- 0x06, 0x42, 0xc4, 0xc7, 0x06, 0x78, 0x60, 0x00, 0x00, 0xc3, 0x3d, 0x00, 0xc0,
- 0x75, 0x10, 0x81, 0x3e, 0x42, 0xc4, 0x00, 0x40, 0x74, 0x41, 0x81, 0x3e, 0x42,
- 0xc4, 0x00, 0x80, 0x74, 0x39, 0xa1, 0x42, 0xc4, 0xa3, 0x78, 0x60, 0x3d, 0x00,
- 0xc0, 0x74, 0x12, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x7a, 0x60, 0x3d, 0x32, 0x00,
- 0x73, 0x06, 0xc7, 0x06, 0x42, 0xc4, 0x00, 0x00, 0xa1, 0xbc, 0x59, 0xa3, 0x7a,
- 0x60, 0xc3, 0x90, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x7a, 0x60, 0x3d, 0xe8, 0x03,
- 0x72, 0x08, 0x81, 0x06, 0x7a, 0x60, 0xfa, 0x00, 0xc3, 0x90, 0xc7, 0x06, 0x42,
- 0xc4, 0x00, 0x00, 0xc3, 0x90, 0xc8, 0x04, 0x00, 0x00, 0x57, 0x56, 0xc7, 0x46,
- 0xfc, 0x00, 0x00, 0xbf, 0xb4, 0xc3, 0xc7, 0x46, 0xfe, 0x54, 0xc4, 0xbe, 0x00,
- 0x50, 0xeb, 0x40, 0x80, 0x7c, 0x67, 0x00, 0x75, 0x0a, 0x8b, 0x5e, 0xfe, 0x8b,
- 0x07, 0x39, 0x44, 0x0c, 0x74, 0x0e, 0xff, 0x46, 0xfc, 0xd0, 0x6c, 0x67, 0x8b,
- 0x44, 0x0c, 0x8b, 0x5e, 0xfe, 0x89, 0x07, 0x80, 0x7c, 0x66, 0x00, 0x75, 0x07,
- 0x8b, 0x05, 0x39, 0x44, 0x12, 0x74, 0x0b, 0xff, 0x46, 0xfc, 0xd0, 0x6c, 0x66,
- 0x8b, 0x44, 0x12, 0x89, 0x05, 0x47, 0x47, 0x83, 0x46, 0xfe, 0x02, 0x81, 0xc6,
- 0x80, 0x00, 0x81, 0xfe, 0x00, 0x58, 0x72, 0xba, 0x8b, 0x46, 0xfc, 0x5e, 0x5f,
- 0xc9, 0xc3, 0x90, 0x83, 0x3e, 0x42, 0xc4, 0x00, 0x74, 0x0c, 0xc7, 0x06, 0xb0,
- 0xc3, 0x01, 0x00, 0xc7, 0x06, 0x7c, 0x60, 0x00, 0x00, 0xe8, 0x84, 0xff, 0x40,
- 0x01, 0x06, 0x7c, 0x60, 0x83, 0x3e, 0x7c, 0x60, 0x14, 0x7c, 0x25, 0xd1, 0x26,
- 0xb0, 0xc3, 0xf7, 0x06, 0xb0, 0xc3, 0xff, 0x03, 0x75, 0x06, 0xc7, 0x06, 0xb0,
- 0xc3, 0x01, 0x00, 0x83, 0x3e, 0x7c, 0x60, 0x28, 0x7c, 0x07, 0xc7, 0x06, 0x7c,
- 0x60, 0x14, 0x00, 0xc3, 0x83, 0x2e, 0x7c, 0x60, 0x14, 0xc3, 0xc8, 0x02, 0x00,
- 0x00, 0x57, 0x56, 0x83, 0x7e, 0x04, 0x10, 0x72, 0x09, 0x68, 0x27, 0x01, 0xe8,
- 0xee, 0xbc, 0x83, 0xc4, 0x02, 0x2b, 0xff, 0x8b, 0x76, 0x04, 0xc1, 0xe6, 0x07,
- 0x81, 0xc6, 0x00, 0x50, 0x8a, 0x54, 0x54, 0x2a, 0xf6, 0x38, 0x36, 0x4d, 0xc4,
- 0x75, 0x4a, 0xf6, 0xc2, 0x02, 0x74, 0x03, 0xbf, 0x04, 0x00, 0xf6, 0xc2, 0x10,
- 0x74, 0x03, 0x83, 0xcf, 0x08, 0xf6, 0xc2, 0x01, 0x74, 0x03, 0x83, 0xcf, 0x40,
- 0xf6, 0xc2, 0x40, 0x74, 0x04, 0x81, 0xcf, 0x80, 0x00, 0xf6, 0x44, 0x28, 0x80,
- 0x74, 0x13, 0xf6, 0xc2, 0x80, 0x74, 0x03, 0x83, 0xcf, 0x10, 0xf6, 0xc2, 0x20,
- 0x74, 0x16, 0x83, 0xcf, 0x20, 0xeb, 0x11, 0x90, 0xf6, 0xc2, 0x80, 0x74, 0x03,
- 0x83, 0xcf, 0x20, 0xf6, 0xc2, 0x20, 0x74, 0x03, 0x83, 0xcf, 0x10, 0xf6, 0x44,
- 0x51, 0x03, 0x74, 0x10, 0xf6, 0x44, 0x29, 0x10, 0x75, 0x06, 0xf6, 0x44, 0x5f,
- 0x03, 0x74, 0x04, 0x81, 0xcf, 0x00, 0x02, 0x8a, 0x44, 0x52, 0x22, 0xc2, 0x3a,
- 0x44, 0x53, 0x74, 0x04, 0x81, 0xcf, 0x00, 0x01, 0x83, 0x3e, 0x42, 0xc4, 0x00,
- 0x74, 0x19, 0x2a, 0xc0, 0x88, 0x44, 0x67, 0x88, 0x44, 0x66, 0x8b, 0x44, 0x12,
- 0x8b, 0x5e, 0x04, 0xd1, 0xe3, 0x89, 0x87, 0xb4, 0xc3, 0x8b, 0x44, 0x0c, 0xeb,
- 0x6c, 0x8a, 0x44, 0x2c, 0x25, 0x0f, 0x00, 0x48, 0x74, 0x0f, 0x48, 0x74, 0x1e,
- 0x48, 0x74, 0x21, 0x48, 0x74, 0x24, 0xba, 0x01, 0x00, 0xeb, 0x22, 0x90, 0x8a,
- 0x64, 0x2d, 0x25, 0x00, 0x04, 0x3d, 0x01, 0x00, 0x1b, 0xd2, 0x83, 0xe2, 0x1f,
- 0x42, 0xeb, 0x10, 0x90, 0xba, 0x10, 0x00, 0xeb, 0x0a, 0x90, 0xba, 0x04, 0x00,
- 0xeb, 0x04, 0x90, 0xba, 0x02, 0x00, 0x8b, 0x44, 0x12, 0x8b, 0x5e, 0x04, 0xd1,
- 0xe3, 0x89, 0x5e, 0xfe, 0x39, 0x87, 0xb4, 0xc3, 0x74, 0x0d, 0x08, 0x54, 0x66,
- 0x8b, 0x44, 0x12, 0x8b, 0x5e, 0xfe, 0x89, 0x87, 0xb4, 0xc3, 0x8b, 0x44, 0x0c,
- 0x8b, 0x5e, 0xfe, 0x39, 0x87, 0x54, 0xc4, 0x74, 0x0d, 0x08, 0x54, 0x67, 0x8b,
- 0x44, 0x0c, 0x8b, 0x5e, 0xfe, 0x89, 0x87, 0x54, 0xc4, 0x80, 0x7c, 0x67, 0x01,
- 0x75, 0x1e, 0xf6, 0x06, 0xb0, 0xc3, 0x01, 0x74, 0x11, 0x6a, 0x64, 0xe8, 0xc6,
- 0x04, 0x83, 0xc4, 0x02, 0x3d, 0x1e, 0x00, 0x7d, 0x04, 0x2b, 0xd2, 0xeb, 0x0b,
- 0xba, 0x01, 0x00, 0xeb, 0x06, 0x90, 0x8a, 0x54, 0x67, 0x2a, 0xf6, 0x0b, 0xd2,
- 0x74, 0x03, 0x83, 0xcf, 0x01, 0x80, 0x7c, 0x66, 0x01, 0x75, 0x1e, 0xf6, 0x06,
- 0xb0, 0xc3, 0x02, 0x74, 0x11, 0x6a, 0x64, 0xe8, 0x96, 0x04, 0x83, 0xc4, 0x02,
- 0x3d, 0x1e, 0x00, 0x7d, 0x04, 0x2b, 0xd2, 0xeb, 0x0b, 0xba, 0x01, 0x00, 0xeb,
- 0x06, 0x90, 0x8a, 0x54, 0x66, 0x2a, 0xf6, 0x0b, 0xd2, 0x74, 0x03, 0x83, 0xcf,
- 0x02, 0xd0, 0x6c, 0x67, 0xd0, 0x6c, 0x66, 0x89, 0x3e, 0xb0, 0xc3, 0x5e, 0x5f,
- 0xc9, 0xc3, 0xe8, 0x2f, 0xfd, 0xa1, 0x42, 0xc4, 0x2d, 0x00, 0x40, 0x74, 0x0d,
- 0x2d, 0x00, 0x40, 0x74, 0x1a, 0x2d, 0x00, 0x40, 0x74, 0x31, 0xeb, 0x67, 0x90,
- 0xff, 0x0e, 0xea, 0xc3, 0x79, 0x60, 0xa1, 0x3e, 0xc4, 0x05, 0x06, 0x00, 0x01,
- 0x06, 0xea, 0xc3, 0xeb, 0x54, 0xa1, 0x3e, 0xc4, 0x05, 0x06, 0x00, 0xff, 0x06,
- 0xea, 0xc3, 0x3b, 0x06, 0xea, 0xc3, 0x77, 0x44, 0xa1, 0x3e, 0xc4, 0x05, 0x06,
- 0x00, 0x29, 0x06, 0xea, 0xc3, 0xeb, 0x38, 0xa1, 0xea, 0xc3, 0x2d, 0x04, 0x00,
- 0x74, 0x04, 0x48, 0x74, 0x25, 0xc3, 0xa1, 0x10, 0x59, 0x8b, 0x16, 0x12, 0x59,
- 0xd1, 0xe0, 0xd1, 0xd2, 0x03, 0x06, 0x04, 0x59, 0x13, 0x16, 0x06, 0x59, 0x03,
- 0x06, 0x0c, 0x59, 0x13, 0x16, 0x0e, 0x59, 0xa3, 0x82, 0x60, 0x89, 0x16, 0x84,
- 0x60, 0xc3, 0x90, 0xc7, 0x06, 0xd8, 0xc3, 0x00, 0x00, 0xc3, 0x90, 0xa1, 0xea,
- 0xc3, 0x3d, 0x15, 0x00, 0x76, 0x03, 0xe9, 0xfd, 0x00, 0xd1, 0xe0, 0x93, 0x2e,
- 0xff, 0xa7, 0x2a, 0x47, 0x90, 0x56, 0x47, 0x68, 0x47, 0x6e, 0x47, 0xa6, 0x47,
- 0xd0, 0x47, 0xf4, 0x47, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04,
- 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48,
- 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0xe8, 0x5f, 0xfd,
- 0x8a, 0x1e, 0x00, 0x5a, 0x2a, 0xff, 0xd1, 0xe3, 0x8b, 0x87, 0xf6, 0x00, 0xe9,
- 0xb3, 0x00, 0xe8, 0x4d, 0xfd, 0xe9, 0xa3, 0x00, 0x83, 0x3e, 0x42, 0xc4, 0x00,
- 0x74, 0x06, 0xc7, 0x06, 0x7e, 0x60, 0x00, 0x00, 0xa1, 0x20, 0x62, 0x39, 0x06,
- 0x10, 0xc4, 0x72, 0x0a, 0xc7, 0x06, 0xb0, 0xc3, 0xff, 0x03, 0xe9, 0x84, 0x00,
- 0x90, 0x68, 0x7e, 0x60, 0x50, 0x2b, 0x06, 0x10, 0xc4, 0x50, 0x6a, 0x0a, 0xe8,
- 0x34, 0x03, 0x83, 0xc4, 0x08, 0x8b, 0xc8, 0xb8, 0xff, 0x03, 0xeb, 0x25, 0x83,
- 0x3e, 0x42, 0xc4, 0x00, 0x74, 0x06, 0xc7, 0x06, 0x7e, 0x60, 0x00, 0x00, 0x68,
- 0x7e, 0x60, 0xff, 0x36, 0xd4, 0xc3, 0xff, 0x36, 0x46, 0xc4, 0x6a, 0x0b, 0xe8,
- 0x0d, 0x03, 0x83, 0xc4, 0x08, 0x8b, 0xc8, 0xb8, 0xff, 0x07, 0xd3, 0xf8, 0xeb,
- 0x1f, 0x90, 0xa1, 0x10, 0x59, 0xd1, 0xe0, 0x2b, 0x06, 0x82, 0x60, 0x03, 0x06,
- 0x04, 0x59, 0x03, 0x06, 0x0c, 0x59, 0xa3, 0xb0, 0xc3, 0x50, 0xe8, 0x18, 0xc0,
- 0x83, 0xc4, 0x02, 0xc1, 0xf8, 0x06, 0xa3, 0xb0, 0xc3, 0xeb, 0x1e, 0x90, 0xa1,
- 0xd8, 0xc3, 0x2d, 0xff, 0x03, 0x1b, 0xc9, 0x23, 0xc1, 0x05, 0xff, 0x03, 0xeb,
- 0xe1, 0x90, 0xa1, 0xea, 0xc3, 0x2d, 0x06, 0x00, 0x50, 0xe8, 0xf2, 0xfc, 0x83,
- 0xc4, 0x02, 0x8b, 0x1e, 0xea, 0xc3, 0xd1, 0xe3, 0x8b, 0x87, 0xc8, 0x00, 0xa3,
- 0xee, 0xc3, 0xff, 0x06, 0x80, 0x60, 0x83, 0x3e, 0x80, 0x60, 0x14, 0x7c, 0x12,
- 0x80, 0x0e, 0xee, 0xc3, 0x80, 0x83, 0x3e, 0x80, 0x60, 0x28, 0x7c, 0x06, 0xc7,
- 0x06, 0x80, 0x60, 0x00, 0x00, 0xa1, 0xb0, 0xc3, 0xbb, 0x00, 0xf1, 0x89, 0x07,
- 0xa1, 0xee, 0xc3, 0xbb, 0x80, 0xf1, 0x89, 0x07, 0xc3, 0x04, 0x20, 0x0a, 0x80,
- 0x0f, 0x00, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xd8, 0x05, 0x61, 0x01,
- 0xf9, 0x0b, 0x16, 0x10, 0x00, 0x11, 0x00, 0x0e, 0x07, 0x05, 0x6b, 0x09, 0x0f,
- 0xff, 0x09, 0xc0, 0x04, 0x20, 0x0a, 0x80, 0x07, 0x7e, 0x02, 0x00, 0x0b, 0x16,
- 0x10, 0x00, 0x11, 0x00, 0x0e, 0x07, 0x0f, 0xc5, 0x07, 0x77, 0x05, 0x6b, 0x03,
- 0xd8, 0x01, 0xf9, 0x09, 0x0e, 0xff, 0x12, 0x80, 0x13, 0x08, 0x04, 0x20, 0x0a,
- 0x80, 0x0f, 0x04, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05, 0x61,
- 0x01, 0xf9, 0x0b, 0x08, 0x0e, 0x04, 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x12, 0x80,
- 0x13, 0x08, 0x14, 0x08, 0x04, 0x20, 0x0a, 0x80, 0x0f, 0x04, 0x07, 0x7e, 0x0f,
- 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05, 0x61, 0x01, 0xf9, 0x0b, 0x08, 0x0e, 0x04,
- 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x12, 0x02, 0x13, 0x02, 0x04, 0x20, 0x0a, 0xa0,
- 0x0f, 0x04, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05, 0x61, 0x01,
- 0xf9, 0x0b, 0x77, 0x0c, 0x0e, 0x0d, 0x00, 0x0e, 0x07, 0x0e, 0xe7, 0x0e, 0xa7,
- 0x0e, 0x27, 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x12, 0x02, 0x13, 0x02, 0x04, 0x20,
- 0x0a, 0xe0, 0x0f, 0x04, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05,
- 0x61, 0x01, 0xf9, 0x0b, 0x77, 0x0c, 0x06, 0x0d, 0x00, 0x0e, 0x07, 0x0e, 0xc7,
- 0x0e, 0xa7, 0x0e, 0x27, 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x00, 0x06, 0x58, 0x1b,
- 0x20, 0x03, 0x14, 0x00, 0x3c, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x00, 0x03, 0xa0,
- 0x0f, 0x58, 0x02, 0x1e, 0x00, 0x28, 0x00, 0x1e, 0x00, 0x3c, 0x00, 0x80, 0x01,
- 0xd0, 0x07, 0xa4, 0x01, 0x28, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x78, 0x00, 0x00,
- 0x01, 0x08, 0x07, 0x7c, 0x01, 0x34, 0x00, 0x1e, 0x00, 0x14, 0x00, 0xb4, 0x00,
- 0xc0, 0x00, 0xb0, 0x04, 0x54, 0x01, 0x40, 0x00, 0x19, 0x00, 0x14, 0x00, 0xf0,
- 0x00, 0x60, 0x00, 0x58, 0x02, 0x2c, 0x01, 0x64, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0xe0, 0x01, 0x40, 0x00, 0xf4, 0x01, 0x2c, 0x01, 0x96, 0x00, 0x14, 0x00, 0x14,
- 0x00, 0xd0, 0x02, 0x39, 0x00, 0xc2, 0x01, 0x2c, 0x01, 0xc8, 0x00, 0x14, 0x00,
- 0x14, 0x00, 0x20, 0x03, 0x30, 0x00, 0x90, 0x01, 0x2c, 0x01, 0xfa, 0x00, 0x14,
- 0x00, 0x14, 0x00, 0xc0, 0x03, 0x20, 0x00, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01,
- 0x14, 0x00, 0x14, 0x00, 0xa0, 0x05, 0x10, 0x00, 0xc8, 0x00, 0x2c, 0x01, 0x58,
- 0x02, 0x14, 0x00, 0x14, 0x00, 0x40, 0x0b, 0x08, 0x00, 0x64, 0x00, 0xe1, 0x00,
- 0xe8, 0x03, 0x0e, 0x00, 0x14, 0x00, 0x80, 0x16, 0x06, 0x00, 0x64, 0x00, 0xdc,
- 0x00, 0xb0, 0x04, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x1e, 0x05, 0x00, 0x64, 0x00,
- 0xc8, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x24, 0x04, 0x00, 0x64,
- 0x00, 0xb4, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x2d, 0x03, 0x00,
- 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x3c, 0x04,
- 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x5a,
- 0x03, 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06, 0x09, 0x00, 0x0f, 0x00, 0x00,
- 0x78, 0x4c, 0x48, 0x9a, 0x49, 0xca, 0x48, 0xa8, 0x49, 0xf3, 0x48, 0xb6, 0x49,
- 0x4c, 0x48, 0x1c, 0x49, 0x4c, 0x48, 0x2a, 0x49, 0x4c, 0x48, 0x38, 0x49, 0x4c,
- 0x48, 0x54, 0x49, 0x4c, 0x48, 0x62, 0x49, 0x4c, 0x48, 0x70, 0x49, 0x4c, 0x48,
- 0x8c, 0x49, 0x4c, 0x48, 0x9a, 0x49, 0x4c, 0x48, 0xa8, 0x49, 0x4c, 0x48, 0xb6,
- 0x49, 0x4c, 0x48, 0xe0, 0x49, 0x4c, 0x48, 0xee, 0x49, 0x8a, 0x48, 0x1c, 0x49,
- 0x8a, 0x48, 0x2a, 0x49, 0x8a, 0x48, 0x38, 0x49, 0x8a, 0x48, 0x54, 0x49, 0x8a,
- 0x48, 0x62, 0x49, 0x8a, 0x48, 0x70, 0x49, 0x8a, 0x48, 0x8c, 0x49, 0x8a, 0x48,
- 0x9a, 0x49, 0x8a, 0x48, 0xa8, 0x49, 0x8a, 0x48, 0xb6, 0x49, 0x8a, 0x48, 0xe0,
- 0x49, 0x8a, 0x48, 0xee, 0x49, 0x8a, 0x48, 0xee, 0x49, 0x8a, 0x48, 0xee, 0x49,
- 0x8a, 0x48, 0xee, 0x49, 0x8a, 0x48, 0xee, 0x49, 0x8a, 0x48, 0xee, 0x49, 0x8a,
- 0x48, 0xee, 0x49, 0x8a, 0x48, 0x46, 0x49, 0x4c, 0x48, 0x9a, 0x49, 0xa9, 0x48,
- 0x1c, 0x49, 0xa9, 0x48, 0x2a, 0x49, 0xa9, 0x48, 0x38, 0x49, 0xa9, 0x48, 0x46,
- 0x49, 0xa9, 0x48, 0x54, 0x49, 0xa9, 0x48, 0x62, 0x49, 0xa9, 0x48, 0x70, 0x49,
- 0xa9, 0x48, 0x7e, 0x49, 0xa9, 0x48, 0x8c, 0x49, 0x4c, 0x48, 0x9a, 0x49, 0xb8,
- 0x18, 0x4a, 0xc3, 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x46, 0x02, 0xf7, 0x66, 0x04,
- 0x8b, 0x5e, 0x08, 0x03, 0x07, 0x83, 0xd2, 0x00, 0xf7, 0x76, 0x06, 0x89, 0x17,
- 0x8b, 0xe9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8c, 0xd8, 0x8e, 0xc0, 0x8b,
- 0x7e, 0x04, 0x8b, 0x76, 0x06, 0x8b, 0x4e, 0x08, 0xf3, 0xa4, 0x5f, 0x5e, 0x5d,
- 0xc3, 0x8b, 0xcd, 0x8b, 0xec, 0xb8, 0x45, 0x31, 0xf7, 0x26, 0x86, 0x60, 0x05,
- 0x1f, 0x28, 0xa3, 0x86, 0x60, 0xf7, 0x66, 0x02, 0x8b, 0xc2, 0x8b, 0xe9, 0xc3,
- 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x56, 0x02, 0xec, 0x32, 0xe4, 0x8b, 0xe9, 0xc3,
- 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x56, 0x02, 0x8a, 0x46, 0x04, 0xee, 0x8b, 0xe9,
- 0xc3, 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x56, 0x02, 0xed, 0x8b, 0xe9, 0xc3, 0x8b,
- 0xcd, 0x8b, 0xec, 0x8b, 0x56, 0x02, 0x8b, 0x46, 0x04, 0xef, 0x8b, 0xe9, 0xc3,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x68, 0x61,
- 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x69, 0x6e, 0x63, 0x2c, 0x76, 0x20, 0x39, 0x2e,
- 0x37, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x33, 0x2f, 0x31, 0x38, 0x20,
- 0x32, 0x30, 0x3a, 0x34, 0x34, 0x3a, 0x34, 0x37, 0x20, 0x72, 0x69, 0x63, 0x6b,
- 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x09, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24,
- 0x49, 0x64, 0x3a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e,
- 0x68, 0x2c, 0x76, 0x20, 0x38, 0x2e, 0x35, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f,
- 0x30, 0x34, 0x2f, 0x32, 0x39, 0x20, 0x31, 0x34, 0x3a, 0x30, 0x38, 0x3a, 0x31,
- 0x31, 0x20, 0x74, 0x6f, 0x6e, 0x69, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x68, 0x61, 0x6e,
- 0x6e, 0x65, 0x6c, 0x2e, 0x68, 0x2c, 0x76, 0x20, 0x37, 0x2e, 0x34, 0x20, 0x31,
- 0x39, 0x39, 0x37, 0x2f, 0x30, 0x33, 0x2f, 0x31, 0x38, 0x20, 0x32, 0x30, 0x3a,
- 0x31, 0x39, 0x3a, 0x35, 0x32, 0x20, 0x72, 0x69, 0x63, 0x6b, 0x20, 0x45, 0x78,
- 0x70, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20,
- 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x61, 0x73, 0x6d, 0x2c,
- 0x76, 0x20, 0x39, 0x2e, 0x31, 0x32, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x34, 0x2f, 0x32, 0x39, 0x20, 0x31, 0x34, 0x3a, 0x30, 0x37, 0x3a, 0x35, 0x39,
- 0x20, 0x74, 0x6f, 0x6e, 0x69, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x09, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x63,
- 0x63, 0x6f, 0x6d, 0x6d, 0x2e, 0x61, 0x73, 0x6d, 0x2c, 0x76, 0x20, 0x39, 0x2e,
- 0x32, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x33, 0x2f, 0x31, 0x38, 0x20,
- 0x32, 0x31, 0x3a, 0x34, 0x34, 0x3a, 0x35, 0x34, 0x20, 0x72, 0x69, 0x63, 0x6b,
- 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49,
- 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x66, 0x65, 0x70, 0x2e, 0x61, 0x73,
- 0x6d, 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x32, 0x30, 0x20, 0x31, 0x39, 0x39, 0x37,
- 0x2f, 0x30, 0x34, 0x2f, 0x32, 0x31, 0x20, 0x32, 0x30, 0x3a, 0x35, 0x35, 0x3a,
- 0x31, 0x37, 0x20, 0x74, 0x6f, 0x6e, 0x69, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e,
- 0x63, 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x63, 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x31,
- 0x30, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x34, 0x2f, 0x32, 0x39, 0x20,
- 0x31, 0x34, 0x3a, 0x30, 0x38, 0x3a, 0x30, 0x32, 0x20, 0x74, 0x6f, 0x6e, 0x69,
- 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49,
- 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x64, 0x69, 0x73, 0x70, 0x2e, 0x63,
- 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x36, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x36, 0x2f, 0x30, 0x33, 0x20, 0x31, 0x39, 0x3a, 0x32, 0x32, 0x3a, 0x32, 0x33,
- 0x20, 0x63, 0x68, 0x72, 0x69, 0x73, 0x73, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x73, 0x79, 0x6e,
- 0x63, 0x2e, 0x61, 0x73, 0x6d, 0x2c, 0x76, 0x20, 0x38, 0x2e, 0x38, 0x20, 0x31,
- 0x39, 0x39, 0x37, 0x2f, 0x30, 0x34, 0x2f, 0x32, 0x35, 0x20, 0x31, 0x39, 0x3a,
- 0x30, 0x37, 0x3a, 0x31, 0x39, 0x20, 0x74, 0x6f, 0x6e, 0x69, 0x20, 0x45, 0x78,
- 0x70, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/sys/dev/digi/con.CX.h b/sys/dev/digi/con.CX.h
deleted file mode 100644
index 8bfb77a..0000000
--- a/sys/dev/digi/con.CX.h
+++ /dev/null
@@ -1,1561 +0,0 @@
-/*-
- * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
- * based on work by Slawa Olhovchenkov
- * 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$
- */
-
-const u_char con_CX[] = {
- 0x43, 0x58, 0x02, 0x00, 0x00, 0x01, 0xff, 0x03, 0x00, 0x11, 0xb0, 0x4d, 0x00,
- 0x00, 0x00, 0x00, 0xe9, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x78, 0x63,
- 0x6f, 0x6e, 0x2e, 0x62, 0x69, 0x6e, 0x09, 0x33, 0x2e, 0x33, 0x20, 0x20, 0x30,
- 0x34, 0x2f, 0x31, 0x31, 0x2f, 0x39, 0x37, 0x20, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29,
- 0x20, 0x31, 0x39, 0x38, 0x39, 0x2d, 0x31, 0x39, 0x39, 0x37, 0x2c, 0x20, 0x44,
- 0x69, 0x67, 0x69, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x61, 0x6c, 0x2c, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x52, 0x69, 0x67,
- 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x00,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0x02, 0x01, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xa5,
- 0x08, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x05, 0x01, 0xff, 0x00,
- 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
- 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x54, 0x54, 0x39, 0x77, 0x3e, 0x38, 0x3e, 0x73, 0x39, 0x73, 0x39, 0x79, 0x06,
- 0x3f, 0x5b, 0x3f, 0x4f, 0x3f, 0x66, 0x3f, 0x6d, 0x3f, 0x7d, 0x3f, 0x07, 0x3f,
- 0x7f, 0x3f, 0x67, 0x3f, 0x3f, 0x06, 0x06, 0x06, 0x5b, 0x06, 0x4f, 0x06, 0x66,
- 0x06, 0x6d, 0x06, 0x7d, 0x06, 0x54, 0x06, 0x54, 0x5b, 0x54, 0x4f, 0x54, 0x66,
- 0x54, 0x6d, 0x54, 0x7d, 0x54, 0x07, 0x54, 0x7f, 0xe8, 0xfa, 0xa3, 0x10, 0x60,
- 0x89, 0x1e, 0x12, 0x60, 0x89, 0x0e, 0x14, 0x60, 0x89, 0x16, 0x16, 0x60, 0x89,
- 0x36, 0x18, 0x60, 0x89, 0x3e, 0x1a, 0x60, 0x89, 0x2e, 0x1c, 0x60, 0x89, 0x26,
- 0x1e, 0x60, 0x8c, 0xc8, 0xa3, 0x20, 0x60, 0x8c, 0xd8, 0xa3, 0x22, 0x60, 0x8c,
- 0xd0, 0xa3, 0x24, 0x60, 0x8c, 0xc0, 0xa3, 0x26, 0x60, 0x8b, 0xec, 0x8b, 0x46,
- 0x00, 0xa3, 0x0a, 0x60, 0x8b, 0x46, 0x02, 0xa3, 0x0c, 0x60, 0x8b, 0x46, 0x04,
- 0xa3, 0x0e, 0x60, 0x8b, 0x2e, 0x1c, 0x60, 0xa1, 0x10, 0x60, 0xb8, 0x00, 0x20,
- 0x8e, 0xc0, 0xbb, 0x40, 0x03, 0x26, 0xc6, 0x07, 0x00, 0x33, 0xc0, 0x8b, 0x1e,
- 0x0c, 0x60, 0xb9, 0x00, 0x80, 0xe2, 0xfe, 0x93, 0xa3, 0x00, 0xf1, 0xeb, 0xf5,
- 0xb8, 0x00, 0x00, 0x8e, 0xc0, 0x8b, 0xf0, 0x8b, 0xf8, 0x2e, 0x8b, 0x9c, 0x83,
- 0x00, 0x83, 0xc6, 0x02, 0x26, 0x89, 0x1d, 0x26, 0x8c, 0x4d, 0x02, 0x83, 0xc7,
- 0x04, 0x81, 0xff, 0x80, 0x00, 0x72, 0xe8, 0x26, 0xc7, 0x05, 0xff, 0x00, 0x26,
- 0x8c, 0x4d, 0x02, 0x83, 0xc7, 0x04, 0x81, 0xff, 0x00, 0x04, 0x72, 0xee, 0xc3,
- 0xfa, 0xfc, 0x8c, 0xc8, 0x8e, 0xd8, 0x8e, 0xd0, 0xf7, 0xd8, 0x05, 0x00, 0x20,
- 0xc1, 0xe0, 0x04, 0x8b, 0xe0, 0xe8, 0xb7, 0xff, 0xb8, 0x00, 0x01, 0x8e, 0xc0,
- 0x33, 0xff, 0xb9, 0x00, 0x80, 0x33, 0xc0, 0xf3, 0xab, 0x8c, 0xc8, 0x8e, 0xc0,
- 0xbf, 0x00, 0x50, 0xb9, 0x00, 0x20, 0x2b, 0xc8, 0xc1, 0xe1, 0x04, 0x2b, 0xcf,
- 0xd1, 0xe9, 0x33, 0xc0, 0xf3, 0xab, 0xb8, 0x00, 0x00, 0xba, 0xfe, 0xff, 0xef,
- 0xb8, 0xfd, 0x1f, 0xb8, 0xfc, 0x1f, 0xe7, 0xa2, 0xb8, 0x00, 0x40, 0xe7, 0x56,
- 0x33, 0xc0, 0xe7, 0x50, 0xb8, 0x00, 0x40, 0xe7, 0x5e, 0xb8, 0xfe, 0xff, 0xe7,
- 0x5a, 0xe7, 0x5c, 0x33, 0xc0, 0xe7, 0x58, 0xb8, 0x07, 0xe0, 0xe7, 0x5e, 0xb8,
- 0x00, 0x40, 0xe7, 0x66, 0x33, 0xc0, 0xe7, 0x60, 0xb8, 0x13, 0x00, 0xe7, 0x38,
- 0xb8, 0x11, 0x00, 0xe7, 0x3a, 0xe7, 0x3c, 0xb8, 0x02, 0x00, 0xe7, 0x32, 0xb8,
- 0xfd, 0x00, 0xe7, 0x28, 0x33, 0xc0, 0xe7, 0x2c, 0xfb, 0xbd, 0x00, 0x00, 0xe8,
- 0xd7, 0x3e, 0xe8, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x46,
- 0x02, 0x8b, 0xd8, 0x81, 0xe3, 0x0f, 0x0f, 0x33, 0xc3, 0x86, 0xdf, 0x0b, 0xc3,
- 0x8b, 0xd8, 0x81, 0xe3, 0x33, 0x33, 0x33, 0xc3, 0xc1, 0xc3, 0x04, 0x0b, 0xc3,
- 0x8b, 0xd8, 0x81, 0xe3, 0x55, 0x55, 0x33, 0xc3, 0xc1, 0xc3, 0x02, 0x0b, 0xc3,
- 0xd1, 0xc0, 0x8b, 0xe9, 0xc3, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xb8, 0xff, 0x20,
- 0xe7, 0xfe, 0x2e, 0xff, 0x1e, 0x32, 0x08, 0x8b, 0xcd, 0x8b, 0xec, 0xfa, 0x8a,
- 0x46, 0x02, 0xa2, 0x00, 0xf2, 0x32, 0xe4, 0xa0, 0x00, 0xf2, 0xfb, 0x8b, 0xe9,
- 0xc3, 0x8b, 0xcd, 0x8b, 0xec, 0xfa, 0x8a, 0x46, 0x02, 0xa2, 0x00, 0xf2, 0x8a,
- 0x46, 0x04, 0x8b, 0xe9, 0xa2, 0x00, 0xf2, 0xfb, 0xc3, 0x8b, 0xcd, 0x8b, 0xec,
- 0xfa, 0x8a, 0x46, 0x02, 0xa2, 0x04, 0xf2, 0x8a, 0x46, 0x04, 0x8b, 0xe9, 0xa2,
- 0x04, 0xf2, 0xfb, 0xc3, 0xfa, 0xc6, 0x06, 0x00, 0xf2, 0x07, 0x8a, 0x26, 0x00,
- 0xf2, 0xc6, 0x06, 0x00, 0xf2, 0x06, 0xa0, 0x00, 0xf2, 0xa3, 0x28, 0x60, 0xc6,
- 0x06, 0x00, 0xf2, 0x01, 0xa0, 0x00, 0xf2, 0x8a, 0x26, 0x00, 0xf2, 0xa3, 0x2a,
- 0x60, 0xfb, 0xc3, 0xfb, 0x60, 0x1e, 0x06, 0x8c, 0xd0, 0x8e, 0xd8, 0xc6, 0x06,
- 0x00, 0xf2, 0x03, 0x90, 0x90, 0xa0, 0x00, 0xf2, 0x0a, 0xc0, 0x75, 0x04, 0xff,
- 0x06, 0x01, 0x5a, 0x83, 0x2e, 0x2c, 0x60, 0x01, 0x73, 0x1c, 0xc6, 0x06, 0x00,
- 0xf2, 0x03, 0x90, 0x90, 0xa0, 0x00, 0xf2, 0xa8, 0x08, 0x75, 0x09, 0xa8, 0x20,
- 0x74, 0x0d, 0xe8, 0x71, 0x34, 0xeb, 0xe9, 0xe8, 0xe8, 0x33, 0xeb, 0xe4, 0xe8,
- 0x1b, 0xf8, 0xff, 0x06, 0x2c, 0x60, 0xfa, 0xb8, 0x00, 0x80, 0xe7, 0x22, 0x83,
- 0x3e, 0x48, 0xb0, 0x00, 0x74, 0x09, 0xc7, 0x06, 0xf2, 0xc3, 0x01, 0x00, 0xeb,
- 0x1f, 0x90, 0xc7, 0x06, 0x48, 0xb0, 0x01, 0x00, 0xc7, 0x06, 0xf2, 0xc3, 0x00,
- 0x00, 0xfb, 0xe8, 0x93, 0x31, 0xfa, 0x83, 0x3e, 0xf2, 0xc3, 0x00, 0x75, 0xee,
- 0xc7, 0x06, 0x48, 0xb0, 0x00, 0x00, 0x07, 0x1f, 0x61, 0xcf, 0x55, 0x8b, 0xec,
- 0x8b, 0x5e, 0x04, 0xba, 0xc4, 0x00, 0xb1, 0x1f, 0xfa, 0xe5, 0xc8, 0x3d, 0x32,
- 0x00, 0x77, 0x0e, 0xb8, 0x64, 0xb2, 0xe7, 0xca, 0xed, 0x03, 0xd8, 0x8b, 0xc3,
- 0xef, 0xeb, 0x11, 0x90, 0xb8, 0x64, 0xb2, 0xe7, 0xca, 0xed, 0x03, 0xd8, 0x8b,
- 0xc3, 0xef, 0xb8, 0x66, 0xb2, 0xe7, 0xca, 0xfb, 0x8b, 0xc3, 0x5d, 0xc3, 0x55,
- 0x8b, 0xec, 0x8b, 0x5e, 0x04, 0xb8, 0x64, 0xb2, 0xfa, 0xb1, 0x1f, 0xd2, 0xc5,
- 0xe7, 0xca, 0xe5, 0xc4, 0x2b, 0xd8, 0x8b, 0xc3, 0x4b, 0x81, 0xfb, 0x88, 0x13,
- 0x77, 0x07, 0xe7, 0xc8, 0xb8, 0x66, 0xb2, 0xe7, 0xca, 0xfb, 0x5d, 0xc3, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x09, 0x00, 0x06, 0x17, 0x04, 0x59, 0x03, 0x00, 0x03,
- 0x40, 0x02, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00, 0x40, 0x00, 0x30, 0x00, 0x18,
- 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x06,
- 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x40, 0x02, 0x80, 0x01, 0x01, 0x00, 0x60,
- 0x00, 0x04, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03, 0x00,
- 0x1f, 0x3f, 0x7f, 0xff, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0xc1, 0x15, 0xdd, 0x15, 0x7c, 0x16,
- 0xa3, 0x15, 0xb5, 0x15, 0xe2, 0x16, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48,
- 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15,
- 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48,
- 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15, 0x48, 0x15,
- 0x48, 0x15, 0x48, 0x15, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x02, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15,
- 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95,
- 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15,
- 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95, 0x15, 0x95,
- 0x15, 0x95, 0x15, 0x10, 0x15, 0x1e, 0x15, 0x2c, 0x15, 0x3a, 0x15, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17,
- 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19,
- 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x17, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19,
- 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14,
- 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x14, 0x19, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x45,
- 0x1d, 0x60, 0x1d, 0xfc, 0x1d, 0x27, 0x1d, 0x39, 0x1d, 0x65, 0x1e, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c,
- 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x41, 0x1f, 0x41, 0x1f,
- 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41,
- 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f,
- 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41,
- 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x41, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0xe1, 0x1c, 0x93, 0x1f, 0x93, 0x1f, 0x93,
- 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f,
- 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93,
- 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f,
- 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0x93, 0x1f, 0xef, 0x1c, 0xfd, 0x1c, 0x0b,
- 0x1d, 0x19, 0x1d, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c,
- 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c,
- 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f, 0x9c, 0x1f,
- 0x9c, 0x1f, 0x9c, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f,
- 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99, 0x1f, 0x99,
- 0x1f, 0x8a, 0x5c, 0x50, 0xf6, 0xc3, 0x0e, 0x75, 0x21, 0xf6, 0xc3, 0x40, 0x75,
- 0x08, 0xf6, 0xc3, 0x10, 0x74, 0x0a, 0xff, 0x64, 0x04, 0x8b, 0x5c, 0x02, 0x89,
- 0x1c, 0xff, 0xe3, 0x80, 0x7c, 0x49, 0x00, 0x74, 0x1a, 0xc7, 0x04, 0xaa, 0x18,
- 0xe9, 0x3d, 0x04, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc3, 0x02, 0x75,
- 0x40, 0xf6, 0xc3, 0x08, 0x75, 0x14, 0xeb, 0x61, 0x90, 0xc7, 0x04, 0x8b, 0x14,
- 0x8b, 0x6c, 0x20, 0xc6, 0x46, 0x02, 0x01, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24,
- 0xf6, 0xc4, 0x20, 0x74, 0x1f, 0x80, 0x64, 0x50, 0xf7, 0xf6, 0x44, 0x51, 0x02,
- 0x74, 0x0f, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x09, 0x8a, 0x44, 0x5d, 0x88, 0x46,
- 0x00, 0xe9, 0xb1, 0x03, 0x8a, 0x44, 0x5c, 0x88, 0x46, 0x00, 0xe9, 0xa8, 0x03,
- 0x80, 0x4c, 0x67, 0x02, 0xf6, 0x44, 0x50, 0x04, 0x75, 0x1e, 0x83, 0x7c, 0x24,
- 0xff, 0x74, 0x15, 0x8b, 0x1e, 0xbc, 0x59, 0x2b, 0x5c, 0x26, 0x81, 0xfb, 0xe8,
- 0x03, 0x77, 0x08, 0x80, 0x66, 0x06, 0xbf, 0x80, 0x64, 0x50, 0xfd, 0xe9, 0x80,
- 0x03, 0xf6, 0xc4, 0x40, 0x74, 0x1a, 0x80, 0x4c, 0x67, 0x02, 0x80, 0x4e, 0x06,
- 0x40, 0x8b, 0x5c, 0x24, 0x03, 0x1e, 0xbc, 0x59, 0x89, 0x5c, 0x26, 0x80, 0x64,
- 0x50, 0xfb, 0x80, 0x4c, 0x50, 0x02, 0xe9, 0x5e, 0x03, 0xf6, 0x44, 0x2a, 0x01,
- 0x75, 0x03, 0xe9, 0x09, 0x04, 0xb0, 0x27, 0xeb, 0x42, 0x90, 0xf6, 0x44, 0x2a,
- 0x01, 0x75, 0x03, 0xe9, 0xfb, 0x03, 0xb0, 0x28, 0xeb, 0x34, 0x90, 0xf6, 0x44,
- 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xed, 0x03, 0xb0, 0x21, 0xeb, 0x26, 0x90, 0xf6,
- 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xdf, 0x03, 0xb0, 0x29, 0xeb, 0x18, 0x90,
- 0xf6, 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xd1, 0x03, 0xb0, 0x5e, 0xeb, 0x0a,
- 0x90, 0xf6, 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0xc3, 0x03, 0x88, 0x44, 0x61,
- 0xb0, 0x5c, 0x88, 0x46, 0x00, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0x69, 0x15,
- 0xc7, 0x44, 0x02, 0x69, 0x15, 0xe9, 0xf7, 0x02, 0x8b, 0x6c, 0x20, 0x8a, 0x66,
- 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x1e, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a,
- 0x44, 0x53, 0x75, 0x13, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c,
- 0x83, 0x44, 0x30, 0x02, 0x8a, 0x44, 0x61, 0xe9, 0x85, 0x03, 0xe9, 0xcb, 0x02,
- 0xf6, 0x44, 0x2a, 0x02, 0x75, 0x03, 0xe9, 0x76, 0x03, 0x2c, 0x20, 0xe9, 0x71,
- 0x03, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x40, 0x75, 0x03, 0xe9, 0xb1, 0x02,
- 0xbb, 0x7f, 0x00, 0xe9, 0x7d, 0x01, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x80,
- 0x75, 0xf1, 0xe9, 0x9f, 0x02, 0x88, 0x46, 0x00, 0xf7, 0x44, 0x30, 0xff, 0xff,
- 0x74, 0x03, 0xff, 0x4c, 0x30, 0xf6, 0x44, 0x2b, 0x20, 0x75, 0x03, 0xe9, 0x89,
- 0x02, 0xbb, 0x02, 0x00, 0xe9, 0x55, 0x01, 0xb3, 0x18, 0x22, 0x5c, 0x2b, 0x75,
- 0x12, 0x88, 0x46, 0x00, 0x8b, 0x5c, 0x30, 0x83, 0xc3, 0x08, 0x80, 0xe3, 0xf8,
- 0x89, 0x5c, 0x30, 0xe9, 0x6a, 0x02, 0x80, 0xfb, 0x18, 0x75, 0x53, 0xb0, 0x20,
- 0x88, 0x46, 0x00, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01,
- 0x5c, 0x30, 0x4b, 0x74, 0x3c, 0x89, 0x5c, 0x32, 0x80, 0x4c, 0x50, 0x40, 0xc7,
- 0x44, 0x02, 0x22, 0x16, 0xc7, 0x04, 0x22, 0x16, 0xe9, 0x3e, 0x02, 0x8b, 0x6c,
- 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x1e, 0x8a, 0x46, 0x0c, 0x22,
- 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x13, 0xb0, 0x20, 0x88, 0x46, 0x00, 0xff,
- 0x4c, 0x32, 0x75, 0x09, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c,
- 0xe9, 0x12, 0x02, 0x88, 0x46, 0x00, 0x80, 0xfb, 0x08, 0x75, 0x14, 0x8b, 0x5c,
- 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30, 0x83, 0xfb, 0x05,
- 0x7c, 0xe4, 0xe9, 0xc8, 0x00, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07,
- 0x43, 0x01, 0x5c, 0x30, 0xbb, 0x02, 0x00, 0xe9, 0xb6, 0x00, 0xf6, 0x44, 0x2a,
- 0x20, 0x75, 0x47, 0xf6, 0x44, 0x2a, 0x04, 0x74, 0x46, 0xf6, 0x44, 0x2a, 0x10,
- 0x74, 0x07, 0xf7, 0x44, 0x30, 0xff, 0xff, 0x74, 0x34, 0xb0, 0x0d, 0x88, 0x46,
- 0x00, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xaa, 0x16, 0xc7, 0x44, 0x02, 0xaa,
- 0x16, 0xe9, 0xb6, 0x01, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20,
- 0x74, 0x24, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x19,
- 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0xb0, 0x0a, 0xeb, 0x27,
- 0x90, 0xb0, 0x0a, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x01, 0x75, 0x03, 0xe9,
- 0x84, 0x01, 0xbb, 0x05, 0x00, 0xeb, 0x51, 0x90, 0xf6, 0x44, 0x2a, 0x08, 0x75,
- 0xe6, 0xf6, 0x44, 0x2a, 0x10, 0x74, 0x06, 0x83, 0x7c, 0x30, 0x00, 0x74, 0x0f,
- 0x88, 0x46, 0x00, 0xb3, 0x06, 0x22, 0x5c, 0x2b, 0x75, 0x08, 0xc7, 0x44, 0x30,
- 0x00, 0x00, 0xe9, 0x5a, 0x01, 0x80, 0xfb, 0x02, 0x75, 0x14, 0x8b, 0x5c, 0x30,
- 0xc1, 0xeb, 0x04, 0x83, 0xc3, 0x03, 0x83, 0xfb, 0x06, 0x72, 0x14, 0xbb, 0x06,
- 0x00, 0xeb, 0x0f, 0x90, 0x80, 0xfb, 0x04, 0x75, 0x06, 0xbb, 0x05, 0x00, 0xeb,
- 0x04, 0x90, 0xbb, 0x09, 0x00, 0xc7, 0x44, 0x30, 0x00, 0x00, 0xf6, 0x44, 0x2a,
- 0x40, 0x74, 0x4d, 0x83, 0xfb, 0x20, 0x77, 0x48, 0xc1, 0xeb, 0x02, 0x74, 0x03,
- 0xbb, 0x01, 0x00, 0x43, 0x89, 0x5c, 0x32, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x44,
- 0x02, 0x59, 0x17, 0xc7, 0x04, 0x59, 0x17, 0xe9, 0x07, 0x01, 0x8b, 0x6c, 0x20,
- 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x1e, 0x8a, 0x46, 0x0c, 0x22, 0x44,
- 0x52, 0x3a, 0x44, 0x53, 0x75, 0x13, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75,
- 0x0b, 0x8a, 0x44, 0x60, 0x88, 0x46, 0x00, 0xff, 0x4c, 0x32, 0x74, 0x4d, 0xe9,
- 0xdb, 0x00, 0x83, 0xc3, 0x06, 0xc1, 0xe3, 0x04, 0x89, 0x5c, 0x32, 0x80, 0x4c,
- 0x50, 0x40, 0xc7, 0x44, 0x02, 0x9e, 0x17, 0xc7, 0x04, 0x9e, 0x17, 0xe9, 0xc2,
- 0x00, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x40, 0x74, 0x10, 0x8b,
- 0x1e, 0xbc, 0x59, 0x01, 0x5c, 0x32, 0xc7, 0x44, 0x02, 0xbc, 0x17, 0xc7, 0x04,
- 0xbc, 0x17, 0xe9, 0xa4, 0x00, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x1e,
- 0xbc, 0x59, 0x2b, 0x5c, 0x32, 0x81, 0xfb, 0xe8, 0x03, 0x77, 0xea, 0x80, 0x64,
- 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0xe9, 0x85, 0x00, 0x90, 0xc7, 0x04,
- 0xe0, 0x17, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x75,
- 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0x60, 0x8a, 0x46, 0x0c, 0x22, 0x44,
- 0x52, 0x3a, 0x44, 0x53, 0x75, 0x62, 0x8e, 0x44, 0x08, 0x26, 0x8a, 0x05, 0x47,
- 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x8a, 0xd8, 0x22, 0x5c, 0x62, 0x32,
- 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7, 0x44, 0x10, 0x80, 0x7c, 0x53, 0x00, 0x75,
- 0xbc, 0xc7, 0x04, 0x24, 0x18, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4,
- 0x20, 0x74, 0x31, 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0x1c, 0x8e, 0x44,
- 0x08, 0x26, 0x8a, 0x05, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x8a,
- 0xd8, 0x22, 0x5c, 0x62, 0x32, 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7, 0x44, 0x10,
- 0xf6, 0xc4, 0x40, 0x74, 0x08, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x44, 0x14,
- 0xf6, 0xc4, 0x01, 0x75, 0x51, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x90, 0xc7,
- 0x04, 0x70, 0x18, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74,
- 0x24, 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0x46, 0x8a, 0x46, 0x0c, 0x22,
- 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x11, 0x8e, 0x44, 0x08, 0x26, 0x8a, 0x05,
- 0x47, 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x88, 0x46, 0x00, 0xf6, 0xc4,
- 0x01, 0x75, 0x12, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x8b, 0x6c, 0x20, 0x8a,
- 0x66, 0x0a, 0xf6, 0xc4, 0x01, 0x74, 0x70, 0x90, 0xc6, 0x44, 0x49, 0x64, 0x8b,
- 0x7c, 0x12, 0x8e, 0x44, 0x10, 0x8a, 0x46, 0x00, 0x23, 0x44, 0x34, 0xff, 0x64,
- 0x06, 0xf6, 0xc4, 0x40, 0x74, 0x3a, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x44,
- 0x14, 0xeb, 0x30, 0x90, 0x90, 0x80, 0x7c, 0x53, 0x00, 0x75, 0x8c, 0xc7, 0x04,
- 0xe4, 0x18, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x20, 0x74, 0x19,
- 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0xd2, 0x8e, 0x44, 0x08, 0x26, 0x8a,
- 0x05, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x0c, 0x88, 0x46, 0x00, 0xf6,
- 0xc4, 0x01, 0x75, 0xa9, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x90, 0xff, 0x44,
- 0x30, 0x88, 0x46, 0x00, 0xf6, 0xc4, 0x01, 0x75, 0x97, 0x81, 0xc6, 0x80, 0x00,
- 0xff, 0x24, 0xfe, 0x4c, 0x49, 0x74, 0x06, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24,
- 0xc7, 0x04, 0x8b, 0x14, 0xc6, 0x46, 0x02, 0x01, 0x81, 0xc6, 0x80, 0x00, 0xff,
- 0x24, 0xb3, 0x1c, 0x22, 0x5c, 0x51, 0x75, 0x1a, 0xf6, 0x44, 0x29, 0x04, 0x74,
- 0x1c, 0xf6, 0x44, 0x29, 0x20, 0x75, 0x26, 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x18,
- 0xc7, 0x44, 0x06, 0x8f, 0x1a, 0xe9, 0x30, 0x01, 0xf6, 0xc3, 0x04, 0x75, 0x30,
- 0xeb, 0x27, 0x90, 0xc7, 0x44, 0x06, 0x99, 0x1a, 0xe9, 0x2a, 0x01, 0xc7, 0x44,
- 0x06, 0x8a, 0x1a, 0xe9, 0x13, 0x01, 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x08, 0xc7,
- 0x44, 0x06, 0xe3, 0x19, 0xeb, 0x5f, 0x90, 0xc7, 0x44, 0x06, 0xde, 0x19, 0xeb,
- 0x52, 0x90, 0x80, 0x64, 0x51, 0xf7, 0xe9, 0x05, 0x01, 0x80, 0x64, 0x53, 0xfc,
- 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0x80, 0x64, 0x54, 0xfb, 0xc7,
- 0x04, 0x44, 0x14, 0x80, 0x64, 0x51, 0xfb, 0xf6, 0x44, 0x29, 0x40, 0x75, 0x7e,
- 0x3a, 0x44, 0x5d, 0x74, 0x79, 0x3a, 0x44, 0x5c, 0x74, 0x74, 0xf6, 0x44, 0x29,
- 0x20, 0x74, 0x0a, 0x3a, 0x44, 0x5a, 0x74, 0x69, 0x3a, 0x44, 0x5b, 0x74, 0x64,
- 0xf6, 0x44, 0x5e, 0xff, 0x74, 0x09, 0x3a, 0x44, 0x5e, 0x75, 0x04, 0x80, 0x4c,
- 0x51, 0x08, 0xe9, 0xbb, 0x00, 0x3a, 0x44, 0x5e, 0x74, 0x73, 0x3a, 0x44, 0x5c,
- 0x74, 0x4e, 0x3a, 0x44, 0x5d, 0x74, 0x75, 0x3a, 0x44, 0x5a, 0x74, 0x08, 0x3a,
- 0x44, 0x5b, 0x74, 0x1e, 0xe9, 0x9f, 0x00, 0xf6, 0x44, 0x53, 0x02, 0x74, 0x0a,
- 0x80, 0x64, 0x53, 0xfd, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x3a, 0x44, 0x5b,
- 0x74, 0x06, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x80, 0x4c, 0x53, 0x02, 0xc7,
- 0x04, 0x44, 0x14, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x0d, 0x80, 0x4c, 0x51, 0x04,
- 0xc7, 0x44, 0x06, 0x3e, 0x19, 0xeb, 0x7a, 0x90, 0x90, 0x81, 0xc6, 0x80, 0x00,
- 0xff, 0x24, 0xf6, 0x44, 0x53, 0x01, 0x74, 0x12, 0x80, 0x64, 0x53, 0xfe, 0x80,
- 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0xc7, 0x04, 0x44, 0x14, 0xeb, 0xe2,
- 0x3a, 0x44, 0x5d, 0x74, 0x0f, 0xeb, 0xdb, 0x90, 0x80, 0x4c, 0x51, 0x08, 0xc7,
- 0x44, 0x06, 0x3e, 0x19, 0xeb, 0x38, 0x90, 0xf6, 0x44, 0x53, 0x01, 0x75, 0x40,
- 0x80, 0x4c, 0x53, 0x01, 0x80, 0x4c, 0x54, 0x04, 0x80, 0x4c, 0x58, 0x04, 0xc7,
- 0x04, 0x44, 0x14, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x2a, 0x80, 0x4c, 0x51, 0x04,
- 0xc7, 0x44, 0x06, 0x3e, 0x19, 0xeb, 0x1f, 0x90, 0x3a, 0x44, 0x5e, 0x74, 0xc7,
- 0x3a, 0x44, 0x5c, 0x74, 0xa2, 0x3a, 0x44, 0x5d, 0x74, 0xc9, 0x3d, 0xff, 0x00,
- 0x73, 0x20, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x74, 0x89,
- 0x7c, 0x12, 0x2b, 0x7c, 0x14, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x1c, 0x73,
- 0x57, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x90, 0x0a, 0xe4, 0x75, 0x20, 0xb3,
- 0x0c, 0x22, 0x5c, 0x28, 0x80, 0xfb, 0x08, 0x75, 0xd2, 0xaa, 0x81, 0xe7, 0xff,
- 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x46, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c,
- 0x14, 0x74, 0x3b, 0xeb, 0xc6, 0xf6, 0xc4, 0x10, 0x75, 0x7d, 0xf6, 0xc4, 0x02,
- 0x74, 0x0e, 0x80, 0x4c, 0x4f, 0x80, 0xfe, 0x44, 0x59, 0xf6, 0xc4, 0x04, 0x75,
- 0x02, 0xeb, 0xa4, 0xff, 0x06, 0xca, 0x59, 0xf6, 0x44, 0x28, 0x04, 0x75, 0xa4,
- 0xf6, 0x44, 0x28, 0x08, 0x75, 0x79, 0x32, 0xc0, 0xeb, 0x90, 0xf6, 0x44, 0x51,
- 0x02, 0x74, 0x1f, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x4f, 0x4f, 0x4f, 0x81,
- 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x12, 0x80, 0x4c, 0x59, 0x01, 0x80, 0x4c, 0x4f,
- 0x80, 0x80, 0x4c, 0x66, 0x01, 0xe9, 0x75, 0xff, 0x80, 0x4c, 0x51, 0x02, 0x8a,
- 0x44, 0x54, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46, 0x08,
- 0x08, 0x44, 0x58, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x10, 0x80, 0x4c, 0x54, 0x08,
- 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50, 0x08, 0xc7, 0x04, 0x44, 0x14, 0x81,
- 0xc6, 0x80, 0x00, 0xff, 0x24, 0x80, 0x4c, 0x66, 0x80, 0xf6, 0x44, 0x28, 0x01,
- 0x75, 0x0a, 0xf6, 0x44, 0x28, 0x02, 0x74, 0x07, 0x80, 0x4c, 0x4f, 0x01, 0xe9,
- 0x2d, 0xff, 0x32, 0xc0, 0xf6, 0x44, 0x28, 0x08, 0x74, 0x23, 0x26, 0xc6, 0x05,
- 0xff, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x22, 0xf6, 0x44,
- 0x29, 0x80, 0x75, 0x02, 0x32, 0xe4, 0x26, 0x88, 0x25, 0x47, 0x81, 0xe7, 0xff,
- 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x10, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c,
- 0x14, 0x74, 0x09, 0xe9, 0xf5, 0xfe, 0xe9, 0x66, 0xff, 0xe9, 0x62, 0xff, 0xe9,
- 0x5e, 0xff, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x4c, 0x44, 0x83, 0xc1,
- 0xb0, 0x72, 0x21, 0x8b, 0x54, 0x46, 0x8a, 0x5c, 0x50, 0xf6, 0xc3, 0x0e, 0x75,
- 0x2e, 0xf6, 0xc3, 0x40, 0x75, 0x1b, 0xf6, 0xc3, 0x10, 0x74, 0x1d, 0xf6, 0xc3,
- 0x01, 0x75, 0x0a, 0xc7, 0x04, 0xcb, 0x1f, 0xe9, 0xf1, 0x03, 0xe9, 0x1d, 0x04,
- 0xc7, 0x04, 0x83, 0x1c, 0xe9, 0x9f, 0x00, 0xc7, 0x04, 0xcd, 0x1c, 0xff, 0x64,
- 0x02, 0xc7, 0x04, 0x19, 0x20, 0xe9, 0x16, 0x04, 0xf6, 0xc3, 0x02, 0x75, 0x2d,
- 0xf6, 0xc3, 0x08, 0x75, 0x03, 0xeb, 0x50, 0x90, 0x80, 0x64, 0x50, 0xf7, 0xf6,
- 0x44, 0x51, 0x02, 0x74, 0x0c, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x06, 0x8a, 0x44,
- 0x5d, 0xeb, 0x04, 0x90, 0x8a, 0x44, 0x5c, 0x88, 0x46, 0x00, 0x03, 0xca, 0x72,
- 0x02, 0xeb, 0x9b, 0xe9, 0xd6, 0x03, 0x80, 0x4c, 0x67, 0x02, 0xf6, 0x44, 0x50,
- 0x04, 0x75, 0x20, 0x83, 0x7c, 0x24, 0xff, 0x74, 0x15, 0x8b, 0x1e, 0xbc, 0x59,
- 0x2b, 0x5c, 0x26, 0x81, 0xfb, 0xe8, 0x03, 0x77, 0x08, 0x80, 0x66, 0x06, 0xbf,
- 0x80, 0x64, 0x50, 0xfd, 0x33, 0xc9, 0xe9, 0xac, 0x03, 0xf6, 0xc4, 0x40, 0x74,
- 0x1a, 0x80, 0x4c, 0x67, 0x02, 0x80, 0x4e, 0x06, 0x40, 0x8b, 0x5c, 0x24, 0x03,
- 0x1e, 0xbc, 0x59, 0x89, 0x5c, 0x26, 0x80, 0x64, 0x50, 0xfb, 0x80, 0x4c, 0x50,
- 0x02, 0x33, 0xc9, 0xe9, 0x88, 0x03, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b,
- 0x4c, 0x44, 0x83, 0xc1, 0xb0, 0x72, 0x39, 0x8b, 0x54, 0x46, 0x8b, 0x7c, 0x0c,
- 0x3b, 0x7c, 0x0a, 0x74, 0x24, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44,
- 0x53, 0x75, 0x21, 0x8e, 0x44, 0x08, 0x26, 0x8a, 0x05, 0x47, 0x81, 0xe7, 0xff,
- 0x07, 0x8a, 0xd8, 0x22, 0x5c, 0x62, 0x32, 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7,
- 0x44, 0x12, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x19, 0x20, 0x33, 0xc9, 0xe9,
- 0x3e, 0x03, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x4c, 0x44, 0x83, 0xc1,
- 0xb0, 0x72, 0xef, 0x8b, 0x54, 0x46, 0xff, 0x64, 0x02, 0xf6, 0x44, 0x2a, 0x01,
- 0x75, 0x03, 0xe9, 0xaf, 0x02, 0xb0, 0x27, 0xe9, 0x58, 0x02, 0xf6, 0x44, 0x2a,
- 0x01, 0x75, 0x03, 0xe9, 0xa1, 0x02, 0xb0, 0x28, 0xe9, 0x4a, 0x02, 0xf6, 0x44,
- 0x2a, 0x01, 0x75, 0x03, 0xe9, 0x93, 0x02, 0xb0, 0x21, 0xe9, 0x3c, 0x02, 0xf6,
- 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0x85, 0x02, 0xb0, 0x29, 0xe9, 0x2e, 0x02,
- 0xf6, 0x44, 0x2a, 0x01, 0x75, 0x03, 0xe9, 0x77, 0x02, 0xb0, 0x5e, 0xe9, 0x20,
- 0x02, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x40, 0x75, 0x03, 0xe9, 0x6c, 0x02,
- 0xbb, 0x7f, 0x00, 0xe9, 0x7c, 0x01, 0x88, 0x46, 0x00, 0xf6, 0x44, 0x2b, 0x80,
- 0x75, 0xf1, 0xe9, 0x5a, 0x02, 0x88, 0x46, 0x00, 0x83, 0x7c, 0x30, 0x00, 0x74,
- 0x03, 0xff, 0x4c, 0x30, 0xf6, 0x44, 0x2b, 0x20, 0x75, 0x03, 0xe9, 0x45, 0x02,
- 0xbb, 0x02, 0x00, 0xe9, 0x55, 0x01, 0xb3, 0x18, 0x22, 0x5c, 0x2b, 0x75, 0x12,
- 0x88, 0x46, 0x00, 0x8b, 0x5c, 0x30, 0x83, 0xc3, 0x08, 0x80, 0xe3, 0xf8, 0x89,
- 0x5c, 0x30, 0xe9, 0x26, 0x02, 0x80, 0xfb, 0x18, 0x75, 0x50, 0x8b, 0x5c, 0x30,
- 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30, 0x89, 0x5c, 0x32, 0xc6,
- 0x46, 0x00, 0x20, 0xff, 0x4c, 0x32, 0x74, 0x30, 0x03, 0xca, 0x73, 0xf3, 0x80,
- 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7, 0x44, 0x02, 0xaa, 0x1d, 0xe9,
- 0x5e, 0x02, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x14,
- 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0x8e, 0x44, 0x08, 0x8b,
- 0x7c, 0x0c, 0xeb, 0xc7, 0xe9, 0xd6, 0x01, 0x33, 0xc9, 0xe9, 0x3d, 0x02, 0x88,
- 0x46, 0x00, 0x80, 0xfb, 0x08, 0x75, 0x14, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83,
- 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30, 0x83, 0xfb, 0x05, 0x7c, 0xdf, 0xe9, 0xcb,
- 0x00, 0x8b, 0x5c, 0x30, 0xf7, 0xd3, 0x83, 0xe3, 0x07, 0x43, 0x01, 0x5c, 0x30,
- 0xbb, 0x02, 0x00, 0xe9, 0xb9, 0x00, 0xf6, 0x44, 0x2a, 0x20, 0x75, 0x1a, 0xf6,
- 0x44, 0x2a, 0x04, 0x74, 0x4a, 0xf6, 0x44, 0x2a, 0x10, 0x74, 0x06, 0x83, 0x7c,
- 0x30, 0x00, 0x74, 0x08, 0xc6, 0x46, 0x00, 0x0d, 0x03, 0xca, 0x72, 0x05, 0xb0,
- 0x0a, 0xeb, 0x57, 0x90, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7,
- 0x44, 0x02, 0x31, 0x1e, 0xe9, 0xd7, 0x01, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52,
- 0x3a, 0x44, 0x53, 0x75, 0x11, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89,
- 0x1c, 0x8e, 0x44, 0x08, 0x8b, 0x7c, 0x0c, 0xeb, 0xcf, 0x33, 0xc9, 0xe9, 0xb9,
- 0x01, 0xc6, 0x46, 0x00, 0x0a, 0xf6, 0x44, 0x2b, 0x01, 0x75, 0x03, 0xe9, 0x40,
- 0x01, 0xbb, 0x05, 0x00, 0xeb, 0x51, 0x90, 0xf6, 0x44, 0x2a, 0x08, 0x75, 0xe7,
- 0xf6, 0x44, 0x2a, 0x10, 0x74, 0x06, 0x83, 0x7c, 0x30, 0x00, 0x74, 0x0f, 0x88,
- 0x46, 0x00, 0xb3, 0x06, 0x22, 0x5c, 0x2b, 0x75, 0x08, 0xc7, 0x44, 0x30, 0x00,
- 0x00, 0xe9, 0x16, 0x01, 0x80, 0xfb, 0x02, 0x75, 0x14, 0x8b, 0x5c, 0x30, 0xc1,
- 0xeb, 0x04, 0x83, 0xc3, 0x03, 0x83, 0xfb, 0x06, 0x72, 0x14, 0xbb, 0x06, 0x00,
- 0xeb, 0x0f, 0x90, 0x80, 0xfb, 0x04, 0x75, 0x06, 0xbb, 0x05, 0x00, 0xeb, 0x04,
- 0x90, 0xbb, 0x09, 0x00, 0xc7, 0x44, 0x30, 0x00, 0x00, 0xf6, 0x44, 0x2a, 0x40,
- 0x74, 0x54, 0x83, 0xfb, 0x20, 0x77, 0x4f, 0xc1, 0xeb, 0x02, 0x74, 0x03, 0xbb,
- 0x01, 0x00, 0x43, 0x89, 0x5c, 0x32, 0x03, 0xca, 0x72, 0x0e, 0x8a, 0x44, 0x60,
- 0x88, 0x46, 0x00, 0xff, 0x4c, 0x32, 0x75, 0xf1, 0xe9, 0xc1, 0x00, 0x80, 0x4c,
- 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7, 0x44, 0x02, 0xee, 0x1e, 0xe9, 0x1a,
- 0x01, 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x11, 0x80,
- 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0x8e, 0x44, 0x08, 0x8b, 0x7c,
- 0x0c, 0xeb, 0xc6, 0x33, 0xc9, 0xe9, 0xfc, 0x00, 0x83, 0xc3, 0x06, 0xc1, 0xe3,
- 0x03, 0x89, 0x5c, 0x32, 0x80, 0x4c, 0x50, 0x40, 0xc7, 0x04, 0xcd, 0x1c, 0xc7,
- 0x44, 0x02, 0x2e, 0x1f, 0x03, 0xca, 0x72, 0x02, 0x33, 0xc9, 0xe9, 0xda, 0x00,
- 0xff, 0x4c, 0x32, 0x75, 0x09, 0x80, 0x64, 0x50, 0xbf, 0x8b, 0x5c, 0x04, 0x89,
- 0x1c, 0x33, 0xc9, 0xe9, 0xca, 0x00, 0xf6, 0x44, 0x2a, 0x01, 0x74, 0x52, 0x88,
- 0x44, 0x61, 0xb0, 0x5c, 0x88, 0x46, 0x00, 0x83, 0x44, 0x30, 0x02, 0x03, 0xca,
- 0x72, 0x06, 0x8a, 0x44, 0x61, 0xeb, 0x40, 0x90, 0x80, 0x4c, 0x50, 0x40, 0xc7,
- 0x04, 0xcd, 0x1c, 0xc7, 0x44, 0x02, 0x6d, 0x1f, 0xe9, 0x9b, 0x00, 0x8a, 0x46,
- 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x11, 0x80, 0x64, 0x50, 0xbf,
- 0x8b, 0x5c, 0x04, 0x89, 0x1c, 0x8e, 0x44, 0x08, 0x8b, 0x7c, 0x0c, 0xeb, 0xce,
- 0x33, 0xc9, 0xeb, 0x7e, 0x90, 0x2c, 0x20, 0xeb, 0x07, 0x90, 0xf6, 0x44, 0x2a,
- 0x02, 0x75, 0xf5, 0xff, 0x44, 0x30, 0x88, 0x46, 0x00, 0x03, 0xca, 0x72, 0x65,
- 0x3b, 0x7c, 0x0a, 0x74, 0x5e, 0x26, 0x8a, 0x05, 0x47, 0x81, 0xe7, 0xff, 0x07,
- 0x8a, 0xd8, 0x22, 0x5c, 0x62, 0x32, 0xff, 0x03, 0xdb, 0x2e, 0xff, 0xa7, 0x44,
- 0x12, 0x80, 0x64, 0x50, 0xef, 0xc7, 0x04, 0x19, 0x20, 0x33, 0xc9, 0xeb, 0x41,
- 0x90, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0x8b, 0x4c, 0x44, 0x83, 0xc1, 0xb0,
- 0x72, 0x32, 0x8b, 0x54, 0x46, 0x8b, 0x7c, 0x0c, 0x3b, 0x7c, 0x0a, 0x74, 0xda,
- 0x8a, 0x46, 0x0c, 0x22, 0x44, 0x52, 0x3a, 0x44, 0x53, 0x75, 0x17, 0x8e, 0x44,
- 0x08, 0x26, 0x8a, 0x05, 0x88, 0x46, 0x00, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x03,
- 0xca, 0x72, 0x07, 0x3b, 0x7c, 0x0a, 0x75, 0xec, 0x33, 0xc9, 0x89, 0x7c, 0x0c,
- 0x89, 0x4c, 0x44, 0xf6, 0xc4, 0x01, 0x75, 0x17, 0x81, 0xc6, 0x80, 0x00, 0xff,
- 0x24, 0x8b, 0x6c, 0x20, 0x8a, 0x66, 0x0a, 0xf6, 0xc4, 0x01, 0x75, 0x06, 0x81,
- 0xc6, 0x80, 0x00, 0xff, 0x24, 0x8b, 0x7c, 0x12, 0x8e, 0x44, 0x10, 0x8a, 0x46,
- 0x00, 0x23, 0x44, 0x34, 0xff, 0x64, 0x06, 0xb3, 0x0c, 0x22, 0x5c, 0x51, 0x75,
- 0x40, 0xf6, 0x44, 0x29, 0x04, 0x74, 0x14, 0xf6, 0x44, 0x29, 0x20, 0x75, 0x1e,
- 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x10, 0xc7, 0x44, 0x06, 0x6a, 0x21, 0xe9, 0x10,
- 0x01, 0xc7, 0x44, 0x06, 0x74, 0x21, 0xe9, 0x12, 0x01, 0xc7, 0x44, 0x06, 0x65,
- 0x21, 0xe9, 0xfb, 0x00, 0x80, 0x7c, 0x5e, 0x00, 0x75, 0x08, 0xc7, 0x44, 0x06,
- 0xd6, 0x20, 0xeb, 0x5f, 0x90, 0xc7, 0x44, 0x06, 0xd1, 0x20, 0xeb, 0x52, 0x90,
- 0xf6, 0xc3, 0x04, 0x75, 0x07, 0x80, 0x64, 0x51, 0xf7, 0xe9, 0xe8, 0x00, 0x80,
- 0x64, 0x53, 0xfc, 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0x80, 0x64,
- 0x51, 0xfb, 0xf6, 0x44, 0x29, 0x40, 0x75, 0x2c, 0x3a, 0x44, 0x5d, 0x74, 0x27,
- 0x3a, 0x44, 0x5c, 0x74, 0x22, 0xf6, 0x44, 0x29, 0x20, 0x74, 0x0a, 0x3a, 0x44,
- 0x5a, 0x74, 0x17, 0x3a, 0x44, 0x5b, 0x74, 0x12, 0x80, 0x7c, 0x5e, 0x00, 0x74,
- 0x09, 0x3a, 0x44, 0x5e, 0x75, 0x04, 0x80, 0x4c, 0x51, 0x08, 0xe9, 0xa6, 0x00,
- 0xe9, 0xb2, 0x00, 0x3a, 0x44, 0x5e, 0x74, 0x5f, 0x3a, 0x44, 0x5c, 0x74, 0x3d,
- 0x3a, 0x44, 0x5d, 0x74, 0x61, 0x3a, 0x44, 0x5a, 0x74, 0x08, 0x3a, 0x44, 0x5b,
- 0x74, 0x18, 0xe9, 0x87, 0x00, 0xf6, 0x44, 0x53, 0x02, 0x74, 0x07, 0x80, 0x64,
- 0x53, 0xfd, 0xe9, 0x89, 0x00, 0x3a, 0x44, 0x5b, 0x74, 0x03, 0xe9, 0x81, 0x00,
- 0x80, 0x4c, 0x53, 0x02, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x09, 0x80, 0x4c, 0x51,
- 0x04, 0xc7, 0x44, 0x06, 0x39, 0x20, 0xeb, 0x6c, 0x90, 0xf6, 0x44, 0x53, 0x01,
- 0x74, 0x0f, 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0x80, 0x64, 0x53,
- 0xfe, 0xeb, 0x57, 0x90, 0x3a, 0x44, 0x5d, 0x74, 0x0f, 0xeb, 0x4f, 0x90, 0x80,
- 0x4c, 0x51, 0x08, 0xc7, 0x44, 0x06, 0x39, 0x20, 0xeb, 0x34, 0x90, 0xf6, 0x44,
- 0x53, 0x01, 0x75, 0x1b, 0x80, 0x4c, 0x53, 0x01, 0x80, 0x4c, 0x54, 0x04, 0x80,
- 0x4c, 0x58, 0x04, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x09, 0x80, 0x4c, 0x51, 0x04,
- 0xc7, 0x44, 0x06, 0x39, 0x20, 0xeb, 0x1f, 0x90, 0x3a, 0x44, 0x5e, 0x74, 0xcb,
- 0x3a, 0x44, 0x5c, 0x74, 0xa9, 0x3a, 0x44, 0x5d, 0x74, 0xcd, 0x3d, 0xff, 0x00,
- 0x73, 0x3b, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x55, 0x8a,
- 0x66, 0x0a, 0xf6, 0xc4, 0x01, 0x74, 0x0e, 0x8a, 0x46, 0x00, 0x23, 0x44, 0x34,
- 0xff, 0x64, 0x06, 0x0a, 0x66, 0x0a, 0xeb, 0xf2, 0xf6, 0x46, 0x04, 0x01, 0x74,
- 0xf5, 0x89, 0x7c, 0x12, 0x2b, 0x7c, 0x14, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c,
- 0x1c, 0x73, 0x63, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x0a, 0xe4, 0x75, 0x23,
- 0xb3, 0x0c, 0x22, 0x5c, 0x28, 0x80, 0xfb, 0x08, 0x75, 0xb7, 0xaa, 0x81, 0xe7,
- 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x53, 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b,
- 0x7c, 0x14, 0x74, 0x48, 0xeb, 0xab, 0xeb, 0x45, 0x90, 0xf6, 0xc4, 0x10, 0x75,
- 0x28, 0xf6, 0xc4, 0x02, 0x74, 0x0e, 0x80, 0x4c, 0x4f, 0x80, 0xfe, 0x44, 0x59,
- 0xf6, 0xc4, 0x04, 0x75, 0x02, 0xeb, 0x86, 0xff, 0x06, 0xca, 0x59, 0xf6, 0x44,
- 0x28, 0x04, 0x75, 0x0e, 0xf6, 0x44, 0x28, 0x08, 0x75, 0x0b, 0x32, 0xc0, 0xe9,
- 0x71, 0xff, 0xeb, 0x5f, 0x90, 0xe9, 0x75, 0xff, 0xeb, 0x7c, 0x90, 0xf6, 0x44,
- 0x51, 0x02, 0x74, 0x1f, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0x4f, 0x4f, 0x4f,
- 0x81, 0xe7, 0xff, 0x07, 0x89, 0x7c, 0x12, 0x80, 0x4c, 0x59, 0x01, 0x80, 0x4c,
- 0x4f, 0x80, 0x80, 0x4c, 0x66, 0x01, 0xe9, 0x4d, 0xff, 0x80, 0x4c, 0x51, 0x02,
- 0x8a, 0x44, 0x54, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46,
- 0x08, 0x08, 0x44, 0x58, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x12, 0x80, 0x4c, 0x54,
- 0x08, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50, 0x08, 0x8b, 0x1e, 0x40, 0x60,
- 0x89, 0x1c, 0x81, 0xc6, 0x80, 0x00, 0xff, 0x24, 0xff, 0x06, 0xcc, 0x59, 0x80,
- 0x4c, 0x66, 0x80, 0xf6, 0x44, 0x28, 0x01, 0x75, 0x0a, 0xf6, 0x44, 0x28, 0x02,
- 0x74, 0x07, 0x80, 0x4c, 0x4f, 0x01, 0xe9, 0xff, 0xfe, 0x32, 0xc0, 0xf6, 0x44,
- 0x28, 0x08, 0x74, 0x23, 0x26, 0xc6, 0x05, 0xff, 0x47, 0x81, 0xe7, 0xff, 0x07,
- 0x3b, 0x7c, 0x14, 0x74, 0x22, 0xf6, 0x44, 0x29, 0x80, 0x75, 0x02, 0x32, 0xe4,
- 0x26, 0x88, 0x25, 0x47, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x10,
- 0xaa, 0x81, 0xe7, 0xff, 0x07, 0x3b, 0x7c, 0x14, 0x74, 0x09, 0xe9, 0xc7, 0xfe,
- 0xe9, 0x60, 0xff, 0xe9, 0x5c, 0xff, 0xe9, 0x58, 0xff, 0x50, 0x55, 0x36, 0x8a,
- 0x26, 0x00, 0xf3, 0xbd, 0x80, 0x53, 0xeb, 0x1b, 0x90, 0x50, 0x55, 0x36, 0x8a,
- 0x26, 0x01, 0xf3, 0xbd, 0x80, 0x57, 0xeb, 0x0e, 0x90, 0xbd, 0x80, 0x57, 0x0a,
- 0xe4, 0x75, 0x06, 0x81, 0xed, 0x00, 0x04, 0x8a, 0xe0, 0xf6, 0xc4, 0xf0, 0x75,
- 0x07, 0x81, 0xed, 0x00, 0x02, 0xc0, 0xe4, 0x04, 0xf6, 0xc4, 0xc0, 0x75, 0x08,
- 0x81, 0xed, 0x00, 0x01, 0x02, 0xe4, 0x02, 0xe4, 0x78, 0x04, 0x81, 0xed, 0x80,
- 0x00, 0xc7, 0x46, 0x00, 0x44, 0x14, 0xc6, 0x46, 0x49, 0x01, 0x8b, 0x6e, 0x20,
- 0xc6, 0x46, 0x02, 0x00, 0x36, 0xa1, 0x00, 0xf3, 0x0b, 0xc0, 0x75, 0xbc, 0xb8,
- 0x00, 0x80, 0xe7, 0x22, 0x5d, 0x58, 0xcf, 0x50, 0x36, 0x83, 0x06, 0xbc, 0x59,
- 0x02, 0x36, 0xff, 0x06, 0xd6, 0xc3, 0x36, 0x81, 0x3e, 0xd6, 0xc3, 0x88, 0x13,
- 0x73, 0x04, 0x33, 0xc0, 0xe7, 0x58, 0xb8, 0x00, 0x80, 0xe7, 0x22, 0x58, 0xcf,
- 0x60, 0x1e, 0x06, 0x8c, 0xd0, 0x8e, 0xd8, 0xfb, 0xbe, 0x00, 0x50, 0xff, 0x24,
- 0xfa, 0xb8, 0x08, 0x00, 0xe7, 0x22, 0xb8, 0x00, 0xe0, 0xe7, 0x66, 0xff, 0x0e,
- 0x3e, 0x60, 0x75, 0x22, 0xc7, 0x06, 0x3e, 0x60, 0x04, 0x00, 0x8b, 0x36, 0x30,
- 0x60, 0x8b, 0x6c, 0x20, 0x8a, 0x46, 0x0c, 0x32, 0x44, 0x54, 0x24, 0xf0, 0x30,
- 0x44, 0x54, 0x08, 0x44, 0x58, 0x03, 0x74, 0x1e, 0x89, 0x36, 0x30, 0x60, 0x07,
- 0x1f, 0x61, 0xcf, 0x60, 0x1e, 0x06, 0x8c, 0xd0, 0x8e, 0xd8, 0xff, 0x06, 0xd6,
- 0xc3, 0x81, 0x3e, 0xd6, 0xc3, 0xa0, 0x05, 0x73, 0x04, 0x33, 0xc0, 0xe7, 0x58,
- 0xb8, 0xfe, 0xff, 0xe7, 0x52, 0xb8, 0x08, 0x00, 0xe7, 0x22, 0xe5, 0x58, 0xa3,
- 0xc0, 0x59, 0x83, 0x06, 0xbc, 0x59, 0x00, 0x81, 0x2e, 0x3c, 0x60, 0xe8, 0x03,
- 0x73, 0x0a, 0xff, 0x06, 0xbc, 0x59, 0x81, 0x06, 0x3c, 0x60, 0xa0, 0x05, 0xbe,
- 0x00, 0x50, 0xff, 0x24, 0x8b, 0x36, 0x30, 0x60, 0x8b, 0x6c, 0x20, 0x8a, 0x46,
- 0x0c, 0x32, 0x44, 0x54, 0x24, 0xf0, 0x30, 0x44, 0x54, 0x08, 0x44, 0x58, 0x03,
- 0x74, 0x1e, 0x89, 0x36, 0x30, 0x60, 0xe5, 0x50, 0x8b, 0xd8, 0xc1, 0xe8, 0x02,
- 0x03, 0xd8, 0x89, 0x1e, 0xc2, 0x59, 0xa1, 0xbe, 0x59, 0x2b, 0xd8, 0xc1, 0xfb,
- 0x02, 0x03, 0xc3, 0x3d, 0xc0, 0x03, 0x77, 0x03, 0xb8, 0xc0, 0x03, 0xa3, 0xbe,
- 0x59, 0x3d, 0x00, 0x05, 0x77, 0x03, 0xb8, 0x00, 0x05, 0xe7, 0x52, 0x8b, 0xd8,
- 0xa3, 0xc4, 0x59, 0xe5, 0x50, 0x3b, 0xc3, 0x72, 0x0e, 0x89, 0x1e, 0xc6, 0x59,
- 0xa3, 0xc8, 0x59, 0x33, 0xc0, 0xe7, 0x50, 0xe9, 0x74, 0xff, 0x07, 0x1f, 0x61,
- 0xcf, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x89, 0x3e, 0x32, 0x60,
- 0x8b, 0x56, 0x06, 0x03, 0xd7, 0x89, 0x16, 0x34, 0x60, 0xc7, 0x06, 0x4a, 0x60,
- 0x4c, 0x60, 0x8c, 0xda, 0x8e, 0xc2, 0x80, 0x3e, 0x6c, 0x60, 0x00, 0x74, 0x33,
- 0xb8, 0xf4, 0xb3, 0xab, 0xb8, 0xc3, 0x95, 0xab, 0xbe, 0x6c, 0x60, 0xb9, 0x0a,
- 0x00, 0xf3, 0xa4, 0x32, 0xdb, 0x86, 0x1e, 0x6c, 0x60, 0x80, 0xfb, 0x02, 0x74,
- 0x18, 0x8b, 0x0e, 0x74, 0x60, 0x8b, 0x36, 0x70, 0x60, 0xa1, 0x71, 0x60, 0x81,
- 0xe6, 0xff, 0x00, 0xc1, 0xe0, 0x04, 0x8e, 0xd8, 0xf3, 0xa4, 0x8e, 0xda, 0xeb,
- 0x41, 0x90, 0xc7, 0x44, 0x2e, 0x00, 0x00, 0xb0, 0xb0, 0x02, 0x44, 0x65, 0xb4,
- 0x01, 0x89, 0x05, 0xb8, 0xff, 0x07, 0x89, 0x45, 0x02, 0x83, 0xc7, 0x04, 0xeb,
- 0x36, 0x90, 0xb0, 0xc0, 0x02, 0x44, 0x65, 0xfa, 0x32, 0xe4, 0x86, 0x64, 0x4f,
- 0x89, 0x05, 0x8a, 0x44, 0x57, 0x32, 0x44, 0x58, 0x88, 0x44, 0x57, 0x88, 0x45,
- 0x02, 0x32, 0x44, 0x54, 0x88, 0x44, 0x58, 0xfb, 0x83, 0xc7, 0x03, 0xeb, 0x18,
- 0x90, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00, 0x50, 0x8b, 0x54, 0x2e, 0x83, 0xfa,
- 0x00, 0x75, 0xb1, 0x8a, 0x44, 0x4f, 0x0a, 0x44, 0x58, 0x75, 0xc3, 0x8b, 0x44,
- 0x38, 0x8b, 0x5c, 0x0a, 0x2b, 0x5c, 0x0c, 0x81, 0xe3, 0xff, 0x07, 0x75, 0x0c,
- 0x3b, 0x44, 0x3a, 0x74, 0x18, 0xf6, 0x44, 0x50, 0x16, 0x74, 0x3d, 0x43, 0x2b,
- 0xc3, 0x8b, 0xd8, 0x2b, 0x5c, 0x3a, 0xba, 0xff, 0x07, 0xc1, 0xea, 0x02, 0x3b,
- 0xda, 0x77, 0x2b, 0x8b, 0x5c, 0x42, 0x8b, 0x44, 0x3c, 0x2b, 0x44, 0x3e, 0x25,
- 0xff, 0xff, 0x2b, 0xd8, 0x8b, 0x44, 0x12, 0x2b, 0x44, 0x14, 0x25, 0xff, 0x07,
- 0x3b, 0xc3, 0x72, 0x02, 0x8b, 0xc3, 0x3d, 0x00, 0x00, 0x75, 0x1b, 0x81, 0xc6,
- 0x80, 0x00, 0xe2, 0x9c, 0xeb, 0x46, 0x90, 0xb3, 0xa0, 0x02, 0x5c, 0x65, 0x88,
- 0x1d, 0x89, 0x45, 0x01, 0x89, 0x44, 0x3a, 0x83, 0xc7, 0x03, 0xeb, 0xc3, 0x3d,
- 0xf4, 0x01, 0x72, 0x03, 0xb8, 0xf4, 0x01, 0x89, 0x44, 0x40, 0x57, 0x8b, 0x1e,
- 0x4a, 0x60, 0x81, 0xfb, 0x4c, 0x60, 0x74, 0x13, 0x8b, 0x7f, 0xfe, 0x3b, 0x45,
- 0x40, 0x73, 0x0b, 0x89, 0x3f, 0x83, 0xeb, 0x02, 0x81, 0xfb, 0x4c, 0x60, 0x75,
- 0xed, 0x89, 0x37, 0x83, 0x06, 0x4a, 0x60, 0x02, 0x5f, 0xeb, 0xb2, 0x8b, 0x0e,
- 0x4a, 0x60, 0x81, 0xe9, 0x4c, 0x60, 0xd1, 0xe9, 0x74, 0x09, 0xa1, 0x34, 0x60,
- 0x2b, 0xc7, 0x2b, 0xc1, 0x7f, 0x03, 0xe9, 0xfb, 0x00, 0xa3, 0x36, 0x60, 0xc7,
- 0x06, 0x38, 0x60, 0x00, 0x00, 0xbb, 0x4c, 0x60, 0x8b, 0x37, 0x83, 0x3e, 0x36,
- 0x60, 0x00, 0x74, 0x2f, 0x8b, 0x44, 0x40, 0x2b, 0x06, 0x38, 0x60, 0xf7, 0xe1,
- 0x3b, 0x06, 0x36, 0x60, 0x77, 0x0d, 0x29, 0x06, 0x36, 0x60, 0x8b, 0x44, 0x40,
- 0xa3, 0x38, 0x60, 0xeb, 0x14, 0x90, 0x33, 0xd2, 0xa1, 0x36, 0x60, 0x48, 0xf7,
- 0xf1, 0x40, 0x01, 0x06, 0x38, 0x60, 0xc7, 0x06, 0x36, 0x60, 0x00, 0x00, 0x51,
- 0x8b, 0x0e, 0x38, 0x60, 0x8a, 0x44, 0x65, 0x83, 0xf9, 0x08, 0x77, 0x10, 0x8a,
- 0xe1, 0xfe, 0xcc, 0xc0, 0xe4, 0x04, 0x80, 0xc4, 0x00, 0x02, 0xc4, 0xaa, 0xeb,
- 0x15, 0x90, 0x81, 0xf9, 0xff, 0x00, 0x77, 0x08, 0x0c, 0x80, 0x8a, 0xe1, 0xab,
- 0xeb, 0x07, 0x90, 0x0c, 0x90, 0xaa, 0x8b, 0xc1, 0xab, 0x51, 0x8b, 0x44, 0x14,
- 0xba, 0xff, 0x07, 0x42, 0x2b, 0xd0, 0x8e, 0x5c, 0x10, 0x3b, 0xca, 0x72, 0x0d,
- 0x2b, 0xca, 0x96, 0x87, 0xca, 0xf3, 0xa4, 0x8b, 0xf0, 0x33, 0xc0, 0x8b, 0xca,
- 0x96, 0xf3, 0xa4, 0x96, 0x8c, 0xc1, 0x8e, 0xd9, 0xfa, 0x59, 0x01, 0x4c, 0x3c,
- 0x89, 0x44, 0x14, 0xf6, 0x44, 0x51, 0x02, 0x74, 0x47, 0x8b, 0x44, 0x12, 0x2b,
- 0x44, 0x14, 0x25, 0xff, 0x07, 0x3b, 0x44, 0x1a, 0x77, 0x39, 0x80, 0x64, 0x51,
- 0xfd, 0x55, 0x8b, 0x6c, 0x20, 0xf6, 0x44, 0x29, 0x10, 0x74, 0x17, 0x80, 0x64,
- 0x54, 0xf7, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50, 0x08, 0xa0, 0x2f, 0x60,
- 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0x8a, 0x44, 0x54, 0xf6, 0xd0,
- 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46, 0x08, 0x08, 0x44,
- 0x58, 0x5d, 0xfb, 0x83, 0xc3, 0x02, 0x59, 0x49, 0x74, 0x03, 0xe9, 0x11, 0xff,
- 0x2b, 0x3e, 0x32, 0x60, 0x8b, 0xc7, 0x5f, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x89, 0x3e, 0x32, 0x60, 0x8b, 0x56, 0x06, 0x03,
- 0xd7, 0x89, 0x16, 0x34, 0x60, 0xc6, 0x06, 0x77, 0x60, 0x00, 0x3b, 0x3e, 0x34,
- 0x60, 0x73, 0x1c, 0x8a, 0x25, 0x8b, 0xf0, 0x81, 0xe6, 0x00, 0x0f, 0xd1, 0xee,
- 0x81, 0xc6, 0x00, 0x50, 0x8a, 0xdc, 0x81, 0xe3, 0xf0, 0x00, 0xc1, 0xeb, 0x03,
- 0x2e, 0xff, 0xa7, 0xec, 0x26, 0x74, 0x06, 0xb8, 0x0e, 0x00, 0xeb, 0x03, 0x90,
- 0x33, 0xc0, 0x5f, 0x5e, 0x5d, 0xc3, 0x0d, 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x0d,
- 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x0d, 0x27, 0x1a, 0x27, 0x25, 0x27,
- 0x96, 0x27, 0xac, 0x27, 0x9b, 0x28, 0x9b, 0x28, 0x9b, 0x28, 0xc9, 0x27, 0xc3,
- 0x8a, 0xcc, 0xc0, 0xe9, 0x04, 0x83, 0xe1, 0x07, 0x41, 0x47, 0xeb, 0x12, 0x90,
- 0x8a, 0x4d, 0x01, 0x32, 0xed, 0x83, 0xc7, 0x02, 0xeb, 0x07, 0x90, 0x8b, 0x4d,
- 0x01, 0x83, 0xc7, 0x03, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x74, 0x04, 0x03, 0xf9,
- 0xeb, 0x86, 0x01, 0x4c, 0x38, 0x8b, 0x5c, 0x0a, 0x8b, 0x54, 0x0c, 0x2b, 0xd3,
- 0x4a, 0x81, 0xe2, 0xff, 0x07, 0x3b, 0xca, 0x76, 0x05, 0xb8, 0x0d, 0x00, 0xeb,
- 0x99, 0x8e, 0x44, 0x08, 0xba, 0xff, 0x07, 0x42, 0x2b, 0xd3, 0x3b, 0xca, 0x72,
- 0x12, 0x2b, 0xca, 0x87, 0xf7, 0x87, 0xfb, 0x87, 0xca, 0xf3, 0xa4, 0x87, 0xfb,
- 0x87, 0xf7, 0x8b, 0xca, 0x33, 0xdb, 0x87, 0xf7, 0x87, 0xfb, 0xf3, 0xa4, 0x87,
- 0xfb, 0x87, 0xf7, 0x89, 0x5c, 0x0a, 0xf6, 0x44, 0x50, 0x10, 0x75, 0x12, 0x80,
- 0x4c, 0x50, 0x10, 0x8b, 0x6c, 0x20, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1,
- 0x40, 0x60, 0x89, 0x04, 0xe9, 0x26, 0xff, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x75,
- 0x09, 0x8b, 0x6c, 0x20, 0x8b, 0x45, 0x01, 0x89, 0x44, 0x3e, 0x83, 0xc7, 0x03,
- 0xe9, 0x10, 0xff, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x75, 0x10, 0x8b, 0x6c, 0x20,
- 0x8a, 0x5d, 0x01, 0x83, 0xe3, 0x0f, 0xd0, 0xe3, 0x2e, 0xff, 0xa7, 0xa1, 0x28,
- 0x83, 0xc7, 0x04, 0xe9, 0xf3, 0xfe, 0x80, 0x3d, 0xf4, 0x74, 0x5f, 0x80, 0x3d,
- 0xfe, 0x74, 0x48, 0x80, 0x3d, 0xff, 0x74, 0x46, 0x80, 0x3d, 0xf0, 0x75, 0x0b,
- 0xc6, 0x06, 0x77, 0x60, 0x00, 0x83, 0xc7, 0x01, 0xe9, 0xd4, 0xfe, 0x80, 0x3d,
- 0xf1, 0x75, 0x0b, 0xc6, 0x06, 0x77, 0x60, 0x01, 0x83, 0xc7, 0x01, 0xe9, 0xc4,
- 0xfe, 0x80, 0x3d, 0xf2, 0x75, 0x0b, 0xc6, 0x06, 0x77, 0x60, 0x02, 0x83, 0xc7,
- 0x01, 0xe9, 0xb4, 0xfe, 0x80, 0x3d, 0xf3, 0x75, 0x0b, 0xc6, 0x06, 0x77, 0x60,
- 0x03, 0x83, 0xc7, 0x01, 0xe9, 0xa4, 0xfe, 0xe9, 0x80, 0x00, 0xe9, 0xc8, 0xfe,
- 0x83, 0xc7, 0x01, 0xe9, 0x98, 0xfe, 0x83, 0xc7, 0x04, 0x03, 0x7d, 0x08, 0xe9,
- 0x8f, 0xfe, 0x80, 0x3e, 0x77, 0x60, 0x00, 0x75, 0xf0, 0x80, 0x3d, 0xff, 0x75,
- 0x04, 0x47, 0xe9, 0x7f, 0xfe, 0x81, 0x3d, 0xf4, 0xb3, 0x75, 0x13, 0x81, 0x7d,
- 0x02, 0xc3, 0x95, 0x75, 0x0c, 0x83, 0xc7, 0x04, 0x8b, 0x4d, 0x08, 0x81, 0xf9,
- 0x80, 0x00, 0x76, 0x06, 0xb8, 0x0c, 0x00, 0xe9, 0x8c, 0xfe, 0x8c, 0xd8, 0x8e,
- 0xc0, 0x8b, 0xf7, 0xbf, 0x6c, 0x60, 0xb9, 0x0a, 0x00, 0xf3, 0xa4, 0x80, 0x3e,
- 0x6c, 0x60, 0x02, 0x75, 0x1b, 0x8b, 0x0e, 0x74, 0x60, 0x8b, 0x3e, 0x70, 0x60,
- 0xa1, 0x71, 0x60, 0x81, 0xe7, 0xff, 0x00, 0xc1, 0xe0, 0x04, 0x8e, 0xc0, 0xfa,
- 0xf3, 0xa4, 0xfb, 0xeb, 0x0b, 0x90, 0x80, 0x3e, 0x6c, 0x60, 0x04, 0x75, 0x03,
- 0xe8, 0xa0, 0xdf, 0x8b, 0xfe, 0xe9, 0x21, 0xfe, 0xb8, 0x0a, 0x00, 0xe9, 0x47,
- 0xfe, 0x26, 0x29, 0xe1, 0x29, 0xed, 0x29, 0x09, 0x2a, 0x25, 0x2a, 0x5b, 0x2a,
- 0xf2, 0x2a, 0x3e, 0x2b, 0xe2, 0x2b, 0x93, 0x2b, 0x14, 0x2c, 0x60, 0x2c, 0x26,
- 0x2c, 0x6f, 0x2c, 0x7e, 0x2c, 0x84, 0x2c, 0xfa, 0xe8, 0xc5, 0x03, 0xfb, 0x8b,
- 0x55, 0x02, 0xeb, 0x62, 0x90, 0xfa, 0x80, 0x4c, 0x53, 0x01, 0x80, 0x4c, 0x54,
- 0x04, 0x80, 0x4c, 0x58, 0x04, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0x8b, 0x1e,
- 0x40, 0x60, 0x89, 0x1c, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x0b, 0x80, 0x4c, 0x51,
- 0x04, 0x8b, 0x1e, 0x46, 0x60, 0x89, 0x5c, 0x06, 0xfb, 0xeb, 0x38, 0x90, 0xfa,
- 0x80, 0x64, 0x53, 0xfe, 0x80, 0x64, 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0xa0,
- 0x2f, 0x60, 0x88, 0x46, 0x02, 0x8b, 0x1e, 0x40, 0x60, 0x89, 0x1c, 0x80, 0x64,
- 0x51, 0xfb, 0xfb, 0xeb, 0x1b, 0x90, 0x80, 0x4c, 0x4f, 0x40, 0xfb, 0x83, 0xc7,
- 0x04, 0xe9, 0x96, 0xfd, 0x8a, 0x45, 0x02, 0xa8, 0x01, 0x75, 0x94, 0xa8, 0x40,
- 0x75, 0x9b, 0xa8, 0x80, 0x75, 0xc5, 0xa8, 0x10, 0x75, 0x0e, 0xa8, 0x20, 0x75,
- 0x57, 0xa8, 0x02, 0x75, 0xda, 0x83, 0xc7, 0x04, 0xe9, 0x75, 0xfd, 0xfa, 0xf6,
- 0x44, 0x51, 0x02, 0x75, 0x40, 0x8b, 0x44, 0x12, 0x2b, 0x44, 0x14, 0x25, 0xff,
- 0x07, 0x3b, 0x44, 0x1a, 0x72, 0x32, 0x80, 0x4c, 0x51, 0x02, 0xf6, 0x44, 0x29,
- 0x10, 0x74, 0x17, 0x80, 0x4c, 0x54, 0x08, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74,
- 0x50, 0x08, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04,
- 0x8a, 0x44, 0x54, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30, 0x46,
- 0x08, 0x08, 0x44, 0x58, 0x8a, 0x45, 0x02, 0xfb, 0xeb, 0xa5, 0xfa, 0xf6, 0x44,
- 0x51, 0x02, 0x74, 0x42, 0x8b, 0x44, 0x12, 0x2b, 0x44, 0x14, 0x25, 0xff, 0x07,
- 0x3b, 0x44, 0x1c, 0x77, 0xe5, 0x80, 0x64, 0x51, 0xfd, 0xf6, 0x44, 0x29, 0x10,
- 0x74, 0x17, 0x80, 0x64, 0x54, 0xf7, 0x80, 0x4c, 0x58, 0x08, 0x80, 0x74, 0x50,
- 0x08, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0x8a,
- 0x44, 0x54, 0xf6, 0xd0, 0x22, 0x44, 0x5f, 0x24, 0x0f, 0x30, 0x44, 0x54, 0x30,
- 0x46, 0x08, 0x08, 0x44, 0x58, 0xfb, 0xe9, 0x5c, 0xff, 0x8b, 0x45, 0x02, 0x89,
- 0x44, 0x42, 0x83, 0xc7, 0x04, 0xe9, 0xcf, 0xfc, 0x8b, 0x45, 0x02, 0x51, 0x52,
- 0x33, 0xd2, 0xb9, 0x00, 0x08, 0xf7, 0xe1, 0xb9, 0x00, 0x80, 0xf7, 0xf1, 0x5a,
- 0x59, 0x89, 0x44, 0x1a, 0x83, 0xc7, 0x04, 0xe9, 0xb3, 0xfc, 0x8b, 0x45, 0x02,
- 0x51, 0x52, 0x33, 0xd2, 0xb9, 0x00, 0x08, 0xf7, 0xe1, 0xb9, 0x00, 0x80, 0xf7,
- 0xf1, 0x5a, 0x59, 0x89, 0x44, 0x1c, 0x83, 0xc7, 0x04, 0xe9, 0x97, 0xfc, 0xfa,
- 0x8b, 0x44, 0x38, 0x2b, 0x45, 0x02, 0x8b, 0x5c, 0x0a, 0x2b, 0x5c, 0x0c, 0x81,
- 0xe3, 0xff, 0x07, 0x3b, 0xc3, 0x73, 0x1a, 0xf7, 0xd8, 0x03, 0x44, 0x0a, 0x25,
- 0xff, 0x07, 0x89, 0x44, 0x0c, 0x80, 0x64, 0x50, 0xbf, 0xa0, 0x2f, 0x60, 0x88,
- 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0x61,
- 0xfc, 0x8b, 0x5d, 0x02, 0x88, 0x5c, 0x2c, 0x88, 0x7c, 0x2d, 0x8b, 0xcb, 0x83,
- 0xe3, 0x0f, 0x03, 0xdb, 0xf6, 0xc5, 0x04, 0x75, 0x08, 0x2e, 0x8b, 0x9f, 0x00,
- 0x10, 0xeb, 0x06, 0x90, 0x2e, 0x8b, 0x9f, 0x20, 0x10, 0x8a, 0xe1, 0x80, 0xe4,
- 0x30, 0xc0, 0xec, 0x04, 0x8a, 0xc4, 0x04, 0x07, 0xf6, 0xc1, 0x40, 0x74, 0x05,
- 0x80, 0xcc, 0x04, 0xfe, 0xc0, 0xf6, 0xc5, 0x01, 0x74, 0x0d, 0x80, 0xcc, 0x08,
- 0xfe, 0xc0, 0xf6, 0xc5, 0x02, 0x75, 0x03, 0x80, 0xcc, 0x10, 0xf6, 0xc5, 0x08,
- 0x74, 0x03, 0x80, 0xcc, 0x20, 0xfa, 0x80, 0x4e, 0x06, 0x80, 0xc6, 0x46, 0x00,
- 0xff, 0xc6, 0x46, 0x02, 0xff, 0x88, 0x5e, 0x00, 0x88, 0x7e, 0x02, 0x32, 0x66,
- 0x06, 0x80, 0xe4, 0xbf, 0x30, 0x66, 0x06, 0x32, 0xe4, 0xf7, 0xe3, 0x89, 0x44,
- 0x46, 0x8a, 0xd9, 0x83, 0xe3, 0x30, 0xc0, 0xeb, 0x04, 0x2e, 0x8a, 0x87, 0x40,
- 0x10, 0x88, 0x44, 0x62, 0xf6, 0x44, 0x28, 0x20, 0x74, 0x02, 0x24, 0x7f, 0x88,
- 0x44, 0x34, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0xca, 0xfb, 0x8b, 0x5d, 0x02, 0xfa,
- 0x8a, 0x44, 0x29, 0x32, 0xc7, 0xa8, 0x10, 0x74, 0x15, 0xf6, 0x44, 0x51, 0x02,
- 0x74, 0x0f, 0x80, 0x74, 0x50, 0x08, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xa1,
- 0x40, 0x60, 0x89, 0x04, 0x88, 0x5c, 0x28, 0x88, 0x7c, 0x29, 0xfb, 0xb4, 0x1a,
- 0xf6, 0xc3, 0x10, 0x74, 0x03, 0x80, 0xcc, 0x04, 0x8a, 0x44, 0x62, 0xf6, 0xc3,
- 0x20, 0x74, 0x02, 0x24, 0x7f, 0x89, 0x44, 0x34, 0xa1, 0x46, 0x60, 0x89, 0x44,
- 0x06, 0x83, 0xc7, 0x04, 0xe9, 0x7e, 0xfb, 0x8b, 0x45, 0x02, 0xfa, 0x88, 0x44,
- 0x2a, 0x88, 0x64, 0x2b, 0x0b, 0xc0, 0x75, 0x0e, 0x80, 0x64, 0x50, 0xfe, 0x8b,
- 0x1e, 0x42, 0x60, 0x89, 0x5c, 0x04, 0xeb, 0x17, 0x90, 0xf6, 0x44, 0x50, 0x01,
- 0x75, 0x10, 0x80, 0x4c, 0x50, 0x01, 0x8b, 0x1e, 0x44, 0x60, 0x89, 0x5c, 0x04,
- 0xc7, 0x44, 0x30, 0x00, 0x00, 0xfb, 0xa8, 0x80, 0x75, 0x07, 0xc6, 0x44, 0x60,
- 0x00, 0xeb, 0x05, 0x90, 0xc6, 0x44, 0x60, 0x7f, 0xfa, 0xa0, 0x2f, 0x60, 0x88,
- 0x46, 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0x29,
- 0xfb, 0x8b, 0x5d, 0x02, 0x8b, 0xd3, 0xfa, 0x88, 0x5c, 0x5f, 0x88, 0x7c, 0x69,
- 0x8a, 0x44, 0x52, 0x8a, 0x64, 0x53, 0x8a, 0xfb, 0x33, 0xc3, 0x25, 0x0f, 0x0f,
- 0x33, 0xc3, 0x88, 0x44, 0x52, 0x88, 0x64, 0x53, 0xa0, 0x2f, 0x60, 0x88, 0x46,
- 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xf6, 0xd3, 0x22, 0x5c, 0x68, 0xf6, 0x44,
- 0x51, 0x02, 0x75, 0x02, 0x0a, 0xdf, 0x32, 0x5c, 0x54, 0x80, 0xe3, 0x0f, 0x30,
- 0x5c, 0x54, 0x30, 0x5e, 0x08, 0x08, 0x5c, 0x58, 0xfb, 0x83, 0xc7, 0x04, 0xe9,
- 0xda, 0xfa, 0x8a, 0x5d, 0x02, 0x88, 0x5c, 0x68, 0x8a, 0xc3, 0x8a, 0x7c, 0x5f,
- 0x8a, 0xe7, 0xfa, 0x32, 0x46, 0x08, 0x80, 0xe4, 0x0f, 0xf6, 0xd4, 0x22, 0xc4,
- 0x30, 0x46, 0x08, 0x32, 0x5c, 0x54, 0xf6, 0xd7, 0x22, 0xdf, 0x80, 0xe3, 0x0f,
- 0x30, 0x5c, 0x54, 0x08, 0x5c, 0x58, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0xa8, 0xfa,
- 0x8a, 0x45, 0x02, 0x88, 0x44, 0x5e, 0xa1, 0x46, 0x60, 0x89, 0x44, 0x06, 0x83,
- 0xc7, 0x04, 0xe9, 0x96, 0xfa, 0xff, 0x44, 0x38, 0x8b, 0x45, 0x02, 0x3d, 0x00,
- 0x00, 0x74, 0x24, 0x3d, 0xff, 0xff, 0x74, 0x06, 0xbb, 0x0a, 0x00, 0xf7, 0xe3,
- 0xfa, 0x89, 0x44, 0x24, 0x80, 0x4c, 0x50, 0x04, 0xa0, 0x2f, 0x60, 0x88, 0x46,
- 0x02, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xfb, 0x83, 0xc7, 0x04, 0xe9, 0x67, 0xfa,
- 0x8b, 0x44, 0x24, 0xbb, 0x0a, 0x00, 0xf7, 0xe3, 0xfa, 0xeb, 0xdf, 0x8b, 0x45,
- 0x02, 0x88, 0x44, 0x5c, 0x88, 0x64, 0x5d, 0x83, 0xc7, 0x04, 0xe9, 0x4d, 0xfa,
- 0x8b, 0x45, 0x02, 0x88, 0x44, 0x5a, 0x88, 0x64, 0x5b, 0x83, 0xc7, 0x04, 0xe9,
- 0x3e, 0xfa, 0x83, 0xc7, 0x04, 0xe9, 0x38, 0xfa, 0xb8, 0x0b, 0x00, 0xe9, 0x5e,
- 0xfa, 0xa1, 0x40, 0x60, 0x89, 0x04, 0xa1, 0x46, 0x60, 0x89, 0x44, 0x06, 0xc7,
- 0x44, 0x02, 0x00, 0x01, 0xa1, 0x42, 0x60, 0x89, 0x44, 0x04, 0x33, 0xc0, 0x89,
- 0x44, 0x0a, 0x89, 0x44, 0x0c, 0x89, 0x44, 0x12, 0x89, 0x44, 0x14, 0x89, 0x44,
- 0x18, 0x89, 0x44, 0x1a, 0xc7, 0x44, 0x1c, 0xff, 0xff, 0x89, 0x44, 0x24, 0x88,
- 0x44, 0x28, 0x88, 0x64, 0x29, 0x88, 0x44, 0x2a, 0x88, 0x64, 0x2b, 0xc6, 0x44,
- 0x2c, 0x3d, 0x88, 0x64, 0x2d, 0xc7, 0x44, 0x2e, 0x02, 0x00, 0xc7, 0x44, 0x34,
- 0xff, 0x0a, 0x89, 0x44, 0x38, 0x89, 0x44, 0x3a, 0x89, 0x44, 0x3c, 0x89, 0x44,
- 0x3e, 0x89, 0x44, 0x40, 0x89, 0x44, 0x44, 0xc7, 0x44, 0x46, 0x78, 0x00, 0x88,
- 0x44, 0x4b, 0x88, 0x44, 0x4c, 0x88, 0x44, 0x4d, 0x88, 0x44, 0x4e, 0x88, 0x44,
- 0x4f, 0x88, 0x44, 0x50, 0x88, 0x44, 0x51, 0x88, 0x44, 0x52, 0x88, 0x44, 0x53,
- 0x88, 0x44, 0x54, 0x88, 0x44, 0x58, 0x88, 0x44, 0x56, 0x88, 0x44, 0x57, 0x88,
- 0x44, 0x58, 0x88, 0x44, 0x59, 0x88, 0x44, 0x64, 0xc6, 0x44, 0x5c, 0x11, 0xc6,
- 0x44, 0x5d, 0x13, 0x88, 0x44, 0x5e, 0x88, 0x44, 0x5f, 0x88, 0x44, 0x60, 0x88,
- 0x44, 0x61, 0xc6, 0x44, 0x62, 0xff, 0x88, 0x44, 0x69, 0x88, 0x44, 0x66, 0x88,
- 0x44, 0x67, 0x8b, 0x6c, 0x20, 0xc6, 0x46, 0x06, 0x80, 0xc6, 0x46, 0x00, 0x0c,
- 0xc6, 0x46, 0x02, 0x00, 0xc6, 0x46, 0x06, 0x03, 0xa1, 0x48, 0x60, 0x88, 0x46,
- 0x04, 0x88, 0x66, 0x04, 0xa0, 0x2f, 0x60, 0x88, 0x46, 0x02, 0xc6, 0x46, 0x08,
- 0x00, 0x8a, 0x46, 0x04, 0x8a, 0x46, 0x00, 0x8a, 0x46, 0x0a, 0x8a, 0x46, 0x0c,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00, 0x50,
- 0x33, 0xc0, 0xfa, 0x89, 0x44, 0x24, 0xc7, 0x44, 0x2e, 0x02, 0x00, 0x89, 0x44,
- 0x38, 0x89, 0x44, 0x3a, 0x89, 0x44, 0x3c, 0x89, 0x44, 0x3e, 0x89, 0x44, 0x0a,
- 0x89, 0x44, 0x0c, 0x89, 0x44, 0x42, 0x88, 0x44, 0x64, 0xfb, 0x81, 0xc6, 0x80,
- 0x00, 0xe2, 0xd8, 0x5f, 0x5e, 0x5d, 0xc3, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00,
- 0x50, 0x33, 0xc0, 0x89, 0x44, 0x0a, 0x89, 0x44, 0x0c, 0x89, 0x44, 0x12, 0x89,
- 0x44, 0x14, 0x81, 0xc6, 0x80, 0x00, 0xe2, 0xee, 0x8b, 0xfe, 0xbb, 0x00, 0x10,
- 0xb8, 0x10, 0x00, 0x8b, 0xd0, 0xb3, 0x00, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00,
- 0x50, 0x2b, 0xda, 0x72, 0x27, 0x89, 0x44, 0x16, 0x81, 0xc6, 0x80, 0x00, 0xe2,
- 0xf3, 0x8b, 0x0e, 0x3e, 0xc4, 0xbe, 0x00, 0x50, 0x2b, 0xda, 0x72, 0x13, 0x89,
- 0x44, 0x0e, 0x81, 0xc6, 0x80, 0x00, 0xe2, 0xf3, 0x8b, 0xd0, 0x03, 0xc0, 0x81,
- 0xfa, 0x00, 0x04, 0x72, 0xce, 0x8c, 0xcf, 0x8b, 0x0e, 0x3e, 0xc4, 0xa1, 0x3e,
- 0xc4, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x00, 0x50, 0x03, 0xd8, 0x8b, 0xf3, 0x81,
- 0xee, 0x80, 0x00, 0x8b, 0x44, 0x16, 0x2b, 0xf8, 0x89, 0x7c, 0x10, 0xc1, 0xe0,
- 0x04, 0x48, 0x89, 0x44, 0x16, 0xe2, 0xeb, 0x8b, 0x0e, 0x3e, 0xc4, 0xa1, 0x3e,
- 0xc4, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x00, 0x50, 0x03, 0xd8, 0x8b, 0xf3, 0x81,
- 0xee, 0x80, 0x00, 0x8b, 0x44, 0x0e, 0x2b, 0xf8, 0x89, 0x7c, 0x08, 0xc1, 0xe0,
- 0x04, 0x48, 0x89, 0x44, 0x0e, 0xe2, 0xeb, 0xc3, 0x55, 0x56, 0x57, 0x33, 0xc0,
- 0x8e, 0xc0, 0xbd, 0x00, 0xf0, 0xc6, 0x46, 0x04, 0x01, 0xf6, 0x46, 0x04, 0x80,
- 0x75, 0x61, 0xc7, 0x06, 0x40, 0x60, 0x44, 0x14, 0xc7, 0x06, 0x46, 0x60, 0x3e,
- 0x19, 0xc7, 0x06, 0x42, 0x60, 0xda, 0x18, 0xc7, 0x06, 0x44, 0x60, 0x1a, 0x18,
- 0x26, 0xc7, 0x06, 0x20, 0x00, 0x2b, 0x23, 0x26, 0xc7, 0x06, 0x4c, 0x00, 0x4b,
- 0x23, 0x26, 0xc7, 0x06, 0x34, 0x00, 0xc5, 0x22, 0x26, 0xc7, 0x06, 0x38, 0x00,
- 0xd2, 0x22, 0xc7, 0x06, 0x00, 0x58, 0x58, 0x23, 0xc6, 0x06, 0x2f, 0x60, 0x00,
- 0xc6, 0x06, 0x2e, 0x60, 0x00, 0xb8, 0x00, 0x00, 0xa3, 0x48, 0x60, 0xb8, 0x66,
- 0x0e, 0xe7, 0x52, 0xb8, 0x05, 0xe0, 0xe7, 0x56, 0xb8, 0xf0, 0x00, 0xe7, 0x62,
- 0xb8, 0x00, 0xe0, 0xe7, 0x66, 0xe9, 0x98, 0x00, 0xc7, 0x06, 0x3e, 0xc4, 0x00,
- 0x00, 0xbd, 0x00, 0xf0, 0xb0, 0x00, 0x88, 0x46, 0x0e, 0x83, 0xc5, 0x10, 0xfe,
- 0xc0, 0x3c, 0x10, 0x7c, 0xf4, 0xbd, 0x00, 0xf0, 0xb0, 0x00, 0x8a, 0x5e, 0x0e,
- 0x3a, 0xd8, 0x75, 0x04, 0xff, 0x06, 0x3e, 0xc4, 0x83, 0xc5, 0x10, 0xfe, 0xc0,
- 0x3c, 0x10, 0x7c, 0xec, 0x83, 0x3e, 0x3e, 0xc4, 0x08, 0x7f, 0x09, 0xc7, 0x06,
- 0x3e, 0xc4, 0x08, 0x00, 0xeb, 0x0a, 0x90, 0xc7, 0x06, 0x3e, 0xc4, 0x10, 0x00,
- 0xeb, 0x01, 0x90, 0xc7, 0x06, 0x40, 0x60, 0xbc, 0x1b, 0xc7, 0x06, 0x46, 0x60,
- 0x39, 0x20, 0xc7, 0x06, 0x42, 0x60, 0xcb, 0x1f, 0xc7, 0x06, 0x44, 0x60, 0x83,
- 0x1c, 0xa1, 0x3e, 0xc4, 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x00, 0x00, 0x03, 0xd8,
- 0x03, 0x1e, 0x00, 0x50, 0xc7, 0x87, 0x00, 0x50, 0xd1, 0x23, 0x26, 0xc7, 0x06,
- 0x20, 0x00, 0x8f, 0x23, 0xc6, 0x06, 0x2f, 0x60, 0x01, 0xc6, 0x06, 0x2e, 0x60,
- 0x60, 0xb8, 0x01, 0x07, 0xa3, 0x48, 0x60, 0xb8, 0x70, 0x0f, 0xe7, 0x52, 0xb8,
- 0x05, 0xe0, 0xe7, 0x56, 0xe8, 0x46, 0xfe, 0xbe, 0x00, 0x50, 0x89, 0x36, 0x30,
- 0x60, 0xba, 0x00, 0xf0, 0xb3, 0x00, 0x88, 0x5c, 0x48, 0x88, 0x5c, 0x65, 0xfe,
- 0xc3, 0x89, 0x54, 0x20, 0x83, 0xc2, 0x10, 0xc7, 0x44, 0x1e, 0x80, 0x00, 0xe8,
- 0x00, 0xfd, 0x81, 0xc6, 0x80, 0x00, 0xa1, 0x3e, 0xc4, 0x69, 0xc0, 0x80, 0x00,
- 0xb9, 0x00, 0x50, 0x03, 0xc8, 0x3b, 0xf1, 0x72, 0xd6, 0xa1, 0x3e, 0xc4, 0x48,
- 0x69, 0xc0, 0x80, 0x00, 0xbb, 0x1e, 0x00, 0x03, 0xd8, 0xa1, 0x3e, 0xc4, 0x48,
- 0x6b, 0xc0, 0x80, 0x89, 0x87, 0x00, 0x50, 0x5f, 0x5e, 0x5d, 0xc3, 0xc8, 0x02,
- 0x00, 0x00, 0x57, 0x56, 0xe8, 0x55, 0x1b, 0x8b, 0xf0, 0x8a, 0x1e, 0x08, 0xc4,
- 0x2a, 0xff, 0xc1, 0xe3, 0x02, 0x8b, 0x38, 0x03, 0xf3, 0x8b, 0x5c, 0x02, 0x8b,
- 0x07, 0x48, 0x48, 0x89, 0x46, 0xfe, 0xeb, 0x76, 0x8a, 0x05, 0x47, 0x2a, 0xe4,
- 0x8b, 0xf0, 0x8b, 0xc2, 0x2d, 0x10, 0x00, 0x3d, 0x05, 0x00, 0x77, 0x1b, 0xd1,
- 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0xf8, 0x2f, 0x90, 0x04, 0x30, 0x1a, 0x30, 0x26,
- 0x30, 0x54, 0x30, 0x32, 0x30, 0x42, 0x30, 0xba, 0x0c, 0x00, 0x8b, 0x76, 0xfe,
- 0x8b, 0xc6, 0x8b, 0xda, 0x88, 0x87, 0xe0, 0x59, 0x56, 0x53, 0xe8, 0x3e, 0xd8,
- 0xeb, 0x13, 0x90, 0xba, 0x0d, 0x00, 0x8a, 0x46, 0xff, 0x2a, 0xe4, 0x8b, 0xf0,
- 0xeb, 0xe4, 0x56, 0x6a, 0x05, 0xe8, 0x3e, 0xd8, 0x83, 0xc4, 0x04, 0xeb, 0x23,
- 0x90, 0xbb, 0x40, 0xf3, 0x8a, 0x07, 0x24, 0xf7, 0x8b, 0xce, 0x0a, 0xc1, 0x88,
- 0x07, 0xeb, 0x13, 0x90, 0x0b, 0xf6, 0x74, 0x08, 0xbb, 0x40, 0xf3, 0x80, 0x0f,
- 0x80, 0xeb, 0x06, 0xbb, 0x40, 0xf3, 0x80, 0x27, 0x7f, 0x8a, 0x15, 0x47, 0x2a,
- 0xf6, 0x81, 0xfa, 0xff, 0x00, 0x74, 0x03, 0xe9, 0x7c, 0xff, 0x5e, 0x5f, 0xc9,
- 0xc3, 0xbb, 0x00, 0xf2, 0x8a, 0x07, 0xa2, 0x38, 0xc4, 0x68, 0xc0, 0x00, 0x6a,
- 0x09, 0xe8, 0xdf, 0xd7, 0x83, 0xc4, 0x04, 0x68, 0x64, 0xb2, 0x68, 0xca, 0x00,
- 0xe8, 0x0b, 0x1b, 0x83, 0xc4, 0x04, 0x6a, 0x01, 0x68, 0xc6, 0x00, 0xe8, 0x00,
- 0x1b, 0x83, 0xc4, 0x04, 0xb8, 0x28, 0x62, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xc4,
- 0x00, 0xe8, 0xf0, 0x1a, 0x83, 0xc4, 0x04, 0x6a, 0x02, 0x68, 0xc2, 0x00, 0xe8,
- 0xe5, 0x1a, 0x83, 0xc4, 0x04, 0x68, 0x02, 0x02, 0x68, 0xc0, 0x00, 0xe8, 0xd9,
- 0x1a, 0x83, 0xc4, 0x04, 0x68, 0xa0, 0x0f, 0x68, 0xc8, 0x00, 0xe8, 0xcd, 0x1a,
- 0x83, 0xc4, 0x04, 0x68, 0xa4, 0x96, 0x68, 0xda, 0x00, 0xe8, 0xc1, 0x1a, 0x83,
- 0xc4, 0x04, 0x6a, 0x01, 0x68, 0xd2, 0x00, 0xe8, 0xb6, 0x1a, 0x83, 0xc4, 0x04,
- 0xb8, 0xdc, 0xc3, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xd0, 0x00, 0xe8, 0xa6, 0x1a,
- 0x83, 0xc4, 0x04, 0x6a, 0x02, 0x68, 0xd6, 0x00, 0xe8, 0x9b, 0x1a, 0x83, 0xc4,
- 0x04, 0x68, 0x02, 0x02, 0x68, 0xd4, 0x00, 0xe8, 0x8f, 0x1a, 0x83, 0xc4, 0x04,
- 0x6a, 0x05, 0x68, 0xd8, 0x00, 0xe8, 0x84, 0x1a, 0x83, 0xc4, 0x04, 0xe8, 0xab,
- 0xfe, 0x68, 0x66, 0xb2, 0x68, 0xca, 0x00, 0xe8, 0x75, 0x1a, 0x83, 0xc4, 0x04,
- 0xa0, 0xe3, 0x59, 0x0c, 0x01, 0x2a, 0xe4, 0x50, 0x6a, 0x03, 0xe8, 0x2d, 0xd7,
- 0x83, 0xc4, 0x04, 0xc3, 0xc8, 0x04, 0x00, 0x00, 0x57, 0x56, 0x8b, 0x7e, 0x04,
- 0x8b, 0x76, 0x08, 0x8b, 0xdf, 0x8e, 0x46, 0x06, 0x26, 0x80, 0x78, 0xff, 0xff,
- 0x75, 0x01, 0x4e, 0x8d, 0x44, 0xfd, 0xa3, 0x22, 0xc4, 0xf7, 0xd8, 0xa3, 0x12,
- 0xc4, 0xa1, 0x22, 0xc4, 0xa3, 0xec, 0xc3, 0x26, 0x8a, 0x05, 0xc0, 0xe8, 0x04,
- 0xa2, 0x06, 0xc4, 0xa2, 0x00, 0x5a, 0x2a, 0xe4, 0x8b, 0xf0, 0x8b, 0xdf, 0x26,
- 0x8a, 0x40, 0x03, 0xa2, 0x08, 0xc4, 0xe8, 0xf4, 0xfe, 0xe8, 0xa3, 0x19, 0x89,
- 0x46, 0xfc, 0xa0, 0x08, 0xc4, 0x2a, 0xe4, 0x8b, 0xf0, 0xc1, 0xe6, 0x02, 0x8b,
- 0x5e, 0xfc, 0x8b, 0x58, 0x02, 0x8b, 0x47, 0x02, 0xa3, 0x2a, 0xc4, 0xc7, 0x06,
- 0x30, 0xc4, 0x72, 0x06, 0x2b, 0xc0, 0xa3, 0x26, 0xc4, 0xa3, 0x28, 0xc4, 0xa3,
- 0x2c, 0xc4, 0xa3, 0x2e, 0xc4, 0xc7, 0x06, 0x20, 0x62, 0xff, 0xff, 0x8b, 0xf8,
- 0xeb, 0x5c, 0xc4, 0x5e, 0x04, 0x26, 0x8a, 0x59, 0x02, 0x2a, 0xff, 0xc1, 0xe3,
- 0x02, 0x03, 0x5e, 0xfc, 0x8b, 0x77, 0x02, 0x8b, 0x5f, 0x02, 0x8b, 0x47, 0x02,
- 0x01, 0x06, 0x26, 0xc4, 0x8b, 0x44, 0x04, 0x01, 0x06, 0x28, 0xc4, 0xa1, 0x30,
- 0xc4, 0x39, 0x44, 0x06, 0x73, 0x06, 0x8b, 0x44, 0x06, 0xa3, 0x30, 0xc4, 0xa1,
- 0x2c, 0xc4, 0x39, 0x44, 0x08, 0x76, 0x06, 0x8b, 0x44, 0x08, 0xa3, 0x2c, 0xc4,
- 0xa1, 0x2e, 0xc4, 0x39, 0x44, 0x0a, 0x76, 0x06, 0x8b, 0x44, 0x0a, 0xa3, 0x2e,
- 0xc4, 0xa1, 0x20, 0x62, 0x39, 0x44, 0x0c, 0x73, 0x06, 0x8b, 0x44, 0x0c, 0xa3,
- 0x20, 0x62, 0x47, 0x39, 0x3e, 0x22, 0xc4, 0x73, 0x9e, 0x5e, 0x5f, 0xc9, 0xc3,
- 0x56, 0xc6, 0x06, 0x08, 0xc4, 0xff, 0xb8, 0x90, 0x60, 0xa3, 0x50, 0xc4, 0xa3,
- 0xb2, 0xc3, 0xa3, 0x4a, 0xb0, 0xb8, 0x28, 0x62, 0xa3, 0x36, 0xc4, 0xa3, 0x34,
- 0xc4, 0xc7, 0x06, 0x48, 0xc4, 0x44, 0xc4, 0xc7, 0x06, 0x14, 0xc4, 0x26, 0x62,
- 0xc7, 0x06, 0xf4, 0xc3, 0x09, 0x00, 0xc6, 0x06, 0x07, 0xc4, 0x01, 0xbe, 0x4e,
- 0xb0, 0xeb, 0x09, 0x90, 0x8d, 0x84, 0x76, 0x06, 0x89, 0x04, 0x8b, 0xf0, 0x81,
- 0xfe, 0x3a, 0xbd, 0x75, 0xf2, 0xb8, 0x4e, 0xb0, 0x89, 0x04, 0xa3, 0xfa, 0xc3,
- 0xa3, 0xf6, 0xc3, 0xa3, 0xf8, 0xc3, 0xc7, 0x06, 0xf2, 0xc3, 0x01, 0x00, 0x5e,
- 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x06, 0x04, 0x59, 0x01, 0x83, 0x16, 0x06, 0x59,
- 0x00, 0x83, 0x3e, 0x48, 0xb0, 0x00, 0x74, 0x07, 0xf6, 0x06, 0x16, 0xc4, 0x01,
- 0x74, 0x08, 0x68, 0x1d, 0x03, 0xe8, 0x71, 0xce, 0x8b, 0xe5, 0xa0, 0xe6, 0xc3,
- 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xf2, 0x18, 0x8b, 0xe5, 0x80, 0x0e, 0x16, 0xc4,
- 0x01, 0x8b, 0x46, 0x04, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xd0, 0x00, 0xe8, 0xde,
- 0x18, 0x8b, 0xe5, 0xff, 0x76, 0x06, 0x68, 0xd8, 0x00, 0xe8, 0xd3, 0x18, 0x8b,
- 0xe5, 0x68, 0xa6, 0x96, 0x68, 0xda, 0x00, 0xe8, 0xc8, 0x18, 0x8b, 0xe5, 0xa0,
- 0x4c, 0xc4, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xbc, 0x18, 0x8b, 0x46, 0x04, 0xa3,
- 0x3a, 0xc4, 0x8b, 0x46, 0x06, 0xa3, 0xda, 0xc3, 0x8b, 0x0e, 0xbc, 0x59, 0x03,
- 0x0e, 0x2a, 0xc4, 0x89, 0x0e, 0x1a, 0xc4, 0x05, 0x04, 0x00, 0x01, 0x06, 0x24,
- 0x62, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x56, 0x06, 0x8b, 0x76, 0x04,
- 0xa0, 0x06, 0xc4, 0x2c, 0xf8, 0xc0, 0xe0, 0x04, 0x08, 0x04, 0xb8, 0xc3, 0xa5,
- 0x2b, 0x04, 0x2b, 0xc2, 0x89, 0x44, 0x02, 0x52, 0x56, 0xe8, 0x59, 0xff, 0x83,
- 0xc4, 0x04, 0x5e, 0xc9, 0xc3, 0x90, 0x56, 0x8b, 0x36, 0x26, 0x62, 0x83, 0x3c,
- 0x04, 0x74, 0x09, 0x68, 0x4f, 0x03, 0xe8, 0xd4, 0xcd, 0x83, 0xc4, 0x02, 0x83,
- 0x3e, 0x40, 0xc4, 0x00, 0x74, 0x09, 0x68, 0x51, 0x03, 0xe8, 0xc4, 0xcd, 0x83,
- 0xc4, 0x02, 0x89, 0x36, 0x40, 0xc4, 0xff, 0x74, 0x06, 0xff, 0x74, 0x04, 0xe8,
- 0x22, 0xff, 0x83, 0xc4, 0x04, 0x8b, 0x44, 0x02, 0xa3, 0x26, 0x62, 0x0b, 0xc0,
- 0x75, 0x06, 0xc7, 0x06, 0x14, 0xc4, 0x26, 0x62, 0x5e, 0xc3, 0x90, 0x56, 0xa0,
- 0xf4, 0xc3, 0x24, 0x09, 0x3c, 0x09, 0x75, 0x2c, 0xc6, 0x06, 0xdc, 0xc3, 0x05,
- 0xa0, 0x07, 0xc4, 0xa2, 0xdd, 0xc3, 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8, 0x73,
- 0xff, 0x83, 0xc4, 0x04, 0x80, 0x26, 0xf4, 0xc3, 0xf7, 0x80, 0x0e, 0xf4, 0xc3,
- 0x04, 0xa1, 0xbc, 0x59, 0x03, 0x06, 0x28, 0xc4, 0xa3, 0xfc, 0xc3, 0x5e, 0xc3,
- 0xf6, 0x06, 0xf4, 0xc3, 0x10, 0x74, 0x1d, 0xc6, 0x06, 0xdc, 0xc3, 0x06, 0xc6,
- 0x06, 0xdd, 0xc3, 0x00, 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8, 0x41, 0xff, 0x83,
- 0xc4, 0x04, 0x80, 0x26, 0xf4, 0xc3, 0x0f, 0x5e, 0xc3, 0x90, 0xa0, 0xf4, 0xc3,
- 0x24, 0x0a, 0x3c, 0x0a, 0x75, 0x09, 0xa2, 0xdc, 0xc3, 0xa0, 0x0c, 0xc4, 0xeb,
- 0xa7, 0x90, 0xf6, 0x06, 0xf4, 0xc3, 0x60, 0x74, 0x3b, 0xa0, 0xf4, 0xc3, 0x25,
- 0x20, 0x00, 0x3d, 0x01, 0x00, 0x1a, 0xc0, 0x24, 0xfe, 0x04, 0x0b, 0xa2, 0xdc,
- 0xc3, 0xa0, 0x0c, 0xc4, 0xa2, 0xdd, 0xc3, 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8,
- 0xfd, 0xfe, 0x83, 0xc4, 0x04, 0x80, 0x26, 0xf4, 0xc3, 0x1f, 0xa0, 0x0b, 0xc4,
- 0x38, 0x06, 0x0a, 0xc4, 0x74, 0x03, 0xe9, 0xa8, 0x00, 0x80, 0x26, 0xf4, 0xc3,
- 0xf7, 0x5e, 0xc3, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a, 0xc4, 0x74, 0x7d, 0x8b,
- 0x36, 0xf8, 0xc3, 0xc6, 0x44, 0x04, 0x07, 0xa0, 0x0a, 0xc4, 0xc0, 0xe0, 0x04,
- 0x02, 0x06, 0x0c, 0xc4, 0x88, 0x44, 0x05, 0xff, 0x74, 0x02, 0x8d, 0x44, 0x04,
- 0x50, 0xe8, 0xba, 0xfe, 0x83, 0xc4, 0x04, 0xf6, 0x06, 0xf4, 0xc3, 0x04, 0x75,
- 0x0f, 0x80, 0x0e, 0xf4, 0xc3, 0x04, 0xa1, 0xbc, 0x59, 0x03, 0x06, 0x28, 0xc4,
- 0xa3, 0xfc, 0xc3, 0xa0, 0x0a, 0xc4, 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x0a, 0xc4,
- 0x8b, 0x04, 0xa3, 0xf8, 0xc3, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a, 0xc4, 0x75,
- 0x25, 0x80, 0x26, 0xf4, 0xc3, 0xf7, 0x80, 0x0e, 0xf5, 0xc3, 0x02, 0xa1, 0x30,
- 0xc4, 0x39, 0x44, 0x02, 0x72, 0x07, 0x8b, 0x16, 0x2c, 0xc4, 0xeb, 0x05, 0x90,
- 0x8b, 0x16, 0x2e, 0xc4, 0x03, 0x16, 0xbc, 0x59, 0x89, 0x16, 0xfe, 0xc3, 0x80,
- 0x26, 0xf4, 0xc3, 0x7f, 0x5e, 0xc3, 0x90, 0xc6, 0x06, 0xdc, 0xc3, 0x08, 0xa0,
- 0x0c, 0xc4, 0xa2, 0xdd, 0xc3, 0x6a, 0x04, 0x68, 0xdc, 0xc3, 0xe8, 0x49, 0xfe,
- 0x83, 0xc4, 0x04, 0x80, 0x26, 0xf4, 0xc3, 0x77, 0x5e, 0xc3, 0x90, 0xf6, 0x06,
- 0x16, 0xc4, 0x01, 0x75, 0x4f, 0xf6, 0x06, 0xf4, 0xc3, 0x78, 0x74, 0x2e, 0xf6,
- 0x06, 0x16, 0xc4, 0x08, 0x75, 0x27, 0x83, 0x3e, 0x26, 0x62, 0x00, 0x74, 0x07,
- 0x83, 0x3e, 0x4a, 0xc4, 0x00, 0x7c, 0x19, 0xe8, 0x88, 0xfe, 0xa1, 0x12, 0xc4,
- 0xb9, 0x01, 0x00, 0x2b, 0x0e, 0x22, 0xc4, 0x01, 0x0e, 0x4a, 0xc4, 0x39, 0x06,
- 0x4a, 0xc4, 0x7d, 0x1c, 0xeb, 0x17, 0x83, 0x3e, 0x26, 0x62, 0x00, 0x74, 0x13,
- 0xe8, 0x22, 0xfe, 0xa1, 0xec, 0xc3, 0xff, 0x06, 0x4a, 0xc4, 0x39, 0x06, 0x4a,
- 0xc4, 0x7e, 0x03, 0xa3, 0x4a, 0xc4, 0xc3, 0x90, 0x56, 0x2a, 0xc0, 0xa2, 0x0b,
- 0xc4, 0xa2, 0x0a, 0xc4, 0xa2, 0x09, 0xc4, 0xa1, 0xf6, 0xc3, 0xa3, 0xfa, 0xc3,
- 0xa3, 0xf8, 0xc3, 0x8b, 0x36, 0x44, 0xc4, 0xeb, 0x08, 0x90, 0xc7, 0x04, 0x03,
- 0x00, 0x8b, 0x74, 0x02, 0x0b, 0xf6, 0x75, 0xf5, 0xc6, 0x06, 0x0c, 0xc4, 0x00,
- 0x5e, 0xc3, 0x55, 0x8b, 0xec, 0xe8, 0xcc, 0xff, 0x8a, 0x46, 0x04, 0xa2, 0x07,
- 0xc4, 0x83, 0x26, 0xf4, 0xc3, 0x10, 0x81, 0x0e, 0xf4, 0xc3, 0x09, 0x01, 0xe8,
- 0x60, 0xff, 0xc9, 0xc3, 0x56, 0x83, 0x06, 0x28, 0x59, 0x01, 0x83, 0x16, 0x2a,
- 0x59, 0x00, 0x8b, 0x1e, 0xb2, 0xc3, 0x8b, 0xf3, 0xc7, 0x04, 0x04, 0x00, 0x8b,
- 0x36, 0x14, 0xc4, 0x89, 0x1c, 0x8d, 0x47, 0x02, 0xa3, 0x14, 0xc4, 0x5e, 0xc3,
- 0x90, 0xc8, 0x08, 0x00, 0x00, 0x57, 0x56, 0x8b, 0x3e, 0xb2, 0xc3, 0x8b, 0x75,
- 0x04, 0x8b, 0xde, 0x8a, 0x07, 0x25, 0x0f, 0x00, 0x2d, 0x05, 0x00, 0x3d, 0x06,
- 0x00, 0x76, 0x03, 0xe9, 0xb3, 0x00, 0xd1, 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0xa2,
- 0x35, 0x90, 0xb0, 0x35, 0x0a, 0x36, 0x3a, 0x36, 0x84, 0x36, 0x84, 0x36, 0x98,
- 0x36, 0x84, 0x36, 0x83, 0x7d, 0x06, 0x04, 0x74, 0x03, 0xe9, 0xd1, 0x00, 0x83,
- 0x06, 0x8c, 0x59, 0x01, 0x83, 0x16, 0x8e, 0x59, 0x00, 0xf6, 0x06, 0xf4, 0xc3,
- 0x01, 0x74, 0x24, 0x83, 0x3e, 0x18, 0xc4, 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18,
- 0xc4, 0x80, 0x26, 0xf4, 0xc3, 0xfa, 0xf6, 0x06, 0xf4, 0xc3, 0x08, 0x74, 0x16,
- 0x80, 0x26, 0xf4, 0xc3, 0xf7, 0x80, 0x0e, 0xf4, 0xc3, 0x10, 0xeb, 0x0a, 0x90,
- 0xe8, 0x1b, 0xff, 0xc7, 0x06, 0xf4, 0xc3, 0x10, 0x01, 0x80, 0x0e, 0xf5, 0xc3,
- 0x02, 0xa1, 0xbc, 0x59, 0xa3, 0xfe, 0xc3, 0x80, 0x26, 0x16, 0xc4, 0xf7, 0xe9,
- 0x5f, 0x02, 0x83, 0x7d, 0x06, 0x04, 0x75, 0x7a, 0xf6, 0x06, 0xf4, 0xc3, 0x01,
- 0x74, 0x13, 0x83, 0x3e, 0x18, 0xc4, 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18, 0xc4,
- 0x80, 0x26, 0xf4, 0xc3, 0xf2, 0xeb, 0xce, 0x90, 0x83, 0x06, 0xac, 0x59, 0x01,
- 0x83, 0x16, 0xae, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0xeb, 0xc8, 0x83, 0x7d,
- 0x06, 0x04, 0x72, 0x4a, 0x81, 0x7d, 0x06, 0x72, 0x06, 0x77, 0x43, 0x80, 0x26,
- 0x16, 0xc4, 0xf7, 0xf6, 0x06, 0xf4, 0xc3, 0x01, 0x74, 0x03, 0xe9, 0x13, 0x02,
- 0x8a, 0x44, 0x01, 0x24, 0x0f, 0x88, 0x46, 0xfd, 0x8a, 0x0e, 0x09, 0xc4, 0x2a,
- 0xed, 0x2a, 0xc1, 0x24, 0x0f, 0x8a, 0x16, 0x0a, 0xc4, 0x2a, 0xd1, 0x80, 0xe2,
- 0x0f, 0x3a, 0xc2, 0x7e, 0x2b, 0x83, 0x06, 0x80, 0x59, 0x01, 0x83, 0x16, 0x82,
- 0x59, 0x00, 0x6a, 0x03, 0xe9, 0x4e, 0x01, 0x83, 0x7d, 0x06, 0x04, 0x74, 0xc2,
- 0x83, 0x06, 0x7c, 0x59, 0x01, 0x83, 0x16, 0x7e, 0x59, 0x00, 0xe9, 0x6a, 0x01,
- 0x90, 0x83, 0x7d, 0x06, 0x04, 0x75, 0xec, 0xeb, 0xa7, 0x89, 0x76, 0xf8, 0xa0,
- 0x09, 0xc4, 0x38, 0x46, 0xfd, 0x75, 0x03, 0xe9, 0x86, 0x00, 0x83, 0x3e, 0x18,
- 0xc4, 0x00, 0x74, 0x04, 0xff, 0x0e, 0x18, 0xc4, 0x8b, 0x36, 0xf6, 0xc3, 0xa0,
- 0x09, 0xc4, 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x09, 0xc4, 0x8b, 0x34, 0x38, 0x46,
- 0xfd, 0x75, 0xef, 0x8b, 0xd6, 0x89, 0x16, 0xf6, 0xc3, 0xf6, 0x06, 0xf4, 0xc3,
- 0x02, 0x75, 0x59, 0xa0, 0x0a, 0xc4, 0x38, 0x06, 0x09, 0xc4, 0x75, 0x08, 0x80,
- 0x26, 0xf4, 0xc3, 0xfb, 0xeb, 0x1b, 0x90, 0xf6, 0x06, 0xf4, 0xc3, 0x04, 0x75,
- 0x09, 0x68, 0x24, 0x05, 0xe8, 0x07, 0xca, 0x83, 0xc4, 0x02, 0xa1, 0xbc, 0x59,
- 0x03, 0x06, 0x28, 0xc4, 0xa3, 0xfc, 0xc3, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a,
- 0xc4, 0x75, 0x25, 0xf6, 0x06, 0xf5, 0xc3, 0x02, 0x75, 0x1e, 0x2a, 0x06, 0x09,
- 0xc4, 0x24, 0x0f, 0x3c, 0x03, 0x7c, 0x09, 0x68, 0x2f, 0x05, 0xe8, 0xda, 0xc9,
- 0x83, 0xc4, 0x02, 0x80, 0x0e, 0xf5, 0xc3, 0x02, 0xa1, 0xbc, 0x59, 0xa3, 0xfe,
- 0xc3, 0x8b, 0x5e, 0xf8, 0x8a, 0x07, 0x25, 0x0f, 0x00, 0x2d, 0x07, 0x00, 0x74,
- 0x17, 0x48, 0x48, 0x75, 0x03, 0xe9, 0x94, 0x00, 0x48, 0x75, 0x03, 0xe9, 0xbc,
- 0x00, 0x48, 0x75, 0x03, 0xe9, 0xc8, 0x00, 0xe9, 0x12, 0x01, 0x90, 0x8a, 0x47,
- 0x01, 0xc0, 0xe8, 0x04, 0x88, 0x46, 0xff, 0x3a, 0x06, 0x0c, 0xc4, 0x75, 0x45,
- 0xfe, 0xc0, 0x24, 0x0f, 0xa2, 0x0c, 0xc4, 0xf6, 0x06, 0xf4, 0xc3, 0x80, 0x75,
- 0x1d, 0x81, 0x3e, 0x20, 0x62, 0xe8, 0x03, 0x73, 0x15, 0x80, 0x0e, 0xf4, 0xc3,
- 0x80, 0xa1, 0x28, 0xc4, 0xc1, 0xe8, 0x03, 0x03, 0x06, 0xbc, 0x59, 0xa3, 0x02,
- 0xc4, 0xeb, 0x06, 0x90, 0x80, 0x0e, 0xf4, 0xc3, 0x88, 0xc7, 0x05, 0x02, 0x00,
- 0x8b, 0x1e, 0x48, 0xc4, 0x89, 0x3f, 0x8d, 0x45, 0x02, 0xa3, 0x48, 0xc4, 0x5e,
- 0x5f, 0xc9, 0xc3, 0x90, 0x8a, 0x46, 0xff, 0x2a, 0x06, 0x0c, 0xc4, 0x24, 0x0f,
- 0x3c, 0x05, 0x7d, 0x0d, 0xff, 0x06, 0xd8, 0xc3, 0x80, 0x0e, 0xf4, 0xc3, 0x40,
- 0x5e, 0x5f, 0xc9, 0xc3, 0x83, 0x06, 0x84, 0x59, 0x01, 0x83, 0x16, 0x86, 0x59,
- 0x00, 0x6a, 0x04, 0xe8, 0x65, 0xfd, 0x83, 0xc4, 0x02, 0x5e, 0x5f, 0xc9, 0xc3,
- 0xf6, 0x06, 0xf4, 0xc3, 0x02, 0x75, 0x14, 0xa0, 0x0b, 0xc4, 0x38, 0x06, 0x0a,
- 0xc4, 0x74, 0x0b, 0x81, 0x26, 0xf4, 0xc3, 0xfb, 0xfd, 0x80, 0x0e, 0xf4, 0xc3,
- 0x0a, 0x83, 0x06, 0xb0, 0x59, 0x01, 0x83, 0x16, 0xb2, 0x59, 0x00, 0xff, 0x06,
- 0xd8, 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x80, 0x0e, 0xf4, 0xc3, 0x20, 0x83,
- 0x06, 0xb4, 0x59, 0x01, 0x83, 0x16, 0xb6, 0x59, 0x00, 0xeb, 0xe6, 0x90, 0xf6,
- 0x06, 0xf4, 0xc3, 0x02, 0x75, 0x0d, 0x83, 0x06, 0xac, 0x59, 0x01, 0x83, 0x16,
- 0xae, 0x59, 0x00, 0xeb, 0xd2, 0x90, 0x83, 0x3e, 0x18, 0xc4, 0x00, 0x74, 0x04,
- 0xff, 0x0e, 0x18, 0xc4, 0x80, 0x26, 0xf4, 0xc3, 0xf1, 0xa0, 0x09, 0xc4, 0xa2,
- 0x0a, 0xc4, 0x8b, 0x0e, 0xf6, 0xc3, 0x89, 0x0e, 0xf8, 0xc3, 0x3a, 0x06, 0x0b,
- 0xc4, 0x75, 0x10, 0x80, 0x0e, 0xf5, 0xc3, 0x02, 0xa1, 0xbc, 0x59, 0xa3, 0xfe,
- 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x80, 0x0e, 0xf4, 0xc3, 0x08, 0x5e, 0x5f,
- 0xc9, 0xc3, 0x90, 0xc8, 0x06, 0x00, 0x00, 0x57, 0x56, 0x8b, 0x3e, 0xb2, 0xc3,
- 0x83, 0x3d, 0x01, 0x74, 0x09, 0x68, 0xd3, 0x05, 0xe8, 0x7d, 0xc8, 0x83, 0xc4,
- 0x02, 0x83, 0x3e, 0x20, 0xc4, 0x00, 0x74, 0x17, 0xff, 0x36, 0x20, 0xc4, 0xff,
- 0x36, 0x1e, 0xc4, 0x68, 0x28, 0x62, 0xe8, 0x9b, 0x12, 0x83, 0xc4, 0x06, 0xc7,
- 0x06, 0x20, 0xc4, 0x00, 0x00, 0x8b, 0x75, 0x04, 0x8b, 0x55, 0x06, 0x83, 0x3e,
- 0x24, 0xc4, 0x00, 0x74, 0x17, 0x39, 0x16, 0x24, 0xc4, 0x77, 0x09, 0xc7, 0x06,
- 0x24, 0xc4, 0x00, 0x00, 0xe9, 0xc5, 0x01, 0x29, 0x16, 0x24, 0xc4, 0xe9, 0xbe,
- 0x01, 0x90, 0x89, 0x56, 0xfc, 0x83, 0x3e, 0xba, 0x59, 0x00, 0x74, 0x46, 0x68,
- 0xe8, 0x03, 0xe8, 0x76, 0x12, 0x83, 0xc4, 0x02, 0x3b, 0x06, 0xba, 0x59, 0x73,
- 0x37, 0x83, 0x06, 0x9c, 0x59, 0x01, 0x83, 0x16, 0x9e, 0x59, 0x00, 0x6a, 0x02,
- 0xe8, 0x5e, 0x12, 0x83, 0xc4, 0x02, 0x89, 0x46, 0xfe, 0x6a, 0x08, 0xe8, 0x53,
- 0x12, 0x83, 0xc4, 0x02, 0x6a, 0x02, 0x89, 0x46, 0xfa, 0xe8, 0x48, 0x12, 0x83,
- 0xc4, 0x02, 0x8b, 0xc8, 0xc0, 0xe1, 0x02, 0x8a, 0x46, 0xfa, 0xd2, 0xe0, 0x8b,
- 0x5e, 0xfe, 0x30, 0x00, 0x8a, 0x04, 0x25, 0x0f, 0x00, 0x48, 0x3d, 0x0a, 0x00,
- 0x77, 0x1f, 0xd1, 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0x2c, 0x39, 0x90, 0x58, 0x39,
- 0xe8, 0x39, 0xe8, 0x39, 0x0c, 0x3a, 0x2e, 0x3a, 0x2e, 0x3a, 0x2e, 0x3a, 0x2e,
- 0x3a, 0x2e, 0x3a, 0x2e, 0x3a, 0x2e, 0x3a, 0x83, 0x06, 0x78, 0x59, 0x01, 0x83,
- 0x16, 0x7a, 0x59, 0x00, 0x83, 0x06, 0x18, 0xc4, 0x02, 0xff, 0x06, 0xd8, 0xc3,
- 0xe9, 0x2d, 0x01, 0x8b, 0x56, 0xfc, 0x8b, 0xda, 0x80, 0x78, 0xff, 0xff, 0x75,
- 0x01, 0x4a, 0x83, 0xfa, 0x04, 0x7d, 0x03, 0xe9, 0x92, 0x00, 0x83, 0xfa, 0x0c,
- 0x7e, 0x03, 0xe9, 0x8a, 0x00, 0x80, 0x7c, 0x01, 0x01, 0x75, 0x03, 0xe8, 0xb9,
- 0xce, 0x8a, 0x04, 0xc0, 0xe8, 0x04, 0x2a, 0xe4, 0x40, 0x8a, 0x0e, 0x06, 0xc4,
- 0x2a, 0xed, 0x3b, 0xc1, 0x7e, 0x05, 0x80, 0x04, 0x10, 0xeb, 0x11, 0xa0, 0x06,
- 0xc4, 0xfe, 0xc0, 0xc0, 0xe0, 0x04, 0x8a, 0x0c, 0x80, 0xe1, 0x0f, 0x0a, 0xc1,
- 0x88, 0x04, 0xa0, 0x08, 0xc4, 0x8a, 0x1c, 0xc0, 0xeb, 0x04, 0x2a, 0xff, 0x38,
- 0x40, 0x03, 0x74, 0x6a, 0xa0, 0xe6, 0xc3, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xcf,
- 0x11, 0x83, 0xc4, 0x04, 0x80, 0x0e, 0x16, 0xc4, 0x04, 0xe8, 0x43, 0x01, 0xc7,
- 0x06, 0x18, 0xc4, 0x00, 0x00, 0xa1, 0xbc, 0x59, 0x05, 0x10, 0x27, 0xa3, 0x1c,
- 0xc4, 0xa0, 0x4c, 0xc4, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xab, 0x11, 0x83, 0xc4,
- 0x04, 0xeb, 0x37, 0x90, 0x8b, 0x56, 0xfc, 0x83, 0xfa, 0x04, 0x75, 0x09, 0x80,
- 0x7c, 0x03, 0xff, 0x75, 0x03, 0xba, 0x03, 0x00, 0x83, 0xfa, 0x03, 0x74, 0x20,
- 0x83, 0x06, 0x7c, 0x59, 0x01, 0x83, 0x16, 0x7e, 0x59, 0x00, 0xe9, 0x41, 0xff,
- 0x90, 0x8b, 0x56, 0xfc, 0x83, 0xfa, 0x0c, 0x72, 0xea, 0x8b, 0x44, 0x0a, 0x05,
- 0x0c, 0x00, 0x3b, 0xc2, 0x75, 0xe0, 0xa1, 0xbc, 0x59, 0x05, 0x10, 0x27, 0xa3,
- 0x1c, 0xc4, 0x80, 0x0e, 0x16, 0xc4, 0x08, 0xeb, 0x54, 0xb8, 0xc3, 0xa5, 0x2b,
- 0x44, 0x02, 0x2b, 0x04, 0x8b, 0xc8, 0x3b, 0x45, 0x06, 0x74, 0x2b, 0x83, 0x3e,
- 0xba, 0x59, 0x00, 0x75, 0x24, 0x83, 0x06, 0x6c, 0x59, 0x01, 0x83, 0x16, 0x6e,
- 0x59, 0x00, 0x83, 0x06, 0x18, 0xc4, 0x02, 0x39, 0x4d, 0x06, 0x73, 0x2d, 0x81,
- 0xf9, 0x72, 0x06, 0x77, 0x27, 0x2b, 0x4d, 0x06, 0x89, 0x0e, 0x24, 0xc4, 0xeb,
- 0x1e, 0x90, 0xa1, 0xbc, 0x59, 0x05, 0x10, 0x27, 0xa3, 0x1c, 0xc4, 0x8a, 0x04,
- 0xc0, 0xe8, 0x04, 0x3a, 0x06, 0x06, 0xc4, 0x75, 0x06, 0xe8, 0xfb, 0xfa, 0xeb,
- 0x04, 0x90, 0xe8, 0xd1, 0xfa, 0x83, 0x3d, 0x01, 0x75, 0x04, 0xc7, 0x05, 0x00,
- 0x00, 0x83, 0xc7, 0x08, 0x81, 0xff, 0x20, 0x62, 0x75, 0x03, 0xbf, 0x90, 0x60,
- 0x89, 0x3e, 0xb2, 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x06,
- 0x24, 0x59, 0x01, 0x83, 0x16, 0x26, 0x59, 0x00, 0xc7, 0x06, 0xf2, 0xc3, 0x00,
- 0x00, 0xeb, 0x04, 0x90, 0xe8, 0xb3, 0xfd, 0x8b, 0x1e, 0xb2, 0xc3, 0x83, 0x3f,
- 0x01, 0x74, 0xf4, 0xe8, 0xed, 0xf9, 0xc9, 0xc3, 0x90, 0x83, 0x3e, 0x48, 0xb0,
- 0x00, 0x74, 0x09, 0x68, 0xe1, 0x06, 0xe8, 0x29, 0xc6, 0x83, 0xc4, 0x02, 0xc7,
- 0x06, 0x48, 0xb0, 0x01, 0x00, 0xc3, 0x90, 0x83, 0x3e, 0x48, 0xb0, 0x01, 0x74,
- 0x14, 0x68, 0xee, 0x06, 0xe8, 0x11, 0xc6, 0x83, 0xc4, 0x02, 0xeb, 0x09, 0xc7,
- 0x06, 0x48, 0xb0, 0x01, 0x00, 0xe8, 0xa5, 0xff, 0xc7, 0x06, 0x48, 0xb0, 0x00,
- 0x00, 0x83, 0x3e, 0xf2, 0xc3, 0x00, 0x75, 0xea, 0xc3, 0x90, 0x57, 0x56, 0x8b,
- 0x1e, 0x50, 0xc4, 0xeb, 0x11, 0x83, 0x3f, 0x00, 0x75, 0x12, 0x83, 0xc3, 0x08,
- 0x81, 0xfb, 0x20, 0x62, 0x72, 0x03, 0xbb, 0x90, 0x60, 0x39, 0x1e, 0xb2, 0xc3,
- 0x75, 0xe9, 0x89, 0x1e, 0x50, 0xc4, 0x3b, 0x1e, 0x4a, 0xb0, 0x75, 0x05, 0xa1,
- 0x34, 0xc4, 0xeb, 0x03, 0x8b, 0x47, 0x04, 0xa3, 0x36, 0xc4, 0x39, 0x06, 0x34,
- 0xc4, 0x72, 0x50, 0x81, 0x3e, 0x34, 0xc4, 0xa4, 0xa0, 0x73, 0x06, 0xbf, 0x48,
- 0xb0, 0xeb, 0x47, 0x90, 0xb8, 0xac, 0xb0, 0x2b, 0x06, 0x34, 0xc4, 0x8b, 0x0e,
- 0x36, 0xc4, 0x81, 0xe9, 0x28, 0x62, 0x3b, 0xc1, 0x7f, 0xe7, 0xf6, 0x06, 0x16,
- 0xc4, 0x06, 0x75, 0x22, 0xb8, 0x28, 0x62, 0x2b, 0x06, 0x34, 0xc4, 0x50, 0xe8,
- 0xa8, 0xcd, 0x83, 0xc4, 0x02, 0x8b, 0xf0, 0x81, 0xee, 0x00, 0x10, 0xa1, 0x34,
- 0xc4, 0xa3, 0x1e, 0xc4, 0x81, 0xee, 0x28, 0x62, 0x89, 0x36, 0x20, 0xc4, 0xc7,
- 0x06, 0x34, 0xc4, 0x28, 0x62, 0x8b, 0x3e, 0x36, 0xc4, 0x81, 0xff, 0x28, 0x62,
- 0x72, 0x06, 0x81, 0xff, 0x48, 0xb0, 0x76, 0x09, 0x68, 0x40, 0x07, 0xe8, 0x54,
- 0xc5, 0x83, 0xc4, 0x02, 0xa1, 0x34, 0xc4, 0x05, 0x04, 0x00, 0x2b, 0xf8, 0x81,
- 0xff, 0xa0, 0x0f, 0x72, 0x05, 0xbf, 0xa0, 0x0f, 0xeb, 0x0a, 0x83, 0x06, 0x44,
- 0x59, 0x01, 0x83, 0x16, 0x46, 0x59, 0x00, 0xf6, 0x06, 0x16, 0xc4, 0x06, 0x75,
- 0x13, 0xa1, 0x34, 0xc4, 0x03, 0xc7, 0x80, 0xc4, 0x10, 0x50, 0xe8, 0x78, 0xcd,
- 0x83, 0xc4, 0x02, 0x5e, 0x5f, 0xc3, 0x90, 0xf6, 0x06, 0x16, 0xc4, 0x04, 0x74,
- 0x07, 0x68, 0x80, 0x00, 0x6a, 0x09, 0xeb, 0x17, 0xa0, 0xe3, 0x59, 0x2a, 0xe4,
- 0x50, 0x6a, 0x03, 0xe8, 0x56, 0xcc, 0x83, 0xc4, 0x04, 0xa0, 0xef, 0x59, 0x25,
- 0xfb, 0x00, 0x50, 0x6a, 0x0f, 0xe8, 0x47, 0xcc, 0x83, 0xc4, 0x04, 0x68, 0x64,
- 0xb2, 0x68, 0xca, 0x00, 0xe8, 0x73, 0x0f, 0x83, 0xc4, 0x04, 0xbe, 0x06, 0x00,
- 0xeb, 0x10, 0x6a, 0x01, 0xe8, 0x1a, 0xcc, 0x83, 0xc4, 0x02, 0xbb, 0x02, 0xf2,
- 0x8a, 0x07, 0xa2, 0x38, 0xc4, 0xbb, 0x00, 0xf2, 0xc6, 0x07, 0x30, 0x4e, 0x75,
- 0xe7, 0xa1, 0x34, 0xc4, 0x80, 0xc4, 0x10, 0x50, 0x68, 0xc4, 0x00, 0xe8, 0x45,
- 0x0f, 0x83, 0xc4, 0x04, 0x57, 0x68, 0xc8, 0x00, 0xe8, 0x3b, 0x0f, 0x83, 0xc4,
- 0x04, 0xf6, 0x06, 0x16, 0xc4, 0x04, 0x74, 0x2a, 0xe8, 0x5b, 0xf3, 0x80, 0x26,
- 0x16, 0xc4, 0xf8, 0x83, 0x3e, 0x40, 0xc4, 0x00, 0x74, 0x0e, 0x8b, 0x1e, 0x40,
- 0xc4, 0xc7, 0x07, 0x00, 0x00, 0xc7, 0x06, 0x40, 0xc4, 0x00, 0x00, 0x83, 0x06,
- 0x94, 0x59, 0x01, 0x83, 0x16, 0x96, 0x59, 0x00, 0xeb, 0x1e, 0x90, 0xa0, 0xef,
- 0x59, 0x2a, 0xe4, 0x50, 0x6a, 0x0f, 0xe8, 0xc4, 0xcb, 0x83, 0xc4, 0x04, 0x80,
- 0x26, 0x16, 0xc4, 0xfd, 0x83, 0x06, 0x90, 0x59, 0x01, 0x83, 0x16, 0x92, 0x59,
- 0x00, 0x83, 0xff, 0x14, 0x72, 0x0c, 0x68, 0x66, 0xb2, 0x68, 0xca, 0x00, 0xe8,
- 0xdc, 0x0e, 0x83, 0xc4, 0x04, 0xa0, 0xe3, 0x59, 0x0c, 0x01, 0x2a, 0xe4, 0x50,
- 0x6a, 0x03, 0xe8, 0x94, 0xcb, 0x83, 0xc4, 0x04, 0x5e, 0x5f, 0xc3, 0x90, 0xbb,
- 0x00, 0xf2, 0xf6, 0x07, 0x40, 0x74, 0x38, 0xf6, 0x06, 0x16, 0xc4, 0x01, 0x74,
- 0x31, 0x68, 0xd8, 0x00, 0xe8, 0xa5, 0x0e, 0x83, 0xc4, 0x02, 0x0b, 0xc0, 0x75,
- 0x16, 0x80, 0x26, 0x16, 0xc4, 0xfe, 0x39, 0x06, 0x40, 0xc4, 0x74, 0x19, 0x8b,
- 0x1e, 0x40, 0xc4, 0x89, 0x07, 0xa3, 0x40, 0xc4, 0xeb, 0x0e, 0x83, 0x06, 0x68,
- 0x59, 0x01, 0x83, 0x16, 0x6a, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0xbb, 0x00,
- 0xf2, 0xf6, 0x07, 0x80, 0x74, 0x21, 0x83, 0x06, 0x60, 0x59, 0x01, 0x83, 0x16,
- 0x62, 0x59, 0x00, 0x68, 0xc4, 0x00, 0xe8, 0x62, 0x0e, 0x83, 0xc4, 0x02, 0x2b,
- 0x06, 0x34, 0xc4, 0x3d, 0x00, 0x10, 0x74, 0x05, 0x80, 0x0e, 0x16, 0xc4, 0x02,
- 0xbb, 0x00, 0xf2, 0xc6, 0x07, 0x10, 0xf6, 0x06, 0x16, 0xc4, 0x06, 0x74, 0x03,
- 0xe8, 0xcb, 0xfd, 0x83, 0x06, 0x00, 0x59, 0x01, 0x83, 0x16, 0x02, 0x59, 0x00,
- 0xc3, 0x55, 0x8b, 0xec, 0x57, 0x56, 0x2b, 0xff, 0xe8, 0x29, 0xcb, 0xf6, 0x06,
- 0x29, 0x60, 0x80, 0x74, 0x03, 0xe9, 0xe4, 0x01, 0xf6, 0x06, 0x29, 0x60, 0x40,
- 0x75, 0x03, 0xe9, 0xa2, 0x01, 0x8b, 0x36, 0x28, 0x60, 0x81, 0xe6, 0xff, 0x3f,
- 0x80, 0x36, 0x2a, 0x60, 0x86, 0xf7, 0x06, 0x2a, 0x60, 0xee, 0x80, 0x74, 0x03,
- 0xe9, 0xbc, 0x00, 0x83, 0x3e, 0xb8, 0x59, 0x00, 0x74, 0x1b, 0x6a, 0x64, 0xe8,
- 0xc0, 0x0d, 0x83, 0xc4, 0x02, 0x3b, 0x06, 0xb8, 0x59, 0x73, 0x0d, 0x83, 0x06,
- 0x98, 0x59, 0x01, 0x83, 0x16, 0x9a, 0x59, 0x00, 0xe9, 0x88, 0x00, 0x8d, 0x44,
- 0x02, 0x01, 0x06, 0x3c, 0xc4, 0xa1, 0x34, 0xc4, 0x2d, 0x28, 0x62, 0x3b, 0x06,
- 0x20, 0xc4, 0x72, 0x07, 0x8b, 0x1e, 0x34, 0xc4, 0xeb, 0x0d, 0x90, 0x8b, 0x1e,
- 0x34, 0xc4, 0x81, 0xeb, 0x28, 0x62, 0x03, 0x1e, 0x1e, 0xc4, 0x8a, 0x0f, 0x2a,
- 0xed, 0x8b, 0xd1, 0x83, 0xe2, 0x0f, 0x83, 0xfa, 0x05, 0x7c, 0x05, 0x83, 0xfa,
- 0x0b, 0x7e, 0x05, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0x8b, 0x16, 0x4a, 0xb0, 0x8b,
- 0xda, 0x83, 0x3f, 0x00, 0x75, 0x35, 0xc7, 0x07, 0x01, 0x00, 0xa1, 0x34, 0xc4,
- 0x89, 0x47, 0x04, 0x8d, 0x44, 0xfe, 0x89, 0x47, 0x06, 0xc7, 0x47, 0x02, 0x00,
- 0x00, 0x83, 0xc2, 0x08, 0x81, 0xfa, 0x20, 0x62, 0x75, 0x03, 0xba, 0x90, 0x60,
- 0xa1, 0x4a, 0xb0, 0x39, 0x06, 0x50, 0xc4, 0x75, 0x04, 0x89, 0x16, 0x50, 0xc4,
- 0x89, 0x16, 0x4a, 0xb0, 0xeb, 0x0f, 0x90, 0x83, 0x06, 0x70, 0x59, 0x01, 0x83,
- 0x16, 0x72, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0x01, 0x36, 0x34, 0xc4, 0xbb,
- 0x00, 0xf2, 0xc6, 0x07, 0x30, 0x47, 0xe9, 0x15, 0xff, 0xf6, 0x06, 0x2b, 0x60,
- 0x80, 0x74, 0x0a, 0x83, 0x06, 0x64, 0x59, 0x01, 0x83, 0x16, 0x66, 0x59, 0x00,
- 0xf6, 0x06, 0x2a, 0x60, 0x80, 0x74, 0x0a, 0x83, 0x06, 0x54, 0x59, 0x01, 0x83,
- 0x16, 0x56, 0x59, 0x00, 0xf6, 0x06, 0x2a, 0x60, 0x40, 0x74, 0x0a, 0x83, 0x06,
- 0x58, 0x59, 0x01, 0x83, 0x16, 0x5a, 0x59, 0x00, 0xf6, 0x06, 0x2a, 0x60, 0x20,
- 0x74, 0x0a, 0x83, 0x06, 0x50, 0x59, 0x01, 0x83, 0x16, 0x52, 0x59, 0x00, 0xf6,
- 0x06, 0x2a, 0x60, 0x0e, 0x74, 0x0a, 0x83, 0x06, 0x5c, 0x59, 0x01, 0x83, 0x16,
- 0x5e, 0x59, 0x00, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0xff, 0x06, 0xd8, 0xc3, 0x0b,
- 0xff, 0x74, 0x08, 0xc7, 0x06, 0x32, 0xc4, 0x00, 0x00, 0xeb, 0x16, 0xff, 0x06,
- 0x32, 0xc4, 0x83, 0x3e, 0x32, 0xc4, 0x14, 0x72, 0x0b, 0xc7, 0x06, 0x32, 0xc4,
- 0x00, 0x00, 0x80, 0x0e, 0x16, 0xc4, 0x02, 0x83, 0xff, 0x05, 0x76, 0x03, 0xbf,
- 0x05, 0x00, 0xc1, 0xe7, 0x02, 0x83, 0x85, 0x08, 0x59, 0x01, 0x83, 0x95, 0x0a,
- 0x59, 0x00, 0x68, 0xc4, 0x00, 0xe8, 0xa9, 0x0c, 0x83, 0xc4, 0x02, 0x8b, 0xf0,
- 0x81, 0xee, 0x00, 0x10, 0x39, 0x36, 0x34, 0xc4, 0x74, 0x72, 0x3b, 0x36, 0x34,
- 0xc4, 0x73, 0x12, 0x83, 0x06, 0x40, 0x59, 0x01, 0x83, 0x16, 0x42, 0x59, 0x00,
- 0x80, 0x0e, 0x16, 0xc4, 0x02, 0xeb, 0x5b, 0x90, 0x83, 0x06, 0x38, 0x59, 0x01,
- 0x83, 0x16, 0x3a, 0x59, 0x00, 0xeb, 0x4e, 0xf6, 0x06, 0x2a, 0x60, 0x80, 0x74,
- 0x0a, 0x83, 0x06, 0x3c, 0x59, 0x01, 0x83, 0x16, 0x3e, 0x59, 0x00, 0xf6, 0x06,
- 0x2a, 0x60, 0x20, 0x75, 0x03, 0xe9, 0x75, 0xff, 0x83, 0x06, 0x4c, 0x59, 0x01,
- 0x83, 0x16, 0x4e, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0x80, 0x0e, 0x16, 0xc4,
- 0x02, 0xbb, 0x00, 0xf2, 0xc6, 0x07, 0x30, 0xe9, 0x59, 0xff, 0x90, 0x83, 0x06,
- 0x48, 0x59, 0x01, 0x83, 0x16, 0x4a, 0x59, 0x00, 0xff, 0x06, 0xd8, 0xc3, 0x80,
- 0x0e, 0x16, 0xc4, 0x02, 0xe9, 0x42, 0xff, 0xe8, 0xaf, 0xfb, 0x5e, 0x5f, 0xc9,
- 0xc3, 0x90, 0x83, 0x06, 0xa0, 0x59, 0x01, 0x83, 0x16, 0xa2, 0x59, 0x00, 0x83,
- 0x06, 0x18, 0xc4, 0x02, 0xff, 0x06, 0xd8, 0xc3, 0xf6, 0x06, 0xf4, 0xc3, 0x01,
- 0x74, 0x08, 0x80, 0x0e, 0xf4, 0xc3, 0x08, 0xeb, 0x24, 0x90, 0xf6, 0x06, 0xf4,
- 0xc3, 0x02, 0x75, 0xf1, 0xa0, 0x0a, 0xc4, 0x38, 0x06, 0x09, 0xc4, 0x75, 0x09,
- 0x68, 0xdb, 0x08, 0xe8, 0x66, 0xc1, 0x83, 0xc4, 0x02, 0x80, 0x0e, 0xf4, 0xc3,
- 0x0a, 0x80, 0x26, 0xf5, 0xc3, 0xfd, 0xe9, 0x0a, 0xf5, 0xc8, 0x02, 0x00, 0x00,
- 0x57, 0x56, 0xf6, 0x06, 0xf5, 0xc3, 0x01, 0x74, 0x14, 0xe8, 0xba, 0xed, 0xe8,
- 0x0d, 0xfb, 0x80, 0x26, 0xf5, 0xc3, 0xfe, 0xe8, 0x1d, 0xfb, 0xc7, 0x06, 0x0e,
- 0xc4, 0x00, 0x00, 0x83, 0x3e, 0x44, 0xc4, 0x00, 0x74, 0x6b, 0xe8, 0xf5, 0xfa,
- 0x8b, 0x36, 0x44, 0xc4, 0x0b, 0xf6, 0x74, 0x57, 0x8b, 0x44, 0x02, 0xa3, 0x44,
- 0xc4, 0x0b, 0xc0, 0x75, 0x06, 0xc7, 0x06, 0x48, 0xc4, 0x44, 0xc4, 0x83, 0x06,
- 0x34, 0x59, 0x01, 0x83, 0x16, 0x36, 0x59, 0x00, 0x8b, 0x7e, 0xfe, 0x83, 0x3c,
- 0x02, 0x75, 0x1c, 0xe8, 0xe0, 0xfa, 0x8b, 0x44, 0x06, 0x2d, 0x04, 0x00, 0x50,
- 0x8b, 0x44, 0x04, 0x05, 0x04, 0x00, 0x50, 0xe8, 0x8f, 0xe6, 0x83, 0xc4, 0x04,
- 0x8b, 0xf8, 0xe8, 0xaf, 0xfa, 0xc7, 0x04, 0x00, 0x00, 0x0b, 0xff, 0x74, 0x11,
- 0x83, 0x06, 0x88, 0x59, 0x01, 0x83, 0x16, 0x8a, 0x59, 0x00, 0x57, 0xe8, 0x09,
- 0xf5, 0x83, 0xc4, 0x02, 0xe8, 0xab, 0xfa, 0xc7, 0x06, 0x0e, 0xc4, 0x00, 0x00,
- 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x57, 0x56, 0xa0, 0x0b, 0xc4, 0x2a, 0x06, 0x09,
- 0xc4, 0x24, 0x0f, 0x3c, 0x03, 0x7c, 0x09, 0x80, 0x26, 0xf5, 0xc3, 0xfd, 0x5e,
- 0x5f, 0xc3, 0x90, 0x8b, 0x3e, 0xfa, 0xc3, 0xe8, 0x81, 0xfa, 0xff, 0x36, 0x30,
- 0xc4, 0x8d, 0x45, 0x08, 0x50, 0xe8, 0xca, 0xe3, 0x83, 0xc4, 0x04, 0x8b, 0xf0,
- 0xe8, 0x56, 0xfa, 0x81, 0xfe, 0x72, 0x06, 0x76, 0x09, 0x68, 0x6c, 0x09, 0xe8,
- 0x80, 0xc0, 0x83, 0xc4, 0x02, 0xf6, 0x06, 0xf5, 0xc3, 0x01, 0x75, 0x7b, 0x0b,
- 0xf6, 0x75, 0x2c, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x00, 0xc4, 0x3d, 0x00, 0x40,
- 0x72, 0x20, 0xa1, 0xbc, 0x59, 0x05, 0x0a, 0x00, 0xa3, 0xfe, 0xc3, 0xf6, 0x06,
- 0xf4, 0xc3, 0x80, 0x74, 0x5b, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x02, 0xc4, 0x3d,
- 0x00, 0x40, 0x73, 0x4f, 0xeb, 0x45, 0x90, 0x90, 0x83, 0x06, 0x30, 0x59, 0x01,
- 0x83, 0x16, 0x32, 0x59, 0x00, 0x80, 0x26, 0xf5, 0xc3, 0xfd, 0x8d, 0x44, 0x04,
- 0x89, 0x45, 0x02, 0x8b, 0x05, 0xa3, 0xfa, 0xc3, 0xa0, 0x0b, 0xc4, 0xfe, 0xc0,
- 0x24, 0x0f, 0xa2, 0x0b, 0xc4, 0xa1, 0xbc, 0x59, 0xa3, 0x00, 0xc4, 0x0b, 0xf6,
- 0x74, 0x08, 0x81, 0x3e, 0x20, 0x62, 0xe8, 0x03, 0x73, 0x06, 0x81, 0x06, 0x00,
- 0xc4, 0x88, 0x13, 0xf6, 0x06, 0xf4, 0xc3, 0x03, 0x75, 0x08, 0x80, 0x0e, 0xf4,
- 0xc3, 0x08, 0xe8, 0xaf, 0xf3, 0x5e, 0x5f, 0xc3, 0x55, 0x8b, 0xec, 0x2b, 0xc0,
- 0xa3, 0xb8, 0x59, 0xa3, 0xba, 0x59, 0xe8, 0xfc, 0xf0, 0x2b, 0xdb, 0x8e, 0xc3,
- 0xbb, 0x40, 0x08, 0x26, 0x8a, 0x07, 0x2a, 0xe4, 0x50, 0x06, 0x68, 0x30, 0x08,
- 0xe8, 0x02, 0xf0, 0x83, 0xc4, 0x06, 0x80, 0x0e, 0x16, 0xc4, 0x08, 0xc7, 0x06,
- 0x1c, 0xc4, 0x10, 0x27, 0xe8, 0x1d, 0xed, 0xe8, 0xb8, 0x01, 0xa0, 0x2e, 0x60,
- 0x0c, 0x9c, 0xa2, 0xe6, 0xc3, 0xa0, 0x2e, 0x60, 0x0c, 0x8c, 0xa2, 0x4c, 0xc4,
- 0x98, 0x50, 0x6a, 0x28, 0xe8, 0x38, 0x0a, 0x83, 0xc4, 0x04, 0xa1, 0x0e, 0xc4,
- 0x01, 0x06, 0x52, 0xc4, 0xc7, 0x06, 0x0e, 0xc4, 0x01, 0x00, 0x83, 0x06, 0x20,
- 0x59, 0x01, 0x83, 0x16, 0x22, 0x59, 0x00, 0xc7, 0x06, 0xd6, 0xc3, 0x00, 0x00,
- 0xe8, 0x32, 0xfe, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0xf0, 0xc3, 0x3d, 0x00, 0x40,
- 0x73, 0x72, 0x83, 0x06, 0xf0, 0xc3, 0x14, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0x22,
- 0x62, 0x3d, 0x00, 0x40, 0x73, 0x5b, 0x83, 0x06, 0x22, 0x62, 0x64, 0xa1, 0x52,
- 0xc4, 0x2b, 0x06, 0x46, 0xc4, 0x99, 0x33, 0xc2, 0x2b, 0xc2, 0xc1, 0xf8, 0x02,
- 0x33, 0xc2, 0x2b, 0xc2, 0x01, 0x06, 0x46, 0xc4, 0xa1, 0xd4, 0xc3, 0x39, 0x06,
- 0x46, 0xc4, 0x76, 0x06, 0xa1, 0x46, 0xc4, 0xa3, 0xd4, 0xc3, 0xa1, 0x3c, 0xc4,
- 0x2b, 0x06, 0x24, 0x62, 0x1b, 0xc9, 0xf7, 0xd1, 0x23, 0xc1, 0x03, 0x06, 0x24,
- 0x62, 0x2b, 0x06, 0x10, 0xc4, 0x99, 0x33, 0xc2, 0x2b, 0xc2, 0xc1, 0xf8, 0x02,
- 0x33, 0xc2, 0x2b, 0xc2, 0x01, 0x06, 0x10, 0xc4, 0x2b, 0xc0, 0xa3, 0x52, 0xc4,
- 0xa3, 0x24, 0x62, 0xa3, 0x3c, 0xc4, 0xe8, 0xeb, 0x03, 0xe8, 0xb4, 0xfd, 0xa1,
- 0xbc, 0x59, 0x2b, 0x06, 0xfc, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x33, 0xe8, 0xc5,
- 0xf8, 0xa1, 0xbc, 0x59, 0x2b, 0x06, 0xfc, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x1e,
- 0xa1, 0xbc, 0x59, 0x05, 0xf4, 0x01, 0xa3, 0xfc, 0xc3, 0xf6, 0x06, 0xf4, 0xc3,
- 0x04, 0x74, 0x08, 0x80, 0x26, 0xf4, 0xc3, 0xfb, 0xe8, 0x39, 0xfd, 0xc7, 0x06,
- 0x0e, 0xc4, 0x00, 0x00, 0xe8, 0xb0, 0xf8, 0xe8, 0x75, 0xfd, 0xa1, 0xbc, 0x59,
- 0x2b, 0x06, 0xfe, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x40, 0xe8, 0x86, 0xf8, 0xa1,
- 0xbc, 0x59, 0x2b, 0x06, 0xfe, 0xc3, 0x3d, 0x00, 0x40, 0x73, 0x2b, 0xa1, 0xbc,
- 0x59, 0x05, 0xf4, 0x01, 0xa3, 0xfe, 0xc3, 0xa0, 0xf5, 0xc3, 0x24, 0x03, 0x3c,
- 0x02, 0x75, 0x13, 0xf6, 0x06, 0xf4, 0xc3, 0x01, 0x74, 0x09, 0x68, 0x3f, 0x0a,
- 0xe8, 0x91, 0xbe, 0x83, 0xc4, 0x02, 0xe8, 0xcd, 0xfd, 0xc7, 0x06, 0x0e, 0xc4,
- 0x00, 0x00, 0xe8, 0x64, 0xf8, 0xe8, 0x29, 0xfd, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0x4c, 0xb0, 0x3d, 0x00, 0x40, 0x72, 0x03, 0xe9, 0xc8, 0xfe, 0x83, 0x06, 0x4c,
- 0xb0, 0x64, 0xf6, 0x06, 0x16, 0xc4, 0x01, 0x74, 0x0c, 0xa1, 0xbc, 0x59, 0x2b,
- 0x06, 0x1a, 0xc4, 0x3d, 0x00, 0x40, 0x72, 0x23, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0x1c, 0xc4, 0x3d, 0x00, 0x40, 0x72, 0x17, 0x68, 0xc8, 0x00, 0xe8, 0xc8, 0x08,
- 0x83, 0xc4, 0x02, 0x0b, 0xc0, 0x74, 0x0a, 0x83, 0x3e, 0x18, 0xc4, 0x14, 0x73,
- 0x03, 0xe9, 0x8d, 0xfe, 0xa0, 0xe6, 0xc3, 0x98, 0x50, 0x6a, 0x28, 0xe8, 0xb8,
- 0x08, 0x83, 0xc4, 0x04, 0x80, 0x0e, 0x16, 0xc4, 0x04, 0xe8, 0x2c, 0xf8, 0xc7,
- 0x06, 0x18, 0xc4, 0x00, 0x00, 0xa1, 0xbc, 0x59, 0x05, 0x10, 0x27, 0xa3, 0x1c,
- 0xc4, 0xa0, 0x4c, 0xc4, 0xe9, 0x59, 0xfe, 0x90, 0xbb, 0x00, 0xf1, 0xc7, 0x07,
- 0x00, 0x00, 0xbb, 0x80, 0xf1, 0xc7, 0x07, 0xff, 0xff, 0xc7, 0x06, 0xea, 0xc3,
- 0x01, 0x00, 0xc3, 0x90, 0xbb, 0x00, 0xf1, 0x8a, 0x67, 0x01, 0x25, 0x00, 0xc0,
- 0xa3, 0x42, 0xc4, 0xa1, 0x78, 0x60, 0x39, 0x06, 0x42, 0xc4, 0x74, 0x57, 0x81,
- 0x3e, 0x42, 0xc4, 0x00, 0xc0, 0x75, 0x15, 0x3d, 0x00, 0x40, 0x74, 0x05, 0x3d,
- 0x00, 0x80, 0x75, 0x0b, 0x31, 0x06, 0x42, 0xc4, 0xc7, 0x06, 0x78, 0x60, 0x00,
- 0x00, 0xc3, 0x3d, 0x00, 0xc0, 0x75, 0x10, 0x81, 0x3e, 0x42, 0xc4, 0x00, 0x40,
- 0x74, 0x41, 0x81, 0x3e, 0x42, 0xc4, 0x00, 0x80, 0x74, 0x39, 0xa1, 0x42, 0xc4,
- 0xa3, 0x78, 0x60, 0x3d, 0x00, 0xc0, 0x74, 0x12, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0x7a, 0x60, 0x3d, 0x32, 0x00, 0x73, 0x06, 0xc7, 0x06, 0x42, 0xc4, 0x00, 0x00,
- 0xa1, 0xbc, 0x59, 0xa3, 0x7a, 0x60, 0xc3, 0x90, 0xa1, 0xbc, 0x59, 0x2b, 0x06,
- 0x7a, 0x60, 0x3d, 0xe8, 0x03, 0x72, 0x08, 0x81, 0x06, 0x7a, 0x60, 0xfa, 0x00,
- 0xc3, 0x90, 0xc7, 0x06, 0x42, 0xc4, 0x00, 0x00, 0xc3, 0x90, 0xc8, 0x04, 0x00,
- 0x00, 0x57, 0x56, 0xc7, 0x46, 0xfc, 0x00, 0x00, 0xbf, 0xb4, 0xc3, 0xc7, 0x46,
- 0xfe, 0x54, 0xc4, 0xbe, 0x00, 0x50, 0xeb, 0x40, 0x80, 0x7c, 0x67, 0x00, 0x75,
- 0x0a, 0x8b, 0x5e, 0xfe, 0x8b, 0x07, 0x39, 0x44, 0x0c, 0x74, 0x0e, 0xff, 0x46,
- 0xfc, 0xd0, 0x6c, 0x67, 0x8b, 0x44, 0x0c, 0x8b, 0x5e, 0xfe, 0x89, 0x07, 0x80,
- 0x7c, 0x66, 0x00, 0x75, 0x07, 0x8b, 0x05, 0x39, 0x44, 0x12, 0x74, 0x0b, 0xff,
- 0x46, 0xfc, 0xd0, 0x6c, 0x66, 0x8b, 0x44, 0x12, 0x89, 0x05, 0x47, 0x47, 0x83,
- 0x46, 0xfe, 0x02, 0x81, 0xc6, 0x80, 0x00, 0x81, 0xfe, 0x00, 0x58, 0x72, 0xba,
- 0x8b, 0x46, 0xfc, 0x5e, 0x5f, 0xc9, 0xc3, 0x90, 0x83, 0x3e, 0x42, 0xc4, 0x00,
- 0x74, 0x0c, 0xc7, 0x06, 0xb0, 0xc3, 0x01, 0x00, 0xc7, 0x06, 0x7c, 0x60, 0x00,
- 0x00, 0xe8, 0x84, 0xff, 0x40, 0x01, 0x06, 0x7c, 0x60, 0x83, 0x3e, 0x7c, 0x60,
- 0x14, 0x7c, 0x25, 0xd1, 0x26, 0xb0, 0xc3, 0xf7, 0x06, 0xb0, 0xc3, 0xff, 0x03,
- 0x75, 0x06, 0xc7, 0x06, 0xb0, 0xc3, 0x01, 0x00, 0x83, 0x3e, 0x7c, 0x60, 0x28,
- 0x7c, 0x07, 0xc7, 0x06, 0x7c, 0x60, 0x14, 0x00, 0xc3, 0x83, 0x2e, 0x7c, 0x60,
- 0x14, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x57, 0x56, 0x83, 0x7e, 0x04, 0x10, 0x72,
- 0x09, 0x68, 0x23, 0x01, 0xe8, 0xac, 0xbc, 0x83, 0xc4, 0x02, 0x2b, 0xff, 0x8b,
- 0x76, 0x04, 0xc1, 0xe6, 0x07, 0x81, 0xc6, 0x00, 0x50, 0x8a, 0x54, 0x54, 0x2a,
- 0xf6, 0xf6, 0xc2, 0x02, 0x74, 0x03, 0xbf, 0x04, 0x00, 0xf6, 0xc2, 0x10, 0x74,
- 0x03, 0x83, 0xcf, 0x08, 0x8a, 0xc2, 0x24, 0x01, 0x74, 0x03, 0x83, 0xcf, 0x40,
- 0x8a, 0xc2, 0x24, 0x01, 0x74, 0x03, 0x83, 0xcf, 0x40, 0xf6, 0xc2, 0x40, 0x74,
- 0x04, 0x81, 0xcf, 0x80, 0x00, 0xf6, 0x44, 0x28, 0x80, 0x74, 0x13, 0xf6, 0xc2,
- 0x80, 0x74, 0x03, 0x83, 0xcf, 0x10, 0xf6, 0xc2, 0x20, 0x74, 0x16, 0x83, 0xcf,
- 0x20, 0xeb, 0x11, 0x90, 0xf6, 0xc2, 0x80, 0x74, 0x03, 0x83, 0xcf, 0x20, 0xf6,
- 0xc2, 0x20, 0x74, 0x03, 0x83, 0xcf, 0x10, 0xf6, 0x44, 0x51, 0x02, 0x74, 0x10,
- 0xf6, 0x44, 0x29, 0x10, 0x75, 0x06, 0xf6, 0x44, 0x5f, 0x03, 0x74, 0x04, 0x81,
- 0xcf, 0x00, 0x02, 0x8a, 0x44, 0x52, 0x22, 0xc2, 0x3a, 0x44, 0x53, 0x74, 0x04,
- 0x81, 0xcf, 0x00, 0x01, 0x83, 0x3e, 0x42, 0xc4, 0x00, 0x74, 0x19, 0x2a, 0xc0,
- 0x88, 0x44, 0x67, 0x88, 0x44, 0x66, 0x8b, 0x44, 0x12, 0x8b, 0x5e, 0x04, 0xd1,
- 0xe3, 0x89, 0x87, 0xb4, 0xc3, 0x8b, 0x44, 0x0c, 0xeb, 0x6c, 0x8a, 0x44, 0x2c,
- 0x25, 0x0f, 0x00, 0x48, 0x74, 0x0f, 0x48, 0x74, 0x1e, 0x48, 0x74, 0x21, 0x48,
- 0x74, 0x24, 0xba, 0x01, 0x00, 0xeb, 0x22, 0x90, 0x8a, 0x64, 0x2d, 0x25, 0x00,
- 0x04, 0x3d, 0x01, 0x00, 0x1b, 0xd2, 0x83, 0xe2, 0x1f, 0x42, 0xeb, 0x10, 0x90,
- 0xba, 0x10, 0x00, 0xeb, 0x0a, 0x90, 0xba, 0x04, 0x00, 0xeb, 0x04, 0x90, 0xba,
- 0x02, 0x00, 0x8b, 0x44, 0x12, 0x8b, 0x5e, 0x04, 0xd1, 0xe3, 0x89, 0x5e, 0xfe,
- 0x39, 0x87, 0xb4, 0xc3, 0x74, 0x0d, 0x08, 0x54, 0x66, 0x8b, 0x44, 0x12, 0x8b,
- 0x5e, 0xfe, 0x89, 0x87, 0xb4, 0xc3, 0x8b, 0x44, 0x0c, 0x8b, 0x5e, 0xfe, 0x39,
- 0x87, 0x54, 0xc4, 0x74, 0x0d, 0x08, 0x54, 0x67, 0x8b, 0x44, 0x0c, 0x8b, 0x5e,
- 0xfe, 0x89, 0x87, 0x54, 0xc4, 0x80, 0x7c, 0x67, 0x01, 0x75, 0x1e, 0xf6, 0x06,
- 0xb0, 0xc3, 0x01, 0x74, 0x11, 0x6a, 0x64, 0xe8, 0xcc, 0x05, 0x83, 0xc4, 0x02,
- 0x3d, 0x1e, 0x00, 0x7d, 0x04, 0x2b, 0xd2, 0xeb, 0x0b, 0xba, 0x01, 0x00, 0xeb,
- 0x06, 0x90, 0x8a, 0x54, 0x67, 0x2a, 0xf6, 0x0b, 0xd2, 0x74, 0x03, 0x83, 0xcf,
- 0x01, 0x80, 0x7c, 0x66, 0x01, 0x75, 0x1e, 0xf6, 0x06, 0xb0, 0xc3, 0x02, 0x74,
- 0x11, 0x6a, 0x64, 0xe8, 0x9c, 0x05, 0x83, 0xc4, 0x02, 0x3d, 0x1e, 0x00, 0x7d,
- 0x04, 0x2b, 0xd2, 0xeb, 0x0b, 0xba, 0x01, 0x00, 0xeb, 0x06, 0x90, 0x8a, 0x54,
- 0x66, 0x2a, 0xf6, 0x0b, 0xd2, 0x74, 0x03, 0x83, 0xcf, 0x02, 0xd0, 0x6c, 0x67,
- 0xd0, 0x6c, 0x66, 0x89, 0x3e, 0xb0, 0xc3, 0x5e, 0x5f, 0xc9, 0xc3, 0x56, 0xe8,
- 0x2a, 0xfd, 0xa1, 0x42, 0xc4, 0x2d, 0x00, 0x40, 0x74, 0x0e, 0x2d, 0x00, 0x40,
- 0x74, 0x1f, 0x2d, 0x00, 0x40, 0x74, 0x3a, 0xe9, 0xad, 0x00, 0x90, 0xff, 0x0e,
- 0xea, 0xc3, 0x78, 0x03, 0xe9, 0xa3, 0x00, 0xa1, 0x3e, 0xc4, 0x05, 0x06, 0x00,
- 0x01, 0x06, 0xea, 0xc3, 0xe9, 0x96, 0x00, 0xa1, 0x3e, 0xc4, 0x05, 0x06, 0x00,
- 0xff, 0x06, 0xea, 0xc3, 0x3b, 0x06, 0xea, 0xc3, 0x76, 0x03, 0xe9, 0x83, 0x00,
- 0xa1, 0x3e, 0xc4, 0x05, 0x06, 0x00, 0x29, 0x06, 0xea, 0xc3, 0xeb, 0x77, 0x90,
- 0xa1, 0xea, 0xc3, 0x2d, 0x04, 0x00, 0x74, 0x08, 0x48, 0x74, 0x29, 0x48, 0x74,
- 0x2e, 0x5e, 0xc3, 0xa1, 0x10, 0x59, 0x8b, 0x16, 0x12, 0x59, 0xd1, 0xe0, 0xd1,
- 0xd2, 0x03, 0x06, 0x04, 0x59, 0x13, 0x16, 0x06, 0x59, 0x03, 0x06, 0x0c, 0x59,
- 0x13, 0x16, 0x0e, 0x59, 0xa3, 0x82, 0x60, 0x89, 0x16, 0x84, 0x60, 0x5e, 0xc3,
- 0xc7, 0x06, 0xd8, 0xc3, 0x00, 0x00, 0x5e, 0xc3, 0xfa, 0x8b, 0x36, 0xea, 0xc3,
- 0xc1, 0xe6, 0x07, 0x81, 0xc6, 0x00, 0x4d, 0x80, 0x64, 0x53, 0xfc, 0x80, 0x64,
- 0x54, 0xfb, 0x80, 0x4c, 0x58, 0x04, 0xf6, 0x44, 0x29, 0x08, 0x74, 0x04, 0x80,
- 0x64, 0x51, 0xfb, 0xf6, 0x44, 0x51, 0x02, 0x75, 0x0f, 0xf6, 0x44, 0x29, 0x10,
- 0x74, 0x09, 0xa1, 0x40, 0x60, 0x89, 0x04, 0x80, 0x4c, 0x50, 0x08, 0xfb, 0x5e,
- 0xc3, 0xa1, 0xea, 0xc3, 0x3d, 0x15, 0x00, 0x76, 0x03, 0xe9, 0xfd, 0x00, 0xd1,
- 0xe0, 0x93, 0x2e, 0xff, 0xa7, 0xb8, 0x46, 0x90, 0xe4, 0x46, 0xf6, 0x46, 0xfc,
- 0x46, 0x34, 0x47, 0x5e, 0x47, 0x82, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47,
- 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92,
- 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47, 0x92, 0x47,
- 0xe8, 0x13, 0xfd, 0x8a, 0x1e, 0x00, 0x5a, 0x2a, 0xff, 0xd1, 0xe3, 0x8b, 0x87,
- 0xef, 0x00, 0xe9, 0xb3, 0x00, 0xe8, 0x01, 0xfd, 0xe9, 0xa3, 0x00, 0x83, 0x3e,
- 0x42, 0xc4, 0x00, 0x74, 0x06, 0xc7, 0x06, 0x7e, 0x60, 0x00, 0x00, 0xa1, 0x20,
- 0x62, 0x39, 0x06, 0x10, 0xc4, 0x72, 0x0a, 0xc7, 0x06, 0xb0, 0xc3, 0xff, 0x03,
- 0xe9, 0x84, 0x00, 0x90, 0x68, 0x7e, 0x60, 0x50, 0x2b, 0x06, 0x10, 0xc4, 0x50,
- 0x6a, 0x0a, 0xe8, 0xf2, 0x03, 0x83, 0xc4, 0x08, 0x8b, 0xc8, 0xb8, 0xff, 0x03,
- 0xeb, 0x25, 0x83, 0x3e, 0x42, 0xc4, 0x00, 0x74, 0x06, 0xc7, 0x06, 0x7e, 0x60,
- 0x00, 0x00, 0x68, 0x7e, 0x60, 0xff, 0x36, 0xd4, 0xc3, 0xff, 0x36, 0x46, 0xc4,
- 0x6a, 0x0b, 0xe8, 0xcb, 0x03, 0x83, 0xc4, 0x08, 0x8b, 0xc8, 0xb8, 0xff, 0x07,
- 0xd3, 0xf8, 0xeb, 0x1f, 0x90, 0xa1, 0x10, 0x59, 0xd1, 0xe0, 0x2b, 0x06, 0x82,
- 0x60, 0x03, 0x06, 0x04, 0x59, 0x03, 0x06, 0x0c, 0x59, 0xa3, 0xb0, 0xc3, 0x50,
- 0xe8, 0x8a, 0xc0, 0x83, 0xc4, 0x02, 0xc1, 0xf8, 0x06, 0xa3, 0xb0, 0xc3, 0xeb,
- 0x1e, 0x90, 0xa1, 0xd8, 0xc3, 0x2d, 0xff, 0x03, 0x1b, 0xc9, 0x23, 0xc1, 0x05,
- 0xff, 0x03, 0xeb, 0xe1, 0x90, 0xa1, 0xea, 0xc3, 0x2d, 0x06, 0x00, 0x50, 0xe8,
- 0xa6, 0xfc, 0x83, 0xc4, 0x02, 0x8b, 0x1e, 0xea, 0xc3, 0xd1, 0xe3, 0x8b, 0x87,
- 0xc3, 0x00, 0xa3, 0xee, 0xc3, 0xff, 0x06, 0x80, 0x60, 0x83, 0x3e, 0x80, 0x60,
- 0x14, 0x7c, 0x12, 0x80, 0x0e, 0xee, 0xc3, 0x80, 0x83, 0x3e, 0x80, 0x60, 0x28,
- 0x7c, 0x06, 0xc7, 0x06, 0x80, 0x60, 0x00, 0x00, 0xa1, 0xb0, 0xc3, 0xbb, 0x00,
- 0xf1, 0x89, 0x07, 0xa1, 0xee, 0xc3, 0xbb, 0x80, 0xf1, 0x89, 0x07, 0x5e, 0xc3,
- 0x90, 0x15, 0x00, 0x04, 0x20, 0x0a, 0x80, 0x0f, 0x00, 0x07, 0x7e, 0x0f, 0xc5,
- 0x07, 0x77, 0x03, 0xd8, 0x05, 0x61, 0x01, 0xf9, 0x0b, 0x16, 0x10, 0x00, 0x11,
- 0x00, 0x0e, 0x07, 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x15, 0x01, 0x04, 0x20, 0x0a,
- 0x80, 0x0f, 0x00, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xd8, 0x05, 0x61,
- 0x01, 0xf9, 0x0b, 0x16, 0x10, 0x00, 0x11, 0x00, 0x0e, 0x07, 0x05, 0x6b, 0x09,
- 0x0f, 0xff, 0x15, 0x00, 0x12, 0x80, 0x13, 0x08, 0x04, 0x20, 0x0a, 0x80, 0x0f,
- 0x04, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05, 0x61, 0x01, 0xf9,
- 0x0b, 0x08, 0x0e, 0x04, 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x15, 0x00, 0x12, 0x80,
- 0x13, 0x08, 0x14, 0x08, 0x04, 0x20, 0x0a, 0x80, 0x0f, 0x04, 0x07, 0x7e, 0x0f,
- 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05, 0x61, 0x01, 0xf9, 0x0b, 0x08, 0x0e, 0x04,
- 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x15, 0x00, 0x12, 0x02, 0x13, 0x02, 0x04, 0x20,
- 0x0a, 0xa0, 0x0f, 0x04, 0x07, 0x7e, 0x0f, 0xc5, 0x07, 0x77, 0x03, 0xc8, 0x05,
- 0x61, 0x01, 0xf9, 0x0b, 0x77, 0x0c, 0x0e, 0x0d, 0x00, 0x0e, 0x07, 0x0e, 0xe7,
- 0x0e, 0xa7, 0x0e, 0x27, 0x05, 0x6b, 0x09, 0x0f, 0xff, 0x15, 0x00, 0x12, 0x02,
- 0x13, 0x02, 0x04, 0x20, 0x0a, 0xe0, 0x0f, 0x04, 0x07, 0x7e, 0x0f, 0xc5, 0x07,
- 0x77, 0x03, 0xc8, 0x05, 0x61, 0x01, 0xf9, 0x0b, 0x77, 0x0c, 0x06, 0x0d, 0x00,
- 0x0e, 0x07, 0x0e, 0xc7, 0x0e, 0xa7, 0x0e, 0x27, 0x05, 0x6b, 0x09, 0x0f, 0xff,
- 0x00, 0x06, 0x58, 0x1b, 0x20, 0x03, 0x14, 0x00, 0x3c, 0x00, 0x1e, 0x00, 0x1e,
- 0x00, 0x00, 0x03, 0xa0, 0x0f, 0x58, 0x02, 0x1e, 0x00, 0x28, 0x00, 0x1e, 0x00,
- 0x3c, 0x00, 0x80, 0x01, 0xd0, 0x07, 0xa4, 0x01, 0x28, 0x00, 0x1e, 0x00, 0x14,
- 0x00, 0x78, 0x00, 0x00, 0x01, 0x08, 0x07, 0x7c, 0x01, 0x34, 0x00, 0x1e, 0x00,
- 0x14, 0x00, 0xb4, 0x00, 0xc0, 0x00, 0xb0, 0x04, 0x54, 0x01, 0x40, 0x00, 0x19,
- 0x00, 0x14, 0x00, 0xf0, 0x00, 0x60, 0x00, 0x58, 0x02, 0x2c, 0x01, 0x64, 0x00,
- 0x14, 0x00, 0x14, 0x00, 0xe0, 0x01, 0x40, 0x00, 0xf4, 0x01, 0x2c, 0x01, 0x96,
- 0x00, 0x14, 0x00, 0x14, 0x00, 0xd0, 0x02, 0x39, 0x00, 0xc2, 0x01, 0x2c, 0x01,
- 0xc8, 0x00, 0x14, 0x00, 0x14, 0x00, 0x20, 0x03, 0x30, 0x00, 0x90, 0x01, 0x2c,
- 0x01, 0xfa, 0x00, 0x14, 0x00, 0x14, 0x00, 0xc0, 0x03, 0x20, 0x00, 0x2c, 0x01,
- 0x2c, 0x01, 0x2c, 0x01, 0x14, 0x00, 0x14, 0x00, 0xa0, 0x05, 0x10, 0x00, 0xc8,
- 0x00, 0x2c, 0x01, 0x58, 0x02, 0x14, 0x00, 0x14, 0x00, 0x40, 0x0b, 0x08, 0x00,
- 0x64, 0x00, 0xe1, 0x00, 0xe8, 0x03, 0x0e, 0x00, 0x14, 0x00, 0x80, 0x16, 0x06,
- 0x00, 0x64, 0x00, 0xdc, 0x00, 0xb0, 0x04, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x1e,
- 0x05, 0x00, 0x64, 0x00, 0xc8, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00,
- 0x24, 0x04, 0x00, 0x64, 0x00, 0xb4, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00,
- 0x00, 0x2d, 0x03, 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14,
- 0x00, 0x00, 0x3c, 0x02, 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06, 0x0a, 0x00,
- 0x14, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06, 0x0c,
- 0x00, 0x14, 0x00, 0x00, 0x5a, 0x02, 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40, 0x06,
- 0x0a, 0x00, 0x14, 0x00, 0x00, 0x5a, 0x04, 0x00, 0x64, 0x00, 0xa0, 0x00, 0x40,
- 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x64, 0x00, 0xa0, 0x00,
- 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x78, 0x02, 0x00, 0x64, 0x00, 0xa0,
- 0x00, 0x40, 0x06, 0x0c, 0x00, 0x14, 0x00, 0x00, 0xb4, 0xdc, 0x47, 0x36, 0x49,
- 0x62, 0x48, 0x44, 0x49, 0x8d, 0x48, 0x52, 0x49, 0xdc, 0x47, 0xb8, 0x48, 0xdc,
- 0x47, 0xc6, 0x48, 0xdc, 0x47, 0xd4, 0x48, 0xdc, 0x47, 0xf0, 0x48, 0xdc, 0x47,
- 0xfe, 0x48, 0xdc, 0x47, 0x0c, 0x49, 0xdc, 0x47, 0x28, 0x49, 0xdc, 0x47, 0x36,
- 0x49, 0xdc, 0x47, 0x44, 0x49, 0xdc, 0x47, 0x52, 0x49, 0xdc, 0x47, 0x7c, 0x49,
- 0xdc, 0x47, 0x8a, 0x49, 0x1e, 0x48, 0xb8, 0x48, 0x1e, 0x48, 0xc6, 0x48, 0x1e,
- 0x48, 0xd4, 0x48, 0x1e, 0x48, 0xf0, 0x48, 0x1e, 0x48, 0xfe, 0x48, 0x1e, 0x48,
- 0x0c, 0x49, 0x1e, 0x48, 0x28, 0x49, 0x1e, 0x48, 0x36, 0x49, 0x1e, 0x48, 0x44,
- 0x49, 0x1e, 0x48, 0x52, 0x49, 0x1e, 0x48, 0x7c, 0x49, 0x1e, 0x48, 0x8a, 0x49,
- 0xdc, 0x47, 0x98, 0x49, 0xdc, 0x47, 0xa6, 0x49, 0xdc, 0x47, 0xb4, 0x49, 0x1e,
- 0x48, 0x98, 0x49, 0x1e, 0x48, 0xa6, 0x49, 0x1e, 0x48, 0xb4, 0x49, 0x1e, 0x48,
- 0xe2, 0x48, 0xdc, 0x47, 0x36, 0x49, 0x3f, 0x48, 0xb8, 0x48, 0x3f, 0x48, 0xc6,
- 0x48, 0x3f, 0x48, 0xd4, 0x48, 0x3f, 0x48, 0xe2, 0x48, 0x3f, 0x48, 0xf0, 0x48,
- 0x3f, 0x48, 0xfe, 0x48, 0x3f, 0x48, 0x0c, 0x49, 0x3f, 0x48, 0x1a, 0x49, 0x3f,
- 0x48, 0x28, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47,
- 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36,
- 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49,
- 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc,
- 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47,
- 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36,
- 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49,
- 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc,
- 0x47, 0x36, 0x49, 0xfd, 0x47, 0xc2, 0x49, 0xfd, 0x47, 0xd0, 0x49, 0xfd, 0x47,
- 0xde, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xdc, 0x47, 0x36, 0x49, 0xb8, 0xec, 0x49,
- 0xc3, 0x8b, 0xcd, 0x8b, 0xec, 0x8b, 0x46, 0x02, 0xf7, 0x66, 0x04, 0x8b, 0x5e,
- 0x08, 0x03, 0x07, 0x83, 0xd2, 0x00, 0xf7, 0x76, 0x06, 0x89, 0x17, 0x8b, 0xe9,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8c, 0xd8, 0x8e, 0xc0, 0x8b, 0x7e, 0x04,
- 0x8b, 0x76, 0x06, 0x8b, 0x4e, 0x08, 0xf3, 0xa4, 0x5f, 0x5e, 0x5d, 0xc3, 0x8b,
- 0xcd, 0x8b, 0xec, 0xb8, 0x45, 0x31, 0xf7, 0x26, 0x86, 0x60, 0x05, 0x1f, 0x28,
- 0xa3, 0x86, 0x60, 0xf7, 0x66, 0x02, 0x8b, 0xc2, 0x8b, 0xe9, 0xc3, 0x8b, 0xcd,
- 0x8b, 0xec, 0x8b, 0x56, 0x02, 0xec, 0x32, 0xe4, 0x8b, 0xe9, 0xc3, 0x8b, 0xcd,
- 0x8b, 0xec, 0x8b, 0x56, 0x02, 0x8a, 0x46, 0x04, 0xee, 0x8b, 0xe9, 0xc3, 0x8b,
- 0xcd, 0x8b, 0xec, 0x8b, 0x56, 0x02, 0xed, 0x8b, 0xe9, 0xc3, 0x8b, 0xcd, 0x8b,
- 0xec, 0x8b, 0x56, 0x02, 0x8b, 0x46, 0x04, 0xef, 0x8b, 0xe9, 0xc3, 0x40, 0x28,
- 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
- 0x6c, 0x2e, 0x69, 0x6e, 0x63, 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x35, 0x20, 0x31,
- 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x30, 0x37, 0x20, 0x32, 0x31, 0x3a,
- 0x33, 0x38, 0x3a, 0x32, 0x39, 0x20, 0x74, 0x6f, 0x6e, 0x69, 0x20, 0x45, 0x78,
- 0x70, 0x20, 0x24, 0x09, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a,
- 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x68, 0x2c, 0x76,
- 0x20, 0x38, 0x2e, 0x31, 0x20, 0x31, 0x39, 0x39, 0x32, 0x2f, 0x30, 0x31, 0x2f,
- 0x32, 0x31, 0x20, 0x31, 0x31, 0x3a, 0x33, 0x37, 0x3a, 0x35, 0x34, 0x20, 0x67,
- 0x65, 0x6e, 0x65, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
- 0x2e, 0x68, 0x2c, 0x76, 0x20, 0x37, 0x2e, 0x33, 0x20, 0x31, 0x39, 0x39, 0x32,
- 0x2f, 0x30, 0x39, 0x2f, 0x30, 0x31, 0x20, 0x31, 0x35, 0x3a, 0x35, 0x33, 0x3a,
- 0x33, 0x39, 0x20, 0x63, 0x68, 0x72, 0x69, 0x73, 0x20, 0x45, 0x78, 0x70, 0x20,
- 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x6f,
- 0x6e, 0x63, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x61, 0x73, 0x6d, 0x2c, 0x76, 0x20,
- 0x39, 0x2e, 0x36, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x32, 0x2f, 0x32,
- 0x38, 0x20, 0x30, 0x30, 0x3a, 0x31, 0x35, 0x3a, 0x32, 0x30, 0x20, 0x63, 0x68,
- 0x72, 0x69, 0x73, 0x73, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x09, 0x00, 0x40,
- 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x63,
- 0x6f, 0x6d, 0x6d, 0x2e, 0x61, 0x73, 0x6d, 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x31,
- 0x20, 0x31, 0x39, 0x39, 0x32, 0x2f, 0x31, 0x31, 0x2f, 0x31, 0x32, 0x20, 0x31,
- 0x38, 0x3a, 0x33, 0x33, 0x3a, 0x31, 0x39, 0x20, 0x63, 0x68, 0x72, 0x69, 0x73,
- 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49,
- 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x66, 0x65, 0x70, 0x2e, 0x61, 0x73,
- 0x6d, 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x31, 0x39, 0x20, 0x31, 0x39, 0x39, 0x37,
- 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x38, 0x20, 0x30, 0x30, 0x3a, 0x31, 0x35, 0x3a,
- 0x31, 0x37, 0x20, 0x63, 0x68, 0x72, 0x69, 0x73, 0x73, 0x20, 0x45, 0x78, 0x70,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63,
- 0x6f, 0x6e, 0x63, 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x63, 0x2c, 0x76, 0x20, 0x39,
- 0x2e, 0x34, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x32, 0x2f, 0x31, 0x39,
- 0x20, 0x32, 0x32, 0x3a, 0x35, 0x30, 0x3a, 0x30, 0x33, 0x20, 0x63, 0x68, 0x72,
- 0x69, 0x73, 0x73, 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x64, 0x69, 0x73,
- 0x70, 0x2e, 0x63, 0x2c, 0x76, 0x20, 0x39, 0x2e, 0x33, 0x20, 0x31, 0x39, 0x39,
- 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x30, 0x37, 0x20, 0x32, 0x31, 0x3a, 0x33, 0x39,
- 0x3a, 0x33, 0x30, 0x20, 0x74, 0x6f, 0x6e, 0x69, 0x20, 0x45, 0x78, 0x70, 0x20,
- 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x73, 0x79,
- 0x6e, 0x63, 0x2e, 0x61, 0x73, 0x6d, 0x2c, 0x76, 0x20, 0x38, 0x2e, 0x35, 0x20,
- 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x38, 0x20, 0x30, 0x30,
- 0x3a, 0x30, 0x30, 0x3a, 0x35, 0x34, 0x20, 0x63, 0x68, 0x72, 0x69, 0x73, 0x73,
- 0x20, 0x45, 0x78, 0x70, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/sys/dev/digi/con.EPCX.h b/sys/dev/digi/con.EPCX.h
deleted file mode 100644
index 329c2f1..0000000
--- a/sys/dev/digi/con.EPCX.h
+++ /dev/null
@@ -1,3975 +0,0 @@
-/*-
- * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
- * based on work by Slawa Olhovchenkov
- * 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$
- */
-
-const u_char con_EPCX[] = {
- 0x43, 0x58, 0x01, 0x10, 0x01, 0x10, 0xff, 0x10, 0x00, 0x01, 0x40, 0xc8, 0x10,
- 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x37, 0xed,
- 0x34, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x23, 0x29, 0x66, 0x78, 0x63,
- 0x6f, 0x6e, 0x2e, 0x62, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32, 0x2e,
- 0x33, 0x2e, 0x32, 0x20, 0x20, 0x30, 0x36, 0x2f, 0x30, 0x32, 0x2f, 0x39, 0x37,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
- 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x31, 0x39, 0x39, 0x32, 0x2c, 0x20, 0x44,
- 0x49, 0x47, 0x49, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x61, 0x6c, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67,
- 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x20, 0x8b, 0x80, 0xaf, 0x01, 0x80, 0x01, 0x3c, 0x74, 0xeb, 0x21, 0xac,
- 0x01, 0x80, 0x01, 0x3c, 0x78, 0xeb, 0x22, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x7c,
- 0xeb, 0x23, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x80, 0xeb, 0x24, 0xac, 0x01, 0x80,
- 0x01, 0x3c, 0x84, 0xeb, 0x25, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x88, 0xeb, 0x26,
- 0xac, 0x01, 0x80, 0x01, 0x3c, 0x8c, 0xeb, 0x27, 0xac, 0x01, 0x80, 0x01, 0x3c,
- 0x90, 0xeb, 0x28, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x94, 0xeb, 0x29, 0xac, 0x01,
- 0x80, 0x01, 0x3c, 0x98, 0xeb, 0x2a, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x9c, 0xeb,
- 0x2b, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xa0, 0xeb, 0x2c, 0xac, 0x01, 0x80, 0x01,
- 0x3c, 0xa4, 0xeb, 0x2d, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xa8, 0xeb, 0x2e, 0xac,
- 0x01, 0x80, 0x01, 0x3c, 0xac, 0xeb, 0x2f, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xb0,
- 0xeb, 0x30, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xb4, 0xeb, 0x31, 0xac, 0x01, 0x80,
- 0x01, 0x3c, 0xb8, 0xeb, 0x32, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xbc, 0xeb, 0x33,
- 0xac, 0x01, 0x80, 0x01, 0x3c, 0xc0, 0xeb, 0x34, 0xac, 0x01, 0x80, 0x01, 0x3c,
- 0xc4, 0xeb, 0x35, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xc8, 0xeb, 0x36, 0xac, 0x01,
- 0x80, 0x01, 0x3c, 0xcc, 0xeb, 0x37, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xd0, 0xeb,
- 0x38, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xd4, 0xeb, 0x39, 0xac, 0x01, 0x80, 0x01,
- 0x3c, 0xd8, 0xeb, 0x3a, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xdc, 0xeb, 0x3b, 0xac,
- 0x01, 0x80, 0x01, 0x3c, 0xe0, 0xeb, 0x3c, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xe4,
- 0xeb, 0x3d, 0xac, 0x01, 0x80, 0x01, 0x3c, 0xe8, 0xeb, 0x3e, 0xac, 0x01, 0x80,
- 0x01, 0x3c, 0xec, 0xeb, 0x3f, 0xac, 0x10, 0x40, 0x00, 0x00, 0x01, 0x80, 0x01,
- 0x3c, 0xf0, 0xeb, 0x28, 0xac, 0x12, 0x40, 0x00, 0x00, 0x01, 0x80, 0x01, 0x3c,
- 0xf4, 0xeb, 0x28, 0xac, 0x01, 0x80, 0x08, 0x3c, 0x90, 0xeb, 0x08, 0x8d, 0xff,
- 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x00, 0x60,
- 0x88, 0x40, 0x01, 0x80, 0x1c, 0x3c, 0x50, 0x60, 0x9c, 0x27, 0x01, 0x00, 0x11,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x3c, 0x00, 0x30, 0xa5, 0x24,
- 0x01, 0x80, 0x06, 0x3c, 0x30, 0xeb, 0xc6, 0x24, 0x00, 0x80, 0x04, 0x3c, 0xcc,
- 0x31, 0x84, 0x24, 0x23, 0x20, 0xe4, 0x03, 0x21, 0x20, 0x86, 0x00, 0xfc, 0xff,
- 0x84, 0x24, 0xfc, 0xff, 0xc6, 0x24, 0x00, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xc8, 0xac, 0x2b, 0x08, 0xa6, 0x00, 0xf9, 0xff, 0x20, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x01, 0x3c, 0xfe, 0x00, 0x21, 0x34, 0x24, 0x40, 0x01, 0x01, 0x00, 0x60,
- 0x88, 0x40, 0x00, 0x80, 0x1f, 0x3c, 0x44, 0x32, 0xff, 0x27, 0x00, 0x80, 0x04,
- 0x3c, 0xd0, 0x47, 0x84, 0x24, 0x00, 0xa0, 0x01, 0x3c, 0x25, 0x20, 0x81, 0x00,
- 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x1d, 0x3c, 0xf8,
- 0xf8, 0xbd, 0x27, 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1f, 0x24, 0xf3, 0x1d,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x6d, 0x0c, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xa1, 0xaf, 0x14, 0x00,
- 0xa2, 0xaf, 0x18, 0x00, 0xa3, 0xaf, 0x1c, 0x00, 0xa4, 0xaf, 0x20, 0x00, 0xa5,
- 0xaf, 0x24, 0x00, 0xa6, 0xaf, 0x28, 0x00, 0xa7, 0xaf, 0x2c, 0x00, 0xa8, 0xaf,
- 0x30, 0x00, 0xa9, 0xaf, 0x34, 0x00, 0xaa, 0xaf, 0x38, 0x00, 0xab, 0xaf, 0x3c,
- 0x00, 0xac, 0xaf, 0x40, 0x00, 0xad, 0xaf, 0x44, 0x00, 0xae, 0xaf, 0x48, 0x00,
- 0xaf, 0xaf, 0x4c, 0x00, 0xb8, 0xaf, 0x50, 0x00, 0xb9, 0xaf, 0x58, 0x00, 0xbe,
- 0xaf, 0x5c, 0x00, 0xbf, 0xaf, 0x00, 0x70, 0x08, 0x40, 0x12, 0x48, 0x00, 0x00,
- 0x10, 0x50, 0x00, 0x00, 0x54, 0x00, 0xa8, 0xaf, 0x60, 0x00, 0xa9, 0xaf, 0x64,
- 0x00, 0xaa, 0xaf, 0x00, 0x68, 0x05, 0x40, 0x00, 0x60, 0x06, 0x40, 0x7c, 0x00,
- 0xa4, 0x30, 0x58, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0xa6,
- 0xaf, 0x24, 0x10, 0xa6, 0x00, 0x00, 0xff, 0x42, 0x30, 0x00, 0x04, 0x48, 0x30,
- 0x3b, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x44, 0x30, 0x42,
- 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x00, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x86, 0x40, 0x00, 0x68, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x24, 0x10, 0xa6, 0x00, 0x00, 0xff, 0x42, 0x30, 0xef, 0xff, 0x40, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x68, 0x00, 0xa8, 0x8f, 0x60, 0x00, 0xa9, 0x8f, 0x64, 0x00,
- 0xaa, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x88, 0x40, 0x13, 0x00, 0x20,
- 0x01, 0x11, 0x00, 0x40, 0x01, 0x14, 0x00, 0xa2, 0x8f, 0x18, 0x00, 0xa3, 0x8f,
- 0x1c, 0x00, 0xa4, 0x8f, 0x20, 0x00, 0xa5, 0x8f, 0x24, 0x00, 0xa6, 0x8f, 0x28,
- 0x00, 0xa7, 0x8f, 0x2c, 0x00, 0xa8, 0x8f, 0x30, 0x00, 0xa9, 0x8f, 0x34, 0x00,
- 0xaa, 0x8f, 0x38, 0x00, 0xab, 0x8f, 0x3c, 0x00, 0xac, 0x8f, 0x40, 0x00, 0xad,
- 0x8f, 0x44, 0x00, 0xae, 0x8f, 0x48, 0x00, 0xaf, 0x8f, 0x4c, 0x00, 0xb8, 0x8f,
- 0x50, 0x00, 0xb9, 0x8f, 0x58, 0x00, 0xbe, 0x8f, 0x5c, 0x00, 0xbf, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0xba, 0x8f, 0x10, 0x00, 0xa1, 0x8f, 0x6c, 0x00,
- 0xbd, 0x27, 0x08, 0x00, 0x40, 0x03, 0x10, 0x00, 0x00, 0x42, 0xb4, 0x8b, 0x88,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x06, 0x01, 0x01, 0xff, 0x08, 0x31,
- 0x26, 0x30, 0xc8, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0x68, 0x89, 0x40, 0x00,
- 0x60, 0x86, 0x40, 0xea, 0x1d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xff,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8b, 0x88, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x26, 0x40, 0x06, 0x01, 0x01, 0xff, 0x08, 0x31, 0x26, 0x30, 0xc8, 0x00,
- 0x00, 0x60, 0x86, 0x40, 0x8c, 0x2b, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc2,
- 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x08, 0x3c, 0x14, 0xf0,
- 0x08, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x06, 0x01, 0x01, 0xff, 0x08,
- 0x31, 0x26, 0x30, 0xc8, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0x68, 0x89, 0x40,
- 0x00, 0x60, 0x86, 0x40, 0x19, 0x35, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xb5,
- 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x04, 0x3c, 0x20, 0xd8,
- 0x84, 0x24, 0x24, 0x0c, 0x00, 0x0c, 0x74, 0x01, 0x05, 0x24, 0xb9, 0xff, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xec, 0xff, 0xbd, 0x27, 0x08, 0x00, 0xa1, 0xaf,
- 0x00, 0x70, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xba, 0xaf, 0x10,
- 0x00, 0xbf, 0xaf, 0x01, 0x80, 0x04, 0x3c, 0x20, 0xd8, 0x84, 0x24, 0x24, 0x0c,
- 0x00, 0x0c, 0x96, 0x01, 0x05, 0x24, 0x10, 0x00, 0xbf, 0x8f, 0x0c, 0x00, 0xba,
- 0x8f, 0x08, 0x00, 0xa1, 0x8f, 0x0c, 0x00, 0xbd, 0x27, 0x08, 0x00, 0x40, 0x03,
- 0x10, 0x00, 0x00, 0x42, 0xdc, 0xff, 0xbd, 0x27, 0x00, 0x00, 0xb0, 0xaf, 0x04,
- 0x00, 0xb1, 0xaf, 0x08, 0x00, 0xb2, 0xaf, 0x0c, 0x00, 0xb3, 0xaf, 0x10, 0x00,
- 0xb4, 0xaf, 0x14, 0x00, 0xb5, 0xaf, 0x18, 0x00, 0xb6, 0xaf, 0x1c, 0x00, 0xb7,
- 0xaf, 0x20, 0x00, 0xbf, 0xaf, 0x01, 0x80, 0x10, 0x3c, 0x2c, 0xea, 0x10, 0x8e,
- 0x00, 0x00, 0x11, 0x24, 0x20, 0x8c, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x80, 0x10, 0x02, 0x14, 0x8c, 0x88, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x08, 0x31, 0x01, 0x80, 0x04, 0x3c, 0x21, 0x20, 0x88, 0x00,
- 0x74, 0xec, 0x84, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x8a, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80,
- 0x10, 0x02, 0x14, 0x8c, 0x88, 0x8f, 0x01, 0x80, 0x04, 0x3c, 0x21, 0x20, 0x88,
- 0x00, 0x7c, 0xec, 0x84, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c,
- 0x04, 0x00, 0x0a, 0x25, 0x0c, 0x00, 0x4a, 0x31, 0x14, 0x8c, 0x8a, 0xaf, 0x08,
- 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x8c, 0x84, 0x8f, 0x10, 0x8c,
- 0x90, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0x26, 0x34, 0x00, 0x88,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x84, 0x8c, 0xf9, 0xff, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x8c, 0x84, 0xaf, 0x00, 0x00, 0xb0, 0x8f, 0x04, 0x00, 0xb1, 0x8f, 0x08, 0x00,
- 0xb2, 0x8f, 0x0c, 0x00, 0xb3, 0x8f, 0x10, 0x00, 0xb4, 0x8f, 0x14, 0x00, 0xb5,
- 0x8f, 0x18, 0x00, 0xb6, 0x8f, 0x1c, 0x00, 0xb7, 0x8f, 0x20, 0x00, 0xbf, 0x8f,
- 0x24, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x24,
- 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0xc0, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00, 0x82, 0x48, 0x07,
- 0x00, 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c, 0x01, 0x00, 0x80, 0x29, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x47, 0x02, 0x00, 0xba, 0x00,
- 0x11, 0x05, 0x00, 0x00, 0x00, 0x00, 0x02, 0x49, 0x07, 0x00, 0x7c, 0x00, 0x29,
- 0x31, 0x44, 0x00, 0x92, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x23, 0x90, 0x50, 0x02,
- 0xac, 0x00, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x21, 0x08, 0x3c, 0x01, 0x20,
- 0x80, 0x29, 0x8c, 0x40, 0x00, 0x93, 0x8c, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x2c, 0x00, 0x89, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x29,
- 0x31, 0x23, 0x01, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x02, 0x49, 0x07, 0x00,
- 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c, 0x01, 0x10, 0x80, 0x29, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x84, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x41, 0x07, 0x00,
- 0x7c, 0x00, 0x08, 0x31, 0x21, 0x08, 0x1c, 0x01, 0x20, 0x80, 0x28, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00,
- 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0x01, 0x00, 0xe8, 0x30, 0x09, 0x00, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x8c, 0x94, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x88, 0x31, 0x04, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x5d,
- 0x00, 0x83, 0x90, 0x03, 0x00, 0x00, 0x10, 0x08, 0x00, 0x2b, 0x35, 0x5c, 0x00,
- 0x83, 0x90, 0xf7, 0xff, 0x2b, 0x31, 0x26, 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49,
- 0x01, 0x54, 0x00, 0xab, 0xa0, 0x58, 0x00, 0xaa, 0xa0, 0xff, 0xfd, 0xe7, 0x30,
- 0x50, 0x00, 0x87, 0xa4, 0x00, 0x00, 0xc3, 0xa0, 0x21, 0x90, 0x53, 0x02, 0xe1,
- 0xff, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x08, 0x24, 0x67, 0x00, 0x88, 0xa0, 0x21, 0x48, 0x12,
- 0x02, 0x68, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xca, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x4a, 0x35, 0x0c, 0x00, 0xca, 0xa0, 0x00,
- 0x04, 0xe7, 0x34, 0x61, 0x00, 0x00, 0x10, 0x50, 0x00, 0x87, 0xa4, 0x02, 0x00,
- 0x08, 0x24, 0x67, 0x00, 0x88, 0xa0, 0x6c, 0x00, 0x89, 0x8c, 0xff, 0xff, 0x01,
- 0x24, 0x0c, 0x00, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x23, 0x48, 0x30, 0x01,
- 0x08, 0x00, 0x20, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xca, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0xbf, 0xff, 0x4a, 0x31, 0x0c, 0x00, 0xca, 0xa0, 0x00, 0x00,
- 0x09, 0x24, 0xff, 0xfa, 0xe7, 0x30, 0x50, 0x00, 0x87, 0xa4, 0x6c, 0x00, 0x89,
- 0xac, 0x4e, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x86, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25,
- 0x28, 0x91, 0x00, 0x08, 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x47,
- 0x02, 0x00, 0x50, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x3c, 0xdc,
- 0x37, 0x4a, 0x25, 0x04, 0x00, 0x8a, 0xac, 0x49, 0x00, 0x88, 0x90, 0x4a, 0x00,
- 0x89, 0x90, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x86,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00, 0x08, 0x00, 0xc2, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0xc0, 0x47, 0x02, 0x00, 0x39, 0x00, 0x11, 0x05, 0x00, 0x00,
- 0x00, 0x00, 0x44, 0x00, 0x92, 0x8c, 0x49, 0x00, 0x88, 0x90, 0x4a, 0x00, 0x89,
- 0x90, 0x23, 0x90, 0x50, 0x02, 0x2c, 0x00, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0xca, 0x90, 0x0a, 0x00, 0xb5, 0x94, 0x0c, 0x00, 0xb6, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40,
- 0x0a, 0x01, 0x1d, 0x00, 0x09, 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x93,
- 0x8c, 0x3c, 0x00, 0x94, 0x8c, 0x0e, 0x00, 0x97, 0x94, 0x21, 0x40, 0x96, 0x02,
- 0x00, 0x00, 0x03, 0x91, 0x01, 0x00, 0xd6, 0x26, 0x00, 0x00, 0xc3, 0xa0, 0x24,
- 0xb0, 0xd7, 0x02, 0x21, 0x90, 0x53, 0x02, 0x04, 0x00, 0x41, 0x06, 0x00, 0x00,
- 0x00, 0x00, 0xf8, 0xff, 0xb6, 0x16, 0x21, 0x40, 0x96, 0x02, 0x00, 0x00, 0x12,
- 0x24, 0x00, 0x00, 0x88, 0x8c, 0x0c, 0x00, 0xb6, 0xa4, 0x04, 0x00, 0x09, 0x8d,
- 0x44, 0x00, 0x92, 0xac, 0x08, 0x00, 0x20, 0x01, 0x21, 0x20, 0x00, 0x01, 0x21,
- 0x40, 0x12, 0x02, 0x06, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff,
- 0xe7, 0x30, 0x50, 0x00, 0x87, 0xa4, 0x00, 0x80, 0x08, 0x3c, 0x80, 0x37, 0x08,
- 0x25, 0x04, 0x00, 0x88, 0xac, 0x00, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x09, 0x8d, 0x44, 0x00, 0x80, 0xac, 0x08, 0x00, 0x20, 0x01, 0x21,
- 0x20, 0x00, 0x01, 0x00, 0x00, 0x88, 0x8c, 0x44, 0x00, 0x92, 0xac, 0x04, 0x00,
- 0x09, 0x8d, 0x21, 0x20, 0x00, 0x01, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x50, 0x00, 0x87, 0x94, 0x6a, 0x00, 0x92, 0x94, 0x42, 0x42, 0x07, 0x00,
- 0x7c, 0x00, 0x08, 0x31, 0x21, 0x98, 0x1c, 0x01, 0xa0, 0x88, 0x73, 0x8e, 0x38,
- 0x00, 0x94, 0x8c, 0x12, 0x00, 0xb5, 0x94, 0x14, 0x00, 0xb6, 0x94, 0x16, 0x00,
- 0x97, 0x94, 0x28, 0x00, 0x8c, 0x94, 0x5c, 0x00, 0x8e, 0x90, 0x5d, 0x00, 0x8f,
- 0x90, 0x14, 0x00, 0xc2, 0x90, 0x00, 0x00, 0xc3, 0x90, 0x00, 0x42, 0x02, 0x00,
- 0x25, 0x18, 0x68, 0x00, 0x08, 0x00, 0x60, 0x02, 0x24, 0x18, 0x72, 0x00, 0xff,
- 0xf9, 0x68, 0x30, 0x89, 0x02, 0x0e, 0x11, 0x21, 0x48, 0x95, 0x02, 0x98, 0x02,
- 0x0f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xa1, 0xff, 0x00, 0x61,
- 0x2c, 0x12, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb5, 0x26,
- 0x24, 0xa8, 0xb7, 0x02, 0x20, 0x00, 0xb6, 0x16, 0x00, 0x00, 0x00, 0x00, 0xef,
- 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x48, 0x95, 0x02, 0x00, 0x00,
- 0x23, 0xa1, 0xff, 0x00, 0x61, 0x2c, 0x07, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x15, 0x00, 0xb6, 0x16,
- 0x00, 0x00, 0x00, 0x00, 0xe4, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x68, 0x30, 0x92, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0xdd, 0x02, 0xb6, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x8a, 0x31, 0x09, 0x00, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x48, 0x95, 0x02, 0x00, 0x00, 0x23, 0xa1, 0x01, 0x00, 0xb5, 0x26, 0x24,
- 0xa8, 0xb7, 0x02, 0x03, 0x00, 0xb6, 0x16, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x48, 0x30, 0xca, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x1c, 0x00, 0x88, 0x94, 0x23, 0x48, 0xb6, 0x02, 0x24, 0x48, 0x37, 0x01, 0x12,
- 0x00, 0xb5, 0xa4, 0x2b, 0x08, 0x28, 0x01, 0x1c, 0x00, 0x20, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0xea, 0x30, 0x19, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0xe7, 0x34, 0x00, 0x10, 0x88, 0x31, 0x06, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x38, 0x00, 0x80, 0x13, 0x3c, 0xbc,
- 0x35, 0x73, 0x26, 0x00, 0x80, 0x1f, 0x3c, 0x04, 0x36, 0xff, 0x27, 0x5f, 0x00,
- 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x31, 0x54, 0x00, 0xa9,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x26, 0x48, 0x28, 0x01, 0x54, 0x00, 0xa9, 0xa0,
- 0x58, 0x00, 0xaa, 0x90, 0x00, 0x00, 0x00, 0x00, 0x25, 0x50, 0x48, 0x01, 0x58,
- 0x00, 0xaa, 0xa0, 0x68, 0x00, 0x8b, 0x90, 0x27, 0x40, 0x00, 0x01, 0x24, 0x58,
- 0x68, 0x01, 0x10, 0x00, 0xcb, 0xa0, 0x12, 0x00, 0xb5, 0xa4, 0x08, 0x00, 0xe0,
- 0x03, 0x50, 0x00, 0x87, 0xa4, 0x24, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x0d, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x28, 0x91, 0x00, 0x18,
- 0x00, 0xc8, 0x90, 0x54, 0x00, 0xa9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40,
- 0x09, 0x01, 0xf0, 0x00, 0x08, 0x31, 0x26, 0x48, 0x28, 0x01, 0x54, 0x00, 0xa9,
- 0xa0, 0x58, 0x00, 0xaa, 0x90, 0x00, 0x00, 0x00, 0x00, 0x25, 0x50, 0x48, 0x01,
- 0x58, 0x00, 0xaa, 0xa0, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x0a, 0x3c, 0xe0, 0x3a, 0x4a, 0x25, 0x07, 0x00, 0x00, 0x10, 0x04, 0x00,
- 0x8a, 0xac, 0x24, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0xc0,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00,
- 0x38, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x20, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x12, 0x00, 0xb5, 0x94, 0x14, 0x00, 0xb6, 0x94, 0x38, 0x00,
- 0x94, 0x8c, 0x16, 0x00, 0x97, 0x94, 0x21, 0x40, 0x95, 0x02, 0x01, 0x00, 0xb5,
- 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x09, 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00,
- 0x48, 0x00, 0xc3, 0x90, 0xff, 0xff, 0x29, 0x25, 0x00, 0x00, 0x03, 0xa1, 0x21,
- 0x40, 0x95, 0x02, 0xf7, 0xff, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x26, 0x24, 0xa8, 0xb7,
- 0x02, 0x12, 0x00, 0xb5, 0xa4, 0x00, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x09, 0x8d, 0x21, 0x20, 0x00, 0x01, 0x08, 0x00, 0x20, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x3c, 0x80, 0x3b, 0x4a, 0x25, 0x04, 0x00,
- 0x00, 0x10, 0x04, 0x00, 0x8a, 0xac, 0x24, 0x00, 0x86, 0x8c, 0x50, 0x00, 0x87,
- 0x94, 0x25, 0x28, 0x91, 0x00, 0x0a, 0x00, 0xb5, 0x94, 0x0c, 0x00, 0xb6, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0xc9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x29, 0x21, 0x22, 0x48,
- 0x09, 0x00, 0x3c, 0x00, 0x94, 0x8c, 0x0e, 0x00, 0x97, 0x94, 0x21, 0x40, 0x96,
- 0x02, 0x08, 0x00, 0x20, 0x19, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x29, 0x25,
- 0x00, 0x00, 0x03, 0x91, 0x01, 0x00, 0xd6, 0x26, 0x48, 0x00, 0xc3, 0xa0, 0x24,
- 0xb0, 0xd7, 0x02, 0xf8, 0xff, 0xb6, 0x16, 0x21, 0x40, 0x96, 0x02, 0x00, 0x00,
- 0x88, 0x8c, 0x0c, 0x00, 0xb6, 0xa4, 0x04, 0x00, 0x09, 0x8d, 0x21, 0x20, 0x00,
- 0x01, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x3c,
- 0x08, 0x3c, 0x4a, 0x25, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, 0x8a, 0xac, 0x24,
- 0x00, 0x86, 0x8c, 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00, 0x0a, 0x00,
- 0xb5, 0x94, 0x0c, 0x00, 0xb6, 0x94, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0xb6,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0xff, 0x29, 0x25, 0x22, 0x48, 0x09, 0x00, 0x3c, 0x00, 0x94, 0x8c, 0x0e,
- 0x00, 0x97, 0x94, 0x2a, 0x00, 0x8c, 0x94, 0x63, 0x00, 0x8e, 0x90, 0x15, 0x00,
- 0x20, 0x19, 0x21, 0x40, 0x96, 0x02, 0xff, 0xff, 0x29, 0x25, 0x00, 0x00, 0x08,
- 0x91, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x00, 0x01, 0x80, 0x40, 0x08, 0x00,
- 0x21, 0x08, 0x1c, 0x01, 0xa0, 0x84, 0x28, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x88, 0x31, 0x02, 0x00,
- 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x63, 0x24, 0x01, 0x00, 0xce,
- 0x25, 0x48, 0x00, 0xc3, 0xa0, 0x01, 0x00, 0xd6, 0x26, 0x24, 0xb0, 0xd7, 0x02,
- 0xeb, 0xff, 0xb6, 0x16, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x8e, 0xa0, 0x00,
- 0x00, 0x88, 0x8c, 0x0c, 0x00, 0xb6, 0xa4, 0x04, 0x00, 0x09, 0x8d, 0x21, 0x20,
- 0x00, 0x01, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xc0,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x00, 0x10, 0xff, 0xff, 0xce, 0x25,
- 0x20, 0x00, 0x8a, 0x31, 0x02, 0x00, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0e, 0x24, 0x04, 0x00, 0x8a, 0x31, 0xea, 0xff, 0x40, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0xed, 0xff, 0x20, 0x11, 0x00, 0x00, 0x0e, 0x24, 0xff, 0xff, 0x29,
- 0x25, 0x0d, 0x00, 0x0a, 0x24, 0xe4, 0xff, 0x00, 0x10, 0x48, 0x00, 0xca, 0xa0,
- 0x21, 0x40, 0xc0, 0x01, 0x00, 0x00, 0x0e, 0x24, 0x08, 0x00, 0x8a, 0x31, 0x08,
- 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8a, 0x31, 0xdc, 0xff,
- 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0xd8, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xff, 0x00, 0x10,
- 0x0a, 0x00, 0x03, 0x24, 0x21, 0x40, 0xc0, 0x01, 0x07, 0x00, 0x08, 0x31, 0x07,
- 0x00, 0x08, 0x39, 0x2b, 0x08, 0x28, 0x01, 0xd5, 0xff, 0x20, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x48, 0x28, 0x01, 0x08, 0x00, 0xce, 0x25, 0xf8, 0xff, 0xce,
- 0x31, 0x20, 0x00, 0x03, 0x24, 0x48, 0x00, 0xc3, 0xa0, 0xff, 0xff, 0x08, 0x25,
- 0xfd, 0xff, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xff, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xbf, 0xff, 0xe7, 0x30, 0x50, 0x00, 0x87, 0xa4, 0x00, 0x80,
- 0x08, 0x3c, 0x64, 0x36, 0x08, 0x25, 0x2d, 0x0e, 0x00, 0x08, 0x04, 0x00, 0x88,
- 0xac, 0x74, 0x00, 0x9f, 0xac, 0x63, 0x00, 0x8e, 0xa0, 0x00, 0x00, 0x88, 0x8c,
- 0x0c, 0x00, 0xb6, 0xa4, 0x04, 0x00, 0x09, 0x8d, 0x44, 0x00, 0x92, 0xac, 0x08,
- 0x00, 0x20, 0x01, 0x21, 0x20, 0x00, 0x01, 0x00, 0x80, 0x0a, 0x3c, 0xcc, 0x3d,
- 0x4a, 0x25, 0x04, 0x00, 0x8a, 0xac, 0x49, 0x00, 0x88, 0x90, 0x4a, 0x00, 0x89,
- 0x90, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x86, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0xbd, 0xfe, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00, 0x08, 0x00, 0xc2, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0xc0, 0x47, 0x02, 0x00, 0xbd, 0xfe, 0x11, 0x05, 0x00, 0x00, 0x00,
- 0x00, 0x44, 0x00, 0x92, 0x8c, 0x49, 0x00, 0x88, 0x90, 0x4a, 0x00, 0x89, 0x90,
- 0x23, 0x90, 0x50, 0x02, 0xb0, 0xfe, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0xca, 0x90, 0x0a, 0x00, 0xb5, 0x94, 0x0c, 0x00, 0xb6, 0x94, 0x24, 0x40,
- 0x0a, 0x01, 0xa4, 0xfe, 0x09, 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x93,
- 0x8c, 0x3c, 0x00, 0x94, 0x8c, 0x0e, 0x00, 0x97, 0x94, 0x74, 0x00, 0x88, 0x8c,
- 0x2a, 0x00, 0x8c, 0x94, 0x62, 0x00, 0x8d, 0x90, 0x63, 0x00, 0x8e, 0x90, 0x09,
- 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x91, 0xfe, 0xb6, 0x12, 0x21, 0x40,
- 0x96, 0x02, 0x00, 0x00, 0x03, 0x91, 0x01, 0x00, 0xd6, 0x26, 0x24, 0xb0, 0xd7,
- 0x02, 0x24, 0x40, 0x6d, 0x00, 0x80, 0x40, 0x08, 0x00, 0x21, 0x08, 0x1c, 0x01,
- 0xa0, 0x80, 0x28, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xce, 0x25, 0x00, 0x00, 0xc3, 0xa0, 0x21, 0x90,
- 0x53, 0x02, 0xc1, 0xff, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xb6,
- 0x12, 0x21, 0x40, 0x96, 0x02, 0x00, 0x00, 0x03, 0x91, 0x01, 0x00, 0xd6, 0x26,
- 0x24, 0xb0, 0xd7, 0x02, 0x24, 0x40, 0x6d, 0x00, 0x80, 0x40, 0x08, 0x00, 0x21,
- 0x08, 0x1c, 0x01, 0xa0, 0x80, 0x28, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x88, 0x31, 0xed, 0xff, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x27, 0x00, 0x03, 0x24,
- 0x01, 0x00, 0x88, 0x31, 0xe8, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x13,
- 0x00, 0x00, 0x10, 0x28, 0x00, 0x03, 0x24, 0x01, 0x00, 0x88, 0x31, 0xe3, 0xff,
- 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x10, 0x21, 0x00, 0x03,
- 0x24, 0x01, 0x00, 0x88, 0x31, 0xde, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x10, 0x29, 0x00, 0x03, 0x24, 0x01, 0x00, 0x88, 0x31, 0xd9,
- 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x10, 0x5e, 0x00,
- 0x03, 0x24, 0x01, 0x00, 0x88, 0x31, 0xd4, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0x5c, 0x00, 0x08, 0x24, 0x00, 0x00, 0xc8, 0xa0, 0x02, 0x00, 0xce, 0x25,
- 0x21, 0x90, 0x53, 0x02, 0xcf, 0xff, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x64,
- 0x0f, 0x00, 0x0c, 0x61, 0x00, 0x83, 0xa0, 0x61, 0x00, 0x83, 0x90, 0xca, 0xff,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x88, 0x31, 0xc6, 0xff, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0x00, 0x10, 0xe0, 0xff, 0x63, 0x24,
- 0x02, 0x00, 0xc0, 0x11, 0x00, 0x20, 0x89, 0x31, 0xff, 0xff, 0xce, 0x25, 0xc0,
- 0xff, 0x20, 0x11, 0x02, 0x00, 0x08, 0x24, 0x57, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x42, 0x4a, 0x0c, 0x00, 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c,
- 0x01, 0x20, 0x89, 0x29, 0x8c, 0x21, 0x40, 0xc0, 0x01, 0x08, 0x00, 0xce, 0x25,
- 0x08, 0x00, 0x20, 0x01, 0xf8, 0xff, 0xce, 0x31, 0x23, 0x40, 0xc8, 0x01, 0x05,
- 0x00, 0x01, 0x29, 0xb2, 0xff, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x10, 0x02, 0x00, 0x08,
- 0x24, 0x23, 0x40, 0xc8, 0x01, 0x20, 0x00, 0x03, 0x24, 0xff, 0xff, 0x08, 0x25,
- 0xa9, 0xff, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xa0, 0x21,
- 0x90, 0x53, 0x02, 0xf9, 0xff, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0f,
- 0x00, 0x0c, 0x61, 0x00, 0x88, 0xa0, 0x61, 0x00, 0x88, 0x90, 0xf4, 0xff, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x89, 0x31, 0x9d, 0xff, 0x20, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x10, 0x7f, 0x00, 0x08, 0x24, 0x00,
- 0x80, 0x89, 0x31, 0x98, 0xff, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00,
- 0x00, 0x10, 0x7f, 0x00, 0x08, 0x24, 0x21, 0x40, 0xc0, 0x01, 0x20, 0x00, 0x8a,
- 0x31, 0x1a, 0x00, 0x40, 0x15, 0x04, 0x00, 0x89, 0x31, 0x09, 0x00, 0x20, 0x11,
- 0x0d, 0x00, 0x0a, 0x24, 0x00, 0x00, 0x0e, 0x24, 0x00, 0x00, 0xca, 0xa0, 0x21,
- 0x90, 0x53, 0x02, 0x04, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0f,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x03, 0x24, 0x00, 0x01, 0x88,
- 0x31, 0x85, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x10,
- 0x05, 0x00, 0x08, 0x24, 0x21, 0x40, 0xc0, 0x01, 0x00, 0x00, 0x0e, 0x24, 0x08,
- 0x00, 0x89, 0x31, 0x0e, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x8a, 0x31, 0x03, 0x00, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xff, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x24, 0xc2, 0x49, 0x0c, 0x00,
- 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c, 0x01, 0x30, 0x89, 0x29, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff,
- 0x00, 0x10, 0x0a, 0x00, 0x03, 0x24, 0x02, 0x41, 0x08, 0x00, 0x05, 0x00, 0x00,
- 0x10, 0x03, 0x00, 0x08, 0x25, 0x03, 0x00, 0x00, 0x10, 0x05, 0x00, 0x08, 0x24,
- 0x01, 0x00, 0x00, 0x10, 0x09, 0x00, 0x08, 0x24, 0x00, 0x00, 0xc3, 0xa0, 0x21,
- 0x90, 0x53, 0x02, 0x04, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x64, 0x0f,
- 0x00, 0x0c, 0x61, 0x00, 0x88, 0xa0, 0x61, 0x00, 0x88, 0x90, 0x40, 0x00, 0x89,
- 0x31, 0x11, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x29,
- 0x0e, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x83, 0x90, 0x04,
- 0x00, 0x01, 0x29, 0x57, 0xff, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xc3, 0xa0, 0x21, 0x90, 0x53, 0x02, 0x53, 0xff, 0x40, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x64, 0x0f, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x83, 0x90,
- 0x4e, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x25, 0x00,
- 0x1e, 0x09, 0x24, 0x19, 0x00, 0x09, 0x01, 0x12, 0x40, 0x00, 0x00, 0x0c, 0xff,
- 0x00, 0x10, 0x21, 0x90, 0x48, 0x02, 0x01, 0x00, 0x00, 0x8c, 0xff, 0xe7, 0xe7,
- 0x30, 0x42, 0x42, 0x07, 0x00, 0x7c, 0x00, 0x08, 0x31, 0x21, 0x98, 0x1c, 0x01,
- 0xa0, 0x88, 0x73, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x5a, 0x00, 0xb8, 0x90, 0x5b, 0x00, 0xb9, 0x90, 0x5e, 0x00,
- 0x8d, 0x90, 0x00, 0x80, 0x13, 0x3c, 0x9c, 0x41, 0x73, 0x26, 0xff, 0xfd, 0x68,
- 0x30, 0x09, 0x00, 0x0d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 0x3c,
- 0x20, 0x43, 0x73, 0x26, 0xee, 0xfd, 0x00, 0x10, 0x00, 0x08, 0xe7, 0x34, 0x5a,
- 0x00, 0xb8, 0x90, 0x5b, 0x00, 0xb9, 0x90, 0x00, 0x80, 0x13, 0x3c, 0xc8, 0x41,
- 0x73, 0x26, 0xff, 0xf9, 0x68, 0x30, 0x05, 0x00, 0x18, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0xd7, 0xfd, 0x19, 0x15, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x09, 0x31, 0x0b, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff,
- 0x08, 0x31, 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa,
- 0x90, 0xfb, 0xff, 0x2b, 0x31, 0x26, 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01,
- 0x54, 0x00, 0xab, 0xa0, 0xf1, 0xfd, 0x00, 0x10, 0x58, 0x00, 0xaa, 0xa0, 0xef,
- 0xfd, 0x19, 0x17, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x08, 0x35, 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9,
- 0x90, 0x58, 0x00, 0xaa, 0x90, 0x04, 0x00, 0x2b, 0x35, 0x26, 0x48, 0x2b, 0x01,
- 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0, 0x58, 0x00, 0xaa, 0xa0, 0x00,
- 0x08, 0x89, 0x31, 0xe1, 0xfd, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0xe7, 0x34, 0x00, 0x80, 0x13, 0x3c, 0xdd, 0xfd, 0x00, 0x10, 0x70, 0x42, 0x73,
- 0x26, 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x08, 0x31,
- 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0xfb,
- 0xff, 0x2b, 0x31, 0x26, 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01, 0x54, 0x00,
- 0xab, 0xa0, 0x58, 0x00, 0xaa, 0xa0, 0xff, 0xef, 0xe7, 0x30, 0x42, 0x4a, 0x07,
- 0x00, 0x7c, 0x00, 0x29, 0x31, 0x21, 0x98, 0x3c, 0x01, 0xa0, 0x88, 0x73, 0x8e,
- 0x40, 0x00, 0x88, 0x31, 0xca, 0xfd, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xfd, 0x68, 0x30, 0xc7, 0xfd, 0x0e, 0x11, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xfd,
- 0x0f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x89, 0x31, 0x07, 0x00, 0x20,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0xaa, 0x90, 0x5b, 0x00, 0xab, 0x90,
- 0xbe, 0xfd, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xfd, 0x0b, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x89, 0x31, 0x9c, 0xfd, 0x20, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0x5e, 0x00, 0x8d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x98, 0xfd, 0x0d,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe7, 0x34, 0x00, 0x80, 0x13, 0x3c,
- 0x94, 0xfd, 0x00, 0x10, 0x20, 0x43, 0x73, 0x26, 0xff, 0xf7, 0xe7, 0x30, 0x42,
- 0x4a, 0x07, 0x00, 0x7c, 0x00, 0x29, 0x31, 0x21, 0x98, 0x3c, 0x01, 0xa0, 0x88,
- 0x73, 0x8e, 0x8d, 0xfd, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x8d,
- 0x90, 0xff, 0xfd, 0x68, 0x30, 0x7b, 0xfd, 0x0d, 0x15, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0xe7, 0x34, 0x00, 0x80, 0x13, 0x3c, 0x85, 0xfd, 0x00, 0x10, 0x20,
- 0x43, 0x73, 0x26, 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x09, 0x31, 0x0b, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xff, 0x08,
- 0x31, 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90,
- 0xfb, 0xff, 0x2b, 0x31, 0x26, 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01, 0x54,
- 0x00, 0xab, 0xa0, 0x93, 0xfd, 0x00, 0x10, 0x58, 0x00, 0xaa, 0xa0, 0x91, 0xfd,
- 0xcf, 0x15, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x08, 0x35, 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9, 0x90,
- 0x58, 0x00, 0xaa, 0x90, 0x04, 0x00, 0x2b, 0x35, 0x26, 0x48, 0x2b, 0x01, 0x25,
- 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0, 0x58, 0x00, 0xaa, 0xa0, 0x00, 0x08,
- 0x89, 0x31, 0x83, 0xfd, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xe7,
- 0x34, 0x00, 0x80, 0x13, 0x3c, 0x7f, 0xfd, 0x00, 0x10, 0x70, 0x42, 0x73, 0x26,
- 0xc2, 0x51, 0x03, 0x00, 0x3c, 0x00, 0x4a, 0x31, 0x21, 0x40, 0x5c, 0x01, 0xd0,
- 0x8b, 0x08, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x25, 0x21, 0x08,
- 0x5c, 0x01, 0xd0, 0x8b, 0x28, 0xac, 0x00, 0x10, 0x6a, 0x30, 0x0e, 0x00, 0x40,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, 0x31, 0x71, 0xfd, 0x60, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8a, 0x31, 0x03, 0x00, 0x40, 0x15, 0x00,
- 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x10, 0x00, 0x10, 0x03, 0x24, 0x4f, 0x00,
- 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x35, 0x67, 0xfd, 0x00,
- 0x10, 0x4f, 0x00, 0xa8, 0xa0, 0x04, 0x00, 0x88, 0x31, 0x64, 0xfd, 0x00, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6a, 0x30, 0x0c, 0x00, 0x40, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xfd, 0x63, 0x30, 0x4f, 0x00, 0xa8, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x08, 0x35, 0x4f, 0x00, 0xa8, 0xa0, 0xff, 0x00, 0x0b,
- 0x24, 0x2a, 0x08, 0x6b, 0x00, 0x40, 0xfd, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x47, 0xfd, 0x6b, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x88, 0x31, 0x08,
- 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xa1, 0x01, 0x00,
- 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x4e, 0xfd, 0xb6, 0x16, 0x00, 0x00, 0x00,
- 0x00, 0x1d, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x08, 0x24,
- 0x00, 0x00, 0x28, 0xa1, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x17,
- 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x00, 0x80,
- 0x89, 0x31, 0x02, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x02, 0x42, 0x03,
- 0x00, 0x21, 0x48, 0x95, 0x02, 0x00, 0x00, 0x28, 0xa1, 0x01, 0x00, 0xb5, 0x26,
- 0x24, 0xa8, 0xb7, 0x02, 0x0a, 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x48, 0x95, 0x02, 0x00, 0x00, 0x23, 0xa1, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8,
- 0xb7, 0x02, 0x35, 0xfd, 0xb6, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x26, 0xff, 0xff, 0xb5, 0x26,
- 0x24, 0xb0, 0xb7, 0x02, 0xff, 0xff, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x4f,
- 0x00, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x35, 0x29, 0xfd,
- 0x00, 0x10, 0x4f, 0x00, 0xa8, 0xa0, 0x24, 0x00, 0x86, 0x8c, 0x25, 0x28, 0x91,
- 0x00, 0x78, 0x00, 0xc8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x48, 0x00, 0x01,
- 0x50, 0x00, 0x08, 0x31, 0x20, 0x00, 0x29, 0x31, 0x80, 0x48, 0x09, 0x00, 0x25,
- 0x40, 0x09, 0x01, 0x70, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x48,
- 0x09, 0x00, 0x20, 0x00, 0x29, 0x31, 0x20, 0x00, 0x29, 0x39, 0x25, 0x40, 0x09,
- 0x01, 0x54, 0x00, 0xa9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x09, 0x01,
- 0xf0, 0x00, 0x08, 0x31, 0x26, 0x48, 0x28, 0x01, 0x54, 0x00, 0xa9, 0xa0, 0x58,
- 0x00, 0xaa, 0x90, 0x00, 0x00, 0x00, 0x00, 0x25, 0x50, 0x48, 0x01, 0x08, 0x00,
- 0xe0, 0x03, 0x58, 0x00, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x01, 0x3c, 0x25, 0x20, 0x81, 0x00, 0x00, 0x20, 0x01, 0x3c,
- 0x25, 0x28, 0xa1, 0x00, 0x05, 0x00, 0xc1, 0x2c, 0x74, 0x00, 0x20, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x82, 0x30, 0x03, 0x00, 0xa3, 0x30, 0x23, 0x38,
- 0x43, 0x00, 0x49, 0x00, 0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x20, 0x82,
- 0x00, 0x05, 0x00, 0xe0, 0x1c, 0xc0, 0x70, 0x02, 0x00, 0x00, 0x00, 0x88, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x10, 0x06, 0x48, 0xc8, 0x01, 0x00,
- 0x00, 0x89, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0xc9, 0x01, 0x22, 0x78,
- 0x0e, 0x00, 0x04, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x50, 0xe8,
- 0x01, 0x25, 0x48, 0x2a, 0x01, 0x04, 0x00, 0x84, 0x24, 0x00, 0x00, 0xa9, 0xb8,
- 0x23, 0x28, 0xa3, 0x00, 0x21, 0x30, 0xc3, 0x00, 0xec, 0xff, 0xc6, 0x24, 0xc0,
- 0x70, 0x07, 0x00, 0x1a, 0x00, 0xc0, 0x18, 0x22, 0x78, 0x0e, 0x00, 0x04, 0x00,
- 0x89, 0x8c, 0x06, 0x40, 0xc8, 0x01, 0x08, 0x00, 0x8a, 0x8c, 0x04, 0x60, 0xe9,
- 0x01, 0x0c, 0x00, 0x8b, 0x8c, 0x25, 0x60, 0x88, 0x01, 0x10, 0x00, 0x88, 0x8c,
- 0x04, 0x00, 0xac, 0xac, 0x06, 0x48, 0xc9, 0x01, 0x04, 0x60, 0xea, 0x01, 0x25,
- 0x60, 0x89, 0x01, 0x08, 0x00, 0xac, 0xac, 0x06, 0x50, 0xca, 0x01, 0x04, 0x60,
- 0xeb, 0x01, 0x25, 0x60, 0x8a, 0x01, 0x0c, 0x00, 0xac, 0xac, 0x06, 0x58, 0xcb,
- 0x01, 0x04, 0x60, 0xe8, 0x01, 0x25, 0x60, 0x8b, 0x01, 0x10, 0x00, 0xac, 0xac,
- 0x10, 0x00, 0x84, 0x24, 0x10, 0x00, 0xa5, 0x24, 0xf0, 0xff, 0xc6, 0x24, 0xe8,
- 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xc6, 0x24, 0x0c, 0x00,
- 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0xc8, 0x01, 0x04, 0x00, 0x88,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x50, 0xe8, 0x01, 0x25, 0x50, 0x49, 0x01,
- 0x04, 0x00, 0xaa, 0xac, 0x04, 0x00, 0x84, 0x24, 0x04, 0x00, 0xa5, 0x24, 0xfc,
- 0xff, 0xc6, 0x24, 0xf6, 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x89, 0x8c, 0x06, 0x40, 0xc8, 0x01, 0x04, 0x48, 0xe9, 0x01, 0x25, 0x40, 0x09,
- 0x01, 0x22, 0x48, 0x06, 0x00, 0xc0, 0x48, 0x09, 0x00, 0x04, 0x40, 0x28, 0x01,
- 0x21, 0x28, 0xa6, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x07, 0x00, 0xa8, 0xa8, 0x00,
- 0x00, 0x88, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xb8, 0x23, 0x28,
- 0xa3, 0x00, 0x23, 0x20, 0x82, 0x00, 0x21, 0x30, 0xc2, 0x00, 0xec, 0xff, 0xc6,
- 0x24, 0x0e, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c,
- 0x08, 0x00, 0x8a, 0x8c, 0x0c, 0x00, 0x8b, 0x8c, 0x10, 0x00, 0x8c, 0x8c, 0x04,
- 0x00, 0xa9, 0xac, 0x10, 0x00, 0x84, 0x24, 0x08, 0x00, 0xaa, 0xac, 0xf0, 0xff,
- 0xc6, 0x24, 0x0c, 0x00, 0xab, 0xac, 0x10, 0x00, 0xac, 0xac, 0x10, 0x00, 0xa5,
- 0x24, 0xf4, 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xc6, 0x24,
- 0x09, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x88, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0xa8, 0xac, 0x04, 0x00, 0x84, 0x24, 0x04, 0x00,
- 0xa5, 0x24, 0xfc, 0xff, 0xc6, 0x24, 0xf9, 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x20, 0x86, 0x00, 0x07, 0x00, 0x88, 0x88, 0x21, 0x28, 0xa6, 0x00,
- 0x08, 0x00, 0xe0, 0x03, 0x07, 0x00, 0xa8, 0xa8, 0x09, 0x00, 0xc0, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xa8, 0xa0, 0x01, 0x00, 0xa5, 0x24, 0x01, 0x00, 0x84, 0x24, 0xff, 0xff, 0xc6,
- 0x24, 0xf9, 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x00, 0x1e, 0x24, 0x00, 0xa0, 0x01, 0x3c, 0x10, 0x00, 0x3e, 0xac, 0x00, 0x00,
- 0x1e, 0x24, 0x00, 0x80, 0x08, 0x3c, 0xf8, 0x47, 0x08, 0x25, 0x00, 0xa0, 0x01,
- 0x3c, 0x25, 0x40, 0x01, 0x01, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x3c, 0x00,
- 0x60, 0x85, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x09, 0x3c, 0x01, 0x00, 0x01, 0x3c, 0x23, 0x40, 0x21, 0x01, 0x03, 0x00, 0x00,
- 0xa1, 0x04, 0x00, 0x08, 0x25, 0xfd, 0xff, 0x09, 0x15, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x05, 0x3c, 0x00, 0x60, 0x85, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x09, 0x3c, 0x01, 0x00, 0x01, 0x3c, 0x23, 0x40,
- 0x21, 0x01, 0x03, 0x00, 0x00, 0xa1, 0x04, 0x00, 0x08, 0x25, 0xfd, 0xff, 0x09,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x04, 0x40, 0xff, 0xff, 0x08, 0x3c, 0xff, 0x3f, 0x08, 0x35, 0x24, 0x20,
- 0x88, 0x00, 0x00, 0x10, 0x84, 0x40, 0x01, 0x80, 0x08, 0x3c, 0x30, 0xeb, 0x08,
- 0x25, 0x01, 0x80, 0x09, 0x3c, 0x84, 0x2c, 0x29, 0x25, 0xfc, 0xff, 0x01, 0x24,
- 0x24, 0x48, 0x21, 0x01, 0xfc, 0xff, 0x01, 0x24, 0x24, 0x40, 0x01, 0x01, 0x00,
- 0x00, 0x00, 0xad, 0x04, 0x00, 0x08, 0x25, 0xfd, 0xff, 0x09, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02,
- 0x40, 0xff, 0xff, 0x01, 0x3c, 0xfe, 0x00, 0x21, 0x34, 0x25, 0x20, 0x81, 0x00,
- 0x24, 0x40, 0x44, 0x00, 0x00, 0x60, 0x88, 0x40, 0x01, 0xff, 0x42, 0x30, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x26, 0x40, 0x44, 0x00, 0x01, 0xff, 0x08, 0x31, 0x26, 0x40, 0x02,
- 0x01, 0x00, 0x60, 0x88, 0x40, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x24, 0x24,
- 0x48, 0x01, 0x01, 0x00, 0x60, 0x89, 0x40, 0x00, 0x68, 0x02, 0x40, 0x00, 0x03,
- 0x84, 0x30, 0x25, 0x18, 0x44, 0x00, 0x00, 0x68, 0x83, 0x40, 0x00, 0x60, 0x88,
- 0x40, 0x24, 0x10, 0x44, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x08, 0x40, 0x00, 0x03, 0x84, 0x30, 0xfe, 0xff, 0x01, 0x24, 0x24,
- 0x48, 0x01, 0x01, 0x00, 0x60, 0x89, 0x40, 0x00, 0x68, 0x02, 0x40, 0x27, 0x18,
- 0x80, 0x00, 0x24, 0x18, 0x62, 0x00, 0x00, 0x68, 0x83, 0x40, 0x00, 0x60, 0x88,
- 0x40, 0x24, 0x10, 0x44, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x10, 0x08, 0x3c, 0x00, 0x60, 0x88, 0x40, 0xc0, 0xbf, 0x08, 0x3c, 0x08,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x09, 0x3c, 0xfe, 0x00, 0x29, 0x35, 0x00, 0x00, 0x00,
- 0x00, 0x24, 0x40, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x25, 0x40, 0x04, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x88, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10,
- 0x85, 0x00, 0x0a, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, 0x00, 0x00, 0x82,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x62, 0x00, 0x04, 0x00, 0x84, 0x24,
- 0x2b, 0x18, 0x43, 0x00, 0x21, 0x18, 0x43, 0x00, 0x2b, 0x10, 0x85, 0x00, 0xf8,
- 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10,
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x04,
- 0x00, 0x00, 0x14, 0x04, 0x00, 0x25, 0x20, 0x62, 0x00, 0x00, 0xff, 0x03, 0x3c,
- 0x00, 0xff, 0x63, 0x34, 0x24, 0x18, 0x83, 0x00, 0x02, 0x1a, 0x03, 0x00, 0xff,
- 0x00, 0x02, 0x3c, 0xff, 0x00, 0x42, 0x34, 0x24, 0x10, 0x82, 0x00, 0x00, 0x12,
- 0x02, 0x00, 0x25, 0x20, 0x62, 0x00, 0xf0, 0xf0, 0x03, 0x3c, 0xf0, 0xf0, 0x63,
- 0x34, 0x24, 0x18, 0x83, 0x00, 0x02, 0x19, 0x03, 0x00, 0x0f, 0x0f, 0x02, 0x3c,
- 0x0f, 0x0f, 0x42, 0x34, 0x24, 0x10, 0x82, 0x00, 0x00, 0x11, 0x02, 0x00, 0x25,
- 0x20, 0x62, 0x00, 0xcc, 0xcc, 0x03, 0x3c, 0xcc, 0xcc, 0x63, 0x34, 0x24, 0x18,
- 0x83, 0x00, 0x82, 0x18, 0x03, 0x00, 0x33, 0x33, 0x02, 0x3c, 0x33, 0x33, 0x42,
- 0x34, 0x24, 0x10, 0x82, 0x00, 0x80, 0x10, 0x02, 0x00, 0x25, 0x20, 0x62, 0x00,
- 0xaa, 0xaa, 0x03, 0x3c, 0xaa, 0xaa, 0x63, 0x34, 0x24, 0x18, 0x83, 0x00, 0x42,
- 0x18, 0x03, 0x00, 0x55, 0x55, 0x02, 0x3c, 0x55, 0x55, 0x42, 0x34, 0x24, 0x10,
- 0x82, 0x00, 0x40, 0x10, 0x02, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x25, 0x10, 0x62,
- 0x00, 0x00, 0xa2, 0x02, 0x3c, 0x00, 0x40, 0x42, 0x34, 0x00, 0x00, 0x42, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x43, 0x30, 0x64, 0x8c, 0x83, 0xaf, 0xf0,
- 0x8a, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x64, 0x10, 0x00, 0xc0,
- 0x02, 0x34, 0x0d, 0x00, 0x62, 0x14, 0x00, 0x40, 0x02, 0x24, 0x03, 0x00, 0x82,
- 0x10, 0x00, 0x80, 0x02, 0x34, 0x09, 0x00, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x64, 0x8c, 0x82, 0x8f, 0xf0, 0x8a, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x26,
- 0x10, 0x43, 0x00, 0x64, 0x8c, 0x82, 0xaf, 0xf0, 0x8a, 0x80, 0xaf, 0xe4, 0x12,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8a, 0x83, 0x8f, 0x00, 0xc0, 0x02,
- 0x34, 0x07, 0x00, 0x62, 0x14, 0x00, 0x40, 0x02, 0x24, 0x64, 0x8c, 0x83, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x62, 0x10, 0x00, 0x80, 0x02, 0x34, 0x1e,
- 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8c, 0x83, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x8a, 0x83, 0xaf, 0x00, 0xc0, 0x02, 0x34, 0x09, 0x00, 0x62,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0xf4, 0x8a, 0x83, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x32, 0x00, 0x42, 0x2c, 0x02,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8c, 0x80, 0xaf, 0xbc, 0x8b,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x8a, 0x82, 0xaf, 0xe4, 0x12, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0xf4, 0x8a, 0x83, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0xe8, 0x03, 0x42, 0x2c, 0x04,
- 0x00, 0x40, 0x14, 0xfa, 0x00, 0x62, 0x24, 0xf4, 0x8a, 0x82, 0xaf, 0xe4, 0x12,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8c, 0x80, 0xaf, 0x08, 0x00, 0xe0,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0x80, 0x8c, 0x88, 0x27,
- 0xb0, 0x8d, 0x86, 0x27, 0x70, 0x8c, 0x85, 0x8f, 0x00, 0xa0, 0x04, 0x3c, 0xff,
- 0xff, 0xa5, 0x24, 0x28, 0x00, 0xa0, 0x04, 0x00, 0x10, 0x84, 0x34, 0x67, 0x00,
- 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0x83, 0x94, 0x00, 0x00, 0xc2, 0x94, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe7, 0x24, 0x67,
- 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x10, 0x02, 0x00, 0x67, 0x00,
- 0x82, 0xa0, 0x0c, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2,
- 0xa4, 0x66, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x83, 0x94, 0x00, 0x00, 0x02, 0x95, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0xe7, 0x24, 0x66, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x10, 0x02,
- 0x00, 0x66, 0x00, 0x82, 0xa0, 0x12, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0xa5, 0x02, 0x00, 0x08, 0x25, 0x02, 0x00, 0xc6, 0x24, 0xff,
- 0xff, 0xa5, 0x24, 0xda, 0xff, 0xa1, 0x04, 0x80, 0x00, 0x84, 0x24, 0x08, 0x00,
- 0xe0, 0x03, 0x21, 0x10, 0xe0, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf,
- 0xaf, 0xe6, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8a, 0x83, 0x97,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x21, 0x18, 0x62, 0x00, 0xf8,
- 0x8a, 0x83, 0xa7, 0x00, 0x1c, 0x03, 0x00, 0x03, 0x1c, 0x03, 0x00, 0x19, 0x00,
- 0x63, 0x28, 0x12, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0x82,
- 0x97, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0xfa, 0x8a, 0x82, 0xa7,
- 0xff, 0x03, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0x01, 0x00, 0x02, 0x24, 0xfa,
- 0x8a, 0x82, 0xa7, 0xf8, 0x8a, 0x82, 0x87, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00,
- 0x42, 0x28, 0x04, 0x00, 0x40, 0x10, 0x19, 0x00, 0x02, 0x24, 0xf8, 0x8a, 0x82,
- 0x97, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xff, 0x42, 0x24, 0xf8, 0x8a, 0x82, 0xa7,
- 0xfa, 0x8a, 0x82, 0x87, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x01, 0x63, 0x34, 0x10,
- 0x00, 0x63, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x68, 0x8c,
- 0x82, 0xaf, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf,
- 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x90, 0x80, 0x00, 0xff, 0xff, 0x42, 0x32, 0x70, 0x8c, 0x83, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x05, 0x00, 0x40, 0x14, 0x00, 0x14, 0x12,
- 0x00, 0x40, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x4d, 0x01, 0x05, 0x24,
- 0x00, 0x14, 0x12, 0x00, 0x43, 0x12, 0x02, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0x00,
- 0x10, 0x63, 0x34, 0x21, 0x80, 0x43, 0x00, 0x54, 0x00, 0x04, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x82, 0x30, 0x02, 0x00, 0x40, 0x10, 0x21, 0x88, 0x00,
- 0x00, 0x04, 0x00, 0x11, 0x24, 0x10, 0x00, 0x82, 0x30, 0x02, 0x00, 0x40, 0x10,
- 0x01, 0x00, 0x82, 0x30, 0x08, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x40,
- 0x00, 0x82, 0x30, 0x40, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x31, 0x36, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x42, 0x30, 0x08, 0x00, 0x40, 0x10, 0x80, 0x00, 0x82, 0x30,
- 0x02, 0x00, 0x40, 0x10, 0x20, 0x00, 0x82, 0x30, 0x10, 0x00, 0x31, 0x36, 0x09,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x77, 0x13, 0x00, 0x08, 0x20, 0x00,
- 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x20, 0x00, 0x82, 0x30, 0x20, 0x00, 0x31,
- 0x36, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x31, 0x36,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0c,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x5f, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x30,
- 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x36, 0x49,
- 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x82, 0x00, 0x4a, 0x00,
- 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x31, 0x36, 0x64, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x00, 0x40, 0x10, 0x00, 0x14, 0x12, 0x00, 0x67, 0x00, 0x00, 0xa2, 0x66,
- 0x00, 0x00, 0xa2, 0xc3, 0x13, 0x02, 0x00, 0x12, 0x00, 0x03, 0x96, 0x21, 0x08,
- 0x5c, 0x00, 0x80, 0x8c, 0x23, 0xa4, 0x0c, 0x00, 0x03, 0x96, 0x21, 0x08, 0x5c,
- 0x00, 0xb0, 0x8d, 0x23, 0xa4, 0xe7, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x2c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x43, 0x30, 0x02,
- 0x00, 0x02, 0x24, 0x15, 0x00, 0x62, 0x10, 0x03, 0x00, 0x62, 0x28, 0x05, 0x00,
- 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x62, 0x10, 0x01, 0x00, 0x04,
- 0x24, 0xc8, 0x13, 0x00, 0x08, 0x00, 0x14, 0x12, 0x00, 0x03, 0x00, 0x02, 0x24,
- 0x13, 0x00, 0x62, 0x10, 0x04, 0x00, 0x02, 0x24, 0x18, 0x00, 0x62, 0x10, 0x01,
- 0x00, 0x04, 0x24, 0xc8, 0x13, 0x00, 0x08, 0x00, 0x14, 0x12, 0x00, 0x2c, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x30, 0x12, 0x00, 0x40,
- 0x10, 0x20, 0x00, 0x04, 0x24, 0xc7, 0x13, 0x00, 0x08, 0x01, 0x00, 0x04, 0x24,
- 0x2c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x30, 0x0b,
- 0x00, 0x40, 0x10, 0x10, 0x00, 0x04, 0x24, 0xc7, 0x13, 0x00, 0x08, 0x01, 0x00,
- 0x04, 0x24, 0x2c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42,
- 0x30, 0x04, 0x00, 0x40, 0x10, 0x04, 0x00, 0x04, 0x24, 0xc7, 0x13, 0x00, 0x08,
- 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x04, 0x24, 0x00, 0x14, 0x12, 0x00, 0x80,
- 0x8c, 0x83, 0x27, 0xc3, 0x13, 0x02, 0x00, 0x21, 0x28, 0x43, 0x00, 0x12, 0x00,
- 0x03, 0x96, 0x00, 0x00, 0xa2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x62,
- 0x10, 0x00, 0x14, 0x12, 0x00, 0x66, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x10, 0x44, 0x00, 0x66, 0x00, 0x02, 0xa2, 0x12, 0x00, 0x02, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa4, 0x00, 0x14, 0x12, 0x00, 0xb0, 0x8d,
- 0x83, 0x27, 0xc3, 0x13, 0x02, 0x00, 0x21, 0x28, 0x43, 0x00, 0x0c, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0xa2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x62, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25,
- 0x10, 0x44, 0x00, 0x67, 0x00, 0x02, 0xa2, 0x0c, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa4, 0x67, 0x00, 0x03, 0x92, 0x01, 0x00, 0x02,
- 0x24, 0x0d, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x68, 0x8c, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0c, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x64, 0x00, 0x04, 0x24, 0x1e, 0x00,
- 0x42, 0x2c, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x13, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x31, 0x36, 0x66,
- 0x00, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42,
- 0x30, 0x0c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x0c,
- 0x64, 0x00, 0x04, 0x24, 0x1e, 0x00, 0x42, 0x2c, 0x07, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00,
- 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x31, 0x36, 0x67, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x42, 0x10, 0x02, 0x00, 0x67, 0x00, 0x02, 0xa2, 0x66, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x10, 0x02, 0x00, 0x66, 0x00, 0x02, 0xa2, 0x68, 0x8c,
- 0x91, 0xaf, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27,
- 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14,
- 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x90, 0x80, 0x00, 0xff, 0xff,
- 0x42, 0x32, 0x70, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43,
- 0x00, 0x05, 0x00, 0x40, 0x14, 0x00, 0x14, 0x12, 0x00, 0x40, 0x89, 0x84, 0x27,
- 0x24, 0x0c, 0x00, 0x0c, 0xc7, 0x01, 0x05, 0x24, 0x00, 0x14, 0x12, 0x00, 0x43,
- 0x12, 0x02, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x10, 0x63, 0x34, 0x21, 0x80,
- 0x43, 0x00, 0x24, 0x00, 0x04, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x82,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x30, 0x2c, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x21,
- 0x88, 0x00, 0x00, 0x04, 0x00, 0x11, 0x24, 0x10, 0x00, 0x62, 0x30, 0x02, 0x00,
- 0x40, 0x10, 0x20, 0x00, 0x62, 0x30, 0x08, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40,
- 0x10, 0x40, 0x00, 0x62, 0x30, 0x20, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40, 0x10,
- 0x02, 0x00, 0x62, 0x30, 0x80, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x31, 0x36, 0x70, 0x00, 0x82, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x2c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x30,
- 0x03, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0x14, 0x00, 0x08, 0x00,
- 0x02, 0x31, 0x36, 0x00, 0x01, 0x31, 0x36, 0x64, 0x8c, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0x40, 0x10, 0x00, 0x14, 0x12, 0x00, 0x67, 0x00, 0x00,
- 0xa2, 0x66, 0x00, 0x00, 0xa2, 0xc3, 0x13, 0x02, 0x00, 0x12, 0x00, 0x03, 0x96,
- 0x21, 0x08, 0x5c, 0x00, 0x80, 0x8c, 0x23, 0xa4, 0x0c, 0x00, 0x03, 0x96, 0x21,
- 0x08, 0x5c, 0x00, 0xb0, 0x8d, 0x23, 0xa4, 0x87, 0x14, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x8c, 0x83, 0x27, 0xc3, 0x13, 0x02, 0x00, 0x21, 0x20, 0x43,
- 0x00, 0x12, 0x00, 0x03, 0x96, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x62, 0x10, 0x00, 0x14, 0x12, 0x00, 0x66, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x66, 0x00, 0x02, 0xa2, 0x12, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xa4, 0x00, 0x14, 0x12,
- 0x00, 0xb0, 0x8d, 0x83, 0x27, 0xc3, 0x13, 0x02, 0x00, 0x21, 0x20, 0x43, 0x00,
- 0x0c, 0x00, 0x03, 0x96, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x02, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x67, 0x00, 0x02, 0xa2, 0x0c, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xa4, 0x67, 0x00, 0x03, 0x92,
- 0x01, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x68,
- 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0c, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x64, 0x00, 0x04,
- 0x24, 0x1e, 0x00, 0x42, 0x2c, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x9c, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x31, 0x36, 0x66, 0x00, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x62,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x68, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x42, 0x30, 0x0c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x21, 0x00, 0x0c, 0x64, 0x00, 0x04, 0x24, 0x1e, 0x00, 0x42, 0x2c, 0x07, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x66, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10,
- 0x42, 0x10, 0x02, 0x00, 0x02, 0x00, 0x31, 0x36, 0x66, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x10, 0x02, 0x00, 0x66, 0x00, 0x02, 0xa2, 0x67, 0x00,
- 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x42, 0x10, 0x02, 0x00, 0x67, 0x00, 0x02,
- 0xa2, 0x68, 0x8c, 0x91, 0xaf, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xbf, 0xaf, 0x1c, 0x00,
- 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0xb8, 0x8e, 0x84, 0x8f, 0x37, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x10, 0x3c, 0x20, 0xf9, 0x10, 0x26,
- 0x99, 0x2a, 0x00, 0x0c, 0x14, 0x00, 0x04, 0x24, 0xa4, 0x12, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x64, 0x8c, 0x83, 0x8f, 0x00, 0x80, 0x02, 0x34, 0x99, 0x00,
- 0x62, 0x10, 0x2a, 0x10, 0x43, 0x00, 0x06, 0x00, 0x40, 0x14, 0x00, 0xc0, 0x02,
- 0x34, 0x00, 0x40, 0x02, 0x24, 0x6e, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x90, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x62, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x60, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
- 0x62, 0x2c, 0x99, 0x01, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01,
- 0x3c, 0x21, 0x08, 0x22, 0x00, 0x30, 0xd8, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x3c, 0x00,
- 0x01, 0x42, 0x34, 0x77, 0x16, 0x00, 0x08, 0x10, 0x00, 0x40, 0xac, 0x00, 0xa0,
- 0x02, 0x3c, 0x44, 0x0d, 0x42, 0x8c, 0x00, 0xa0, 0x03, 0x3c, 0x4c, 0x0d, 0x63,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0xa0, 0x03, 0x3c,
- 0x50, 0x0d, 0x63, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x18, 0x03, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x04, 0x8b, 0x82, 0xaf, 0x77, 0x16, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x77, 0x16, 0x00, 0x08, 0xc8, 0x00, 0x00, 0xae, 0xb4, 0x8e, 0x82,
- 0x97, 0x70, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00,
- 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x40, 0x89, 0x84, 0x27, 0x24,
- 0x0c, 0x00, 0x0c, 0x57, 0x02, 0x05, 0x24, 0xb4, 0x8e, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0xc0, 0x11, 0x02, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x10, 0x63,
- 0x34, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c,
- 0x21, 0x80, 0x43, 0x00, 0x21, 0x88, 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x00, 0x42, 0x30, 0x4a, 0x00, 0x02, 0xa2, 0x28, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x30, 0x05, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xef, 0x42, 0x30, 0x50, 0x00, 0x02, 0xa6, 0x54, 0x00, 0x06, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x00, 0xc3, 0x30, 0x21, 0x10, 0x60, 0x00, 0x54, 0x00,
- 0x02, 0xa2, 0x26, 0x18, 0x66, 0x00, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x25, 0x10, 0x43, 0x00, 0x58, 0x00, 0x02, 0xa2, 0x28, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x0a, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x62, 0x30, 0x05, 0x00, 0x40, 0x14, 0x00, 0x02, 0x62, 0x34, 0x50, 0x00, 0x02,
- 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xbc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x42, 0x30, 0x20,
- 0x00, 0x03, 0x24, 0x09, 0x00, 0x43, 0x14, 0x21, 0x20, 0x00, 0x02, 0x68, 0x00,
- 0x05, 0x92, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x30, 0x00, 0x0c, 0x01, 0x00, 0xa5,
- 0x38, 0x68, 0x00, 0x05, 0x92, 0x21, 0x20, 0x00, 0x02, 0x9b, 0x30, 0x00, 0x0c,
- 0x01, 0x00, 0xa5, 0x38, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x77,
- 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x60, 0x8c, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x09, 0x00, 0x40, 0x14, 0x06, 0x00, 0x42, 0x28, 0x06, 0x00, 0x02,
- 0x24, 0x60, 0x8c, 0x82, 0xaf, 0x70, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0xb4, 0x8e, 0x82, 0xaf, 0x60, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x42, 0x28, 0x05, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x8e,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x40, 0x14, 0x00, 0xa0, 0x03,
- 0x3c, 0x60, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24,
- 0x60, 0x8c, 0x82, 0xaf, 0x8d, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x63, 0x34, 0xb4, 0x8e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x42, 0x24, 0xb4, 0x8e, 0x82, 0xaf, 0xc0, 0x11, 0x02, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x50, 0x00, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x42, 0x30,
- 0xf6, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x15, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x60, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
- 0x62, 0x28, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x62, 0x24, 0x60, 0x8c, 0x82,
- 0xaf, 0xb4, 0x8e, 0x80, 0xaf, 0x8d, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0xb4, 0x8e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xb4,
- 0x8e, 0x82, 0xaf, 0x70, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10,
- 0x43, 0x00, 0x12, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x8e, 0x84,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, 0x04, 0x00, 0x00, 0xa0, 0x03, 0x3c,
- 0x00, 0x10, 0x63, 0x34, 0x21, 0x10, 0x43, 0x00, 0x50, 0x00, 0x42, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x30, 0x00, 0x42, 0x30, 0x08, 0x00, 0x40, 0x14, 0x01, 0x00,
- 0x83, 0x24, 0xb4, 0x8e, 0x83, 0xaf, 0x70, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x2a, 0x18, 0x62, 0x00, 0xf0, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x60, 0x8c, 0x80, 0xaf, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x8a, 0x82, 0xaf, 0x60, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
- 0x62, 0x2c, 0x75, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01,
- 0x3c, 0x21, 0x08, 0x22, 0x00, 0x50, 0xd8, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x13, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8c,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x8b, 0x80, 0xaf, 0x00, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x40, 0x10, 0x02, 0x00, 0x00,
- 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x44, 0x00, 0x04, 0x8d,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0xc3, 0x00, 0x02, 0x00, 0x60,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x12, 0x30, 0x00, 0x00,
- 0x21, 0x10, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x43, 0x00, 0x02,
- 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x10, 0x18,
- 0x00, 0x00, 0x00, 0x8b, 0x83, 0xaf, 0xff, 0x03, 0x02, 0x24, 0x07, 0x10, 0xc2,
- 0x00, 0x68, 0x8c, 0x82, 0xaf, 0x24, 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x80, 0x10, 0x3c, 0x20, 0xf9, 0x10, 0x26, 0x64, 0x8c, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b,
- 0x80, 0xaf, 0xb4, 0x00, 0x03, 0x8e, 0xc4, 0x00, 0x04, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x2b, 0x10, 0x64, 0x00, 0x03, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00,
- 0x21, 0x18, 0x80, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x40,
- 0x10, 0x02, 0x00, 0x00, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30,
- 0x44, 0x00, 0x94, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0xc3,
- 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00,
- 0x12, 0x30, 0x00, 0x00, 0x21, 0x10, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x07, 0x00, 0x10, 0x18, 0x00, 0x00, 0x00, 0x8b, 0x83, 0xaf, 0xff, 0x03, 0x03,
- 0x24, 0x68, 0x8c, 0x83, 0xaf, 0x0a, 0x00, 0xc2, 0x28, 0x3d, 0x00, 0x40, 0x10,
- 0x0a, 0x00, 0x02, 0x24, 0x23, 0x10, 0x46, 0x00, 0x07, 0x10, 0x43, 0x00, 0x68,
- 0x8c, 0x82, 0xaf, 0x24, 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x04, 0x3c, 0x44, 0x0d, 0x84, 0x8c, 0x00, 0xa0, 0x02, 0x3c, 0x4c, 0x0d, 0x42,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x82, 0x00, 0x00, 0xa0, 0x02, 0x3c,
- 0x50, 0x0d, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x21,
- 0x20, 0x82, 0x00, 0x04, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x16,
- 0x00, 0x08, 0x23, 0x20, 0x82, 0x00, 0xc8, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x62, 0x28, 0x02, 0x00, 0x40, 0x10, 0xff, 0x03, 0x04, 0x24,
- 0x21, 0x20, 0x60, 0x00, 0x68, 0x8c, 0x84, 0xaf, 0x7c, 0x12, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x82, 0x15, 0x02, 0x00, 0x68, 0x8c, 0x82, 0xaf, 0x24, 0x16,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x8e, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0xc0, 0x11, 0x02, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x10, 0x63, 0x34,
- 0x21, 0x10, 0x43, 0x00, 0x50, 0x00, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x30,
- 0x00, 0x43, 0x30, 0x10, 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10, 0x20, 0x00,
- 0x02, 0x24, 0x08, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x16, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x8e, 0x84, 0x87, 0x41, 0x13, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xb4,
- 0x8e, 0x84, 0x87, 0x20, 0x14, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x16,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x68, 0x8c, 0x80, 0xaf, 0x60, 0x8c, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x80, 0x02, 0x3c, 0xc8, 0xee, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x10, 0x02, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x3e, 0xda,
- 0x22, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x59, 0x16, 0x00,
- 0x08, 0x54, 0x00, 0x42, 0x24, 0x06, 0x00, 0x42, 0x28, 0x1d, 0x00, 0x40, 0x14,
- 0x66, 0x66, 0x02, 0x3c, 0xb4, 0x8e, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x63, 0x24, 0x67, 0x66, 0x42, 0x34, 0x18, 0x00, 0x62, 0x00, 0x10, 0x38,
- 0x00, 0x00, 0x83, 0x20, 0x07, 0x00, 0xc3, 0x17, 0x03, 0x00, 0x23, 0x20, 0x82,
- 0x00, 0x40, 0x10, 0x04, 0x00, 0x01, 0x80, 0x05, 0x3c, 0x21, 0x28, 0xa2, 0x00,
- 0x3c, 0xda, 0xa5, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x05, 0x00, 0x80,
- 0x10, 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, 0x40, 0x10, 0x02, 0x00, 0x23, 0x18,
- 0x62, 0x00, 0x40, 0x18, 0x03, 0x00, 0x01, 0x80, 0x02, 0x3c, 0x21, 0x10, 0x43,
- 0x00, 0x3c, 0xda, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0xa2, 0x00,
- 0x6c, 0x8c, 0x85, 0xaf, 0x5a, 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x60,
- 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x01, 0x80,
- 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x30, 0xda, 0x22, 0x94, 0x00, 0x00, 0x00,
- 0x00, 0x6c, 0x8c, 0x82, 0xaf, 0xbc, 0x8b, 0x82, 0x8f, 0xfc, 0x8a, 0x83, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0xf4, 0x01, 0x42, 0x2c, 0x05,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x8c, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x42, 0x34, 0x6c, 0x8c, 0x82, 0xaf, 0xbc, 0x8b, 0x83,
- 0x8f, 0xfc, 0x8a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x62, 0x00,
- 0xe8, 0x03, 0x42, 0x2c, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x8a, 0x83, 0xaf, 0x00, 0xa2, 0x03, 0x3c, 0x00, 0x40, 0x63, 0x34, 0x68, 0x8c,
- 0x82, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xa4, 0x00, 0xa2, 0x03,
- 0x3c, 0x04, 0x40, 0x63, 0x34, 0x6c, 0x8c, 0x82, 0x97, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x62, 0xa4, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe8, 0xff,
- 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x00, 0xa2, 0x02, 0x3c, 0x00, 0x40, 0x42,
- 0x34, 0x00, 0x00, 0x40, 0xa4, 0x00, 0xa2, 0x03, 0x3c, 0x04, 0x40, 0x63, 0x34,
- 0xff, 0xff, 0x02, 0x34, 0x00, 0x00, 0x62, 0xa4, 0x01, 0x00, 0x02, 0x24, 0x60,
- 0x8c, 0x82, 0xaf, 0x10, 0x8d, 0x84, 0x27, 0x00, 0x80, 0x06, 0x3c, 0x00, 0x53,
- 0xc6, 0x24, 0x01, 0x80, 0x07, 0x3c, 0x20, 0xf9, 0xe7, 0x24, 0x1e, 0x2a, 0x00,
- 0x0c, 0x01, 0x00, 0x05, 0x24, 0x10, 0x8d, 0x84, 0x27, 0x39, 0x2a, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x42, 0x30, 0x0f, 0x00, 0x40, 0x10, 0x21, 0x18, 0xa0, 0x00,
- 0x48, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x42, 0x24, 0x00,
- 0x00, 0xa2, 0xa0, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0xa2, 0xa0, 0x0e, 0x00,
- 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xa2, 0xa0, 0x0e, 0x00, 0x82,
- 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x02, 0x00, 0x03, 0x00, 0xa2, 0xa0,
- 0x04, 0x00, 0xa3, 0x24, 0x2e, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x42, 0x30, 0x0f, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
- 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62,
- 0xa0, 0x0e, 0x00, 0x02, 0x24, 0x01, 0x00, 0x62, 0xa0, 0x78, 0x00, 0x82, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0xa0, 0x78, 0x00, 0x82, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x12, 0x02, 0x00, 0x03, 0x00, 0x62, 0xa0, 0x04, 0x00,
- 0x63, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x23, 0x10, 0x65, 0x00, 0xe8, 0xff, 0xbd,
- 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x48, 0x00, 0x86, 0x90, 0x65, 0x00, 0x83, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00,
- 0x11, 0x02, 0x00, 0x01, 0x80, 0x03, 0x3c, 0x21, 0x18, 0x62, 0x00, 0xb8, 0xfa,
- 0x63, 0x8c, 0x06, 0x00, 0x02, 0x24, 0x06, 0x00, 0x62, 0x14, 0x09, 0x00, 0xc2,
- 0x28, 0x08, 0x00, 0xc2, 0x28, 0x05, 0x00, 0x40, 0x14, 0x21, 0x10, 0x00, 0x00,
- 0xd7, 0x16, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x10, 0x21,
- 0x10, 0x00, 0x00, 0x98, 0x16, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x90, 0xfe, 0xbd, 0x27, 0x6c, 0x01, 0xbf, 0xaf, 0x68, 0x01, 0xbe, 0xaf,
- 0x64, 0x01, 0xb7, 0xaf, 0x60, 0x01, 0xb6, 0xaf, 0x5c, 0x01, 0xb5, 0xaf, 0x58,
- 0x01, 0xb4, 0xaf, 0x54, 0x01, 0xb3, 0xaf, 0x50, 0x01, 0xb2, 0xaf, 0x4c, 0x01,
- 0xb1, 0xaf, 0x48, 0x01, 0xb0, 0xaf, 0x10, 0x01, 0xa5, 0xaf, 0x10, 0x01, 0xb2,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x46, 0x02, 0x18, 0x01, 0xa6, 0xaf,
- 0xbc, 0x8b, 0x8b, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xab, 0xaf, 0xc0,
- 0x8e, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x40, 0x10, 0x21, 0xa8,
- 0x00, 0x00, 0xf4, 0x00, 0x02, 0x24, 0x00, 0x00, 0x42, 0xa2, 0xb3, 0x00, 0x02,
- 0x24, 0x10, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0xa1,
- 0xc3, 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0xa1, 0x95, 0x00, 0x02, 0x24, 0x03,
- 0x00, 0x62, 0xa1, 0xc0, 0x8e, 0x84, 0x27, 0x04, 0x00, 0x65, 0x25, 0x70, 0x11,
- 0x00, 0x0c, 0x0a, 0x00, 0x06, 0x24, 0x10, 0x01, 0xab, 0x8f, 0xc0, 0x8e, 0x83,
- 0x93, 0x01, 0x00, 0x02, 0x24, 0x11, 0x00, 0x62, 0x14, 0x0e, 0x00, 0x72, 0x25,
- 0x01, 0x80, 0x04, 0x3c, 0x14, 0xef, 0x84, 0x8c, 0xff, 0x1f, 0x02, 0x3c, 0xff,
- 0xff, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0x00, 0xa0, 0x02, 0x3c, 0x25, 0x20,
- 0x82, 0x00, 0x01, 0x80, 0x06, 0x3c, 0x18, 0xef, 0xc6, 0x94, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x11, 0x00, 0x0c, 0x21, 0x28, 0x40, 0x02, 0x01, 0x80, 0x02, 0x3c,
- 0x18, 0xef, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x42, 0x02, 0xc0,
- 0x8e, 0x80, 0xa3, 0x18, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10,
- 0x4b, 0x02, 0x7b, 0x01, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xa0,
- 0xaf, 0x21, 0xb0, 0x00, 0x00, 0x10, 0x00, 0xbe, 0x27, 0x21, 0x88, 0x00, 0x00,
- 0x01, 0x80, 0x14, 0x3c, 0x90, 0xfa, 0x94, 0x26, 0x00, 0x00, 0x90, 0x8e, 0x24,
- 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x40, 0x10, 0x21, 0x98,
- 0x00, 0x00, 0xf0, 0xff, 0x37, 0x26, 0x12, 0x00, 0x03, 0x96, 0x14, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x62, 0x00, 0x16, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x28, 0x62, 0x00, 0x20, 0x00, 0x82, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x10, 0x62, 0x02, 0x50, 0x89, 0x83, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x10, 0x43, 0x00, 0x11, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x54, 0x89, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0xa4, 0x00,
- 0x0c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x96, 0x54,
- 0x89, 0x83, 0x97, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x16, 0x00,
- 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x12, 0x00, 0x02,
- 0xa6, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x28, 0x44, 0x00,
- 0x1e, 0x00, 0x04, 0x96, 0x7c, 0x00, 0x02, 0x96, 0x7e, 0x00, 0x03, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0xff, 0xff, 0x42, 0x30, 0x23, 0x20,
- 0x82, 0x00, 0x2b, 0x10, 0x85, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x28, 0x80, 0x00, 0x13, 0x00, 0xa0, 0x10, 0x09, 0x00, 0xa2, 0x2c,
- 0x05, 0x00, 0x40, 0x14, 0x01, 0x00, 0xa2, 0x24, 0x00, 0x01, 0xa2, 0x2c, 0x02,
- 0x00, 0x40, 0x14, 0x02, 0x00, 0xa2, 0x24, 0x03, 0x00, 0xa2, 0x24, 0x21, 0x28,
- 0x40, 0x00, 0x00, 0x16, 0x11, 0x00, 0x00, 0x1c, 0x13, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x21, 0x10, 0x45, 0x00, 0x00, 0x00, 0xc2, 0xaf, 0x04, 0x00, 0xde, 0x27,
- 0x01, 0x00, 0xd6, 0x26, 0x28, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x58, 0x65, 0x01, 0x28, 0x01, 0xab, 0xaf, 0x2e, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xb1,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xa2, 0x01, 0x00, 0x52, 0x26,
- 0x21, 0xa8, 0x20, 0x02, 0x08, 0x00, 0x82, 0x8e, 0x21, 0x20, 0x00, 0x02, 0x09,
- 0xf8, 0x40, 0x00, 0x21, 0x28, 0x40, 0x02, 0x21, 0x90, 0x42, 0x02, 0x2e, 0x00,
- 0x00, 0xa6, 0x18, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x4b,
- 0x02, 0x1d, 0x01, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x03, 0x92,
- 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x21,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xb1, 0x12, 0xc0, 0x00,
- 0x62, 0x26, 0x00, 0x00, 0x57, 0xa2, 0x01, 0x00, 0x52, 0x26, 0x21, 0xa8, 0x20,
- 0x02, 0x00, 0x00, 0x42, 0xa2, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x43, 0xa2, 0x4f, 0x00, 0x00, 0xa2, 0x57, 0x00, 0x04, 0x92, 0x58, 0x00,
- 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x64, 0x00, 0x57, 0x00, 0x03,
- 0xa2, 0x02, 0x00, 0x43, 0xa2, 0x54, 0x00, 0x03, 0x92, 0x57, 0x00, 0x04, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x64, 0x00, 0x58, 0x00, 0x03, 0xa2, 0x37,
- 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x00, 0x03, 0x00, 0x52, 0x26, 0x18, 0x01,
- 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x4b, 0x02, 0xf7, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0x96, 0x0c, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x28, 0xa2, 0x00, 0x0e, 0x00, 0x02, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x28, 0xa2, 0x00, 0x0d, 0x00, 0xa0, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0x00, 0x03, 0x96, 0x7a, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x1d, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xe5, 0x17, 0x00, 0x08, 0x01, 0x00, 0x73, 0x26, 0x78, 0x00,
- 0x02, 0x96, 0x7a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43,
- 0x00, 0x00, 0x14, 0x02, 0x00, 0x03, 0x14, 0x02, 0x00, 0x23, 0x10, 0x45, 0x00,
- 0x16, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x82, 0x18, 0x03, 0x00, 0x2b,
- 0x10, 0x43, 0x00, 0x0e, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
- 0x03, 0x96, 0x7a, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x62,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x02, 0x96, 0x20, 0x01, 0xab, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x62, 0x01, 0xff, 0xff, 0x42, 0x30, 0xd0,
- 0x07, 0x42, 0x2c, 0x17, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01,
- 0xab, 0x97, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xb1, 0x12, 0x72, 0x00, 0x0b,
- 0xa6, 0x00, 0x00, 0x57, 0xa2, 0x01, 0x00, 0x52, 0x26, 0x21, 0xa8, 0x20, 0x02,
- 0x78, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x28, 0x45, 0x00, 0x7a,
- 0x00, 0x05, 0xa6, 0xa0, 0x00, 0x62, 0x26, 0x00, 0x00, 0x42, 0xa2, 0x01, 0x00,
- 0x45, 0xa2, 0x02, 0x12, 0x05, 0x00, 0x02, 0x00, 0x42, 0xa2, 0x03, 0x00, 0x52,
- 0x26, 0x18, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x4b, 0x02,
- 0xb2, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x73, 0x26, 0x24,
- 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x62, 0x02, 0x3e, 0xff,
- 0x40, 0x14, 0x80, 0x00, 0x10, 0x26, 0x01, 0x00, 0x31, 0x26, 0x04, 0x00, 0x22,
- 0x2a, 0x34, 0xff, 0x40, 0x14, 0x30, 0x00, 0x94, 0x26, 0xa6, 0x00, 0xc0, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x50, 0x72, 0x01, 0x28, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10,
- 0x4b, 0x01, 0x03, 0x00, 0x40, 0x14, 0x21, 0x38, 0x40, 0x01, 0x20, 0x18, 0x00,
- 0x08, 0x21, 0xa0, 0x40, 0x01, 0x21, 0x20, 0xc0, 0x02, 0x21, 0x40, 0x00, 0x00,
- 0x1a, 0x00, 0xe4, 0x00, 0x02, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0x81, 0x14, 0x00, 0x80,
- 0x01, 0x3c, 0x02, 0x00, 0xe1, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06,
- 0x00, 0x12, 0xa0, 0x00, 0x00, 0x21, 0x48, 0x80, 0x00, 0x21, 0x38, 0x40, 0x01,
- 0x21, 0x20, 0xc0, 0x02, 0x10, 0x00, 0xa6, 0x27, 0x0c, 0x00, 0xc0, 0x1a, 0x21,
- 0x28, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10,
- 0x83, 0x02, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x23, 0x38, 0xe3,
- 0x00, 0xff, 0xff, 0x84, 0x24, 0x01, 0x00, 0xa5, 0x24, 0x2a, 0x10, 0xb6, 0x00,
- 0xf6, 0xff, 0x40, 0x14, 0x04, 0x00, 0xc6, 0x24, 0x08, 0x00, 0x80, 0x10, 0x02,
- 0x00, 0x82, 0x2a, 0x06, 0x00, 0x89, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x08, 0x25, 0x04, 0x00, 0x02, 0x29, 0xdd, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x82, 0x2a, 0x09, 0x00, 0x40, 0x10, 0x40, 0x18, 0x16, 0x00,
- 0x10, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x4b, 0x02, 0x21,
- 0x10, 0x43, 0x00, 0x2c, 0x01, 0x42, 0x28, 0x6f, 0x00, 0x40, 0x10, 0x23, 0x10,
- 0x4b, 0x02, 0x02, 0x00, 0x14, 0x24, 0x10, 0x00, 0xbe, 0x27, 0x68, 0x00, 0xc0,
- 0x1a, 0x21, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x26, 0x10, 0x00, 0x03, 0x14, 0x10, 0x00, 0xff, 0x00, 0x45, 0x30, 0xff,
- 0xff, 0x10, 0x32, 0x40, 0x10, 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, 0x00, 0x11,
- 0x02, 0x00, 0xc0, 0x19, 0x05, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22,
- 0x00, 0x90, 0xfa, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa4, 0x12,
- 0x21, 0x98, 0x62, 0x00, 0xf0, 0xff, 0x82, 0x24, 0x00, 0x00, 0x42, 0xa2, 0x01,
- 0x00, 0x52, 0x26, 0x21, 0xa8, 0x80, 0x00, 0x2a, 0x10, 0x90, 0x02, 0x03, 0x00,
- 0x40, 0x10, 0x0a, 0x00, 0x02, 0x2a, 0x21, 0x80, 0x80, 0x02, 0x0a, 0x00, 0x02,
- 0x2a, 0x08, 0x00, 0x40, 0x10, 0x02, 0x01, 0x02, 0x2a, 0xff, 0xff, 0x10, 0x26,
- 0xff, 0xff, 0x02, 0x26, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x45, 0x00, 0x00,
- 0x00, 0x42, 0xa2, 0x5e, 0x18, 0x00, 0x08, 0x01, 0x00, 0x52, 0x26, 0x06, 0x00,
- 0x40, 0x10, 0x80, 0xff, 0xa2, 0x24, 0xfe, 0xff, 0x10, 0x26, 0x00, 0x00, 0x42,
- 0xa2, 0x01, 0x00, 0x50, 0xa2, 0x5e, 0x18, 0x00, 0x08, 0x02, 0x00, 0x52, 0x26,
- 0xfd, 0xff, 0x10, 0x26, 0x90, 0xff, 0xa2, 0x24, 0x00, 0x00, 0x42, 0xa2, 0x01,
- 0x00, 0x50, 0xa2, 0x03, 0x12, 0x10, 0x00, 0x02, 0x00, 0x42, 0xa2, 0x03, 0x00,
- 0x52, 0x26, 0x7c, 0x00, 0x62, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x50,
- 0x00, 0x7c, 0x00, 0x62, 0xa6, 0x16, 0x00, 0x63, 0x96, 0x14, 0x00, 0x65, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x24, 0x23, 0x88, 0x62, 0x00, 0x2a,
- 0x10, 0x11, 0x02, 0x0a, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
- 0x64, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0xa4, 0x00, 0x21, 0x28, 0x40,
- 0x02, 0x70, 0x11, 0x00, 0x0c, 0x21, 0x30, 0x20, 0x02, 0x21, 0x90, 0x51, 0x02,
- 0x23, 0x80, 0x11, 0x02, 0x14, 0x00, 0x60, 0xa6, 0x14, 0x00, 0x62, 0x96, 0x38,
- 0x00, 0x64, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x44, 0x00, 0x21, 0x28,
- 0x40, 0x02, 0x70, 0x11, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x02, 0x14, 0x00, 0x62,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x50, 0x00, 0x14, 0x00, 0x62, 0xa6,
- 0x50, 0x00, 0x62, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0f,
- 0x00, 0x40, 0x10, 0x21, 0x90, 0x50, 0x02, 0x12, 0x00, 0x62, 0x96, 0x14, 0x00,
- 0x63, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x63,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x63, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x03, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xc6, 0x2c, 0x00, 0x0c, 0x21, 0x20, 0x60, 0x02, 0x01, 0x00,
- 0xf7, 0x26, 0x2a, 0x10, 0xf6, 0x02, 0x9a, 0xff, 0x40, 0x14, 0x04, 0x00, 0xde,
- 0x27, 0x10, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x4b, 0x02,
- 0x6c, 0x01, 0xbf, 0x8f, 0x68, 0x01, 0xbe, 0x8f, 0x64, 0x01, 0xb7, 0x8f, 0x60,
- 0x01, 0xb6, 0x8f, 0x5c, 0x01, 0xb5, 0x8f, 0x58, 0x01, 0xb4, 0x8f, 0x54, 0x01,
- 0xb3, 0x8f, 0x50, 0x01, 0xb2, 0x8f, 0x4c, 0x01, 0xb1, 0x8f, 0x48, 0x01, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x70, 0x01, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27,
- 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10,
- 0x00, 0xb0, 0xaf, 0x03, 0x00, 0xb1, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
- 0x11, 0x00, 0x02, 0x00, 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x25, 0x88, 0x22,
- 0x02, 0x01, 0x00, 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x43, 0x30,
- 0x0f, 0x00, 0x62, 0x2c, 0x5e, 0x01, 0x40, 0x10, 0x21, 0x80, 0x80, 0x00, 0x80,
- 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x70, 0xd8,
- 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x22, 0x32, 0x0a, 0x00, 0x40, 0x10, 0x40, 0x00, 0x22, 0x32,
- 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x90, 0x40, 0x00, 0x6b, 0x2e, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x37, 0x12,
- 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x40, 0x00, 0x22, 0x32, 0x1e, 0x00, 0x40,
- 0x10, 0x80, 0x00, 0x22, 0x32, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x34, 0x4a, 0x00, 0x02, 0xa2, 0x28, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x30, 0x05, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x42, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x54, 0x00, 0x04, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x83, 0x34, 0x54, 0x00, 0x03, 0xa2, 0x26, 0x18,
- 0x64, 0x00, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43,
- 0x00, 0x58, 0x00, 0x02, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02,
- 0x80, 0x00, 0x22, 0x32, 0x1e, 0x00, 0x40, 0x10, 0x10, 0x00, 0x22, 0x32, 0xc0,
- 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90,
- 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x42,
- 0x30, 0x4a, 0x00, 0x02, 0xa2, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0x42, 0x30, 0x50, 0x00,
- 0x02, 0xa6, 0x54, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x83,
- 0x30, 0x54, 0x00, 0x03, 0xa2, 0x26, 0x18, 0x64, 0x00, 0x58, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x58, 0x00, 0x02, 0xa2, 0x37,
- 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x10, 0x00, 0x22, 0x32, 0x10, 0x00,
- 0x40, 0x10, 0x20, 0x00, 0x22, 0x32, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x40, 0x14, 0x20, 0x00,
- 0x22, 0x32, 0x8f, 0x2c, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x20, 0x00, 0x22,
- 0x32, 0x10, 0x00, 0x40, 0x10, 0x00, 0x02, 0x22, 0x32, 0x12, 0x00, 0x03, 0x96,
- 0x14, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x62, 0x00, 0x16,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x62, 0x00, 0x1c, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x40,
- 0x14, 0x00, 0x02, 0x22, 0x32, 0xc6, 0x2c, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0x00, 0x02, 0x22, 0x32, 0x1f, 0x00, 0x40, 0x10, 0x00, 0x04, 0x22, 0x32, 0xc0,
- 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90,
- 0x40, 0x00, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x10, 0x43, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x2c,
- 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x42, 0x34, 0x50,
- 0x00, 0x02, 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x00, 0x04,
- 0x22, 0x32, 0x1f, 0x00, 0x40, 0x10, 0x02, 0x00, 0x22, 0x32, 0xc0, 0x8b, 0x84,
- 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00,
- 0x12, 0x00, 0x03, 0x96, 0x14, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x18, 0x62, 0x00, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18,
- 0x62, 0x00, 0x1c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43,
- 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x2c, 0x00, 0x0c,
- 0x21, 0x20, 0x00, 0x02, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x42, 0x34, 0x50, 0x00, 0x02,
- 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x02, 0x00, 0x22, 0x32,
- 0xad, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x4f, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x34, 0x15, 0x1a, 0x00, 0x08, 0x4f, 0x00,
- 0x02, 0xa2, 0x1e, 0x00, 0x11, 0xa6, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x91, 0x19, 0x00, 0x08, 0x2a, 0x10, 0x43, 0x00, 0x16, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x18, 0x00, 0x51,
- 0x00, 0x12, 0x30, 0x00, 0x00, 0xc2, 0x13, 0x06, 0x00, 0x1a, 0x00, 0x02, 0xa6,
- 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10,
- 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43,
- 0x00, 0x89, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x50, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x84, 0x00, 0x40, 0x10, 0x01,
- 0x00, 0x02, 0x24, 0xc6, 0x2c, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x16, 0x1a,
- 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x18, 0x00, 0x51, 0x00, 0x12, 0x30, 0x00, 0x00,
- 0xc2, 0x13, 0x06, 0x00, 0x1c, 0x00, 0x02, 0xa6, 0x12, 0x00, 0x03, 0x96, 0x14,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x62, 0x00, 0x16, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x62, 0x00, 0x1c, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x6d, 0x00, 0x40, 0x10,
- 0x01, 0x00, 0x02, 0x24, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x30, 0x68, 0x00, 0x40, 0x14, 0x01, 0x00, 0x02, 0x24, 0x8f, 0x2c,
- 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x16, 0x1a, 0x00, 0x08, 0x01, 0x00, 0x02,
- 0x24, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x90, 0x40, 0x00, 0x78, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x10, 0x51, 0x00, 0xff, 0xff, 0x42, 0x30, 0x0a, 0x00, 0x03, 0x96, 0x0c, 0x00,
- 0x04, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x64, 0x00, 0x0e, 0x00, 0x04,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x64, 0x00, 0x2b, 0x10, 0x43, 0x00,
- 0x33, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x10, 0x51, 0x00, 0x78, 0x00, 0x03, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x0e, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x24, 0x10, 0x43, 0x00, 0xf7, 0x19, 0x00, 0x08, 0x0c, 0x00, 0x02, 0xa6,
- 0x21, 0x20, 0x00, 0x02, 0xfd, 0x2c, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x16,
- 0x1a, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0x64, 0x2d,
- 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x16, 0x1a, 0x00, 0x08, 0x01, 0x00, 0x02,
- 0x24, 0x21, 0x20, 0x00, 0x02, 0x9d, 0x2d, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02,
- 0x16, 0x1a, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0xf8,
- 0x2d, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x16, 0x1a, 0x00, 0x08, 0x01, 0x00,
- 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0x32, 0x2e, 0x00, 0x0c, 0x21, 0x28, 0x20,
- 0x02, 0x16, 0x1a, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0xc0, 0x8b, 0x84, 0x8f,
- 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x50,
- 0x00, 0x04, 0x96, 0x21, 0x10, 0x20, 0x02, 0x5e, 0x00, 0x02, 0xa2, 0xff, 0x00,
- 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0xff, 0xd7, 0x02, 0x24, 0xf6, 0x19, 0x00,
- 0x08, 0x00, 0x20, 0x84, 0x34, 0x24, 0x20, 0x82, 0x00, 0x50, 0x00, 0x04, 0xa6,
- 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x16, 0x1a, 0x00, 0x08, 0x01,
- 0x00, 0x02, 0x24, 0x5c, 0x00, 0x11, 0xa2, 0x02, 0x12, 0x11, 0x00, 0x15, 0x1a,
- 0x00, 0x08, 0x5d, 0x00, 0x02, 0xa2, 0x78, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x78, 0x00, 0x02, 0xa6, 0x21, 0x20, 0x00, 0x02,
- 0xc9, 0x2d, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x16, 0x1a, 0x00, 0x08, 0x01,
- 0x00, 0x02, 0x24, 0x5a, 0x00, 0x11, 0xa2, 0x02, 0x12, 0x11, 0x00, 0x15, 0x1a,
- 0x00, 0x08, 0x5b, 0x00, 0x02, 0xa2, 0x7c, 0x00, 0x03, 0x96, 0x7e, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x03, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x16, 0x1a, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00, 0x7c,
- 0x00, 0x11, 0xa6, 0x01, 0x00, 0x02, 0x24, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00,
- 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf,
- 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0x48, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x42, 0x2c, 0x05, 0x00, 0x40, 0x10, 0x08, 0x00, 0x02, 0x24, 0xa4, 0x18, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x1b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x48, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x62, 0x14, 0x21,
- 0x10, 0x00, 0x00, 0x65, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10,
- 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00, 0x01, 0x80, 0x03,
- 0x3c, 0x21, 0x18, 0x62, 0x00, 0xb8, 0xfa, 0x63, 0x8c, 0x06, 0x00, 0x02, 0x24,
- 0x6d, 0x01, 0x62, 0x10, 0x21, 0x10, 0x00, 0x00, 0x03, 0x00, 0xb1, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x8a, 0x11, 0x00, 0x02, 0x00, 0xa2, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x88, 0x22, 0x02, 0x01, 0x00, 0xa2, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x1f, 0x00, 0x43, 0x30, 0x0f, 0x00, 0x62, 0x2c, 0x5d, 0x01, 0x40, 0x10,
- 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0xb0,
- 0xd8, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x22, 0x32, 0x0a, 0x00, 0x40, 0x10, 0x40, 0x00, 0x22,
- 0x32, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x90, 0x40, 0x00, 0xac, 0x30, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x37,
- 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x40, 0x00, 0x22, 0x32, 0x1e, 0x00,
- 0x40, 0x10, 0x80, 0x00, 0x22, 0x32, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x34, 0x4a, 0x00, 0x02, 0xa2, 0x28,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x30, 0x05, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x42, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x54, 0x00, 0x04, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x83, 0x34, 0x54, 0x00, 0x03, 0xa2, 0x26,
- 0x18, 0x64, 0x00, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10,
- 0x43, 0x00, 0x58, 0x00, 0x02, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40,
- 0x02, 0x80, 0x00, 0x22, 0x32, 0x1e, 0x00, 0x40, 0x10, 0x10, 0x00, 0x22, 0x32,
- 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x90, 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00,
- 0x42, 0x30, 0x4a, 0x00, 0x02, 0xa2, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0x42, 0x30, 0x50,
- 0x00, 0x02, 0xa6, 0x54, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x00,
- 0x83, 0x30, 0x54, 0x00, 0x03, 0xa2, 0x26, 0x18, 0x64, 0x00, 0x58, 0x00, 0x02,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x58, 0x00, 0x02, 0xa2,
- 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x10, 0x00, 0x22, 0x32, 0x10,
- 0x00, 0x40, 0x10, 0x20, 0x00, 0x22, 0x32, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00,
- 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x40, 0x14, 0x20,
- 0x00, 0x22, 0x32, 0x5a, 0x2f, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x20, 0x00,
- 0x22, 0x32, 0x10, 0x00, 0x40, 0x10, 0x00, 0x02, 0x22, 0x32, 0x12, 0x00, 0x03,
- 0x96, 0x14, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x62, 0x00,
- 0x16, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x62, 0x00, 0x1c,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x04, 0x00,
- 0x40, 0x14, 0x00, 0x02, 0x22, 0x32, 0x80, 0x2f, 0x00, 0x0c, 0x21, 0x20, 0x00,
- 0x02, 0x00, 0x02, 0x22, 0x32, 0x1f, 0x00, 0x40, 0x10, 0x00, 0x04, 0x22, 0x32,
- 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x90, 0x40, 0x00, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0x10, 0x43, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x5a,
- 0x2f, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x42, 0x34,
- 0x50, 0x00, 0x02, 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x00,
- 0x04, 0x22, 0x32, 0x1f, 0x00, 0x40, 0x10, 0x02, 0x00, 0x22, 0x32, 0xc0, 0x8b,
- 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40,
- 0x00, 0x12, 0x00, 0x03, 0x96, 0x14, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x18, 0x62, 0x00, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24,
- 0x18, 0x62, 0x00, 0x1c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10,
- 0x43, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2f, 0x00,
- 0x0c, 0x21, 0x20, 0x00, 0x02, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x42, 0x34, 0x50, 0x00,
- 0x02, 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x02, 0x00, 0x22,
- 0x32, 0xad, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x4f, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x34, 0xa5, 0x1b, 0x00, 0x08, 0x4f,
- 0x00, 0x02, 0xa2, 0x1e, 0x00, 0x11, 0xa6, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00,
- 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x1b, 0x00, 0x08, 0x2a, 0x10, 0x43, 0x00, 0x16,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x18, 0x00,
- 0x51, 0x00, 0x12, 0x30, 0x00, 0x00, 0xc2, 0x13, 0x06, 0x00, 0x1a, 0x00, 0x02,
- 0xa6, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24,
- 0x10, 0x43, 0x00, 0x1a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10,
- 0x43, 0x00, 0x89, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x50, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x84, 0x00, 0x40, 0x10,
- 0x01, 0x00, 0x02, 0x24, 0x80, 0x2f, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xa6,
- 0x1b, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x18, 0x00, 0x51, 0x00, 0x12, 0x30, 0x00,
- 0x00, 0xc2, 0x13, 0x06, 0x00, 0x1c, 0x00, 0x02, 0xa6, 0x12, 0x00, 0x03, 0x96,
- 0x14, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x62, 0x00, 0x16,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x62, 0x00, 0x1c, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x6d, 0x00, 0x40,
- 0x10, 0x01, 0x00, 0x02, 0x24, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x30, 0x68, 0x00, 0x40, 0x14, 0x01, 0x00, 0x02, 0x24, 0x5a,
- 0x2f, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xa6, 0x1b, 0x00, 0x08, 0x01, 0x00,
- 0x02, 0x24, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x90, 0x40, 0x00, 0x78, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x10, 0x51, 0x00, 0xff, 0xff, 0x42, 0x30, 0x0a, 0x00, 0x03, 0x96, 0x0c,
- 0x00, 0x04, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x64, 0x00, 0x0e, 0x00,
- 0x04, 0x96, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x64, 0x00, 0x2b, 0x10, 0x43,
- 0x00, 0x33, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x51, 0x00, 0x78, 0x00, 0x03, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x0e, 0x00, 0x03, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x87, 0x1b, 0x00, 0x08, 0x0c, 0x00, 0x02,
- 0xa6, 0x21, 0x20, 0x00, 0x02, 0x3f, 0x30, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02,
- 0xa6, 0x1b, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0x2e,
- 0x30, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0xa6, 0x1b, 0x00, 0x08, 0x01, 0x00,
- 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0x66, 0x30, 0x00, 0x0c, 0x21, 0x28, 0x20,
- 0x02, 0xa6, 0x1b, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02,
- 0x9b, 0x30, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0xa6, 0x1b, 0x00, 0x08, 0x01,
- 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0xa6, 0x2f, 0x00, 0x0c, 0x21, 0x28,
- 0x20, 0x02, 0xa6, 0x1b, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0xc0, 0x8b, 0x84,
- 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00,
- 0x50, 0x00, 0x04, 0x96, 0x21, 0x10, 0x20, 0x02, 0x5e, 0x00, 0x02, 0xa2, 0xff,
- 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0xff, 0xd7, 0x02, 0x24, 0x86, 0x1b,
- 0x00, 0x08, 0x00, 0x20, 0x84, 0x34, 0x24, 0x20, 0x82, 0x00, 0x50, 0x00, 0x04,
- 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0xa6, 0x1b, 0x00, 0x08,
- 0x01, 0x00, 0x02, 0x24, 0x5c, 0x00, 0x11, 0xa2, 0x02, 0x12, 0x11, 0x00, 0xa5,
- 0x1b, 0x00, 0x08, 0x5d, 0x00, 0x02, 0xa2, 0x78, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x78, 0x00, 0x02, 0xa6, 0x21, 0x20, 0x00,
- 0x02, 0x58, 0x2f, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0xa6, 0x1b, 0x00, 0x08,
- 0x01, 0x00, 0x02, 0x24, 0x5a, 0x00, 0x11, 0xa2, 0x02, 0x12, 0x11, 0x00, 0xa5,
- 0x1b, 0x00, 0x08, 0x5b, 0x00, 0x02, 0xa2, 0x7c, 0x00, 0x03, 0x96, 0x7e, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x03, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x1b, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00,
- 0x7c, 0x00, 0x11, 0xa6, 0x01, 0x00, 0x02, 0x24, 0x1c, 0x00, 0xbf, 0x8f, 0x18,
- 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xd0, 0xff, 0xbd, 0x27, 0x28, 0x00, 0xbf,
- 0xaf, 0x24, 0x00, 0xb5, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf,
- 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x90, 0xa0, 0x00, 0x21, 0xa8, 0x46, 0x02, 0x01, 0x80, 0x14, 0x3c, 0x90, 0xfa,
- 0x94, 0x26, 0x2b, 0x10, 0x55, 0x02, 0x0b, 0x01, 0x40, 0x10, 0x26, 0x10, 0x55,
- 0x02, 0x00, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x02, 0x19, 0x02, 0x00,
- 0x10, 0x00, 0x62, 0x2c, 0x03, 0x01, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01,
- 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0xf0, 0xd8, 0x22, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x44, 0x30, 0x00, 0x00, 0x42, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x02, 0x00, 0x01, 0x00, 0x51, 0x24, 0xe1,
- 0x1b, 0x00, 0x08, 0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x42, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x0f, 0x00, 0x44, 0x30, 0x01, 0x00, 0x51, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0xe1, 0x1b, 0x00, 0x08, 0x02, 0x00, 0x52, 0x26, 0x00, 0x00, 0x42, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x44, 0x30, 0x02, 0x00, 0x42, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x01, 0x00, 0x43, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x88, 0x43, 0x00, 0x03, 0x00, 0x52, 0x26, 0x24, 0x00, 0x82,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x82, 0x00, 0x03, 0x00, 0x40, 0x14,
- 0xc0, 0x19, 0x04, 0x00, 0xb8, 0x1b, 0x00, 0x08, 0x21, 0x90, 0x51, 0x02, 0x00,
- 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x62, 0x00, 0x0c, 0x00,
- 0x02, 0x96, 0x0a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43,
- 0x00, 0xff, 0xff, 0x42, 0x24, 0x0e, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x24, 0x10, 0x43, 0x00, 0x2a, 0x10, 0x51, 0x00, 0xd3, 0x00, 0x40, 0x14, 0x0d,
- 0x00, 0x02, 0x24, 0x78, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10,
- 0x51, 0x00, 0x78, 0x00, 0x02, 0xa6, 0x0e, 0x00, 0x03, 0x96, 0x0a, 0x00, 0x06,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x24, 0x23, 0x98, 0x62, 0x00,
- 0x2a, 0x10, 0x33, 0x02, 0x09, 0x00, 0x40, 0x14, 0x21, 0x20, 0x40, 0x02, 0x3c,
- 0x00, 0x05, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0xc5, 0x00, 0x70, 0x11,
- 0x00, 0x0c, 0x21, 0x30, 0x60, 0x02, 0x21, 0x90, 0x53, 0x02, 0x23, 0x88, 0x33,
- 0x02, 0x0a, 0x00, 0x00, 0xa6, 0x0a, 0x00, 0x02, 0x96, 0x3c, 0x00, 0x05, 0x8e,
- 0x21, 0x20, 0x40, 0x02, 0x21, 0x28, 0x45, 0x00, 0x70, 0x11, 0x00, 0x0c, 0x21,
- 0x30, 0x20, 0x02, 0x0a, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10,
- 0x51, 0x00, 0x0a, 0x00, 0x02, 0xa6, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x00, 0x42, 0x30, 0xa0, 0xff, 0x40, 0x14, 0x21, 0x90, 0x51, 0x02,
- 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x63, 0x34, 0x50, 0x00,
- 0x03, 0xa6, 0x00, 0x80, 0x03, 0x3c, 0xbc, 0x35, 0x63, 0x24, 0x04, 0x00, 0x03,
- 0xae, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x00, 0xb9, 0x1b, 0x00, 0x08,
- 0x2b, 0x10, 0x55, 0x02, 0x00, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x44, 0x30, 0x24, 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10,
- 0x82, 0x00, 0x03, 0x00, 0x40, 0x14, 0xc0, 0x19, 0x04, 0x00, 0xb8, 0x1b, 0x00,
- 0x08, 0x03, 0x00, 0x52, 0x26, 0x00, 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x80, 0x62, 0x00, 0x02, 0x00, 0x51, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x8a, 0x11, 0x00, 0x01, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x88,
- 0x22, 0x02, 0x7c, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x20, 0x51,
- 0x00, 0x7e, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0xff, 0xff, 0x84, 0x30, 0xff, 0xff, 0x42, 0x30, 0x2b, 0x10, 0x44, 0x00, 0x84,
- 0x00, 0x40, 0x14, 0x11, 0x00, 0x02, 0x24, 0x7e, 0x00, 0x11, 0xa6, 0xb8, 0x1b,
- 0x00, 0x08, 0x03, 0x00, 0x52, 0x26, 0x00, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x44, 0x30, 0x24, 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0x10, 0x82, 0x00, 0x03, 0x00, 0x40, 0x14, 0xc0, 0x11, 0x04, 0x00, 0xb8,
- 0x1b, 0x00, 0x08, 0x04, 0x00, 0x52, 0x26, 0x00, 0x00, 0x84, 0x8e, 0x0c, 0x00,
- 0x83, 0x8e, 0x21, 0x20, 0x44, 0x00, 0x09, 0xf8, 0x60, 0x00, 0x21, 0x28, 0x40,
- 0x02, 0x60, 0xff, 0x40, 0x14, 0x04, 0x00, 0x52, 0x26, 0xc8, 0x1c, 0x00, 0x08,
- 0x0b, 0x00, 0x02, 0x24, 0x00, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0xff, 0x43, 0x24, 0x10, 0x00, 0x62, 0x2c, 0x63, 0x00, 0x40, 0x10, 0x80, 0x10,
- 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x30, 0xd9, 0x22,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x40, 0x18, 0x02, 0x00, 0x21,
- 0x18, 0x62, 0x00, 0x00, 0x19, 0x03, 0x00, 0x01, 0x80, 0x02, 0x3c, 0x90, 0xcd,
- 0x42, 0x24, 0x21, 0xa0, 0x62, 0x00, 0xb8, 0x1b, 0x00, 0x08, 0x01, 0x00, 0x52,
- 0x26, 0x00, 0x00, 0x43, 0x92, 0xf4, 0x00, 0x02, 0x24, 0x54, 0x00, 0x62, 0x14,
- 0x0c, 0x00, 0x02, 0x24, 0x01, 0x00, 0x43, 0x92, 0xb3, 0x00, 0x02, 0x24, 0x50,
- 0x00, 0x62, 0x14, 0x0c, 0x00, 0x02, 0x24, 0x02, 0x00, 0x43, 0x92, 0xc3, 0x00,
- 0x02, 0x24, 0x4c, 0x00, 0x62, 0x14, 0x0c, 0x00, 0x02, 0x24, 0x03, 0x00, 0x43,
- 0x92, 0x95, 0x00, 0x02, 0x24, 0x48, 0x00, 0x62, 0x14, 0x0c, 0x00, 0x02, 0x24,
- 0x04, 0x00, 0x52, 0x26, 0x21, 0x20, 0x40, 0x02, 0xc0, 0x8e, 0x85, 0x27, 0x70,
- 0x11, 0x00, 0x0c, 0x0a, 0x00, 0x06, 0x24, 0x01, 0x80, 0x02, 0x3c, 0x18, 0xef,
- 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x42, 0x2c, 0x04, 0x00, 0x40,
- 0x14, 0x0a, 0x00, 0x52, 0x26, 0x80, 0x00, 0x02, 0x24, 0x01, 0x80, 0x01, 0x3c,
- 0x18, 0xef, 0x22, 0xa4, 0xc0, 0x8e, 0x83, 0x93, 0x02, 0x00, 0x02, 0x24, 0x0e,
- 0x00, 0x62, 0x10, 0x03, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00,
- 0x02, 0x24, 0x22, 0xff, 0x62, 0x10, 0x0c, 0x00, 0x02, 0x24, 0xc8, 0x1c, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x24, 0x13, 0x00, 0x62, 0x10,
- 0x04, 0x00, 0x02, 0x24, 0x22, 0x00, 0x62, 0x10, 0x0c, 0x00, 0x02, 0x24, 0xc8,
- 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x3c, 0x14, 0xef,
- 0x63, 0x8c, 0xff, 0x1f, 0x02, 0x3c, 0xff, 0xff, 0x42, 0x34, 0x24, 0x88, 0x62,
- 0x00, 0x00, 0x80, 0x05, 0x3c, 0x21, 0x20, 0x40, 0x02, 0x01, 0x80, 0x06, 0x3c,
- 0x18, 0xef, 0xc6, 0x94, 0x00, 0x00, 0x00, 0x00, 0x70, 0x11, 0x00, 0x0c, 0x26,
- 0x28, 0x25, 0x02, 0xba, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
- 0x02, 0x3c, 0x14, 0xef, 0x42, 0x8c, 0x01, 0x80, 0x04, 0x3c, 0x1a, 0xef, 0x84,
- 0x8c, 0x01, 0x80, 0x05, 0x3c, 0x1e, 0xef, 0xa5, 0x8c, 0x01, 0x80, 0x06, 0x3c,
- 0x22, 0xef, 0xc6, 0x8c, 0x01, 0x80, 0x07, 0x3c, 0x26, 0xef, 0xe7, 0x8c, 0x09,
- 0xf8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x3c, 0x18, 0xef,
- 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x1b, 0x00, 0x08, 0x21, 0x90, 0x42,
- 0x02, 0xbf, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x1c, 0x00, 0x08,
- 0x21, 0x10, 0x00, 0x00, 0xc8, 0x1c, 0x00, 0x08, 0x0a, 0x00, 0x02, 0x24, 0x2b,
- 0x10, 0x02, 0x00, 0x23, 0x10, 0x02, 0x00, 0x0e, 0x00, 0x42, 0x30, 0x28, 0x00,
- 0xbf, 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0x6c, 0x00, 0x80, 0xac, 0x02,
- 0x00, 0x02, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x2e, 0x00, 0x82, 0xa4, 0xe8, 0xff,
- 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x48, 0x00, 0x85, 0x90, 0x65, 0x00, 0x83,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x00, 0x11, 0x02, 0x00, 0x01, 0x80, 0x03, 0x3c, 0x21, 0x18, 0x62, 0x00, 0xb8,
- 0xfa, 0x63, 0x8c, 0x06, 0x00, 0x02, 0x24, 0x06, 0x00, 0x62, 0x14, 0x09, 0x00,
- 0xa2, 0x28, 0x08, 0x00, 0xa2, 0x28, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0xea, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0xd1, 0x1c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0xd0, 0xff, 0xbd, 0x27, 0x28, 0x00, 0xbf, 0xaf, 0x24, 0x00, 0xb3,
- 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf,
- 0x21, 0x98, 0x00, 0x00, 0x01, 0x80, 0x12, 0x3c, 0x90, 0xfa, 0x52, 0x26, 0x00,
- 0x00, 0x50, 0x8e, 0x24, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
- 0x40, 0x10, 0x21, 0x88, 0x00, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x2e, 0x12, 0x00, 0x0c, 0x01, 0x00, 0x31, 0x26, 0x0a, 0x00, 0x00, 0xa6,
- 0x0c, 0x00, 0x00, 0xa6, 0x7a, 0x00, 0x00, 0xa6, 0x78, 0x00, 0x00, 0xa6, 0x7c,
- 0x00, 0x00, 0xa6, 0x7e, 0x00, 0x00, 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20,
- 0x40, 0x00, 0x14, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x40,
- 0x00, 0x21, 0x20, 0x00, 0x02, 0x24, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0x10, 0x22, 0x02, 0xec, 0xff, 0x40, 0x14, 0x80, 0x00, 0x10, 0x26, 0x01,
- 0x00, 0x73, 0x26, 0x04, 0x00, 0x62, 0x2a, 0xe3, 0xff, 0x40, 0x14, 0x30, 0x00,
- 0x52, 0x26, 0x28, 0x00, 0xbf, 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2,
- 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x30, 0x00, 0xbd, 0x27, 0xc0, 0xff, 0xbd, 0x27, 0x3c, 0x00, 0xbf, 0xaf, 0x38,
- 0x00, 0xbe, 0xaf, 0x34, 0x00, 0xb7, 0xaf, 0x30, 0x00, 0xb6, 0xaf, 0x2c, 0x00,
- 0xb5, 0xaf, 0x28, 0x00, 0xb4, 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x20, 0x00, 0xb2,
- 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x00, 0xa0, 0x04, 0x3c,
- 0x00, 0x10, 0x84, 0x34, 0x00, 0xa0, 0x05, 0x3c, 0x35, 0x21, 0x00, 0x0c, 0x00,
- 0x30, 0xa5, 0x34, 0x4c, 0x8f, 0x80, 0xa3, 0x00, 0xa0, 0x15, 0x3c, 0x00, 0x10,
- 0xb5, 0x36, 0x70, 0x8c, 0x80, 0xaf, 0x01, 0x80, 0x11, 0x3c, 0x90, 0xfa, 0x31,
- 0x26, 0x01, 0xa2, 0x14, 0x3c, 0x21, 0x98, 0x00, 0x00, 0x01, 0x80, 0x1e, 0x3c,
- 0x10, 0xbb, 0xde, 0x27, 0x01, 0x00, 0x17, 0x24, 0x02, 0x00, 0x16, 0x24, 0x70,
- 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x22, 0xae, 0x00, 0x00,
- 0x35, 0xae, 0x10, 0x00, 0x60, 0x12, 0x04, 0x00, 0x34, 0xae, 0xff, 0x00, 0x02,
- 0x24, 0x00, 0x00, 0x82, 0xa2, 0xf3, 0x01, 0x02, 0x24, 0xff, 0xff, 0x03, 0x24,
- 0x01, 0xa2, 0x01, 0x3c, 0x00, 0x00, 0x20, 0xa4, 0xff, 0xff, 0x42, 0x24, 0xfc,
- 0xff, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x12, 0x01, 0x00,
- 0x10, 0x24, 0x00, 0x00, 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, 0x50, 0x1d, 0x00,
- 0x08, 0x82, 0x80, 0x02, 0x00, 0x01, 0x00, 0x10, 0x24, 0xff, 0xff, 0x03, 0x26,
- 0x1c, 0x00, 0x62, 0x2c, 0x41, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01,
- 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x70, 0xd9, 0x22, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x1d, 0x00,
- 0x08, 0x10, 0x00, 0x02, 0x24, 0x40, 0x20, 0x13, 0x00, 0x21, 0x20, 0x93, 0x00,
- 0xc0, 0x20, 0x04, 0x00, 0x50, 0x8f, 0x82, 0x27, 0x21, 0x20, 0x82, 0x00, 0x01,
- 0x00, 0x05, 0x24, 0x01, 0x80, 0x06, 0x3c, 0x40, 0xc2, 0xc6, 0x24, 0x1e, 0x2a,
- 0x00, 0x0c, 0x08, 0x00, 0xa7, 0x26, 0x04, 0x00, 0x02, 0x24, 0x02, 0x00, 0x02,
- 0x16, 0x08, 0x00, 0x02, 0x24, 0x09, 0x00, 0x02, 0x24, 0x24, 0x00, 0x22, 0xae,
- 0x00, 0x80, 0x02, 0x3c, 0x70, 0x68, 0x42, 0x24, 0x0c, 0x00, 0x22, 0xae, 0x00,
- 0x80, 0x02, 0x3c, 0x00, 0x5b, 0x42, 0x24, 0x08, 0x00, 0x22, 0xae, 0x00, 0x80,
- 0x02, 0x3c, 0x54, 0x73, 0x42, 0x24, 0x14, 0x00, 0x22, 0xae, 0x01, 0x80, 0x02,
- 0x3c, 0xb0, 0xc2, 0x42, 0x24, 0x18, 0x00, 0x22, 0xae, 0x01, 0x80, 0x02, 0x3c,
- 0x70, 0xc6, 0x42, 0x24, 0x8c, 0x1d, 0x00, 0x08, 0x1c, 0x00, 0x22, 0xae, 0x04,
- 0x00, 0x02, 0x24, 0x24, 0x00, 0x22, 0xae, 0x00, 0x80, 0x02, 0x3c, 0x90, 0x62,
- 0x42, 0x24, 0x0c, 0x00, 0x22, 0xae, 0x00, 0x80, 0x02, 0x3c, 0x60, 0x5a, 0x42,
- 0x24, 0x08, 0x00, 0x22, 0xae, 0x00, 0x80, 0x02, 0x3c, 0x44, 0x73, 0x42, 0x24,
- 0x14, 0x00, 0x22, 0xae, 0x01, 0x80, 0x02, 0x3c, 0xac, 0xb9, 0x42, 0x24, 0x18,
- 0x00, 0x22, 0xae, 0x01, 0x80, 0x02, 0x3c, 0xac, 0xbc, 0x42, 0x24, 0x1c, 0x00,
- 0x22, 0xae, 0x28, 0x00, 0x30, 0xae, 0x0d, 0x00, 0x60, 0x12, 0x2c, 0x00, 0x3e,
- 0xae, 0x04, 0x10, 0x77, 0x02, 0x4c, 0x8f, 0x82, 0xa3, 0x0c, 0x00, 0x96, 0xa2,
- 0x9c, 0x1d, 0x00, 0x08, 0x21, 0x90, 0xa0, 0x02, 0x24, 0x00, 0x20, 0xae, 0x01,
- 0x80, 0x02, 0x3c, 0x80, 0x8a, 0x42, 0x24, 0x08, 0x00, 0x22, 0xae, 0x0c, 0x00,
- 0x22, 0xae, 0x14, 0x00, 0x22, 0xae, 0x18, 0x00, 0x22, 0xae, 0x21, 0x90, 0xa0,
- 0x02, 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x40, 0x10,
- 0x21, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x22, 0x8e, 0x21, 0x20, 0x40, 0x02, 0x21,
- 0x28, 0x20, 0x02, 0x09, 0xf8, 0x40, 0x00, 0x21, 0x30, 0x00, 0x02, 0x01, 0x00,
- 0x10, 0x26, 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x02,
- 0x02, 0xf6, 0xff, 0x40, 0x14, 0x80, 0x00, 0x52, 0x26, 0x24, 0x00, 0x23, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, 0x03, 0x00, 0x21, 0xa8, 0xa2, 0x02, 0x70,
- 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x70, 0x8c,
- 0x82, 0xaf, 0x30, 0x00, 0x31, 0x26, 0x01, 0x00, 0x73, 0x26, 0x04, 0x00, 0x62,
- 0x2a, 0x83, 0xff, 0x40, 0x14, 0x00, 0x40, 0x94, 0x26, 0x70, 0x8c, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x42, 0x24, 0x42, 0x11, 0x02, 0x00, 0x10,
- 0x8c, 0x82, 0xaf, 0x4c, 0x8f, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x38, 0x90,
- 0x82, 0xa3, 0x94, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
- 0x3c, 0x00, 0x01, 0x42, 0x34, 0x14, 0x00, 0x42, 0x8c, 0x00, 0x80, 0x05, 0x3c,
- 0xb0, 0x8f, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x21, 0x00, 0x0c, 0x23,
- 0x28, 0x45, 0x00, 0x3c, 0x00, 0xbf, 0x8f, 0x38, 0x00, 0xbe, 0x8f, 0x34, 0x00,
- 0xb7, 0x8f, 0x30, 0x00, 0xb6, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4,
- 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f,
- 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24, 0xc4, 0x8b,
- 0x82, 0xaf, 0xcc, 0x8f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43,
- 0x34, 0xc0, 0x8b, 0x83, 0xaf, 0x01, 0x04, 0x42, 0x34, 0xb0, 0x8b, 0x82, 0xaf,
- 0xc0, 0x8f, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0xc4,
- 0x8f, 0x82, 0xaf, 0xb4, 0x8b, 0x82, 0xaf, 0x00, 0x0b, 0x43, 0x34, 0xb8, 0x8e,
- 0x83, 0xaf, 0xd0, 0x8f, 0x82, 0xaf, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x60, 0x89, 0x84, 0x27,
- 0x24, 0x0c, 0x00, 0x0c, 0x5c, 0x00, 0x05, 0x24, 0x10, 0x00, 0xbf, 0x8f, 0x18,
- 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff,
- 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0xe0, 0x31, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x40, 0xa4, 0x4c, 0x12, 0x00, 0x0c,
- 0x00, 0x03, 0x04, 0x24, 0x00, 0x80, 0x02, 0x3c, 0x70, 0x34, 0x42, 0x24, 0x82,
- 0x10, 0x02, 0x00, 0xff, 0x03, 0x04, 0x3c, 0xff, 0xff, 0x84, 0x34, 0x24, 0x10,
- 0x44, 0x00, 0x00, 0x08, 0x03, 0x3c, 0x25, 0x10, 0x43, 0x00, 0x00, 0x80, 0x01,
- 0x3c, 0x00, 0x00, 0x22, 0xac, 0x00, 0x80, 0x01, 0x3c, 0x04, 0x00, 0x20, 0xac,
- 0x00, 0x80, 0x02, 0x3c, 0x80, 0x32, 0x42, 0x24, 0x82, 0x10, 0x02, 0x00, 0x24,
- 0x10, 0x44, 0x00, 0x25, 0x10, 0x43, 0x00, 0x00, 0x80, 0x01, 0x3c, 0x80, 0x00,
- 0x22, 0xac, 0x00, 0x80, 0x01, 0x3c, 0x84, 0x00, 0x20, 0xac, 0x01, 0xa2, 0x03,
- 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x19, 0x00, 0x02, 0x24, 0xc8, 0x8f, 0x82, 0xaf,
- 0x19, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xa4, 0x21, 0x18, 0x00, 0x00, 0x01,
- 0x00, 0x63, 0x24, 0x64, 0x00, 0x62, 0x28, 0xfe, 0xff, 0x40, 0x14, 0x01, 0x00,
- 0x63, 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x18, 0x00, 0x02,
- 0x24, 0xc8, 0x8f, 0x82, 0xaf, 0x18, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xa4,
- 0x00, 0x80, 0x04, 0x3c, 0x00, 0x30, 0x84, 0x24, 0x01, 0x80, 0x05, 0x3c, 0x6c,
- 0x12, 0x00, 0x0c, 0x30, 0xeb, 0xa5, 0x24, 0xff, 0xff, 0x03, 0x24, 0x03, 0x00,
- 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0x59, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0xd8, 0x1d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x2b, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x16, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0xcd, 0x22, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1d, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x1d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0x8f, 0x84, 0x27, 0x21, 0x28, 0x00, 0x00, 0x01, 0x80, 0x06, 0x3c, 0xe0,
- 0x88, 0xc6, 0x24, 0x1e, 0x2a, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x00, 0xe0, 0x8f,
- 0x84, 0x27, 0x39, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xca, 0x2a, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x21, 0x10, 0x00, 0x00,
- 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x80, 0x08, 0x3c, 0x20, 0xf9, 0x08, 0x25, 0x30, 0x8e,
- 0x8a, 0x27, 0x21, 0x10, 0xa4, 0x00, 0xff, 0xff, 0x43, 0x90, 0xff, 0x00, 0x02,
- 0x24, 0x03, 0x00, 0x62, 0x14, 0xfd, 0xff, 0xa2, 0x24, 0xff, 0xff, 0xa5, 0x24,
- 0xfd, 0xff, 0xa2, 0x24, 0x14, 0x90, 0x82, 0xaf, 0x23, 0x18, 0x02, 0x00, 0x18,
- 0x90, 0x83, 0xaf, 0x08, 0x90, 0x82, 0xaf, 0x00, 0x00, 0x83, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x19, 0x03, 0x00, 0xff, 0xff, 0x63, 0x24, 0x2a, 0x10, 0x62,
- 0x00, 0x02, 0x00, 0x40, 0x14, 0x48, 0x00, 0x43, 0xad, 0xfc, 0xff, 0xa3, 0x24,
- 0x21, 0x10, 0x64, 0x00, 0x02, 0x00, 0x45, 0x90, 0xb8, 0x8a, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x2a, 0x10, 0xa2, 0x00, 0x02, 0x00, 0x40, 0x10, 0x0a, 0x00,
- 0x06, 0x24, 0x21, 0x30, 0xa0, 0x00, 0x4c, 0x00, 0x06, 0xad, 0x21, 0x10, 0x64,
- 0x00, 0x03, 0x00, 0x45, 0x90, 0xb8, 0x8a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0x10, 0xa2, 0x00, 0x02, 0x00, 0x40, 0x10, 0x0a, 0x00, 0x03, 0x24, 0x21,
- 0x18, 0xa0, 0x00, 0x48, 0x00, 0x03, 0xad, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10,
- 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22,
- 0x00, 0xac, 0xdc, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0xc2, 0x10, 0x02, 0x00, 0x90, 0x00, 0x02, 0xad, 0x94,
- 0x00, 0x02, 0xad, 0x10, 0x27, 0x02, 0x24, 0x80, 0x00, 0x02, 0xad, 0x70, 0x00,
- 0x00, 0xad, 0x14, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x40,
- 0x04, 0x21, 0x38, 0x00, 0x00, 0xb8, 0x8a, 0x8c, 0x8f, 0x01, 0x80, 0x0d, 0x3c,
- 0xa8, 0xdc, 0xad, 0x25, 0x1e, 0x00, 0x09, 0x3c, 0x80, 0x84, 0x29, 0x35, 0x14,
- 0x90, 0x8b, 0x8f, 0x21, 0x10, 0xe4, 0x00, 0x02, 0x00, 0x45, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x2a, 0x10, 0xac, 0x00, 0x03, 0x00, 0x40, 0x14, 0x40, 0x10, 0x05,
- 0x00, 0x0a, 0x00, 0x05, 0x24, 0x40, 0x10, 0x05, 0x00, 0x21, 0x10, 0x45, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x4d, 0x00, 0x04, 0x00, 0x46, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x28,
- 0x02, 0x00, 0x1a, 0x00, 0x25, 0x01, 0x02, 0x00, 0xa0, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0xa1, 0x14,
- 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x21, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0x70, 0x00, 0x03, 0x8d, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x70, 0x00, 0x02, 0xad, 0x94, 0x00, 0x02,
- 0x8d, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0xa2, 0x00, 0x02, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x05, 0xad, 0x04, 0x00, 0xc3, 0x94, 0x80,
- 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x62, 0x00, 0x02, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0xad, 0x01, 0x00, 0xe7,
- 0x24, 0x2a, 0x10, 0x67, 0x01, 0xd2, 0xff, 0x40, 0x10, 0x21, 0x10, 0xe4, 0x00,
- 0x80, 0x00, 0x03, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x62, 0x28, 0x02,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x03, 0x24, 0x70, 0x00,
- 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x62, 0x00, 0x12, 0x18, 0x00,
- 0x00, 0x62, 0x10, 0x02, 0x3c, 0xd3, 0x4d, 0x42, 0x34, 0x19, 0x00, 0x62, 0x00,
- 0x10, 0x70, 0x00, 0x00, 0x82, 0x11, 0x0e, 0x00, 0x74, 0x00, 0x02, 0xad, 0x70,
- 0x00, 0x04, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x84, 0x24, 0x14, 0x90,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x40, 0x18, 0x02,
- 0x00, 0x21, 0x18, 0x62, 0x00, 0xc0, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
- 0x40, 0x18, 0x03, 0x00, 0x21, 0x20, 0x83, 0x00, 0x70, 0x00, 0x04, 0xad, 0x74,
- 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x42, 0x24, 0x21, 0x10,
- 0x43, 0x00, 0x74, 0x00, 0x02, 0xad, 0x01, 0x00, 0x03, 0x24, 0x04, 0x90, 0x83,
- 0xaf, 0x0c, 0x00, 0x0a, 0xad, 0x10, 0x00, 0x0a, 0xad, 0x14, 0x00, 0x0a, 0xad,
- 0x28, 0x00, 0x03, 0xad, 0xf0, 0x00, 0x02, 0x24, 0x2c, 0x00, 0x02, 0xad, 0x68,
- 0x00, 0x03, 0xad, 0x6c, 0x00, 0x03, 0xad, 0x0c, 0x90, 0x83, 0xaf, 0x09, 0x00,
- 0x02, 0x24, 0x20, 0x00, 0x42, 0xad, 0x04, 0x00, 0x48, 0xad, 0x00, 0x00, 0x4a,
- 0xad, 0x10, 0x00, 0x42, 0x25, 0x14, 0x00, 0x42, 0xad, 0x08, 0x00, 0xe0, 0x03,
- 0x1c, 0x00, 0x43, 0xad, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14,
- 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x00, 0x90, 0x90, 0x8f, 0x01, 0x80,
- 0x11, 0x3c, 0x20, 0xf9, 0x31, 0x26, 0x10, 0x00, 0x03, 0x8e, 0x03, 0x00, 0x02,
- 0x24, 0x04, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x89, 0x84, 0x27,
- 0x24, 0x0c, 0x00, 0x0c, 0xc3, 0x00, 0x05, 0x24, 0x40, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x11, 0x02, 0x00, 0x1c, 0x00, 0x23, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x04, 0x00, 0x03, 0x24, 0x18, 0x00, 0x43,
- 0xac, 0x20, 0x00, 0x50, 0xac, 0x01, 0x80, 0x04, 0x3c, 0x20, 0xf9, 0x84, 0x24,
- 0x08, 0x00, 0x05, 0x8e, 0x14, 0x00, 0x06, 0x8e, 0x7c, 0x32, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
- 0x82, 0xaf, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x82,
- 0x27, 0x1c, 0x90, 0x82, 0xaf, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0,
- 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00,
- 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x30, 0x8e, 0x91, 0x27, 0x20, 0x00, 0x22,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x42, 0x30, 0x40, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0x42, 0x30, 0x3b, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x40, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x62, 0x28, 0x21, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
- 0x62, 0x28, 0x91, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x03,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x90,
- 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00,
- 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01,
- 0x24, 0x04, 0x00, 0x61, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0xbc,
- 0x8b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x78, 0x00,
- 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x05, 0x00, 0x42,
- 0x28, 0x74, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x23, 0x00, 0x0c,
- 0x21, 0x20, 0x20, 0x02, 0x10, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0x14, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10,
- 0x43, 0x00, 0x10, 0x90, 0x82, 0xaf, 0x18, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x96, 0x1f, 0x00, 0x08, 0x2a, 0x10, 0x43, 0x00, 0x00, 0x90, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x8c,
- 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0x28, 0x20, 0x00,
- 0x40, 0x14, 0x05, 0x00, 0x62, 0x28, 0x5c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x88, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00,
- 0x23, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0,
- 0x10, 0x02, 0x00, 0x90, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
- 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07,
- 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0x61, 0x14, 0x00, 0x80, 0x01, 0x3c,
- 0x02, 0x00, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12,
- 0x10, 0x00, 0x00, 0xbc, 0x8b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10,
- 0x43, 0x00, 0x78, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x05, 0x00, 0x42, 0x28, 0x3f, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xf2, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x90, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x10, 0x90, 0x82, 0xaf, 0x08, 0x90,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x62, 0x00, 0x8a, 0xff, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x90, 0x83, 0xaf, 0x21, 0x1f, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x9c, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x29,
- 0x00, 0x40, 0x10, 0xfe, 0xff, 0x03, 0x24, 0x8c, 0x00, 0x03, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x62, 0x28, 0x20, 0x00, 0x40, 0x14, 0x05, 0x00, 0x62,
- 0x28, 0x26, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00, 0x23, 0x10, 0x43, 0x00, 0x80,
- 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x90, 0x00,
- 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24,
- 0x04, 0x00, 0x61, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0xbc, 0x8b,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x78, 0x00, 0x03,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x05, 0x00, 0x42, 0x28,
- 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x24, 0x00, 0x0c, 0x21,
- 0x20, 0x00, 0x02, 0x9f, 0x1f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x2c, 0x00, 0x02,
- 0xae, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x00, 0xa0, 0x03, 0x3c, 0x68,
- 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x03, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa2,
- 0xac, 0x00, 0x00, 0xa0, 0xac, 0x1c, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x45, 0xac, 0x1c, 0x90, 0x85, 0xaf, 0x2c, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x08, 0x00, 0xe0, 0x03, 0x2c, 0x00,
- 0x82, 0xac, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2,
- 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00,
- 0x21, 0x90, 0xa0, 0x00, 0x08, 0x00, 0x50, 0x8e, 0x14, 0x00, 0x44, 0x8e, 0x00,
- 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x43, 0x30, 0x04, 0x00,
- 0x62, 0x28, 0x07, 0x00, 0x40, 0x10, 0x02, 0x00, 0x62, 0x28, 0x26, 0x00, 0x40,
- 0x10, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0x62, 0x10, 0x21, 0x10, 0x90, 0x00,
- 0x3a, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x24, 0x28,
- 0x00, 0x62, 0x10, 0xf4, 0xff, 0x82, 0x24, 0x3a, 0x20, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x43, 0x90, 0xff, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62,
- 0x14, 0xfc, 0xff, 0x82, 0x24, 0xff, 0xff, 0x84, 0x24, 0xfc, 0xff, 0x82, 0x24,
- 0x09, 0x00, 0x42, 0x2c, 0x2f, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x00,
- 0x01, 0x42, 0x34, 0x5c, 0x00, 0x43, 0x90, 0x00, 0x00, 0x02, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x10, 0x43, 0x00, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02,
- 0x24, 0x01, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x14,
- 0x00, 0xa0, 0x02, 0x3c, 0x59, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xa0, 0x02, 0x3c, 0x00, 0x01, 0x42, 0x34, 0x5c, 0x00, 0x42, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x2a, 0x20, 0x00, 0x08, 0x00, 0x00, 0x02, 0xa2, 0x04, 0x00, 0x02,
- 0x24, 0x0e, 0x00, 0x82, 0x14, 0x03, 0x00, 0x02, 0x24, 0x03, 0x00, 0x03, 0x92,
- 0xff, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x62, 0x14, 0x03, 0x00, 0x02, 0x24, 0x28,
- 0x20, 0x00, 0x08, 0x03, 0x00, 0x04, 0x24, 0x01, 0x08, 0x42, 0x2c, 0x11, 0x00,
- 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x0a, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0x42, 0x24, 0xff, 0xff, 0x42, 0x30, 0x0b, 0x00, 0x82, 0x14,
- 0x00, 0xa0, 0x03, 0x3c, 0x2c, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0x42, 0x34, 0x2c, 0x00, 0x22, 0xae, 0x21, 0x20, 0x20, 0x02, 0xd0, 0x1f,
- 0x00, 0x0c, 0x21, 0x28, 0x40, 0x02, 0x3d, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xa0, 0x03, 0x3c, 0xbc, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x3d, 0x20, 0x00, 0x08, 0x00,
- 0x00, 0x62, 0xac, 0x70, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x81, 0x01,
- 0x05, 0x24, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27,
- 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x00, 0xa0, 0x02, 0x3c, 0x00,
- 0x01, 0x42, 0x34, 0x00, 0xa0, 0x04, 0x3c, 0x5c, 0x01, 0x84, 0x34, 0x58, 0x00,
- 0x45, 0x8c, 0x4c, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x29, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x82, 0x27, 0x1c, 0x90, 0x82, 0xaf,
- 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00,
- 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x00,
- 0x00, 0x21, 0x80, 0x00, 0x00, 0x01, 0xa2, 0x05, 0x3c, 0xff, 0x00, 0x04, 0x24,
- 0x01, 0x00, 0x03, 0x24, 0x80, 0x13, 0x10, 0x00, 0x21, 0x10, 0x45, 0x00, 0x00,
- 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x42, 0x30, 0x02, 0x00,
- 0x44, 0x10, 0x04, 0x10, 0x03, 0x02, 0x25, 0x88, 0x22, 0x02, 0x01, 0x00, 0x10,
- 0x26, 0x04, 0x00, 0x02, 0x2a, 0xf6, 0xff, 0x40, 0x14, 0x80, 0x13, 0x10, 0x00,
- 0x38, 0x90, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x22, 0x02, 0x4c,
- 0x8f, 0x83, 0x93, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x17, 0x00,
- 0x40, 0x10, 0x21, 0x18, 0x40, 0x00, 0x21, 0x80, 0x00, 0x00, 0xff, 0x00, 0x72,
- 0x30, 0x07, 0x10, 0x12, 0x02, 0x01, 0x00, 0x42, 0x30, 0x0d, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x38, 0x90, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x10, 0x02, 0x02, 0x01, 0x00, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0xf2, 0x20, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x85, 0x20, 0x00,
- 0x08, 0x01, 0x00, 0x10, 0x26, 0xb2, 0x20, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0x01, 0x00, 0x10, 0x26, 0x04, 0x00, 0x02, 0x2a, 0xee, 0xff, 0x40, 0x14, 0x07,
- 0x10, 0x12, 0x02, 0x4c, 0x8f, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10,
- 0x22, 0x02, 0x38, 0x90, 0x82, 0xa3, 0x99, 0x2a, 0x00, 0x0c, 0xfa, 0x00, 0x04,
- 0x24, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe8,
- 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80,
- 0x00, 0x00, 0x07, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x8f, 0x82,
- 0x93, 0x00, 0x00, 0x00, 0x00, 0x07, 0x10, 0x02, 0x02, 0x01, 0x00, 0x42, 0x30,
- 0x03, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x20, 0x00, 0x0c, 0x21,
- 0x20, 0x00, 0x02, 0x01, 0x00, 0x10, 0x26, 0x04, 0x00, 0x02, 0x2a, 0xf3, 0xff,
- 0x40, 0x14, 0x02, 0x00, 0x05, 0x24, 0x20, 0x90, 0x84, 0x27, 0x01, 0x80, 0x06,
- 0x3c, 0x50, 0x81, 0xc6, 0x24, 0x1e, 0x2a, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x00,
- 0x20, 0x90, 0x84, 0x27, 0x39, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00,
- 0xbd, 0x27, 0xc8, 0xff, 0xbd, 0x27, 0x30, 0x00, 0xbf, 0xaf, 0x2c, 0x00, 0xb5,
- 0xaf, 0x28, 0x00, 0xb4, 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x20, 0x00, 0xb2, 0xaf,
- 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x40, 0x10, 0x04, 0x00, 0x21,
- 0x10, 0x44, 0x00, 0x00, 0x11, 0x02, 0x00, 0x01, 0x80, 0x03, 0x3c, 0x90, 0xfa,
- 0x63, 0x24, 0x21, 0x88, 0x43, 0x00, 0x00, 0x00, 0x30, 0x8e, 0x24, 0x00, 0x22,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x40, 0x10, 0x21, 0x90, 0x00, 0x00,
- 0x04, 0x00, 0x15, 0x24, 0x08, 0x00, 0x14, 0x24, 0xc0, 0x8b, 0x84, 0x8f, 0x2e,
- 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x98, 0x40, 0x00, 0x28, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x55, 0x14, 0x40, 0x11, 0x12,
- 0x00, 0x48, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x54, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xdc,
- 0x20, 0x00, 0x08, 0x00, 0x08, 0x42, 0x24, 0x40, 0x11, 0x12, 0x00, 0x00, 0x01,
- 0x42, 0x24, 0x04, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x24, 0x00, 0x02, 0xae, 0x2c, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0xf8, 0x40, 0x00, 0x21, 0x20, 0x00, 0x02, 0x37, 0x12, 0x00, 0x0c, 0x21,
- 0x20, 0x60, 0x02, 0x01, 0x00, 0x52, 0x26, 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x10, 0x42, 0x02, 0xdf, 0xff, 0x40, 0x14, 0x80, 0x00, 0x10,
- 0x26, 0x30, 0x00, 0xbf, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f,
- 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00, 0xbd, 0x27, 0xd8, 0xff,
- 0xbd, 0x27, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x1c, 0x00, 0xb1,
- 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x00, 0xa0, 0x05, 0x3c, 0x21, 0x0c, 0xa5, 0x34,
- 0x01, 0x00, 0x03, 0x24, 0x04, 0x18, 0x83, 0x00, 0x00, 0x00, 0xa2, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0x40, 0x10,
- 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, 0x00, 0x11, 0x02, 0x00, 0x01, 0x80, 0x03,
- 0x3c, 0x90, 0xfa, 0x63, 0x24, 0x21, 0x90, 0x43, 0x00, 0x00, 0x00, 0x50, 0x8e,
- 0x24, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x40, 0x10, 0x21,
- 0x88, 0x00, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12,
- 0x00, 0x0c, 0x01, 0x00, 0x31, 0x26, 0x24, 0x00, 0x00, 0xae, 0x54, 0x00, 0x00,
- 0xa2, 0x58, 0x00, 0x00, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x00,
- 0x24, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x22, 0x02, 0xf3,
- 0xff, 0x40, 0x14, 0x80, 0x00, 0x10, 0x26, 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00,
- 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x28, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x8b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10,
- 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x1f, 0x28, 0x42, 0x24,
- 0x10, 0x8b, 0x82, 0xaf, 0x02, 0x14, 0x02, 0x00, 0x18, 0x00, 0x82, 0x00, 0x12,
- 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0xe0, 0x03, 0x02, 0x14, 0x05, 0x00, 0x2b, 0x10, 0x85, 0x00, 0x06, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xac, 0x04, 0x00, 0x84, 0x24,
- 0x2b, 0x10, 0x85, 0x00, 0xfc, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xff, 0xbd, 0x27, 0x5c, 0x00,
- 0xbf, 0xaf, 0x58, 0x00, 0xbe, 0xaf, 0x54, 0x00, 0xb7, 0xaf, 0x50, 0x00, 0xb6,
- 0xaf, 0x4c, 0x00, 0xb5, 0xaf, 0x48, 0x00, 0xb4, 0xaf, 0x44, 0x00, 0xb3, 0xaf,
- 0x40, 0x00, 0xb2, 0xaf, 0x3c, 0x00, 0xb1, 0xaf, 0x38, 0x00, 0xb0, 0xaf, 0xff,
- 0x00, 0x97, 0x24, 0xff, 0x1f, 0x03, 0x3c, 0x00, 0xff, 0x63, 0x34, 0x24, 0xb8,
- 0xe3, 0x02, 0x00, 0xa0, 0x02, 0x3c, 0x25, 0xb8, 0xe2, 0x02, 0x24, 0xf0, 0xa3,
- 0x00, 0x25, 0xf0, 0xc2, 0x03, 0x21, 0x20, 0xe0, 0x02, 0x35, 0x21, 0x00, 0x0c,
- 0x21, 0x28, 0xc0, 0x03, 0x18, 0x00, 0xa0, 0xaf, 0x01, 0x80, 0x11, 0x3c, 0x90,
- 0xfa, 0x31, 0x26, 0xc0, 0x00, 0x22, 0x26, 0x17, 0x00, 0x22, 0x12, 0x10, 0x00,
- 0xa0, 0xaf, 0x04, 0x00, 0x04, 0x24, 0x01, 0x80, 0x03, 0x3c, 0x50, 0xfb, 0x63,
- 0x24, 0x28, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x44, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x22, 0x8e, 0x10, 0x00, 0xa6, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x6e, 0x21, 0x00, 0x08, 0x21, 0x30, 0xc2, 0x00, 0x18, 0x00,
- 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc6, 0x24, 0x18, 0x00, 0xa6,
- 0xaf, 0x10, 0x00, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc6, 0x24,
- 0x30, 0x00, 0x31, 0x26, 0xee, 0xff, 0x23, 0x16, 0x10, 0x00, 0xa6, 0xaf, 0x10,
- 0x00, 0x15, 0x24, 0x21, 0x98, 0xc0, 0x03, 0x00, 0x10, 0xa2, 0x2a, 0x02, 0x00,
- 0x40, 0x14, 0x00, 0x10, 0x12, 0x24, 0x21, 0x90, 0xa0, 0x02, 0x23, 0x18, 0x77,
- 0x02, 0x10, 0x00, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x06, 0x00,
- 0x18, 0x00, 0xa2, 0x02, 0x12, 0x30, 0x00, 0x00, 0x23, 0x18, 0x66, 0x00, 0x18,
- 0x00, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x46, 0x02, 0x12, 0x30,
- 0x00, 0x00, 0x23, 0xa0, 0x66, 0x00, 0x2a, 0x10, 0x95, 0x02, 0x08, 0x00, 0x40,
- 0x10, 0x11, 0x00, 0xa2, 0x2a, 0xa4, 0x00, 0x40, 0x10, 0x23, 0x10, 0xd7, 0x03,
- 0x80, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0xae, 0x00, 0x05, 0x24, 0x2b,
- 0x22, 0x00, 0x08, 0x23, 0x10, 0xd7, 0x03, 0x01, 0x80, 0x11, 0x3c, 0x90, 0xfa,
- 0x31, 0x26, 0x01, 0x80, 0x06, 0x3c, 0x50, 0xfb, 0xc6, 0x24, 0x2f, 0x00, 0x26,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56, 0x26, 0x21, 0x30, 0xd2, 0x02,
- 0x20, 0x00, 0xa6, 0xaf, 0x28, 0x00, 0x22, 0x8e, 0x04, 0x00, 0x06, 0x24, 0x21,
- 0x00, 0x46, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x50, 0x24, 0x2a, 0x10, 0x92, 0x02, 0x05, 0x00, 0x40,
- 0x14, 0x0e, 0x00, 0x16, 0xa6, 0x20, 0x00, 0xa6, 0x97, 0x00, 0x00, 0x00, 0x00,
- 0x0e, 0x00, 0x06, 0xa6, 0x23, 0xa0, 0x92, 0x02, 0x0e, 0x00, 0x02, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x23, 0x98, 0x62, 0x02, 0x2b, 0x10,
- 0x77, 0x02, 0x07, 0x00, 0x40, 0x14, 0x3c, 0x00, 0x13, 0xae, 0x0e, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x53, 0x00, 0x2b, 0x10, 0x5e, 0x00,
- 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x84, 0x27, 0x24,
- 0x0c, 0x00, 0x0c, 0xcb, 0x00, 0x05, 0x24, 0x0e, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x16, 0x00, 0x02, 0xa6, 0x3c, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x00, 0x02, 0xae, 0x30, 0x00, 0x31, 0x26, 0x01, 0x80, 0x06, 0x3c,
- 0x50, 0xfb, 0xc6, 0x24, 0xd8, 0xff, 0x26, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x80, 0x11, 0x3c, 0x90, 0xfa, 0x31, 0x26, 0x2b, 0x00, 0x26, 0x12, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0xb6, 0x26, 0x21, 0x30, 0xd5, 0x02, 0x28, 0x00, 0xa6,
- 0xaf, 0x28, 0x00, 0x22, 0x8e, 0x04, 0x00, 0x06, 0x24, 0x02, 0x00, 0x46, 0x10,
- 0x08, 0x00, 0x12, 0x24, 0x24, 0x00, 0x32, 0x8e, 0x00, 0x00, 0x30, 0x8e, 0x1b,
- 0x00, 0x40, 0x12, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x95, 0x02, 0x05, 0x00,
- 0x40, 0x14, 0x16, 0x00, 0x16, 0xa6, 0x28, 0x00, 0xa6, 0x97, 0x00, 0x00, 0x00,
- 0x00, 0x16, 0x00, 0x06, 0xa6, 0x23, 0xa0, 0x95, 0x02, 0x16, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x23, 0x98, 0x62, 0x02, 0x2b,
- 0x10, 0x77, 0x02, 0x07, 0x00, 0x40, 0x14, 0x38, 0x00, 0x13, 0xae, 0x16, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x53, 0x00, 0x2b, 0x10, 0x5e,
- 0x00, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x84, 0x27,
- 0x24, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x24, 0xff, 0xff, 0x52, 0x26, 0xe7,
- 0xff, 0x40, 0x16, 0x80, 0x00, 0x10, 0x26, 0x30, 0x00, 0x31, 0x26, 0x01, 0x80,
- 0x06, 0x3c, 0x50, 0xfb, 0xc6, 0x24, 0xda, 0xff, 0x26, 0x16, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x80, 0x11, 0x3c, 0x90, 0xfa, 0x31, 0x26, 0x01, 0x80, 0x06, 0x3c,
- 0x50, 0xfb, 0xc6, 0x24, 0x35, 0x00, 0x26, 0x12, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xb6, 0x26, 0x21, 0x30, 0xd5, 0x02, 0x30, 0x00, 0xa6, 0xaf, 0x28, 0x00,
- 0x22, 0x8e, 0x04, 0x00, 0x06, 0x24, 0x02, 0x00, 0x46, 0x10, 0x08, 0x00, 0x12,
- 0x24, 0x24, 0x00, 0x32, 0x8e, 0x00, 0x00, 0x30, 0x8e, 0x25, 0x00, 0x40, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x95, 0x02, 0x05, 0x00, 0x40, 0x14, 0x0e,
- 0x00, 0x16, 0xa6, 0x30, 0x00, 0xa6, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
- 0x06, 0xa6, 0x23, 0xa0, 0x95, 0x02, 0x0e, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x23, 0x98, 0x62, 0x02, 0x3c, 0x00, 0x13, 0xae,
- 0x38, 0x00, 0x02, 0x8e, 0xff, 0x1f, 0x06, 0x3c, 0xff, 0xff, 0xc6, 0x34, 0x24,
- 0x10, 0x46, 0x00, 0x00, 0x80, 0x06, 0x3c, 0x25, 0x10, 0x46, 0x00, 0x38, 0x00,
- 0x02, 0xae, 0x3c, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x77,
- 0x00, 0x07, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x2b, 0x10, 0x5e, 0x00, 0x04,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x84, 0x27, 0x24, 0x0c,
- 0x00, 0x0c, 0x2c, 0x01, 0x05, 0x24, 0xff, 0xff, 0x52, 0x26, 0xdd, 0xff, 0x40,
- 0x16, 0x80, 0x00, 0x10, 0x26, 0x30, 0x00, 0x31, 0x26, 0x01, 0x80, 0x06, 0x3c,
- 0x50, 0xfb, 0xc6, 0x24, 0xd0, 0xff, 0x26, 0x16, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xa8, 0x15, 0x00, 0x01, 0x40, 0xa2, 0x2a, 0x48, 0xff, 0x40, 0x14, 0x23, 0x10,
- 0xd7, 0x03, 0x82, 0x12, 0x02, 0x00, 0x5c, 0x00, 0xbf, 0x8f, 0x58, 0x00, 0xbe,
- 0x8f, 0x54, 0x00, 0xb7, 0x8f, 0x50, 0x00, 0xb6, 0x8f, 0x4c, 0x00, 0xb5, 0x8f,
- 0x48, 0x00, 0xb4, 0x8f, 0x44, 0x00, 0xb3, 0x8f, 0x40, 0x00, 0xb2, 0x8f, 0x3c,
- 0x00, 0xb1, 0x8f, 0x38, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x60, 0x00,
- 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0xb8, 0x8e, 0x84,
- 0x8f, 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x99, 0x2a, 0x00, 0x0c,
- 0x32, 0x00, 0x04, 0x24, 0xbc, 0x8b, 0x82, 0x8f, 0x44, 0x90, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x60, 0xea, 0x03, 0x34, 0x2a, 0x18,
- 0x62, 0x00, 0x04, 0x00, 0x60, 0x10, 0x01, 0xa2, 0x02, 0x3c, 0x59, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x40, 0xa4,
- 0x40, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x83, 0xaf, 0x04,
- 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x43, 0x00, 0x02, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8d, 0x83, 0xaf, 0x40, 0x90, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x82, 0x18, 0x02, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0x40, 0x90, 0x82, 0xaf, 0x14, 0x8b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x62, 0x24, 0x14, 0x8b, 0x82, 0xaf, 0x14, 0x00, 0x42, 0x28, 0x02, 0x00,
- 0x40, 0x14, 0xf3, 0xff, 0x62, 0x24, 0x14, 0x8b, 0x82, 0xaf, 0x01, 0x80, 0x04,
- 0x3c, 0x20, 0xf9, 0x84, 0x24, 0x04, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x40, 0x40, 0x00, 0x34, 0x00, 0x40, 0x18, 0x21, 0x30, 0x00, 0x00, 0x14,
- 0x8b, 0x85, 0x8f, 0xcc, 0xcc, 0x07, 0x3c, 0xcd, 0xcc, 0xe7, 0x34, 0xb0, 0x00,
- 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x82, 0xac, 0xb0, 0x00, 0x83,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x65, 0x00, 0x19, 0x00, 0x47, 0x00,
- 0x10, 0x48, 0x00, 0x00, 0x02, 0x11, 0x09, 0x00, 0x23, 0x18, 0x62, 0x00, 0xb0,
- 0x00, 0x83, 0xac, 0xa8, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00,
- 0x82, 0xac, 0xa8, 0x00, 0x83, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x65,
- 0x00, 0x19, 0x00, 0x47, 0x00, 0x10, 0x48, 0x00, 0x00, 0x02, 0x11, 0x09, 0x00,
- 0x23, 0x18, 0x62, 0x00, 0xa8, 0x00, 0x83, 0xac, 0xc0, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0xc4, 0x00, 0x82, 0xac, 0xc0, 0x00, 0x83, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x10, 0x65, 0x00, 0x19, 0x00, 0x47, 0x00, 0x10, 0x48, 0x00,
- 0x00, 0x02, 0x11, 0x09, 0x00, 0x23, 0x18, 0x62, 0x00, 0xc0, 0x00, 0x83, 0xac,
- 0xb8, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x82, 0xac, 0xb8,
- 0x00, 0x83, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x65, 0x00, 0x19, 0x00,
- 0x47, 0x00, 0x10, 0x48, 0x00, 0x00, 0x02, 0x11, 0x09, 0x00, 0x23, 0x18, 0x62,
- 0x00, 0xb8, 0x00, 0x83, 0xac, 0x01, 0x00, 0xc6, 0x24, 0x2a, 0x10, 0xc8, 0x00,
- 0xd1, 0xff, 0x40, 0x14, 0x68, 0x01, 0x84, 0x24, 0x18, 0x00, 0xbf, 0x8f, 0x20,
- 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x00, 0xa0, 0x08,
- 0x3c, 0x00, 0x10, 0x08, 0x35, 0x21, 0x38, 0x00, 0x00, 0x20, 0x8c, 0x89, 0x27,
- 0x80, 0x10, 0x07, 0x00, 0xac, 0x22, 0x00, 0x08, 0x21, 0x30, 0x49, 0x00, 0x07,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x60, 0x00, 0x00, 0x00,
- 0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x68, 0x00, 0xf9, 0xff, 0x40,
- 0x10, 0x2b, 0x10, 0x64, 0x00, 0x07, 0x00, 0x64, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x17, 0x00, 0xa7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0xbd, 0x22, 0x00, 0x08, 0x00, 0x00, 0xc2, 0xac, 0x01, 0x00,
- 0xe7, 0x24, 0x07, 0x00, 0xe2, 0x28, 0xeb, 0xff, 0x40, 0x14, 0x80, 0x10, 0x07,
- 0x00, 0x80, 0x10, 0x05, 0x00, 0x20, 0x8c, 0x83, 0x27, 0xc4, 0x22, 0x00, 0x08,
- 0x21, 0x30, 0x43, 0x00, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x30, 0x60, 0x00, 0x00, 0x00, 0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10,
- 0x68, 0x00, 0xf9, 0xff, 0x40, 0x10, 0x2b, 0x10, 0x64, 0x00, 0x00, 0x00, 0x83,
- 0xac, 0x00, 0x00, 0xc4, 0xac, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0x90, 0x85, 0x27, 0x50, 0x90, 0x80, 0xaf, 0x00, 0x80, 0x02, 0x3c, 0xfc,
- 0x34, 0x42, 0x24, 0x01, 0x80, 0x01, 0x3c, 0xa4, 0xf0, 0x22, 0xac, 0x01, 0x80,
- 0x04, 0x3c, 0xa8, 0xf0, 0x84, 0x24, 0x01, 0x80, 0x01, 0x3c, 0xa8, 0xf0, 0x20,
- 0xac, 0x00, 0x80, 0x02, 0x3c, 0x2c, 0x35, 0x42, 0x24, 0x01, 0x80, 0x01, 0x3c,
- 0xac, 0xf0, 0x22, 0xac, 0x01, 0x80, 0x03, 0x3c, 0xb0, 0xf0, 0x63, 0x24, 0x01,
- 0x80, 0x01, 0x3c, 0xb0, 0xf0, 0x20, 0xac, 0x00, 0x80, 0x02, 0x3c, 0x5c, 0x35,
- 0x42, 0x24, 0x01, 0x80, 0x01, 0x3c, 0xb4, 0xf0, 0x22, 0xac, 0x20, 0x8c, 0x85,
- 0xaf, 0x01, 0x80, 0x01, 0x3c, 0x78, 0xec, 0x24, 0xac, 0x01, 0x80, 0x01, 0x3c,
- 0x74, 0xec, 0x24, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x88, 0xec, 0x23, 0xac, 0x01,
- 0x80, 0x01, 0x3c, 0x84, 0xec, 0x23, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x80, 0xec,
- 0x23, 0xac, 0x01, 0x80, 0x01, 0x3c, 0x08, 0x00, 0xe0, 0x03, 0x7c, 0xec, 0x23,
- 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x48, 0x00, 0x83, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x19, 0x03, 0x00, 0x00, 0x00, 0xa2, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x80, 0x00, 0x42, 0x34, 0x00, 0x00, 0xa2,
- 0xa0, 0x00, 0x00, 0xa3, 0x90, 0xc3, 0xa5, 0x02, 0x34, 0x23, 0x10, 0x43, 0x00,
- 0x01, 0x00, 0xa3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x23,
- 0x10, 0x43, 0x00, 0x23, 0x10, 0x46, 0x00, 0x02, 0x00, 0xa2, 0xa0, 0x02, 0x12,
- 0x02, 0x00, 0x03, 0x00, 0xa2, 0xa0, 0x04, 0x00, 0x84, 0x8c, 0x7c, 0x32, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27,
- 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x1c,
- 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00,
- 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x04, 0x00, 0x12, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x02, 0x00,
- 0x1c, 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x43, 0x00, 0x20,
- 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x42, 0x30, 0x09, 0x00,
- 0x03, 0x24, 0x09, 0x00, 0x43, 0x14, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00, 0xa2,
- 0xac, 0x05, 0x00, 0x02, 0x24, 0x24, 0x00, 0xa2, 0xa0, 0x50, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0xa2, 0xa0, 0x52, 0x23, 0x00, 0x08, 0x24,
- 0x00, 0xa5, 0x24, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x42, 0x30, 0x14, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00, 0xa2,
- 0xac, 0x06, 0x00, 0x02, 0x24, 0x24, 0x00, 0xa2, 0xa0, 0x25, 0x00, 0xa0, 0xa0,
- 0x21, 0x20, 0x00, 0x02, 0x24, 0x00, 0xa5, 0x24, 0xf4, 0x22, 0x00, 0x0c, 0x04,
- 0x00, 0x06, 0x24, 0x20, 0x00, 0x03, 0x8e, 0x07, 0xff, 0x02, 0x24, 0x24, 0x20,
- 0x62, 0x00, 0x20, 0x00, 0x04, 0xae, 0x3c, 0x00, 0x03, 0x8e, 0x38, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x62, 0x10, 0x08, 0x00, 0x82, 0x34,
- 0xce, 0x23, 0x00, 0x08, 0x20, 0x00, 0x02, 0xae, 0x20, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x00, 0x42, 0x30, 0x0a, 0x00, 0x03, 0x24, 0x16, 0x00,
- 0x43, 0x14, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00, 0xa2, 0xac, 0x0a, 0x00, 0x02,
- 0x24, 0x24, 0x00, 0xa2, 0xa0, 0x30, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x00, 0xa2, 0xa0, 0x21, 0x20, 0x00, 0x02, 0x24, 0x00, 0xa5, 0x24, 0xf4,
- 0x22, 0x00, 0x0c, 0x04, 0x00, 0x06, 0x24, 0x20, 0x00, 0x02, 0x8e, 0xf7, 0xff,
- 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0x02, 0xae, 0xbc, 0x8b, 0x82,
- 0x8f, 0x74, 0x00, 0x45, 0x8e, 0x6c, 0x00, 0x04, 0x26, 0x6d, 0x2a, 0x00, 0x0c,
- 0x21, 0x28, 0x45, 0x00, 0xce, 0x23, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x42, 0x30, 0x1b, 0x00,
- 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00, 0xa2, 0xac, 0x20, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10,
- 0x09, 0x00, 0x03, 0x24, 0x0b, 0x00, 0x03, 0x24, 0x24, 0x00, 0xa3, 0xa0, 0x30,
- 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0xa2, 0xa0, 0x21, 0x20,
- 0x00, 0x02, 0x24, 0x00, 0xa5, 0x24, 0xf4, 0x22, 0x00, 0x0c, 0x04, 0x00, 0x06,
- 0x24, 0x20, 0x00, 0x03, 0x8e, 0x1f, 0xff, 0x02, 0x24, 0x24, 0x20, 0x62, 0x00,
- 0x20, 0x00, 0x04, 0xae, 0x3c, 0x00, 0x03, 0x8e, 0x38, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x00, 0x62, 0x14, 0xf7, 0xff, 0x02, 0x24, 0xcd, 0x23,
- 0x00, 0x08, 0x24, 0x10, 0x82, 0x00, 0x3c, 0x00, 0x03, 0x8e, 0x38, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x62, 0x10, 0x07, 0x00, 0x02, 0x24,
- 0x18, 0x00, 0x11, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x22, 0xa2, 0x3c,
- 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x30, 0x00,
- 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x0d, 0x00, 0x22,
- 0xa2, 0x03, 0x00, 0x02, 0x24, 0x18, 0x00, 0xa2, 0xac, 0x1c, 0x00, 0xb1, 0xac,
- 0x04, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x04,
- 0x00, 0x22, 0xae, 0x21, 0x20, 0x00, 0x02, 0x08, 0x00, 0x26, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xf4, 0x22, 0x00, 0x0c, 0x0c, 0x00, 0x25, 0x26, 0x3c, 0x00, 0x03,
- 0x8e, 0x34, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x14,
- 0x6c, 0x00, 0x04, 0x26, 0xbc, 0x8b, 0x82, 0x8f, 0x74, 0x00, 0x45, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x6d, 0x2a, 0x00, 0x0c, 0x21, 0x28, 0x45, 0x00, 0x3c, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42,
- 0x30, 0x3c, 0x00, 0x02, 0xae, 0x00, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x02, 0xae, 0x3c, 0x00, 0x03, 0x8e, 0x38, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x62, 0x14, 0xf7, 0xff, 0x03, 0x24, 0x20, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x43, 0x00, 0x04, 0x00, 0x42,
- 0x30, 0x06, 0x00, 0x40, 0x10, 0x20, 0x00, 0x03, 0xae, 0xfb, 0xff, 0x02, 0x24,
- 0x24, 0x10, 0x62, 0x00, 0x20, 0x00, 0x02, 0xae, 0x39, 0x2a, 0x00, 0x0c, 0xd0,
- 0x00, 0x44, 0x26, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x23,
- 0x00, 0x08, 0x7f, 0xff, 0x03, 0x24, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00, 0xa2,
- 0xac, 0x08, 0x00, 0x02, 0x24, 0x24, 0x00, 0xa2, 0xa0, 0x30, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0xa2, 0xa0, 0x21, 0x20, 0x00, 0x02, 0x24,
- 0x00, 0xa5, 0x24, 0xf4, 0x22, 0x00, 0x0c, 0x04, 0x00, 0x06, 0x24, 0x20, 0x00,
- 0x02, 0x8e, 0x77, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0x02,
- 0xae, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x20,
- 0x00, 0xa2, 0x28, 0x1a, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x22, 0x33,
- 0x0b, 0x3c, 0x00, 0x11, 0x6b, 0x35, 0x66, 0x77, 0x0a, 0x3c, 0x44, 0x55, 0x4a,
- 0x35, 0xaa, 0xbb, 0x09, 0x3c, 0x88, 0x99, 0x29, 0x35, 0xee, 0xff, 0x08, 0x3c,
- 0xcc, 0xdd, 0x08, 0x35, 0xa5, 0xa5, 0x07, 0x3c, 0xa5, 0xa5, 0xe7, 0x34, 0xf0,
- 0xf0, 0x06, 0x3c, 0xf0, 0xf0, 0xc6, 0x34, 0xff, 0xff, 0x03, 0x24, 0x00, 0x00,
- 0x8b, 0xac, 0x04, 0x00, 0x8a, 0xac, 0x08, 0x00, 0x89, 0xac, 0x0c, 0x00, 0x88,
- 0xac, 0x10, 0x00, 0x80, 0xac, 0x14, 0x00, 0x87, 0xac, 0x18, 0x00, 0x86, 0xac,
- 0x1c, 0x00, 0x83, 0xac, 0xe0, 0xff, 0xa5, 0x24, 0x20, 0x00, 0xa2, 0x28, 0xf5,
- 0xff, 0x40, 0x10, 0x20, 0x00, 0x84, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0xa0, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40,
- 0x14, 0x20, 0x00, 0xa2, 0x28, 0x2a, 0x24, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00,
- 0x30, 0x00, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, 0x22, 0x33, 0x0b, 0x3c, 0x00,
- 0x11, 0x6b, 0x35, 0x66, 0x77, 0x0a, 0x3c, 0x44, 0x55, 0x4a, 0x35, 0xaa, 0xbb,
- 0x09, 0x3c, 0x88, 0x99, 0x29, 0x35, 0xee, 0xff, 0x08, 0x3c, 0xcc, 0xdd, 0x08,
- 0x35, 0xa5, 0xa5, 0x07, 0x3c, 0xa5, 0xa5, 0xe7, 0x34, 0xf0, 0xf0, 0x06, 0x3c,
- 0xf0, 0xf0, 0xc6, 0x34, 0x00, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x26,
- 0x10, 0x4b, 0x00, 0x25, 0x18, 0x62, 0x00, 0x04, 0x00, 0x82, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x26, 0x10, 0x4a, 0x00, 0x25, 0x18, 0x62, 0x00, 0x08, 0x00, 0x82,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x49, 0x00, 0x25, 0x18, 0x62, 0x00,
- 0x0c, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x48, 0x00, 0x25,
- 0x18, 0x62, 0x00, 0x10, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x25, 0x18,
- 0x62, 0x00, 0x14, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x47,
- 0x00, 0x25, 0x18, 0x62, 0x00, 0x18, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x26, 0x10, 0x46, 0x00, 0x25, 0x18, 0x62, 0x00, 0x1c, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x27, 0x10, 0x02, 0x00, 0x25, 0x18, 0x62, 0x00, 0xe0, 0xff,
- 0xa5, 0x24, 0x20, 0x00, 0xa2, 0x28, 0xde, 0xff, 0x40, 0x10, 0x20, 0x00, 0x84,
- 0x24, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10,
- 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x40, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x11, 0x02, 0x00, 0x1c, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x01, 0x00, 0x03, 0x24, 0x18, 0x00, 0x43, 0xac,
- 0x01, 0x80, 0x04, 0x3c, 0x54, 0xfb, 0x84, 0x24, 0x00, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x23,
- 0x00, 0x0c, 0x3c, 0x1f, 0x05, 0x24, 0xa8, 0x89, 0x84, 0x8f, 0xa4, 0x89, 0x90,
- 0x8f, 0x80, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x64, 0x00,
- 0x03, 0x00, 0x40, 0x10, 0x04, 0x00, 0x82, 0x28, 0x21, 0x20, 0x60, 0x00, 0x04,
- 0x00, 0x82, 0x28, 0x02, 0x00, 0x40, 0x10, 0x04, 0x00, 0x02, 0x2a, 0x04, 0x00,
- 0x04, 0x24, 0x03, 0x00, 0x40, 0x10, 0x2a, 0x10, 0x90, 0x00, 0x04, 0x00, 0x10,
- 0x24, 0x2a, 0x10, 0x90, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x80, 0x80, 0x00, 0x23, 0x20, 0x90, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x01,
- 0x00, 0x84, 0x24, 0x21, 0x20, 0x20, 0x02, 0x01, 0x80, 0x05, 0x3c, 0x54, 0xfb,
- 0xa5, 0x24, 0x7c, 0x32, 0x00, 0x0c, 0x21, 0x30, 0x02, 0x02, 0x18, 0x00, 0xbf,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x20, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x24, 0x00, 0xbf, 0xaf, 0x20,
- 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00,
- 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x00, 0xa0, 0x03,
- 0x3c, 0xd4, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x04, 0x00, 0x33, 0x8e, 0x3c,
- 0x00, 0x22, 0x8e, 0x34, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0xa0,
- 0x43, 0x00, 0x21, 0x90, 0x60, 0x00, 0x38, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x42, 0x12, 0x0f, 0x00, 0x94, 0x32, 0x10, 0x00, 0x30, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x22, 0xae, 0x34, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10,
- 0x42, 0x02, 0x0f, 0x00, 0x42, 0x30, 0x2a, 0x10, 0x54, 0x00, 0x08, 0x00, 0x40,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0xfc, 0xff, 0x42, 0x24, 0x08, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x10, 0x43, 0x00, 0x84, 0x00, 0x62, 0xae, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x0a, 0x00, 0x42, 0x2c, 0x04, 0x00, 0x40,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c,
- 0x4f, 0x02, 0x05, 0x24, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x42, 0x24, 0x09, 0x00, 0x40, 0x14, 0x04, 0x00, 0x02, 0xae, 0xb0, 0x90,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xae, 0xb0, 0x90, 0x90,
- 0xaf, 0x64, 0x00, 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
- 0x64, 0x00, 0x62, 0xae, 0x01, 0x00, 0x42, 0x26, 0x0f, 0x00, 0x52, 0x30, 0x38,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xff, 0x42, 0x16, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c,
- 0x59, 0x02, 0x05, 0x24, 0x18, 0x00, 0x20, 0xae, 0x10, 0x00, 0x22, 0x26, 0x14,
- 0x00, 0x22, 0xae, 0x78, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
- 0x60, 0x10, 0x01, 0x00, 0x05, 0x24, 0x02, 0x00, 0x04, 0x24, 0x10, 0x00, 0x62,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x45, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x51, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x64, 0xac, 0x00, 0x00, 0x63, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0xf4, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x20,
- 0xae, 0x3c, 0x00, 0x20, 0xae, 0x34, 0x00, 0x20, 0xae, 0x30, 0x00, 0x20, 0xae,
- 0x20, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x30, 0x05,
- 0x00, 0x40, 0x10, 0xfb, 0xff, 0x02, 0x24, 0x24, 0x10, 0x62, 0x00, 0x20, 0x00,
- 0x22, 0xae, 0x39, 0x2a, 0x00, 0x0c, 0xd0, 0x00, 0x64, 0x26, 0x20, 0x00, 0x22,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae,
- 0x59, 0x2a, 0x00, 0x0c, 0x6c, 0x00, 0x24, 0x26, 0x39, 0x2a, 0x00, 0x0c, 0x54,
- 0x00, 0x24, 0x26, 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00,
- 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27,
- 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0x21, 0x88, 0xa0, 0x00, 0x20, 0x00, 0x02, 0x8e, 0x0d, 0xff,
- 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x09, 0x00, 0x42, 0x34, 0x61, 0x24, 0x00,
- 0x0c, 0x20, 0x00, 0x02, 0xae, 0x50, 0x00, 0x11, 0xae, 0x04, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x34, 0x2c, 0x00, 0x62, 0xac, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xd0, 0xff, 0xbd, 0x27, 0x28, 0x00, 0xbf, 0xaf, 0x24, 0x00, 0xb5, 0xaf,
- 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14,
- 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x21, 0x98,
- 0xa0, 0x00, 0x04, 0x00, 0x32, 0x8e, 0x08, 0x00, 0x75, 0x8e, 0x14, 0x00, 0x64,
- 0x8e, 0x00, 0x00, 0xa2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x30,
- 0x03, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x81, 0x26, 0x00, 0x08, 0x7c,
- 0x0d, 0x42, 0x34, 0x2c, 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,
- 0x62, 0x30, 0x09, 0x00, 0x40, 0x10, 0x0f, 0xff, 0x02, 0x24, 0x24, 0x18, 0x62,
- 0x00, 0x2c, 0x00, 0x43, 0xae, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x78, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x01, 0x00, 0x62, 0x34, 0x2c,
- 0x00, 0x42, 0xae, 0x00, 0x00, 0xa2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
- 0x42, 0x30, 0xfb, 0xff, 0x43, 0x24, 0x07, 0x00, 0x62, 0x2c, 0x49, 0x00, 0x40,
- 0x10, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00,
- 0xe0, 0xd9, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x24, 0x57, 0x01, 0x82, 0x14, 0x00, 0xa0,
- 0x02, 0x3c, 0xcc, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac, 0x20, 0x00, 0x22, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0e, 0x00, 0x40, 0x10, 0xfd,
- 0xff, 0x03, 0x24, 0xcc, 0x00, 0x40, 0xae, 0x59, 0x2a, 0x00, 0x0c, 0x6c, 0x00,
- 0x24, 0x26, 0x20, 0x00, 0x22, 0x8e, 0xfe, 0xff, 0x03, 0x24, 0x24, 0x18, 0x43,
- 0x00, 0x08, 0x00, 0x42, 0x30, 0x4d, 0x01, 0x40, 0x10, 0x20, 0x00, 0x23, 0xae,
- 0xf7, 0xff, 0x02, 0x24, 0x24, 0x10, 0x62, 0x00, 0x70, 0x26, 0x00, 0x08, 0x10,
- 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10,
- 0x43, 0x00, 0x18, 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00, 0x42, 0xae,
- 0x61, 0x24, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x89, 0x26, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x24, 0x30, 0x01, 0x82, 0x14, 0x00, 0xa0,
- 0x02, 0x3c, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x30, 0xb1, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0xcc, 0x00, 0x40, 0xae,
- 0x59, 0x2a, 0x00, 0x0c, 0x6c, 0x00, 0x24, 0x26, 0x20, 0x00, 0x22, 0x8e, 0xf6,
- 0xff, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x89, 0x26, 0x00, 0x08, 0x20, 0x00,
- 0x22, 0xae, 0x04, 0x00, 0x02, 0x24, 0x20, 0x01, 0x82, 0x14, 0x00, 0xa0, 0x02,
- 0x3c, 0x6c, 0x25, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x82, 0x24,
- 0xe9, 0x13, 0x42, 0x2c, 0x1a, 0x01, 0x40, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x6c,
- 0x25, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c,
- 0x00, 0x0c, 0x5a, 0x03, 0x05, 0x24, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x30, 0x19, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0xa2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x45, 0x30, 0xff,
- 0x00, 0xa3, 0x30, 0x34, 0x00, 0x24, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18,
- 0x64, 0x00, 0x0f, 0x00, 0x63, 0x30, 0x3c, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x10, 0x44, 0x00, 0x0f, 0x00, 0x42, 0x30, 0x2a, 0x10, 0x43, 0x00,
- 0x0b, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0xc0, 0x0d, 0x63, 0x34, 0x00,
- 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00,
- 0x62, 0xac, 0x21, 0x20, 0x20, 0x02, 0xe1, 0x24, 0x00, 0x0c, 0x03, 0x00, 0x05,
- 0x24, 0x89, 0x26, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xa3, 0x30,
- 0x34, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x43, 0x10, 0xff,
- 0x00, 0xb4, 0x30, 0xcc, 0x00, 0x40, 0xae, 0x10, 0x00, 0x30, 0x8e, 0x34, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42,
- 0x30, 0x34, 0x00, 0x22, 0xae, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x22, 0xae, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x42, 0x24, 0x0a, 0x00, 0x42, 0x2c, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x95, 0x03, 0x05,
- 0x24, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24,
- 0x09, 0x00, 0x40, 0x14, 0x04, 0x00, 0x02, 0xae, 0xb0, 0x90, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xae, 0xb0, 0x90, 0x90, 0xaf, 0x64, 0x00,
- 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x64, 0x00, 0x42,
- 0xae, 0x34, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xde, 0xff, 0x54, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x40, 0x14, 0x10, 0x00, 0x22, 0x26, 0x14, 0x00, 0x22, 0xae, 0x20, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x0f, 0x00, 0x40,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x23, 0x8e, 0x34, 0x00, 0x22, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x62, 0x14, 0x6c, 0x00, 0x24, 0x26, 0x59,
- 0x2a, 0x00, 0x0c, 0x6c, 0x00, 0x24, 0x26, 0xcb, 0x25, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0x74, 0x00, 0x45, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x6d, 0x2a, 0x00, 0x0c, 0x21, 0x28, 0x45, 0x00, 0x00, 0x00, 0xa2, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x43, 0x30, 0x09, 0x00, 0x02, 0x24, 0x0e,
- 0x00, 0x62, 0x10, 0x0a, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10, 0x07, 0x00,
- 0x02, 0x24, 0x61, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x89, 0x26, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x24, 0x18, 0x00, 0x62, 0x10,
- 0x0b, 0x00, 0x02, 0x24, 0x25, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x89,
- 0x26, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x24, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x82, 0x30, 0x0d, 0x00, 0x40, 0x14, 0x00, 0xa0, 0x02,
- 0x3c, 0x3c, 0x00, 0x23, 0x8e, 0x38, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x07, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x82, 0x34, 0x20,
- 0x00, 0x22, 0xae, 0x2c, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x34, 0x2c, 0x00, 0x42, 0xae, 0x00, 0xa0, 0x02, 0x3c, 0x81, 0x26, 0x00,
- 0x08, 0xf0, 0x0d, 0x42, 0x34, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x42, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00, 0x42, 0xae, 0x00, 0xa0,
- 0x03, 0x3c, 0xf4, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x85, 0x26, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac,
- 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x08,
- 0x00, 0x40, 0x14, 0xf5, 0xff, 0x03, 0x24, 0x00, 0xa0, 0x03, 0x3c, 0xec, 0x0d,
- 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0x89, 0x26, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0xcc, 0x00, 0x40, 0xae,
- 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x20,
- 0x00, 0x22, 0xae, 0x10, 0x00, 0x30, 0x8e, 0x18, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x0d, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x24, 0x08, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x84, 0x00, 0x42, 0xae, 0x00,
- 0x00, 0x10, 0x8e, 0x18, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xff,
- 0x02, 0x16, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x3c, 0x00, 0x22, 0xae, 0x10, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x22, 0xae, 0x34, 0x00, 0x23, 0x8e, 0x38, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x70, 0x26, 0x00, 0x08, 0x08, 0x00, 0x42,
- 0x34, 0x59, 0x2a, 0x00, 0x0c, 0x6c, 0x00, 0x24, 0x26, 0x89, 0x26, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x21, 0x02, 0x00, 0xff, 0x00, 0x83, 0x30, 0x30, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x2a, 0x00, 0x62, 0x14, 0xff, 0x00, 0x82, 0x30, 0x01, 0x00, 0x02,
- 0x24, 0x10, 0x00, 0x62, 0xae, 0x04, 0x00, 0x71, 0xae, 0x00, 0x00, 0x60, 0xae,
- 0x78, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x90, 0x90, 0x84, 0x27, 0x39, 0x2a, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0xa8, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
- 0xac, 0xa8, 0x90, 0x93, 0xaf, 0x30, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42, 0x30, 0x30, 0x00, 0x22, 0xae, 0x20,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x30, 0x05, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x89, 0x26, 0x00, 0x08, 0x28, 0x00, 0x22, 0xae, 0x20, 0x00, 0x22, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae, 0x74,
- 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x10, 0x02, 0x00, 0xbc, 0x8b,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x89, 0x26, 0x00,
- 0x08, 0x28, 0x00, 0x22, 0xae, 0x30, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x10, 0x43, 0x00, 0x0f, 0x00, 0x42, 0x30, 0x05, 0x00, 0x42, 0x28, 0x0a,
- 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x89, 0x26, 0x00, 0x08,
- 0x2c, 0x00, 0x42, 0xae, 0xc4, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x21, 0x20,
- 0x20, 0x02, 0xe1, 0x24, 0x00, 0x0c, 0x04, 0x00, 0x05, 0x24, 0x89, 0x26, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac, 0xc8,
- 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xc8, 0x00,
- 0x42, 0xae, 0x28, 0x00, 0xbf, 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20, 0x00, 0xb4,
- 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0xd0,
- 0xff, 0xbd, 0x27, 0x2c, 0x00, 0xbf, 0xaf, 0x28, 0x00, 0xb6, 0xaf, 0x24, 0x00,
- 0xb5, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2,
- 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0xa0, 0x80, 0x00,
- 0x21, 0xa8, 0xa0, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x90, 0x82, 0xaf, 0x08, 0x00, 0xb3, 0x8e, 0x14, 0x00, 0xb6, 0x8e, 0x7c, 0x00,
- 0x83, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x60, 0x10, 0x2a, 0x10, 0xc3,
- 0x02, 0x60, 0x00, 0x40, 0x14, 0x23, 0x10, 0x76, 0x00, 0x07, 0x27, 0x00, 0x08,
- 0x21, 0x10, 0x00, 0x00, 0x70, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x29,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x64, 0x00,
- 0x04, 0x24, 0x70, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43,
- 0x00, 0x22, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x02, 0x00, 0x04, 0x24, 0x21,
- 0x88, 0x40, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x08, 0x00, 0x04, 0x24, 0x21, 0x80,
- 0x40, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x02, 0x00, 0x04, 0x24, 0x21, 0x88, 0x71,
- 0x02, 0x80, 0x10, 0x02, 0x00, 0x04, 0x80, 0x50, 0x00, 0x00, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x50, 0x00, 0x00, 0x00, 0x22, 0xa2, 0x00,
- 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x43, 0x30, 0x01, 0x00,
- 0x02, 0x24, 0x05, 0x00, 0x62, 0x14, 0x0f, 0x00, 0x42, 0x32, 0x04, 0x00, 0x43,
- 0x10, 0x00, 0xa0, 0x03, 0x3c, 0xd6, 0x26, 0x00, 0x08, 0x00, 0x00, 0x72, 0xa2,
- 0x00, 0xa0, 0x03, 0x3c, 0xdc, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x00, 0x00,
- 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x43, 0x30, 0x41, 0x00, 0x60,
- 0x10, 0x05, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10, 0x21, 0x20, 0x80, 0x02,
- 0xe2, 0x1f, 0x00, 0x0c, 0x21, 0x28, 0xa0, 0x02, 0x25, 0x27, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x62, 0x28, 0x38, 0x00, 0x40, 0x10, 0xc3, 0xa5,
- 0x02, 0x34, 0x02, 0x00, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00, 0x23, 0x90, 0x43,
- 0x00, 0x00, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, 0x23, 0x90, 0x42, 0x02,
- 0x01, 0x00, 0x62, 0x92, 0x03, 0x00, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x00, 0x12, 0x02, 0x00, 0x23, 0x90, 0x42, 0x02, 0xff, 0xff,
- 0x52, 0x32, 0x17, 0x00, 0x56, 0x12, 0x00, 0x00, 0x00, 0x00, 0x70, 0x90, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x40, 0x14, 0x00, 0xa0, 0x03, 0x3c,
- 0xac, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0xc8, 0x00, 0x82, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xc8, 0x00, 0x82, 0xae, 0x14, 0x00, 0xa5,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0xb2, 0x00, 0x21, 0x00, 0x40, 0x10,
- 0xa0, 0x0f, 0x42, 0x2a, 0x1f, 0x00, 0x40, 0x10, 0x23, 0x10, 0x45, 0x02, 0x25,
- 0x27, 0x00, 0x08, 0x7c, 0x00, 0x82, 0xae, 0x00, 0x00, 0x62, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x11, 0x02, 0x00, 0x07, 0x00, 0x52, 0x30, 0x30, 0x8e, 0x84,
- 0x27, 0x48, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x42, 0x16,
- 0x00, 0x00, 0x00, 0x00, 0xf9, 0x24, 0x00, 0x0c, 0x21, 0x28, 0xa0, 0x02, 0x25,
- 0x27, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x80, 0x02, 0xd0, 0x1f,
- 0x00, 0x0c, 0x21, 0x28, 0xa0, 0x02, 0x25, 0x27, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xa0, 0x02, 0x3c, 0xb8, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac, 0xc8,
- 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xc8, 0x00,
- 0x82, 0xae, 0x2c, 0x00, 0xbf, 0x8f, 0x28, 0x00, 0xb6, 0x8f, 0x24, 0x00, 0xb5,
- 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30,
- 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00,
- 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x78, 0x90, 0x91, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x90, 0x82, 0xaf,
- 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x78, 0x90, 0x82, 0x27, 0xa8,
- 0x90, 0x82, 0xaf, 0x10, 0x00, 0x23, 0x8e, 0x01, 0x00, 0x02, 0x24, 0x24, 0x00,
- 0x62, 0x14, 0x02, 0x00, 0x02, 0x24, 0xb8, 0x8e, 0x84, 0x8f, 0x37, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x44, 0x8c, 0x08, 0x00, 0x23, 0x8e, 0x14, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x80, 0x62, 0x00, 0xfd, 0xff, 0x02, 0x3c, 0x00, 0xff,
- 0x42, 0x34, 0x21, 0x80, 0x02, 0x02, 0x20, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x80, 0x02, 0x02, 0x06, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x05, 0x3c,
- 0x00, 0x01, 0xa5, 0x34, 0x21, 0x20, 0x40, 0x00, 0x21, 0x28, 0x45, 0x00, 0x70,
- 0x11, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x02, 0x08, 0x00, 0x25, 0x8e, 0x14, 0x00,
- 0x26, 0x8e, 0x04, 0x00, 0x24, 0x8e, 0x04, 0x00, 0xa5, 0x24, 0xac, 0x1b, 0x00,
- 0x0c, 0xfc, 0xff, 0xc6, 0x24, 0xc4, 0x8f, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x80, 0x40, 0x00, 0x69, 0x27, 0x00, 0x08, 0x10,
- 0x00, 0x20, 0xae, 0x04, 0x00, 0x62, 0x10, 0x21, 0x80, 0x00, 0x00, 0xac, 0x89,
- 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x1e, 0x05, 0x05, 0x24, 0x10, 0x00, 0x20,
- 0xae, 0x00, 0xa0, 0x03, 0x3c, 0x74, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x0b, 0x00, 0x00, 0x12, 0x00,
- 0x00, 0x62, 0xac, 0x00, 0xa0, 0x03, 0x3c, 0xc8, 0x0d, 0x63, 0x34, 0x00, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62,
- 0xac, 0x04, 0x00, 0x24, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x24, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x02, 0x78, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x84, 0x27, 0x39, 0x2a,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27,
- 0xe8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0xf0,
- 0x1c, 0x00, 0x0c, 0x21, 0x80, 0x80, 0x00, 0x20, 0x00, 0x02, 0x8e, 0xff, 0xfe,
- 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0x02, 0xae, 0x14, 0x00, 0xbf,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27,
- 0xd8, 0xff, 0xbd, 0x27, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c,
- 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00,
- 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x04, 0x00, 0x13, 0x8e, 0x20, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x42, 0x30, 0xdc, 0x00, 0x40, 0x14,
- 0x21, 0x10, 0x00, 0x00, 0x38, 0x00, 0x02, 0x8e, 0x34, 0x00, 0x03, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x0f, 0x00, 0x42, 0x30, 0x05, 0x00,
- 0x42, 0x28, 0x19, 0x00, 0x40, 0x14, 0x80, 0x00, 0x02, 0x24, 0x20, 0x00, 0x04,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x83, 0x30, 0xcf, 0x00, 0x62, 0x14,
- 0x21, 0x10, 0x00, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0x28, 0x00, 0x03, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0xff, 0x3f, 0x03, 0x3c, 0xff, 0xff,
- 0x63, 0x34, 0x2b, 0x18, 0x62, 0x00, 0xc6, 0x00, 0x60, 0x14, 0x21, 0x10, 0x00,
- 0x00, 0x08, 0x00, 0x82, 0x34, 0x20, 0x00, 0x02, 0xae, 0x2c, 0x00, 0x62, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00, 0x62, 0xae, 0x1b,
- 0x1f, 0x00, 0x0c, 0x21, 0x20, 0x60, 0x02, 0x7c, 0x28, 0x00, 0x08, 0x21, 0x10,
- 0x00, 0x00, 0xb0, 0x90, 0x92, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x90, 0x82, 0xaf, 0x00, 0x00, 0x40, 0xae,
- 0x04, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x76, 0x05,
- 0x05, 0x24, 0xb8, 0x8e, 0x84, 0x8f, 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x20, 0x00, 0x02, 0x80, 0x00, 0x66, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0xdb, 0x16, 0x00, 0x0c, 0x10, 0x00, 0x45, 0x26, 0x21, 0xa0, 0x40, 0x00, 0x90,
- 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x82,
- 0x02, 0x1a, 0x00, 0x40, 0x10, 0x21, 0x10, 0x54, 0x02, 0xfe, 0x00, 0x03, 0x24,
- 0x10, 0x00, 0x43, 0xa0, 0x98, 0x89, 0x84, 0x8f, 0x94, 0x89, 0x91, 0x8f, 0x80,
- 0x00, 0x63, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x64, 0x00, 0x03, 0x00,
- 0x40, 0x10, 0x2a, 0x10, 0x94, 0x00, 0x21, 0x20, 0x60, 0x00, 0x2a, 0x10, 0x94,
- 0x00, 0x02, 0x00, 0x40, 0x10, 0x2a, 0x10, 0x34, 0x02, 0x21, 0x20, 0x80, 0x02,
- 0x03, 0x00, 0x40, 0x10, 0x2a, 0x10, 0x91, 0x00, 0x21, 0x88, 0x80, 0x02, 0x2a,
- 0x10, 0x91, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x88,
- 0x80, 0x00, 0x23, 0x20, 0x91, 0x00, 0x20, 0x21, 0x00, 0x0c, 0x01, 0x00, 0x84,
- 0x24, 0x21, 0xa0, 0x22, 0x02, 0xc4, 0x8f, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x74, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x10, 0x54, 0x00, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89,
- 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x93, 0x05, 0x05, 0x24, 0x20, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x07, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0xb0, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x42, 0xae, 0xb0, 0x90, 0x92, 0xaf, 0x7c, 0x28, 0x00, 0x08, 0x21, 0x10,
- 0x80, 0x02, 0x2a, 0x00, 0x80, 0x16, 0xff, 0x3f, 0x06, 0x3c, 0xbc, 0x8b, 0x85,
- 0x8f, 0x2c, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0xa2, 0x00,
- 0xff, 0xff, 0xc6, 0x34, 0x2b, 0x10, 0xc2, 0x00, 0x20, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x42, 0x30, 0x1b, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x90, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xae, 0xb0, 0x90, 0x92, 0xaf,
- 0x20, 0x00, 0x04, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x83, 0x30, 0x80,
- 0x00, 0x02, 0x24, 0x55, 0x00, 0x62, 0x14, 0x21, 0x10, 0x80, 0x02, 0x28, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0xa2, 0x00, 0x2b, 0x10, 0xc2,
- 0x00, 0x4f, 0x00, 0x40, 0x14, 0x21, 0x10, 0x80, 0x02, 0x08, 0x00, 0x82, 0x34,
- 0x20, 0x00, 0x02, 0xae, 0x2c, 0x00, 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x34, 0x2c, 0x00, 0x62, 0xae, 0x1b, 0x1f, 0x00, 0x0c, 0x21, 0x20,
- 0x60, 0x02, 0x7c, 0x28, 0x00, 0x08, 0x21, 0x10, 0x80, 0x02, 0x05, 0x00, 0x80,
- 0x12, 0xff, 0xfd, 0x03, 0x24, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x41, 0x28, 0x00, 0x08, 0x00, 0x02, 0x42, 0x34, 0x20, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0x02, 0xae, 0x04, 0x00,
- 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02,
- 0x24, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0xda, 0x05, 0x05, 0x24,
- 0x01, 0x00, 0x02, 0x24, 0x04, 0x00, 0x42, 0xae, 0x64, 0x00, 0x62, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x64, 0x00, 0x62, 0xae, 0x00, 0xa0,
- 0x03, 0x3c, 0x70, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x04, 0x00, 0x83, 0x26,
- 0x08, 0x00, 0x43, 0xae, 0x84, 0x00, 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x42, 0x24, 0x21, 0x10, 0x43, 0x00, 0x84, 0x00, 0x62, 0xae, 0x14, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xac, 0x14, 0x00, 0x12,
- 0xae, 0x18, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x12, 0xae, 0x38, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42, 0x30, 0x38, 0x00,
- 0x02, 0xae, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13, 0x42,
- 0x24, 0x2c, 0x00, 0x02, 0xae, 0x20, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x62, 0x30, 0x08, 0x00, 0x40, 0x14, 0x08, 0x00, 0x62, 0x34, 0x20,
- 0x00, 0x02, 0xae, 0x2c, 0x00, 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x34, 0x2c, 0x00, 0x62, 0xae, 0x1b, 0x1f, 0x00, 0x0c, 0x21, 0x20, 0x60,
- 0x02, 0x06, 0x00, 0x94, 0x26, 0x21, 0x10, 0x80, 0x02, 0x24, 0x00, 0xbf, 0x8f,
- 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00,
- 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0x11, 0x8e,
- 0x2c, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x42, 0x30, 0x05,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x15, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x89, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x2c, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x62, 0x30, 0x04,
- 0x00, 0x40, 0x14, 0x01, 0x00, 0x62, 0x34, 0x2c, 0x00, 0x02, 0xae, 0x1b, 0x1f,
- 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x2c, 0x00, 0x22, 0xae, 0x28, 0x00, 0x22, 0xae, 0x99, 0x2a, 0x00, 0x0c,
- 0x64, 0x00, 0x04, 0x24, 0x4d, 0x29, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x64,
- 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10, 0x00, 0xa0,
- 0x03, 0x3c, 0xb0, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x20,
- 0x00, 0x24, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x83, 0x30, 0x80, 0x00,
- 0x02, 0x24, 0x11, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x8b, 0x82,
- 0x8f, 0x28, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0xff, 0x3f, 0x03, 0x3c, 0xff, 0xff, 0x63, 0x34, 0x2b, 0x18, 0x62, 0x00, 0x08,
- 0x00, 0x60, 0x14, 0x08, 0x00, 0x82, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00, 0x02,
- 0xae, 0x1b, 0x1f, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x99, 0x2a, 0x00, 0x0c,
- 0x02, 0x00, 0x04, 0x24, 0x4d, 0x29, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x00, 0x23, 0x8e, 0x38, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00,
- 0x62, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x60, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac,
- 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x34, 0x4d,
- 0x29, 0x00, 0x08, 0x20, 0x00, 0x22, 0xae, 0x93, 0x27, 0x00, 0x0c, 0x21, 0x20,
- 0x20, 0x02, 0x21, 0x30, 0x40, 0x00, 0x00, 0x00, 0x31, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x14, 0x00, 0x11, 0xae, 0xbc, 0x8b, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0xf6, 0xff, 0xa3, 0x24, 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x5b,
- 0x00, 0xc0, 0x10, 0x23, 0x38, 0x43, 0x00, 0x90, 0x00, 0x03, 0x8e, 0x94, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x98, 0x00, 0x04, 0x8e, 0x9c, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x10, 0xa2, 0x00, 0xe8, 0x03, 0x42, 0x2c, 0x0c, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x9c, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18,
- 0xa3, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x23, 0x20, 0x82, 0x00,
- 0x02, 0x00, 0x81, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x9c,
- 0x00, 0x05, 0xae, 0x40, 0x10, 0x06, 0x00, 0x21, 0x10, 0x46, 0x00, 0x80, 0x19,
- 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x46,
- 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x46, 0x00, 0x40, 0x11, 0x02, 0x00,
- 0x94, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02,
- 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff,
- 0x01, 0x24, 0x04, 0x00, 0x61, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00,
- 0x21, 0x20, 0x82, 0x00, 0x98, 0x00, 0x04, 0xae, 0xeb, 0x51, 0x02, 0x3c, 0x1f,
- 0x85, 0x42, 0x34, 0x18, 0x00, 0x82, 0x00, 0x10, 0x40, 0x00, 0x00, 0x43, 0x11,
- 0x08, 0x00, 0xc3, 0x1f, 0x04, 0x00, 0x23, 0x10, 0x43, 0x00, 0x9c, 0xff, 0x44,
- 0x24, 0x2a, 0x10, 0xe4, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x38, 0x80, 0x00, 0x84, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x11, 0x03, 0x00, 0x23, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10,
- 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x90, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0x61, 0x14, 0x00,
- 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x06, 0x00, 0x12, 0x20, 0x00, 0x00, 0x78, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x10, 0xa2, 0x00, 0x23, 0x20, 0x82, 0x00, 0xec, 0xff, 0x84, 0x24,
- 0x2a, 0x10, 0xe4, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x38, 0x80, 0x00, 0x03, 0x00, 0xe0, 0x18, 0x21, 0x10, 0xe5, 0x00, 0x49, 0x29,
- 0x00, 0x08, 0x24, 0x00, 0x22, 0xae, 0x24, 0x00, 0x25, 0xae, 0x24, 0x00, 0x25,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x2a, 0x00, 0x0c, 0xd0, 0x00, 0x04, 0x26,
- 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00,
- 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80,
- 0x00, 0x04, 0x00, 0x11, 0x8e, 0x00, 0xa0, 0x03, 0x3c, 0xe0, 0x0d, 0x63, 0x34,
- 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00,
- 0x00, 0x62, 0xac, 0xc8, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0xc8, 0x00, 0x22, 0xae, 0x20, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x62, 0x30, 0x0c, 0x00, 0x40, 0x14, 0x08, 0x00, 0x62, 0x34,
- 0x3c, 0x00, 0x03, 0x8e, 0x34, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x24, 0x0c,
- 0x00, 0x0c, 0xfd, 0x06, 0x05, 0x24, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x0a, 0x00, 0x42, 0x34, 0x20, 0x00, 0x02, 0xae, 0x2c, 0x00, 0x22, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00, 0x22, 0xae, 0x1b,
- 0x1f, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xc0, 0xff, 0xbd, 0x27, 0x38, 0x00, 0xbf, 0xaf, 0x34, 0x00, 0xb5, 0xaf,
- 0x30, 0x00, 0xb4, 0xaf, 0x2c, 0x00, 0xb3, 0xaf, 0x28, 0x00, 0xb2, 0xaf, 0x24,
- 0x00, 0xb1, 0xaf, 0x4a, 0x35, 0x00, 0x0c, 0x20, 0x00, 0xb0, 0xaf, 0x01, 0x80,
- 0x11, 0x3c, 0xa0, 0xf9, 0x31, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x22,
- 0x2a, 0x03, 0x00, 0x40, 0x10, 0x5f, 0x00, 0x22, 0x26, 0x2c, 0x01, 0x11, 0x24,
- 0x5f, 0x00, 0x22, 0x26, 0xf0, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x74,
- 0x90, 0x82, 0xaf, 0x21, 0x88, 0x00, 0x00, 0xff, 0xff, 0x12, 0x3c, 0x01, 0x00,
- 0x13, 0x3c, 0xb0, 0x8f, 0x83, 0x8f, 0x74, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x10, 0x62, 0x00, 0x26, 0x10, 0x43, 0x00, 0x24, 0x10, 0x52, 0x00,
- 0x03, 0x00, 0x40, 0x10, 0x21, 0x10, 0x73, 0x00, 0x24, 0x10, 0x52, 0x00, 0xb0,
- 0x8f, 0x82, 0xaf, 0xb0, 0x8f, 0x90, 0x8f, 0x74, 0x90, 0x85, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x28, 0x05, 0x02, 0xb0, 0x8f, 0x85, 0xaf, 0x35, 0x21, 0x00,
- 0x0c, 0x21, 0x20, 0x00, 0x02, 0xb0, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0xae, 0xb0, 0x90, 0x90, 0xaf, 0x01, 0x00, 0x31, 0x26, 0x05,
- 0x00, 0x22, 0x2a, 0xe8, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x90,
- 0x91, 0xaf, 0x01, 0x80, 0x11, 0x3c, 0x20, 0xf9, 0x31, 0x26, 0x04, 0x90, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x40, 0x00, 0x3f, 0x00, 0x40, 0x18,
- 0x21, 0x98, 0x00, 0x00, 0x01, 0x00, 0x14, 0x24, 0x09, 0x00, 0x15, 0x24, 0x0a,
- 0x00, 0x74, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x90, 0x83, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x02, 0x00, 0x41,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x24, 0xc5, 0x29, 0x00, 0x08,
- 0x83, 0x10, 0x02, 0x00, 0x80, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x64,
- 0x00, 0x22, 0xae, 0x0c, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x22, 0xae, 0x0c, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x22,
- 0xae, 0xd0, 0x00, 0x30, 0x26, 0x21, 0x20, 0x00, 0x02, 0x02, 0x00, 0x05, 0x24,
- 0x01, 0x80, 0x06, 0x3c, 0x10, 0xa2, 0xc6, 0x24, 0x1e, 0x2a, 0x00, 0x0c, 0x21,
- 0x38, 0x20, 0x02, 0x39, 0x2a, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x0c, 0x00,
- 0x30, 0x8e, 0x68, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x40,
- 0x18, 0x21, 0x90, 0x00, 0x00, 0x20, 0x00, 0x15, 0xae, 0x50, 0x00, 0x14, 0xae,
- 0x54, 0x00, 0x04, 0x26, 0x21, 0x28, 0x00, 0x00, 0x01, 0x80, 0x06, 0x3c, 0x18,
- 0x9e, 0xc6, 0x24, 0x1e, 0x2a, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x02, 0x6c, 0x00,
- 0x04, 0x26, 0x03, 0x00, 0x05, 0x24, 0x01, 0x80, 0x06, 0x3c, 0x48, 0xa5, 0xc6,
- 0x24, 0x1e, 0x2a, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x02, 0x01, 0x00, 0x52, 0x26,
- 0x68, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x42, 0x02, 0xed,
- 0xff, 0x40, 0x14, 0x84, 0x00, 0x10, 0x26, 0x01, 0x00, 0x73, 0x26, 0x04, 0x90,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x63, 0x02, 0xc5, 0xff, 0x40,
- 0x14, 0x68, 0x01, 0x31, 0x26, 0x78, 0x90, 0x82, 0x27, 0xa8, 0x90, 0x82, 0xaf,
- 0x90, 0x90, 0x84, 0x27, 0x01, 0x00, 0x05, 0x24, 0x01, 0x80, 0x06, 0x3c, 0xbc,
- 0x9c, 0xc6, 0x24, 0x1e, 0x2a, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x00, 0x38, 0x00,
- 0xbf, 0x8f, 0x34, 0x00, 0xb5, 0x8f, 0x30, 0x00, 0xb4, 0x8f, 0x2c, 0x00, 0xb3,
- 0x8f, 0x28, 0x00, 0xb2, 0x8f, 0x24, 0x00, 0xb1, 0x8f, 0x20, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0xc0, 0x90, 0x82, 0xaf, 0x21, 0x20, 0x00,
- 0x00, 0x40, 0x8c, 0x83, 0x27, 0x00, 0x00, 0x63, 0xac, 0x04, 0x00, 0x63, 0xac,
- 0x01, 0x00, 0x84, 0x24, 0x04, 0x00, 0x82, 0x28, 0xfb, 0xff, 0x40, 0x14, 0x08,
- 0x00, 0x63, 0x24, 0x21, 0x20, 0x00, 0x00, 0x30, 0x8d, 0x83, 0x27, 0x00, 0x00,
- 0x63, 0xac, 0x04, 0x00, 0x63, 0xac, 0x01, 0x00, 0x84, 0x24, 0x10, 0x00, 0x82,
- 0x28, 0xfb, 0xff, 0x40, 0x14, 0x08, 0x00, 0x63, 0x24, 0x08, 0x00, 0xe0, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xbf, 0xaf, 0x1c,
- 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00,
- 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x21, 0x88, 0xa0, 0x00, 0x21, 0x90, 0xc0,
- 0x00, 0xd0, 0x8f, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c,
- 0x21, 0x98, 0xe0, 0x00, 0x00, 0x00, 0x10, 0xae, 0x04, 0x00, 0x10, 0xae, 0x10,
- 0x00, 0x11, 0xae, 0x08, 0x00, 0x12, 0xae, 0x0c, 0x00, 0x13, 0xae, 0x37, 0x12,
- 0x00, 0x0c, 0x21, 0x20, 0x40, 0x00, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x14,
- 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xd0, 0x8f,
- 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x8b, 0x83,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x03, 0xae, 0x04, 0x00, 0x04, 0x8e,
- 0x00, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xac, 0x04,
- 0x00, 0x64, 0xac, 0x10, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x18,
- 0x03, 0x00, 0x40, 0x8c, 0x84, 0x27, 0x21, 0x18, 0x64, 0x00, 0x04, 0x00, 0x64,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xac, 0x04, 0x00, 0x04, 0xae,
- 0x00, 0x00, 0x03, 0xae, 0x04, 0x00, 0x70, 0xac, 0x37, 0x12, 0x00, 0x0c, 0x21,
- 0x20, 0x40, 0x00, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xd0, 0x8f, 0x84, 0x8f,
- 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x8e, 0x00,
- 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xac, 0x04, 0x00,
- 0x64, 0xac, 0x04, 0x00, 0x10, 0xae, 0x00, 0x00, 0x10, 0xae, 0x37, 0x12, 0x00,
- 0x0c, 0x21, 0x20, 0x40, 0x00, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18,
- 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80,
- 0x80, 0x00, 0xd0, 0x8f, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00,
- 0x0c, 0x21, 0x88, 0xa0, 0x00, 0x21, 0x20, 0x40, 0x00, 0x04, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xac, 0x04,
- 0x00, 0x43, 0xac, 0xbc, 0x8b, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18,
- 0xb1, 0x00, 0xff, 0x3f, 0x02, 0x3c, 0xff, 0xff, 0x42, 0x34, 0x2b, 0x10, 0x43,
- 0x00, 0x06, 0x00, 0x40, 0x14, 0x0f, 0x00, 0x22, 0x32, 0x14, 0x00, 0x05, 0xae,
- 0x10, 0x00, 0x02, 0x8e, 0x40, 0x8c, 0x83, 0x27, 0x8c, 0x2a, 0x00, 0x08, 0xc0,
- 0x10, 0x02, 0x00, 0x14, 0x00, 0x11, 0xae, 0xc0, 0x10, 0x02, 0x00, 0x30, 0x8d,
- 0x83, 0x27, 0x21, 0x18, 0x43, 0x00, 0x04, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xac, 0x04, 0x00, 0x02, 0xae, 0x00, 0x00, 0x03, 0xae,
- 0x37, 0x12, 0x00, 0x0c, 0x04, 0x00, 0x70, 0xac, 0x18, 0x00, 0xbf, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0,
- 0xaf, 0xc4, 0x90, 0x90, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x82, 0x00, 0x14, 0x00, 0x04, 0xae, 0xd0,
- 0x8f, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20,
- 0x40, 0x00, 0x04, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x62, 0xac, 0x04, 0x00, 0x43, 0xac, 0xbc, 0x8b, 0x85, 0x8f,
- 0x14, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0xa3, 0x00, 0xff,
- 0x3f, 0x02, 0x3c, 0xff, 0xff, 0x42, 0x34, 0x2b, 0x10, 0x43, 0x00, 0x06, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0xae, 0x10, 0x00, 0x02,
- 0x8e, 0x40, 0x8c, 0x83, 0x27, 0xbe, 0x2a, 0x00, 0x08, 0xc0, 0x10, 0x02, 0x00,
- 0x14, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x42, 0x30, 0xc0,
- 0x10, 0x02, 0x00, 0x30, 0x8d, 0x83, 0x27, 0x21, 0x18, 0x43, 0x00, 0x04, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xac, 0x04, 0x00, 0x02,
- 0xae, 0x00, 0x00, 0x03, 0xae, 0x37, 0x12, 0x00, 0x0c, 0x04, 0x00, 0x70, 0xac,
- 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18,
- 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xbf, 0xaf, 0x1c, 0x00,
- 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0,
- 0xaf, 0xb8, 0x8e, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x37, 0x12, 0x00, 0x0c,
- 0xff, 0x7f, 0x12, 0x3c, 0x30, 0x8d, 0x93, 0x27, 0xff, 0xff, 0x52, 0x36, 0x40,
- 0x8c, 0x91, 0x27, 0xd0, 0x8f, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x2b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xc0, 0x90, 0x82, 0xaf,
- 0x0f, 0x00, 0x42, 0x30, 0xc0, 0x10, 0x02, 0x00, 0x21, 0x30, 0x53, 0x00, 0x00,
- 0x00, 0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x66, 0x10, 0x21, 0x28,
- 0xc0, 0x00, 0xc0, 0x90, 0x87, 0x8f, 0x14, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x10, 0xe2, 0x00, 0x2b, 0x10, 0x42, 0x02, 0x10, 0x00, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xa2, 0xac, 0x04, 0x00, 0x45, 0xac, 0x10, 0x00, 0x62, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x21, 0x20, 0x51, 0x00, 0x04, 0x00, 0x82,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xac, 0x04, 0x00, 0x62, 0xac,
- 0x00, 0x00, 0x64, 0xac, 0xfe, 0x2a, 0x00, 0x08, 0x04, 0x00, 0x83, 0xac, 0x21,
- 0x28, 0x60, 0x00, 0x00, 0x00, 0xa3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xff,
- 0x66, 0x14, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x83, 0x8f, 0xbc, 0x8b, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xff, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x8c, 0x84, 0x27, 0x40, 0x8c, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1f,
- 0x00, 0x44, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x04, 0x3c, 0x98, 0xec,
- 0x84, 0x24, 0x01, 0x80, 0x02, 0x3c, 0x98, 0xec, 0x42, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x00, 0x44, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x04, 0x3c,
- 0xa0, 0xec, 0x84, 0x24, 0x01, 0x80, 0x02, 0x3c, 0xa0, 0xec, 0x42, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x44, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
- 0x04, 0x3c, 0xa8, 0xec, 0x84, 0x24, 0x01, 0x80, 0x02, 0x3c, 0xa8, 0xec, 0x42,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x44, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0xb8, 0x8e, 0x84, 0x8f, 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x40, 0x90,
- 0x82, 0xaf, 0xd7, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x82, 0xac, 0x04, 0x00, 0x44, 0xac, 0x00, 0x00, 0x63, 0xac, 0x04,
- 0x00, 0x63, 0xac, 0xc4, 0x90, 0x83, 0xaf, 0xbc, 0x8b, 0x90, 0x8f, 0x08, 0x00,
- 0x62, 0x8c, 0x0c, 0x00, 0x64, 0x8c, 0x09, 0xf8, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xb8, 0x8e, 0x84, 0x8f, 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0xc4, 0x90, 0x80, 0xaf, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x80, 0x50, 0x00, 0x32, 0x00, 0x02, 0x2e, 0x02, 0x00, 0x40, 0x14, 0x21, 0x18,
- 0x00, 0x02, 0x31, 0x00, 0x03, 0x24, 0x01, 0x80, 0x02, 0x3c, 0x90, 0x20, 0x42,
- 0x24, 0x80, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x21, 0x20, 0x00, 0x02,
- 0x32, 0x00, 0x82, 0x2c, 0x03, 0x00, 0x40, 0x14, 0x80, 0x10, 0x04, 0x00, 0x31,
- 0x00, 0x04, 0x24, 0x80, 0x10, 0x04, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08,
- 0x22, 0x00, 0x90, 0x20, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0xd7, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0x20, 0x00, 0xbf, 0x8f,
- 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2,
- 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x90, 0x00, 0x00,
- 0x01, 0x80, 0x11, 0x3c, 0x60, 0xda, 0x31, 0x26, 0x21, 0x80, 0x00, 0x00, 0xd0,
- 0x90, 0x80, 0xaf, 0x21, 0x28, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, 0x00, 0x00,
- 0x82, 0x94, 0x02, 0x00, 0x83, 0x90, 0x00, 0xa2, 0x01, 0x3c, 0x21, 0x08, 0x22,
- 0x00, 0x00, 0x00, 0x23, 0xa0, 0xd0, 0x90, 0x80, 0xaf, 0x01, 0x00, 0xa5, 0x24,
- 0x04, 0x00, 0xa2, 0x28, 0xf7, 0xff, 0x40, 0x14, 0x04, 0x00, 0x84, 0x24, 0x00,
- 0x00, 0x82, 0x94, 0x00, 0xa2, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x00, 0x00,
- 0x22, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x08, 0x00, 0x40,
- 0x10, 0x64, 0x00, 0x02, 0x2a, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0xc0, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x61, 0x00, 0x05, 0x24, 0x65,
- 0x2b, 0x00, 0x08, 0x01, 0x00, 0x10, 0x26, 0x05, 0x00, 0x52, 0x26, 0x0f, 0x00,
- 0x42, 0x2a, 0xe0, 0xff, 0x40, 0x14, 0x14, 0x00, 0x31, 0x26, 0x1c, 0x00, 0xbf,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0xd8,
- 0xff, 0xbd, 0x27, 0x20, 0x00, 0xbf, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00,
- 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x00, 0xa2, 0x11,
- 0x3c, 0x01, 0xa2, 0x02, 0x3c, 0x10, 0x00, 0x42, 0x34, 0x00, 0x00, 0x40, 0xa4,
- 0xf8, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00, 0x23,
- 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10,
- 0x02, 0x00, 0xe8, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x43,
- 0x00, 0x70, 0x00, 0x02, 0x3c, 0xff, 0x7f, 0x42, 0x34, 0x2b, 0x10, 0x50, 0x00,
- 0x0c, 0x00, 0x40, 0x10, 0x8f, 0xff, 0x04, 0x3c, 0x00, 0x80, 0x84, 0x34, 0x70,
- 0x00, 0x03, 0x3c, 0xff, 0x7f, 0x63, 0x34, 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xbc, 0x8b, 0x82, 0xaf, 0x21, 0x80, 0x04,
- 0x02, 0x2b, 0x10, 0x70, 0x00, 0xf9, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0xe8, 0x90, 0x90, 0xaf, 0x80, 0x00, 0x04, 0x24, 0x00, 0xa0, 0x03, 0x3c, 0xba,
- 0x2b, 0x00, 0x08, 0x14, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x00, 0x00, 0x62,
- 0x8c, 0x0c, 0x00, 0x24, 0xa2, 0xd0, 0x90, 0x80, 0xaf, 0x08, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x53, 0x30, 0x08, 0x00, 0x22, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x98, 0x62, 0x02, 0xd0, 0x90,
- 0x80, 0xaf, 0x0c, 0x00, 0x24, 0xa2, 0xd0, 0x90, 0x80, 0xaf, 0x08, 0x00, 0x22,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x50, 0x30, 0x08, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x80, 0x02, 0x02, 0x23,
- 0x10, 0x70, 0x02, 0xff, 0xff, 0x50, 0x30, 0x80, 0x00, 0x02, 0x2e, 0xe4, 0xff,
- 0x40, 0x10, 0x42, 0x10, 0x10, 0x00, 0x21, 0x98, 0x62, 0x02, 0x70, 0x8c, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10, 0x80, 0x00, 0x04, 0x24,
- 0x2c, 0x0d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x24, 0x00,
- 0xa0, 0x03, 0x3c, 0xe2, 0x2b, 0x00, 0x08, 0x18, 0x00, 0x63, 0x34, 0x00, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62,
- 0xac, 0x00, 0x00, 0x62, 0x8c, 0x0c, 0x00, 0x24, 0xa2, 0xd0, 0x90, 0x80, 0xaf,
- 0x08, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x52, 0x30, 0x08,
- 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x90,
- 0x42, 0x02, 0xd0, 0x90, 0x80, 0xaf, 0x0c, 0x00, 0x24, 0xa2, 0xd0, 0x90, 0x80,
- 0xaf, 0x08, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x50, 0x30,
- 0x08, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25,
- 0x80, 0x02, 0x02, 0x23, 0x10, 0x50, 0x02, 0xff, 0xff, 0x50, 0x30, 0x80, 0x00,
- 0x02, 0x2e, 0xe4, 0xff, 0x40, 0x10, 0x42, 0x10, 0x10, 0x00, 0x21, 0x90, 0x42,
- 0x02, 0x23, 0x80, 0x72, 0x02, 0xff, 0xff, 0x10, 0x32, 0xe4, 0x90, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x02, 0x02, 0xe0, 0x90, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0xe0, 0x90, 0x82, 0xaf, 0xd0, 0x89,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x62, 0x00, 0x12, 0x18, 0x00,
- 0x00, 0x82, 0x19, 0x03, 0x00, 0xe4, 0x90, 0x83, 0xaf, 0xd4, 0x89, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x43, 0x00, 0x12, 0x80, 0x00, 0x00, 0x02,
- 0x19, 0x10, 0x00, 0xd8, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80,
- 0x62, 0x00, 0xfc, 0x90, 0x90, 0xaf, 0xdc, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x02, 0x00, 0x01, 0x00, 0x43, 0x24, 0x2b, 0x10, 0x03, 0x02,
- 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x60, 0x00, 0xf8,
- 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x50, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x30, 0xa2, 0xf8, 0x90, 0x90, 0xaf, 0x02, 0x12, 0x10,
- 0x00, 0x00, 0x00, 0x22, 0xa2, 0xe0, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x90, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x25, 0x00, 0x40, 0x10, 0x23, 0x80, 0x53, 0x00, 0xec, 0x90,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xec, 0x90, 0x82,
- 0xaf, 0xe8, 0x03, 0x42, 0x28, 0x0a, 0x00, 0x40, 0x14, 0xff, 0xff, 0x10, 0x32,
- 0xe4, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x50, 0x00, 0x06,
- 0x00, 0x40, 0x10, 0x80, 0x10, 0x10, 0x00, 0xe8, 0x89, 0x84, 0x27, 0x24, 0x0c,
- 0x00, 0x0c, 0xd4, 0x01, 0x05, 0x24, 0xec, 0x90, 0x80, 0xaf, 0x80, 0x10, 0x10,
- 0x00, 0x21, 0x10, 0x50, 0x00, 0x00, 0x11, 0x02, 0x00, 0x23, 0x10, 0x50, 0x00,
- 0xc0, 0x18, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x02,
- 0x85, 0x02, 0x00, 0x64, 0x00, 0x02, 0x2e, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x00, 0x10, 0x24, 0x01, 0x80, 0x02, 0x3c, 0x60, 0x21, 0x42,
- 0x24, 0x80, 0x18, 0x10, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0xf0,
- 0x90, 0x93, 0xaf, 0x23, 0x80, 0x72, 0x02, 0xff, 0xff, 0x10, 0x32, 0x80, 0x10,
- 0x10, 0x00, 0x21, 0x10, 0x50, 0x00, 0x00, 0x11, 0x02, 0x00, 0x23, 0x10, 0x50,
- 0x00, 0xc0, 0x18, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00,
- 0x02, 0x85, 0x02, 0x00, 0x64, 0x00, 0x02, 0x2e, 0x02, 0x00, 0x40, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x63, 0x00, 0x10, 0x24, 0x01, 0x80, 0x02, 0x3c, 0xf0, 0x22,
- 0x42, 0x24, 0x80, 0x18, 0x10, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x62,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac,
- 0xf4, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x60, 0x10, 0x01,
- 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x83, 0x0c,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0xe8, 0x89, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0xdb, 0x02, 0x05, 0x24,
- 0xf4, 0x90, 0x80, 0xaf, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18,
- 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x83,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x62, 0x28, 0x0d, 0x00, 0x40, 0x14,
- 0x21, 0x10, 0x00, 0x00, 0x3c, 0x00, 0x62, 0x28, 0x06, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x30, 0x8d, 0x2c, 0x00, 0x08, 0x01, 0x00, 0x42, 0x24, 0x48, 0x00, 0x82,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x30, 0x03, 0x00, 0x42, 0x24,
- 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x18,
- 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80,
- 0x80, 0x00, 0x24, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0x21, 0x28, 0x40, 0x00, 0x50,
- 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, 0x1e, 0x00,
- 0x40, 0x14, 0x01, 0x00, 0x63, 0x34, 0x50, 0x00, 0x03, 0xa6, 0x28, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10,
- 0x00, 0x02, 0x62, 0x38, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xbc,
- 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x68, 0x00, 0x04, 0x92, 0x5f, 0x00,
- 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x30, 0x27, 0x10, 0x02,
- 0x00, 0x24, 0x20, 0x82, 0x00, 0x10, 0x00, 0x24, 0xa2, 0x54, 0x00, 0x03, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x64, 0x00, 0x03, 0x00, 0x63, 0x30, 0x54,
- 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x43, 0x00, 0x54, 0x00,
- 0x02, 0xa2, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x43,
- 0x00, 0x58, 0x00, 0x02, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0xa0, 0x00,
- 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00,
- 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80,
- 0x00, 0x24, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e,
- 0x12, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0x21, 0x28, 0x40, 0x00, 0x50, 0x00,
- 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, 0x1e, 0x00, 0x40,
- 0x10, 0xfe, 0xff, 0x63, 0x30, 0x50, 0x00, 0x03, 0xa6, 0x28, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00,
- 0x02, 0x62, 0x38, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xbc, 0x35,
- 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x5f, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x42, 0x30, 0x68, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x18, 0x62, 0x00, 0x10, 0x00, 0x23, 0xa2, 0x54, 0x00, 0x04, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x26, 0x20, 0x83, 0x00, 0x03, 0x00, 0x84, 0x30, 0x54, 0x00,
- 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x44, 0x00, 0x54, 0x00, 0x02,
- 0xa2, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x44, 0x00,
- 0x58, 0x00, 0x02, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0xa0, 0x00, 0x18,
- 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf,
- 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf,
- 0x21, 0x80, 0x80, 0x00, 0x24, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x00, 0x40, 0x10, 0x21, 0x90, 0xa0, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0x21, 0x20, 0x40,
- 0x00, 0x30, 0x00, 0x47, 0x32, 0x02, 0x39, 0x07, 0x00, 0x05, 0x00, 0xe7, 0x24,
- 0x01, 0x00, 0x02, 0x24, 0x04, 0x18, 0xe2, 0x00, 0xff, 0xff, 0x63, 0x24, 0x62,
- 0x00, 0x03, 0xa2, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
- 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x02, 0x00, 0x08, 0x24, 0x7f, 0x00, 0x63,
- 0x30, 0x6a, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x30,
- 0x25, 0x10, 0x43, 0x00, 0x6a, 0x00, 0x02, 0xa6, 0x00, 0x01, 0x42, 0x32, 0x06,
- 0x00, 0x40, 0x10, 0xfb, 0xff, 0xe6, 0x24, 0x00, 0x02, 0x42, 0x32, 0x02, 0x00,
- 0x40, 0x14, 0x08, 0x00, 0xc6, 0x34, 0x10, 0x00, 0xc6, 0x34, 0x01, 0x00, 0x08,
- 0x25, 0x40, 0x00, 0x42, 0x32, 0x03, 0x00, 0x40, 0x10, 0x0f, 0x00, 0x45, 0x32,
- 0x04, 0x00, 0xc6, 0x34, 0x01, 0x00, 0x08, 0x25, 0x00, 0x04, 0x42, 0x32, 0x10,
- 0x00, 0x40, 0x10, 0x40, 0x28, 0x05, 0x00, 0x65, 0x00, 0x03, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02,
- 0x00, 0x01, 0x80, 0x03, 0x3c, 0x21, 0x18, 0x62, 0x00, 0xb8, 0xfa, 0x63, 0x8c,
- 0x03, 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x80, 0x02, 0x3c, 0xc0, 0xda, 0x42, 0x24, 0x40, 0x2d, 0x00, 0x08, 0x21, 0x10,
- 0xa2, 0x00, 0x01, 0x80, 0x02, 0x3c, 0xa0, 0xda, 0x42, 0x24, 0x21, 0x10, 0xa2,
- 0x00, 0x00, 0x00, 0x43, 0x94, 0x0c, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x42, 0x34, 0x0c, 0x00, 0x22, 0xa2, 0x7f, 0x00, 0x02, 0x24, 0x04,
- 0x00, 0x22, 0xa2, 0x00, 0x00, 0x23, 0xa2, 0x03, 0x12, 0x03, 0x00, 0x04, 0x00,
- 0x22, 0xa2, 0x0c, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42,
- 0x30, 0x21, 0x10, 0x46, 0x00, 0x0c, 0x00, 0x22, 0xa2, 0x21, 0x10, 0xe8, 0x00,
- 0x18, 0x00, 0x62, 0x00, 0x12, 0x18, 0x00, 0x00, 0x40, 0x00, 0x03, 0xae, 0x14,
- 0x00, 0x63, 0x28, 0x02, 0x00, 0x60, 0x10, 0x14, 0x00, 0x02, 0x24, 0x40, 0x00,
- 0x02, 0xae, 0x37, 0x12, 0x00, 0x0c, 0x2c, 0x00, 0x12, 0xa6, 0x7c, 0x2c, 0x00,
- 0x0c, 0x21, 0x20, 0x00, 0x02, 0x21, 0x20, 0x00, 0x02, 0xa2, 0x22, 0x00, 0x0c,
- 0x21, 0x28, 0x40, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xc0, 0x8b, 0x84, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x88, 0xa0, 0x00, 0x21,
- 0x20, 0x40, 0x00, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10,
- 0x22, 0x02, 0x00, 0x10, 0x42, 0x30, 0x0a, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x50, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30,
- 0x05, 0x00, 0x40, 0x10, 0x00, 0x02, 0x62, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x00,
- 0x80, 0x02, 0x3c, 0xbc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x62, 0x00,
- 0x03, 0x92, 0x20, 0x00, 0x22, 0x32, 0x02, 0x00, 0x40, 0x10, 0x10, 0x00, 0x22,
- 0x32, 0x7f, 0x00, 0x63, 0x30, 0x02, 0x00, 0x40, 0x10, 0x00, 0x1a, 0x63, 0x34,
- 0x00, 0x04, 0x63, 0x34, 0x6a, 0x00, 0x03, 0xa6, 0x50, 0x00, 0x03, 0x96, 0x00,
- 0x04, 0x22, 0x32, 0x0a, 0x00, 0x40, 0x10, 0xfb, 0x3f, 0x63, 0x30, 0x00, 0x20,
- 0x22, 0x32, 0x02, 0x00, 0x40, 0x10, 0x00, 0x80, 0x63, 0x34, 0x00, 0x40, 0x63,
- 0x34, 0x00, 0x08, 0x22, 0x32, 0x04, 0x00, 0x40, 0x10, 0xff, 0xef, 0x02, 0x24,
- 0x95, 0x2d, 0x00, 0x08, 0x04, 0x00, 0x63, 0x34, 0xff, 0xe7, 0x02, 0x24, 0x24,
- 0x18, 0x62, 0x00, 0x50, 0x00, 0x03, 0xa6, 0x37, 0x12, 0x00, 0x0c, 0x28, 0x00,
- 0x11, 0xa6, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27,
- 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12,
- 0x00, 0x0c, 0x21, 0x88, 0xa0, 0x00, 0x21, 0x20, 0x40, 0x00, 0x7f, 0xff, 0x02,
- 0x24, 0x24, 0x10, 0x22, 0x02, 0x0b, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x30, 0x02,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0xa2, 0x50, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x2d, 0x00, 0x08, 0x80, 0x00, 0x42,
- 0x34, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x42, 0x30,
- 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xbc, 0x35, 0x42, 0x24, 0x04,
- 0x00, 0x02, 0xae, 0x80, 0x00, 0x22, 0x32, 0x03, 0x00, 0x40, 0x10, 0x7f, 0x00,
- 0x02, 0x24, 0xc2, 0x2d, 0x00, 0x08, 0x60, 0x00, 0x02, 0xa2, 0x60, 0x00, 0x00,
- 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x2a, 0x00, 0x11, 0xa6, 0x18, 0x00, 0xbf, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00,
- 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xc0, 0x8b, 0x84,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x88, 0xa0, 0x00,
- 0x21, 0x20, 0x40, 0x00, 0x6c, 0x00, 0x03, 0x8e, 0xff, 0xff, 0x02, 0x24, 0x09,
- 0x00, 0x62, 0x14, 0xff, 0xff, 0x02, 0x34, 0x07, 0x00, 0x22, 0x12, 0x00, 0x00,
- 0x00, 0x00, 0x6c, 0x00, 0x00, 0xae, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xfe, 0x42, 0x30, 0xf1, 0x2d, 0x00, 0x08, 0x50, 0x00, 0x02, 0xa6,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x34, 0x50,
- 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xbc, 0x35, 0x42, 0x24, 0x04, 0x00,
- 0x02, 0xae, 0xff, 0xff, 0x02, 0x34, 0x07, 0x00, 0x22, 0x12, 0xc0, 0x10, 0x11,
- 0x00, 0x21, 0x10, 0x51, 0x00, 0x40, 0x12, 0x02, 0x00, 0x6c, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2d, 0x00, 0x08, 0x21, 0x10, 0x43, 0x00, 0xff,
- 0xff, 0x02, 0x24, 0x6c, 0x00, 0x02, 0xae, 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27,
- 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10,
- 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x00, 0x40, 0x10, 0x21, 0x80, 0xa0, 0x00, 0x21, 0x90, 0x40,
- 0x00, 0x10, 0x00, 0x02, 0x32, 0x03, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x0a, 0x2e, 0x00, 0x08, 0x1f, 0x00, 0x10, 0x32, 0x03, 0x00, 0x10, 0x32, 0x08,
- 0x00, 0x10, 0x36, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x20, 0x40, 0x00, 0x68, 0x00, 0x30, 0xa2, 0x50, 0x00, 0x22,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x07, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x42, 0x30, 0x27, 0x10, 0x02, 0x00, 0x1e, 0x2e, 0x00, 0x08, 0x24, 0x80,
- 0x02, 0x02, 0x5f, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42,
- 0x30, 0x25, 0x80, 0x02, 0x02, 0x10, 0x00, 0x50, 0xa2, 0x54, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x50, 0x00, 0x03, 0x00, 0x42, 0x30, 0x54,
- 0x00, 0x23, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x62, 0x00, 0x54, 0x00,
- 0x23, 0xa2, 0x58, 0x00, 0x23, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x62,
- 0x00, 0x37, 0x12, 0x00, 0x0c, 0x58, 0x00, 0x23, 0xa2, 0x1c, 0x00, 0xbf, 0x8f,
- 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00,
- 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x88, 0x80, 0x00, 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0x00, 0x40, 0x10, 0x21, 0x80, 0xa0, 0x00, 0x21, 0x90, 0x40, 0x00, 0xc0,
- 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c, 0xf3, 0x00,
- 0x10, 0x32, 0x21, 0x20, 0x40, 0x00, 0x5f, 0x00, 0x30, 0xa2, 0xf0, 0x00, 0x02,
- 0x32, 0x49, 0x00, 0x22, 0xa2, 0x4a, 0x00, 0x23, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x0f, 0x00, 0x63, 0x30, 0x25, 0x18, 0x62, 0x00, 0x4a, 0x00, 0x23, 0xa2, 0x50,
- 0x00, 0x22, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x06, 0x00,
- 0x40, 0x10, 0x03, 0x00, 0x10, 0x32, 0x27, 0x80, 0x10, 0x00, 0x68, 0x00, 0x22,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x57, 0x2e, 0x00, 0x08, 0x24, 0x80, 0x02, 0x02,
- 0x68, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x80, 0x02, 0x02, 0x10,
- 0x00, 0x50, 0xa2, 0x54, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10,
- 0x50, 0x00, 0x03, 0x00, 0x42, 0x30, 0x54, 0x00, 0x23, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x26, 0x18, 0x62, 0x00, 0x54, 0x00, 0x23, 0xa2, 0x58, 0x00, 0x23, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x62, 0x00, 0x37, 0x12, 0x00, 0x0c, 0x58,
- 0x00, 0x23, 0xa2, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf,
- 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x24, 0x00, 0x11, 0x8e, 0xc0,
- 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20,
- 0x40, 0x00, 0x0a, 0x00, 0x00, 0xa6, 0x0c, 0x00, 0x00, 0xa6, 0x12, 0x00, 0x00,
- 0xa6, 0x14, 0x00, 0x00, 0xa6, 0x1a, 0x00, 0x00, 0xa6, 0xff, 0xff, 0x02, 0x34,
- 0x1c, 0x00, 0x02, 0xa6, 0x28, 0x00, 0x00, 0xa6, 0x2a, 0x00, 0x00, 0xa6, 0x3f,
- 0x00, 0x02, 0x24, 0x2c, 0x00, 0x02, 0xa6, 0x78, 0x00, 0x02, 0x24, 0x40, 0x00,
- 0x02, 0xae, 0x44, 0x00, 0x00, 0xae, 0x10, 0x00, 0x02, 0x24, 0x50, 0x00, 0x02,
- 0xa6, 0x49, 0x00, 0x00, 0xa2, 0x4a, 0x00, 0x00, 0xa2, 0x54, 0x00, 0x00, 0xa2,
- 0x57, 0x00, 0x00, 0xa2, 0x58, 0x00, 0x00, 0xa2, 0x5a, 0x00, 0x00, 0xa2, 0x5b,
- 0x00, 0x00, 0xa2, 0x11, 0x00, 0x02, 0x24, 0x5c, 0x00, 0x02, 0xa2, 0x13, 0x00,
- 0x02, 0x24, 0x5d, 0x00, 0x02, 0xa2, 0x5e, 0x00, 0x00, 0xa2, 0x5f, 0x00, 0x00,
- 0xa2, 0x60, 0x00, 0x00, 0xa2, 0x61, 0x00, 0x00, 0xa2, 0xff, 0x00, 0x02, 0x24,
- 0x62, 0x00, 0x02, 0xa2, 0x63, 0x00, 0x00, 0xa2, 0x68, 0x00, 0x00, 0xa2, 0xff,
- 0x0a, 0x02, 0x24, 0x6a, 0x00, 0x02, 0xa6, 0x6c, 0x00, 0x00, 0xae, 0x00, 0x80,
- 0x02, 0x3c, 0xbc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x00, 0x80, 0x02,
- 0x3c, 0x4c, 0x3e, 0x42, 0x24, 0x74, 0x00, 0x02, 0xae, 0x00, 0x80, 0x02, 0x3c,
- 0x88, 0x3a, 0x42, 0x24, 0x34, 0x00, 0x02, 0xae, 0x24, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x00, 0x40, 0x10, 0x80, 0x00, 0x02, 0x24, 0x0c, 0x00,
- 0x22, 0xa2, 0x0c, 0x00, 0x02, 0x24, 0x00, 0x00, 0x22, 0xa2, 0x04, 0x00, 0x20,
- 0xa2, 0x03, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x22, 0xa2, 0x0f, 0x00, 0x02, 0x24,
- 0x08, 0x00, 0x22, 0xa2, 0x01, 0x00, 0x02, 0x24, 0x04, 0x00, 0x22, 0xa2, 0x08,
- 0x00, 0x02, 0x24, 0x10, 0x00, 0x22, 0xa2, 0x08, 0x00, 0x22, 0x92, 0x00, 0x00,
- 0x22, 0x92, 0x14, 0x00, 0x22, 0x92, 0x18, 0x00, 0x22, 0x92, 0x37, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x2c, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0x21, 0x20, 0x00, 0x02, 0xa2, 0x22, 0x00, 0x0c, 0x21, 0x28, 0x40, 0x00, 0x18,
- 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf,
- 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00,
- 0x24, 0x00, 0x30, 0x8e, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x20, 0x40, 0x00, 0x44, 0x00, 0x20, 0xae, 0x2c, 0x00,
- 0x22, 0x96, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x42, 0x30, 0x02, 0x29, 0x02,
- 0x00, 0x05, 0x00, 0xa5, 0x24, 0x01, 0x00, 0x02, 0x24, 0x04, 0x18, 0xa2, 0x00,
- 0xff, 0xff, 0x63, 0x24, 0x62, 0x00, 0x23, 0xa2, 0x28, 0x00, 0x22, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x7f, 0x00, 0x63, 0x30, 0x6a, 0x00, 0x22, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x42, 0x30, 0x25, 0x10, 0x43, 0x00, 0x6a, 0x00, 0x22, 0xa6,
- 0x2c, 0x00, 0x23, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30, 0x05,
- 0x00, 0x40, 0x10, 0xfb, 0xff, 0xa6, 0x24, 0x00, 0x02, 0x62, 0x30, 0x02, 0x00,
- 0x40, 0x14, 0x08, 0x00, 0xc6, 0x34, 0x10, 0x00, 0xc6, 0x34, 0x2c, 0x00, 0x22,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xc6, 0x34, 0x2c, 0x00, 0x22, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x45, 0x30, 0x00, 0x04, 0x42, 0x30, 0x10, 0x00,
- 0x40, 0x10, 0x40, 0x28, 0x05, 0x00, 0x65, 0x00, 0x23, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00,
- 0x01, 0x80, 0x03, 0x3c, 0x21, 0x18, 0x62, 0x00, 0xb8, 0xfa, 0x63, 0x8c, 0x03,
- 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
- 0x02, 0x3c, 0xc0, 0xda, 0x42, 0x24, 0x0a, 0x2f, 0x00, 0x08, 0x21, 0x10, 0xa2,
- 0x00, 0x01, 0x80, 0x02, 0x3c, 0xa0, 0xda, 0x42, 0x24, 0x21, 0x10, 0xa2, 0x00,
- 0x00, 0x00, 0x43, 0x94, 0x0c, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x42, 0x34, 0x0c, 0x00, 0x02, 0xa2, 0x7f, 0x00, 0x02, 0x24, 0x04, 0x00,
- 0x02, 0xa2, 0x00, 0x00, 0x03, 0xa2, 0x03, 0x1a, 0x03, 0x00, 0x04, 0x00, 0x03,
- 0xa2, 0x0c, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30,
- 0x21, 0x10, 0x46, 0x00, 0x0c, 0x00, 0x02, 0xa2, 0x01, 0x00, 0x03, 0x24, 0x08,
- 0x00, 0x03, 0xa2, 0x0f, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0xa2, 0x04, 0x00,
- 0x03, 0xa2, 0x08, 0x00, 0x02, 0x24, 0x10, 0x00, 0x02, 0xa2, 0x08, 0x00, 0x02,
- 0x92, 0x00, 0x00, 0x02, 0x92, 0x14, 0x00, 0x02, 0x92, 0x18, 0x00, 0x02, 0x92,
- 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x80, 0x80, 0x00, 0x01, 0x80, 0x03, 0x3c, 0x90, 0xfa, 0x63, 0x24,
- 0x23, 0x18, 0xa3, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00,
- 0x19, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x21, 0x10,
- 0x43, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x23, 0x10, 0x02,
- 0x00, 0x03, 0x11, 0x02, 0x00, 0x65, 0x00, 0x02, 0xa2, 0x48, 0x00, 0x06, 0xa2,
- 0x40, 0x31, 0x06, 0x00, 0x00, 0x01, 0xc6, 0x24, 0x04, 0x00, 0xa2, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x30, 0xc2, 0x00, 0x24, 0x00, 0x06, 0xae, 0x02, 0x00,
- 0x02, 0x24, 0x6b, 0x2e, 0x00, 0x0c, 0x2e, 0x00, 0x02, 0xa6, 0x3c, 0x8c, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x53, 0x2f, 0x00, 0x08, 0x30, 0x00, 0x10, 0xae, 0x3c, 0x8c, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x30, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x02, 0xae, 0x30, 0x00, 0x70, 0xac, 0x3c, 0x8c, 0x90, 0xaf, 0x14, 0x00, 0xbf,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27,
- 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x14,
- 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xc0, 0x8b,
- 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x40,
- 0x00, 0x50, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30,
- 0x14, 0x00, 0x40, 0x14, 0x01, 0x00, 0x62, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x68,
- 0x00, 0x04, 0x92, 0x5f, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
- 0x42, 0x30, 0x27, 0x10, 0x02, 0x00, 0x24, 0x20, 0x82, 0x00, 0x54, 0x00, 0x03,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x64, 0x00, 0x03, 0x00, 0x63, 0x30,
- 0x54, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x43, 0x00, 0x54,
- 0x00, 0x02, 0xa2, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10,
- 0x43, 0x00, 0x58, 0x00, 0x02, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0xa0,
- 0x00, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x18, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf, 0xaf, 0x10,
- 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x2e, 0x12,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x40, 0x00, 0x50, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, 0x14, 0x00, 0x40, 0x10,
- 0xfe, 0xff, 0x62, 0x30, 0x50, 0x00, 0x02, 0xa6, 0x5f, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x30, 0x68, 0x00, 0x03, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x18, 0x62, 0x00, 0x54, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x26, 0x20, 0x83, 0x00, 0x03, 0x00, 0x84, 0x30, 0x54, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x44, 0x00, 0x54, 0x00, 0x02, 0xa2, 0x58,
- 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x44, 0x00, 0x58, 0x00,
- 0x02, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0xa0, 0x00, 0x14, 0x00, 0xbf,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27,
- 0xd8, 0xff, 0xbd, 0x27, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x1c,
- 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x24, 0x00,
- 0x12, 0x8e, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00,
- 0x0c, 0xf3, 0x00, 0xb1, 0x30, 0x21, 0x20, 0x40, 0x00, 0x5f, 0x00, 0x11, 0xa2,
- 0xf0, 0x00, 0x22, 0x32, 0x49, 0x00, 0x02, 0xa2, 0x4a, 0x00, 0x03, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x63, 0x30, 0x25, 0x18, 0x62, 0x00, 0x4a, 0x00,
- 0x03, 0xa2, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x30, 0x06, 0x00, 0x40, 0x10, 0x03, 0x00, 0x31, 0x32, 0x27, 0x88, 0x11, 0x00,
- 0x68, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x2f, 0x00, 0x08, 0x24,
- 0x88, 0x22, 0x02, 0x68, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x88,
- 0x22, 0x02, 0x28, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x43,
- 0x30, 0x4a, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x30,
- 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x60, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00,
- 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0xc2, 0x10, 0x02, 0x00, 0x04, 0x00, 0x42, 0x30, 0x28, 0x00, 0x42, 0xa2,
- 0x10, 0x27, 0x02, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00,
- 0xa3, 0x8f, 0xff, 0xff, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x10, 0xff, 0xff, 0x03,
- 0x24, 0x2c, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x10,
- 0x80, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0xf5, 0xff, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02,
- 0x24, 0x2c, 0x00, 0x42, 0xa2, 0x10, 0x27, 0x02, 0x24, 0x10, 0x00, 0xa2, 0xaf,
- 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10,
- 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa3, 0x8f, 0xff, 0xff, 0x02, 0x24, 0x0d, 0x00,
- 0x62, 0x10, 0xff, 0xff, 0x03, 0x24, 0x2c, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x0a, 0x00, 0x40, 0x10, 0x41, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa2, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10,
- 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xff, 0x43, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x41, 0x00, 0x02, 0x24, 0x2c, 0x00, 0x42, 0xa2, 0x2c, 0x00, 0x05,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xa3, 0x30, 0x04, 0x00, 0x62, 0x28,
- 0x04, 0x00, 0x40, 0x10, 0x00, 0x04, 0xa2, 0x30, 0x02, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x18, 0x00, 0x00, 0x01, 0x80, 0x02, 0x3c, 0x21, 0x10,
- 0x43, 0x00, 0xe0, 0xda, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
- 0xa2, 0x08, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x42, 0xa2,
- 0x54, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x71, 0x00, 0x03,
- 0x00, 0x63, 0x30, 0x54, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10,
- 0x43, 0x00, 0x54, 0x00, 0x02, 0xa2, 0x58, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x25, 0x10, 0x43, 0x00, 0x37, 0x12, 0x00, 0x0c, 0x58, 0x00, 0x02, 0xa2,
- 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe0, 0xff,
- 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x88, 0x80, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x80, 0xa0, 0x00, 0x28, 0x00, 0x30, 0xa6, 0x37,
- 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf,
- 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x90, 0x80, 0x00, 0x24,
- 0x00, 0x51, 0x8e, 0xc0, 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12,
- 0x00, 0x0c, 0x21, 0x80, 0xa0, 0x00, 0x21, 0x20, 0x40, 0x00, 0x2c, 0x00, 0x50,
- 0xa6, 0x21, 0x18, 0x00, 0x02, 0x0f, 0x00, 0x10, 0x32, 0x04, 0x00, 0x02, 0x2e,
- 0x04, 0x00, 0x40, 0x10, 0x00, 0x04, 0x62, 0x30, 0x02, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x01, 0x80, 0x02, 0x3c, 0x21, 0x10,
- 0x50, 0x00, 0xe0, 0xda, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x22,
- 0xa2, 0x08, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x37, 0x12, 0x00, 0x0c,
- 0x0c, 0x00, 0x22, 0xa2, 0x21, 0x20, 0x40, 0x02, 0xa2, 0x22, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf,
- 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xc0, 0x8b, 0x84, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x88, 0xa0, 0x00, 0x21, 0x20,
- 0x40, 0x00, 0x7f, 0xff, 0x02, 0x24, 0x24, 0x10, 0x22, 0x02, 0x0b, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x63,
- 0x00, 0x00, 0xa2, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x81, 0x30,
- 0x00, 0x08, 0x80, 0x00, 0x42, 0x34, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x7f, 0xff, 0x42, 0x30, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c,
- 0xbc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x74, 0x00, 0x00, 0xae, 0x00,
- 0x80, 0x02, 0x3c, 0x40, 0x45, 0x42, 0x24, 0x34, 0x00, 0x02, 0xae, 0x37, 0x12,
- 0x00, 0x0c, 0x2a, 0x00, 0x11, 0xa6, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27,
- 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0xc0, 0x8b, 0x84, 0x8f, 0x2e,
- 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20,
- 0x40, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xbf, 0xaf,
- 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00, 0xc0,
- 0x8b, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x12, 0x00, 0x0c, 0x21, 0x80,
- 0xa0, 0x00, 0x68, 0x00, 0x30, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40,
- 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x20,
- 0x00, 0xbf, 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x80,
- 0x80, 0x00, 0x48, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
- 0x2c, 0x05, 0x00, 0x40, 0x10, 0x08, 0x00, 0x02, 0x24, 0x6b, 0x2e, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x38, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x62, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x65, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00, 0x01, 0x80, 0x03, 0x3c,
- 0x21, 0x18, 0x62, 0x00, 0xb8, 0xfa, 0x63, 0x8c, 0x06, 0x00, 0x02, 0x24, 0x70,
- 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x11, 0x8e, 0xc0, 0x8b,
- 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x40,
- 0x00, 0x0a, 0x00, 0x00, 0xa6, 0x0c, 0x00, 0x00, 0xa6, 0x12, 0x00, 0x00, 0xa6,
- 0x14, 0x00, 0x00, 0xa6, 0x1a, 0x00, 0x00, 0xa6, 0xff, 0xff, 0x02, 0x34, 0x1c,
- 0x00, 0x02, 0xa6, 0x28, 0x00, 0x00, 0xa6, 0x2a, 0x00, 0x00, 0xa6, 0x2c, 0x00,
- 0x00, 0xa6, 0x40, 0x00, 0x00, 0xae, 0x44, 0x00, 0x00, 0xae, 0x20, 0x00, 0x02,
- 0x24, 0x50, 0x00, 0x02, 0xa6, 0x49, 0x00, 0x00, 0xa2, 0x4a, 0x00, 0x00, 0xa2,
- 0x54, 0x00, 0x00, 0xa2, 0x57, 0x00, 0x00, 0xa2, 0x58, 0x00, 0x00, 0xa2, 0x5a,
- 0x00, 0x00, 0xa2, 0x5b, 0x00, 0x00, 0xa2, 0x5c, 0x00, 0x00, 0xa2, 0x5d, 0x00,
- 0x00, 0xa2, 0x5e, 0x00, 0x00, 0xa2, 0x5f, 0x00, 0x00, 0xa2, 0x60, 0x00, 0x00,
- 0xa2, 0x61, 0x00, 0x00, 0xa2, 0x62, 0x00, 0x00, 0xa2, 0x63, 0x00, 0x00, 0xa2,
- 0x68, 0x00, 0x00, 0xa2, 0x6a, 0x00, 0x00, 0xa6, 0x6c, 0x00, 0x00, 0xae, 0x00,
- 0x80, 0x02, 0x3c, 0xbc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x74, 0x00,
- 0x00, 0xae, 0x00, 0x80, 0x02, 0x3c, 0x40, 0x45, 0x42, 0x24, 0x34, 0x00, 0x02,
- 0xae, 0x24, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x20, 0xa2, 0x10, 0x27, 0x02, 0x24, 0x10,
- 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa3, 0x8f, 0xff, 0xff, 0x02,
- 0x24, 0x0d, 0x00, 0x62, 0x10, 0xff, 0xff, 0x03, 0x24, 0x2c, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x10, 0x80, 0x00, 0x02, 0x24, 0x10,
- 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10, 0x00,
- 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xff, 0x43,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x24, 0x2c, 0x00, 0x22, 0xa2,
- 0x10, 0x27, 0x02, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00,
- 0xa3, 0x8f, 0xff, 0xff, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x10, 0xff, 0xff, 0x03,
- 0x24, 0x2c, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x10,
- 0x41, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0xf5, 0xff, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x02,
- 0x24, 0x2c, 0x00, 0x22, 0xa2, 0x09, 0x00, 0x02, 0x24, 0x78, 0x00, 0x22, 0xa2,
- 0x01, 0x80, 0x02, 0x3c, 0xe0, 0xda, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x22, 0xa2, 0x08, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
- 0x22, 0xa2, 0x37, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00,
- 0x02, 0xa2, 0x22, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x20, 0x00, 0xbf, 0x8f,
- 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28,
- 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00,
- 0xb0, 0xaf, 0x48, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
- 0x2c, 0x05, 0x00, 0x40, 0x10, 0x08, 0x00, 0x02, 0x24, 0xc4, 0x2e, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x98, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x00, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x62, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x65, 0x00, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00, 0x01, 0x80, 0x03, 0x3c,
- 0x21, 0x18, 0x62, 0x00, 0xb8, 0xfa, 0x63, 0x8c, 0x06, 0x00, 0x02, 0x24, 0x41,
- 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x90, 0x8c, 0xc0, 0x8b,
- 0x84, 0x8f, 0x2e, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x40,
- 0x00, 0x28, 0x00, 0x00, 0xa2, 0x10, 0x27, 0x02, 0x24, 0x10, 0x00, 0xa2, 0xaf,
- 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10,
- 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa3, 0x8f, 0xff, 0xff, 0x02, 0x24, 0x0d, 0x00,
- 0x62, 0x10, 0xff, 0xff, 0x03, 0x24, 0x2c, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x0a, 0x00, 0x40, 0x10, 0x80, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa2, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10,
- 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xff, 0x43, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x02, 0x24, 0x2c, 0x00, 0x02, 0xa2, 0x10, 0x27, 0x02,
- 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa3, 0x8f, 0xff,
- 0xff, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x10, 0xff, 0xff, 0x03, 0x24, 0x2c, 0x00,
- 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x10, 0x41, 0x00, 0x02,
- 0x24, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24,
- 0x10, 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf5,
- 0xff, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x02, 0x24, 0x2c, 0x00,
- 0x02, 0xa2, 0x09, 0x00, 0x02, 0x24, 0x78, 0x00, 0x02, 0xa2, 0x01, 0x80, 0x02,
- 0x3c, 0xe0, 0xda, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0xa2,
- 0x08, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x37, 0x12, 0x00, 0x0c, 0x0c,
- 0x00, 0x02, 0xa2, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xbf,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x01, 0x80, 0x03, 0x3c,
- 0x90, 0xfa, 0x63, 0x24, 0x23, 0x18, 0xa3, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x00, 0x19, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x1a,
- 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x23, 0x10, 0x02, 0x00, 0x03, 0x11, 0x02, 0x00, 0x65, 0x00, 0x02, 0xa2,
- 0x08, 0x00, 0xc2, 0x28, 0x07, 0x00, 0x40, 0x10, 0x48, 0x00, 0x06, 0xa2, 0x40,
- 0x11, 0x06, 0x00, 0x00, 0x01, 0x42, 0x24, 0x04, 0x00, 0xa3, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0xc1, 0x31, 0x00, 0x08, 0x21, 0x10, 0x43, 0x00, 0x08, 0x00, 0x02,
- 0x24, 0x21, 0x00, 0xc2, 0x14, 0x06, 0x00, 0x02, 0x24, 0x28, 0x00, 0xa3, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x24, 0x24, 0x00,
- 0x02, 0xae, 0x02, 0x00, 0x02, 0x24, 0x2e, 0x00, 0x02, 0xa6, 0x08, 0x00, 0xc2,
- 0x28, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x2e, 0x00, 0x0c,
- 0x21, 0x20, 0x00, 0x02, 0xcd, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xac,
- 0x30, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x3c, 0x8c, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x31, 0x00,
- 0x08, 0x30, 0x00, 0x10, 0xae, 0x3c, 0x8c, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0xae, 0x30,
- 0x00, 0x70, 0xac, 0x3c, 0x8c, 0x90, 0xaf, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00,
- 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x3c, 0x00,
- 0x10, 0xce, 0x35, 0x01, 0x80, 0x0d, 0x3c, 0x00, 0xda, 0xad, 0x25, 0x01, 0xa2,
- 0x08, 0x3c, 0x0c, 0x00, 0x08, 0x35, 0xfb, 0xfe, 0x0c, 0x24, 0xff, 0xfe, 0x0b,
- 0x24, 0xe1, 0x00, 0x0a, 0x3c, 0xff, 0xfb, 0x09, 0x24, 0x00, 0x00, 0xa7, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0xee, 0x00, 0x09, 0x00, 0x62, 0x2c, 0x2e,
- 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x4d, 0x00, 0x00, 0x00,
- 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc8, 0x8f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x32, 0x00, 0x08,
- 0x24, 0x10, 0x4c, 0x00, 0xc8, 0x8f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x24,
- 0x10, 0x4b, 0x00, 0x1d, 0x32, 0x00, 0x08, 0x04, 0x00, 0x42, 0x34, 0xc8, 0x8f,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x32, 0x00, 0x08, 0x04, 0x01, 0x42,
- 0x34, 0x02, 0x00, 0xa3, 0x94, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x62, 0x00, 0x12, 0x18, 0x00, 0x00, 0x42, 0x10, 0x03, 0x00, 0x21,
- 0x10, 0x4a, 0x00, 0x1b, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x32, 0x00, 0x08, 0x29, 0x00, 0x82, 0xa0,
- 0xc8, 0x8f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x32, 0x00, 0x08, 0x24,
- 0x10, 0x49, 0x00, 0xc8, 0x8f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x42, 0x34, 0xc8, 0x8f, 0x82, 0xaf, 0x00, 0x00, 0x02, 0xa5, 0xee, 0x31, 0x00,
- 0x08, 0x04, 0x00, 0xa5, 0x24, 0x21, 0x18, 0x87, 0x00, 0x02, 0x00, 0xa2, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xa0, 0xee, 0x31, 0x00, 0x08, 0x04,
- 0x00, 0xa5, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff,
- 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x00, 0xa1, 0x04, 0x3c, 0x01, 0x80, 0x05,
- 0x3c, 0xf0, 0xda, 0xa5, 0x24, 0xe4, 0x31, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x00,
- 0x00, 0xa1, 0x04, 0x3c, 0x40, 0x00, 0x84, 0x34, 0x01, 0x80, 0x05, 0x3c, 0x48,
- 0xdb, 0xa5, 0x24, 0xe4, 0x31, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x00, 0x00, 0xa1,
- 0x04, 0x3c, 0x00, 0x01, 0x84, 0x34, 0x01, 0x80, 0x05, 0x3c, 0x9c, 0xdb, 0xa5,
- 0x24, 0xe4, 0x31, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x00, 0x00, 0xa1, 0x04, 0x3c,
- 0x40, 0x01, 0x84, 0x34, 0x01, 0x80, 0x05, 0x3c, 0xa8, 0xdb, 0xa5, 0x24, 0xe4,
- 0x31, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00,
- 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd,
- 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf,
- 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x90, 0x80, 0x00, 0x4e, 0x00, 0xc6, 0x2c, 0x04,
- 0x00, 0xc0, 0x10, 0x21, 0x88, 0xa0, 0x00, 0x4e, 0x00, 0x22, 0x2e, 0x05, 0x00,
- 0x40, 0x14, 0x40, 0x80, 0x11, 0x00, 0xbc, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00,
- 0x0c, 0x6e, 0x02, 0x05, 0x24, 0x40, 0x80, 0x11, 0x00, 0x21, 0x80, 0x11, 0x02,
- 0x80, 0x80, 0x10, 0x00, 0x01, 0x80, 0x02, 0x3c, 0xa8, 0xdc, 0x42, 0x24, 0x21,
- 0x80, 0x02, 0x02, 0x80, 0x11, 0x12, 0x00, 0x00, 0xa1, 0x04, 0x3c, 0x40, 0x00,
- 0x84, 0x34, 0x00, 0x00, 0x05, 0x8e, 0x04, 0x00, 0x06, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0xe4, 0x31, 0x00, 0x0c, 0x21, 0x20, 0x44, 0x00, 0x08, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x10, 0x01, 0xa2, 0x03, 0x3c, 0x0c,
- 0x00, 0x63, 0x34, 0xc8, 0x8f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x42, 0x34, 0xc8, 0x8f, 0x82, 0xaf, 0x75, 0x32, 0x00, 0x08, 0x00, 0x00, 0x62,
- 0xa4, 0x01, 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34, 0xc8, 0x8f, 0x83, 0x8f,
- 0xfd, 0xff, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, 0xc8, 0x8f, 0x83, 0xaf, 0x00,
- 0x00, 0x43, 0xa4, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x89, 0x8c, 0x40, 0x00, 0x88, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x19, 0x08, 0x00, 0x1c, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x38, 0x62, 0x00, 0xfd, 0xff, 0x02, 0x3c, 0x00, 0xff,
- 0x42, 0x34, 0x21, 0x10, 0xa2, 0x00, 0x20, 0x00, 0x83, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0x18, 0x62, 0x00, 0x2b, 0x10, 0x66, 0x00, 0x0d, 0x00, 0x40, 0x10,
- 0x0e, 0x00, 0xe2, 0x24, 0x02, 0x00, 0xe2, 0xa4, 0x04, 0x00, 0xe5, 0xac, 0x08,
- 0x00, 0xe3, 0xa4, 0x0a, 0x00, 0xe0, 0xa0, 0x20, 0x00, 0x82, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x00, 0xe2, 0xac, 0x23, 0x10, 0xc3, 0x00, 0x14, 0x00, 0xe2,
- 0xa4, 0x80, 0x00, 0x02, 0x24, 0xa0, 0x32, 0x00, 0x08, 0x16, 0x00, 0xe2, 0xa0,
- 0x0e, 0x00, 0xe2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xe2, 0xa4, 0x04,
- 0x00, 0xe5, 0xac, 0x08, 0x00, 0xe6, 0xa4, 0x80, 0x00, 0x02, 0x24, 0x0a, 0x00,
- 0xe2, 0xa0, 0x14, 0x00, 0xe0, 0xa4, 0x0e, 0x00, 0xe2, 0x94, 0x00, 0x00, 0x00,
- 0x00, 0x54, 0x00, 0x22, 0xa5, 0x60, 0x00, 0x22, 0x91, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x42, 0x30, 0x07, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x78,
- 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0xb0, 0x32, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0x02, 0x00, 0x02,
- 0x24, 0x60, 0x00, 0x22, 0xa1, 0x01, 0x00, 0x08, 0x25, 0x08, 0x00, 0x02, 0x29,
- 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, 0x00, 0x00, 0x8c,
- 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x8c, 0x00,
- 0x82, 0xac, 0x88, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xc2,
- 0x00, 0x88, 0x00, 0x82, 0xac, 0x40, 0x00, 0x88, 0xac, 0xbc, 0x8b, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x78, 0x00, 0x82, 0xac, 0x04,
- 0x00, 0x86, 0x8c, 0x08, 0x00, 0x85, 0x8c, 0x11, 0x00, 0x02, 0x24, 0x18, 0x00,
- 0xc2, 0xa0, 0x01, 0x00, 0x02, 0x24, 0x29, 0x00, 0xa2, 0xa0, 0x38, 0x00, 0x83,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x18, 0x00, 0x83, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x02, 0x00, 0x42, 0x24, 0x10, 0x00, 0xa2, 0xa4, 0x02, 0x00,
- 0x02, 0x24, 0x20, 0x00, 0xa2, 0xa0, 0x12, 0x00, 0x02, 0x24, 0x08, 0x00, 0xe0,
- 0x03, 0x18, 0x00, 0xc2, 0xa0, 0xc0, 0xff, 0xbd, 0x27, 0x3c, 0x00, 0xbf, 0xaf,
- 0x38, 0x00, 0xbe, 0xaf, 0x34, 0x00, 0xb7, 0xaf, 0x30, 0x00, 0xb6, 0xaf, 0x2c,
- 0x00, 0xb5, 0xaf, 0x28, 0x00, 0xb4, 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x20, 0x00,
- 0xb2, 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x90, 0x80,
- 0x00, 0x08, 0x00, 0x47, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xa7, 0xaf,
- 0x34, 0x00, 0x44, 0x8e, 0x30, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x1a,
- 0x00, 0x82, 0x10, 0x40, 0x18, 0x04, 0x00, 0x24, 0x00, 0x42, 0x8e, 0x21, 0x18,
- 0x64, 0x00, 0xc0, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x10, 0x00, 0x62,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x00, 0x06, 0x24, 0x30, 0x00, 0x45, 0x8e, 0x01, 0x00, 0x84, 0x24, 0x02,
- 0x00, 0x86, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x0a, 0x00,
- 0x85, 0x10, 0x40, 0x18, 0x04, 0x00, 0x24, 0x00, 0x42, 0x8e, 0x21, 0x18, 0x64,
- 0x00, 0xc0, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x10, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0xf4, 0xff, 0x40, 0x10, 0x01, 0x00, 0x84, 0x24, 0xff,
- 0xff, 0x84, 0x24, 0x34, 0x00, 0x44, 0xae, 0x41, 0x00, 0x02, 0x24, 0x10, 0x00,
- 0xa7, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe2, 0xa0, 0x10, 0x00, 0xe2,
- 0x94, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5e, 0x30, 0x38, 0x00, 0x54, 0x8e,
- 0x3c, 0x00, 0x57, 0x8e, 0x18, 0x00, 0x50, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x02, 0x32, 0x23, 0x88, 0xc2, 0x03, 0xaa, 0xaa, 0x02, 0x3c, 0xab, 0xaa,
- 0x42, 0x34, 0x19, 0x00, 0x22, 0x02, 0x10, 0x38, 0x00, 0x00, 0xc2, 0x88, 0x07,
- 0x00, 0x01, 0x02, 0x22, 0x2e, 0x05, 0x00, 0x40, 0x14, 0x40, 0x10, 0x11, 0x00,
- 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x09, 0x01, 0x05, 0x24, 0x40,
- 0x10, 0x11, 0x00, 0x21, 0x10, 0x51, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10,
- 0x02, 0x02, 0x02, 0x00, 0x42, 0x24, 0xff, 0xff, 0x42, 0x30, 0x05, 0x00, 0xc2,
- 0x13, 0x23, 0x28, 0x34, 0x02, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c,
- 0x0a, 0x01, 0x05, 0x24, 0x23, 0x28, 0x34, 0x02, 0x01, 0x02, 0xa5, 0x24, 0x80,
- 0xff, 0x04, 0x3c, 0xe1, 0x3f, 0x84, 0x34, 0x19, 0x00, 0xa4, 0x00, 0x10, 0x38,
- 0x00, 0x00, 0x42, 0x1a, 0x07, 0x00, 0x40, 0x12, 0x03, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x23, 0x28, 0xa2, 0x00, 0x23, 0x18, 0xf4, 0x02, 0x01, 0x02, 0x63, 0x24,
- 0x19, 0x00, 0x64, 0x00, 0x10, 0x38, 0x00, 0x00, 0x42, 0x22, 0x07, 0x00, 0x40,
- 0x12, 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, 0x23, 0x18, 0x62, 0x00, 0x2b, 0x18,
- 0x65, 0x00, 0x05, 0x00, 0x60, 0x10, 0x21, 0xb0, 0x00, 0x00, 0xd0, 0x8a, 0x84,
- 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x0b, 0x01, 0x05, 0x24, 0x21, 0xb0, 0x00, 0x00,
- 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x54, 0x00, 0x80, 0x10, 0x02, 0x00, 0x18,
- 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x43, 0x00, 0x04, 0x00,
- 0x15, 0x8e, 0x21, 0x98, 0x00, 0x00, 0x02, 0x00, 0x02, 0x26, 0xff, 0xff, 0x42,
- 0x30, 0xb1, 0x00, 0x5e, 0x10, 0x06, 0x00, 0xc2, 0x2a, 0x05, 0x00, 0x97, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c,
- 0x00, 0x0c, 0x1d, 0x01, 0x05, 0x24, 0x01, 0x00, 0x94, 0x26, 0x01, 0x02, 0x82,
- 0x2a, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0xa0, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x96, 0x0a, 0x00, 0x10, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0e,
- 0x00, 0x00, 0x16, 0x21, 0x98, 0x62, 0x02, 0x00, 0x01, 0x07, 0x24, 0x05, 0x00,
- 0x47, 0x10, 0x40, 0x10, 0x14, 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00,
- 0x0c, 0x25, 0x01, 0x05, 0x24, 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x54, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x18, 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x33, 0x00, 0x08, 0x21, 0x80, 0x43, 0x00, 0x80, 0x00, 0x02, 0x32, 0x04, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00,
- 0x0c, 0x2a, 0x01, 0x05, 0x24, 0xc0, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x10, 0x62, 0x02, 0xc0, 0x00, 0x42, 0xae, 0xb8, 0x00, 0x42, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xb8, 0x00, 0x42, 0xae, 0x7c, 0x00,
- 0x02, 0x32, 0x2d, 0x00, 0x40, 0x10, 0x40, 0x00, 0x02, 0x32, 0x06, 0x00, 0x40,
- 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x8c, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x20,
- 0x00, 0x02, 0x32, 0x06, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x90, 0x0d,
- 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0x00, 0x00, 0x62, 0xac, 0x10, 0x00, 0x02, 0x32, 0x06, 0x00, 0x40, 0x10,
- 0x00, 0xa0, 0x03, 0x3c, 0x9c, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x08, 0x00,
- 0x02, 0x32, 0x06, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x94, 0x0d, 0x63,
- 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
- 0x00, 0x00, 0x62, 0xac, 0x04, 0x00, 0x02, 0x32, 0x06, 0x00, 0x40, 0x10, 0x00,
- 0xa0, 0x03, 0x3c, 0x98, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0xc8, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xfa, 0x33, 0x00, 0x08,
- 0xc8, 0x00, 0x42, 0xae, 0x00, 0x00, 0xa3, 0x8e, 0x22, 0x33, 0x02, 0x3c, 0x00,
- 0x11, 0x42, 0x34, 0x14, 0x00, 0x62, 0x14, 0x21, 0x30, 0xb3, 0x02, 0xfd, 0xff,
- 0x02, 0x3c, 0x00, 0xff, 0x42, 0x34, 0x21, 0x30, 0xc2, 0x00, 0x20, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x30, 0xc2, 0x00, 0x05, 0x00, 0xc0, 0x18,
- 0x02, 0x00, 0x05, 0x3c, 0x00, 0x01, 0xa5, 0x34, 0x21, 0x20, 0x40, 0x00, 0x70,
- 0x11, 0x00, 0x0c, 0x21, 0x28, 0x45, 0x00, 0x21, 0x20, 0xa0, 0x02, 0xf2, 0x23,
- 0x00, 0x0c, 0x21, 0x28, 0x60, 0x02, 0x3b, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03,
- 0x3c, 0xe1, 0x33, 0x00, 0x08, 0xfc, 0x0d, 0x63, 0x34, 0xb4, 0x90, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x21, 0x00, 0x0c, 0x64, 0x00, 0x04, 0x24, 0xb4, 0x90, 0x83, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x18, 0x62, 0x00, 0x03, 0x00, 0x60, 0x14, 0x00, 0xa0, 0x03,
- 0x3c, 0xe1, 0x33, 0x00, 0x08, 0xd8, 0x0d, 0x63, 0x34, 0x30, 0x00, 0x50, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, 0x00, 0x21, 0x10, 0x50, 0x00, 0xc0,
- 0x10, 0x02, 0x00, 0x24, 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x88,
- 0x43, 0x00, 0x01, 0x00, 0x10, 0x26, 0x40, 0x00, 0x02, 0x24, 0x02, 0x00, 0x02,
- 0x16, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x00, 0x00, 0x34, 0x00, 0x42, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x16, 0x00, 0xa0, 0x03, 0x3c, 0xb0,
- 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0xfa, 0x33, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0x10, 0x00, 0x22,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x7f, 0x01, 0x05, 0x24, 0x38,
- 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x22, 0xae, 0x08, 0x00,
- 0x35, 0xae, 0x14, 0x00, 0x33, 0xae, 0x21, 0x20, 0x40, 0x02, 0x92, 0x26, 0x00,
- 0x0c, 0x21, 0x28, 0x20, 0x02, 0x10, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x50, 0xae, 0x38,
- 0x00, 0x54, 0xae, 0x41, 0x33, 0x00, 0x08, 0x01, 0x00, 0xd6, 0x26, 0x03, 0x00,
- 0x40, 0x14, 0x80, 0x10, 0x16, 0x00, 0x05, 0x00, 0x16, 0x24, 0x80, 0x10, 0x16,
- 0x00, 0x00, 0xa0, 0x03, 0x3c, 0x48, 0x0d, 0x63, 0x34, 0x21, 0x10, 0x43, 0x00,
- 0x00, 0x00, 0x43, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x23,
- 0xb0, 0x97, 0x02, 0x02, 0x00, 0xc1, 0x06, 0x00, 0x00, 0x43, 0xac, 0x01, 0x02,
- 0xd6, 0x26, 0x01, 0x02, 0xc2, 0x2a, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0xa0, 0x01, 0x05, 0x24,
- 0x01, 0x80, 0x02, 0x3c, 0x80, 0x24, 0x42, 0x24, 0x80, 0x18, 0x16, 0x00, 0x21,
- 0x18, 0x62, 0x00, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x30, 0x00, 0x42, 0x8e, 0x34, 0x00, 0x44,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x44, 0x10, 0x40, 0x10, 0x04, 0x00,
- 0x24, 0x00, 0x43, 0x8e, 0x21, 0x10, 0x44, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x0c, 0x00, 0x57, 0x8c, 0x2a, 0x34, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0x10, 0x00, 0x02, 0x17, 0x24, 0xff, 0xff, 0x57, 0x24, 0x3c, 0x00, 0x42, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xe2, 0x12, 0x40, 0x10, 0x17, 0x00, 0x21,
- 0x10, 0x57, 0x00, 0x80, 0x10, 0x02, 0x00, 0x18, 0x00, 0x43, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x02, 0x00, 0x42, 0x24, 0x10, 0x00, 0xa7,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xe2, 0xa4, 0x3c, 0x00, 0x57, 0xae,
- 0x10, 0x00, 0xa7, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe2, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x22, 0x00, 0x42, 0x30, 0x02, 0x00, 0x03, 0x24, 0x0a, 0x00,
- 0x43, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x80, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac,
- 0x21, 0x00, 0x02, 0x24, 0x20, 0x00, 0xe2, 0xa0, 0xc2, 0x32, 0x00, 0x0c, 0x21,
- 0x20, 0x40, 0x02, 0x3c, 0x00, 0xbf, 0x8f, 0x38, 0x00, 0xbe, 0x8f, 0x34, 0x00,
- 0xb7, 0x8f, 0x30, 0x00, 0xb6, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4,
- 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f,
- 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27, 0xd0,
- 0xff, 0xbd, 0x27, 0x2c, 0x00, 0xbf, 0xaf, 0x28, 0x00, 0xb6, 0xaf, 0x24, 0x00,
- 0xb5, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2,
- 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x80, 0x00,
- 0x00, 0xa0, 0x02, 0x3c, 0x44, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac, 0x04, 0x00,
- 0x24, 0x8e, 0x08, 0x00, 0x25, 0x8e, 0x04, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x42, 0x30, 0x08, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x02, 0x3c,
- 0xa4, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac, 0x00, 0x80, 0x02, 0x34, 0x04, 0x00,
- 0x82, 0xa4, 0x41, 0x00, 0x02, 0x24, 0x60, 0x00, 0xa2, 0xa0, 0x50, 0x00, 0xa2,
- 0x94, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x30, 0x44, 0x00, 0x33, 0x8e,
- 0x40, 0x00, 0x34, 0x8e, 0x1c, 0x00, 0x30, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x02, 0x32, 0x23, 0x90, 0xa2, 0x02, 0x82, 0x91, 0x12, 0x00, 0x08, 0x00,
- 0x42, 0x2e, 0x05, 0x00, 0x40, 0x14, 0x80, 0x11, 0x12, 0x00, 0xd0, 0x8a, 0x84,
- 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x01, 0x02, 0x05, 0x24, 0x80, 0x11, 0x12, 0x00,
- 0x21, 0x18, 0x02, 0x02, 0x02, 0x00, 0x62, 0x24, 0xff, 0xff, 0x42, 0x30, 0x07,
- 0x00, 0xa2, 0x12, 0x0e, 0x00, 0x62, 0x24, 0xff, 0xff, 0x42, 0x30, 0x05, 0x00,
- 0xa2, 0x12, 0x23, 0x18, 0x53, 0x02, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00,
- 0x0c, 0x07, 0x02, 0x05, 0x24, 0x23, 0x18, 0x53, 0x02, 0x08, 0x00, 0x63, 0x24,
- 0x07, 0x00, 0x63, 0x30, 0x23, 0x10, 0x93, 0x02, 0x08, 0x00, 0x42, 0x24, 0x07,
- 0x00, 0x42, 0x30, 0x2b, 0x10, 0x43, 0x00, 0x05, 0x00, 0x40, 0x10, 0x80, 0x19,
- 0x13, 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00, 0x0c, 0x09, 0x02, 0x05,
- 0x24, 0x80, 0x19, 0x13, 0x00, 0x1c, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x80, 0x62, 0x00, 0x02, 0x00, 0x02, 0x26, 0xff, 0xff, 0x42, 0x30, 0x23,
- 0x10, 0xa2, 0x02, 0x40, 0x00, 0x42, 0x2c, 0x61, 0x00, 0x40, 0x14, 0x21, 0xa0,
- 0x00, 0x00, 0x03, 0x00, 0x16, 0x24, 0x40, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x62, 0x16, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8a, 0x84, 0x27,
- 0x24, 0x0c, 0x00, 0x0c, 0x1c, 0x02, 0x05, 0x24, 0x08, 0x00, 0x03, 0x96, 0x14,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x62, 0x00, 0x18, 0x00,
- 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x76, 0x10, 0x04, 0x00, 0x02,
- 0x24, 0x22, 0x00, 0x62, 0x10, 0x01, 0x00, 0x02, 0x24, 0xe7, 0x34, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x10, 0x8e, 0x84, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0xff, 0x42, 0x24, 0x08, 0x00, 0x03, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x84, 0x00, 0x22, 0xae, 0x04, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x0a, 0x00, 0x42, 0x2c,
- 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24,
- 0x0c, 0x00, 0x0c, 0x39, 0x02, 0x05, 0x24, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x1c, 0x00, 0x40, 0x14, 0x04, 0x00, 0x02,
- 0xae, 0xb0, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xae,
- 0xb0, 0x90, 0x90, 0xaf, 0x64, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0xec, 0x34, 0x00, 0x08, 0x64, 0x00, 0x22, 0xae, 0x20, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x56, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8a, 0x84, 0x27,
- 0x24, 0x0c, 0x00, 0x0c, 0x54, 0x02, 0x05, 0x24, 0x20, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0xec, 0x34, 0x00, 0x08, 0x10, 0x00, 0x40, 0xac, 0x04, 0x00,
- 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x8a, 0x84, 0x27, 0x24, 0x0c, 0x00,
- 0x0c, 0x5a, 0x02, 0x05, 0x24, 0x88, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x23, 0x10, 0x52, 0x00, 0x88, 0x00, 0x22, 0xae, 0xb0, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x10, 0x42, 0x02, 0xb0, 0x00, 0x22, 0xae, 0xa8, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xa8, 0x00, 0x22,
- 0xae, 0x01, 0x00, 0x73, 0x26, 0x08, 0x00, 0x62, 0x2e, 0x02, 0x00, 0x40, 0x14,
- 0x01, 0x00, 0x94, 0x26, 0x21, 0x98, 0x00, 0x00, 0x80, 0x19, 0x13, 0x00, 0x1c,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x62, 0x00, 0x02, 0x00,
- 0x02, 0x26, 0xff, 0xff, 0x42, 0x30, 0x23, 0x10, 0xa2, 0x02, 0x40, 0x00, 0x42,
- 0x2c, 0xa2, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x33, 0xae,
- 0xbc, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x22, 0xae, 0x8c,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x54, 0x00, 0x8c, 0x00,
- 0x22, 0xae, 0x2c, 0x00, 0xbf, 0x8f, 0x28, 0x00, 0xb6, 0x8f, 0x24, 0x00, 0xb5,
- 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30,
- 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00,
- 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x00, 0xa0, 0x03,
- 0x3c, 0x40, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x00, 0xa1, 0x02, 0x3c, 0x20,
- 0x00, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x50, 0x30, 0x1b, 0x00,
- 0x00, 0x12, 0x00, 0xa1, 0x12, 0x3c, 0x01, 0x80, 0x11, 0x3c, 0x4c, 0xf9, 0x31,
- 0x26, 0x0c, 0x08, 0x02, 0x32, 0x05, 0x00, 0x40, 0x10, 0x03, 0x03, 0x02, 0x32,
- 0x01, 0x80, 0x04, 0x3c, 0x55, 0x34, 0x00, 0x0c, 0x20, 0xf9, 0x84, 0x24, 0x03,
- 0x03, 0x02, 0x32, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
- 0x04, 0x3c, 0xd7, 0x32, 0x00, 0x0c, 0x20, 0xf9, 0x84, 0x24, 0x00, 0x00, 0x22,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1f, 0x00, 0x0c, 0xd4, 0xff, 0x24, 0x26, 0x20,
- 0x00, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x50, 0x30, 0xea, 0xff,
- 0x00, 0x16, 0x0c, 0x08, 0x02, 0x32, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x20, 0x00, 0xbd, 0x27, 0xc8, 0xff, 0xbd, 0x27, 0x30, 0x00, 0xbf, 0xaf, 0x2c,
- 0x00, 0xb5, 0xaf, 0x28, 0x00, 0xb4, 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x20, 0x00,
- 0xb2, 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x00, 0xa0, 0x04,
- 0x3c, 0x40, 0x0d, 0x84, 0x34, 0x00, 0xa0, 0x05, 0x3c, 0x35, 0x21, 0x00, 0x0c,
- 0x00, 0x0e, 0xa5, 0x34, 0x01, 0x80, 0x03, 0x3c, 0x84, 0x2c, 0x63, 0x24, 0x00,
- 0xa0, 0x02, 0x3c, 0x25, 0x18, 0x62, 0x00, 0xb0, 0x8f, 0x83, 0xaf, 0x00, 0x02,
- 0x62, 0x24, 0x26, 0x10, 0x43, 0x00, 0xff, 0xff, 0x04, 0x3c, 0x24, 0x10, 0x44,
- 0x00, 0x04, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x3c, 0x21, 0x10, 0x62, 0x00,
- 0x24, 0x10, 0x44, 0x00, 0xb0, 0x8f, 0x82, 0xaf, 0xb0, 0x8f, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0x90, 0x82, 0xaf, 0x00, 0x02, 0x43, 0x24, 0xb0, 0x8f,
- 0x83, 0xaf, 0x0c, 0x1a, 0x42, 0x24, 0x26, 0x10, 0x43, 0x00, 0xff, 0xff, 0x04,
- 0x3c, 0x24, 0x10, 0x44, 0x00, 0x04, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x3c,
- 0x21, 0x10, 0x62, 0x00, 0x24, 0x10, 0x44, 0x00, 0xb0, 0x8f, 0x82, 0xaf, 0xb0,
- 0x8f, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x84, 0x90, 0x85, 0xaf, 0x0b, 0x19,
- 0xa5, 0x24, 0x00, 0xff, 0x02, 0x24, 0x24, 0x28, 0xa2, 0x00, 0xb0, 0x8f, 0x85,
- 0xaf, 0x7c, 0x90, 0x85, 0xaf, 0x02, 0x00, 0x02, 0x3c, 0x00, 0x14, 0x42, 0x34,
- 0x21, 0x28, 0xa2, 0x00, 0xb0, 0x8f, 0x85, 0xaf, 0x01, 0x80, 0x02, 0x3c, 0x84,
- 0x2c, 0x42, 0x24, 0x00, 0xa0, 0x04, 0x3c, 0x35, 0x21, 0x00, 0x0c, 0x25, 0x20,
- 0x44, 0x00, 0x29, 0x32, 0x00, 0x0c, 0x21, 0x98, 0x00, 0x00, 0x01, 0x80, 0x12,
- 0x3c, 0x20, 0xf9, 0x52, 0x26, 0x04, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x74, 0x00, 0x40, 0x18, 0x00, 0xa1, 0x15, 0x3c, 0x02, 0x00, 0x14, 0x24, 0x40,
- 0x20, 0x13, 0x00, 0x21, 0x20, 0x93, 0x00, 0x40, 0x2a, 0x04, 0x00, 0x01, 0x80,
- 0x02, 0x3c, 0x90, 0x1a, 0x42, 0x24, 0x21, 0x10, 0xa2, 0x00, 0x24, 0x00, 0x42,
- 0xae, 0x40, 0x11, 0x13, 0x00, 0x21, 0x10, 0x53, 0x00, 0x80, 0x10, 0x02, 0x00,
- 0x21, 0x10, 0x53, 0x00, 0x80, 0x12, 0x02, 0x00, 0x7c, 0x90, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, 0x20, 0x00, 0x42, 0xae, 0x40, 0x12,
- 0x13, 0x00, 0xac, 0x90, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x1c, 0x00, 0x42, 0xae, 0x21, 0x20, 0x85, 0x00, 0x80, 0x20, 0x04, 0x00,
- 0x84, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x82, 0x00, 0x18,
- 0x00, 0x44, 0xae, 0x1c, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
- 0x43, 0x24, 0x02, 0x00, 0x42, 0x24, 0x02, 0x00, 0x62, 0xa4, 0x0e, 0x00, 0x62,
- 0xa4, 0x07, 0x00, 0x04, 0x24, 0x21, 0x10, 0x60, 0x00, 0xc0, 0xff, 0x63, 0x24,
- 0x02, 0x00, 0x42, 0x24, 0x02, 0x00, 0x62, 0xa4, 0xff, 0xff, 0x84, 0x24, 0xfa,
- 0xff, 0x80, 0x14, 0x0e, 0x00, 0x62, 0xa4, 0x18, 0x00, 0x46, 0x8e, 0x20, 0x00,
- 0x42, 0x8e, 0x02, 0x00, 0x04, 0x3c, 0x00, 0x18, 0xc3, 0x24, 0x21, 0x20, 0x44,
- 0x00, 0x04, 0x00, 0x64, 0xac, 0x02, 0x00, 0xc2, 0x24, 0x02, 0x00, 0x62, 0xa4,
- 0x00, 0x02, 0x05, 0x24, 0x21, 0x30, 0x60, 0x00, 0xf4, 0xff, 0x63, 0x24, 0x00,
- 0xff, 0x84, 0x24, 0x04, 0x00, 0x64, 0xac, 0x02, 0x00, 0xc2, 0x24, 0xff, 0xff,
- 0xa5, 0x24, 0xf9, 0xff, 0xa0, 0x14, 0x02, 0x00, 0x62, 0xa4, 0x3c, 0x00, 0x40,
- 0xae, 0x01, 0x00, 0x02, 0x24, 0x38, 0x00, 0x42, 0xae, 0x00, 0x00, 0x55, 0xae,
- 0x80, 0x89, 0x13, 0x00, 0x40, 0x00, 0x31, 0x26, 0x21, 0x88, 0x35, 0x02, 0x04,
- 0x00, 0x51, 0xae, 0xc0, 0x81, 0x13, 0x00, 0x00, 0x01, 0x10, 0x26, 0x21, 0x80,
- 0x15, 0x02, 0x08, 0x00, 0x50, 0xae, 0x48, 0x00, 0x45, 0x8e, 0x4c, 0x00, 0x46,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x46, 0x32, 0x00, 0x0c, 0x21, 0x20, 0x60, 0x02,
- 0x18, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x24, 0x02,
- 0x14, 0x02, 0x00, 0x0c, 0x00, 0x02, 0xa2, 0x18, 0x00, 0x42, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x42, 0x24, 0x14, 0x00, 0x02, 0xa6, 0x18, 0x00, 0x42,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x42, 0x24, 0x10, 0x00, 0x02, 0xa6,
- 0x00, 0x01, 0x02, 0x24, 0x18, 0x00, 0x02, 0xa6, 0x1c, 0x00, 0x42, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x24, 0x02, 0x14, 0x02, 0x00, 0x4c, 0x00,
- 0x02, 0xa2, 0x1c, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42,
- 0x24, 0x50, 0x00, 0x02, 0xa6, 0x1c, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x42, 0x24, 0x54, 0x00, 0x02, 0xa6, 0x20, 0x00, 0x14, 0xa2, 0x60,
- 0x00, 0x14, 0xa2, 0x12, 0x00, 0x02, 0x24, 0x18, 0x00, 0x22, 0xa2, 0x18, 0x00,
- 0x34, 0xa2, 0x01, 0x00, 0x73, 0x26, 0x04, 0x90, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x2a, 0x10, 0x62, 0x02, 0x8f, 0xff, 0x40, 0x14, 0x68, 0x01, 0x52, 0x26,
- 0x30, 0x00, 0xbf, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f, 0x24,
- 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00,
- 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00, 0xbd, 0x27, 0x2e, 0x2e, 0x2f,
- 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x00, 0x00,
- 0x94, 0x53, 0x00, 0x80, 0x94, 0x53, 0x00, 0x80, 0xdc, 0x59, 0x00, 0x80, 0xdc,
- 0x59, 0x00, 0x80, 0xa4, 0x53, 0x00, 0x80, 0xdc, 0x53, 0x00, 0x80, 0xe4, 0x53,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x56, 0x00, 0x80, 0x6c, 0x56, 0x00,
- 0x80, 0x00, 0x57, 0x00, 0x80, 0x7c, 0x56, 0x00, 0x80, 0xb4, 0x57, 0x00, 0x80,
- 0xf0, 0x57, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x62, 0x00, 0x80, 0xbc, 0x65, 0x00, 0x80, 0xec, 0x65, 0x00, 0x80, 0x5c, 0x66,
- 0x00, 0x80, 0xcc, 0x66, 0x00, 0x80, 0x40, 0x67, 0x00, 0x80, 0x54, 0x67, 0x00,
- 0x80, 0x68, 0x67, 0x00, 0x80, 0x7c, 0x67, 0x00, 0x80, 0x90, 0x67, 0x00, 0x80,
- 0xa4, 0x67, 0x00, 0x80, 0xec, 0x67, 0x00, 0x80, 0xfc, 0x67, 0x00, 0x80, 0x20,
- 0x68, 0x00, 0x80, 0x30, 0x68, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x69,
- 0x00, 0x80, 0xfc, 0x6b, 0x00, 0x80, 0x2c, 0x6c, 0x00, 0x80, 0x9c, 0x6c, 0x00,
- 0x80, 0x0c, 0x6d, 0x00, 0x80, 0x80, 0x6d, 0x00, 0x80, 0x94, 0x6d, 0x00, 0x80,
- 0xa8, 0x6d, 0x00, 0x80, 0xbc, 0x6d, 0x00, 0x80, 0xd0, 0x6d, 0x00, 0x80, 0xe4,
- 0x6d, 0x00, 0x80, 0x2c, 0x6e, 0x00, 0x80, 0x3c, 0x6e, 0x00, 0x80, 0x60, 0x6e,
- 0x00, 0x80, 0x70, 0x6e, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x6f, 0x00,
- 0x80, 0x1c, 0x6f, 0x00, 0x80, 0x1c, 0x6f, 0x00, 0x80, 0x1c, 0x6f, 0x00, 0x80,
- 0x1c, 0x6f, 0x00, 0x80, 0x1c, 0x6f, 0x00, 0x80, 0x1c, 0x6f, 0x00, 0x80, 0x1c,
- 0x6f, 0x00, 0x80, 0x40, 0x6f, 0x00, 0x80, 0x5c, 0x6f, 0x00, 0x80, 0x9c, 0x70,
- 0x00, 0x80, 0x20, 0x71, 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73, 0x00,
- 0x80, 0x0c, 0x73, 0x00, 0x80, 0x6c, 0x71, 0x00, 0x80, 0x9c, 0x71, 0x00, 0x80,
- 0x9c, 0x71, 0x00, 0x80, 0x9c, 0x71, 0x00, 0x80, 0x9c, 0x71, 0x00, 0x80, 0xc4,
- 0x71, 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73,
- 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73, 0x00,
- 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80, 0x0c, 0x73, 0x00, 0x80,
- 0x04, 0x73, 0x00, 0x80, 0xbc, 0x71, 0x00, 0x80, 0x68, 0x75, 0x00, 0x80, 0x50,
- 0x76, 0x00, 0x80, 0x68, 0x75, 0x00, 0x80, 0x70, 0x75, 0x00, 0x80, 0x50, 0x76,
- 0x00, 0x80, 0x98, 0x75, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00,
- 0x80, 0x68, 0x75, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80,
- 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x50,
- 0x76, 0x00, 0x80, 0xec, 0x75, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x50, 0x76,
- 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x98, 0x75, 0x00, 0x80, 0x50, 0x76, 0x00,
- 0x80, 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0xec, 0x75, 0x00, 0x80,
- 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x50, 0x76, 0x00, 0x80, 0x98,
- 0x75, 0x00, 0x80, 0x9c, 0x94, 0x00, 0x80, 0x38, 0x95, 0x00, 0x80, 0x8c, 0x95,
- 0x00, 0x80, 0x78, 0x95, 0x00, 0x80, 0x78, 0x95, 0x00, 0x80, 0x78, 0x95, 0x00,
- 0x80, 0x78, 0x95, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xc8, 0x00, 0x80,
- 0x18, 0xc8, 0x00, 0x80, 0x84, 0xc8, 0x00, 0x80, 0x84, 0xc8, 0x00, 0x80, 0xe4,
- 0xc7, 0x00, 0x80, 0x08, 0xc8, 0x00, 0x80, 0xf4, 0xc7, 0x00, 0x80, 0x58, 0xc8,
- 0x00, 0x80, 0x68, 0xc8, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x39, 0x77, 0x3e, 0x38, 0x3e, 0x73,
- 0x39, 0x73, 0x39, 0x79, 0x3f, 0x00, 0x06, 0x00, 0x5b, 0x00, 0x4f, 0x00, 0x66,
- 0x00, 0x6d, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x67, 0x00, 0x77, 0x00,
- 0x7c, 0x00, 0x58, 0x00, 0x5e, 0x00, 0x79, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x41, 0x0b, 0x00, 0x00, 0x0b, 0x00,
- 0x0c, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0c, 0x00, 0x74, 0x00, 0x04,
- 0x00, 0x6e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xe4, 0x00, 0x04, 0x00,
- 0x40, 0x00, 0x0c, 0x00, 0xb4, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0xe8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x24, 0x00, 0x18, 0x5d, 0x10, 0x6f, 0x0d, 0x00, 0x0c, 0x00,
- 0x09, 0x00, 0x06, 0x00, 0x03, 0x80, 0x01, 0x00, 0x01, 0xc0, 0x00, 0x60, 0x00,
- 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x30, 0x00, 0x08, 0x00, 0x06, 0x00, 0x04,
- 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x02, 0x00,
- 0x10, 0x00, 0x01, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x04,
- 0xfa, 0xc8, 0x96, 0x64, 0x32, 0x19, 0x14, 0x0f, 0x0a, 0x08, 0x06, 0x05, 0x04,
- 0x04, 0x04, 0x20, 0x01, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00,
- 0x00, 0xe0, 0x01, 0x00, 0x00, 0x29, 0x01, 0x03, 0x00, 0x69, 0x01, 0x03, 0x00,
- 0xa9, 0x01, 0x03, 0x00, 0xe9, 0x01, 0x03, 0x00, 0x58, 0x00, 0x21, 0x00, 0x98,
- 0x00, 0x21, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c,
- 0x00, 0x28, 0x00, 0xcc, 0x00, 0x29, 0x00, 0xbb, 0x00, 0x2c, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x10, 0x00, 0x11, 0x00, 0x80, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x18,
- 0x00, 0x01, 0x00, 0x18, 0x00, 0x11, 0x00, 0x1c, 0x00, 0x87, 0x00, 0x1d, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x21, 0x00, 0x10,
- 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x29, 0x00, 0x02, 0x00,
- 0x30, 0x00, 0x12, 0x00, 0x31, 0x00, 0x1f, 0x00, 0x34, 0x00, 0x0e, 0x00, 0x10,
- 0x00, 0xc0, 0x00, 0x11, 0x00, 0x80, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00,
- 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x28, 0x00, 0x7e,
- 0x00, 0x00, 0xf0, 0x00, 0x00, 0x21, 0x00, 0x14, 0x00, 0x28, 0x00, 0x60, 0x00,
- 0x00, 0xf0, 0x00, 0x00, 0x21, 0x00, 0x14, 0x00, 0x28, 0x00, 0x40, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0x06, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00,
- 0x00, 0x00, 0x2d, 0x00, 0x41, 0x00, 0x01, 0xf0, 0x02, 0x00, 0x07, 0xf0, 0x00,
- 0x00, 0x00, 0xf0, 0x00, 0x00, 0x06, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x45, 0x00, 0x01, 0xf0, 0x20, 0x00, 0x07,
- 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00,
- 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00,
- 0x00, 0x00, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
- 0x2d, 0x00, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x2c, 0x00,
- 0x40, 0x00, 0x2d, 0x00, 0x63, 0x00, 0x01, 0xf0, 0x08, 0x00, 0x04, 0xf0, 0x00,
- 0x00, 0x00, 0xf0, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x2c, 0x00, 0x60, 0x00, 0x2d, 0x00, 0x43, 0x00, 0x01, 0xf0, 0x08, 0x00, 0x04,
- 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x20, 0x00,
- 0x28, 0x00, 0x2c, 0x00, 0x60, 0x00, 0x2d, 0x00, 0x44, 0x00, 0x01, 0xf0, 0x10,
- 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00,
- 0x20, 0x00, 0xc0, 0x00, 0x2c, 0x00, 0x60, 0x00, 0x2d, 0x00, 0x43, 0x00, 0x01,
- 0xf0, 0x08, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x08, 0xf0,
- 0x00, 0x00, 0x20, 0x00, 0xc8, 0x00, 0x2c, 0x00, 0x60, 0x00, 0x2d, 0x00, 0x44,
- 0x00, 0x01, 0xf0, 0x10, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
- 0xd0, 0xdb, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x54,
- 0xdc, 0x00, 0x80, 0xa0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xdc,
- 0x00, 0x80, 0xa8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00,
- 0x80, 0x50, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80,
- 0x58, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x60,
- 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x70, 0xea,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x78, 0xea, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x80, 0xea, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x90, 0xea, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0xb4, 0xdb, 0x00, 0x80, 0xa0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xb4, 0xdb, 0x00, 0x80, 0xa8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0xb4, 0xdb, 0x00, 0x80, 0xb0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4,
- 0xdb, 0x00, 0x80, 0xb8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc,
- 0x00, 0x80, 0x50, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00,
- 0x80, 0x58, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80,
- 0x60, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x70,
- 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x78, 0xea,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x80, 0xea, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x90, 0xea, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0xa0, 0xea, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0xa8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0xdc, 0x00, 0x80, 0xb0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0xdc, 0x00, 0x80, 0xb8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4,
- 0xdb, 0x00, 0x80, 0xc0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb,
- 0x00, 0x80, 0xc8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x00,
- 0x80, 0xd0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80,
- 0xc0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0xc8,
- 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0xd0, 0xea,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x68, 0xea, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x50, 0xea, 0x00, 0x80, 0x01,
- 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x58, 0xea, 0x00, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x60, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00,
- 0x00, 0x04, 0xdc, 0x00, 0x80, 0x68, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
- 0x04, 0xdc, 0x00, 0x80, 0x70, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04,
- 0xdc, 0x00, 0x80, 0x78, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04, 0xdc,
- 0x00, 0x80, 0x80, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00,
- 0x80, 0x88, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80,
- 0x90, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98,
- 0xea, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc,
- 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00,
- 0x80, 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80,
- 0x98, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98,
- 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x54, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x8c, 0xdc, 0x00, 0x80, 0x98, 0xea, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0xdc, 0x00, 0x80, 0xa0, 0xea, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x8c, 0xdc, 0x00, 0x80, 0xa0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x54, 0xdc, 0x00, 0x80, 0xa8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x8c, 0xdc, 0x00, 0x80, 0xa8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x54,
- 0xdc, 0x00, 0x80, 0xb0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xdc,
- 0x00, 0x80, 0xb0, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0xdc, 0x00,
- 0x80, 0xd8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0xdc, 0x00, 0x80,
- 0xd8, 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x00, 0x80, 0xd8,
- 0xea, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x00, 0x80, 0xe0, 0xea,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x00, 0x80, 0xe8, 0xea, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x00, 0x80, 0xf0, 0xea, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0xec, 0xdb, 0x00, 0x80, 0xf8, 0xea, 0x00, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x68, 0xea, 0x00, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0xd0, 0xdb, 0x00, 0x80, 0x80, 0xea, 0x00, 0x80, 0x01, 0x00, 0x00,
- 0x00, 0x1c, 0xdc, 0x00, 0x80, 0x00, 0xeb, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x64, 0x36, 0x00, 0x80, 0xf0, 0x35, 0x00, 0x80, 0x34, 0x36, 0x00, 0x80, 0x64,
- 0x36, 0x00, 0x80, 0x78, 0x3d, 0x00, 0x80, 0x70, 0x3b, 0x00, 0x80, 0x78, 0x3d,
- 0x00, 0x80, 0xf8, 0x3b, 0x00, 0x80, 0x94, 0x38, 0x00, 0x80, 0xc0, 0x37, 0x00,
- 0x80, 0x94, 0x38, 0x00, 0x80, 0xb0, 0x3d, 0x00, 0x80, 0x04, 0x37, 0x00, 0x80,
- 0x04, 0x37, 0x00, 0x80, 0x04, 0x37, 0x00, 0x80, 0x04, 0x37, 0x00, 0x80, 0x98,
- 0x36, 0x00, 0x80, 0x98, 0x36, 0x00, 0x80, 0x98, 0x36, 0x00, 0x80, 0x98, 0x36,
- 0x00, 0x80, 0x98, 0x36, 0x00, 0x80, 0x98, 0x36, 0x00, 0x80, 0x98, 0x36, 0x00,
- 0x80, 0x98, 0x36, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80,
- 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34,
- 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37,
- 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00,
- 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80, 0x34, 0x37, 0x00, 0x80,
- 0x34, 0x37, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e,
- 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x70, 0x3f, 0x00,
- 0x80, 0x8c, 0x3f, 0x00, 0x80, 0x2c, 0x40, 0x00, 0x80, 0x04, 0x40, 0x00, 0x80,
- 0x18, 0x40, 0x00, 0x80, 0x78, 0x40, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e,
- 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00,
- 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80,
- 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24,
- 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f,
- 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00,
- 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80,
- 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24,
- 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f,
- 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00,
- 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80, 0x24, 0x3f, 0x00, 0x80,
- 0x24, 0x3f, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0xc0, 0x3e,
- 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00,
- 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80,
- 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c,
- 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f,
- 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00,
- 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80,
- 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c,
- 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f, 0x00, 0x80, 0x5c, 0x3f,
- 0x00, 0x80, 0xd4, 0x3e, 0x00, 0x80, 0xe8, 0x3e, 0x00, 0x80, 0xfc, 0x3e, 0x00,
- 0x80, 0x10, 0x3f, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80,
- 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e,
- 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00,
- 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80,
- 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e,
- 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00,
- 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80,
- 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80,
- 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c,
- 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e,
- 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00, 0x80, 0x7c, 0x3e, 0x00,
- 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80,
- 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c,
- 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0xbc, 0x3c, 0x00, 0x80, 0x38, 0x3d,
- 0x00, 0x80, 0xcc, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00,
- 0x80, 0x00, 0x3d, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80,
- 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c,
- 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c,
- 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00,
- 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80,
- 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x78,
- 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c,
- 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00,
- 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80,
- 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78,
- 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c,
- 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00,
- 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80,
- 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x78, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00,
- 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80,
- 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c,
- 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c,
- 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00,
- 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80,
- 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c,
- 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c,
- 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00,
- 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80, 0x8c, 0x3c, 0x00, 0x80,
- 0x8c, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c,
- 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00,
- 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80,
- 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88,
- 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x88, 0x3c, 0x00, 0x80, 0x6c, 0x39,
- 0x00, 0x80, 0x20, 0x43, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x70, 0x42, 0x00,
- 0x80, 0x6c, 0x39, 0x00, 0x80, 0x20, 0x43, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80,
- 0x70, 0x42, 0x00, 0x80, 0x6c, 0x39, 0x00, 0x80, 0x20, 0x43, 0x00, 0x80, 0x70,
- 0x42, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x6c, 0x39, 0x00, 0x80, 0x20, 0x43,
- 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x30, 0x39, 0x00,
- 0x80, 0x20, 0x43, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80,
- 0x3c, 0x43, 0x00, 0x80, 0x20, 0x43, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x70,
- 0x42, 0x00, 0x80, 0xb8, 0x41, 0x00, 0x80, 0x20, 0x43, 0x00, 0x80, 0x70, 0x42,
- 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x88, 0x41, 0x00, 0x80, 0x20, 0x43, 0x00,
- 0x80, 0x70, 0x42, 0x00, 0x80, 0x70, 0x42, 0x00, 0x80, 0x80, 0x3e, 0x00, 0x80,
- 0xac, 0x3f, 0x00, 0x80, 0xc4, 0x3f, 0x00, 0x80, 0xcc, 0x3f, 0x00, 0x80, 0x80,
- 0x3e, 0x00, 0x80, 0xc8, 0x40, 0x00, 0x80, 0xd4, 0x40, 0x00, 0x80, 0xdc, 0x40,
- 0x00, 0x80, 0x2e, 0x2e, 0x2f, 0x63, 0x6f, 0x6e, 0x63, 0x64, 0x69, 0x73, 0x70,
- 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x63, 0x6f,
- 0x6e, 0x63, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x2e, 0x2e,
- 0x2f, 0x63, 0x6f, 0x6e, 0x63, 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x63, 0x00, 0x00,
- 0x00, 0x2e, 0x2e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x63, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10,
- 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27,
- 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2e, 0x2e, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x63, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x93, 0x00,
- 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x2e, 0x2e, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x69, 0x6e, 0x74, 0x2e,
- 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
- 0x09, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc0, 0x12, 0x00, 0x00, 0x1e, 0x00,
- 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x38, 0x00,
- 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
- 0x00, 0x96, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x96,
- 0x00, 0x00, 0x00, 0x6f, 0xfa, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x2c,
- 0x01, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x38, 0xc1, 0x01, 0x00, 0x2c, 0x01, 0x00,
- 0x00, 0x70, 0x82, 0x03, 0x00, 0x58, 0x02, 0x00, 0x00, 0xe0, 0x04, 0x07, 0x00,
- 0xe8, 0x03, 0x00, 0x00, 0xa8, 0x0d, 0x0e, 0x00, 0x40, 0x06, 0x00, 0x00, 0xc8,
- 0xc0, 0x12, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x20, 0x1c, 0x00, 0x40, 0x06,
- 0x00, 0x00, 0x00, 0x80, 0x25, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x40, 0x38,
- 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x20, 0x1c, 0x00, 0xc4, 0x09, 0x00, 0x00,
- 0x00, 0x80, 0x25, 0x00, 0xa0, 0x0f, 0x00, 0x00, 0x00, 0x40, 0x38, 0x00, 0x88,
- 0x13, 0x00, 0x00, 0x00, 0x80, 0x70, 0x00, 0x88, 0x13, 0x00, 0x00, 0x80, 0x96,
- 0x98, 0x00, 0x88, 0x13, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x00, 0xa0, 0x0f, 0x00,
- 0x00, 0x4e, 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x73, 0x63, 0x61, 0x2e, 0x63,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
- 0x2e, 0x2f, 0x73, 0x63, 0x61, 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x63, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0x83, 0xf7, 0x9b, 0x40, 0x28, 0x23, 0x29, 0x62, 0x69, 0x6f,
- 0x73, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52,
- 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20,
- 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39,
- 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x34, 0x32,
- 0x3a, 0x31, 0x37, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x68, 0x61,
- 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52,
- 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x32, 0x31,
- 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39,
- 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x30, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x31,
- 0x38, 0x3a, 0x30, 0x36, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x68,
- 0x65, 0x63, 0x6b, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x63, 0x20, 0x20, 0x24,
- 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x33,
- 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39,
- 0x39, 0x36, 0x2f, 0x30, 0x39, 0x2f, 0x31, 0x36, 0x20, 0x32, 0x33, 0x3a, 0x32,
- 0x32, 0x3a, 0x30, 0x35, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x68,
- 0x65, 0x63, 0x6b, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x68, 0x20, 0x20, 0x24,
- 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33,
- 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39,
- 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x34,
- 0x33, 0x3a, 0x33, 0x37, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f,
- 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24,
- 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31,
- 0x38, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31,
- 0x39, 0x39, 0x37, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x36, 0x20, 0x32, 0x32, 0x3a,
- 0x30, 0x37, 0x3a, 0x35, 0x39, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e,
- 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31,
- 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x31, 0x30, 0x20, 0x32, 0x33, 0x3a,
- 0x32, 0x37, 0x3a, 0x30, 0x35, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x6b, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e,
- 0x32, 0x38, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20,
- 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x35, 0x2f, 0x33, 0x30, 0x20, 0x31, 0x35,
- 0x3a, 0x30, 0x32, 0x3a, 0x30, 0x36, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x63, 0x6f, 0x6e, 0x63, 0x62, 0x69, 0x6f, 0x73, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32,
- 0x2e, 0x31, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a,
- 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30, 0x39, 0x2f, 0x31, 0x39, 0x20, 0x32,
- 0x31, 0x3a, 0x32, 0x33, 0x3a, 0x33, 0x39, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x63, 0x68, 0x61, 0x6e, 0x2e, 0x68, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a,
- 0x20, 0x33, 0x2e, 0x34, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65,
- 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30, 0x35, 0x20,
- 0x31, 0x36, 0x3a, 0x34, 0x34, 0x3a, 0x31, 0x32, 0x20, 0x24, 0x00, 0x40, 0x28,
- 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x64, 0x69, 0x73, 0x70, 0x2e, 0x63, 0x20,
- 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a,
- 0x20, 0x33, 0x2e, 0x35, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65,
- 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30, 0x35, 0x20,
- 0x31, 0x36, 0x3a, 0x34, 0x34, 0x3a, 0x34, 0x34, 0x20, 0x24, 0x00, 0x40, 0x28,
- 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x64, 0x69, 0x73, 0x70, 0x2e, 0x68, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30,
- 0x35, 0x20, 0x31, 0x37, 0x3a, 0x35, 0x35, 0x3a, 0x35, 0x38, 0x20, 0x24, 0x0d,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x66, 0x65, 0x70, 0x2e,
- 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x39, 0x20, 0x24, 0x20, 0x20, 0x24,
- 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x32,
- 0x2f, 0x32, 0x30, 0x20, 0x32, 0x32, 0x3a, 0x32, 0x37, 0x3a, 0x34, 0x39, 0x20,
- 0x24, 0x20, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6e,
- 0x69, 0x74, 0x2e, 0x73, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30,
- 0x33, 0x2f, 0x31, 0x39, 0x20, 0x32, 0x30, 0x3a, 0x35, 0x37, 0x3a, 0x35, 0x35,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x6d, 0x61,
- 0x69, 0x6e, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x2e, 0x39, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x32, 0x2f, 0x32, 0x38, 0x20, 0x32, 0x30, 0x3a, 0x33, 0x32, 0x3a, 0x32, 0x33,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x70, 0x72,
- 0x6f, 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31,
- 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x34, 0x36, 0x3a, 0x30, 0x39,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x70, 0x72,
- 0x6f, 0x74, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31,
- 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x34, 0x36, 0x3a, 0x32, 0x38,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x63,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x31,
- 0x30, 0x20, 0x32, 0x33, 0x3a, 0x32, 0x37, 0x3a, 0x30, 0x37, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44,
- 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x34, 0x2f,
- 0x30, 0x39, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x38, 0x3a, 0x30, 0x32, 0x20, 0x24,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x68,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24,
- 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30, 0x37,
- 0x2f, 0x32, 0x33, 0x20, 0x30, 0x31, 0x3a, 0x35, 0x36, 0x3a, 0x35, 0x35, 0x20,
- 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x2e, 0x73, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x24, 0x20, 0x20, 0x24,
- 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30, 0x33,
- 0x2f, 0x31, 0x39, 0x20, 0x32, 0x30, 0x3a, 0x35, 0x37, 0x3a, 0x35, 0x36, 0x20,
- 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x66, 0x65, 0x70, 0x6d, 0x73, 0x67, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x2e, 0x35, 0x20, 0x24, 0x20, 0x20, 0x24,
- 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30,
- 0x2f, 0x30, 0x37, 0x20, 0x31, 0x39, 0x3a, 0x32, 0x39, 0x3a, 0x34, 0x33, 0x20,
- 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x66, 0x78, 0x63, 0x6f, 0x6e, 0x2f, 0x4d,
- 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e,
- 0x36, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31,
- 0x39, 0x39, 0x37, 0x2f, 0x30, 0x31, 0x2f, 0x30, 0x38, 0x20, 0x31, 0x39, 0x3a,
- 0x34, 0x37, 0x3a, 0x31, 0x33, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x68,
- 0x6f, 0x73, 0x74, 0x63, 0x6f, 0x6d, 0x6d, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20,
- 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e,
- 0x31, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20,
- 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x34, 0x2f, 0x32, 0x39, 0x20, 0x31, 0x39,
- 0x3a, 0x33, 0x31, 0x3a, 0x31, 0x30, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x68, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33,
- 0x2e, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20,
- 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x31, 0x30, 0x20, 0x32, 0x33,
- 0x3a, 0x32, 0x37, 0x3a, 0x30, 0x38, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x69, 0x75, 0x73, 0x63, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32,
- 0x2e, 0x33, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20,
- 0x31, 0x39, 0x39, 0x32, 0x2f, 0x30, 0x35, 0x2f, 0x32, 0x34, 0x20, 0x30, 0x30,
- 0x3a, 0x30, 0x36, 0x3a, 0x32, 0x39, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x6d, 0x69, 0x64, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33,
- 0x2e, 0x31, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a,
- 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x31, 0x30, 0x20, 0x32,
- 0x33, 0x3a, 0x32, 0x37, 0x3a, 0x30, 0x38, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x6d, 0x6f, 0x64, 0x65, 0x6d, 0x63, 0x68, 0x6b, 0x2e, 0x63, 0x20, 0x20,
- 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20,
- 0x33, 0x2e, 0x39, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a,
- 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x35, 0x2f, 0x30, 0x39, 0x20, 0x31,
- 0x38, 0x3a, 0x35, 0x35, 0x3a, 0x33, 0x30, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x6d, 0x6f, 0x64, 0x65, 0x6d, 0x63, 0x68, 0x6b, 0x2e, 0x68, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74,
- 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30, 0x35,
- 0x20, 0x31, 0x37, 0x3a, 0x32, 0x32, 0x3a, 0x34, 0x39, 0x20, 0x24, 0x0d, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x63, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x32, 0x2e, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30,
- 0x35, 0x20, 0x31, 0x36, 0x3a, 0x34, 0x39, 0x3a, 0x32, 0x36, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x68, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x34, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f, 0x30,
- 0x35, 0x20, 0x31, 0x36, 0x3a, 0x34, 0x39, 0x3a, 0x33, 0x33, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x31,
- 0x30, 0x20, 0x32, 0x33, 0x3a, 0x32, 0x37, 0x3a, 0x31, 0x30, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x73, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x33, 0x2f, 0x30, 0x38, 0x2f, 0x32,
- 0x30, 0x20, 0x31, 0x35, 0x3a, 0x32, 0x34, 0x3a, 0x32, 0x32, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x70, 0x61, 0x72, 0x61, 0x2e, 0x63, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x33, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44,
- 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x35, 0x2f,
- 0x30, 0x39, 0x20, 0x31, 0x38, 0x3a, 0x35, 0x35, 0x3a, 0x33, 0x31, 0x20, 0x24,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x61, 0x72, 0x61, 0x2e, 0x68, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44,
- 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f,
- 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x35, 0x30, 0x3a, 0x31, 0x36, 0x20, 0x24,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x62, 0x75, 0x73, 0x2e, 0x68, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x34, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44,
- 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31, 0x32, 0x2f,
- 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x35, 0x30, 0x3a, 0x32, 0x35, 0x20, 0x24,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x32, 0x37, 0x20, 0x24, 0x20, 0x20, 0x24,
- 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x35,
- 0x2f, 0x33, 0x30, 0x20, 0x31, 0x36, 0x3a, 0x33, 0x30, 0x3a, 0x31, 0x37, 0x20,
- 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
- 0x6c, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x30, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x34, 0x2f, 0x32, 0x39, 0x20, 0x31, 0x39, 0x3a, 0x33, 0x31, 0x3a, 0x31, 0x31,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
- 0x6f, 0x6c, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x37, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x34, 0x2f, 0x32, 0x39, 0x20, 0x31, 0x39, 0x3a, 0x33, 0x31, 0x3a, 0x31, 0x32,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x72, 0x77, 0x2e, 0x68, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x2e, 0x34, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x32, 0x2f, 0x32, 0x30, 0x20, 0x32, 0x32, 0x3a, 0x32, 0x37, 0x3a, 0x35, 0x30,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x37, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x34, 0x2f, 0x30, 0x37, 0x20, 0x32, 0x31, 0x3a, 0x34, 0x33, 0x3a, 0x31, 0x34,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x61, 0x2e, 0x68, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x36, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x31,
- 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x35, 0x33, 0x3a, 0x30, 0x33,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x61, 0x70, 0x72, 0x6f,
- 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x38, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x31, 0x2f, 0x32, 0x39, 0x20, 0x32, 0x31, 0x3a, 0x31, 0x39, 0x3a, 0x31, 0x35,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x68, 0x65, 0x64, 0x2e,
- 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x35, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30,
- 0x39, 0x2f, 0x31, 0x36, 0x20, 0x32, 0x33, 0x3a, 0x33, 0x32, 0x3a, 0x32, 0x36,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x68, 0x65, 0x64, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30,
- 0x39, 0x2f, 0x32, 0x34, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x31, 0x3a, 0x34, 0x39,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e,
- 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x36, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30,
- 0x39, 0x2f, 0x31, 0x36, 0x20, 0x32, 0x33, 0x3a, 0x34, 0x31, 0x3a, 0x34, 0x35,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x38, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f, 0x30,
- 0x39, 0x2f, 0x31, 0x36, 0x20, 0x32, 0x33, 0x3a, 0x34, 0x32, 0x3a, 0x30, 0x38,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x69,
- 0x6e, 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x36, 0x20, 0x24, 0x20, 0x20,
- 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30,
- 0x31, 0x2f, 0x31, 0x35, 0x20, 0x31, 0x38, 0x3a, 0x31, 0x30, 0x3a, 0x30, 0x39,
- 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x75, 0x61, 0x72, 0x74, 0x2e, 0x63,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x31, 0x38, 0x20, 0x24, 0x20,
- 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f,
- 0x30, 0x35, 0x2f, 0x33, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x33, 0x3a, 0x34,
- 0x36, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x75, 0x61, 0x72, 0x74, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x36, 0x20, 0x24, 0x20,
- 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f,
- 0x31, 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x35, 0x38, 0x3a, 0x35,
- 0x32, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x75, 0x74, 0x69, 0x6c, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x24, 0x20,
- 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2f,
- 0x31, 0x32, 0x2f, 0x30, 0x35, 0x20, 0x31, 0x36, 0x3a, 0x35, 0x39, 0x3a, 0x30,
- 0x39, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x75, 0x74, 0x69, 0x6c, 0x2e,
- 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x33, 0x2e, 0x34, 0x20, 0x24, 0x20,
- 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f,
- 0x30, 0x31, 0x2f, 0x32, 0x31, 0x20, 0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x35,
- 0x32, 0x20, 0x24, 0x00, 0x00
-};
diff --git a/sys/dev/digi/con.MBank.h b/sys/dev/digi/con.MBank.h
deleted file mode 100644
index 89f2d0a..0000000
--- a/sys/dev/digi/con.MBank.h
+++ /dev/null
@@ -1,7870 +0,0 @@
-/*-
- * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
- * based on work by Slawa Olhovchenkov
- * 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$
- */
-
-const u_char con_MBank[] = {
- 0x43, 0x58, 0x00, 0x14, 0x00, 0x14, 0xff, 0x14, 0x00, 0x01, 0x10, 0x8e, 0x10,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x53,
- 0x7c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x23, 0x29, 0x6d, 0x62, 0x63,
- 0x6f, 0x6e, 0x2e, 0x62, 0x69, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32, 0x2e,
- 0x32, 0x20, 0x30, 0x38, 0x2f, 0x31, 0x37, 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28,
- 0x23, 0x29, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28,
- 0x43, 0x29, 0x20, 0x31, 0x39, 0x39, 0x36, 0x2c, 0x20, 0x44, 0x49, 0x47, 0x49,
- 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61,
- 0x6c, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73,
- 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x00, 0x00, 0x30, 0x9a,
- 0x80, 0xaf, 0x02, 0x80, 0x01, 0x3c, 0x44, 0xb9, 0x21, 0xac, 0x02, 0x80, 0x01,
- 0x3c, 0x48, 0xb9, 0x22, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x4c, 0xb9, 0x23, 0xac,
- 0x02, 0x80, 0x01, 0x3c, 0x50, 0xb9, 0x24, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x54,
- 0xb9, 0x25, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x58, 0xb9, 0x26, 0xac, 0x02, 0x80,
- 0x01, 0x3c, 0x5c, 0xb9, 0x27, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x60, 0xb9, 0x28,
- 0xac, 0x02, 0x80, 0x01, 0x3c, 0x64, 0xb9, 0x29, 0xac, 0x02, 0x80, 0x01, 0x3c,
- 0x68, 0xb9, 0x2a, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x6c, 0xb9, 0x2b, 0xac, 0x02,
- 0x80, 0x01, 0x3c, 0x70, 0xb9, 0x2c, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x74, 0xb9,
- 0x2d, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x78, 0xb9, 0x2e, 0xac, 0x02, 0x80, 0x01,
- 0x3c, 0x7c, 0xb9, 0x2f, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x80, 0xb9, 0x30, 0xac,
- 0x02, 0x80, 0x01, 0x3c, 0x84, 0xb9, 0x31, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x88,
- 0xb9, 0x32, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x8c, 0xb9, 0x33, 0xac, 0x02, 0x80,
- 0x01, 0x3c, 0x90, 0xb9, 0x34, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x94, 0xb9, 0x35,
- 0xac, 0x02, 0x80, 0x01, 0x3c, 0x98, 0xb9, 0x36, 0xac, 0x02, 0x80, 0x01, 0x3c,
- 0x9c, 0xb9, 0x37, 0xac, 0x02, 0x80, 0x01, 0x3c, 0xa0, 0xb9, 0x38, 0xac, 0x02,
- 0x80, 0x01, 0x3c, 0xa4, 0xb9, 0x39, 0xac, 0x02, 0x80, 0x01, 0x3c, 0xa8, 0xb9,
- 0x3a, 0xac, 0x02, 0x80, 0x01, 0x3c, 0xac, 0xb9, 0x3b, 0xac, 0x02, 0x80, 0x01,
- 0x3c, 0xb0, 0xb9, 0x3c, 0xac, 0x02, 0x80, 0x01, 0x3c, 0xb4, 0xb9, 0x3d, 0xac,
- 0x02, 0x80, 0x01, 0x3c, 0xb8, 0xb9, 0x3e, 0xac, 0x02, 0x80, 0x01, 0x3c, 0xbc,
- 0xb9, 0x3f, 0xac, 0x10, 0x40, 0x00, 0x00, 0x02, 0x80, 0x01, 0x3c, 0xc0, 0xb9,
- 0x28, 0xac, 0x12, 0x40, 0x00, 0x00, 0x02, 0x80, 0x01, 0x3c, 0xc4, 0xb9, 0x28,
- 0xac, 0x02, 0x80, 0x08, 0x3c, 0x60, 0xb9, 0x08, 0x8d, 0xff, 0xff, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x00, 0x60, 0x88, 0x40, 0x02,
- 0x80, 0x1c, 0x3c, 0x10, 0x1f, 0x9c, 0x27, 0x01, 0x00, 0x11, 0x04, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x05, 0x3c, 0x00, 0x30, 0xa5, 0x24, 0x02, 0x80, 0x06,
- 0x3c, 0x90, 0xb8, 0xc6, 0x24, 0x00, 0x80, 0x04, 0x3c, 0xbc, 0x31, 0x84, 0x24,
- 0x23, 0x20, 0xe4, 0x03, 0x21, 0x20, 0x86, 0x00, 0xfc, 0xff, 0x84, 0x24, 0xfc,
- 0xff, 0xc6, 0x24, 0x00, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xc8, 0xac, 0x2b, 0x08, 0xa6, 0x00, 0xf9, 0xff, 0x20, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3c,
- 0xfe, 0x00, 0x21, 0x34, 0x24, 0x40, 0x01, 0x01, 0x00, 0x60, 0x88, 0x40, 0x00,
- 0x80, 0x1f, 0x3c, 0x34, 0x32, 0xff, 0x27, 0x00, 0x80, 0x04, 0x3c, 0xf0, 0x47,
- 0x84, 0x24, 0x00, 0xa0, 0x01, 0x3c, 0x25, 0x20, 0x81, 0x00, 0x08, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x1d, 0x3c, 0xc0, 0xcb, 0xbd, 0x27,
- 0x00, 0x00, 0x1e, 0x24, 0x00, 0x00, 0x1f, 0x24, 0x27, 0x1b, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x62, 0x1b, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x00, 0x00, 0x69, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x94, 0xff, 0xbd,
- 0x27, 0x10, 0x00, 0xa1, 0xaf, 0x14, 0x00, 0xa2, 0xaf, 0x18, 0x00, 0xa3, 0xaf,
- 0x1c, 0x00, 0xa4, 0xaf, 0x20, 0x00, 0xa5, 0xaf, 0x24, 0x00, 0xa6, 0xaf, 0x28,
- 0x00, 0xa7, 0xaf, 0x2c, 0x00, 0xa8, 0xaf, 0x30, 0x00, 0xa9, 0xaf, 0x34, 0x00,
- 0xaa, 0xaf, 0x38, 0x00, 0xab, 0xaf, 0x3c, 0x00, 0xac, 0xaf, 0x40, 0x00, 0xad,
- 0xaf, 0x44, 0x00, 0xae, 0xaf, 0x48, 0x00, 0xaf, 0xaf, 0x4c, 0x00, 0xb8, 0xaf,
- 0x50, 0x00, 0xb9, 0xaf, 0x58, 0x00, 0xbe, 0xaf, 0x5c, 0x00, 0xbf, 0xaf, 0x00,
- 0x70, 0x08, 0x40, 0x12, 0x48, 0x00, 0x00, 0x10, 0x50, 0x00, 0x00, 0x54, 0x00,
- 0xa8, 0xaf, 0x60, 0x00, 0xa9, 0xaf, 0x64, 0x00, 0xaa, 0xaf, 0x00, 0x68, 0x05,
- 0x40, 0x00, 0x60, 0x06, 0x40, 0x7c, 0x00, 0xa4, 0x30, 0x65, 0x00, 0x80, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0xa6, 0xaf, 0x24, 0x10, 0xa6, 0x00, 0x00,
- 0xff, 0x42, 0x30, 0x00, 0x04, 0x48, 0x30, 0x3e, 0x00, 0x00, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x44, 0x30, 0x45, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x44, 0x30, 0x4f, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0xa6, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x86, 0x40, 0x00, 0x68,
- 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0xa6, 0x00, 0x00, 0xff, 0x42,
- 0x30, 0xec, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0xa8, 0x8f,
- 0x60, 0x00, 0xa9, 0x8f, 0x64, 0x00, 0xaa, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x60, 0x88, 0x40, 0x13, 0x00, 0x20, 0x01, 0x11, 0x00, 0x40, 0x01, 0x14, 0x00,
- 0xa2, 0x8f, 0x18, 0x00, 0xa3, 0x8f, 0x1c, 0x00, 0xa4, 0x8f, 0x20, 0x00, 0xa5,
- 0x8f, 0x24, 0x00, 0xa6, 0x8f, 0x28, 0x00, 0xa7, 0x8f, 0x2c, 0x00, 0xa8, 0x8f,
- 0x30, 0x00, 0xa9, 0x8f, 0x34, 0x00, 0xaa, 0x8f, 0x38, 0x00, 0xab, 0x8f, 0x3c,
- 0x00, 0xac, 0x8f, 0x40, 0x00, 0xad, 0x8f, 0x44, 0x00, 0xae, 0x8f, 0x48, 0x00,
- 0xaf, 0x8f, 0x4c, 0x00, 0xb8, 0x8f, 0x50, 0x00, 0xb9, 0x8f, 0x58, 0x00, 0xbe,
- 0x8f, 0x5c, 0x00, 0xbf, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0xba, 0x8f,
- 0x10, 0x00, 0xa1, 0x8f, 0x6c, 0x00, 0xbd, 0x27, 0x08, 0x00, 0x40, 0x03, 0x10,
- 0x00, 0x00, 0x42, 0xc4, 0x9a, 0x88, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40,
- 0x06, 0x01, 0x01, 0xff, 0x08, 0x31, 0x26, 0x30, 0xc8, 0x00, 0x00, 0x00, 0x09,
- 0x24, 0x00, 0x68, 0x89, 0x40, 0x00, 0x60, 0x86, 0x40, 0x1e, 0x1b, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0xcc, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0x9a, 0x88, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x06, 0x01, 0x01, 0xff,
- 0x08, 0x31, 0x26, 0x30, 0xc8, 0x00, 0x00, 0x60, 0x86, 0x40, 0x8c, 0x27, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x80, 0x08, 0x3c, 0x04, 0xbe, 0x08, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x26,
- 0x40, 0x06, 0x01, 0x01, 0xff, 0x08, 0x31, 0x26, 0x30, 0xc8, 0x00, 0x00, 0x00,
- 0x09, 0x24, 0x00, 0x68, 0x89, 0x40, 0x00, 0x60, 0x86, 0x40, 0xc9, 0x45, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xcc, 0x9a, 0x88, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x06, 0x01, 0x01,
- 0xff, 0x08, 0x31, 0x26, 0x30, 0xc8, 0x00, 0x00, 0x60, 0x86, 0x40, 0xa0, 0x35,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xab, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x80, 0x04, 0x3c, 0xd0, 0x1a, 0x84, 0x24, 0x20, 0x0c, 0x00, 0x0c,
- 0x8c, 0x01, 0x05, 0x24, 0xaf, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xec,
- 0xff, 0xbd, 0x27, 0x08, 0x00, 0xa1, 0xaf, 0x00, 0x70, 0x1a, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0xba, 0xaf, 0x10, 0x00, 0xbf, 0xaf, 0x01, 0x80, 0x04,
- 0x3c, 0xd0, 0x1a, 0x84, 0x24, 0x20, 0x0c, 0x00, 0x0c, 0xae, 0x01, 0x05, 0x24,
- 0x10, 0x00, 0xbf, 0x8f, 0x0c, 0x00, 0xba, 0x8f, 0x08, 0x00, 0xa1, 0x8f, 0x0c,
- 0x00, 0xbd, 0x27, 0x08, 0x00, 0x40, 0x03, 0x10, 0x00, 0x00, 0x42, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xff, 0xbd,
- 0x27, 0x00, 0x00, 0xb0, 0xaf, 0x04, 0x00, 0xb1, 0xaf, 0x08, 0x00, 0xb2, 0xaf,
- 0x0c, 0x00, 0xb3, 0xaf, 0x10, 0x00, 0xb4, 0xaf, 0x14, 0x00, 0xb5, 0xaf, 0x18,
- 0x00, 0xb6, 0xaf, 0x1c, 0x00, 0xb7, 0xaf, 0x20, 0x00, 0xbf, 0xaf, 0x02, 0x80,
- 0x10, 0x3c, 0xec, 0xa8, 0x10, 0x8e, 0x00, 0x00, 0x11, 0x24, 0x30, 0x9b, 0x84,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x10, 0x02, 0x24,
- 0x9b, 0x88, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x31, 0x02, 0x80,
- 0x04, 0x3c, 0x21, 0x20, 0x88, 0x00, 0x44, 0xba, 0x84, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x8a, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x10, 0x02, 0x24, 0x9b, 0x88, 0x8f, 0x02,
- 0x80, 0x04, 0x3c, 0x21, 0x20, 0x88, 0x00, 0x4c, 0xba, 0x84, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c, 0x04, 0x00, 0x0a, 0x25, 0x0c, 0x00, 0x4a,
- 0x31, 0x24, 0x9b, 0x8a, 0xaf, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x4c, 0x9b, 0x84, 0x8f, 0x20, 0x9b, 0x90, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x10, 0x26, 0x34, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x84, 0x8c, 0xf9, 0xff, 0x00,
- 0x16, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9b, 0x84, 0xaf, 0x00, 0x00, 0xb0, 0x8f,
- 0x04, 0x00, 0xb1, 0x8f, 0x08, 0x00, 0xb2, 0x8f, 0x0c, 0x00, 0xb3, 0x8f, 0x10,
- 0x00, 0xb4, 0x8f, 0x14, 0x00, 0xb5, 0x8f, 0x18, 0x00, 0xb6, 0x8f, 0x1c, 0x00,
- 0xb7, 0x8f, 0x20, 0x00, 0xbf, 0x8f, 0x24, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0xc1, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x87, 0x94, 0x25,
- 0x28, 0x91, 0x00, 0x82, 0x48, 0x07, 0x00, 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08,
- 0x3c, 0x01, 0x00, 0x80, 0x29, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0xc0, 0x47, 0x02, 0x00, 0xba, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x49, 0x07, 0x00, 0x7c, 0x00, 0x29, 0x31, 0x44, 0x00, 0x92, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x90, 0x50, 0x02, 0xac, 0x00, 0x41, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x08, 0x3c, 0x01, 0x20, 0x80, 0x29, 0x8c, 0x40, 0x00, 0x93, 0x8c,
- 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x89, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x29, 0x31, 0x23, 0x01, 0x20, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x49, 0x07, 0x00, 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c,
- 0x01, 0x10, 0x80, 0x29, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x89, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x41, 0x07, 0x00, 0x7c, 0x00, 0x08, 0x31, 0x21, 0x08, 0x1c,
- 0x01, 0x20, 0x80, 0x28, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0x01,
- 0x00, 0xe8, 0x30, 0x09, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
- 0x8c, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x31, 0x04, 0x00, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x83, 0x90, 0x03, 0x00, 0x00, 0x10,
- 0x08, 0x00, 0x2b, 0x35, 0x5c, 0x00, 0x83, 0x90, 0xf7, 0xff, 0x2b, 0x31, 0x26,
- 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0, 0x58, 0x00,
- 0xaa, 0xa0, 0xff, 0xfd, 0xe7, 0x30, 0x50, 0x00, 0x87, 0xa4, 0x00, 0x00, 0xc3,
- 0xa0, 0x21, 0x90, 0x53, 0x02, 0xe1, 0xff, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00,
- 0x73, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x24, 0x67,
- 0x00, 0x88, 0xa0, 0x21, 0x48, 0x12, 0x02, 0x68, 0x00, 0x20, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0xca, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x4a,
- 0x35, 0x0c, 0x00, 0xca, 0xa0, 0x00, 0x04, 0xe7, 0x34, 0x61, 0x00, 0x00, 0x10,
- 0x50, 0x00, 0x87, 0xa4, 0x02, 0x00, 0x08, 0x24, 0x67, 0x00, 0x88, 0xa0, 0x6c,
- 0x00, 0x89, 0x8c, 0xff, 0xff, 0x01, 0x24, 0x0c, 0x00, 0x21, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x48, 0x30, 0x01, 0x08, 0x00, 0x20, 0x1d, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0xca, 0x90, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0x4a, 0x31,
- 0x0c, 0x00, 0xca, 0xa0, 0x00, 0x00, 0x09, 0x24, 0xff, 0xfa, 0xe7, 0x30, 0x50,
- 0x00, 0x87, 0xa4, 0x6c, 0x00, 0x89, 0xac, 0x4e, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x24, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xc0,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0x28, 0x91, 0x00, 0x08, 0x00, 0xc2, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x47, 0x02, 0x00, 0x50, 0x00, 0x11, 0x05, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x89, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x0a, 0x3c, 0xfc, 0x37, 0x4a, 0x25, 0x04, 0x00, 0x8a, 0xac,
- 0x49, 0x00, 0x88, 0x90, 0x4a, 0x00, 0x89, 0x90, 0x12, 0x00, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00,
- 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91,
- 0x00, 0x08, 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x47, 0x02, 0x00,
- 0x39, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x92, 0x8c, 0x49,
- 0x00, 0x88, 0x90, 0x4a, 0x00, 0x89, 0x90, 0x23, 0x90, 0x50, 0x02, 0x2c, 0x00,
- 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xca, 0x90, 0x0a, 0x00, 0xb5,
- 0x94, 0x0c, 0x00, 0xb6, 0x94, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xb6, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x0a, 0x01, 0x1d, 0x00, 0x09, 0x15, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x93, 0x8c, 0x3c, 0x00, 0x94, 0x8c, 0x0e, 0x00,
- 0x97, 0x94, 0x21, 0x40, 0x96, 0x02, 0x00, 0x00, 0x03, 0x91, 0x01, 0x00, 0xd6,
- 0x26, 0x00, 0x00, 0xc3, 0xa0, 0x24, 0xb0, 0xd7, 0x02, 0x21, 0x90, 0x53, 0x02,
- 0x04, 0x00, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xb6, 0x16, 0x21,
- 0x40, 0x96, 0x02, 0x00, 0x00, 0x12, 0x24, 0x00, 0x00, 0x88, 0x8c, 0x0c, 0x00,
- 0xb6, 0xa4, 0x04, 0x00, 0x09, 0x8d, 0x44, 0x00, 0x92, 0xac, 0x08, 0x00, 0x20,
- 0x01, 0x21, 0x20, 0x00, 0x01, 0x21, 0x40, 0x12, 0x02, 0x06, 0x00, 0x00, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xe7, 0x30, 0x50, 0x00, 0x87, 0xa4, 0x00,
- 0x80, 0x08, 0x3c, 0xa0, 0x37, 0x08, 0x25, 0x04, 0x00, 0x88, 0xac, 0x00, 0x00,
- 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x8d, 0x44, 0x00, 0x80,
- 0xac, 0x08, 0x00, 0x20, 0x01, 0x21, 0x20, 0x00, 0x01, 0x00, 0x00, 0x88, 0x8c,
- 0x44, 0x00, 0x92, 0xac, 0x04, 0x00, 0x09, 0x8d, 0x21, 0x20, 0x00, 0x01, 0x08,
- 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x87, 0x94, 0x6a, 0x00,
- 0x92, 0x94, 0x42, 0x42, 0x07, 0x00, 0x7c, 0x00, 0x08, 0x31, 0x21, 0x98, 0x1c,
- 0x01, 0xa0, 0x88, 0x73, 0x8e, 0x38, 0x00, 0x94, 0x8c, 0x12, 0x00, 0xb5, 0x94,
- 0x14, 0x00, 0xb6, 0x94, 0x16, 0x00, 0x97, 0x94, 0x28, 0x00, 0x8c, 0x94, 0x5c,
- 0x00, 0x8e, 0x90, 0x5d, 0x00, 0x8f, 0x90, 0x14, 0x00, 0xc2, 0x90, 0x00, 0x00,
- 0xc3, 0x90, 0x00, 0x42, 0x02, 0x00, 0x25, 0x18, 0x68, 0x00, 0x08, 0x00, 0x60,
- 0x02, 0x24, 0x18, 0x72, 0x00, 0xff, 0xf9, 0x68, 0x30, 0x89, 0x02, 0x0e, 0x11,
- 0x21, 0x48, 0x95, 0x02, 0x98, 0x02, 0x0f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x23, 0xa1, 0xff, 0x00, 0x61, 0x2c, 0x12, 0x00, 0x20, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x20, 0x00, 0xb6,
- 0x16, 0x00, 0x00, 0x00, 0x00, 0xef, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x48, 0x95, 0x02, 0x00, 0x00, 0x23, 0xa1, 0xff, 0x00, 0x61, 0x2c, 0x07,
- 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8,
- 0xb7, 0x02, 0x15, 0x00, 0xb6, 0x16, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x02, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x68, 0x30, 0x92, 0x02, 0x00, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0xdd,
- 0x02, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8a, 0x31, 0x09, 0x00,
- 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x21, 0x48, 0x95, 0x02, 0x00, 0x00, 0x23,
- 0xa1, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x03, 0x00, 0xb6, 0x16,
- 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x30, 0xca, 0xff,
- 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x88, 0x94, 0x23, 0x48, 0xb6,
- 0x02, 0x24, 0x48, 0x37, 0x01, 0x12, 0x00, 0xb5, 0xa4, 0x2b, 0x08, 0x28, 0x01,
- 0x1c, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xea, 0x30, 0x19,
- 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe7, 0x34, 0x00, 0x10,
- 0x88, 0x31, 0x06, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7,
- 0x38, 0x00, 0x80, 0x13, 0x3c, 0xdc, 0x35, 0x73, 0x26, 0x00, 0x80, 0x1f, 0x3c,
- 0x24, 0x36, 0xff, 0x27, 0x5f, 0x00, 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x08, 0x31, 0x54, 0x00, 0xa9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x26, 0x48,
- 0x28, 0x01, 0x54, 0x00, 0xa9, 0xa0, 0x58, 0x00, 0xaa, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x25, 0x50, 0x48, 0x01, 0x58, 0x00, 0xaa, 0xa0, 0x68, 0x00, 0x8b, 0x90,
- 0x27, 0x40, 0x00, 0x01, 0x24, 0x58, 0x68, 0x01, 0x10, 0x00, 0xcb, 0xa0, 0x12,
- 0x00, 0xb5, 0xa4, 0x08, 0x00, 0xe0, 0x03, 0x50, 0x00, 0x87, 0xa4, 0x24, 0x00,
- 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x25, 0x28, 0x91, 0x00, 0x18, 0x00, 0xc8, 0x90, 0x54, 0x00, 0xa9, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x09, 0x01, 0xf0, 0x00, 0x08, 0x31, 0x26,
- 0x48, 0x28, 0x01, 0x54, 0x00, 0xa9, 0xa0, 0x58, 0x00, 0xaa, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x50, 0x48, 0x01, 0x58, 0x00, 0xaa, 0xa0, 0x08, 0x00, 0xe0,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x3c, 0x00, 0x3b, 0x4a, 0x25,
- 0x07, 0x00, 0x00, 0x10, 0x04, 0x00, 0x8a, 0xac, 0x24, 0x00, 0x86, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
- 0x87, 0x94, 0x25, 0x28, 0x91, 0x00, 0x38, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x15, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xb5, 0x94,
- 0x14, 0x00, 0xb6, 0x94, 0x38, 0x00, 0x94, 0x8c, 0x16, 0x00, 0x97, 0x94, 0x21,
- 0x40, 0x95, 0x02, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x09, 0x00,
- 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xc3, 0x90, 0xff, 0xff, 0x29,
- 0x25, 0x00, 0x00, 0x03, 0xa1, 0x21, 0x40, 0x95, 0x02, 0xf7, 0xff, 0x20, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x12, 0x00, 0xb5, 0xa4, 0x00, 0x00,
- 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x8d, 0x21, 0x20, 0x00,
- 0x01, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x3c,
- 0xa0, 0x3b, 0x4a, 0x25, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, 0x8a, 0xac, 0x24,
- 0x00, 0x86, 0x8c, 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00, 0x0a, 0x00,
- 0xb5, 0x94, 0x0c, 0x00, 0xb6, 0x94, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0xb6,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0xff, 0x29, 0x21, 0x22, 0x48, 0x09, 0x00, 0x3c, 0x00, 0x94, 0x8c, 0x0e,
- 0x00, 0x97, 0x94, 0x21, 0x40, 0x96, 0x02, 0x08, 0x00, 0x20, 0x19, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x29, 0x25, 0x00, 0x00, 0x03, 0x91, 0x01, 0x00, 0xd6,
- 0x26, 0x48, 0x00, 0xc3, 0xa0, 0x24, 0xb0, 0xd7, 0x02, 0xf8, 0xff, 0xb6, 0x16,
- 0x21, 0x40, 0x96, 0x02, 0x00, 0x00, 0x88, 0x8c, 0x0c, 0x00, 0xb6, 0xa4, 0x04,
- 0x00, 0x09, 0x8d, 0x21, 0x20, 0x00, 0x01, 0x08, 0x00, 0x20, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x0a, 0x3c, 0x28, 0x3c, 0x4a, 0x25, 0x04, 0x00, 0x00,
- 0x10, 0x04, 0x00, 0x8a, 0xac, 0x24, 0x00, 0x86, 0x8c, 0x50, 0x00, 0x87, 0x94,
- 0x25, 0x28, 0x91, 0x00, 0x0a, 0x00, 0xb5, 0x94, 0x0c, 0x00, 0xb6, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
- 0xc9, 0x90, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x29, 0x25, 0x22, 0x48, 0x09,
- 0x00, 0x3c, 0x00, 0x94, 0x8c, 0x0e, 0x00, 0x97, 0x94, 0x2a, 0x00, 0x8c, 0x94,
- 0x63, 0x00, 0x8e, 0x90, 0x15, 0x00, 0x20, 0x19, 0x21, 0x40, 0x96, 0x02, 0xff,
- 0xff, 0x29, 0x25, 0x00, 0x00, 0x08, 0x91, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18,
- 0x00, 0x01, 0x80, 0x40, 0x08, 0x00, 0x21, 0x08, 0x1c, 0x01, 0xa0, 0x84, 0x28,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x88, 0x31, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0xe0,
- 0xff, 0x63, 0x24, 0x01, 0x00, 0xce, 0x25, 0x48, 0x00, 0xc3, 0xa0, 0x01, 0x00,
- 0xd6, 0x26, 0x24, 0xb0, 0xd7, 0x02, 0xeb, 0xff, 0xb6, 0x16, 0x00, 0x00, 0x00,
- 0x00, 0x63, 0x00, 0x8e, 0xa0, 0x00, 0x00, 0x88, 0x8c, 0x0c, 0x00, 0xb6, 0xa4,
- 0x04, 0x00, 0x09, 0x8d, 0x21, 0x20, 0x00, 0x01, 0x08, 0x00, 0x20, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0xff, 0xc0, 0x11, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff,
- 0x00, 0x10, 0xff, 0xff, 0xce, 0x25, 0x20, 0x00, 0x8a, 0x31, 0x02, 0x00, 0x40,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x24, 0x04, 0x00, 0x8a, 0x31,
- 0xea, 0xff, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0xed, 0xff, 0x20, 0x11, 0x00,
- 0x00, 0x0e, 0x24, 0xff, 0xff, 0x29, 0x25, 0x0d, 0x00, 0x0a, 0x24, 0xe4, 0xff,
- 0x00, 0x10, 0x48, 0x00, 0xca, 0xa0, 0x21, 0x40, 0xc0, 0x01, 0x00, 0x00, 0x0e,
- 0x24, 0x08, 0x00, 0x8a, 0x31, 0x08, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x8a, 0x31, 0xdc, 0xff, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0xdb,
- 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0xd6, 0xff, 0x00, 0x10, 0x0a, 0x00, 0x03, 0x24, 0x21, 0x40, 0xc0,
- 0x01, 0x07, 0x00, 0x08, 0x31, 0x07, 0x00, 0x08, 0x39, 0x2b, 0x08, 0x28, 0x01,
- 0xd5, 0xff, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x23, 0x48, 0x28, 0x01, 0x08,
- 0x00, 0xce, 0x25, 0xf8, 0xff, 0xce, 0x31, 0x20, 0x00, 0x03, 0x24, 0x48, 0x00,
- 0xc3, 0xa0, 0xff, 0xff, 0x08, 0x25, 0xfd, 0xff, 0x01, 0x05, 0x00, 0x00, 0x00,
- 0x00, 0xc7, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xe7, 0x30,
- 0x50, 0x00, 0x87, 0xa4, 0x00, 0x80, 0x08, 0x3c, 0x84, 0x36, 0x08, 0x25, 0x35,
- 0x0e, 0x00, 0x08, 0x04, 0x00, 0x88, 0xac, 0x74, 0x00, 0x9f, 0xac, 0x63, 0x00,
- 0x8e, 0xa0, 0x00, 0x00, 0x88, 0x8c, 0x0c, 0x00, 0xb6, 0xa4, 0x04, 0x00, 0x09,
- 0x8d, 0x44, 0x00, 0x92, 0xac, 0x08, 0x00, 0x20, 0x01, 0x21, 0x20, 0x00, 0x01,
- 0x00, 0x80, 0x0a, 0x3c, 0xec, 0x3d, 0x4a, 0x25, 0x04, 0x00, 0x8a, 0xac, 0x49,
- 0x00, 0x88, 0x90, 0x4a, 0x00, 0x89, 0x90, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x24, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xfe, 0xc0,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x87, 0x94, 0x25, 0x28, 0x91, 0x00,
- 0x08, 0x00, 0xc2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x47, 0x02, 0x00, 0xbd,
- 0xfe, 0x11, 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x92, 0x8c, 0x49, 0x00,
- 0x88, 0x90, 0x4a, 0x00, 0x89, 0x90, 0x23, 0x90, 0x50, 0x02, 0xb0, 0xfe, 0x41,
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xca, 0x90, 0x0a, 0x00, 0xb5, 0x94,
- 0x0c, 0x00, 0xb6, 0x94, 0x24, 0x40, 0x0a, 0x01, 0xa4, 0xfe, 0x09, 0x15, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x93, 0x8c, 0x3c, 0x00, 0x94, 0x8c, 0x0e, 0x00,
- 0x97, 0x94, 0x74, 0x00, 0x88, 0x8c, 0x2a, 0x00, 0x8c, 0x94, 0x62, 0x00, 0x8d,
- 0x90, 0x63, 0x00, 0x8e, 0x90, 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x91, 0xfe, 0xb6, 0x12, 0x21, 0x40, 0x96, 0x02, 0x00, 0x00, 0x03, 0x91, 0x01,
- 0x00, 0xd6, 0x26, 0x24, 0xb0, 0xd7, 0x02, 0x24, 0x40, 0x6d, 0x00, 0x80, 0x40,
- 0x08, 0x00, 0x21, 0x08, 0x1c, 0x01, 0xa0, 0x80, 0x28, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xce, 0x25,
- 0x00, 0x00, 0xc3, 0xa0, 0x21, 0x90, 0x53, 0x02, 0xc1, 0xff, 0x41, 0x06, 0x00,
- 0x00, 0x00, 0x00, 0xbf, 0xff, 0xb6, 0x12, 0x21, 0x40, 0x96, 0x02, 0x00, 0x00,
- 0x03, 0x91, 0x01, 0x00, 0xd6, 0x26, 0x24, 0xb0, 0xd7, 0x02, 0x24, 0x40, 0x6d,
- 0x00, 0x80, 0x40, 0x08, 0x00, 0x21, 0x08, 0x1c, 0x01, 0xa0, 0x80, 0x28, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x88, 0x31, 0xed, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
- 0x00, 0x10, 0x27, 0x00, 0x03, 0x24, 0x01, 0x00, 0x88, 0x31, 0xe8, 0xff, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x10, 0x28, 0x00, 0x03, 0x24,
- 0x01, 0x00, 0x88, 0x31, 0xe3, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x0e,
- 0x00, 0x00, 0x10, 0x21, 0x00, 0x03, 0x24, 0x01, 0x00, 0x88, 0x31, 0xde, 0xff,
- 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x10, 0x29, 0x00, 0x03,
- 0x24, 0x01, 0x00, 0x88, 0x31, 0xd9, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x10, 0x5e, 0x00, 0x03, 0x24, 0x01, 0x00, 0x88, 0x31, 0xd4,
- 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x08, 0x24, 0x00, 0x00,
- 0xc8, 0xa0, 0x02, 0x00, 0xce, 0x25, 0x21, 0x90, 0x53, 0x02, 0xcf, 0xff, 0x40,
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0f, 0x00, 0x0c, 0x61, 0x00, 0x83, 0xa0,
- 0x61, 0x00, 0x83, 0x90, 0xca, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x88, 0x31, 0xc6, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff,
- 0x00, 0x10, 0xe0, 0xff, 0x63, 0x24, 0x02, 0x00, 0xc0, 0x11, 0x00, 0x20, 0x89,
- 0x31, 0xff, 0xff, 0xce, 0x25, 0xc0, 0xff, 0x20, 0x11, 0x02, 0x00, 0x08, 0x24,
- 0x57, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4a, 0x0c, 0x00, 0x0c,
- 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c, 0x01, 0x20, 0x89, 0x29, 0x8c, 0x21, 0x40,
- 0xc0, 0x01, 0x08, 0x00, 0xce, 0x25, 0x08, 0x00, 0x20, 0x01, 0xf8, 0xff, 0xce,
- 0x31, 0x23, 0x40, 0xc8, 0x01, 0x05, 0x00, 0x01, 0x29, 0xb2, 0xff, 0x20, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x00, 0x00, 0x10, 0x02, 0x00, 0x08, 0x24, 0x23, 0x40, 0xc8, 0x01, 0x20, 0x00,
- 0x03, 0x24, 0xff, 0xff, 0x08, 0x25, 0xa9, 0xff, 0x00, 0x19, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xc3, 0xa0, 0x21, 0x90, 0x53, 0x02, 0xf9, 0xff, 0x40, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0f, 0x00, 0x0c, 0x61, 0x00, 0x88, 0xa0, 0x61,
- 0x00, 0x88, 0x90, 0xf4, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x89, 0x31, 0x9d, 0xff, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
- 0x10, 0x7f, 0x00, 0x08, 0x24, 0x00, 0x80, 0x89, 0x31, 0x98, 0xff, 0x20, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x10, 0x7f, 0x00, 0x08, 0x24, 0x21,
- 0x40, 0xc0, 0x01, 0x20, 0x00, 0x8a, 0x31, 0x1a, 0x00, 0x40, 0x15, 0x04, 0x00,
- 0x89, 0x31, 0x09, 0x00, 0x20, 0x11, 0x0d, 0x00, 0x0a, 0x24, 0x00, 0x00, 0x0e,
- 0x24, 0x00, 0x00, 0xca, 0xa0, 0x21, 0x90, 0x53, 0x02, 0x04, 0x00, 0x40, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0f, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x00, 0x03, 0x24, 0x00, 0x01, 0x88, 0x31, 0x85, 0xff, 0x00, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x05, 0x00, 0x08, 0x24, 0x21, 0x40, 0xc0,
- 0x01, 0x00, 0x00, 0x0e, 0x24, 0x08, 0x00, 0x89, 0x31, 0x0e, 0x00, 0x20, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8a, 0x31, 0x03, 0x00, 0x40, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x7d, 0xff, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0e, 0x24, 0xc2, 0x49, 0x0c, 0x00, 0x0c, 0x00, 0x29, 0x31, 0x21, 0x08, 0x3c,
- 0x01, 0x30, 0x89, 0x29, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff, 0x00, 0x10, 0x0a, 0x00, 0x03, 0x24, 0x02,
- 0x41, 0x08, 0x00, 0x05, 0x00, 0x00, 0x10, 0x03, 0x00, 0x08, 0x25, 0x03, 0x00,
- 0x00, 0x10, 0x05, 0x00, 0x08, 0x24, 0x01, 0x00, 0x00, 0x10, 0x09, 0x00, 0x08,
- 0x24, 0x00, 0x00, 0xc3, 0xa0, 0x21, 0x90, 0x53, 0x02, 0x04, 0x00, 0x40, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0f, 0x00, 0x0c, 0x61, 0x00, 0x88, 0xa0, 0x61,
- 0x00, 0x88, 0x90, 0x40, 0x00, 0x89, 0x31, 0x11, 0x00, 0x20, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x01, 0x29, 0x0e, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x00, 0x83, 0x90, 0x04, 0x00, 0x01, 0x29, 0x57, 0xff, 0x20, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xa0, 0x21, 0x90, 0x53, 0x02, 0x53,
- 0xff, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0f, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x00, 0x83, 0x90, 0x4e, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x06, 0x00, 0x08, 0x25, 0x00, 0x1e, 0x09, 0x24, 0x19, 0x00, 0x09, 0x01,
- 0x12, 0x40, 0x00, 0x00, 0x0c, 0xff, 0x00, 0x10, 0x21, 0x90, 0x48, 0x02, 0x01,
- 0x00, 0x00, 0x8c, 0xff, 0xe7, 0xe7, 0x30, 0x42, 0x42, 0x07, 0x00, 0x7c, 0x00,
- 0x08, 0x31, 0x21, 0x98, 0x1c, 0x01, 0xa0, 0x88, 0x73, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0xb8, 0x90,
- 0x5b, 0x00, 0xb9, 0x90, 0x5e, 0x00, 0x8d, 0x90, 0x00, 0x80, 0x13, 0x3c, 0xbc,
- 0x41, 0x73, 0x26, 0xff, 0xfd, 0x68, 0x30, 0x09, 0x00, 0x0d, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x13, 0x3c, 0x40, 0x43, 0x73, 0x26, 0xee, 0xfd, 0x00,
- 0x10, 0x00, 0x08, 0xe7, 0x34, 0x5a, 0x00, 0xb8, 0x90, 0x5b, 0x00, 0xb9, 0x90,
- 0x00, 0x80, 0x13, 0x3c, 0xe8, 0x41, 0x73, 0x26, 0xff, 0xf9, 0x68, 0x30, 0x05,
- 0x00, 0x18, 0x11, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xfd, 0x19, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x88,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x31, 0x0b, 0x00, 0x20, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0x08, 0x31, 0x4a, 0x00, 0x88, 0xa0, 0x54,
- 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0xfb, 0xff, 0x2b, 0x31, 0x26, 0x48,
- 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0, 0xf1, 0xfd, 0x00,
- 0x10, 0x58, 0x00, 0xaa, 0xa0, 0xef, 0xfd, 0x19, 0x17, 0x00, 0x00, 0x00, 0x00,
- 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x35, 0x4a,
- 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0x04, 0x00,
- 0x2b, 0x35, 0x26, 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab,
- 0xa0, 0x58, 0x00, 0xaa, 0xa0, 0x00, 0x08, 0x89, 0x31, 0xe1, 0xfd, 0x20, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xe7, 0x34, 0x00, 0x80, 0x13, 0x3c, 0xdd,
- 0xfd, 0x00, 0x10, 0x90, 0x42, 0x73, 0x26, 0x4a, 0x00, 0x88, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0xf3, 0xff, 0x08, 0x31, 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00, 0xa9,
- 0x90, 0x58, 0x00, 0xaa, 0x90, 0xfb, 0xff, 0x2b, 0x31, 0x26, 0x48, 0x2b, 0x01,
- 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0, 0x58, 0x00, 0xaa, 0xa0, 0xff,
- 0xef, 0xe7, 0x30, 0x42, 0x4a, 0x07, 0x00, 0x7c, 0x00, 0x29, 0x31, 0x21, 0x98,
- 0x3c, 0x01, 0xa0, 0x88, 0x73, 0x8e, 0x40, 0x00, 0x88, 0x31, 0xca, 0xfd, 0x00,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x68, 0x30, 0xc7, 0xfd, 0x0e, 0x11,
- 0x00, 0x00, 0x00, 0x00, 0xc5, 0xfd, 0x0f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x89, 0x31, 0x07, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
- 0xaa, 0x90, 0x5b, 0x00, 0xab, 0x90, 0xbe, 0xfd, 0x0a, 0x11, 0x00, 0x00, 0x00,
- 0x00, 0xbc, 0xfd, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x89, 0x31,
- 0x9c, 0xfd, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x8d, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x98, 0xfd, 0x0d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xe7, 0x34, 0x00, 0x80, 0x13, 0x3c, 0x94, 0xfd, 0x00, 0x10, 0x40, 0x43, 0x73,
- 0x26, 0xff, 0xf7, 0xe7, 0x30, 0x42, 0x4a, 0x07, 0x00, 0x7c, 0x00, 0x29, 0x31,
- 0x21, 0x98, 0x3c, 0x01, 0xa0, 0x88, 0x73, 0x8e, 0x8d, 0xfd, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x00, 0x8d, 0x90, 0xff, 0xfd, 0x68, 0x30, 0x7b, 0xfd,
- 0x0d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe7, 0x34, 0x00, 0x80, 0x13,
- 0x3c, 0x85, 0xfd, 0x00, 0x10, 0x40, 0x43, 0x73, 0x26, 0x4a, 0x00, 0x88, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x31, 0x0b, 0x00, 0x20, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0xff, 0x08, 0x31, 0x4a, 0x00, 0x88, 0xa0, 0x54, 0x00,
- 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0xfb, 0xff, 0x2b, 0x31, 0x26, 0x48, 0x2b,
- 0x01, 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0, 0x93, 0xfd, 0x00, 0x10,
- 0x58, 0x00, 0xaa, 0xa0, 0x91, 0xfd, 0xcf, 0x15, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x00, 0x88, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x35, 0x4a, 0x00,
- 0x88, 0xa0, 0x54, 0x00, 0xa9, 0x90, 0x58, 0x00, 0xaa, 0x90, 0x04, 0x00, 0x2b,
- 0x35, 0x26, 0x48, 0x2b, 0x01, 0x25, 0x50, 0x49, 0x01, 0x54, 0x00, 0xab, 0xa0,
- 0x58, 0x00, 0xaa, 0xa0, 0x00, 0x08, 0x89, 0x31, 0x83, 0xfd, 0x20, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0xe7, 0x34, 0x00, 0x80, 0x13, 0x3c, 0x7f, 0xfd,
- 0x00, 0x10, 0x90, 0x42, 0x73, 0x26, 0xc2, 0x51, 0x03, 0x00, 0x3c, 0x00, 0x4a,
- 0x31, 0x21, 0x40, 0x5c, 0x01, 0xe0, 0x9a, 0x08, 0x8d, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x08, 0x25, 0x21, 0x08, 0x5c, 0x01, 0xe0, 0x9a, 0x28, 0xac, 0x00,
- 0x10, 0x6a, 0x30, 0x0e, 0x00, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x8b, 0x31, 0x71, 0xfd, 0x60, 0x15, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8a,
- 0x31, 0x03, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x10,
- 0x00, 0x10, 0x03, 0x24, 0x4f, 0x00, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x08, 0x35, 0x67, 0xfd, 0x00, 0x10, 0x4f, 0x00, 0xa8, 0xa0, 0x04, 0x00,
- 0x88, 0x31, 0x64, 0xfd, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6a,
- 0x30, 0x0c, 0x00, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x63, 0x30,
- 0x4f, 0x00, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x35, 0x4f,
- 0x00, 0xa8, 0xa0, 0xff, 0x00, 0x0b, 0x24, 0x2a, 0x08, 0x6b, 0x00, 0x40, 0xfd,
- 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x47, 0xfd, 0x6b, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x88, 0x31, 0x08, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0xa1, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x4e,
- 0xfd, 0xb6, 0x16, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0x00, 0x08, 0x24, 0x00, 0x00, 0x28, 0xa1, 0x01, 0x00, 0xb5,
- 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x17, 0x00, 0xb6, 0x12, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x24, 0x00, 0x80, 0x89, 0x31, 0x02, 0x00, 0x20, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x42, 0x03, 0x00, 0x21, 0x48, 0x95, 0x02, 0x00, 0x00,
- 0x28, 0xa1, 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x0a, 0x00, 0xb6,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x21, 0x48, 0x95, 0x02, 0x00, 0x00, 0x23, 0xa1,
- 0x01, 0x00, 0xb5, 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x35, 0xfd, 0xb6, 0x16, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xb5, 0x26, 0xff, 0xff, 0xb5, 0x26, 0x24, 0xb0, 0xb7, 0x02, 0xff, 0xff, 0xb5,
- 0x26, 0x24, 0xa8, 0xb7, 0x02, 0x4f, 0x00, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x00, 0x08, 0x35, 0x29, 0xfd, 0x00, 0x10, 0x4f, 0x00, 0xa8, 0xa0, 0x24,
- 0x00, 0x86, 0x8c, 0x25, 0x28, 0x91, 0x00, 0x78, 0x00, 0xc8, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x48, 0x00, 0x01, 0x50, 0x00, 0x08, 0x31, 0x20, 0x00, 0x29,
- 0x31, 0x80, 0x48, 0x09, 0x00, 0x25, 0x40, 0x09, 0x01, 0x70, 0x00, 0xc9, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x42, 0x48, 0x09, 0x00, 0x20, 0x00, 0x29, 0x31, 0x20,
- 0x00, 0x29, 0x39, 0x25, 0x40, 0x09, 0x01, 0x54, 0x00, 0xa9, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x26, 0x40, 0x09, 0x01, 0xf0, 0x00, 0x08, 0x31, 0x26, 0x48, 0x28,
- 0x01, 0x54, 0x00, 0xa9, 0xa0, 0x58, 0x00, 0xaa, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x50, 0x48, 0x01, 0x08, 0x00, 0xe0, 0x03, 0x58, 0x00, 0xaa, 0xa0, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x3c, 0x25, 0x20,
- 0x81, 0x00, 0x00, 0x20, 0x01, 0x3c, 0x25, 0x28, 0xa1, 0x00, 0x05, 0x00, 0xc1,
- 0x2c, 0x74, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x82, 0x30,
- 0x03, 0x00, 0xa3, 0x30, 0x23, 0x38, 0x43, 0x00, 0x49, 0x00, 0xe0, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x20, 0x82, 0x00, 0x05, 0x00, 0xe0, 0x1c, 0xc0, 0x70,
- 0x02, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
- 0x10, 0x06, 0x48, 0xc8, 0x01, 0x00, 0x00, 0x89, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x48, 0xc9, 0x01, 0x22, 0x78, 0x0e, 0x00, 0x04, 0x00, 0x88, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x50, 0xe8, 0x01, 0x25, 0x48, 0x2a, 0x01, 0x04, 0x00,
- 0x84, 0x24, 0x00, 0x00, 0xa9, 0xb8, 0x23, 0x28, 0xa3, 0x00, 0x21, 0x30, 0xc3,
- 0x00, 0xec, 0xff, 0xc6, 0x24, 0xc0, 0x70, 0x07, 0x00, 0x1a, 0x00, 0xc0, 0x18,
- 0x22, 0x78, 0x0e, 0x00, 0x04, 0x00, 0x89, 0x8c, 0x06, 0x40, 0xc8, 0x01, 0x08,
- 0x00, 0x8a, 0x8c, 0x04, 0x60, 0xe9, 0x01, 0x0c, 0x00, 0x8b, 0x8c, 0x25, 0x60,
- 0x88, 0x01, 0x10, 0x00, 0x88, 0x8c, 0x04, 0x00, 0xac, 0xac, 0x06, 0x48, 0xc9,
- 0x01, 0x04, 0x60, 0xea, 0x01, 0x25, 0x60, 0x89, 0x01, 0x08, 0x00, 0xac, 0xac,
- 0x06, 0x50, 0xca, 0x01, 0x04, 0x60, 0xeb, 0x01, 0x25, 0x60, 0x8a, 0x01, 0x0c,
- 0x00, 0xac, 0xac, 0x06, 0x58, 0xcb, 0x01, 0x04, 0x60, 0xe8, 0x01, 0x25, 0x60,
- 0x8b, 0x01, 0x10, 0x00, 0xac, 0xac, 0x10, 0x00, 0x84, 0x24, 0x10, 0x00, 0xa5,
- 0x24, 0xf0, 0xff, 0xc6, 0x24, 0xe8, 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x00, 0xc6, 0x24, 0x0c, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x48, 0xc8, 0x01, 0x04, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x50,
- 0xe8, 0x01, 0x25, 0x50, 0x49, 0x01, 0x04, 0x00, 0xaa, 0xac, 0x04, 0x00, 0x84,
- 0x24, 0x04, 0x00, 0xa5, 0x24, 0xfc, 0xff, 0xc6, 0x24, 0xf6, 0xff, 0xc0, 0x1c,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c, 0x06, 0x40, 0xc8, 0x01, 0x04,
- 0x48, 0xe9, 0x01, 0x25, 0x40, 0x09, 0x01, 0x22, 0x48, 0x06, 0x00, 0xc0, 0x48,
- 0x09, 0x00, 0x04, 0x40, 0x28, 0x01, 0x21, 0x28, 0xa6, 0x00, 0x08, 0x00, 0xe0,
- 0x03, 0x07, 0x00, 0xa8, 0xa8, 0x00, 0x00, 0x88, 0x98, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xa8, 0xb8, 0x23, 0x28, 0xa3, 0x00, 0x23, 0x20, 0x82, 0x00, 0x21,
- 0x30, 0xc2, 0x00, 0xec, 0xff, 0xc6, 0x24, 0x0e, 0x00, 0xc0, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x00, 0x89, 0x8c, 0x08, 0x00, 0x8a, 0x8c, 0x0c, 0x00, 0x8b,
- 0x8c, 0x10, 0x00, 0x8c, 0x8c, 0x04, 0x00, 0xa9, 0xac, 0x10, 0x00, 0x84, 0x24,
- 0x08, 0x00, 0xaa, 0xac, 0xf0, 0xff, 0xc6, 0x24, 0x0c, 0x00, 0xab, 0xac, 0x10,
- 0x00, 0xac, 0xac, 0x10, 0x00, 0xa5, 0x24, 0xf4, 0xff, 0xc0, 0x1c, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0xc6, 0x24, 0x09, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xa8, 0xac,
- 0x04, 0x00, 0x84, 0x24, 0x04, 0x00, 0xa5, 0x24, 0xfc, 0xff, 0xc6, 0x24, 0xf9,
- 0xff, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x86, 0x00, 0x07, 0x00,
- 0x88, 0x88, 0x21, 0x28, 0xa6, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x07, 0x00, 0xa8,
- 0xa8, 0x09, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0x01, 0x00, 0xa5, 0x24, 0x01,
- 0x00, 0x84, 0x24, 0xff, 0xff, 0xc6, 0x24, 0xf9, 0xff, 0xc0, 0x1c, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3c, 0x08, 0x48, 0x08, 0x25,
- 0x00, 0xa0, 0x01, 0x3c, 0x25, 0x40, 0x01, 0x01, 0x08, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x05, 0x3c, 0x00, 0x60, 0x85, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xa0, 0x09, 0x3c, 0x01, 0x00, 0x01, 0x3c, 0x23, 0x40, 0x21, 0x01,
- 0x03, 0x00, 0x00, 0xa1, 0x04, 0x00, 0x08, 0x25, 0xfd, 0xff, 0x09, 0x15, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x3c, 0x00, 0x60, 0x85, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x09, 0x3c, 0x01, 0x00, 0x01,
- 0x3c, 0x23, 0x40, 0x21, 0x01, 0x03, 0x00, 0x00, 0xa1, 0x04, 0x00, 0x08, 0x25,
- 0xfd, 0xff, 0x09, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x04, 0x40, 0xff, 0xff, 0x08, 0x3c, 0xff, 0x3f, 0x08,
- 0x35, 0x24, 0x20, 0x88, 0x00, 0x00, 0x10, 0x84, 0x40, 0x02, 0x80, 0x08, 0x3c,
- 0x90, 0xb8, 0x08, 0x25, 0xfc, 0xff, 0x01, 0x24, 0x24, 0x40, 0x01, 0x01, 0x02,
- 0x80, 0x09, 0x3c, 0x44, 0xff, 0x29, 0x25, 0xfc, 0xff, 0x01, 0x24, 0x24, 0x48,
- 0x21, 0x01, 0x00, 0x00, 0x00, 0xad, 0x04, 0x00, 0x08, 0x25, 0xfd, 0xff, 0x09,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x02, 0x40, 0xff, 0xff, 0x01, 0x3c, 0xfe, 0x00, 0x21, 0x34, 0x25,
- 0x20, 0x81, 0x00, 0x24, 0x40, 0x44, 0x00, 0x00, 0x60, 0x88, 0x40, 0x01, 0xff,
- 0x42, 0x30, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x26, 0x40, 0x44, 0x00, 0x01, 0xff, 0x08, 0x31,
- 0x26, 0x40, 0x02, 0x01, 0x00, 0x60, 0x88, 0x40, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
- 0x01, 0x24, 0x24, 0x48, 0x01, 0x01, 0x00, 0x60, 0x89, 0x40, 0x00, 0x68, 0x02,
- 0x40, 0x00, 0x03, 0x84, 0x30, 0x25, 0x18, 0x44, 0x00, 0x00, 0x68, 0x83, 0x40,
- 0x00, 0x60, 0x88, 0x40, 0x24, 0x10, 0x44, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x40, 0x00, 0x03, 0x84, 0x30, 0xfe, 0xff,
- 0x01, 0x24, 0x24, 0x48, 0x01, 0x01, 0x00, 0x60, 0x89, 0x40, 0x00, 0x68, 0x02,
- 0x40, 0x27, 0x18, 0x80, 0x00, 0x24, 0x18, 0x62, 0x00, 0x00, 0x68, 0x83, 0x40,
- 0x00, 0x60, 0x88, 0x40, 0x24, 0x10, 0x44, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x10, 0x08, 0x3c, 0x00, 0x60, 0x88, 0x40, 0xc0, 0xbf,
- 0x08, 0x3c, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x09, 0x3c, 0xfe, 0x00, 0x29, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x25,
- 0x40, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x88, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x2b, 0x10, 0x85, 0x00, 0x09, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x82, 0x8c, 0x04, 0x00, 0x84, 0x24, 0x21, 0x10, 0x62, 0x00, 0x2b,
- 0x18, 0x43, 0x00, 0x21, 0x18, 0x43, 0x00, 0x2b, 0x10, 0x85, 0x00, 0xf9, 0xff,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x60,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x1c, 0x04, 0x00, 0x00, 0x14, 0x04, 0x00, 0x25, 0x20, 0x62, 0x00, 0x00,
- 0xff, 0x03, 0x3c, 0x00, 0xff, 0x63, 0x34, 0xff, 0x00, 0x02, 0x3c, 0xff, 0x00,
- 0x42, 0x34, 0x24, 0x18, 0x83, 0x00, 0x02, 0x1a, 0x03, 0x00, 0x24, 0x10, 0x82,
- 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x20, 0x62, 0x00, 0xf0, 0xf0, 0x03, 0x3c,
- 0xf0, 0xf0, 0x63, 0x34, 0x0f, 0x0f, 0x02, 0x3c, 0x0f, 0x0f, 0x42, 0x34, 0x24,
- 0x18, 0x83, 0x00, 0x02, 0x19, 0x03, 0x00, 0x24, 0x10, 0x82, 0x00, 0x00, 0x11,
- 0x02, 0x00, 0x25, 0x20, 0x62, 0x00, 0xcc, 0xcc, 0x03, 0x3c, 0xcc, 0xcc, 0x63,
- 0x34, 0x33, 0x33, 0x02, 0x3c, 0x33, 0x33, 0x42, 0x34, 0x24, 0x18, 0x83, 0x00,
- 0x82, 0x18, 0x03, 0x00, 0x24, 0x10, 0x82, 0x00, 0x80, 0x10, 0x02, 0x00, 0x25,
- 0x20, 0x62, 0x00, 0xaa, 0xaa, 0x03, 0x3c, 0xaa, 0xaa, 0x63, 0x34, 0x55, 0x55,
- 0x02, 0x3c, 0x55, 0x55, 0x42, 0x34, 0x24, 0x18, 0x83, 0x00, 0x42, 0x18, 0x03,
- 0x00, 0x24, 0x10, 0x82, 0x00, 0x40, 0x10, 0x02, 0x00, 0x08, 0x00, 0xe0, 0x03,
- 0x25, 0x10, 0x62, 0x00, 0x00, 0xa2, 0x02, 0x3c, 0x00, 0x40, 0x42, 0x34, 0x00,
- 0x00, 0x42, 0x94, 0x90, 0x99, 0x84, 0x8f, 0x00, 0xc0, 0x43, 0x30, 0x74, 0x9b,
- 0x83, 0xaf, 0x28, 0x00, 0x64, 0x10, 0x00, 0xc0, 0x02, 0x34, 0x0a, 0x00, 0x62,
- 0x14, 0x00, 0x40, 0x02, 0x24, 0x03, 0x00, 0x82, 0x10, 0x00, 0x80, 0x02, 0x34,
- 0x06, 0x00, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x82, 0x38, 0x74,
- 0x9b, 0x82, 0xaf, 0x90, 0x99, 0x80, 0xaf, 0xe2, 0x12, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x99, 0x83, 0x8f, 0x00, 0xc0, 0x02, 0x34, 0x07, 0x00, 0x62,
- 0x14, 0x00, 0x40, 0x02, 0x24, 0x74, 0x9b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x00, 0x62, 0x10, 0x00, 0x80, 0x02, 0x34, 0x1d, 0x00, 0x62, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x74, 0x9b, 0x83, 0x8f, 0x00, 0xc0, 0x02, 0x34, 0x90, 0x99,
- 0x83, 0xaf, 0x09, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9a, 0x82,
- 0x8f, 0x94, 0x99, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0x32, 0x00, 0x42, 0x2c, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x74,
- 0x9b, 0x80, 0xaf, 0xd0, 0x9a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x94, 0x99,
- 0x82, 0xaf, 0xe2, 0x12, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9a, 0x82,
- 0x8f, 0x94, 0x99, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0xe8, 0x03, 0x42, 0x2c, 0x04, 0x00, 0x40, 0x14, 0xfa, 0x00, 0x62, 0x24, 0x94,
- 0x99, 0x82, 0xaf, 0xe2, 0x12, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x74, 0x9b,
- 0x80, 0xaf, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9b, 0x89,
- 0x27, 0x80, 0x9b, 0x86, 0x8f, 0xc0, 0x9c, 0x87, 0x27, 0xff, 0xff, 0xc6, 0x24,
- 0x24, 0x00, 0xc0, 0x04, 0x21, 0x40, 0x00, 0x00, 0x00, 0xa0, 0x04, 0x3c, 0x12,
- 0x10, 0x84, 0x34, 0x55, 0x00, 0x85, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
- 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xff, 0x83, 0x94, 0x00, 0x00, 0xe2,
- 0x94, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x08, 0x25, 0xfa, 0xff, 0x83, 0x94, 0x42, 0x10, 0x05, 0x00, 0x55,
- 0x00, 0x82, 0xa0, 0x00, 0x00, 0xe3, 0xa4, 0x54, 0x00, 0x85, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x00, 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83,
- 0x94, 0x00, 0x00, 0x22, 0x95, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x25, 0x00, 0x00, 0x83, 0x94, 0x42,
- 0x10, 0x05, 0x00, 0x54, 0x00, 0x82, 0xa0, 0x00, 0x00, 0x23, 0xa5, 0x02, 0x00,
- 0x29, 0x25, 0x02, 0x00, 0xe7, 0x24, 0xff, 0xff, 0xc6, 0x24, 0xe0, 0xff, 0xc1,
- 0x04, 0x80, 0x00, 0x84, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x00, 0x01,
- 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0xe4, 0x12, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x98, 0x99, 0x83, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x63, 0x24, 0x21, 0x18, 0x62, 0x00, 0x00, 0x14, 0x03, 0x00, 0x03, 0x24, 0x02,
- 0x00, 0x19, 0x00, 0x82, 0x28, 0x98, 0x99, 0x83, 0xa7, 0x10, 0x00, 0x40, 0x14,
- 0x00, 0xa0, 0x02, 0x3c, 0x9a, 0x99, 0x82, 0x97, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x10, 0x02, 0x00, 0x9a, 0x99, 0x82, 0xa7, 0xfe, 0x03, 0x42, 0x30, 0x04, 0x00,
- 0x40, 0x14, 0x32, 0x00, 0x82, 0x28, 0x01, 0x00, 0x02, 0x24, 0x9a, 0x99, 0x82,
- 0xa7, 0x32, 0x00, 0x82, 0x28, 0x02, 0x00, 0x40, 0x14, 0xe7, 0xff, 0x62, 0x24,
- 0x19, 0x00, 0x02, 0x24, 0x98, 0x99, 0x82, 0xa7, 0x00, 0xa0, 0x02, 0x3c, 0x00,
- 0x01, 0x42, 0x34, 0x9a, 0x99, 0x83, 0x87, 0x10, 0x00, 0x42, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x18, 0x62, 0x00, 0x78, 0x9b, 0x83, 0xaf, 0x10, 0x00, 0xbf,
- 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x18,
- 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x00, 0x02, 0x80, 0x9b, 0x83, 0x8f, 0xff, 0xff,
- 0x42, 0x32, 0x1c, 0x00, 0xbf, 0xaf, 0x2a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x40,
- 0x14, 0x14, 0x00, 0xb1, 0xaf, 0x40, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c,
- 0x74, 0x01, 0x05, 0x24, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x10, 0x63, 0x34, 0x00,
- 0x14, 0x10, 0x00, 0x43, 0x12, 0x02, 0x00, 0x21, 0x80, 0x43, 0x00, 0x54, 0x00,
- 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x30, 0x40, 0x10, 0x04,
- 0x00, 0x04, 0x00, 0x51, 0x30, 0x10, 0x00, 0x82, 0x30, 0x02, 0x00, 0x40, 0x10,
- 0x01, 0x00, 0x82, 0x30, 0x08, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x40,
- 0x00, 0x82, 0x30, 0x40, 0x00, 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x00, 0x31, 0x36, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x42, 0x30, 0x08, 0x00, 0x40, 0x10, 0x80, 0x00, 0x82, 0x30,
- 0x02, 0x00, 0x40, 0x10, 0x20, 0x00, 0x82, 0x30, 0x10, 0x00, 0x31, 0x36, 0x09,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x13, 0x00, 0x08, 0x20, 0x00,
- 0x31, 0x36, 0x02, 0x00, 0x40, 0x10, 0x20, 0x00, 0x82, 0x30, 0x20, 0x00, 0x31,
- 0x36, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x31, 0x36,
- 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0c,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x5f, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x30,
- 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x36, 0x49,
- 0x00, 0x02, 0x92, 0x4a, 0x00, 0x03, 0x92, 0x24, 0x10, 0x44, 0x00, 0x02, 0x00,
- 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31, 0x36, 0x74, 0x9b, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x40, 0x10, 0x00, 0x14, 0x12, 0x00,
- 0x12, 0x00, 0x03, 0x96, 0xc3, 0x13, 0x02, 0x00, 0x67, 0x00, 0x00, 0xa2, 0x66,
- 0x00, 0x00, 0xa2, 0x21, 0x08, 0x5c, 0x00, 0x90, 0x9b, 0x23, 0xa4, 0x0c, 0x00,
- 0x03, 0x96, 0x21, 0x08, 0x5c, 0x00, 0xc0, 0x9c, 0x23, 0xa4, 0xc6, 0x13, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x96, 0x02, 0x00, 0x02, 0x24,
- 0x0f, 0x00, 0xa3, 0x30, 0x14, 0x00, 0x62, 0x10, 0x03, 0x00, 0x62, 0x28, 0x05,
- 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x62, 0x10, 0x01, 0x00,
- 0x04, 0x24, 0xad, 0x13, 0x00, 0x08, 0x00, 0x14, 0x12, 0x00, 0x03, 0x00, 0x02,
- 0x24, 0x0d, 0x00, 0x62, 0x10, 0x04, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x10,
- 0x01, 0x00, 0x04, 0x24, 0xad, 0x13, 0x00, 0x08, 0x00, 0x14, 0x12, 0x00, 0x20,
- 0x00, 0x04, 0x24, 0x00, 0x04, 0xa2, 0x30, 0x09, 0x00, 0x40, 0x10, 0x00, 0x14,
- 0x12, 0x00, 0xad, 0x13, 0x00, 0x08, 0x01, 0x00, 0x04, 0x24, 0xa2, 0x13, 0x00,
- 0x08, 0x10, 0x00, 0x04, 0x24, 0xa2, 0x13, 0x00, 0x08, 0x04, 0x00, 0x04, 0x24,
- 0x02, 0x00, 0x04, 0x24, 0x00, 0x14, 0x12, 0x00, 0x90, 0x9b, 0x83, 0x27, 0xc3,
- 0x33, 0x02, 0x00, 0x21, 0x28, 0xc3, 0x00, 0x12, 0x00, 0x03, 0x96, 0x00, 0x00,
- 0xa2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x66, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x44, 0x00,
- 0x66, 0x00, 0x02, 0xa2, 0x00, 0x00, 0xa3, 0xa4, 0xc0, 0x9c, 0x82, 0x27, 0x21,
- 0x28, 0xc2, 0x00, 0x0c, 0x00, 0x03, 0x96, 0x00, 0x00, 0xa2, 0x94, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x02,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x44, 0x00, 0x67, 0x00, 0x02, 0xa2,
- 0x00, 0x00, 0xa3, 0xa4, 0x67, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x43, 0x30, 0x01, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x62, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0x9b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x30, 0x0a, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1d, 0x00, 0x0c,
- 0x64, 0x00, 0x04, 0x24, 0x1e, 0x00, 0x42, 0x28, 0x05, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xdb, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x31, 0x36, 0x66, 0x00, 0x02,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x30, 0x01, 0x00, 0x02, 0x24,
- 0x0d, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x78, 0x9b, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x0a, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x1d, 0x00, 0x0c, 0x64, 0x00, 0x04, 0x24, 0x1e, 0x00, 0x42,
- 0x28, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x13, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x31, 0x36, 0x67, 0x00, 0x02, 0x92, 0x66, 0x00, 0x03, 0x92, 0x42, 0x10,
- 0x02, 0x00, 0x42, 0x18, 0x03, 0x00, 0x67, 0x00, 0x02, 0xa2, 0x66, 0x00, 0x03,
- 0xa2, 0x78, 0x9b, 0x91, 0xaf, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0xc8, 0x9d, 0x84, 0x8f, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00,
- 0xb0, 0xaf, 0x02, 0x80, 0x10, 0x3c, 0xf0, 0xcb, 0x10, 0x26, 0x1c, 0x00, 0xbf,
- 0xaf, 0x3b, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x26, 0x00, 0x0c,
- 0x14, 0x00, 0x04, 0x24, 0xa8, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x74,
- 0x9b, 0x83, 0x8f, 0x00, 0x80, 0x02, 0x34, 0xb8, 0x00, 0x62, 0x10, 0x2a, 0x10,
- 0x43, 0x00, 0x06, 0x00, 0x40, 0x14, 0x00, 0xc0, 0x02, 0x34, 0x00, 0x40, 0x02,
- 0x24, 0x92, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0x9b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x62, 0x2c, 0xce, 0x01,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01,
- 0x3c, 0x21, 0x08, 0x22, 0x00, 0xe0, 0x1a, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x3c, 0x00,
- 0x01, 0x42, 0x34, 0xe8, 0x15, 0x00, 0x08, 0x10, 0x00, 0x40, 0xac, 0x00, 0xa0,
- 0x02, 0x3c, 0x44, 0x0d, 0x42, 0x8c, 0x00, 0xa0, 0x04, 0x3c, 0x4c, 0x0d, 0x84,
- 0x8c, 0x00, 0xa0, 0x03, 0x3c, 0x50, 0x0d, 0x63, 0x8c, 0x21, 0x10, 0x44, 0x00,
- 0x40, 0x18, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0xa4, 0x99, 0x82, 0xaf, 0xe8,
- 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00, 0x08, 0xc8, 0x00,
- 0x00, 0xae, 0xc4, 0x9d, 0x82, 0x97, 0x80, 0x9b, 0x83, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x2a, 0x10, 0x43, 0x00, 0x05, 0x00, 0x40, 0x14, 0x00, 0xa0, 0x03, 0x3c,
- 0x40, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x7f, 0x02, 0x05, 0x24, 0x00,
- 0xa0, 0x03, 0x3c, 0x00, 0x10, 0x63, 0x34, 0xc4, 0x9d, 0x82, 0x8f, 0xd4, 0x9a,
- 0x84, 0x8f, 0xc0, 0x11, 0x02, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x80, 0x43,
- 0x00, 0x4a, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x63, 0x30,
- 0x4a, 0x00, 0x03, 0xa2, 0x28, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x63, 0x30, 0x05, 0x00, 0x60, 0x10, 0x21, 0x28, 0x40, 0x00, 0x50, 0x00,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0x42, 0x30, 0x50, 0x00, 0x02,
- 0xa6, 0x54, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x30,
- 0xfb, 0x00, 0x64, 0x30, 0x21, 0x10, 0x80, 0x00, 0x26, 0x20, 0x83, 0x00, 0x54,
- 0x00, 0x02, 0xa2, 0x58, 0x00, 0x02, 0x92, 0x28, 0x00, 0x03, 0x96, 0x25, 0x10,
- 0x44, 0x00, 0x00, 0x10, 0x63, 0x30, 0x0a, 0x00, 0x60, 0x10, 0x58, 0x00, 0x02,
- 0xa2, 0x50, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30,
- 0x05, 0x00, 0x40, 0x14, 0x00, 0x02, 0x62, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x00,
- 0x80, 0x02, 0x3c, 0xdc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x3b, 0x12,
- 0x00, 0x0c, 0x21, 0x20, 0xa0, 0x00, 0xe8, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0xa0,
- 0x04, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00, 0x08, 0x00,
- 0x00, 0x43, 0xa0, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
- 0x40, 0xa0, 0x0c, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00,
- 0x08, 0x08, 0x00, 0x43, 0xa0, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x40, 0xa0, 0x14, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0x15, 0x00, 0x08, 0x10, 0x00, 0x43, 0xa0, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0x00, 0x40, 0xa0, 0x1c, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0xe8, 0x15, 0x00, 0x08, 0x18, 0x00, 0x43, 0xa0, 0x54, 0xa0, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x40, 0xa0, 0x24, 0x00, 0x43, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00, 0x08, 0x20, 0x00, 0x43, 0xa0, 0x54, 0xa0,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x40, 0xa0, 0x2c, 0x00, 0x43,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00, 0x08, 0x28, 0x00, 0x43, 0xa0,
- 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x40, 0xa0, 0x34,
- 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00, 0x08, 0x30, 0x00,
- 0x43, 0xa0, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x40,
- 0xa0, 0x3c, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x15, 0x00, 0x08,
- 0x38, 0x00, 0x43, 0xa0, 0x70, 0x9b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x40, 0x14, 0x0f, 0x00, 0x02, 0x24, 0x80, 0x9b, 0x83, 0x8f, 0x70, 0x9b,
- 0x82, 0xaf, 0xc4, 0x9d, 0x83, 0xaf, 0x70, 0x9b, 0x83, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x62, 0x28, 0x06, 0x00, 0x40, 0x14, 0xff, 0xff, 0x62, 0x24,
- 0xc4, 0x9d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x14, 0x00,
- 0xa0, 0x04, 0x3c, 0xff, 0xff, 0x62, 0x24, 0x70, 0x9b, 0x82, 0xaf, 0xe2, 0x14,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x34, 0xc4, 0x9d, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0xc0, 0x19, 0x02, 0x00,
- 0x21, 0x18, 0x64, 0x00, 0x50, 0x00, 0x63, 0x94, 0xc4, 0x9d, 0x82, 0xaf, 0x30,
- 0x00, 0x63, 0x30, 0xf7, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x14,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x70, 0x9b, 0x83, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x62, 0x28, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x62, 0x24, 0x70, 0x9b, 0x82, 0xaf, 0xc4, 0x9d, 0x80, 0xaf, 0xe2,
- 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x9d, 0x82, 0x8f, 0x80, 0x9b,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x14, 0x00, 0x08, 0x01, 0x00, 0x42,
- 0x24, 0xc4, 0x9d, 0x84, 0x8f, 0x00, 0x10, 0x42, 0x34, 0xc0, 0x19, 0x04, 0x00,
- 0x21, 0x18, 0x62, 0x00, 0x50, 0x00, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00, 0x30,
- 0x00, 0x42, 0x30, 0x07, 0x00, 0x40, 0x14, 0x01, 0x00, 0x82, 0x24, 0x80, 0x9b,
- 0x83, 0x8f, 0xc4, 0x9d, 0x82, 0xaf, 0x2a, 0x10, 0x43, 0x00, 0xf3, 0xff, 0x40,
- 0x14, 0x00, 0xa0, 0x02, 0x3c, 0x70, 0x9b, 0x80, 0xaf, 0xd0, 0x9a, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x9c, 0x99, 0x82, 0xaf, 0x70, 0x9b, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x62, 0x2c, 0xab, 0x00, 0x40, 0x10, 0x80, 0x10,
- 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x20, 0x1b, 0x22,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0f, 0x13, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x15, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x74, 0x9b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x99, 0x80, 0xaf, 0x10, 0x9c, 0x83,
- 0x8f, 0xa0, 0x99, 0x84, 0x8f, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x40, 0x10, 0x02, 0x00, 0x14, 0x9c, 0x83, 0x8f, 0x21, 0x10, 0x44, 0x00, 0x1b,
- 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x07, 0x00, 0x12, 0x18, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0xa0, 0x99, 0x82,
- 0xaf, 0xff, 0x03, 0x02, 0x24, 0x07, 0x10, 0x62, 0x00, 0x78, 0x9b, 0x82, 0xaf,
- 0xa3, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x74, 0x9b, 0x82, 0x8f, 0x02,
- 0x80, 0x10, 0x3c, 0x02, 0x00, 0x40, 0x10, 0xf0, 0xcb, 0x10, 0x26, 0xa0, 0x99,
- 0x80, 0xaf, 0xb4, 0x00, 0x03, 0x8e, 0xc4, 0x00, 0x04, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x2b, 0x10, 0x64, 0x00, 0x03, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00,
- 0x21, 0x18, 0x80, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x40,
- 0x10, 0x02, 0x00, 0xa0, 0x99, 0x84, 0x8f, 0x94, 0x00, 0x03, 0x8e, 0x21, 0x10,
- 0x44, 0x00, 0x1b, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x0d, 0x00, 0x07, 0x00, 0x12, 0x18, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
- 0xff, 0x03, 0x04, 0x24, 0x78, 0x9b, 0x84, 0xaf, 0xa0, 0x99, 0x82, 0xaf, 0x0a,
- 0x00, 0x62, 0x28, 0x7a, 0x00, 0x40, 0x10, 0x0a, 0x00, 0x02, 0x24, 0x23, 0x10,
- 0x43, 0x00, 0x07, 0x10, 0x44, 0x00, 0x78, 0x9b, 0x82, 0xaf, 0xa3, 0x15, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x04, 0x3c, 0x44, 0x0d, 0x84, 0x8c,
- 0x00, 0xa0, 0x03, 0x3c, 0x4c, 0x0d, 0x63, 0x8c, 0x00, 0xa0, 0x02, 0x3c, 0x50,
- 0x0d, 0x42, 0x8c, 0x21, 0x20, 0x83, 0x00, 0x40, 0x10, 0x02, 0x00, 0xa4, 0x99,
- 0x83, 0x8f, 0x21, 0x20, 0x82, 0x00, 0x23, 0x20, 0x83, 0x00, 0x78, 0x9b, 0x84,
- 0xaf, 0x8e, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x62, 0x28, 0x02, 0x00, 0x40, 0x10, 0xff,
- 0x03, 0x04, 0x24, 0x21, 0x20, 0x60, 0x00, 0x78, 0x9b, 0x84, 0xaf, 0x8e, 0x15,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x43, 0x90, 0x24, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x12, 0x02, 0x00, 0x25, 0x18, 0x62, 0x00, 0x78, 0x9b, 0x83, 0xaf, 0xa3,
- 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, 0x04, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x87, 0x15, 0x00, 0x08, 0x00, 0x12, 0x02, 0x00, 0x54, 0xa0, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x43, 0x90, 0x0c, 0x00, 0x42, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x87, 0x15, 0x00, 0x08, 0x00, 0x12, 0x02, 0x00, 0x54, 0xa0,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x43, 0x90, 0x14, 0x00, 0x42,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x87, 0x15, 0x00, 0x08, 0x00, 0x12, 0x02, 0x00,
- 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x43, 0x90, 0x1c,
- 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x87, 0x15, 0x00, 0x08, 0x00, 0x12,
- 0x02, 0x00, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x43,
- 0x90, 0x24, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x87, 0x15, 0x00, 0x08,
- 0x00, 0x12, 0x02, 0x00, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x28,
- 0x00, 0x43, 0x90, 0x2c, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x87, 0x15,
- 0x00, 0x08, 0x00, 0x12, 0x02, 0x00, 0x54, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x43, 0x90, 0x34, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x87, 0x15, 0x00, 0x08, 0x00, 0x12, 0x02, 0x00, 0x54, 0xa0, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x38, 0x00, 0x43, 0x90, 0x3c, 0x00, 0x42, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x18, 0x62, 0x00, 0x78, 0x9b, 0x83,
- 0xaf, 0x00, 0x04, 0x63, 0x28, 0x02, 0x00, 0x60, 0x14, 0xff, 0x03, 0x02, 0x24,
- 0x78, 0x9b, 0x82, 0xaf, 0x78, 0x9b, 0x84, 0x8f, 0x80, 0x12, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x82, 0x15, 0x02, 0x00, 0x78, 0x9b, 0x82, 0xaf, 0xa3, 0x15,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0xc4, 0x9d, 0x84,
- 0x8f, 0x00, 0x10, 0x63, 0x34, 0xc0, 0x11, 0x04, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x50, 0x00, 0x42, 0x94, 0x10, 0x00, 0x03, 0x24, 0x30, 0x00, 0x42, 0x30, 0x05,
- 0x00, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x36, 0x13, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0xa3, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x9b, 0x80,
- 0xaf, 0x70, 0x9b, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x60, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x98, 0xbc, 0x42, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08,
- 0x22, 0x00, 0x52, 0x22, 0x22, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02,
- 0x00, 0xd1, 0x15, 0x00, 0x08, 0x54, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x62, 0x28,
- 0x18, 0x00, 0x40, 0x14, 0x66, 0x66, 0x02, 0x3c, 0xc4, 0x9d, 0x84, 0x8f, 0x67,
- 0x66, 0x42, 0x34, 0x01, 0x00, 0x84, 0x24, 0x18, 0x00, 0x82, 0x00, 0xc3, 0x17,
- 0x04, 0x00, 0x10, 0x30, 0x00, 0x00, 0x83, 0x18, 0x06, 0x00, 0x23, 0x18, 0x62,
- 0x00, 0x40, 0x28, 0x03, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x40, 0x10, 0x02, 0x00, 0x23, 0x20, 0x82, 0x00, 0x40, 0x20, 0x04, 0x00, 0x01,
- 0x80, 0x02, 0x3c, 0x21, 0x10, 0x45, 0x00, 0x50, 0x22, 0x42, 0x94, 0x01, 0x80,
- 0x03, 0x3c, 0x21, 0x18, 0x64, 0x00, 0x50, 0x22, 0x63, 0x94, 0x00, 0x12, 0x02,
- 0x00, 0xd1, 0x15, 0x00, 0x08, 0x21, 0x10, 0x43, 0x00, 0x40, 0x10, 0x03, 0x00,
- 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x30, 0x22, 0x22, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x7c, 0x9b, 0x82, 0xaf, 0xd0, 0x9a, 0x84, 0x8f, 0x9c, 0x99,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x82, 0x00, 0xf4, 0x01, 0x62,
- 0x2c, 0x06, 0x00, 0x40, 0x10, 0xe8, 0x03, 0x62, 0x2c, 0x7c, 0x9b, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x34, 0x7c, 0x9b, 0x82, 0xaf, 0xe8,
- 0x03, 0x62, 0x2c, 0x02, 0x00, 0x40, 0x14, 0x00, 0xa2, 0x05, 0x3c, 0x9c, 0x99,
- 0x84, 0xaf, 0x00, 0x40, 0xa5, 0x34, 0x00, 0xa2, 0x04, 0x3c, 0x78, 0x9b, 0x82,
- 0x97, 0x7c, 0x9b, 0x83, 0x97, 0x04, 0x40, 0x84, 0x34, 0x00, 0x00, 0xa2, 0xa4,
- 0x00, 0x00, 0x83, 0xa4, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x00, 0xa2,
- 0x02, 0x3c, 0x00, 0x40, 0x42, 0x34, 0x00, 0xa2, 0x03, 0x3c, 0x04, 0x40, 0x63,
- 0x34, 0x20, 0x9c, 0x84, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x00, 0x00, 0x40, 0xa4,
- 0xff, 0xff, 0x02, 0x34, 0x00, 0x00, 0x62, 0xa4, 0x01, 0x00, 0x02, 0x24, 0x00,
- 0x80, 0x06, 0x3c, 0xf4, 0x4f, 0xc6, 0x24, 0x02, 0x80, 0x07, 0x3c, 0xf0, 0xcb,
- 0xe7, 0x24, 0x70, 0x9b, 0x82, 0xaf, 0x35, 0x26, 0x00, 0x0c, 0x01, 0x00, 0x05,
- 0x24, 0x20, 0x9c, 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42,
- 0x30, 0x0d, 0x00, 0x40, 0x10, 0x21, 0x30, 0xa0, 0x00, 0x48, 0x00, 0x82, 0x90,
- 0x01, 0x00, 0x03, 0x24, 0x01, 0x00, 0xa3, 0xa0, 0xb0, 0x00, 0x42, 0x24, 0x00,
- 0x00, 0xa2, 0xa0, 0x0e, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0xa2, 0xa0, 0x0e, 0x00, 0x82, 0x94, 0x04, 0x00, 0xa6, 0x24, 0x02, 0x12, 0x02,
- 0x00, 0x03, 0x00, 0xa2, 0xa0, 0x2e, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x42, 0x30, 0x0d, 0x00, 0x40, 0x10, 0x0e, 0x00, 0x03, 0x24, 0x48,
- 0x00, 0x82, 0x90, 0x01, 0x00, 0xc3, 0xa0, 0xb0, 0x00, 0x42, 0x24, 0x00, 0x00,
- 0xc2, 0xa0, 0x78, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc2,
- 0xa0, 0x78, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x02, 0x00,
- 0x03, 0x00, 0xc2, 0xa0, 0x04, 0x00, 0xc6, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x23,
- 0x10, 0xc5, 0x00, 0x80, 0xfe, 0xbd, 0x27, 0x5c, 0x01, 0xb1, 0xaf, 0x10, 0x01,
- 0xa5, 0xaf, 0x10, 0x01, 0xb1, 0x8f, 0xd0, 0x9d, 0x82, 0x93, 0xd0, 0x9a, 0x8b,
- 0x8f, 0x6c, 0x01, 0xb5, 0xaf, 0x21, 0xa8, 0x00, 0x00, 0x7c, 0x01, 0xbf, 0xaf,
- 0x78, 0x01, 0xbe, 0xaf, 0x74, 0x01, 0xb7, 0xaf, 0x70, 0x01, 0xb6, 0xaf, 0x68,
- 0x01, 0xb4, 0xaf, 0x64, 0x01, 0xb3, 0xaf, 0x60, 0x01, 0xb2, 0xaf, 0x58, 0x01,
- 0xb0, 0xaf, 0x21, 0x30, 0x26, 0x02, 0x18, 0x01, 0xa6, 0xaf, 0x28, 0x00, 0x40,
- 0x10, 0x20, 0x01, 0xab, 0xaf, 0xd0, 0x9d, 0x84, 0x27, 0x04, 0x00, 0x25, 0x26,
- 0x0a, 0x00, 0x06, 0x24, 0xf4, 0x00, 0x02, 0x24, 0x00, 0x00, 0x22, 0xa2, 0x10,
- 0x01, 0xab, 0x8f, 0xb3, 0x00, 0x02, 0x24, 0x01, 0x00, 0x62, 0xa1, 0xc3, 0x00,
- 0x02, 0x24, 0x02, 0x00, 0x62, 0xa1, 0x95, 0x00, 0x02, 0x24, 0x78, 0x11, 0x00,
- 0x0c, 0x03, 0x00, 0x62, 0xa1, 0x01, 0x00, 0x02, 0x24, 0x10, 0x01, 0xab, 0x8f,
- 0xd0, 0x9d, 0x83, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x62, 0x14, 0x0e,
- 0x00, 0x71, 0x25, 0xff, 0x1f, 0x02, 0x3c, 0xff, 0xff, 0x42, 0x34, 0x21, 0x28,
- 0x20, 0x02, 0x02, 0x80, 0x04, 0x3c, 0xe4, 0xbc, 0x84, 0x8c, 0x02, 0x80, 0x06,
- 0x3c, 0xe8, 0xbc, 0xc6, 0x94, 0x24, 0x20, 0x82, 0x00, 0x00, 0xa0, 0x02, 0x3c,
- 0x78, 0x11, 0x00, 0x0c, 0x25, 0x20, 0x82, 0x00, 0x02, 0x80, 0x02, 0x3c, 0xe8,
- 0xbc, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x21, 0x88, 0x22, 0x02, 0x18, 0x01,
- 0xab, 0x8f, 0xd0, 0x9d, 0x80, 0xa3, 0x2b, 0x10, 0x2b, 0x02, 0x68, 0x01, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0xb0, 0x00, 0x00, 0x10, 0x00, 0xab, 0x27,
- 0x21, 0x90, 0x00, 0x00, 0x38, 0x01, 0xab, 0xaf, 0x02, 0x80, 0x0b, 0x3c, 0x60,
- 0xcd, 0x6b, 0x25, 0x24, 0x00, 0x74, 0x25, 0x28, 0x01, 0xa0, 0xaf, 0x30, 0x01,
- 0xab, 0xaf, 0x30, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x82, 0x8e, 0x00, 0x00, 0x77,
- 0x8d, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x40, 0x10, 0x21, 0x98, 0x00, 0x00,
- 0xf0, 0xff, 0x5e, 0x26, 0x7a, 0x00, 0xf0, 0x26, 0x98, 0xff, 0x02, 0x96, 0x9a,
- 0xff, 0x06, 0x96, 0x9c, 0xff, 0x07, 0x96, 0x23, 0x10, 0x46, 0x00, 0x24, 0x20,
- 0xe2, 0x00, 0xfc, 0xff, 0x82, 0x8e, 0x50, 0x89, 0x83, 0x8f, 0x21, 0x10, 0x62,
- 0x02, 0x2b, 0x10, 0x43, 0x00, 0x0c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x54, 0x89, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x85, 0x00, 0x07,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xff, 0x03, 0x96, 0x54, 0x89,
- 0x82, 0x97, 0x24, 0x20, 0xa3, 0x00, 0x21, 0x10, 0xc2, 0x00, 0x24, 0x10, 0xe2,
- 0x00, 0x98, 0xff, 0x02, 0xa6, 0x02, 0x00, 0x02, 0x96, 0x04, 0x00, 0x03, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0xa4, 0xff, 0x03, 0x96, 0xff,
- 0xff, 0x42, 0x30, 0x23, 0x18, 0x62, 0x00, 0x2a, 0x10, 0x64, 0x00, 0x02, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x60, 0x00, 0x14, 0x00, 0x80,
- 0x18, 0x09, 0x00, 0x82, 0x28, 0x05, 0x00, 0x40, 0x14, 0x01, 0x00, 0x82, 0x24,
- 0x00, 0x01, 0x82, 0x28, 0x02, 0x00, 0x40, 0x14, 0x02, 0x00, 0x82, 0x24, 0x03,
- 0x00, 0x82, 0x24, 0x21, 0x20, 0x40, 0x00, 0x00, 0x16, 0x12, 0x00, 0x00, 0x1c,
- 0x13, 0x00, 0x21, 0x10, 0x43, 0x00, 0x38, 0x01, 0xab, 0x8f, 0x21, 0x10, 0x44,
- 0x00, 0x00, 0x00, 0x62, 0xad, 0x04, 0x00, 0x6b, 0x25, 0x38, 0x01, 0xab, 0xaf,
- 0x28, 0x01, 0xab, 0x8f, 0x01, 0x00, 0xd6, 0x26, 0x21, 0x58, 0x64, 0x01, 0x28,
- 0x01, 0xab, 0xaf, 0xb4, 0xff, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xb2, 0x12, 0x21, 0x20, 0xe0,
- 0x02, 0x00, 0x00, 0x3e, 0xa2, 0x01, 0x00, 0x31, 0x26, 0x21, 0xa8, 0x40, 0x02,
- 0xe4, 0xff, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x40, 0x00, 0x21,
- 0x28, 0x20, 0x02, 0xb4, 0xff, 0x00, 0xa6, 0x18, 0x01, 0xab, 0x8f, 0x21, 0x88,
- 0x22, 0x02, 0x2b, 0x10, 0x2b, 0x02, 0x0e, 0x01, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0xd5, 0xff, 0x02, 0x92, 0xde, 0xff, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x10, 0x43, 0x00, 0x1f, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0xb2, 0x12, 0xc0, 0xff, 0x62, 0x26, 0x00, 0x00, 0x3e, 0xa2, 0x01, 0x00,
- 0x31, 0x26, 0x21, 0xa8, 0x40, 0x02, 0x00, 0x00, 0x22, 0xa2, 0xd4, 0x9a, 0x84,
- 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xff, 0x03, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x23, 0xa2, 0xdd, 0xff, 0x03, 0x92, 0xde,
- 0xff, 0x05, 0x92, 0x21, 0x20, 0x40, 0x00, 0xd5, 0xff, 0x00, 0xa2, 0x26, 0x18,
- 0x65, 0x00, 0xdd, 0xff, 0x03, 0xa2, 0x02, 0x00, 0x23, 0xa2, 0xda, 0xff, 0x02,
- 0x92, 0xdd, 0xff, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x43, 0x00,
- 0x3b, 0x12, 0x00, 0x0c, 0xde, 0xff, 0x02, 0xa2, 0x18, 0x01, 0xab, 0x8f, 0x03,
- 0x00, 0x31, 0x26, 0x2b, 0x10, 0x2b, 0x02, 0xea, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0xff, 0x02, 0x96, 0x92, 0xff, 0x03, 0x96, 0x94, 0xff, 0x04,
- 0x96, 0x23, 0x10, 0x43, 0x00, 0x24, 0x20, 0x44, 0x00, 0x0d, 0x00, 0x80, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x96, 0x00, 0x00, 0x02, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x32, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xff,
- 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x18, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x17, 0x00, 0x08, 0x01, 0x00, 0x73, 0x26,
- 0xfe, 0xff, 0x06, 0x96, 0x00, 0x00, 0x05, 0x96, 0x9c, 0xff, 0x03, 0x96, 0x23,
- 0x10, 0xc5, 0x00, 0x00, 0x14, 0x02, 0x00, 0x03, 0x14, 0x02, 0x00, 0x23, 0x10,
- 0x44, 0x00, 0x82, 0x18, 0x03, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x0b, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xc5, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xf8, 0xff, 0x02, 0x96, 0x20, 0x01, 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23,
- 0x10, 0x62, 0x01, 0xff, 0xff, 0x42, 0x30, 0xd0, 0x07, 0x42, 0x2c, 0x16, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xab, 0x97, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0xb2, 0x12, 0xf8, 0xff, 0x0b, 0xa6, 0x00, 0x00, 0x3e, 0xa2,
- 0x01, 0x00, 0x31, 0x26, 0x21, 0xa8, 0x40, 0x02, 0xfe, 0xff, 0x02, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x20, 0x44, 0x00, 0xa0, 0xff, 0x62, 0x26, 0x00, 0x00,
- 0x04, 0xa6, 0x00, 0x00, 0x22, 0xa2, 0x03, 0x12, 0x04, 0x00, 0x01, 0x00, 0x24,
- 0xa2, 0x02, 0x00, 0x22, 0xa2, 0x18, 0x01, 0xab, 0x8f, 0x03, 0x00, 0x31, 0x26,
- 0x2b, 0x10, 0x2b, 0x02, 0xad, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x73, 0x26, 0x80, 0x00, 0x10, 0x26, 0x00, 0x00, 0x82, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x10, 0x62, 0x02, 0x50, 0xff, 0x40, 0x14, 0x80, 0x00, 0xf7,
- 0x26, 0x01, 0x00, 0x52, 0x26, 0x2c, 0x00, 0x94, 0x26, 0x30, 0x01, 0xab, 0x8f,
- 0x04, 0x00, 0x42, 0x2a, 0x2c, 0x00, 0x6b, 0x25, 0x41, 0xff, 0x40, 0x14, 0x30,
- 0x01, 0xab, 0xaf, 0x9d, 0x00, 0xc0, 0x12, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01,
- 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x50, 0x71, 0x01, 0x28, 0x01, 0xab,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x4b, 0x01, 0x03, 0x00, 0x40, 0x14,
- 0x21, 0x38, 0x40, 0x01, 0x62, 0x17, 0x00, 0x08, 0x21, 0xa0, 0x40, 0x01, 0x21,
- 0x28, 0xc0, 0x02, 0x21, 0x40, 0x00, 0x00, 0x1a, 0x00, 0xe5, 0x00, 0x02, 0x00,
- 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01,
- 0x24, 0x04, 0x00, 0xa1, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0xe1, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0xa0, 0x00, 0x00, 0x21,
- 0x38, 0x40, 0x01, 0x21, 0x48, 0xa0, 0x00, 0x21, 0x28, 0xc0, 0x02, 0x10, 0x00,
- 0xa6, 0x27, 0x0c, 0x00, 0xc0, 0x1a, 0x21, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc3,
- 0x94, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x83, 0x02, 0x03, 0x00, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x38, 0xe3, 0x00, 0xff, 0xff, 0xa5, 0x24, 0x01,
- 0x00, 0x84, 0x24, 0x2a, 0x10, 0x96, 0x00, 0xf6, 0xff, 0x40, 0x14, 0x04, 0x00,
- 0xc6, 0x24, 0x08, 0x00, 0xa0, 0x10, 0x02, 0x00, 0x82, 0x2a, 0x06, 0x00, 0xa9,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x25, 0x04, 0x00, 0x02, 0x29,
- 0xdd, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82, 0x2a, 0x09,
- 0x00, 0x40, 0x10, 0x40, 0x18, 0x16, 0x00, 0x10, 0x01, 0xab, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x10, 0x2b, 0x02, 0x21, 0x10, 0x43, 0x00, 0x2c, 0x01, 0x42,
- 0x28, 0x66, 0x00, 0x40, 0x10, 0x23, 0x10, 0x2b, 0x02, 0x02, 0x00, 0x14, 0x24,
- 0x10, 0x00, 0xbe, 0x27, 0x5f, 0x00, 0xc0, 0x1a, 0x21, 0xb8, 0x00, 0x00, 0x00,
- 0x00, 0xd0, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x03, 0x26, 0x10, 0x00, 0x03, 0x14,
- 0x10, 0x00, 0xff, 0xff, 0x10, 0x32, 0xff, 0x00, 0x45, 0x30, 0x40, 0x10, 0x04,
- 0x00, 0x21, 0x10, 0x44, 0x00, 0x80, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03, 0x3c, 0x21, 0x18, 0x62, 0x00, 0x60,
- 0xcd, 0x63, 0x8c, 0xc0, 0x11, 0x05, 0x00, 0x05, 0x00, 0xa4, 0x12, 0x21, 0x98,
- 0x62, 0x00, 0xf0, 0xff, 0x82, 0x24, 0x00, 0x00, 0x22, 0xa2, 0x01, 0x00, 0x31,
- 0x26, 0x21, 0xa8, 0x80, 0x00, 0x2a, 0x10, 0x90, 0x02, 0x03, 0x00, 0x40, 0x10,
- 0x0a, 0x00, 0x02, 0x2a, 0x21, 0x80, 0x80, 0x02, 0x0a, 0x00, 0x02, 0x2a, 0x08,
- 0x00, 0x40, 0x10, 0x02, 0x01, 0x02, 0x2a, 0xff, 0xff, 0x10, 0x26, 0xff, 0xff,
- 0x02, 0x26, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x45, 0x00, 0x00, 0x00, 0x22,
- 0xa2, 0xa1, 0x17, 0x00, 0x08, 0x01, 0x00, 0x31, 0x26, 0x06, 0x00, 0x40, 0x10,
- 0x80, 0xff, 0xa2, 0x24, 0xfe, 0xff, 0x10, 0x26, 0x00, 0x00, 0x22, 0xa2, 0x01,
- 0x00, 0x30, 0xa2, 0xa1, 0x17, 0x00, 0x08, 0x02, 0x00, 0x31, 0x26, 0xfd, 0xff,
- 0x10, 0x26, 0x90, 0xff, 0xa2, 0x24, 0x00, 0x00, 0x22, 0xa2, 0x03, 0x12, 0x10,
- 0x00, 0x01, 0x00, 0x30, 0xa2, 0x02, 0x00, 0x22, 0xa2, 0x03, 0x00, 0x31, 0x26,
- 0x7c, 0x00, 0x62, 0x96, 0x14, 0x00, 0x67, 0x96, 0x16, 0x00, 0x63, 0x96, 0x21,
- 0x10, 0x50, 0x00, 0x7c, 0x00, 0x62, 0xa6, 0xff, 0xff, 0xe2, 0x24, 0x23, 0x90,
- 0x62, 0x00, 0x2a, 0x10, 0x12, 0x02, 0x09, 0x00, 0x40, 0x14, 0x21, 0x28, 0x20,
- 0x02, 0x21, 0x30, 0x40, 0x02, 0x21, 0x88, 0x26, 0x02, 0x38, 0x00, 0x64, 0x8e,
- 0x23, 0x80, 0x06, 0x02, 0x78, 0x11, 0x00, 0x0c, 0x21, 0x20, 0x87, 0x00, 0x14,
- 0x00, 0x60, 0xa6, 0x21, 0x28, 0x20, 0x02, 0x21, 0x30, 0x00, 0x02, 0x14, 0x00,
- 0x62, 0x96, 0x38, 0x00, 0x64, 0x8e, 0x21, 0x88, 0x30, 0x02, 0x78, 0x11, 0x00,
- 0x0c, 0x21, 0x20, 0x82, 0x00, 0x14, 0x00, 0x63, 0x96, 0x50, 0x00, 0x62, 0x96,
- 0x21, 0x18, 0x70, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0c, 0x00, 0x40, 0x10, 0x14,
- 0x00, 0x63, 0xa6, 0x12, 0x00, 0x62, 0x96, 0xff, 0xff, 0x63, 0x30, 0x23, 0x10,
- 0x43, 0x00, 0x16, 0x00, 0x63, 0x96, 0x1a, 0x00, 0x64, 0x96, 0x24, 0x10, 0x43,
- 0x00, 0x2a, 0x10, 0x44, 0x00, 0x03, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xa7, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0xf7, 0x26, 0x2a,
- 0x10, 0xf6, 0x02, 0xa3, 0xff, 0x40, 0x14, 0x04, 0x00, 0xde, 0x27, 0x10, 0x01,
- 0xab, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x2b, 0x02, 0x7c, 0x01, 0xbf,
- 0x8f, 0x78, 0x01, 0xbe, 0x8f, 0x74, 0x01, 0xb7, 0x8f, 0x70, 0x01, 0xb6, 0x8f,
- 0x6c, 0x01, 0xb5, 0x8f, 0x68, 0x01, 0xb4, 0x8f, 0x64, 0x01, 0xb3, 0x8f, 0x60,
- 0x01, 0xb2, 0x8f, 0x5c, 0x01, 0xb1, 0x8f, 0x58, 0x01, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x80, 0x01, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x80, 0x80, 0x00, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf,
- 0x14, 0x00, 0xb1, 0xaf, 0x03, 0x00, 0xa2, 0x90, 0x02, 0x00, 0xa3, 0x90, 0x01,
- 0x00, 0xa4, 0x90, 0x00, 0x12, 0x02, 0x00, 0x25, 0x88, 0x43, 0x00, 0x1f, 0x00,
- 0x84, 0x30, 0x0f, 0x00, 0x82, 0x2c, 0x2c, 0x01, 0x40, 0x10, 0x80, 0x10, 0x04,
- 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x60, 0x1b, 0x22, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x22, 0x32, 0x0a, 0x00, 0x40, 0x10, 0x40, 0x00, 0x22, 0x32, 0xd4, 0x9a,
- 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40,
- 0x00, 0x2f, 0x2a, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x3b, 0x12, 0x00, 0x0c,
- 0x21, 0x20, 0x40, 0x02, 0x40, 0x00, 0x22, 0x32, 0x19, 0x00, 0x40, 0x10, 0x80,
- 0x00, 0x22, 0x32, 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x28, 0x00, 0x03,
- 0x96, 0x04, 0x00, 0x42, 0x34, 0x00, 0x08, 0x63, 0x30, 0x05, 0x00, 0x60, 0x10,
- 0x4a, 0x00, 0x02, 0xa2, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x42, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x21, 0x20, 0x40, 0x02, 0x54, 0x00,
- 0x05, 0x92, 0x58, 0x00, 0x02, 0x92, 0x04, 0x00, 0xa3, 0x34, 0x54, 0x00, 0x03,
- 0xa2, 0x26, 0x18, 0x65, 0x00, 0x25, 0x10, 0x43, 0x00, 0x3b, 0x12, 0x00, 0x0c,
- 0x58, 0x00, 0x02, 0xa2, 0x80, 0x00, 0x22, 0x32, 0x19, 0x00, 0x40, 0x10, 0x10,
- 0x00, 0x22, 0x32, 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x4a, 0x00, 0x02, 0x92, 0x28, 0x00, 0x03,
- 0x96, 0xf3, 0x00, 0x42, 0x30, 0x00, 0x08, 0x63, 0x30, 0x05, 0x00, 0x60, 0x10,
- 0x4a, 0x00, 0x02, 0xa2, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xef, 0x42, 0x30, 0x50, 0x00, 0x02, 0xa6, 0x21, 0x20, 0x40, 0x02, 0x54, 0x00,
- 0x05, 0x92, 0x58, 0x00, 0x02, 0x92, 0xfb, 0x00, 0xa3, 0x30, 0x54, 0x00, 0x03,
- 0xa2, 0x26, 0x18, 0x65, 0x00, 0x25, 0x10, 0x43, 0x00, 0x3b, 0x12, 0x00, 0x0c,
- 0x58, 0x00, 0x02, 0xa2, 0x10, 0x00, 0x22, 0x32, 0x0e, 0x00, 0x40, 0x10, 0x20,
- 0x00, 0x22, 0x32, 0x12, 0x00, 0x02, 0x96, 0x14, 0x00, 0x03, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x16, 0x00, 0x03, 0x96, 0x1a, 0x00, 0x04,
- 0x96, 0x24, 0x10, 0x43, 0x00, 0x2a, 0x10, 0x44, 0x00, 0x04, 0x00, 0x40, 0x14,
- 0x20, 0x00, 0x22, 0x32, 0x77, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x20,
- 0x00, 0x22, 0x32, 0x0d, 0x00, 0x40, 0x10, 0x00, 0x02, 0x22, 0x32, 0x12, 0x00,
- 0x03, 0x96, 0x14, 0x00, 0x02, 0x96, 0x16, 0x00, 0x04, 0x96, 0x23, 0x18, 0x62,
- 0x00, 0x1c, 0x00, 0x02, 0x96, 0x24, 0x18, 0x64, 0x00, 0x2a, 0x10, 0x43, 0x00,
- 0x04, 0x00, 0x40, 0x14, 0x00, 0x02, 0x22, 0x32, 0xa7, 0x28, 0x00, 0x0c, 0x21,
- 0x20, 0x00, 0x02, 0x00, 0x02, 0x22, 0x32, 0x1c, 0x00, 0x40, 0x10, 0x00, 0x04,
- 0x22, 0x32, 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x90, 0x40, 0x00, 0x12, 0x00, 0x03, 0x96, 0x14, 0x00, 0x04, 0x96,
- 0x16, 0x00, 0x02, 0x96, 0x23, 0x18, 0x64, 0x00, 0x1a, 0x00, 0x04, 0x96, 0x24,
- 0x18, 0x62, 0x00, 0x2a, 0x18, 0x64, 0x00, 0x03, 0x00, 0x60, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x77, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x28, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x42, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x3b, 0x12, 0x00, 0x0c, 0x21, 0x20,
- 0x40, 0x02, 0x00, 0x04, 0x22, 0x32, 0xae, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02,
- 0x24, 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x12, 0x00, 0x03, 0x96, 0x14, 0x00, 0x04, 0x96, 0x21, 0x90, 0x40, 0x00, 0x23,
- 0x18, 0x64, 0x00, 0x16, 0x00, 0x04, 0x96, 0x1c, 0x00, 0x02, 0x96, 0x24, 0x18,
- 0x64, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0xa7, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x28, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x7c, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x42, 0x34, 0xfd, 0x18, 0x00, 0x08, 0x50, 0x00, 0x02, 0xa6, 0x12, 0x00, 0x02,
- 0x96, 0x14, 0x00, 0x03, 0x96, 0x1a, 0x00, 0x04, 0x96, 0x23, 0x10, 0x43, 0x00,
- 0x16, 0x00, 0x03, 0x96, 0x1e, 0x00, 0x11, 0xa6, 0x24, 0x10, 0x43, 0x00, 0xa3,
- 0x18, 0x00, 0x08, 0x2a, 0x10, 0x44, 0x00, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x18, 0x00, 0x51, 0x00, 0x14, 0x00, 0x04,
- 0x96, 0x12, 0x00, 0x02, 0x96, 0x16, 0x00, 0x05, 0x96, 0x23, 0x10, 0x44, 0x00,
- 0x24, 0x10, 0x45, 0x00, 0x12, 0x38, 0x00, 0x00, 0xc2, 0x1b, 0x07, 0x00, 0x1a,
- 0x00, 0x03, 0xa6, 0xff, 0xff, 0x63, 0x30, 0x2a, 0x10, 0x43, 0x00, 0x7c, 0x00,
- 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x30, 0x77, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24,
- 0xa7, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x1b, 0x19, 0x00, 0x08, 0x01,
- 0x00, 0x02, 0x24, 0x16, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0x18, 0x00, 0x51, 0x00, 0x14, 0x00, 0x04, 0x96, 0x12, 0x00, 0x02,
- 0x96, 0x16, 0x00, 0x05, 0x96, 0x23, 0x10, 0x44, 0x00, 0x24, 0x10, 0x45, 0x00,
- 0x12, 0x38, 0x00, 0x00, 0xc2, 0x1b, 0x07, 0x00, 0x1c, 0x00, 0x03, 0xa6, 0xff,
- 0xff, 0x63, 0x30, 0x2a, 0x18, 0x62, 0x00, 0x63, 0x00, 0x60, 0x10, 0x01, 0x00,
- 0x02, 0x24, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x30, 0x5e, 0x00, 0x40, 0x14, 0x01, 0x00, 0x02, 0x24, 0x77, 0x28, 0x00, 0x0c,
- 0x21, 0x20, 0x00, 0x02, 0x1b, 0x19, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0xd4,
- 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90,
- 0x40, 0x00, 0x78, 0x00, 0x06, 0x96, 0x0a, 0x00, 0x04, 0x96, 0x0c, 0x00, 0x02,
- 0x96, 0x0e, 0x00, 0x05, 0x96, 0x23, 0x18, 0xd1, 0x00, 0xff, 0xff, 0x63, 0x30,
- 0x23, 0x10, 0x82, 0x00, 0x24, 0x10, 0xa2, 0x00, 0x2b, 0x18, 0x62, 0x00, 0x2d,
- 0x00, 0x60, 0x10, 0x21, 0x10, 0x91, 0x00, 0x23, 0x10, 0x46, 0x00, 0x24, 0x10,
- 0xa2, 0x00, 0xfd, 0x18, 0x00, 0x08, 0x0c, 0x00, 0x02, 0xa6, 0x21, 0x20, 0x00,
- 0x02, 0xd6, 0x28, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x1b, 0x19, 0x00, 0x08,
- 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0x3b, 0x29, 0x00, 0x0c, 0x21,
- 0x28, 0x20, 0x02, 0x1b, 0x19, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20,
- 0x00, 0x02, 0x72, 0x29, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x1b, 0x19, 0x00,
- 0x08, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0x00, 0x02, 0xc9, 0x29, 0x00, 0x0c,
- 0x21, 0x28, 0x20, 0x02, 0x1b, 0x19, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x21,
- 0x20, 0x00, 0x02, 0xfd, 0x29, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x1b, 0x19,
- 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x21, 0x10, 0x20, 0x02,
- 0x5e, 0x00, 0x02, 0xa2, 0xff, 0x00, 0x42, 0x30, 0x50, 0x00, 0x05, 0x96, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x10, 0xff, 0xd7, 0x02, 0x24, 0xfc, 0x18,
- 0x00, 0x08, 0x00, 0x20, 0xa5, 0x34, 0x24, 0x28, 0xa2, 0x00, 0x50, 0x00, 0x05,
- 0xa6, 0x3b, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x1b, 0x19, 0x00, 0x08,
- 0x01, 0x00, 0x02, 0x24, 0x02, 0x12, 0x11, 0x00, 0x5c, 0x00, 0x11, 0xa2, 0x1a,
- 0x19, 0x00, 0x08, 0x5d, 0x00, 0x02, 0xa2, 0x21, 0x20, 0x00, 0x02, 0x78, 0x00,
- 0x82, 0x94, 0x21, 0x28, 0x20, 0x02, 0x01, 0x00, 0x42, 0x24, 0x9d, 0x29, 0x00,
- 0x0c, 0x78, 0x00, 0x82, 0xa4, 0x1b, 0x19, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24,
- 0x02, 0x12, 0x11, 0x00, 0x5a, 0x00, 0x11, 0xa2, 0x1a, 0x19, 0x00, 0x08, 0x5b,
- 0x00, 0x02, 0xa2, 0x7c, 0x00, 0x02, 0x96, 0x7e, 0x00, 0x03, 0x96, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x10, 0x43, 0x00, 0x03, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x1b, 0x19, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00, 0x7c, 0x00, 0x11, 0xa6,
- 0x01, 0x00, 0x02, 0x24, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xd0, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xa0,
- 0x00, 0x20, 0x00, 0xb4, 0xaf, 0x02, 0x80, 0x14, 0x3c, 0x60, 0xcd, 0x94, 0x26,
- 0x24, 0x00, 0xb5, 0xaf, 0x21, 0xa8, 0x26, 0x02, 0x2b, 0x10, 0x35, 0x02, 0x2c,
- 0x00, 0xbf, 0xaf, 0x28, 0x00, 0xb6, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00,
- 0xb2, 0xaf, 0xff, 0x00, 0x40, 0x10, 0x10, 0x00, 0xb0, 0xaf, 0x02, 0x80, 0x16,
- 0x3c, 0xe8, 0xbc, 0xd6, 0x26, 0x00, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x19, 0x02, 0x00, 0x10, 0x00, 0x62, 0x2c, 0xf2, 0x00, 0x40, 0x10, 0x80,
- 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0xa0, 0x1b,
- 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x22, 0x92, 0x01, 0x00, 0x31, 0x26, 0x0f, 0x00, 0x46, 0x30,
- 0x02, 0x11, 0x02, 0x00, 0x50, 0x19, 0x00, 0x08, 0x01, 0x00, 0x52, 0x24, 0x01,
- 0x00, 0x32, 0x92, 0x00, 0x00, 0x22, 0x92, 0x02, 0x00, 0x31, 0x26, 0x50, 0x19,
- 0x00, 0x08, 0x0f, 0x00, 0x46, 0x30, 0x00, 0x00, 0x22, 0x92, 0x02, 0x00, 0x23,
- 0x92, 0x01, 0x00, 0x24, 0x92, 0x03, 0x00, 0x31, 0x26, 0x0f, 0x00, 0x46, 0x30,
- 0x00, 0x1a, 0x03, 0x00, 0x21, 0x90, 0x64, 0x00, 0x24, 0x00, 0x82, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x2b, 0x10, 0xc2, 0x00, 0x03, 0x00, 0x40, 0x14, 0xc0, 0x11,
- 0x06, 0x00, 0x2b, 0x1a, 0x00, 0x08, 0x21, 0x88, 0x32, 0x02, 0x00, 0x00, 0x83,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x62, 0x00, 0x0c, 0x00, 0x02, 0x96,
- 0x0a, 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x0e,
- 0x00, 0x03, 0x96, 0xff, 0xff, 0x42, 0x24, 0x24, 0x10, 0x43, 0x00, 0x2a, 0x10,
- 0x52, 0x00, 0xcf, 0x00, 0x40, 0x14, 0x0d, 0x00, 0x02, 0x24, 0x78, 0x00, 0x02,
- 0x96, 0x0a, 0x00, 0x07, 0x96, 0x0e, 0x00, 0x03, 0x96, 0x21, 0x10, 0x52, 0x00,
- 0x78, 0x00, 0x02, 0xa6, 0xff, 0xff, 0xe2, 0x24, 0x23, 0x98, 0x62, 0x00, 0x2a,
- 0x10, 0x53, 0x02, 0x09, 0x00, 0x40, 0x14, 0x21, 0x20, 0x20, 0x02, 0x21, 0x30,
- 0x60, 0x02, 0x21, 0x88, 0x26, 0x02, 0x3c, 0x00, 0x05, 0x8e, 0x23, 0x90, 0x46,
- 0x02, 0x78, 0x11, 0x00, 0x0c, 0x21, 0x28, 0xa7, 0x00, 0x0a, 0x00, 0x00, 0xa6,
- 0x21, 0x20, 0x20, 0x02, 0x21, 0x30, 0x40, 0x02, 0x0a, 0x00, 0x02, 0x96, 0x3c,
- 0x00, 0x05, 0x8e, 0x21, 0x88, 0x32, 0x02, 0x78, 0x11, 0x00, 0x0c, 0x21, 0x28,
- 0xa2, 0x00, 0x0a, 0x00, 0x02, 0x96, 0x50, 0x00, 0x03, 0x96, 0x21, 0x10, 0x52,
- 0x00, 0x40, 0x00, 0x63, 0x30, 0xaa, 0x00, 0x60, 0x14, 0x0a, 0x00, 0x02, 0xa6,
- 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x20, 0x40, 0x00, 0x50, 0x00, 0x03, 0x96, 0x00, 0x80, 0x02, 0x3c, 0xdc, 0x35,
- 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x40, 0x00, 0x63, 0x34, 0x3b, 0x12, 0x00,
- 0x0c, 0x50, 0x00, 0x03, 0xa6, 0x2c, 0x1a, 0x00, 0x08, 0x2b, 0x10, 0x35, 0x02,
- 0x00, 0x00, 0x23, 0x92, 0x24, 0x00, 0x82, 0x8e, 0x0f, 0x00, 0x66, 0x30, 0x2b,
- 0x10, 0xc2, 0x00, 0x03, 0x00, 0x40, 0x14, 0xc0, 0x11, 0x06, 0x00, 0x2b, 0x1a,
- 0x00, 0x08, 0x03, 0x00, 0x31, 0x26, 0x00, 0x00, 0x83, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x80, 0x62, 0x00, 0x02, 0x00, 0x22, 0x92, 0x01, 0x00, 0x23, 0x92,
- 0x7e, 0x00, 0x04, 0x96, 0x00, 0x12, 0x02, 0x00, 0x21, 0x90, 0x43, 0x00, 0x7c,
- 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x52, 0x00, 0x23, 0x10,
- 0x44, 0x00, 0xff, 0xff, 0x63, 0x30, 0xff, 0xff, 0x42, 0x30, 0x2b, 0x10, 0x43,
- 0x00, 0x03, 0x00, 0x40, 0x10, 0x21, 0x28, 0x40, 0x02, 0x32, 0x1a, 0x00, 0x08,
- 0x11, 0x00, 0x02, 0x24, 0x7e, 0x00, 0x05, 0xa6, 0x2b, 0x1a, 0x00, 0x08, 0x03,
- 0x00, 0x31, 0x26, 0x00, 0x00, 0x23, 0x92, 0x24, 0x00, 0x82, 0x8e, 0x0f, 0x00,
- 0x66, 0x30, 0x2b, 0x10, 0xc2, 0x00, 0x03, 0x00, 0x40, 0x14, 0x21, 0x28, 0x20,
- 0x02, 0x2b, 0x1a, 0x00, 0x08, 0x04, 0x00, 0x31, 0x26, 0xc0, 0x11, 0x06, 0x00,
- 0x00, 0x00, 0x84, 0x8e, 0x0c, 0x00, 0x83, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0xf8, 0x60, 0x00, 0x21, 0x20, 0x82, 0x00, 0x6f, 0x00, 0x40, 0x14, 0x04, 0x00,
- 0x31, 0x26, 0x32, 0x1a, 0x00, 0x08, 0x0b, 0x00, 0x02, 0x24, 0x00, 0x00, 0x22,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x43, 0x24, 0x10, 0x00, 0x62, 0x2c,
- 0x65, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21,
- 0x08, 0x22, 0x00, 0xe0, 0x1b, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x92, 0x01, 0x00, 0x31,
- 0x26, 0x40, 0x18, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0x80, 0x18, 0x03, 0x00,
- 0x23, 0x18, 0x62, 0x00, 0x80, 0x18, 0x03, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x20,
- 0xa4, 0x42, 0x24, 0x2b, 0x1a, 0x00, 0x08, 0x21, 0xa0, 0x62, 0x00, 0x00, 0x00,
- 0x23, 0x92, 0xf4, 0x00, 0x02, 0x24, 0x59, 0x00, 0x62, 0x14, 0x0c, 0x00, 0x02,
- 0x24, 0x01, 0x00, 0x23, 0x92, 0xb3, 0x00, 0x02, 0x24, 0x55, 0x00, 0x62, 0x14,
- 0x0c, 0x00, 0x02, 0x24, 0x02, 0x00, 0x23, 0x92, 0xc3, 0x00, 0x02, 0x24, 0x51,
- 0x00, 0x62, 0x14, 0x0c, 0x00, 0x02, 0x24, 0x03, 0x00, 0x23, 0x92, 0x95, 0x00,
- 0x02, 0x24, 0x4d, 0x00, 0x62, 0x14, 0x0c, 0x00, 0x02, 0x24, 0x04, 0x00, 0x31,
- 0x26, 0x21, 0x20, 0x20, 0x02, 0xd0, 0x9d, 0x85, 0x27, 0x78, 0x11, 0x00, 0x0c,
- 0x0a, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3c, 0xe8, 0xbc, 0x42, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x81, 0x00, 0x42, 0x2c, 0x04, 0x00, 0x40, 0x14, 0x0a, 0x00,
- 0x31, 0x26, 0x80, 0x00, 0x02, 0x24, 0x02, 0x80, 0x01, 0x3c, 0xe8, 0xbc, 0x22,
- 0xa4, 0xf8, 0xff, 0xc3, 0x92, 0x02, 0x00, 0x02, 0x24, 0x0e, 0x00, 0x62, 0x10,
- 0x03, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0x31,
- 0x00, 0x62, 0x10, 0x2b, 0x10, 0x35, 0x02, 0x32, 0x1a, 0x00, 0x08, 0x0c, 0x00,
- 0x02, 0x24, 0x03, 0x00, 0x02, 0x24, 0x12, 0x00, 0x62, 0x10, 0x04, 0x00, 0x02,
- 0x24, 0x21, 0x00, 0x62, 0x10, 0x0c, 0x00, 0x02, 0x24, 0x32, 0x1a, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x03, 0x3c, 0xff, 0xff, 0x63, 0x34, 0x21,
- 0x20, 0x20, 0x02, 0x00, 0x80, 0x05, 0x3c, 0x02, 0x80, 0x02, 0x3c, 0xe4, 0xbc,
- 0x42, 0x8c, 0x02, 0x80, 0x06, 0x3c, 0xe8, 0xbc, 0xc6, 0x94, 0x24, 0x10, 0x43,
- 0x00, 0x78, 0x11, 0x00, 0x0c, 0x26, 0x28, 0x45, 0x00, 0x1e, 0x1a, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3c, 0xea, 0xbc, 0x84, 0x8c, 0x02,
- 0x80, 0x05, 0x3c, 0xee, 0xbc, 0xa5, 0x8c, 0x02, 0x80, 0x06, 0x3c, 0xf2, 0xbc,
- 0xc6, 0x8c, 0x02, 0x80, 0x02, 0x3c, 0xe4, 0xbc, 0x42, 0x8c, 0x02, 0x80, 0x07,
- 0x3c, 0xf6, 0xbc, 0xe7, 0x8c, 0x09, 0xf8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x80, 0x02, 0x3c, 0xe8, 0xbc, 0x42, 0x94, 0x00, 0x00, 0x00, 0x00, 0x2b,
- 0x1a, 0x00, 0x08, 0x21, 0x88, 0x22, 0x02, 0x23, 0x1a, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x32, 0x1a, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00, 0x2b, 0x1a, 0x00,
- 0x08, 0x01, 0x00, 0x31, 0x26, 0x32, 0x1a, 0x00, 0x08, 0x0a, 0x00, 0x02, 0x24,
- 0x2b, 0x10, 0x35, 0x02, 0x05, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x26,
- 0x10, 0x35, 0x02, 0x2b, 0x10, 0x02, 0x00, 0x23, 0x10, 0x02, 0x00, 0x0e, 0x00,
- 0x42, 0x30, 0x2c, 0x00, 0xbf, 0x8f, 0x28, 0x00, 0xb6, 0x8f, 0x24, 0x00, 0xb5,
- 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30,
- 0x00, 0xbd, 0x27, 0x02, 0x00, 0x02, 0x24, 0x6c, 0x00, 0x80, 0xac, 0x08, 0x00,
- 0xe0, 0x03, 0x2e, 0x00, 0x82, 0xa4, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf,
- 0xaf, 0x65, 0x00, 0x83, 0x90, 0x48, 0x00, 0x85, 0x90, 0x40, 0x10, 0x03, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x23, 0x10, 0x43, 0x00, 0x80,
- 0x10, 0x02, 0x00, 0x02, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x88, 0xcd,
- 0x22, 0x8c, 0x06, 0x00, 0x03, 0x24, 0x06, 0x00, 0x43, 0x14, 0x09, 0x00, 0xa2,
- 0x28, 0x08, 0x00, 0xa2, 0x28, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x56, 0x1a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x3c, 0x1a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0xc8, 0xff, 0xbd, 0x27, 0x2c, 0x00, 0xb5, 0xaf, 0x21, 0xa8, 0x00, 0x00,
- 0x28, 0x00, 0xb4, 0xaf, 0x02, 0x80, 0x14, 0x3c, 0x60, 0xcd, 0x94, 0x26, 0x24,
- 0x00, 0xb3, 0xaf, 0x24, 0x00, 0x93, 0x26, 0x30, 0x00, 0xbf, 0xaf, 0x20, 0x00,
- 0xb2, 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x00, 0x00, 0x62,
- 0x8e, 0x00, 0x00, 0x91, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x10,
- 0x21, 0x90, 0x00, 0x00, 0x7e, 0x00, 0x30, 0x26, 0xd4, 0x9a, 0x84, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x01, 0x00, 0x52, 0x26, 0x21, 0x20,
- 0x40, 0x00, 0x8c, 0xff, 0x00, 0xa6, 0x8e, 0xff, 0x00, 0xa6, 0xfc, 0xff, 0x00,
- 0xa6, 0xfa, 0xff, 0x00, 0xa6, 0xfe, 0xff, 0x00, 0xa6, 0x3b, 0x12, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0xa6, 0x21, 0x20, 0x20, 0x02, 0xf0, 0xff, 0x62, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xf8, 0x40, 0x00, 0x80, 0x00, 0x10, 0x26, 0x00, 0x00,
- 0x62, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x42, 0x02, 0xeb, 0xff, 0x40,
- 0x14, 0x80, 0x00, 0x31, 0x26, 0x01, 0x00, 0xb5, 0x26, 0x2c, 0x00, 0x73, 0x26,
- 0x04, 0x00, 0xa2, 0x2a, 0xe0, 0xff, 0x40, 0x14, 0x2c, 0x00, 0x94, 0x26, 0x30,
- 0x00, 0xbf, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f, 0x24, 0x00,
- 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00, 0xbd, 0x27, 0xc0, 0xff, 0xbd, 0x27,
- 0x00, 0xa0, 0x04, 0x3c, 0x00, 0x10, 0x84, 0x34, 0x00, 0xa0, 0x05, 0x3c, 0x00,
- 0x30, 0xa5, 0x34, 0x3c, 0x00, 0xbf, 0xaf, 0x38, 0x00, 0xbe, 0xaf, 0x34, 0x00,
- 0xb7, 0xaf, 0x30, 0x00, 0xb6, 0xaf, 0x2c, 0x00, 0xb5, 0xaf, 0x28, 0x00, 0xb4,
- 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x1c, 0x00, 0xb1, 0xaf,
- 0xa5, 0x1d, 0x00, 0x0c, 0x18, 0x00, 0xb0, 0xaf, 0x00, 0xa0, 0x15, 0x3c, 0x00,
- 0x10, 0xb5, 0x36, 0x02, 0x80, 0x14, 0x3c, 0x60, 0xcd, 0x94, 0x26, 0x01, 0xa2,
- 0x1e, 0x3c, 0x20, 0x12, 0xde, 0x37, 0x21, 0x98, 0x00, 0x00, 0x01, 0x00, 0x17,
- 0x24, 0x00, 0x80, 0x16, 0x3c, 0x50, 0x7d, 0xd6, 0x26, 0x24, 0x00, 0x92, 0x26,
- 0x80, 0x9b, 0x80, 0xaf, 0x80, 0x9b, 0x82, 0x8f, 0x02, 0x00, 0x63, 0x2a, 0xfc,
- 0xff, 0x42, 0xae, 0x00, 0x00, 0x95, 0xae, 0x04, 0x00, 0x77, 0x10, 0xe0, 0xff,
- 0x5e, 0xae, 0x03, 0x00, 0x02, 0x24, 0x16, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x77, 0x16, 0x10, 0x00, 0x02, 0x24, 0x0f, 0x00, 0x02, 0x24,
- 0x00, 0x00, 0x42, 0xae, 0x00, 0x80, 0x02, 0x3c, 0x74, 0x5f, 0x42, 0x24, 0xe8,
- 0xff, 0x42, 0xae, 0x00, 0x80, 0x02, 0x3c, 0x20, 0x58, 0x42, 0x24, 0xe4, 0xff,
- 0x42, 0xae, 0x00, 0x80, 0x02, 0x3c, 0xf0, 0x68, 0x42, 0x24, 0xf0, 0xff, 0x42,
- 0xae, 0x01, 0x80, 0x02, 0x3c, 0xbc, 0xa8, 0x42, 0x24, 0xf4, 0xff, 0x42, 0xae,
- 0x01, 0x80, 0x02, 0x3c, 0x34, 0xaa, 0x42, 0x24, 0xf8, 0xff, 0x42, 0xae, 0xd1,
- 0x1a, 0x00, 0x08, 0x04, 0x00, 0x43, 0xae, 0x00, 0x00, 0x40, 0xae, 0xe4, 0xff,
- 0x56, 0xae, 0xe8, 0xff, 0x56, 0xae, 0xf0, 0xff, 0x56, 0xae, 0xf4, 0xff, 0x56,
- 0xae, 0x21, 0x88, 0xa0, 0x02, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x0e, 0x00, 0x40, 0x10, 0x21, 0x80, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, 0x21,
- 0x28, 0x80, 0x02, 0x21, 0x30, 0x00, 0x02, 0x24, 0x00, 0x20, 0xae, 0xf8, 0xff,
- 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x40, 0x00, 0x01, 0x00, 0x10,
- 0x26, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x02, 0x02,
- 0xf4, 0xff, 0x40, 0x14, 0x80, 0x00, 0x31, 0x26, 0x02, 0x00, 0x77, 0x16, 0x80,
- 0xff, 0x22, 0x26, 0x5c, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x44, 0x8e, 0x2c, 0x00,
- 0x52, 0x26, 0x01, 0x00, 0x73, 0x26, 0x80, 0x9b, 0x83, 0x8f, 0xc0, 0x11, 0x04,
- 0x00, 0x21, 0xa8, 0xa2, 0x02, 0x21, 0x28, 0x64, 0x00, 0x04, 0x00, 0x62, 0x2a,
- 0x80, 0x9b, 0x85, 0xaf, 0xbe, 0xff, 0x40, 0x14, 0x2c, 0x00, 0x94, 0x26, 0x00,
- 0xa0, 0x03, 0x3c, 0x00, 0x01, 0x63, 0x34, 0xf9, 0xff, 0xa2, 0x24, 0x80, 0x9b,
- 0x82, 0xaf, 0x18, 0x00, 0xa2, 0x24, 0x42, 0x11, 0x02, 0x00, 0x00, 0x80, 0x05,
- 0x3c, 0x20, 0x9b, 0x82, 0xaf, 0x14, 0x00, 0x62, 0x8c, 0x60, 0x9e, 0x84, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0xaf, 0x1d, 0x00, 0x0c, 0x23, 0x28, 0x45, 0x00, 0x3c,
- 0x00, 0xbf, 0x8f, 0x38, 0x00, 0xbe, 0x8f, 0x34, 0x00, 0xb7, 0x8f, 0x30, 0x00,
- 0xb6, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f, 0x24, 0x00, 0xb3,
- 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x38, 0x9f, 0x82, 0x8f, 0x01, 0x00, 0x03, 0x24, 0xd8, 0x9a,
- 0x83, 0xaf, 0x01, 0x00, 0x43, 0x34, 0xd4, 0x9a, 0x83, 0xaf, 0x01, 0x04, 0x43,
- 0x34, 0xcc, 0x9a, 0x83, 0xaf, 0xf0, 0x9e, 0x83, 0x8f, 0x01, 0x84, 0x42, 0x34,
- 0xc0, 0x9a, 0x82, 0xaf, 0x25, 0x10, 0x43, 0x00, 0x00, 0x0b, 0x43, 0x34, 0xf4,
- 0x9e, 0x82, 0xaf, 0xc4, 0x9a, 0x82, 0xaf, 0xc8, 0x9d, 0x83, 0xaf, 0x3c, 0x9f,
- 0x82, 0xaf, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff, 0xbd,
- 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x60, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c,
- 0x64, 0x00, 0x05, 0x24, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x01, 0xa2,
- 0x02, 0x3c, 0x10, 0x00, 0xbf, 0xaf, 0x00, 0x00, 0x40, 0xa4, 0x50, 0x12, 0x00,
- 0x0c, 0x00, 0x03, 0x04, 0x24, 0xff, 0x03, 0x04, 0x3c, 0xff, 0xff, 0x84, 0x34,
- 0x01, 0xa2, 0x05, 0x3c, 0x0c, 0x00, 0xa5, 0x34, 0x63, 0x00, 0x06, 0x24, 0x00,
- 0x80, 0x02, 0x3c, 0x84, 0x34, 0x42, 0x24, 0x82, 0x10, 0x02, 0x00, 0x24, 0x10,
- 0x44, 0x00, 0x00, 0x08, 0x03, 0x3c, 0x25, 0x10, 0x43, 0x00, 0x00, 0x80, 0x01,
- 0x3c, 0x00, 0x00, 0x22, 0xac, 0x00, 0x80, 0x02, 0x3c, 0x60, 0x32, 0x42, 0x24,
- 0x82, 0x10, 0x02, 0x00, 0x24, 0x10, 0x44, 0x00, 0x25, 0x10, 0x43, 0x00, 0x00,
- 0x80, 0x01, 0x3c, 0x80, 0x00, 0x22, 0xac, 0x18, 0x00, 0x02, 0x24, 0xf8, 0x9e,
- 0x82, 0xaf, 0x18, 0x00, 0x02, 0x24, 0x00, 0x80, 0x01, 0x3c, 0x04, 0x00, 0x20,
- 0xac, 0x00, 0x80, 0x01, 0x3c, 0x84, 0x00, 0x20, 0xac, 0x00, 0x00, 0xa2, 0xa4,
- 0xff, 0xff, 0xc6, 0x24, 0xff, 0xff, 0xc1, 0x04, 0xff, 0xff, 0xc6, 0x24, 0x01,
- 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x00, 0x80, 0x04, 0x3c, 0x00, 0x30,
- 0x84, 0x24, 0x19, 0x00, 0x02, 0x24, 0xf8, 0x9e, 0x82, 0xaf, 0x19, 0x00, 0x02,
- 0x24, 0x02, 0x80, 0x05, 0x3c, 0x90, 0xb8, 0xa5, 0x24, 0x70, 0x12, 0x00, 0x0c,
- 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0x03, 0x24, 0x04, 0x00, 0x43, 0x10, 0x01,
- 0xa2, 0x02, 0x3c, 0x5d, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa2,
- 0x02, 0x3c, 0x00, 0x00, 0x40, 0xa4, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd,
- 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27,
- 0x10, 0x00, 0xbf, 0xaf, 0xbc, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xa2, 0x02, 0x3c, 0x0c, 0x1b, 0x00, 0x0c, 0x00, 0x00, 0x40, 0xa4, 0x5c, 0x27,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x20, 0x26, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x7c, 0x1d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xec, 0x15, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x81, 0x1f, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x92,
- 0x1a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x01,
- 0x63, 0x34, 0x54, 0x00, 0x02, 0x24, 0x3c, 0x00, 0x62, 0xa0, 0xff, 0x00, 0x02,
- 0x24, 0x3d, 0x00, 0x62, 0xa0, 0x3e, 0x00, 0x62, 0xa0, 0x9c, 0x2f, 0x00, 0x0c,
- 0x3f, 0x00, 0x62, 0xa0, 0x20, 0x9f, 0x84, 0x27, 0x01, 0x00, 0x05, 0x24, 0x01,
- 0x80, 0x06, 0x3c, 0x88, 0xbd, 0xc6, 0x24, 0x35, 0x26, 0x00, 0x0c, 0x21, 0x38,
- 0x00, 0x00, 0x20, 0x9f, 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x9f, 0x84, 0x27, 0x03, 0x00, 0x05, 0x24, 0x01, 0x80, 0x06, 0x3c,
- 0xfc, 0xaf, 0xc6, 0x24, 0x35, 0x26, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x00, 0x00,
- 0x9f, 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1b,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x9f, 0x84, 0x27, 0x21, 0x28, 0x00,
- 0x00, 0x00, 0x80, 0x06, 0x3c, 0xfc, 0x7a, 0xc6, 0x24, 0x35, 0x26, 0x00, 0x0c,
- 0x21, 0x38, 0x00, 0x00, 0x40, 0x9f, 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x84, 0x9f, 0x80, 0xaf, 0xd4, 0x26, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xe0,
- 0x03, 0x18, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x58, 0x80, 0x00, 0x02, 0x80, 0x07, 0x3c, 0xf0, 0xcb, 0xe7, 0x24, 0x40,
- 0x9d, 0x8a, 0x27, 0x21, 0x10, 0xab, 0x00, 0xff, 0xff, 0x43, 0x90, 0xff, 0x00,
- 0x02, 0x24, 0x03, 0x00, 0x62, 0x14, 0xfd, 0xff, 0xa6, 0x24, 0xff, 0xff, 0xa5,
- 0x24, 0xfd, 0xff, 0xa6, 0x24, 0x23, 0x10, 0x06, 0x00, 0x74, 0x9f, 0x86, 0xaf,
- 0x78, 0x9f, 0x82, 0xaf, 0x68, 0x9f, 0x86, 0xaf, 0x00, 0x00, 0x62, 0x91, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x11, 0x02, 0x00, 0xff, 0xff, 0x43, 0x24, 0x2a, 0x10,
- 0x66, 0x00, 0x02, 0x00, 0x40, 0x14, 0x48, 0x00, 0x43, 0xad, 0xfc, 0xff, 0xa3,
- 0x24, 0x21, 0x28, 0x6b, 0x00, 0x02, 0x00, 0xa3, 0x90, 0x60, 0x99, 0x89, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x69, 0x00, 0x02, 0x00, 0x40, 0x10, 0x0a,
- 0x00, 0x04, 0x24, 0x21, 0x20, 0x60, 0x00, 0x4c, 0x00, 0xe4, 0xac, 0x03, 0x00,
- 0xa3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x69, 0x00, 0x02, 0x00, 0x40,
- 0x10, 0x0a, 0x00, 0x04, 0x24, 0x21, 0x20, 0x60, 0x00, 0x40, 0x10, 0x04, 0x00,
- 0x21, 0x10, 0x44, 0x00, 0x80, 0x10, 0x02, 0x00, 0x48, 0x00, 0xe4, 0xac, 0x02,
- 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x6c, 0x9b, 0x22, 0x8c, 0x21, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x43, 0x8c, 0x10, 0x27, 0x02, 0x24, 0x80, 0x00, 0xe2,
- 0xac, 0x70, 0x00, 0xe0, 0xac, 0xc2, 0x18, 0x03, 0x00, 0x90, 0x00, 0xe3, 0xac,
- 0x34, 0x00, 0xc0, 0x04, 0x94, 0x00, 0xe3, 0xac, 0x21, 0x68, 0x20, 0x01, 0x02,
- 0x80, 0x0e, 0x3c, 0x68, 0x9b, 0xce, 0x25, 0x1e, 0x00, 0x09, 0x3c, 0x80, 0x84,
- 0x29, 0x35, 0x21, 0x60, 0xc0, 0x00, 0x21, 0x10, 0x0b, 0x01, 0x02, 0x00, 0x43,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x6d, 0x00, 0x03, 0x00, 0x40, 0x14,
- 0x40, 0x10, 0x03, 0x00, 0x0a, 0x00, 0x03, 0x24, 0x40, 0x10, 0x03, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x4e, 0x00, 0x04, 0x00,
- 0x46, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0xc2, 0x28, 0x02, 0x00, 0x1a, 0x00, 0x25, 0x01, 0x02, 0x00, 0xa0, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04,
- 0x00, 0xa1, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x21, 0x15, 0x00, 0x00,
- 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0x20, 0x00, 0x00, 0x94, 0x00, 0xe3,
- 0x8c, 0x70, 0x00, 0xe2, 0x8c, 0x2a, 0x18, 0xa3, 0x00, 0x21, 0x10, 0x44, 0x00,
- 0x02, 0x00, 0x60, 0x10, 0x70, 0x00, 0xe2, 0xac, 0x94, 0x00, 0xe5, 0xac, 0x04,
- 0x00, 0xc3, 0x94, 0x80, 0x00, 0xe2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10,
- 0x62, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xe3,
- 0xac, 0x01, 0x00, 0x08, 0x25, 0x2a, 0x10, 0x88, 0x01, 0xd5, 0xff, 0x40, 0x10,
- 0x21, 0x10, 0x0b, 0x01, 0x80, 0x00, 0xe3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x82,
- 0x00, 0x62, 0x28, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00,
- 0x03, 0x24, 0x70, 0x00, 0xe2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x62,
- 0x00, 0x62, 0x10, 0x04, 0x3c, 0xd3, 0x4d, 0x84, 0x34, 0x0c, 0x00, 0xea, 0xac,
- 0x10, 0x00, 0xea, 0xac, 0x14, 0x00, 0xea, 0xac, 0x01, 0x00, 0x03, 0x24, 0xf0,
- 0x00, 0x02, 0x24, 0x64, 0x9f, 0x83, 0xaf, 0x28, 0x00, 0xe3, 0xac, 0x2c, 0x00,
- 0xe2, 0xac, 0x68, 0x00, 0xe3, 0xac, 0x12, 0x28, 0x00, 0x00, 0x6c, 0x00, 0xe3,
- 0xac, 0x6c, 0x9f, 0x83, 0xaf, 0x19, 0x00, 0xa4, 0x00, 0x1c, 0x00, 0x43, 0xad,
- 0x74, 0x9f, 0x83, 0x8f, 0x09, 0x00, 0x02, 0x24, 0x20, 0x00, 0x42, 0xad, 0x10,
- 0x00, 0x42, 0x25, 0x04, 0x00, 0x47, 0xad, 0x00, 0x00, 0x4a, 0xad, 0x14, 0x00,
- 0x42, 0xad, 0x70, 0x00, 0xe4, 0x8c, 0x01, 0x00, 0x63, 0x24, 0x64, 0x00, 0x84,
- 0x24, 0x10, 0x78, 0x00, 0x00, 0x82, 0x11, 0x0f, 0x00, 0x74, 0x00, 0xe2, 0xac,
- 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x40, 0x10, 0x02, 0x00, 0x74, 0x00, 0xe3, 0x8c, 0x21, 0x20,
- 0x82, 0x00, 0x70, 0x00, 0xe4, 0xac, 0x64, 0x00, 0x63, 0x24, 0x21, 0x18, 0x62,
- 0x00, 0x08, 0x00, 0xe0, 0x03, 0x74, 0x00, 0xe3, 0xac, 0xe0, 0xff, 0xbd, 0x27,
- 0x10, 0x00, 0xb0, 0xaf, 0x60, 0x9f, 0x90, 0x8f, 0x14, 0x00, 0xb1, 0xaf, 0x02,
- 0x80, 0x11, 0x3c, 0xf0, 0xcb, 0x31, 0x26, 0x18, 0x00, 0xbf, 0xaf, 0x10, 0x00,
- 0x03, 0x8e, 0x03, 0x00, 0x02, 0x24, 0x04, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0xc4, 0x00, 0x05, 0x24,
- 0x40, 0x00, 0x22, 0x8e, 0x1c, 0x00, 0x23, 0x8e, 0x80, 0x11, 0x02, 0x00, 0x21,
- 0x18, 0x62, 0x00, 0x04, 0x00, 0x02, 0x24, 0x18, 0x00, 0x62, 0xac, 0x20, 0x00,
- 0x70, 0xac, 0x08, 0x00, 0x05, 0x8e, 0x14, 0x00, 0x06, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x54, 0x43, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x00, 0x00, 0x02, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x9f, 0x82, 0xaf, 0x03, 0x00, 0x40, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x60, 0x9f, 0x82, 0x27, 0x7c, 0x9f, 0x82, 0xaf, 0x18, 0x00,
- 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf,
- 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0xb1, 0xaf, 0x40, 0x9d, 0x91, 0x27, 0x18,
- 0x00, 0xbf, 0xaf, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
- 0x42, 0x30, 0x3d, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x42, 0x30, 0x38, 0x00, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x9f, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x30, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x03,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0x28, 0x1d, 0x00, 0x40, 0x14,
- 0x05, 0x00, 0x62, 0x28, 0x87, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88,
- 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00, 0x23, 0x10,
- 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x90, 0x00, 0x03,
- 0x8e, 0xc0, 0x10, 0x02, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04,
- 0x00, 0x61, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0xd0, 0x9a, 0x83,
- 0x8f, 0x78, 0x00, 0x04, 0x8e, 0x23, 0x10, 0x43, 0x00, 0x21, 0x10, 0x44, 0x00,
- 0x05, 0x00, 0x42, 0x28, 0x6d, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc1,
- 0x1f, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x70, 0x9f, 0x82, 0x8f, 0x74, 0x9f,
- 0x83, 0x8f, 0x78, 0x9f, 0x84, 0x8f, 0x01, 0x00, 0x42, 0x24, 0x23, 0x10, 0x43,
- 0x00, 0x70, 0x9f, 0x82, 0xaf, 0x2a, 0x10, 0x44, 0x00, 0xc3, 0xff, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x70, 0x9f, 0x84, 0xaf, 0x6b, 0x1c, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x60, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x62, 0x28, 0x1d, 0x00, 0x40, 0x14, 0x05, 0x00, 0x62, 0x28,
- 0x54, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x03, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00, 0x23, 0x10, 0x43, 0x00, 0x80, 0x10,
- 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x90, 0x00, 0x03, 0x8e, 0xc0, 0x10, 0x02,
- 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0x61, 0x14, 0x00,
- 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0xd0, 0x9a, 0x83, 0x8f, 0x78, 0x00, 0x04,
- 0x8e, 0x23, 0x10, 0x43, 0x00, 0x21, 0x10, 0x44, 0x00, 0x05, 0x00, 0x42, 0x28,
- 0x3a, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1c, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x70, 0x9f, 0x82, 0x8f, 0x68, 0x9f, 0x83, 0x8f, 0x01, 0x00,
- 0x42, 0x24, 0x70, 0x9f, 0x82, 0xaf, 0x2a, 0x10, 0x62, 0x00, 0x92, 0xff, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x9f, 0x83, 0xaf, 0x6b, 0x1c, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x9c, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x26,
- 0x00, 0x40, 0x10, 0xfe, 0xff, 0x03, 0x24, 0x8c, 0x00, 0x03, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x62, 0x28, 0x1d, 0x00, 0x40, 0x14, 0x05, 0x00, 0x62,
- 0x28, 0x23, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x03, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03, 0x00, 0x23, 0x10, 0x43, 0x00, 0x80,
- 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x90, 0x00, 0x03, 0x8e, 0xc0, 0x10,
- 0x02, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0x61, 0x14,
- 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0xd0, 0x9a, 0x83, 0x8f, 0x78, 0x00,
- 0x04, 0x8e, 0x23, 0x10, 0x43, 0x00, 0x21, 0x10, 0x44, 0x00, 0x05, 0x00, 0x42,
- 0x28, 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x20, 0x00, 0x0c,
- 0x21, 0x20, 0x00, 0x02, 0xe1, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2c,
- 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, 0x2c, 0x00,
- 0x02, 0xae, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x00, 0xa0, 0x06, 0x3c,
- 0x68, 0x0d, 0xc6, 0x34, 0x03, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa2, 0xac, 0x00,
- 0x00, 0xa0, 0xac, 0x00, 0x00, 0xc2, 0x8c, 0x7c, 0x9f, 0x83, 0x8f, 0x01, 0x00,
- 0x42, 0x24, 0x00, 0x00, 0xc2, 0xac, 0x00, 0x00, 0x65, 0xac, 0x2c, 0x00, 0x82,
- 0x8c, 0x7c, 0x9f, 0x85, 0xaf, 0x01, 0x00, 0x42, 0x34, 0x08, 0x00, 0xe0, 0x03,
- 0x2c, 0x00, 0x82, 0xac, 0xe0, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21,
- 0x88, 0xa0, 0x00, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10, 0x00,
- 0xb0, 0xaf, 0x08, 0x00, 0x30, 0x8e, 0x21, 0x90, 0x80, 0x00, 0x00, 0x00, 0x06,
- 0x92, 0x14, 0x00, 0x24, 0x8e, 0x0f, 0x00, 0xc5, 0x30, 0x04, 0x00, 0xa2, 0x28,
- 0x07, 0x00, 0x40, 0x10, 0x02, 0x00, 0xa2, 0x28, 0x25, 0x00, 0x40, 0x10, 0x01,
- 0x00, 0x02, 0x24, 0x08, 0x00, 0xa2, 0x10, 0x21, 0x10, 0x90, 0x00, 0x73, 0x1d,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x24, 0x27, 0x00, 0xa2,
- 0x10, 0xf4, 0xff, 0x82, 0x24, 0x73, 0x1d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x43, 0x90, 0xff, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x14, 0xfc,
- 0xff, 0x82, 0x24, 0xff, 0xff, 0x84, 0x24, 0xfc, 0xff, 0x82, 0x24, 0x09, 0x00,
- 0x42, 0x2c, 0x2d, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x00, 0x01, 0x42,
- 0x34, 0x5c, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0xc2, 0x00,
- 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x45, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0x5d, 0x12,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x3c, 0x00, 0x01, 0x42,
- 0x34, 0x5c, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x64, 0x1d, 0x00, 0x08,
- 0x00, 0x00, 0x02, 0xa2, 0x04, 0x00, 0x02, 0x24, 0x0e, 0x00, 0x82, 0x14, 0x03,
- 0x00, 0x02, 0x24, 0x03, 0x00, 0x03, 0x92, 0xff, 0x00, 0x02, 0x24, 0x0a, 0x00,
- 0x62, 0x14, 0x03, 0x00, 0x02, 0x24, 0x62, 0x1d, 0x00, 0x08, 0x03, 0x00, 0x04,
- 0x24, 0x01, 0x08, 0x42, 0x2c, 0x10, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c,
- 0x0a, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x42, 0x24, 0xff,
- 0xff, 0x42, 0x30, 0x0a, 0x00, 0x82, 0x14, 0x00, 0xa0, 0x03, 0x3c, 0x21, 0x20,
- 0x40, 0x02, 0x2c, 0x00, 0x82, 0x8c, 0x21, 0x28, 0x20, 0x02, 0xf0, 0x00, 0x42,
- 0x34, 0x0f, 0x1d, 0x00, 0x0c, 0x2c, 0x00, 0x82, 0xac, 0x76, 0x1d, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x03, 0x3c, 0xbc, 0x0d, 0x63, 0x34, 0x00,
- 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x76, 0x1d,
- 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0x70, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00,
- 0x0c, 0x87, 0x01, 0x05, 0x24, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x00, 0xa0, 0x02, 0x3c, 0x00, 0x01,
- 0x42, 0x34, 0x00, 0xa0, 0x04, 0x3c, 0x10, 0x00, 0xbf, 0xaf, 0x58, 0x00, 0x45,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1b, 0x00, 0x0c, 0x5c, 0x01, 0x84, 0x34,
- 0x96, 0x25, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x9f, 0x82, 0x27, 0x7c,
- 0x9f, 0x82, 0xaf, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00,
- 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x99, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11, 0x02, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x11,
- 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x1f, 0x28, 0x42, 0x24, 0x02, 0x1c, 0x02, 0x00, 0x18, 0x00, 0x83, 0x00,
- 0xb0, 0x99, 0x82, 0xaf, 0x12, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x02, 0x14, 0x05, 0x00, 0x2b, 0x10,
- 0x85, 0x00, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0xac, 0x04, 0x00, 0x84, 0x24, 0x2b, 0x10, 0x85, 0x00, 0xfc, 0xff, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0xff, 0xbd, 0x27, 0xff, 0x1f, 0x03, 0x3c, 0x00, 0xff, 0x63, 0x34, 0xff, 0x00,
- 0x84, 0x24, 0x24, 0x20, 0x83, 0x00, 0x00, 0xa0, 0x02, 0x3c, 0x25, 0x20, 0x82,
- 0x00, 0x24, 0x28, 0xa3, 0x00, 0x58, 0x00, 0xbe, 0xaf, 0x25, 0xf0, 0xa2, 0x00,
- 0x10, 0x00, 0xa4, 0xaf, 0x10, 0x00, 0xa4, 0x8f, 0x21, 0x28, 0xc0, 0x03, 0x5c,
- 0x00, 0xbf, 0xaf, 0x54, 0x00, 0xb7, 0xaf, 0x50, 0x00, 0xb6, 0xaf, 0x4c, 0x00,
- 0xb5, 0xaf, 0x48, 0x00, 0xb4, 0xaf, 0x44, 0x00, 0xb3, 0xaf, 0x40, 0x00, 0xb2,
- 0xaf, 0x3c, 0x00, 0xb1, 0xaf, 0xa5, 0x1d, 0x00, 0x0c, 0x38, 0x00, 0xb0, 0xaf,
- 0x21, 0x38, 0x00, 0x00, 0x02, 0x80, 0x12, 0x3c, 0x60, 0xcd, 0x52, 0x26, 0xb0,
- 0x00, 0x42, 0x26, 0x14, 0x00, 0x42, 0x12, 0x18, 0x00, 0xa0, 0xaf, 0x04, 0x00,
- 0x05, 0x24, 0x21, 0x20, 0x40, 0x00, 0x24, 0x00, 0x43, 0x26, 0x04, 0x00, 0x62,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x45, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x38, 0xe2, 0x00, 0xdc,
- 0x1d, 0x00, 0x08, 0x01, 0x00, 0xe7, 0x24, 0x18, 0x00, 0xa9, 0x8f, 0x08, 0x00,
- 0xe7, 0x24, 0x01, 0x00, 0x29, 0x25, 0x18, 0x00, 0xa9, 0xaf, 0x2c, 0x00, 0x52,
- 0x26, 0xf1, 0xff, 0x44, 0x16, 0x2c, 0x00, 0x63, 0x24, 0x10, 0x00, 0x15, 0x24,
- 0x10, 0x00, 0xa9, 0x8f, 0x02, 0x80, 0x08, 0x3c, 0x10, 0xce, 0x08, 0x25, 0x23,
- 0x48, 0xc9, 0x03, 0x20, 0x00, 0xa9, 0xaf, 0x21, 0x98, 0xc0, 0x03, 0x00, 0x10,
- 0xa2, 0x2a, 0x02, 0x00, 0x40, 0x14, 0x00, 0x10, 0x11, 0x24, 0x21, 0x88, 0xa0,
- 0x02, 0x40, 0x10, 0x07, 0x00, 0x18, 0x00, 0xa2, 0x02, 0x12, 0x30, 0x00, 0x00,
- 0x18, 0x00, 0xa9, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x29, 0x02, 0x20,
- 0x00, 0xa9, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x26, 0x01, 0x12, 0x18,
- 0x00, 0x00, 0x23, 0xa0, 0x43, 0x00, 0x2a, 0x10, 0x95, 0x02, 0x08, 0x00, 0x40,
- 0x10, 0x11, 0x00, 0xa2, 0x2a, 0xb6, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0xc4, 0x00, 0x05, 0x24, 0xaf,
- 0x1e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x3c, 0x60, 0xcd,
- 0x52, 0x26, 0x36, 0x00, 0x12, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36,
- 0x26, 0x21, 0xb8, 0xd1, 0x02, 0xb0, 0x00, 0x46, 0x26, 0x28, 0x00, 0x42, 0x8e,
- 0x04, 0x00, 0x09, 0x24, 0x2a, 0x00, 0x49, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x50, 0x24, 0x2a, 0x10,
- 0x91, 0x02, 0x03, 0x00, 0x40, 0x14, 0x0e, 0x00, 0x16, 0xa6, 0x0e, 0x00, 0x17,
- 0xa6, 0x23, 0xa0, 0x91, 0x02, 0x0e, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x23, 0x98, 0x62, 0x02, 0x02, 0x11, 0x13, 0x00, 0x08,
- 0x00, 0x02, 0xa6, 0x3c, 0x00, 0x13, 0xae, 0x10, 0x00, 0xa9, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x10, 0x69, 0x02, 0x07, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x0e, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x62, 0x02,
- 0x2b, 0x10, 0x5e, 0x00, 0x0a, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x89, 0x84, 0x27, 0xe0, 0x00, 0x05, 0x24, 0x2c, 0x00, 0xa6, 0xaf, 0x30, 0x00,
- 0xa7, 0xaf, 0x20, 0x0c, 0x00, 0x0c, 0x34, 0x00, 0xa8, 0xaf, 0x34, 0x00, 0xa8,
- 0x8f, 0x30, 0x00, 0xa7, 0x8f, 0x2c, 0x00, 0xa6, 0x8f, 0x0e, 0x00, 0x02, 0x96,
- 0x08, 0x00, 0x03, 0x96, 0x3c, 0x00, 0x04, 0x8e, 0x16, 0x00, 0x02, 0xa6, 0x10,
- 0x00, 0x03, 0xa6, 0x38, 0x00, 0x04, 0xae, 0x2c, 0x00, 0x52, 0x26, 0xd1, 0xff,
- 0x46, 0x16, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x3c, 0x60, 0xcd, 0x52,
- 0x26, 0x38, 0x00, 0x12, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x26,
- 0x21, 0x30, 0xf5, 0x02, 0x24, 0x00, 0x56, 0x26, 0x04, 0x00, 0xc2, 0x8e, 0x04,
- 0x00, 0x09, 0x24, 0x05, 0x00, 0x49, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xd1, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x00, 0x08, 0x01, 0x00, 0x31,
- 0x26, 0x08, 0x00, 0x11, 0x24, 0x00, 0x00, 0x50, 0x8e, 0x26, 0x00, 0x20, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x10, 0x26, 0x2a, 0x10, 0x95, 0x02, 0x03,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x17, 0xa6, 0x00, 0x00, 0x06, 0xa6, 0x23, 0xa0,
- 0x95, 0x02, 0x00, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0x23, 0x98, 0x62, 0x02, 0x22, 0x00, 0x13, 0xae, 0x22, 0x00, 0x03, 0x8e,
- 0x02, 0x11, 0x13, 0x00, 0xfa, 0xff, 0x02, 0xa6, 0x10, 0x00, 0xa9, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x2b, 0x10, 0x69, 0x00, 0x07, 0x00, 0x40, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x62,
- 0x00, 0x2b, 0x10, 0x5e, 0x00, 0x0a, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x89, 0x84, 0x27, 0x16, 0x01, 0x05, 0x24, 0x2c, 0x00, 0xa6, 0xaf, 0x30,
- 0x00, 0xa7, 0xaf, 0x20, 0x0c, 0x00, 0x0c, 0x34, 0x00, 0xa8, 0xaf, 0x34, 0x00,
- 0xa8, 0x8f, 0x30, 0x00, 0xa7, 0x8f, 0x2c, 0x00, 0xa6, 0x8f, 0xff, 0xff, 0x31,
- 0x26, 0xdd, 0xff, 0x20, 0x16, 0x80, 0x00, 0x10, 0x26, 0x2c, 0x00, 0x52, 0x26,
- 0xcd, 0xff, 0x48, 0x16, 0x2c, 0x00, 0xd6, 0x26, 0x02, 0x80, 0x12, 0x3c, 0x60,
- 0xcd, 0x52, 0x26, 0x37, 0x00, 0x12, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xb7, 0x26, 0x21, 0x18, 0xf5, 0x02, 0x24, 0x00, 0x56, 0x26, 0x04, 0x00, 0xc2,
- 0x8e, 0x04, 0x00, 0x09, 0x24, 0x05, 0x00, 0x49, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xd1, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x81, 0x1e, 0x00, 0x08, 0x01,
- 0x00, 0x31, 0x26, 0x08, 0x00, 0x11, 0x24, 0x00, 0x00, 0x50, 0x8e, 0x25, 0x00,
- 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x10, 0x26, 0x2a, 0x10, 0x95,
- 0x02, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x17, 0xa6, 0x00, 0x00, 0x03, 0xa6,
- 0x23, 0xa0, 0x95, 0x02, 0x00, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0x23, 0x98, 0x62, 0x02, 0x02, 0x11, 0x13, 0x00, 0xfa, 0xff,
- 0x02, 0xa6, 0x2e, 0x00, 0x13, 0xae, 0x10, 0x00, 0xa9, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x2b, 0x10, 0x69, 0x02, 0x07, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x62, 0x02, 0x2b,
- 0x10, 0x5e, 0x00, 0x0a, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x80, 0x89,
- 0x84, 0x27, 0x41, 0x01, 0x05, 0x24, 0x28, 0x00, 0xa3, 0xaf, 0x30, 0x00, 0xa7,
- 0xaf, 0x20, 0x0c, 0x00, 0x0c, 0x34, 0x00, 0xa8, 0xaf, 0x34, 0x00, 0xa8, 0x8f,
- 0x30, 0x00, 0xa7, 0x8f, 0x28, 0x00, 0xa3, 0x8f, 0xff, 0xff, 0x31, 0x26, 0xde,
- 0xff, 0x20, 0x16, 0x80, 0x00, 0x10, 0x26, 0x2c, 0x00, 0x52, 0x26, 0xce, 0xff,
- 0x48, 0x16, 0x2c, 0x00, 0xd6, 0x26, 0x40, 0xa8, 0x15, 0x00, 0x01, 0x40, 0xa2,
- 0x2a, 0x37, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xa9, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0xc9, 0x03, 0x82, 0x12, 0x02, 0x00, 0x5c,
- 0x00, 0xbf, 0x8f, 0x58, 0x00, 0xbe, 0x8f, 0x54, 0x00, 0xb7, 0x8f, 0x50, 0x00,
- 0xb6, 0x8f, 0x4c, 0x00, 0xb5, 0x8f, 0x48, 0x00, 0xb4, 0x8f, 0x44, 0x00, 0xb3,
- 0x8f, 0x40, 0x00, 0xb2, 0x8f, 0x3c, 0x00, 0xb1, 0x8f, 0x38, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x60, 0x00, 0xbd, 0x27, 0xc8, 0x9d, 0x84, 0x8f, 0xe0,
- 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x3b, 0x12, 0x00, 0x0c, 0x18, 0x00,
- 0xb0, 0xaf, 0xa8, 0x26, 0x00, 0x0c, 0x32, 0x00, 0x04, 0x24, 0xd0, 0x9a, 0x82,
- 0x8f, 0x8c, 0x9f, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0x60, 0xea, 0x03, 0x34, 0x2a, 0x18, 0x62, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x5d, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x84, 0x9f,
- 0x84, 0x8f, 0x14, 0x9c, 0x83, 0x8f, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x40,
- 0xa4, 0x2b, 0x18, 0x64, 0x00, 0x10, 0x9c, 0x84, 0xaf, 0x02, 0x00, 0x60, 0x10,
- 0x82, 0x10, 0x04, 0x00, 0x14, 0x9c, 0x84, 0xaf, 0xb4, 0x99, 0x83, 0x8f, 0x23,
- 0x10, 0x82, 0x00, 0x84, 0x9f, 0x82, 0xaf, 0x07, 0x00, 0x62, 0x24, 0xb4, 0x99,
- 0x82, 0xaf, 0x14, 0x00, 0x42, 0x28, 0x02, 0x00, 0x40, 0x14, 0xf3, 0xff, 0x62,
- 0x24, 0xb4, 0x99, 0x82, 0xaf, 0x64, 0x9f, 0x98, 0x8f, 0x02, 0x80, 0x04, 0x3c,
- 0xf0, 0xcb, 0x84, 0x24, 0x30, 0x00, 0x00, 0x1b, 0x21, 0x58, 0x00, 0x00, 0xb4,
- 0x99, 0x8a, 0x8f, 0xcc, 0xcc, 0x0f, 0x3c, 0xcd, 0xcc, 0xef, 0x35, 0xb8, 0x00,
- 0x89, 0x24, 0xf8, 0xff, 0x26, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xca,
- 0x00, 0x19, 0x00, 0x4f, 0x00, 0xf0, 0xff, 0x27, 0x8d, 0x10, 0x60, 0x00, 0x00,
- 0x21, 0x10, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x4f, 0x00, 0x08,
- 0x00, 0x28, 0x8d, 0x10, 0x68, 0x00, 0x00, 0x21, 0x10, 0x0a, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x19, 0x00, 0x4f, 0x00, 0xf0, 0xff, 0x23, 0x8d, 0x00, 0x00, 0x25,
- 0x8d, 0x00, 0x00, 0x24, 0x8d, 0x01, 0x00, 0x6b, 0x25, 0xf4, 0xff, 0x23, 0xad,
- 0x08, 0x00, 0x23, 0x8d, 0xf8, 0xff, 0x22, 0x8d, 0x10, 0x70, 0x00, 0x00, 0xfc,
- 0xff, 0x22, 0xad, 0x21, 0x10, 0xaa, 0x00, 0x19, 0x00, 0x4f, 0x00, 0x04, 0x00,
- 0x24, 0xad, 0x0c, 0x00, 0x23, 0xad, 0x02, 0x11, 0x0c, 0x00, 0x23, 0x30, 0xc2,
- 0x00, 0x02, 0x11, 0x0d, 0x00, 0x23, 0x38, 0xe2, 0x00, 0x02, 0x11, 0x0e, 0x00,
- 0x23, 0x40, 0x02, 0x01, 0xf8, 0xff, 0x26, 0xad, 0xf0, 0xff, 0x27, 0xad, 0x08,
- 0x00, 0x28, 0xad, 0x10, 0x80, 0x00, 0x00, 0x02, 0x11, 0x10, 0x00, 0x23, 0x28,
- 0xa2, 0x00, 0x00, 0x00, 0x25, 0xad, 0x2a, 0x10, 0x78, 0x01, 0xd6, 0xff, 0x40,
- 0x14, 0x68, 0x01, 0x29, 0x25, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x3c, 0x00, 0x43, 0x90, 0x80, 0x9f, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x88, 0x9f, 0x82, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x88, 0x9f, 0x82, 0xa3, 0xff, 0x00, 0x42,
- 0x30, 0x0b, 0x00, 0x42, 0x2c, 0x08, 0x00, 0x40, 0x14, 0x00, 0xa0, 0x03, 0x3c,
- 0x88, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0x2c, 0x1f, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0x88, 0x9f,
- 0x80, 0xa3, 0x50, 0xa0, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xa2,
- 0x90, 0x08, 0x00, 0xa3, 0x90, 0x48, 0x00, 0x42, 0x38, 0x01, 0x00, 0x46, 0x2c,
- 0x53, 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0x14, 0x21, 0x20, 0xc0, 0x00, 0x02,
- 0x00, 0xc4, 0x34, 0x04, 0x00, 0xa3, 0x90, 0x52, 0x00, 0x02, 0x24, 0x02, 0x00,
- 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x84, 0x34, 0x00, 0x00, 0xa3,
- 0x90, 0x43, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x14, 0xff, 0x00, 0x83, 0x30,
- 0x08, 0x00, 0x84, 0x34, 0xff, 0x00, 0x83, 0x30, 0x0f, 0x00, 0x02, 0x24, 0x08,
- 0x00, 0x62, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0x88, 0x0d, 0x42, 0x34, 0x00, 0x00,
- 0x43, 0x8c, 0x05, 0xa2, 0x04, 0x3c, 0x00, 0x00, 0x80, 0xa0, 0x01, 0x00, 0x63,
- 0x24, 0x9c, 0x2f, 0x00, 0x0c, 0x00, 0x00, 0x43, 0xac, 0x50, 0xa0, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x9f, 0x82, 0xa3, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x00,
- 0x00, 0x00, 0xa0, 0x08, 0x3c, 0x00, 0x10, 0x08, 0x35, 0x21, 0x38, 0x00, 0x00,
- 0x30, 0x9b, 0x89, 0x27, 0x80, 0x10, 0x07, 0x00, 0x60, 0x1f, 0x00, 0x08, 0x21,
- 0x30, 0x49, 0x00, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30,
- 0x60, 0x00, 0x00, 0x00, 0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x68,
- 0x00, 0xf9, 0xff, 0x40, 0x10, 0x2b, 0x10, 0x64, 0x00, 0x07, 0x00, 0x64, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0xa7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x71, 0x1f, 0x00, 0x08, 0x00, 0x00,
- 0xc2, 0xac, 0x01, 0x00, 0xe7, 0x24, 0x07, 0x00, 0xe2, 0x28, 0xeb, 0xff, 0x40,
- 0x14, 0x80, 0x10, 0x07, 0x00, 0x80, 0x10, 0x05, 0x00, 0x30, 0x9b, 0x83, 0x27,
- 0x78, 0x1f, 0x00, 0x08, 0x21, 0x30, 0x43, 0x00, 0x07, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x30, 0x60, 0x00, 0x00, 0x00, 0xc3, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x2b, 0x10, 0x68, 0x00, 0xf9, 0xff, 0x40, 0x10, 0x2b, 0x10, 0x64,
- 0x00, 0x00, 0x00, 0x83, 0xac, 0x00, 0x00, 0xc4, 0xac, 0x08, 0x00, 0xe0, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x3c, 0x1c, 0x35, 0x42, 0x24, 0x02,
- 0x80, 0x01, 0x3c, 0xa4, 0xbe, 0x22, 0xac, 0x00, 0x80, 0x02, 0x3c, 0x4c, 0x35,
- 0x42, 0x24, 0x02, 0x80, 0x01, 0x3c, 0xac, 0xbe, 0x22, 0xac, 0x00, 0x80, 0x02,
- 0x3c, 0x7c, 0x35, 0x42, 0x24, 0x02, 0x80, 0x01, 0x3c, 0xb4, 0xbe, 0x22, 0xac,
- 0x90, 0x9f, 0x82, 0x27, 0x30, 0x9b, 0x82, 0xaf, 0x02, 0x80, 0x02, 0x3c, 0xa8,
- 0xbe, 0x42, 0x24, 0x02, 0x80, 0x01, 0x3c, 0x48, 0xba, 0x22, 0xac, 0x02, 0x80,
- 0x01, 0x3c, 0x44, 0xba, 0x22, 0xac, 0x02, 0x80, 0x02, 0x3c, 0xb0, 0xbe, 0x42,
- 0x24, 0x90, 0x9f, 0x80, 0xaf, 0x02, 0x80, 0x01, 0x3c, 0xa8, 0xbe, 0x20, 0xac,
- 0x02, 0x80, 0x01, 0x3c, 0xb0, 0xbe, 0x20, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x58,
- 0xba, 0x22, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x54, 0xba, 0x22, 0xac, 0x02, 0x80,
- 0x01, 0x3c, 0x50, 0xba, 0x22, 0xac, 0x02, 0x80, 0x01, 0x3c, 0x08, 0x00, 0xe0,
- 0x03, 0x4c, 0xba, 0x22, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x48,
- 0x00, 0x82, 0x90, 0x00, 0x00, 0xa7, 0x90, 0x01, 0x00, 0xa3, 0x90, 0x00, 0x11,
- 0x02, 0x00, 0x25, 0x38, 0xe2, 0x00, 0x80, 0x00, 0xe7, 0x34, 0xff, 0x00, 0xe8,
- 0x30, 0xc3, 0xa5, 0x02, 0x34, 0x23, 0x10, 0x48, 0x00, 0x00, 0x1a, 0x03, 0x00,
- 0x23, 0x10, 0x43, 0x00, 0x23, 0x10, 0x46, 0x00, 0x02, 0x1a, 0x02, 0x00, 0x00,
- 0x00, 0xa7, 0xa0, 0x02, 0x00, 0xa2, 0xa0, 0x03, 0x00, 0xa3, 0xa0, 0x04, 0x00,
- 0x84, 0x8c, 0x54, 0x43, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xbf,
- 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x1c,
- 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x04, 0x00,
- 0x12, 0x8e, 0x20, 0x00, 0x04, 0x8e, 0x40, 0x00, 0x42, 0x8e, 0x1c, 0x00, 0x43,
- 0x8e, 0x80, 0x11, 0x02, 0x00, 0x21, 0x38, 0x62, 0x00, 0x09, 0x00, 0x83, 0x30,
- 0x09, 0x00, 0x02, 0x24, 0x0b, 0x00, 0x62, 0x14, 0x10, 0x00, 0x82, 0x30, 0x21,
- 0x20, 0x00, 0x02, 0x24, 0x00, 0xe5, 0x24, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00,
- 0xe2, 0xac, 0x05, 0x00, 0x02, 0x24, 0x24, 0x00, 0xe2, 0xa0, 0x50, 0x00, 0x02,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x1f, 0x00, 0x08, 0x04, 0x00, 0x06, 0x24,
- 0x12, 0x00, 0x40, 0x10, 0x24, 0x00, 0xe5, 0x24, 0x21, 0x20, 0x00, 0x02, 0x04,
- 0x00, 0x06, 0x24, 0x01, 0x00, 0x02, 0x24, 0x18, 0x00, 0xe2, 0xac, 0x06, 0x00,
- 0x02, 0x24, 0x24, 0x00, 0xe2, 0xa0, 0xa8, 0x1f, 0x00, 0x0c, 0x25, 0x00, 0xe0,
- 0xa0, 0x07, 0xff, 0x04, 0x24, 0x20, 0x00, 0x02, 0x8e, 0x3c, 0x00, 0x05, 0x8e,
- 0x38, 0x00, 0x03, 0x8e, 0x24, 0x10, 0x44, 0x00, 0x7d, 0x00, 0xa3, 0x10, 0x20,
- 0x00, 0x02, 0xae, 0x67, 0x20, 0x00, 0x08, 0x08, 0x00, 0x42, 0x34, 0x0a, 0x00,
- 0x83, 0x30, 0x0a, 0x00, 0x02, 0x24, 0x16, 0x00, 0x62, 0x14, 0x60, 0x00, 0x82,
- 0x30, 0x21, 0x20, 0x00, 0x02, 0x24, 0x00, 0xe5, 0x24, 0x01, 0x00, 0x02, 0x24,
- 0x18, 0x00, 0xe2, 0xac, 0x0a, 0x00, 0x02, 0x24, 0x24, 0x00, 0xe2, 0xa0, 0x30,
- 0x00, 0x02, 0x92, 0x04, 0x00, 0x06, 0x24, 0xa8, 0x1f, 0x00, 0x0c, 0x25, 0x00,
- 0xe2, 0xa0, 0x20, 0x00, 0x02, 0x8e, 0xf7, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43,
- 0x00, 0x20, 0x00, 0x02, 0xae, 0xd0, 0x9a, 0x82, 0x8f, 0x74, 0x00, 0x45, 0x8e,
- 0x6c, 0x00, 0x04, 0x26, 0x7e, 0x26, 0x00, 0x0c, 0x21, 0x28, 0x45, 0x00, 0x68,
- 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x40, 0x10, 0x01, 0x00,
- 0x02, 0x24, 0x18, 0x00, 0xe2, 0xac, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x09, 0x00, 0x03, 0x24,
- 0x0b, 0x00, 0x03, 0x24, 0x21, 0x20, 0x00, 0x02, 0x24, 0x00, 0xe5, 0x24, 0x24,
- 0x00, 0xe3, 0xa0, 0x30, 0x00, 0x02, 0x92, 0x04, 0x00, 0x06, 0x24, 0xa8, 0x1f,
- 0x00, 0x0c, 0x25, 0x00, 0xe2, 0xa0, 0x1f, 0xff, 0x04, 0x24, 0x20, 0x00, 0x02,
- 0x8e, 0x3c, 0x00, 0x05, 0x8e, 0x38, 0x00, 0x03, 0x8e, 0x24, 0x20, 0x44, 0x00,
- 0x4b, 0x00, 0xa3, 0x14, 0x20, 0x00, 0x04, 0xae, 0xf7, 0xff, 0x02, 0x24, 0x67,
- 0x20, 0x00, 0x08, 0x24, 0x10, 0x82, 0x00, 0x3c, 0x00, 0x03, 0x8e, 0x38, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00,
- 0x02, 0x18, 0x00, 0x11, 0x8e, 0x07, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x25, 0x26,
- 0x0c, 0x00, 0x22, 0xa2, 0x3c, 0x00, 0x02, 0x92, 0x30, 0x00, 0x03, 0x92, 0x00,
- 0x11, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0x03, 0x00, 0x02, 0x24, 0x0d, 0x00,
- 0x23, 0xa2, 0x18, 0x00, 0xe2, 0xac, 0x1c, 0x00, 0xf1, 0xac, 0x04, 0x00, 0x22,
- 0x8e, 0x08, 0x00, 0x26, 0x8e, 0x01, 0x00, 0x42, 0x24, 0xa8, 0x1f, 0x00, 0x0c,
- 0x04, 0x00, 0x22, 0xae, 0x3c, 0x00, 0x03, 0x8e, 0x34, 0x00, 0x02, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x14, 0x6c, 0x00, 0x04, 0x26, 0xd0, 0x9a,
- 0x82, 0x8f, 0x74, 0x00, 0x45, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x26, 0x00,
- 0x0c, 0x21, 0x28, 0x45, 0x00, 0x3c, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42, 0x30, 0x3c, 0x00, 0x02, 0xae, 0x00,
- 0x00, 0x23, 0x8e, 0x3c, 0x00, 0x04, 0x8e, 0x38, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0x82, 0x14, 0x18, 0x00, 0x03, 0xae, 0x20, 0x00, 0x02,
- 0x8e, 0xf7, 0xff, 0x03, 0x24, 0x24, 0x18, 0x43, 0x00, 0x04, 0x00, 0x42, 0x30,
- 0x06, 0x00, 0x40, 0x10, 0x20, 0x00, 0x03, 0xae, 0xfb, 0xff, 0x02, 0x24, 0x24,
- 0x10, 0x62, 0x00, 0x20, 0x00, 0x02, 0xae, 0x4f, 0x26, 0x00, 0x0c, 0xd0, 0x00,
- 0x44, 0x26, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x66, 0x20, 0x00,
- 0x08, 0x7f, 0xff, 0x03, 0x24, 0x24, 0x00, 0xe5, 0x24, 0x01, 0x00, 0x02, 0x24,
- 0x18, 0x00, 0xe2, 0xac, 0x08, 0x00, 0x02, 0x24, 0x24, 0x00, 0xe2, 0xa0, 0x30,
- 0x00, 0x02, 0x92, 0x04, 0x00, 0x06, 0x24, 0xa8, 0x1f, 0x00, 0x0c, 0x25, 0x00,
- 0xe2, 0xa0, 0x20, 0x00, 0x02, 0x8e, 0x77, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43,
- 0x00, 0x20, 0x00, 0x02, 0xae, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0x20, 0x00, 0xa2, 0x28, 0x1c, 0x00, 0x40, 0x14, 0x21, 0x18,
- 0x80, 0x00, 0x22, 0x33, 0x0b, 0x3c, 0x00, 0x11, 0x6b, 0x35, 0x66, 0x77, 0x0a,
- 0x3c, 0x44, 0x55, 0x4a, 0x35, 0xaa, 0xbb, 0x09, 0x3c, 0x88, 0x99, 0x29, 0x35,
- 0xee, 0xff, 0x08, 0x3c, 0xcc, 0xdd, 0x08, 0x35, 0xa5, 0xa5, 0x07, 0x3c, 0xa5,
- 0xa5, 0xe7, 0x34, 0xf0, 0xf0, 0x06, 0x3c, 0xf0, 0xf0, 0xc6, 0x34, 0xff, 0xff,
- 0x0c, 0x24, 0x1c, 0x00, 0x84, 0x24, 0x00, 0x00, 0x6b, 0xac, 0xe8, 0xff, 0x8a,
- 0xac, 0xec, 0xff, 0x89, 0xac, 0xf0, 0xff, 0x88, 0xac, 0xf4, 0xff, 0x80, 0xac,
- 0xf8, 0xff, 0x87, 0xac, 0xfc, 0xff, 0x86, 0xac, 0x00, 0x00, 0x8c, 0xac, 0x20,
- 0x00, 0x84, 0x24, 0xe0, 0xff, 0xa5, 0x24, 0x20, 0x00, 0xa2, 0x28, 0xf4, 0xff,
- 0x40, 0x10, 0x20, 0x00, 0x63, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0xf8, 0xff, 0xbd, 0x27, 0x21, 0x60, 0x80, 0x00, 0xa0, 0x89, 0x82, 0x8f,
- 0x21, 0x68, 0xa0, 0x00, 0x04, 0x00, 0xb1, 0xaf, 0x03, 0x00, 0x40, 0x14, 0x00,
- 0x00, 0xb0, 0xaf, 0xc4, 0x20, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00, 0x20, 0x00,
- 0xa2, 0x29, 0x2a, 0x00, 0x40, 0x14, 0x21, 0x50, 0x00, 0x00, 0x22, 0x33, 0x11,
- 0x3c, 0x00, 0x11, 0x31, 0x36, 0x66, 0x77, 0x10, 0x3c, 0x44, 0x55, 0x10, 0x36,
- 0xaa, 0xbb, 0x19, 0x3c, 0x88, 0x99, 0x39, 0x37, 0xee, 0xff, 0x18, 0x3c, 0xcc,
- 0xdd, 0x18, 0x37, 0xa5, 0xa5, 0x0f, 0x3c, 0xa5, 0xa5, 0xef, 0x35, 0xf0, 0xf0,
- 0x0e, 0x3c, 0xf0, 0xf0, 0xce, 0x35, 0x1c, 0x00, 0x8b, 0x25, 0xe8, 0xff, 0x63,
- 0x8d, 0xec, 0xff, 0x64, 0x8d, 0xf0, 0xff, 0x65, 0x8d, 0xf4, 0xff, 0x69, 0x8d,
- 0xf8, 0xff, 0x66, 0x8d, 0xfc, 0xff, 0x67, 0x8d, 0x00, 0x00, 0x68, 0x8d, 0x20,
- 0x00, 0x6b, 0x25, 0x00, 0x00, 0x82, 0x8d, 0x20, 0x00, 0x8c, 0x25, 0xe0, 0xff,
- 0xad, 0x25, 0x26, 0x10, 0x51, 0x00, 0x25, 0x50, 0x42, 0x01, 0x26, 0x18, 0x70,
- 0x00, 0x25, 0x50, 0x43, 0x01, 0x26, 0x20, 0x99, 0x00, 0x25, 0x50, 0x44, 0x01,
- 0x26, 0x28, 0xb8, 0x00, 0x25, 0x50, 0x45, 0x01, 0x25, 0x50, 0x49, 0x01, 0x26,
- 0x30, 0xcf, 0x00, 0x25, 0x50, 0x46, 0x01, 0x26, 0x38, 0xee, 0x00, 0x25, 0x50,
- 0x47, 0x01, 0x27, 0x40, 0x08, 0x00, 0x20, 0x00, 0xa2, 0x29, 0xe5, 0xff, 0x40,
- 0x10, 0x25, 0x50, 0x48, 0x01, 0x21, 0x10, 0x40, 0x01, 0x04, 0x00, 0xb1, 0x8f,
- 0x00, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x08, 0x00, 0xbd, 0x27, 0xe0,
- 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x18, 0x00,
- 0xb2, 0xaf, 0x02, 0x80, 0x12, 0x3c, 0x14, 0xce, 0x52, 0x26, 0x1c, 0x00, 0xbf,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x40, 0x00, 0x22, 0x8e, 0x1c, 0x00, 0x23, 0x8e,
- 0x80, 0x11, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24, 0x18,
- 0x00, 0x62, 0xac, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
- 0x40, 0x14, 0x21, 0x20, 0x40, 0x02, 0x6e, 0x20, 0x00, 0x0c, 0x3c, 0x1f, 0x05,
- 0x24, 0xa8, 0x89, 0x84, 0x8f, 0x80, 0x00, 0x23, 0x8e, 0xa4, 0x89, 0x90, 0x8f,
- 0x2a, 0x10, 0x64, 0x00, 0x03, 0x00, 0x40, 0x10, 0x04, 0x00, 0x82, 0x28, 0x21,
- 0x20, 0x60, 0x00, 0x04, 0x00, 0x82, 0x28, 0x02, 0x00, 0x40, 0x10, 0x04, 0x00,
- 0x02, 0x2a, 0x04, 0x00, 0x04, 0x24, 0x03, 0x00, 0x40, 0x10, 0x2a, 0x10, 0x90,
- 0x00, 0x04, 0x00, 0x10, 0x24, 0x2a, 0x10, 0x90, 0x00, 0x02, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x80, 0x00, 0x23, 0x20, 0x90, 0x00, 0x90,
- 0x1d, 0x00, 0x0c, 0x01, 0x00, 0x84, 0x24, 0x21, 0x20, 0x20, 0x02, 0x21, 0x28,
- 0x40, 0x02, 0x54, 0x43, 0x00, 0x0c, 0x21, 0x30, 0x02, 0x02, 0x1c, 0x00, 0xbf,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x14,
- 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x00, 0xa0, 0x04, 0x3c, 0xd4, 0x0d,
- 0x84, 0x34, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3,
- 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x34, 0x00, 0x22, 0x8e,
- 0x3c, 0x00, 0x23, 0x8e, 0x21, 0x90, 0x40, 0x00, 0x23, 0x18, 0x72, 0x00, 0x00,
- 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00,
- 0x82, 0xac, 0x38, 0x00, 0x22, 0x8e, 0x04, 0x00, 0x33, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x28, 0x00, 0x42, 0x12, 0x0f, 0x00, 0x74, 0x30, 0x34, 0x00, 0x22, 0x8e,
- 0x10, 0x00, 0x30, 0x8e, 0x23, 0x10, 0x42, 0x02, 0x0f, 0x00, 0x42, 0x30, 0x00,
- 0x00, 0x03, 0x8e, 0x2a, 0x10, 0x54, 0x00, 0x06, 0x00, 0x40, 0x14, 0x10, 0x00,
- 0x23, 0xae, 0x84, 0x00, 0x62, 0x8e, 0x08, 0x00, 0x03, 0x8e, 0xfc, 0xff, 0x42,
- 0x24, 0x23, 0x10, 0x43, 0x00, 0x84, 0x00, 0x62, 0xae, 0x04, 0x00, 0x02, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x0a, 0x00, 0x42, 0x2c, 0x04,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x20, 0x0c,
- 0x00, 0x0c, 0x45, 0x02, 0x05, 0x24, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x42, 0x24, 0x08, 0x00, 0x40, 0x14, 0x04, 0x00, 0x02, 0xae,
- 0xf0, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xae, 0x64,
- 0x00, 0x62, 0x8e, 0xf0, 0x9f, 0x90, 0xaf, 0x01, 0x00, 0x42, 0x24, 0x64, 0x00,
- 0x62, 0xae, 0x01, 0x00, 0x42, 0x26, 0x38, 0x00, 0x23, 0x8e, 0x0f, 0x00, 0x52,
- 0x30, 0xda, 0xff, 0x43, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x22, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xac,
- 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x4f, 0x02, 0x05, 0x24, 0xb8, 0x9f,
- 0x83, 0x8f, 0x10, 0x00, 0x22, 0x26, 0x18, 0x00, 0x20, 0xae, 0x10, 0x00, 0x60,
- 0x10, 0x14, 0x00, 0x22, 0xae, 0x01, 0x00, 0x05, 0x24, 0x02, 0x00, 0x04, 0x24,
- 0x10, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x45, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x51, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x64, 0xac, 0x00, 0x00, 0x63,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0xf4, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x23, 0x8e, 0x38, 0x00, 0x20, 0xae, 0x3c, 0x00, 0x20, 0xae, 0x34,
- 0x00, 0x20, 0xae, 0x04, 0x00, 0x62, 0x30, 0x06, 0x00, 0x40, 0x10, 0x30, 0x00,
- 0x20, 0xae, 0xfb, 0xff, 0x02, 0x24, 0x24, 0x10, 0x62, 0x00, 0x20, 0x00, 0x22,
- 0xae, 0x4f, 0x26, 0x00, 0x0c, 0xd0, 0x00, 0x64, 0x26, 0x20, 0x00, 0x22, 0x8e,
- 0x6c, 0x00, 0x24, 0x26, 0x00, 0x01, 0x42, 0x34, 0x6b, 0x26, 0x00, 0x0c, 0x20,
- 0x00, 0x22, 0xae, 0x4f, 0x26, 0x00, 0x0c, 0x54, 0x00, 0x24, 0x26, 0x24, 0x00,
- 0xbf, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x28, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xa0, 0x00, 0x0d, 0xff,
- 0x03, 0x24, 0x18, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x24, 0x10, 0x43, 0x00, 0x09, 0x00, 0x42, 0x34, 0xfb, 0x20, 0x00, 0x0c,
- 0x20, 0x00, 0x02, 0xae, 0x04, 0x00, 0x03, 0x8e, 0x50, 0x00, 0x11, 0xae, 0x2c,
- 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00,
- 0x62, 0xac, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xd0, 0xff, 0xbd, 0x27,
- 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x1c, 0x00, 0xb3, 0xaf, 0x21,
- 0x98, 0xa0, 0x00, 0x28, 0x00, 0xbf, 0xaf, 0x24, 0x00, 0xb5, 0xaf, 0x20, 0x00,
- 0xb4, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x08, 0x00, 0x74,
- 0x8e, 0x04, 0x00, 0x32, 0x8e, 0x00, 0x00, 0x82, 0x92, 0x14, 0x00, 0x64, 0x8e,
- 0x80, 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0xe2,
- 0x22, 0x00, 0x08, 0x7c, 0x0d, 0x42, 0x34, 0x2c, 0x00, 0x43, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x00, 0x62, 0x30, 0x09, 0x00, 0x40, 0x10, 0x0f, 0xff, 0x02,
- 0x24, 0x24, 0x18, 0x62, 0x00, 0x2c, 0x00, 0x43, 0xae, 0x20, 0x00, 0x22, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x01,
- 0x00, 0x62, 0x34, 0x2c, 0x00, 0x42, 0xae, 0x00, 0x00, 0x82, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x0f, 0x00, 0x42, 0x30, 0xfb, 0xff, 0x43, 0x24, 0x07, 0x00, 0x62,
- 0x2c, 0x43, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c,
- 0x21, 0x08, 0x22, 0x00, 0x20, 0x1c, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x24, 0x2b, 0x01,
- 0x82, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0xcc, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43,
- 0x8c, 0x20, 0x00, 0x24, 0x8e, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac,
- 0x01, 0x00, 0x82, 0x30, 0x0e, 0x00, 0x40, 0x10, 0xfd, 0xff, 0x02, 0x24, 0x6c,
- 0x00, 0x24, 0x26, 0x6b, 0x26, 0x00, 0x0c, 0xcc, 0x00, 0x40, 0xae, 0x20, 0x00,
- 0x22, 0x8e, 0xfe, 0xff, 0x03, 0x24, 0x24, 0x18, 0x43, 0x00, 0x08, 0x00, 0x42,
- 0x30, 0x21, 0x01, 0x40, 0x10, 0x20, 0x00, 0x23, 0xae, 0xf7, 0xff, 0x02, 0x24,
- 0x24, 0x10, 0x62, 0x00, 0xd2, 0x22, 0x00, 0x08, 0x10, 0x00, 0x42, 0x34, 0x24,
- 0x10, 0x82, 0x00, 0x18, 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00,
- 0x42, 0x8e, 0x21, 0x20, 0x20, 0x02, 0x01, 0x00, 0x42, 0x34, 0xfb, 0x20, 0x00,
- 0x0c, 0x2c, 0x00, 0x42, 0xae, 0xe8, 0x22, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x02, 0x24, 0x09, 0x01, 0x82, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0x20,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0xa2, 0x00,
- 0x40, 0x10, 0x6c, 0x00, 0x24, 0x26, 0x6b, 0x26, 0x00, 0x0c, 0xcc, 0x00, 0x40,
- 0xae, 0x20, 0x00, 0x22, 0x8e, 0xf6, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
- 0xe8, 0x22, 0x00, 0x08, 0x20, 0x00, 0x22, 0xae, 0x04, 0x00, 0x02, 0x24, 0xfa,
- 0x00, 0x82, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0xf3, 0x21, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0xff, 0x82, 0x24, 0xe9, 0x13, 0x42, 0x2c, 0xf4, 0x00, 0x40,
- 0x10, 0x00, 0xa0, 0x02, 0x3c, 0xf3, 0x21, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0xac, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x47, 0x03, 0x05, 0x24, 0x20,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0xf1, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x92, 0x34, 0x00, 0x24,
- 0x8e, 0x0f, 0x00, 0x45, 0x30, 0x23, 0x18, 0xa4, 0x00, 0x3c, 0x00, 0x22, 0x8e,
- 0x0f, 0x00, 0x63, 0x30, 0x23, 0x10, 0x44, 0x00, 0x0f, 0x00, 0x42, 0x30, 0x2a,
- 0x10, 0x43, 0x00, 0x07, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0xc0, 0x0d,
- 0x63, 0x34, 0x21, 0x20, 0x20, 0x02, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0xdc, 0x22, 0x00, 0x08, 0x03, 0x00, 0x05, 0x24, 0x3b, 0x00, 0x85, 0x10,
- 0x21, 0xa8, 0xa0, 0x00, 0xcc, 0x00, 0x40, 0xae, 0x34, 0x00, 0x22, 0x8e, 0x10,
- 0x00, 0x30, 0x8e, 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42, 0x30, 0x34, 0x00,
- 0x22, 0xae, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x22,
- 0xae, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24,
- 0x0a, 0x00, 0x42, 0x2c, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xac,
- 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x82, 0x03, 0x05, 0x24, 0x04, 0x00,
- 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x08, 0x00, 0x40,
- 0x14, 0x04, 0x00, 0x02, 0xae, 0xf0, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0xae, 0x64, 0x00, 0x42, 0x8e, 0xf0, 0x9f, 0x90, 0xaf, 0x01,
- 0x00, 0x42, 0x24, 0x64, 0x00, 0x42, 0xae, 0x34, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0xff, 0x55, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x22,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x14, 0x10, 0x00, 0x22, 0x26,
- 0x14, 0x00, 0x22, 0xae, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x42, 0x30, 0x0f, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
- 0x23, 0x8e, 0x34, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x62,
- 0x14, 0x6c, 0x00, 0x24, 0x26, 0x6b, 0x26, 0x00, 0x0c, 0x6c, 0x00, 0x24, 0x26,
- 0x45, 0x22, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9a, 0x82, 0x8f, 0x74,
- 0x00, 0x45, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x26, 0x00, 0x0c, 0x21, 0x28,
- 0x45, 0x00, 0x00, 0x00, 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x43,
- 0x30, 0x09, 0x00, 0x02, 0x24, 0x0e, 0x00, 0x62, 0x10, 0x0a, 0x00, 0x62, 0x28,
- 0x05, 0x00, 0x40, 0x10, 0x07, 0x00, 0x02, 0x24, 0x58, 0x00, 0x62, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xe8, 0x22, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
- 0x02, 0x24, 0x18, 0x00, 0x62, 0x10, 0x0b, 0x00, 0x02, 0x24, 0x25, 0x00, 0x62,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x22, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x24, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82, 0x30, 0x0d,
- 0x00, 0x40, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0x3c, 0x00, 0x23, 0x8e, 0x38, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x0a, 0x00, 0x82, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x42, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x2c, 0x00, 0x42, 0xae, 0x00,
- 0xa0, 0x02, 0x3c, 0xe2, 0x22, 0x00, 0x08, 0xf0, 0x0d, 0x42, 0x34, 0x00, 0xa0,
- 0x04, 0x3c, 0xf4, 0x0d, 0x84, 0x34, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x83,
- 0x8c, 0x20, 0x00, 0x42, 0x34, 0x01, 0x00, 0x63, 0x24, 0x20, 0x00, 0x22, 0xae,
- 0x00, 0x00, 0x83, 0xac, 0x2c, 0x00, 0x42, 0x8e, 0xc8, 0x00, 0x43, 0x8e, 0x01,
- 0x00, 0x42, 0x34, 0x01, 0x00, 0x63, 0x24, 0x2c, 0x00, 0x42, 0xae, 0xe8, 0x22,
- 0x00, 0x08, 0xc8, 0x00, 0x43, 0xae, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x42, 0x30, 0x08, 0x00, 0x40, 0x14, 0xf5, 0xff, 0x02, 0x24,
- 0x00, 0xa0, 0x03, 0x3c, 0xec, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xe8, 0x22, 0x00, 0x08, 0x00, 0x00,
- 0x62, 0xac, 0xcc, 0x00, 0x40, 0xae, 0x10, 0x00, 0x30, 0x8e, 0x20, 0x00, 0x23,
- 0x8e, 0x18, 0x00, 0x24, 0x8e, 0x24, 0x18, 0x62, 0x00, 0x0b, 0x00, 0x04, 0x12,
- 0x20, 0x00, 0x23, 0xae, 0x84, 0x00, 0x42, 0x8e, 0x08, 0x00, 0x03, 0x8e, 0x04,
- 0x00, 0x42, 0x24, 0x21, 0x10, 0x43, 0x00, 0x84, 0x00, 0x42, 0xae, 0x00, 0x00,
- 0x10, 0x8e, 0x18, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0x02,
- 0x16, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x23, 0x8e, 0x10, 0x00, 0x24, 0x8e,
- 0x34, 0x00, 0x25, 0x8e, 0x38, 0x00, 0x22, 0x8e, 0x3c, 0x00, 0x23, 0xae, 0x05,
- 0x00, 0xa2, 0x10, 0x18, 0x00, 0x24, 0xae, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xd2, 0x22, 0x00, 0x08, 0x08, 0x00, 0x42, 0x34, 0x6b, 0x26, 0x00,
- 0x0c, 0x6c, 0x00, 0x24, 0x26, 0xe8, 0x22, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x82, 0x92, 0x30, 0x00, 0x23, 0x8e, 0x02, 0x11, 0x02, 0x00, 0x21,
- 0x00, 0x43, 0x14, 0x23, 0x10, 0x43, 0x00, 0xb8, 0x9f, 0x83, 0x8f, 0x01, 0x00,
- 0x02, 0x24, 0x10, 0x00, 0x62, 0xae, 0x04, 0x00, 0x71, 0xae, 0x04, 0x00, 0x60,
- 0x14, 0x00, 0x00, 0x60, 0xae, 0xd0, 0x9f, 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0xe8, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x53, 0xac, 0x30, 0x00, 0x22, 0x8e, 0x20, 0x00, 0x23, 0x8e, 0xe8, 0x9f,
- 0x93, 0xaf, 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42, 0x30, 0x30, 0x00, 0x22,
- 0xae, 0x80, 0x00, 0x62, 0x30, 0x05, 0x00, 0x40, 0x10, 0x80, 0x00, 0x62, 0x34,
- 0xd0, 0x9a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x22, 0x00, 0x08, 0x28,
- 0x00, 0x22, 0xae, 0x20, 0x00, 0x22, 0xae, 0x74, 0x00, 0x42, 0x8e, 0xd0, 0x9a,
- 0x83, 0x8f, 0xc2, 0x10, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0xe8, 0x22, 0x00,
- 0x08, 0x28, 0x00, 0x23, 0xae, 0x0f, 0x00, 0x42, 0x30, 0x05, 0x00, 0x42, 0x28,
- 0x0a, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x20, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00,
- 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0xe8, 0x22, 0x00,
- 0x08, 0x2c, 0x00, 0x42, 0xae, 0xc4, 0x0d, 0x63, 0x34, 0x21, 0x20, 0x20, 0x02,
- 0x00, 0x00, 0x62, 0x8c, 0x04, 0x00, 0x05, 0x24, 0x01, 0x00, 0x42, 0x24, 0x6f,
- 0x21, 0x00, 0x0c, 0x00, 0x00, 0x62, 0xac, 0xe8, 0x22, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0xbc, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c, 0xc8, 0x00, 0x44,
- 0x8e, 0x01, 0x00, 0x63, 0x24, 0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x43, 0xac,
- 0xc8, 0x00, 0x44, 0xae, 0x28, 0x00, 0xbf, 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20,
- 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd,
- 0x27, 0xd0, 0x9a, 0x82, 0x8f, 0xd0, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xb4, 0xaf,
- 0x21, 0xa0, 0x80, 0x00, 0x24, 0x00, 0xb5, 0xaf, 0x21, 0xa8, 0xa0, 0x00, 0x2c,
- 0x00, 0xbf, 0xaf, 0x28, 0x00, 0xb6, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00,
- 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x08, 0x00, 0xb3,
- 0x8e, 0x7c, 0x00, 0x83, 0x8e, 0x14, 0x00, 0xb6, 0x8e, 0x8c, 0x9f, 0x82, 0xaf,
- 0x06, 0x00, 0x60, 0x10, 0x2a, 0x10, 0xc3, 0x02, 0x02, 0x00, 0x40, 0x10, 0x21,
- 0x20, 0x00, 0x00, 0x23, 0x20, 0x76, 0x00, 0x79, 0x23, 0x00, 0x08, 0x7c, 0x00,
- 0x84, 0xae, 0xb0, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1d, 0x00, 0x0c, 0x64, 0x00, 0x04, 0x24,
- 0xb0, 0x9f, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x43, 0x00, 0x21,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x1d, 0x00, 0x0c, 0x02, 0x00, 0x04, 0x24, 0x08, 0x00, 0x04,
- 0x24, 0x90, 0x1d, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0x02, 0x00, 0x04, 0x24,
- 0x90, 0x1d, 0x00, 0x0c, 0x21, 0x80, 0x40, 0x00, 0x21, 0x88, 0x71, 0x02, 0x80,
- 0x10, 0x02, 0x00, 0x00, 0x00, 0x23, 0x92, 0x04, 0x80, 0x50, 0x00, 0x26, 0x18,
- 0x70, 0x00, 0x00, 0x00, 0x23, 0xa2, 0x00, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x43, 0x30, 0x01, 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x14,
- 0x0f, 0x00, 0x42, 0x32, 0x04, 0x00, 0x43, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x33,
- 0x23, 0x00, 0x08, 0x00, 0x00, 0x72, 0xa2, 0x00, 0xa0, 0x03, 0x3c, 0xdc, 0x0d,
- 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0x00, 0x00, 0x62, 0xac, 0x00, 0x00, 0x65, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x0f, 0x00, 0xa3, 0x30, 0x3a, 0x00, 0x60, 0x10, 0x05, 0x00, 0x62, 0x28, 0x05,
- 0x00, 0x40, 0x10, 0x21, 0x20, 0x80, 0x02, 0x1e, 0x1d, 0x00, 0x0c, 0x21, 0x28,
- 0xa0, 0x02, 0x79, 0x23, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x62,
- 0x28, 0x31, 0x00, 0x40, 0x10, 0xc3, 0xa5, 0x02, 0x34, 0x02, 0x00, 0x63, 0x92,
- 0x03, 0x00, 0x64, 0x92, 0x23, 0x10, 0x43, 0x00, 0x01, 0x00, 0x63, 0x92, 0x23,
- 0x10, 0x45, 0x00, 0x21, 0x18, 0x64, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x23, 0x10,
- 0x43, 0x00, 0xff, 0xff, 0x52, 0x30, 0x16, 0x00, 0x56, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0xb0, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x14,
- 0x00, 0xa0, 0x03, 0x3c, 0xc8, 0x00, 0x82, 0x8e, 0xac, 0x0d, 0x63, 0x34, 0x01,
- 0x00, 0x42, 0x24, 0xc8, 0x00, 0x82, 0xae, 0x00, 0x00, 0x62, 0x8c, 0x14, 0x00,
- 0xa5, 0x8e, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x2b, 0x10, 0xb2,
- 0x00, 0x1f, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x42, 0x2a,
- 0x1c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x45, 0x02, 0x79,
- 0x23, 0x00, 0x08, 0x7c, 0x00, 0x82, 0xae, 0x40, 0x9d, 0x84, 0x27, 0x00, 0x00,
- 0x62, 0x92, 0x48, 0x00, 0x83, 0x8c, 0x02, 0x11, 0x02, 0x00, 0x07, 0x00, 0x52,
- 0x30, 0x05, 0x00, 0x43, 0x16, 0x00, 0x00, 0x00, 0x00, 0x87, 0x21, 0x00, 0x0c,
- 0x21, 0x28, 0xa0, 0x02, 0x79, 0x23, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x20, 0x80, 0x02, 0x0f, 0x1d, 0x00, 0x0c, 0x21, 0x28, 0xa0, 0x02, 0x79, 0x23,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x3c, 0xb8, 0x0d, 0x42,
- 0x34, 0x00, 0x00, 0x43, 0x8c, 0xc8, 0x00, 0x84, 0x8e, 0x01, 0x00, 0x63, 0x24,
- 0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x43, 0xac, 0xc8, 0x00, 0x84, 0xae, 0x2c,
- 0x00, 0xbf, 0x8f, 0x28, 0x00, 0xb6, 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20, 0x00,
- 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27,
- 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0xb8, 0x9f, 0x90, 0x8f, 0x18,
- 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xb8, 0x9f, 0x82, 0xaf, 0x03, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0xb8, 0x9f, 0x82, 0x27, 0xe8, 0x9f, 0x82, 0xaf, 0x10, 0x00, 0x03, 0x8e,
- 0x01, 0x00, 0x02, 0x24, 0x20, 0x00, 0x62, 0x14, 0x02, 0x00, 0x02, 0x24, 0xc8,
- 0x9d, 0x84, 0x8f, 0x3b, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xff,
- 0x05, 0x3c, 0x00, 0xff, 0xa5, 0x34, 0x04, 0x00, 0x04, 0x8e, 0x08, 0x00, 0x02,
- 0x8e, 0x14, 0x00, 0x03, 0x8e, 0x04, 0x00, 0x84, 0x8c, 0x21, 0x10, 0x43, 0x00,
- 0x20, 0x00, 0x84, 0x8c, 0x21, 0x10, 0x45, 0x00, 0x23, 0x88, 0x44, 0x00, 0x05,
- 0x00, 0x20, 0x1a, 0x02, 0x00, 0x05, 0x3c, 0x00, 0x01, 0xa5, 0x34, 0x21, 0x28,
- 0x85, 0x00, 0x78, 0x11, 0x00, 0x0c, 0x21, 0x30, 0x20, 0x02, 0x04, 0x00, 0x04,
- 0x8e, 0x08, 0x00, 0x05, 0x8e, 0x14, 0x00, 0x06, 0x8e, 0x04, 0x00, 0xa5, 0x24,
- 0x21, 0x19, 0x00, 0x0c, 0xfc, 0xff, 0xc6, 0x24, 0xf4, 0x9e, 0x84, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0xb8, 0x23,
- 0x00, 0x08, 0x00, 0xa0, 0x03, 0x3c, 0x04, 0x00, 0x62, 0x10, 0x21, 0x88, 0x00,
- 0x00, 0xac, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x0d, 0x05, 0x05, 0x24,
- 0x00, 0xa0, 0x03, 0x3c, 0x74, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x10,
- 0x00, 0x00, 0xae, 0x01, 0x00, 0x42, 0x24, 0x09, 0x00, 0x20, 0x12, 0x00, 0x00,
- 0x62, 0xac, 0x00, 0xa0, 0x03, 0x3c, 0xc8, 0x0d, 0x63, 0x34, 0x21, 0x28, 0x20,
- 0x02, 0x00, 0x00, 0x62, 0x8c, 0x04, 0x00, 0x04, 0x8e, 0x01, 0x00, 0x42, 0x24,
- 0x6f, 0x21, 0x00, 0x0c, 0x00, 0x00, 0x62, 0xac, 0xb8, 0x9f, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9f,
- 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xbf,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x20, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x14,
- 0x00, 0xbf, 0xaf, 0x5c, 0x1a, 0x00, 0x0c, 0x21, 0x80, 0x80, 0x00, 0x20, 0x00,
- 0x02, 0x8e, 0xff, 0xfe, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0x02,
- 0xae, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x18, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21,
- 0x88, 0x80, 0x00, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00,
- 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x20, 0x00, 0x25,
- 0x8e, 0x04, 0x00, 0x34, 0x8e, 0x03, 0x01, 0xa2, 0x30, 0xc3, 0x00, 0x40, 0x14,
- 0x21, 0x10, 0x00, 0x00, 0x38, 0x00, 0x22, 0x8e, 0x34, 0x00, 0x23, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x0f, 0x00, 0x42, 0x30, 0x05, 0x00,
- 0x42, 0x28, 0x15, 0x00, 0x40, 0x14, 0x88, 0x00, 0xa3, 0x30, 0x80, 0x00, 0x02,
- 0x24, 0xb8, 0x00, 0x62, 0x14, 0x21, 0x10, 0x00, 0x00, 0xff, 0x3f, 0x02, 0x3c,
- 0xd0, 0x9a, 0x83, 0x8f, 0x28, 0x00, 0x24, 0x8e, 0xff, 0xff, 0x42, 0x34, 0x23,
- 0x18, 0x64, 0x00, 0x2b, 0x10, 0x43, 0x00, 0xb0, 0x00, 0x40, 0x14, 0x21, 0x10,
- 0x00, 0x00, 0x08, 0x00, 0xa2, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x82,
- 0x8e, 0x21, 0x20, 0x80, 0x02, 0x01, 0x00, 0x42, 0x34, 0x65, 0x1c, 0x00, 0x0c,
- 0x2c, 0x00, 0x82, 0xac, 0xae, 0x24, 0x00, 0x08, 0x21, 0x10, 0x00, 0x00, 0xf0,
- 0x9f, 0x92, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x8e, 0x04, 0x00,
- 0x43, 0x8e, 0x00, 0x00, 0x40, 0xae, 0xf0, 0x9f, 0x82, 0xaf, 0x04, 0x00, 0x60,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c,
- 0x67, 0x05, 0x05, 0x24, 0xc8, 0x9d, 0x84, 0x8f, 0x3b, 0x12, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, 0x80, 0x00, 0x86, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x2c, 0x16, 0x00, 0x0c, 0x10, 0x00, 0x45, 0x26, 0x90, 0x89, 0x83,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x60, 0x10, 0x21, 0x98, 0x40, 0x00,
- 0x80, 0x00, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x62, 0x02, 0x19,
- 0x00, 0x40, 0x10, 0x21, 0x10, 0x53, 0x02, 0xfe, 0x00, 0x03, 0x24, 0x10, 0x00,
- 0x43, 0xa0, 0x98, 0x89, 0x84, 0x8f, 0x80, 0x00, 0x83, 0x8e, 0x94, 0x89, 0x90,
- 0x8f, 0x2a, 0x10, 0x64, 0x00, 0x03, 0x00, 0x40, 0x10, 0x2a, 0x10, 0x93, 0x00,
- 0x21, 0x20, 0x60, 0x00, 0x2a, 0x10, 0x93, 0x00, 0x02, 0x00, 0x40, 0x10, 0x2a,
- 0x10, 0x13, 0x02, 0x21, 0x20, 0x60, 0x02, 0x03, 0x00, 0x40, 0x10, 0x2a, 0x10,
- 0x90, 0x00, 0x21, 0x80, 0x60, 0x02, 0x2a, 0x10, 0x90, 0x00, 0x02, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x80, 0x00, 0x23, 0x20, 0x90, 0x00,
- 0x90, 0x1d, 0x00, 0x0c, 0x01, 0x00, 0x84, 0x24, 0x21, 0x98, 0x02, 0x02, 0xf4,
- 0x9e, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x9f,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x53, 0x00, 0x04, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c,
- 0x84, 0x05, 0x05, 0x24, 0x20, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x62, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9f,
- 0x82, 0x8f, 0xf0, 0x9f, 0x92, 0xaf, 0xad, 0x24, 0x00, 0x08, 0x00, 0x00, 0x42,
- 0xae, 0x23, 0x00, 0x60, 0x16, 0xff, 0x3f, 0x06, 0x3c, 0xd0, 0x9a, 0x85, 0x8f,
- 0x2c, 0x00, 0x22, 0x8e, 0xff, 0xff, 0xc6, 0x34, 0x23, 0x10, 0xa2, 0x00, 0x2b,
- 0x10, 0xc2, 0x00, 0x1a, 0x00, 0x40, 0x10, 0x00, 0x02, 0x62, 0x30, 0x18, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9f, 0x82, 0x8f, 0xf0, 0x9f, 0x92,
- 0xaf, 0x00, 0x00, 0x42, 0xae, 0x20, 0x00, 0x24, 0x8e, 0x80, 0x00, 0x02, 0x24,
- 0x88, 0x00, 0x83, 0x30, 0x4c, 0x00, 0x62, 0x14, 0x21, 0x10, 0x60, 0x02, 0x28,
- 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0xa2, 0x00, 0x2b, 0x10,
- 0xc2, 0x00, 0x46, 0x00, 0x40, 0x14, 0x21, 0x10, 0x60, 0x02, 0x08, 0x00, 0x82,
- 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x82, 0x8e, 0x21, 0x20, 0x80, 0x02,
- 0x01, 0x00, 0x42, 0x34, 0x65, 0x1c, 0x00, 0x0c, 0x2c, 0x00, 0x82, 0xac, 0xae,
- 0x24, 0x00, 0x08, 0x21, 0x10, 0x60, 0x02, 0x05, 0x00, 0x60, 0x12, 0xff, 0xfd,
- 0x03, 0x24, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x24, 0x00,
- 0x08, 0x00, 0x02, 0x42, 0x34, 0x20, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0x22, 0xae, 0x04, 0x00, 0x42, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0xac, 0x89,
- 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0xcb, 0x05, 0x05, 0x24, 0x01, 0x00, 0x02,
- 0x24, 0x00, 0xa0, 0x04, 0x3c, 0x04, 0x00, 0x42, 0xae, 0x64, 0x00, 0x82, 0x8e,
- 0x04, 0x00, 0x63, 0x26, 0xff, 0xff, 0x42, 0x24, 0x64, 0x00, 0x82, 0xae, 0x08,
- 0x00, 0x43, 0xae, 0x84, 0x00, 0x82, 0x8e, 0x70, 0x0d, 0x84, 0x34, 0x04, 0x00,
- 0x42, 0x24, 0x21, 0x10, 0x43, 0x00, 0x84, 0x00, 0x82, 0xae, 0x00, 0x00, 0x82,
- 0x8c, 0x14, 0x00, 0x23, 0x8e, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x82, 0xac,
- 0x00, 0x00, 0x72, 0xac, 0x18, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x40, 0x14, 0x14, 0x00, 0x32, 0xae, 0x18, 0x00, 0x32, 0xae, 0x38, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x0f, 0x00, 0x42,
- 0x30, 0x38, 0x00, 0x22, 0xae, 0xd0, 0x9a, 0x82, 0x8f, 0x20, 0x00, 0x23, 0x8e,
- 0x88, 0x13, 0x42, 0x24, 0x2c, 0x00, 0x22, 0xae, 0x03, 0x00, 0x62, 0x30, 0x07,
- 0x00, 0x40, 0x14, 0x08, 0x00, 0x62, 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00,
- 0x82, 0x8e, 0x21, 0x20, 0x80, 0x02, 0x01, 0x00, 0x42, 0x34, 0x65, 0x1c, 0x00,
- 0x0c, 0x2c, 0x00, 0x82, 0xac, 0x06, 0x00, 0x73, 0x26, 0x21, 0x10, 0x60, 0x02,
- 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18,
- 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x80, 0x80, 0x00, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf,
- 0x2c, 0x00, 0x03, 0x8e, 0x14, 0x00, 0x11, 0x8e, 0xf0, 0x00, 0x62, 0x30, 0x05,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x89, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x10, 0xf1, 0x00, 0x62, 0x30,
- 0x04, 0x00, 0x40, 0x14, 0x01, 0x00, 0x62, 0x34, 0x2c, 0x00, 0x02, 0xae, 0x65,
- 0x1c, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xd0, 0x9a, 0x82, 0x8f, 0x64, 0x00,
- 0x04, 0x24, 0x2c, 0x00, 0x22, 0xae, 0xa8, 0x26, 0x00, 0x0c, 0x28, 0x00, 0x22,
- 0xae, 0x69, 0x25, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x02, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0xf0,
- 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x6c, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x20, 0x00, 0x25,
- 0x8e, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x88, 0x00, 0xa3, 0x30,
- 0x80, 0x00, 0x02, 0x24, 0x0e, 0x00, 0x62, 0x14, 0xff, 0x3f, 0x02, 0x3c, 0xd0,
- 0x9a, 0x83, 0x8f, 0x28, 0x00, 0x24, 0x8e, 0xff, 0xff, 0x42, 0x34, 0x23, 0x18,
- 0x64, 0x00, 0x2b, 0x10, 0x43, 0x00, 0x07, 0x00, 0x40, 0x14, 0x08, 0x00, 0xa2,
- 0x34, 0x20, 0x00, 0x22, 0xae, 0x2c, 0x00, 0x02, 0x8e, 0x21, 0x20, 0x00, 0x02,
- 0x01, 0x00, 0x42, 0x34, 0x65, 0x1c, 0x00, 0x0c, 0x2c, 0x00, 0x82, 0xac, 0xa8,
- 0x26, 0x00, 0x0c, 0x02, 0x00, 0x04, 0x24, 0x69, 0x25, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x00, 0x23, 0x8e, 0x38, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x09, 0x00, 0x62, 0x10, 0x00, 0xa0, 0x02, 0x3c, 0x60, 0x0d, 0x42, 0x34,
- 0x00, 0x00, 0x43, 0x8c, 0x20, 0x00, 0x24, 0x8e, 0x01, 0x00, 0x63, 0x24, 0x04,
- 0x00, 0x84, 0x34, 0x00, 0x00, 0x43, 0xac, 0x69, 0x25, 0x00, 0x08, 0x20, 0x00,
- 0x24, 0xae, 0xdf, 0x23, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x00, 0x00, 0x31,
- 0x8e, 0xd0, 0x9a, 0x87, 0x8f, 0x21, 0x30, 0x40, 0x00, 0x14, 0x00, 0x11, 0xae,
- 0x24, 0x00, 0x24, 0x8e, 0xf6, 0xff, 0xe3, 0x24, 0x54, 0x00, 0xc0, 0x10, 0x23,
- 0x20, 0x83, 0x00, 0x90, 0x00, 0x03, 0x8e, 0x94, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x33, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x02,
- 0x8e, 0x98, 0x00, 0x05, 0x8e, 0x23, 0x18, 0xe2, 0x00, 0xe8, 0x03, 0x62, 0x2c,
- 0x08, 0x00, 0x40, 0x10, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0xc0,
- 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x23, 0x28,
- 0xa2, 0x00, 0x03, 0x00, 0xa1, 0x04, 0x40, 0x10, 0x06, 0x00, 0x21, 0x28, 0x00,
- 0x00, 0x40, 0x10, 0x06, 0x00, 0x21, 0x10, 0x46, 0x00, 0x80, 0x19, 0x02, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x46, 0x00, 0x80,
- 0x10, 0x02, 0x00, 0x21, 0x10, 0x46, 0x00, 0x94, 0x00, 0x03, 0x8e, 0x40, 0x11,
- 0x02, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff, 0x01, 0x24, 0x04, 0x00, 0x61, 0x14,
- 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x06, 0x00, 0x12, 0x10, 0x00, 0x00, 0xeb, 0x51, 0x03, 0x3c, 0x1f, 0x85,
- 0x63, 0x34, 0x21, 0x28, 0xa2, 0x00, 0x18, 0x00, 0xa3, 0x00, 0x9c, 0x00, 0x07,
- 0xae, 0xc3, 0x1f, 0x05, 0x00, 0x98, 0x00, 0x05, 0xae, 0x10, 0x40, 0x00, 0x00,
- 0x43, 0x11, 0x08, 0x00, 0x23, 0x10, 0x43, 0x00, 0x9c, 0xff, 0x45, 0x24, 0x2a,
- 0x10, 0x85, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20,
- 0xa0, 0x00, 0x84, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x03,
- 0x00, 0x23, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x90, 0x00, 0x03, 0x8e, 0xc0, 0x10, 0x02, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x02,
- 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0xff, 0xff,
- 0x01, 0x24, 0x04, 0x00, 0x61, 0x14, 0x00, 0x80, 0x01, 0x3c, 0x02, 0x00, 0x41,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x12, 0x28, 0x00, 0x00,
- 0x78, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0xe2, 0x00, 0x23,
- 0x28, 0xa2, 0x00, 0xec, 0xff, 0xa5, 0x24, 0x2a, 0x10, 0x85, 0x00, 0x02, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0xa0, 0x00, 0x03, 0x00, 0x80,
- 0x18, 0x21, 0x10, 0x87, 0x00, 0x65, 0x25, 0x00, 0x08, 0x24, 0x00, 0x22, 0xae,
- 0x24, 0x00, 0x27, 0xae, 0x24, 0x00, 0x25, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x7e,
- 0x26, 0x00, 0x0c, 0xd0, 0x00, 0x04, 0x26, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00,
- 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x04, 0x00, 0x11, 0x8e, 0x00,
- 0xa0, 0x03, 0x3c, 0xc8, 0x00, 0x22, 0x8e, 0xe0, 0x0d, 0x63, 0x34, 0x01, 0x00,
- 0x42, 0x24, 0xc8, 0x00, 0x22, 0xae, 0x00, 0x00, 0x62, 0x8c, 0x20, 0x00, 0x04,
- 0x8e, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x03, 0x00, 0x82, 0x30,
- 0x0c, 0x00, 0x40, 0x14, 0x08, 0x00, 0x82, 0x34, 0x3c, 0x00, 0x03, 0x8e, 0x34,
- 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0xac, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0xf0, 0x06, 0x05,
- 0x24, 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x42, 0x34,
- 0x20, 0x00, 0x02, 0xae, 0x2c, 0x00, 0x22, 0x8e, 0x21, 0x20, 0x20, 0x02, 0x01,
- 0x00, 0x42, 0x34, 0x65, 0x1c, 0x00, 0x0c, 0x2c, 0x00, 0x82, 0xac, 0x18, 0x00,
- 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x20, 0x00, 0xbd, 0x27, 0xb8, 0xff, 0xbd, 0x27, 0x40, 0x00, 0xbf, 0xaf,
- 0x3c, 0x00, 0xb7, 0xaf, 0x38, 0x00, 0xb6, 0xaf, 0x34, 0x00, 0xb5, 0xaf, 0x30,
- 0x00, 0xb4, 0xaf, 0x2c, 0x00, 0xb3, 0xaf, 0x28, 0x00, 0xb2, 0xaf, 0x24, 0x00,
- 0xb1, 0xaf, 0xf8, 0x45, 0x00, 0x0c, 0x20, 0x00, 0xb0, 0xaf, 0x02, 0x80, 0x11,
- 0x3c, 0x70, 0xcc, 0x31, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x22, 0x2a,
- 0x03, 0x00, 0x40, 0x10, 0x5f, 0x00, 0x22, 0x26, 0x2c, 0x01, 0x11, 0x24, 0x5f,
- 0x00, 0x22, 0x26, 0xf0, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xb4, 0x9f,
- 0x82, 0xaf, 0x21, 0x88, 0x00, 0x00, 0xff, 0xff, 0x12, 0x3c, 0x01, 0x00, 0x13,
- 0x3c, 0x05, 0x00, 0x22, 0x2a, 0x16, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x60, 0x9e, 0x83, 0x8f, 0xb4, 0x9f, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x10, 0x65, 0x00, 0x26, 0x10, 0x62, 0x00, 0x24, 0x10, 0x52, 0x00, 0x03, 0x00,
- 0x40, 0x10, 0x21, 0x10, 0x73, 0x00, 0x24, 0x10, 0x52, 0x00, 0x60, 0x9e, 0x82,
- 0xaf, 0x60, 0x9e, 0x90, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x05, 0x02,
- 0x60, 0x9e, 0x85, 0xaf, 0xa5, 0x1d, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xf0,
- 0x9f, 0x82, 0x8f, 0x01, 0x00, 0x31, 0x26, 0xf0, 0x9f, 0x90, 0xaf, 0xaf, 0x25,
- 0x00, 0x08, 0x00, 0x00, 0x02, 0xae, 0x02, 0x80, 0x14, 0x3c, 0xf0, 0xcb, 0x94,
- 0x26, 0x64, 0x9f, 0x83, 0x8f, 0xc0, 0x9f, 0x91, 0xaf, 0x40, 0x00, 0x60, 0x18,
- 0x21, 0xa8, 0x00, 0x00, 0x01, 0x00, 0x16, 0x24, 0x09, 0x00, 0x17, 0x24, 0x68,
- 0x00, 0x92, 0x26, 0x0a, 0x00, 0x76, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x9f,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x05, 0x00, 0x41, 0x04, 0x83, 0x40, 0x02, 0x00, 0x03, 0x00, 0x42, 0x24,
- 0xdc, 0x25, 0x00, 0x08, 0x83, 0x40, 0x02, 0x00, 0xc0, 0x9f, 0x88, 0x8f, 0xd0,
- 0x00, 0x90, 0x26, 0x21, 0x20, 0x00, 0x02, 0x02, 0x00, 0x05, 0x24, 0x01, 0x80,
- 0x06, 0x3c, 0xd8, 0x92, 0xc6, 0x24, 0x21, 0x38, 0x80, 0x02, 0xa4, 0xff, 0x42,
- 0x8e, 0xa4, 0xff, 0x43, 0x8e, 0x21, 0x98, 0x00, 0x00, 0xfc, 0xff, 0x48, 0xae,
- 0xa8, 0xff, 0x42, 0xae, 0x35, 0x26, 0x00, 0x0c, 0xac, 0xff, 0x43, 0xae, 0x4f,
- 0x26, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x00, 0x00, 0x42, 0x8e, 0xa4, 0xff,
- 0x50, 0x8e, 0x17, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x11,
- 0x26, 0x54, 0x00, 0x04, 0x26, 0x21, 0x28, 0x00, 0x00, 0x01, 0x80, 0x06, 0x3c,
- 0x48, 0x8f, 0xc6, 0x24, 0x21, 0x38, 0x00, 0x02, 0xb4, 0xff, 0x37, 0xae, 0x35,
- 0x26, 0x00, 0x0c, 0xe4, 0xff, 0x36, 0xae, 0x21, 0x20, 0x20, 0x02, 0x03, 0x00,
- 0x05, 0x24, 0x01, 0x80, 0x06, 0x3c, 0xb8, 0x95, 0xc6, 0x24, 0x35, 0x26, 0x00,
- 0x0c, 0x21, 0x38, 0x00, 0x02, 0x01, 0x00, 0x73, 0x26, 0x84, 0x00, 0x31, 0x26,
- 0x00, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x62, 0x02, 0xec,
- 0xff, 0x40, 0x14, 0x84, 0x00, 0x10, 0x26, 0x01, 0x00, 0xb5, 0x26, 0x68, 0x01,
- 0x52, 0x26, 0x64, 0x9f, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0xa3,
- 0x02, 0xc5, 0xff, 0x40, 0x14, 0x68, 0x01, 0x94, 0x26, 0xb8, 0x9f, 0x82, 0x27,
- 0xe8, 0x9f, 0x82, 0xaf, 0xd0, 0x9f, 0x84, 0x27, 0x01, 0x00, 0x05, 0x24, 0x01,
- 0x80, 0x06, 0x3c, 0x0c, 0x8e, 0xc6, 0x24, 0x35, 0x26, 0x00, 0x0c, 0x21, 0x38,
- 0x00, 0x00, 0x40, 0x00, 0xbf, 0x8f, 0x3c, 0x00, 0xb7, 0x8f, 0x38, 0x00, 0xb6,
- 0x8f, 0x34, 0x00, 0xb5, 0x8f, 0x30, 0x00, 0xb4, 0x8f, 0x2c, 0x00, 0xb3, 0x8f,
- 0x28, 0x00, 0xb2, 0x8f, 0x24, 0x00, 0xb1, 0x8f, 0x20, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x48, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20,
- 0x00, 0x00, 0xd0, 0x9a, 0x82, 0x8f, 0x50, 0x9b, 0x83, 0x27, 0xff, 0xff, 0x42,
- 0x24, 0x00, 0xa0, 0x82, 0xaf, 0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x63, 0xac,
- 0x04, 0x00, 0x63, 0xac, 0x04, 0x00, 0x82, 0x28, 0xfb, 0xff, 0x40, 0x14, 0x08,
- 0x00, 0x63, 0x24, 0x21, 0x20, 0x00, 0x00, 0x40, 0x9c, 0x83, 0x27, 0x01, 0x00,
- 0x84, 0x24, 0x00, 0x00, 0x63, 0xac, 0x04, 0x00, 0x63, 0xac, 0x10, 0x00, 0x82,
- 0x28, 0xfb, 0xff, 0x40, 0x14, 0x08, 0x00, 0x63, 0x24, 0x08, 0x00, 0xe0, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0x3c, 0x9f, 0x84, 0x8f, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88,
- 0xa0, 0x00, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0xc0, 0x00, 0x1c, 0x00, 0xb3,
- 0xaf, 0x20, 0x00, 0xbf, 0xaf, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x98, 0xe0, 0x00,
- 0x21, 0x20, 0x40, 0x00, 0x00, 0x00, 0x10, 0xae, 0x04, 0x00, 0x10, 0xae, 0x10,
- 0x00, 0x11, 0xae, 0x08, 0x00, 0x12, 0xae, 0x3b, 0x12, 0x00, 0x0c, 0x0c, 0x00,
- 0x13, 0xae, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x28, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0x3c, 0x9f, 0x84, 0x8f, 0x14, 0x00, 0xbf, 0xaf, 0x32, 0x12,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9a, 0x85, 0x8f, 0x04, 0x00, 0x04,
- 0x8e, 0x00, 0x00, 0x03, 0x8e, 0x14, 0x00, 0x05, 0xae, 0x00, 0x00, 0x83, 0xac,
- 0x04, 0x00, 0x64, 0xac, 0x10, 0x00, 0x03, 0x8e, 0x50, 0x9b, 0x84, 0x27, 0xc0,
- 0x18, 0x03, 0x00, 0x21, 0x18, 0x64, 0x00, 0x04, 0x00, 0x65, 0x8c, 0x21, 0x20,
- 0x40, 0x00, 0x00, 0x00, 0xb0, 0xac, 0x04, 0x00, 0x05, 0xae, 0x00, 0x00, 0x03,
- 0xae, 0x3b, 0x12, 0x00, 0x0c, 0x04, 0x00, 0x70, 0xac, 0x14, 0x00, 0xbf, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xe8,
- 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x3c, 0x9f,
- 0x84, 0x8f, 0x14, 0x00, 0xbf, 0xaf, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x05, 0x8e, 0x00, 0x00, 0x03, 0x8e, 0x21, 0x20, 0x40, 0x00,
- 0x00, 0x00, 0xa3, 0xac, 0x04, 0x00, 0x65, 0xac, 0x04, 0x00, 0x10, 0xae, 0x3b,
- 0x12, 0x00, 0x0c, 0x00, 0x00, 0x10, 0xae, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00,
- 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd,
- 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x3c, 0x9f, 0x84, 0x8f,
- 0x14, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xbf, 0xaf, 0x32, 0x12, 0x00, 0x0c, 0x21,
- 0x88, 0xa0, 0x00, 0xff, 0x3f, 0x04, 0x3c, 0x04, 0x00, 0x05, 0x8e, 0x00, 0x00,
- 0x03, 0x8e, 0xff, 0xff, 0x84, 0x34, 0x00, 0x00, 0xa3, 0xac, 0x04, 0x00, 0x65,
- 0xac, 0xd0, 0x9a, 0x83, 0x8f, 0x21, 0x28, 0x40, 0x00, 0x23, 0x10, 0x71, 0x00,
- 0x2b, 0x20, 0x82, 0x00, 0x06, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x02, 0x8e, 0x14, 0x00, 0x03, 0xae, 0x50, 0x9b, 0x83, 0x27, 0x9b, 0x26,
- 0x00, 0x08, 0xc0, 0x10, 0x02, 0x00, 0x14, 0x00, 0x11, 0xae, 0x0f, 0x00, 0x22,
- 0x32, 0xc0, 0x10, 0x02, 0x00, 0x40, 0x9c, 0x83, 0x27, 0x21, 0x18, 0x43, 0x00,
- 0x04, 0x00, 0x62, 0x8c, 0x21, 0x20, 0xa0, 0x00, 0x00, 0x00, 0x50, 0xac, 0x04,
- 0x00, 0x02, 0xae, 0x00, 0x00, 0x03, 0xae, 0x3b, 0x12, 0x00, 0x0c, 0x04, 0x00,
- 0x70, 0xac, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27,
- 0x10, 0x00, 0xb0, 0xaf, 0x04, 0xa0, 0x90, 0x8f, 0x14, 0x00, 0xbf, 0xaf, 0x14,
- 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x44, 0x00, 0x3c, 0x9f,
- 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x14, 0x00, 0x02,
- 0xae, 0xff, 0x3f, 0x05, 0x3c, 0x04, 0x00, 0x04, 0x8e, 0x00, 0x00, 0x03, 0x8e,
- 0xd0, 0x9a, 0x86, 0x8f, 0xff, 0xff, 0xa5, 0x34, 0x00, 0x00, 0x83, 0xac, 0x04,
- 0x00, 0x64, 0xac, 0x14, 0x00, 0x03, 0x8e, 0x21, 0x20, 0x40, 0x00, 0x23, 0x10,
- 0xc3, 0x00, 0x2b, 0x28, 0xa2, 0x00, 0x06, 0x00, 0xa0, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x02, 0x8e, 0x50, 0x9b, 0x83, 0x27, 0x14, 0x00, 0x06, 0xae,
- 0xc8, 0x26, 0x00, 0x08, 0xc0, 0x10, 0x02, 0x00, 0x0f, 0x00, 0x62, 0x30, 0xc0,
- 0x10, 0x02, 0x00, 0x40, 0x9c, 0x83, 0x27, 0x21, 0x18, 0x43, 0x00, 0x04, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xac, 0x04, 0x00, 0x02,
- 0xae, 0x00, 0x00, 0x03, 0xae, 0x3b, 0x12, 0x00, 0x0c, 0x04, 0x00, 0x70, 0xac,
- 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18,
- 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xb3, 0xaf, 0x40, 0x9c,
- 0x93, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0xff, 0x7f, 0x11, 0x3c, 0xc8, 0x9d, 0x84,
- 0x8f, 0xff, 0xff, 0x31, 0x36, 0x18, 0x00, 0xb2, 0xaf, 0x50, 0x9b, 0x92, 0x27,
- 0x20, 0x00, 0xbf, 0xaf, 0x3b, 0x12, 0x00, 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0x3c,
- 0x9f, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x27,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x44, 0x24, 0x0f, 0x00, 0x82, 0x30, 0xc0, 0x10, 0x02, 0x00,
- 0x21, 0x30, 0x53, 0x00, 0x00, 0x00, 0xc3, 0x8c, 0x00, 0xa0, 0x84, 0xaf, 0x1c,
- 0x00, 0x66, 0x10, 0x21, 0x28, 0xc0, 0x00, 0x21, 0x38, 0x80, 0x00, 0x14, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0xe2, 0x00, 0x2b, 0x10, 0x22,
- 0x02, 0x10, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xac, 0x04, 0x00, 0x45, 0xac, 0x10,
- 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x21, 0x20,
- 0x52, 0x00, 0x04, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xac, 0x04, 0x00, 0x62, 0xac, 0x00, 0x00, 0x64, 0xac, 0x06, 0x27, 0x00, 0x08,
- 0x04, 0x00, 0x83, 0xac, 0x21, 0x28, 0x60, 0x00, 0x00, 0x00, 0xa3, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0xe7, 0xff, 0x66, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x83, 0x8f, 0xd0, 0x9a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xff, 0x62,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x50, 0x9b, 0x82, 0x8f, 0x50, 0x9b, 0x84, 0x27,
- 0x1c, 0x00, 0x44, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x68,
- 0xba, 0x42, 0x8c, 0x02, 0x80, 0x04, 0x3c, 0x68, 0xba, 0x84, 0x24, 0x16, 0x00,
- 0x44, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x70, 0xba, 0x42,
- 0x8c, 0x02, 0x80, 0x04, 0x3c, 0x70, 0xba, 0x84, 0x24, 0x10, 0x00, 0x44, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x78, 0xba, 0x42, 0x8c, 0x02,
- 0x80, 0x04, 0x3c, 0x78, 0xba, 0x84, 0x24, 0x0a, 0x00, 0x44, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0xc8, 0x9d, 0x84, 0x8f, 0x3b, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x84, 0x9f, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
- 0x84, 0x9f, 0x82, 0xaf, 0xe0, 0x26, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x83, 0x8c, 0xd0, 0x9a, 0x90, 0x8f, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x82, 0xac, 0x04, 0x00, 0x44, 0xac, 0x0c, 0x00, 0x64,
- 0x8c, 0x08, 0x00, 0x62, 0x8c, 0x04, 0xa0, 0x83, 0xaf, 0x00, 0x00, 0x63, 0xac,
- 0x09, 0xf8, 0x40, 0x00, 0x04, 0x00, 0x63, 0xac, 0xc8, 0x9d, 0x84, 0x8f, 0x3b,
- 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9a, 0x82, 0x8f, 0x04, 0xa0,
- 0x80, 0xaf, 0x23, 0x80, 0x50, 0x00, 0x32, 0x00, 0x04, 0x2e, 0x02, 0x00, 0x80,
- 0x14, 0x21, 0x10, 0x00, 0x02, 0x31, 0x00, 0x02, 0x24, 0x21, 0x18, 0x00, 0x02,
- 0x02, 0x80, 0x06, 0x3c, 0x50, 0xf3, 0xc6, 0x24, 0x80, 0x10, 0x02, 0x00, 0x02,
- 0x00, 0x80, 0x14, 0x21, 0x28, 0x46, 0x00, 0x31, 0x00, 0x03, 0x24, 0x80, 0x10,
- 0x03, 0x00, 0x21, 0x10, 0x46, 0x00, 0x00, 0x00, 0x42, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0xe0, 0x26, 0x00, 0x08, 0x00, 0x00, 0xa2, 0xac,
- 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00,
- 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x00, 0x00,
- 0x14, 0x00, 0xb1, 0xaf, 0x01, 0x80, 0x11, 0x3c, 0x70, 0x22, 0x31, 0x26, 0x1c,
- 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x00, 0x00, 0x10, 0xa0,
- 0x80, 0xaf, 0x21, 0x28, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, 0x01, 0x00, 0xa5,
- 0x24, 0x00, 0x00, 0x83, 0x94, 0x02, 0x00, 0x82, 0x90, 0x00, 0xa2, 0x01, 0x3c,
- 0x21, 0x08, 0x23, 0x00, 0x00, 0x00, 0x22, 0xa0, 0x04, 0x00, 0xa2, 0x28, 0x10,
- 0xa0, 0x80, 0xaf, 0xf7, 0xff, 0x40, 0x14, 0x04, 0x00, 0x84, 0x24, 0x00, 0x00,
- 0x82, 0x94, 0x00, 0xa2, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x00, 0x00, 0x22,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x08, 0x00, 0x40, 0x10,
- 0x64, 0x00, 0x02, 0x2a, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xc0,
- 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x47, 0x00, 0x05, 0x24, 0x65, 0x27,
- 0x00, 0x08, 0x01, 0x00, 0x10, 0x26, 0x05, 0x00, 0x52, 0x26, 0x0f, 0x00, 0x42,
- 0x2e, 0xe0, 0xff, 0x40, 0x14, 0x14, 0x00, 0x31, 0x26, 0x1c, 0x00, 0xbf, 0x8f,
- 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff,
- 0xbd, 0x27, 0x01, 0xa2, 0x02, 0x3c, 0x10, 0x00, 0x42, 0x34, 0x70, 0x00, 0x04,
- 0x3c, 0x38, 0xa0, 0x83, 0x8f, 0xff, 0x7f, 0x84, 0x34, 0x14, 0x00, 0xb1, 0xaf,
- 0x20, 0x00, 0xbf, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10,
- 0x00, 0xb0, 0xaf, 0x00, 0x00, 0x40, 0xa4, 0x40, 0x11, 0x03, 0x00, 0x23, 0x10,
- 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x28, 0xa0, 0x83,
- 0x8f, 0xc0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x62, 0x00, 0x2b, 0x20, 0x90, 0x00,
- 0x0c, 0x00, 0x80, 0x10, 0x00, 0xa2, 0x11, 0x3c, 0x8f, 0xff, 0x04, 0x3c, 0x00,
- 0x80, 0x84, 0x34, 0x70, 0x00, 0x03, 0x3c, 0xff, 0x7f, 0x63, 0x34, 0xd0, 0x9a,
- 0x82, 0x8f, 0x21, 0x80, 0x04, 0x02, 0x01, 0x00, 0x42, 0x24, 0xd0, 0x9a, 0x82,
- 0xaf, 0x2b, 0x10, 0x70, 0x00, 0xfa, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0xa0, 0x90, 0xaf, 0x00, 0xa0, 0x06, 0x3c, 0x14, 0x00, 0xc6, 0x34, 0xb7,
- 0x27, 0x00, 0x08, 0x80, 0x00, 0x07, 0x24, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0xc2, 0xac, 0x00, 0x00, 0xc2,
- 0x8c, 0x0c, 0x00, 0x27, 0xa2, 0x10, 0xa0, 0x80, 0xaf, 0x08, 0x00, 0x25, 0x92,
- 0x08, 0x00, 0x23, 0x92, 0x10, 0xa0, 0x80, 0xaf, 0x0c, 0x00, 0x27, 0xa2, 0x10,
- 0xa0, 0x80, 0xaf, 0x08, 0x00, 0x24, 0x92, 0x08, 0x00, 0x22, 0x92, 0x00, 0x1a,
- 0x03, 0x00, 0x25, 0x98, 0xa3, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x80, 0x82,
- 0x00, 0x23, 0x10, 0x70, 0x02, 0xff, 0xff, 0x50, 0x30, 0x80, 0x00, 0x02, 0x2e,
- 0xea, 0xff, 0x40, 0x10, 0x42, 0x10, 0x10, 0x00, 0x34, 0x0d, 0x00, 0x0c, 0x21,
- 0x98, 0x62, 0x02, 0x00, 0xa0, 0x06, 0x3c, 0x18, 0x00, 0xc6, 0x34, 0xd4, 0x27,
- 0x00, 0x08, 0x80, 0x00, 0x07, 0x24, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0xc2, 0xac, 0x00, 0x00, 0xc2, 0x8c,
- 0x0c, 0x00, 0x27, 0xa2, 0x10, 0xa0, 0x80, 0xaf, 0x08, 0x00, 0x25, 0x92, 0x08,
- 0x00, 0x23, 0x92, 0x10, 0xa0, 0x80, 0xaf, 0x0c, 0x00, 0x27, 0xa2, 0x10, 0xa0,
- 0x80, 0xaf, 0x08, 0x00, 0x24, 0x92, 0x08, 0x00, 0x22, 0x92, 0x00, 0x1a, 0x03,
- 0x00, 0x25, 0x90, 0xa3, 0x00, 0x00, 0x12, 0x02, 0x00, 0x25, 0x80, 0x82, 0x00,
- 0x23, 0x10, 0x50, 0x02, 0xff, 0xff, 0x50, 0x30, 0x80, 0x00, 0x02, 0x2e, 0xea,
- 0xff, 0x40, 0x10, 0x42, 0x10, 0x10, 0x00, 0x21, 0x90, 0x42, 0x02, 0x23, 0x18,
- 0x72, 0x02, 0xff, 0xff, 0x70, 0x30, 0x24, 0xa0, 0x82, 0x8f, 0x20, 0xa0, 0x83,
- 0x8f, 0xd0, 0x89, 0x84, 0x8f, 0x23, 0x10, 0x02, 0x02, 0x21, 0x18, 0x62, 0x00,
- 0x18, 0x00, 0x83, 0x00, 0x12, 0x40, 0x00, 0x00, 0xd4, 0x89, 0x82, 0x8f, 0x82,
- 0x21, 0x08, 0x00, 0x18, 0x00, 0x44, 0x00, 0x20, 0xa0, 0x83, 0xaf, 0xd8, 0x89,
- 0x83, 0x8f, 0xdc, 0x89, 0x82, 0x8f, 0x24, 0xa0, 0x84, 0xaf, 0x00, 0x11, 0x02,
- 0x00, 0x12, 0x40, 0x00, 0x00, 0x02, 0x21, 0x08, 0x00, 0x21, 0x80, 0x83, 0x00,
- 0x01, 0x00, 0x43, 0x24, 0x2b, 0x10, 0x03, 0x02, 0x3c, 0xa0, 0x90, 0xaf, 0x02,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x60, 0x00, 0x38, 0xa0,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x50, 0x10, 0x02, 0x12, 0x10,
- 0x00, 0x00, 0x00, 0x30, 0xa2, 0x38, 0xa0, 0x90, 0xaf, 0x00, 0x00, 0x22, 0xa2,
- 0xe0, 0x89, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x30, 0xa0, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00,
- 0x60, 0x10, 0x23, 0x18, 0x73, 0x00, 0x2c, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0x2c, 0xa0, 0x82, 0xaf, 0xe8, 0x03, 0x42, 0x28,
- 0x0a, 0x00, 0x40, 0x14, 0xff, 0xff, 0x70, 0x30, 0xe4, 0x89, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x2b, 0x10, 0x50, 0x00, 0x06, 0x00, 0x40, 0x10, 0x80, 0x10,
- 0x10, 0x00, 0xe8, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x40, 0x01, 0x05,
- 0x24, 0x2c, 0xa0, 0x80, 0xaf, 0x80, 0x10, 0x10, 0x00, 0x21, 0x10, 0x50, 0x00,
- 0x00, 0x11, 0x02, 0x00, 0x23, 0x10, 0x50, 0x00, 0xc0, 0x18, 0x02, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x02, 0x85, 0x02, 0x00, 0x64, 0x00,
- 0x02, 0x2e, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x10,
- 0x24, 0x02, 0x80, 0x02, 0x3c, 0x20, 0xf4, 0x42, 0x24, 0x80, 0x18, 0x10, 0x00,
- 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x30, 0xa0, 0x93, 0xaf, 0x23, 0x10,
- 0x72, 0x02, 0xff, 0xff, 0x50, 0x30, 0x80, 0x10, 0x10, 0x00, 0x21, 0x10, 0x50,
- 0x00, 0x00, 0x11, 0x02, 0x00, 0x23, 0x10, 0x50, 0x00, 0xc0, 0x18, 0x02, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0xc0, 0x10, 0x02, 0x00, 0x02, 0x85, 0x02, 0x00, 0x64,
- 0x00, 0x02, 0x2e, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00,
- 0x10, 0x24, 0x02, 0x80, 0x02, 0x3c, 0xb0, 0xf5, 0x42, 0x24, 0x80, 0x18, 0x10,
- 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x34, 0xa0, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x24, 0x05, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x28, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0xe8, 0x89, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0xbf, 0x01, 0x05, 0x24, 0x34,
- 0xa0, 0x80, 0xaf, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00,
- 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x28, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x83, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x1e,
- 0x00, 0x62, 0x28, 0x0d, 0x00, 0x40, 0x14, 0x21, 0x10, 0x00, 0x00, 0x3c, 0x00,
- 0x62, 0x28, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x82,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x75, 0x28, 0x00, 0x08,
- 0x01, 0x00, 0x42, 0x24, 0x48, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x42, 0x30, 0x03, 0x00, 0x42, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80,
- 0x00, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x24, 0x00, 0x11, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
- 0x03, 0x96, 0x21, 0x28, 0x40, 0x00, 0x01, 0x00, 0x62, 0x30, 0x19, 0x00, 0x40,
- 0x14, 0x01, 0x00, 0x63, 0x34, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x42, 0x30, 0x06, 0x00, 0x40, 0x10, 0x50, 0x00, 0x03, 0xa6, 0x00,
- 0x02, 0x62, 0x38, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xdc, 0x35,
- 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x5f, 0x00, 0x02, 0x92, 0x68, 0x00, 0x03,
- 0x92, 0x03, 0x00, 0x42, 0x30, 0x27, 0x10, 0x02, 0x00, 0x24, 0x18, 0x62, 0x00,
- 0x10, 0x00, 0x23, 0xa2, 0x54, 0x00, 0x02, 0x92, 0x58, 0x00, 0x04, 0x92, 0x26,
- 0x18, 0x43, 0x00, 0x03, 0x00, 0x63, 0x30, 0x26, 0x10, 0x43, 0x00, 0x25, 0x20,
- 0x83, 0x00, 0x54, 0x00, 0x02, 0xa2, 0x58, 0x00, 0x04, 0xa2, 0x3b, 0x12, 0x00,
- 0x0c, 0x21, 0x20, 0xa0, 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0,
- 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x18, 0x00,
- 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x24, 0x00, 0x11, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x22, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x9a, 0x84, 0x8f,
- 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x03, 0x96, 0x21,
- 0x28, 0x40, 0x00, 0x01, 0x00, 0x62, 0x30, 0x18, 0x00, 0x40, 0x10, 0xfe, 0xff,
- 0x63, 0x30, 0x28, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42,
- 0x30, 0x06, 0x00, 0x40, 0x10, 0x50, 0x00, 0x03, 0xa6, 0x00, 0x02, 0x62, 0x38,
- 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xdc, 0x35, 0x42, 0x24, 0x04,
- 0x00, 0x02, 0xae, 0x5f, 0x00, 0x03, 0x92, 0x68, 0x00, 0x02, 0x92, 0x03, 0x00,
- 0x63, 0x30, 0x25, 0x10, 0x43, 0x00, 0x10, 0x00, 0x22, 0xa2, 0x54, 0x00, 0x03,
- 0x92, 0x58, 0x00, 0x04, 0x92, 0x26, 0x10, 0x62, 0x00, 0x03, 0x00, 0x42, 0x30,
- 0x26, 0x18, 0x62, 0x00, 0x25, 0x20, 0x82, 0x00, 0x54, 0x00, 0x03, 0xa2, 0x58,
- 0x00, 0x04, 0xa2, 0x3b, 0x12, 0x00, 0x0c, 0x21, 0x20, 0xa0, 0x00, 0x18, 0x00,
- 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf,
- 0x21, 0x80, 0x80, 0x00, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14,
- 0x00, 0xb1, 0xaf, 0x24, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00,
- 0x40, 0x10, 0x21, 0x90, 0xa0, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0x02, 0x00, 0x07, 0x24,
- 0x30, 0x00, 0x43, 0x32, 0x02, 0x31, 0x03, 0x00, 0x05, 0x00, 0xc8, 0x24, 0x01,
- 0x00, 0x03, 0x24, 0x04, 0x18, 0x03, 0x01, 0xff, 0xff, 0x65, 0x24, 0x28, 0x00,
- 0x03, 0x96, 0x21, 0x20, 0x40, 0x00, 0x20, 0x00, 0x63, 0x30, 0x02, 0x00, 0x60,
- 0x10, 0x62, 0x00, 0x05, 0xa2, 0x7f, 0x00, 0xa5, 0x30, 0x6a, 0x00, 0x02, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x30, 0x25, 0x10, 0x45, 0x00, 0x6a,
- 0x00, 0x02, 0xa6, 0x00, 0x01, 0x42, 0x32, 0x05, 0x00, 0x40, 0x10, 0x00, 0x02,
- 0x42, 0x32, 0x02, 0x00, 0x40, 0x14, 0x08, 0x00, 0xc6, 0x34, 0x10, 0x00, 0xc6,
- 0x34, 0x03, 0x00, 0x07, 0x24, 0x40, 0x00, 0x42, 0x32, 0x03, 0x00, 0x40, 0x10,
- 0x0f, 0x00, 0x42, 0x32, 0x04, 0x00, 0xc6, 0x34, 0x01, 0x00, 0xe7, 0x24, 0x40,
- 0x28, 0x02, 0x00, 0x00, 0x04, 0x42, 0x32, 0x12, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x65, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03, 0x3c, 0x21, 0x18, 0x62, 0x00, 0x88,
- 0xcd, 0x63, 0x8c, 0x03, 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x80, 0x02, 0x3c, 0xd0, 0x22, 0x42, 0x24, 0x1a, 0x29, 0x00,
- 0x08, 0x21, 0x18, 0xa2, 0x00, 0x01, 0x80, 0x02, 0x3c, 0xb0, 0x22, 0x42, 0x24,
- 0x21, 0x18, 0xa2, 0x00, 0x0c, 0x00, 0x22, 0x92, 0x00, 0x00, 0x63, 0x94, 0x80,
- 0x00, 0x42, 0x34, 0x0c, 0x00, 0x22, 0xa2, 0x21, 0x10, 0x07, 0x01, 0x18, 0x00,
- 0x62, 0x00, 0x7f, 0x00, 0x02, 0x24, 0x04, 0x00, 0x22, 0xa2, 0x00, 0x00, 0x23,
- 0xa2, 0x03, 0x1a, 0x03, 0x00, 0x04, 0x00, 0x23, 0xa2, 0x0c, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0x21, 0x10, 0x46, 0x00, 0x0c,
- 0x00, 0x22, 0xa2, 0x2c, 0x00, 0x12, 0xa6, 0x12, 0x48, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x12, 0x00, 0x0c, 0x40, 0x00, 0x09,
- 0xae, 0x64, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x21, 0x20, 0x00, 0x02,
- 0x56, 0x1f, 0x00, 0x0c, 0x21, 0x28, 0x40, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18,
- 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x80, 0x80, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x14, 0x00, 0xb1, 0xaf,
- 0x18, 0x00, 0xbf, 0xaf, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x88, 0xa0, 0x00, 0x28,
- 0x00, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x26, 0x18, 0x23, 0x02, 0x00, 0x10,
- 0x63, 0x30, 0x0a, 0x00, 0x60, 0x10, 0x21, 0x20, 0x40, 0x00, 0x50, 0x00, 0x03,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, 0x05, 0x00, 0x40, 0x10,
- 0x00, 0x02, 0x62, 0x34, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c, 0xdc,
- 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x62, 0x00, 0x03, 0x92, 0x20, 0x00,
- 0x22, 0x32, 0x02, 0x00, 0x40, 0x10, 0x10, 0x00, 0x22, 0x32, 0x7f, 0x00, 0x63,
- 0x30, 0x02, 0x00, 0x40, 0x10, 0x00, 0x1a, 0x63, 0x34, 0x00, 0x04, 0x63, 0x34,
- 0x50, 0x00, 0x02, 0x96, 0x6a, 0x00, 0x03, 0xa6, 0xfb, 0x3f, 0x43, 0x30, 0x00,
- 0x04, 0x22, 0x32, 0x09, 0x00, 0x40, 0x10, 0x00, 0x20, 0x22, 0x32, 0x02, 0x00,
- 0x40, 0x10, 0x00, 0x80, 0x63, 0x34, 0x00, 0x40, 0x63, 0x34, 0x00, 0x08, 0x22,
- 0x32, 0x04, 0x00, 0x40, 0x10, 0xff, 0xef, 0x02, 0x24, 0x6a, 0x29, 0x00, 0x08,
- 0x04, 0x00, 0x63, 0x34, 0xff, 0xe7, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00, 0x50,
- 0x00, 0x03, 0xa6, 0x3b, 0x12, 0x00, 0x0c, 0x28, 0x00, 0x11, 0xa6, 0x18, 0x00,
- 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf,
- 0x21, 0x80, 0x80, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x14, 0x00, 0xb1, 0xaf, 0x18,
- 0x00, 0xbf, 0xaf, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x88, 0xa0, 0x00, 0x21, 0x20,
- 0x40, 0x00, 0x7f, 0xff, 0x02, 0x24, 0x24, 0x10, 0x22, 0x02, 0x0b, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x63,
- 0x00, 0x00, 0xa2, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x29,
- 0x00, 0x08, 0x80, 0x00, 0x42, 0x34, 0x50, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00,
- 0x00, 0x7f, 0xff, 0x42, 0x30, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x80, 0x02, 0x3c,
- 0xdc, 0x35, 0x42, 0x24, 0x04, 0x00, 0x02, 0xae, 0x80, 0x00, 0x22, 0x32, 0x03,
- 0x00, 0x40, 0x10, 0x7f, 0x00, 0x02, 0x24, 0x96, 0x29, 0x00, 0x08, 0x60, 0x00,
- 0x02, 0xa2, 0x60, 0x00, 0x00, 0xa2, 0x3b, 0x12, 0x00, 0x0c, 0x2a, 0x00, 0x11,
- 0xa6, 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10,
- 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x14, 0x00,
- 0xb1, 0xaf, 0x18, 0x00, 0xbf, 0xaf, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x88, 0xa0,
- 0x00, 0x21, 0x20, 0x40, 0x00, 0x6c, 0x00, 0x03, 0x8e, 0xff, 0xff, 0x02, 0x24,
- 0x08, 0x00, 0x62, 0x14, 0xff, 0xff, 0x02, 0x34, 0x06, 0x00, 0x22, 0x12, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x02, 0x96, 0x6c, 0x00, 0x00, 0xae, 0xff, 0xfe,
- 0x42, 0x30, 0xc2, 0x29, 0x00, 0x08, 0x50, 0x00, 0x02, 0xa6, 0x50, 0x00, 0x02,
- 0x96, 0x00, 0x80, 0x03, 0x3c, 0xdc, 0x35, 0x63, 0x24, 0x04, 0x00, 0x03, 0xae,
- 0x00, 0x01, 0x42, 0x34, 0x50, 0x00, 0x02, 0xa6, 0xff, 0xff, 0x02, 0x34, 0x07,
- 0x00, 0x22, 0x12, 0xc0, 0x10, 0x11, 0x00, 0x21, 0x10, 0x51, 0x00, 0x6c, 0x00,
- 0x03, 0x8e, 0x40, 0x12, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0xc2, 0x29, 0x00,
- 0x08, 0x6c, 0x00, 0x03, 0xae, 0xff, 0xff, 0x02, 0x24, 0x6c, 0x00, 0x02, 0xae,
- 0x3b, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xbf, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80,
- 0x00, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10, 0x00, 0xb0, 0xaf,
- 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x40, 0x10, 0x21,
- 0x80, 0xa0, 0x00, 0x21, 0x90, 0x40, 0x00, 0x10, 0x00, 0x02, 0x32, 0x03, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x29, 0x00, 0x08, 0x1f, 0x00, 0x10,
- 0x32, 0x03, 0x00, 0x10, 0x32, 0x08, 0x00, 0x10, 0x36, 0xd4, 0x9a, 0x84, 0x8f,
- 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x23, 0x96, 0x21,
- 0x20, 0x40, 0x00, 0x01, 0x00, 0x63, 0x30, 0x07, 0x00, 0x60, 0x10, 0x68, 0x00,
- 0x30, 0xa2, 0x5f, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42,
- 0x30, 0x27, 0x10, 0x02, 0x00, 0xed, 0x29, 0x00, 0x08, 0x24, 0x80, 0x02, 0x02,
- 0x5f, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x30, 0x25,
- 0x80, 0x02, 0x02, 0x10, 0x00, 0x50, 0xa2, 0x54, 0x00, 0x22, 0x92, 0x58, 0x00,
- 0x25, 0x92, 0x26, 0x18, 0x50, 0x00, 0x03, 0x00, 0x63, 0x30, 0x26, 0x10, 0x43,
- 0x00, 0x25, 0x28, 0xa3, 0x00, 0x54, 0x00, 0x22, 0xa2, 0x3b, 0x12, 0x00, 0x0c,
- 0x58, 0x00, 0x25, 0xa2, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80,
- 0x00, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x10, 0x00, 0xb0, 0xaf,
- 0x24, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x40, 0x10, 0x21,
- 0x80, 0xa0, 0x00, 0xf3, 0x00, 0x10, 0x32, 0xd4, 0x9a, 0x84, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x90, 0x40, 0x00, 0x4a, 0x00, 0x23,
- 0x92, 0xf0, 0x00, 0x04, 0x32, 0x5f, 0x00, 0x30, 0xa2, 0x49, 0x00, 0x24, 0xa2,
- 0x0f, 0x00, 0x63, 0x30, 0x25, 0x20, 0x83, 0x00, 0x50, 0x00, 0x23, 0x96, 0x03,
- 0x00, 0x10, 0x32, 0x4a, 0x00, 0x24, 0xa2, 0x01, 0x00, 0x63, 0x30, 0x05, 0x00,
- 0x60, 0x10, 0x21, 0x20, 0x40, 0x00, 0x68, 0x00, 0x23, 0x92, 0x27, 0x10, 0x10,
- 0x00, 0x1f, 0x2a, 0x00, 0x08, 0x24, 0x80, 0x43, 0x00, 0x68, 0x00, 0x22, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x80, 0x02, 0x02, 0x10, 0x00, 0x50, 0xa2, 0x54,
- 0x00, 0x22, 0x92, 0x58, 0x00, 0x25, 0x92, 0x26, 0x18, 0x50, 0x00, 0x03, 0x00,
- 0x63, 0x30, 0x26, 0x10, 0x43, 0x00, 0x25, 0x28, 0xa3, 0x00, 0x54, 0x00, 0x22,
- 0xa2, 0x3b, 0x12, 0x00, 0x0c, 0x58, 0x00, 0x25, 0xa2, 0x1c, 0x00, 0xbf, 0x8f,
- 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00,
- 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x18, 0x00, 0xbf,
- 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x24, 0x00, 0x11, 0x8e, 0x32, 0x12, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x34, 0x1c, 0x00, 0x03, 0xa6, 0x3f,
- 0x00, 0x03, 0x24, 0x2c, 0x00, 0x03, 0xa6, 0x78, 0x00, 0x03, 0x24, 0x40, 0x00,
- 0x03, 0xae, 0x10, 0x00, 0x03, 0x24, 0x50, 0x00, 0x03, 0xa6, 0x11, 0x00, 0x03,
- 0x24, 0x5c, 0x00, 0x03, 0xa2, 0x13, 0x00, 0x03, 0x24, 0x5d, 0x00, 0x03, 0xa2,
- 0xff, 0x00, 0x03, 0x24, 0x62, 0x00, 0x03, 0xa2, 0xff, 0x0a, 0x03, 0x24, 0x0a,
- 0x00, 0x00, 0xa6, 0x0c, 0x00, 0x00, 0xa6, 0x12, 0x00, 0x00, 0xa6, 0x14, 0x00,
- 0x00, 0xa6, 0x18, 0x00, 0x00, 0xa6, 0x1a, 0x00, 0x00, 0xa6, 0x28, 0x00, 0x00,
- 0xa6, 0x2a, 0x00, 0x00, 0xa6, 0x44, 0x00, 0x00, 0xae, 0x49, 0x00, 0x00, 0xa2,
- 0x4a, 0x00, 0x00, 0xa2, 0x54, 0x00, 0x00, 0xa2, 0x57, 0x00, 0x00, 0xa2, 0x58,
- 0x00, 0x00, 0xa2, 0x5a, 0x00, 0x00, 0xa2, 0x5b, 0x00, 0x00, 0xa2, 0x5e, 0x00,
- 0x00, 0xa2, 0x5f, 0x00, 0x00, 0xa2, 0x60, 0x00, 0x00, 0xa2, 0x61, 0x00, 0x00,
- 0xa2, 0x63, 0x00, 0x00, 0xa2, 0x64, 0x00, 0x00, 0xa2, 0x66, 0x00, 0x00, 0xa2,
- 0x67, 0x00, 0x00, 0xa2, 0x68, 0x00, 0x00, 0xa2, 0x69, 0x00, 0x00, 0xa2, 0x6a,
- 0x00, 0x03, 0xa6, 0x00, 0x80, 0x03, 0x3c, 0xdc, 0x35, 0x63, 0x24, 0x04, 0x00,
- 0x03, 0xae, 0x00, 0x80, 0x03, 0x3c, 0x6c, 0x3e, 0x63, 0x24, 0x74, 0x00, 0x03,
- 0xae, 0x00, 0x80, 0x03, 0x3c, 0xa8, 0x3a, 0x63, 0x24, 0x34, 0x00, 0x03, 0xae,
- 0x24, 0x00, 0x03, 0x8e, 0x21, 0x20, 0x40, 0x00, 0x13, 0x00, 0x60, 0x10, 0x6c,
- 0x00, 0x00, 0xae, 0x80, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x22, 0xa2, 0x0c, 0x00,
- 0x02, 0x24, 0x00, 0x00, 0x22, 0xa2, 0x03, 0x00, 0x02, 0x24, 0x01, 0x00, 0x03,
- 0x24, 0x04, 0x00, 0x20, 0xa2, 0x0c, 0x00, 0x22, 0xa2, 0x0f, 0x00, 0x02, 0x24,
- 0x08, 0x00, 0x23, 0xa2, 0x08, 0x00, 0x22, 0xa2, 0x08, 0x00, 0x02, 0x24, 0x04,
- 0x00, 0x23, 0xa2, 0x10, 0x00, 0x22, 0xa2, 0x08, 0x00, 0x22, 0x92, 0x00, 0x00,
- 0x22, 0x92, 0x14, 0x00, 0x22, 0x92, 0x18, 0x00, 0x22, 0x92, 0x3b, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0x21, 0x20, 0x00, 0x02, 0x56, 0x1f, 0x00, 0x0c, 0x21, 0x28, 0x40, 0x00, 0x18,
- 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0,
- 0xaf, 0x21, 0x80, 0x80, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x60, 0xcd, 0x42, 0x24,
- 0x23, 0x28, 0xa2, 0x00, 0x40, 0x19, 0x05, 0x00, 0x23, 0x18, 0x65, 0x00, 0x40,
- 0x19, 0x03, 0x00, 0x21, 0x18, 0x65, 0x00, 0xc0, 0x10, 0x03, 0x00, 0x21, 0x18,
- 0x62, 0x00, 0xc0, 0x13, 0x03, 0x00, 0x23, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02,
- 0x00, 0x21, 0x10, 0x45, 0x00, 0x23, 0x10, 0x02, 0x00, 0x83, 0x10, 0x02, 0x00,
- 0x14, 0x00, 0xbf, 0xaf, 0x65, 0x00, 0x02, 0xa2, 0x02, 0x00, 0x02, 0x24, 0x48,
- 0x00, 0x06, 0xa2, 0x2f, 0x2a, 0x00, 0x0c, 0x2e, 0x00, 0x02, 0xa6, 0x4c, 0x9b,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0xaf, 0x2a, 0x00, 0x08, 0x30, 0x00, 0x10, 0xae, 0x30, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0xae, 0x30, 0x00, 0x70, 0xac, 0x4c,
- 0x9b, 0x90, 0xaf, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0x10, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x85,
- 0xac, 0x04, 0x00, 0x86, 0xac, 0x08, 0x00, 0x87, 0xac, 0x08, 0x00, 0xe0, 0x03,
- 0x0c, 0x00, 0x82, 0xac, 0x21, 0x50, 0x00, 0x00, 0x21, 0x58, 0x00, 0x00, 0x21,
- 0x48, 0x00, 0x00, 0x21, 0x18, 0x00, 0x00, 0x21, 0x68, 0x00, 0x00, 0x00, 0x00,
- 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0x42, 0x24, 0x08, 0x00, 0x42,
- 0x2c, 0x0b, 0x00, 0x40, 0x14, 0x21, 0x60, 0x00, 0x00, 0x21, 0x38, 0x80, 0x00,
- 0x10, 0x00, 0x62, 0x2c, 0x3b, 0x00, 0x40, 0x10, 0x01, 0x00, 0xe7, 0x24, 0x00,
- 0x00, 0xe2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0x42, 0x24, 0x08, 0x00,
- 0x42, 0x2c, 0xf8, 0xff, 0x40, 0x10, 0x01, 0x00, 0x63, 0x24, 0x10, 0x00, 0x62,
- 0x2c, 0x33, 0x00, 0x40, 0x10, 0xff, 0xff, 0x02, 0x24, 0x14, 0x00, 0x20, 0x15,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, 0x64, 0x00, 0x00, 0x00, 0x07, 0x91, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xff, 0xe2, 0x24, 0x0a, 0x00, 0x42, 0x2c, 0x0d, 0x00,
- 0x40, 0x10, 0x80, 0x10, 0x0a, 0x00, 0x01, 0x00, 0x0d, 0x24, 0x21, 0x10, 0x4a,
- 0x00, 0x40, 0x10, 0x02, 0x00, 0xd0, 0xff, 0x42, 0x24, 0x21, 0x50, 0xe2, 0x00,
- 0x01, 0x00, 0x63, 0x24, 0x10, 0x00, 0x62, 0x2c, 0x02, 0x00, 0x40, 0x14, 0x01,
- 0x00, 0x08, 0x25, 0x01, 0x00, 0x09, 0x24, 0xef, 0xff, 0x20, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x10, 0x00, 0x62, 0x2c, 0x19, 0x00, 0x40,
- 0x10, 0x21, 0x48, 0x00, 0x00, 0x21, 0x20, 0x64, 0x00, 0x00, 0x00, 0x87, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xe2, 0x24, 0x0a, 0x00, 0x42, 0x2c, 0x0d,
- 0x00, 0x40, 0x10, 0x80, 0x10, 0x0b, 0x00, 0x01, 0x00, 0x0c, 0x24, 0x21, 0x10,
- 0x4b, 0x00, 0x40, 0x10, 0x02, 0x00, 0xd0, 0xff, 0x42, 0x24, 0x21, 0x58, 0xe2,
- 0x00, 0x01, 0x00, 0x63, 0x24, 0x10, 0x00, 0x62, 0x2c, 0x02, 0x00, 0x40, 0x14,
- 0x01, 0x00, 0x84, 0x24, 0x01, 0x00, 0x09, 0x24, 0xef, 0xff, 0x20, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xac, 0x03, 0x00, 0x80, 0x11, 0x00, 0x00,
- 0xcb, 0xac, 0x02, 0x00, 0xa0, 0x15, 0x21, 0x10, 0x00, 0x00, 0xff, 0xff, 0x02,
- 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xbd, 0x27,
- 0x01, 0xa2, 0x02, 0x3c, 0x1c, 0x00, 0x42, 0x34, 0x1c, 0x00, 0xb1, 0xaf, 0x21,
- 0x88, 0x80, 0x00, 0x18, 0x00, 0xb0, 0xaf, 0x18, 0x00, 0x30, 0x26, 0x20, 0x00,
- 0xbf, 0xaf, 0x00, 0x00, 0x46, 0x90, 0x03, 0x00, 0x02, 0x24, 0x14, 0x00, 0x22,
- 0xae, 0x01, 0x00, 0x02, 0x24, 0x00, 0x8a, 0x84, 0x27, 0x10, 0x00, 0x25, 0xae,
- 0x10, 0x00, 0xa5, 0x27, 0x18, 0x00, 0x22, 0xae, 0x04, 0x00, 0x00, 0xae, 0x10,
- 0x00, 0xa0, 0xaf, 0x14, 0x00, 0xa0, 0xaf, 0x0f, 0x00, 0xc2, 0x30, 0x08, 0x00,
- 0x02, 0xae, 0x02, 0x11, 0x06, 0x00, 0x14, 0x00, 0xa6, 0x27, 0xba, 0x2a, 0x00,
- 0x0c, 0x0c, 0x00, 0x02, 0xae, 0xff, 0xff, 0x03, 0x24, 0x04, 0x00, 0x43, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xae, 0x29, 0x2b, 0x00, 0x08, 0x14,
- 0x00, 0x00, 0xae, 0x10, 0x00, 0xa2, 0x8f, 0x14, 0x00, 0xa3, 0x8f, 0x10, 0x00,
- 0x02, 0xae, 0x14, 0x00, 0x03, 0xae, 0x18, 0x00, 0x10, 0x26, 0x00, 0xa2, 0x05,
- 0x3c, 0x00, 0x80, 0xa5, 0x34, 0x02, 0xa2, 0x03, 0x3c, 0x08, 0x00, 0x63, 0x34,
- 0x02, 0xa2, 0x04, 0x3c, 0x04, 0x00, 0x84, 0x34, 0x21, 0x38, 0x00, 0x00, 0x04,
- 0x00, 0x0a, 0x24, 0x01, 0xa2, 0x09, 0x3c, 0x04, 0x13, 0x29, 0x35, 0x01, 0xa2,
- 0x08, 0x3c, 0x00, 0x00, 0xa6, 0x90, 0x02, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02,
- 0xae, 0x01, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0xae, 0x10, 0x00, 0x00, 0xae,
- 0x14, 0x00, 0x00, 0xae, 0x0c, 0x00, 0x00, 0xae, 0x42, 0x11, 0x06, 0x00, 0x08,
- 0x00, 0x02, 0xae, 0x18, 0x00, 0x10, 0x26, 0x00, 0x00, 0x66, 0x90, 0x03, 0x00,
- 0x02, 0x24, 0x00, 0x00, 0x02, 0xae, 0x07, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02,
- 0xae, 0x00, 0x00, 0x83, 0x90, 0x50, 0xa0, 0x84, 0x8f, 0x0f, 0x00, 0xc2, 0x30,
- 0x0c, 0x00, 0x02, 0xae, 0x08, 0x00, 0x03, 0xae, 0x34, 0x00, 0x82, 0x90, 0x00,
- 0x13, 0x08, 0x35, 0x10, 0x00, 0x02, 0xae, 0x38, 0x00, 0x82, 0x90, 0x00, 0x00,
- 0xa6, 0x90, 0x14, 0x00, 0x04, 0x26, 0x14, 0x00, 0x02, 0xae, 0x14, 0x00, 0x25,
- 0x92, 0x01, 0x00, 0xc2, 0x30, 0x11, 0x00, 0x40, 0x14, 0xff, 0x00, 0xe3, 0x30,
- 0x18, 0x00, 0x84, 0x24, 0x18, 0x00, 0x10, 0x26, 0x02, 0x00, 0x62, 0x24, 0x40,
- 0x1a, 0x03, 0x00, 0x00, 0x00, 0x0a, 0xae, 0xf0, 0xff, 0x82, 0xac, 0x21, 0x10,
- 0x69, 0x00, 0x00, 0x00, 0x42, 0x90, 0x21, 0x18, 0x68, 0x00, 0x0f, 0x00, 0x42,
- 0x30, 0xf8, 0xff, 0x82, 0xac, 0x00, 0x00, 0x62, 0x90, 0x01, 0x00, 0xa5, 0x24,
- 0xfc, 0xff, 0x80, 0xac, 0x00, 0x00, 0x80, 0xac, 0xf4, 0xff, 0x82, 0xac, 0x01,
- 0x00, 0xe7, 0x24, 0xff, 0x00, 0xe2, 0x30, 0x05, 0x00, 0x42, 0x2c, 0xe9, 0xff,
- 0x40, 0x14, 0x42, 0x30, 0x06, 0x00, 0xff, 0x00, 0xa2, 0x30, 0x14, 0x00, 0x22,
- 0xae, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0x00, 0xa2, 0x02, 0x3c, 0x00,
- 0x80, 0x42, 0x34, 0x00, 0x00, 0x42, 0x90, 0x10, 0x00, 0x85, 0xac, 0x42, 0x11,
- 0x02, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x14, 0x00, 0x82, 0xac, 0x18, 0x00, 0xc2,
- 0x2c, 0x03, 0x00, 0x40, 0x14, 0x21, 0x38, 0x80, 0x00, 0x94, 0x2b, 0x00, 0x08,
- 0xff, 0xff, 0x02, 0x24, 0x00, 0xa0, 0x03, 0x3c, 0x00, 0x10, 0x63, 0x34, 0xc0,
- 0x11, 0x06, 0x00, 0x14, 0x00, 0xe6, 0xac, 0x21, 0x30, 0x43, 0x00, 0x10, 0x00,
- 0xe5, 0xac, 0x18, 0x00, 0xe0, 0xac, 0x54, 0x00, 0xc3, 0x90, 0x0c, 0x00, 0xc4,
- 0x94, 0x0a, 0x00, 0xc2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x82, 0x10,
- 0x21, 0x28, 0x60, 0x00, 0x00, 0x80, 0x02, 0x3c, 0x25, 0x28, 0xa2, 0x00, 0x14,
- 0x00, 0xc3, 0x94, 0x12, 0x00, 0xc2, 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x62, 0x10, 0x00, 0x40, 0x02, 0x3c, 0x25, 0x28, 0xa2, 0x00, 0x1c, 0x00, 0xe5,
- 0xac, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0xc0, 0xff, 0xbd, 0x27, 0x2c, 0x00, 0xb5, 0xaf, 0x21, 0xa8, 0x00, 0x00, 0x38,
- 0x00, 0xbe, 0xaf, 0x01, 0xa2, 0x1e, 0x3c, 0x28, 0x00, 0xb4, 0xaf, 0x01, 0xa2,
- 0x14, 0x3c, 0x00, 0x12, 0x94, 0x36, 0x30, 0x00, 0xb6, 0xaf, 0x21, 0xb0, 0x00,
- 0x00, 0x74, 0x8b, 0x83, 0x8f, 0x08, 0x00, 0x02, 0x24, 0x3c, 0x00, 0xbf, 0xaf,
- 0x34, 0x00, 0xb7, 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x1c,
- 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x10, 0x00, 0xa5, 0xaf, 0x10, 0x00,
- 0xa2, 0xac, 0x24, 0xb8, 0x83, 0x00, 0x21, 0x88, 0x00, 0x00, 0x40, 0x9a, 0x15,
- 0x00, 0x21, 0x30, 0xd1, 0x02, 0x01, 0x00, 0x07, 0x24, 0x04, 0x10, 0xc7, 0x00,
- 0x24, 0x10, 0xe2, 0x02, 0x35, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0xc1, 0x04, 0x21, 0x18, 0xc0, 0x00, 0x0f, 0x00, 0xc3, 0x24, 0x00, 0xa0,
- 0x05, 0x3c, 0x00, 0x10, 0xa5, 0x34, 0x03, 0x19, 0x03, 0x00, 0x40, 0x10, 0x03,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x23, 0x10, 0x43, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03, 0x3c, 0x60, 0xcd, 0x63, 0x24, 0x21,
- 0x90, 0x43, 0x00, 0xc0, 0x11, 0x06, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x80, 0x45, 0x00, 0x21, 0x20, 0x40,
- 0x00, 0x3b, 0x12, 0x00, 0x0c, 0x24, 0x00, 0x00, 0xae, 0x21, 0x18, 0x00, 0x00,
- 0x01, 0x00, 0x07, 0x24, 0x04, 0x10, 0x27, 0x02, 0x3f, 0x00, 0x42, 0x38, 0x00,
- 0x00, 0x82, 0xa2, 0x00, 0x00, 0xc0, 0xa7, 0x01, 0x00, 0x63, 0x24, 0x64, 0x00,
- 0x62, 0x28, 0xfc, 0xff, 0x40, 0x14, 0x3f, 0x00, 0x02, 0x24, 0x00, 0x00, 0x82,
- 0xa2, 0x21, 0x18, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa7, 0x01, 0x00, 0x63, 0x24,
- 0x88, 0x13, 0x62, 0x28, 0xfc, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x43, 0x8e, 0x21, 0x20, 0x00, 0x02, 0x21, 0x18, 0x73, 0x00, 0x24, 0x00, 0x83,
- 0xac, 0x18, 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x60, 0x00,
- 0x21, 0x80, 0x40, 0x00, 0x3b, 0x12, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x01,
- 0x00, 0x31, 0x26, 0x06, 0x00, 0x22, 0x2a, 0xc3, 0xff, 0x40, 0x14, 0x20, 0x00,
- 0x73, 0x26, 0x00, 0x02, 0x94, 0x26, 0x01, 0x00, 0xb5, 0x26, 0x04, 0x00, 0xa2,
- 0x2a, 0xbc, 0xff, 0x40, 0x14, 0x06, 0x00, 0xd6, 0x26, 0x10, 0x00, 0xa7, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xf7, 0xac, 0x3c, 0x00, 0xbf, 0x8f, 0x38,
- 0x00, 0xbe, 0x8f, 0x34, 0x00, 0xb7, 0x8f, 0x30, 0x00, 0xb6, 0x8f, 0x2c, 0x00,
- 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2,
- 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x40, 0x00, 0xbd, 0x27, 0x80, 0xfb, 0xbd, 0x27, 0x5c, 0x04, 0xb1, 0xaf, 0x5c,
- 0x9e, 0x91, 0x8f, 0x7c, 0x04, 0xbf, 0xaf, 0x78, 0x04, 0xbe, 0xaf, 0x74, 0x04,
- 0xb7, 0xaf, 0x70, 0x04, 0xb6, 0xaf, 0x6c, 0x04, 0xb5, 0xaf, 0x68, 0x04, 0xb4,
- 0xaf, 0x64, 0x04, 0xb3, 0xaf, 0x60, 0x04, 0xb2, 0xaf, 0x58, 0x04, 0xb0, 0xaf,
- 0x0a, 0x00, 0x28, 0x96, 0x0c, 0x00, 0x23, 0x96, 0xff, 0xff, 0x14, 0x31, 0xff,
- 0xff, 0x67, 0x30, 0xfa, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0xa0,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x40, 0x14, 0x21, 0x90, 0x60,
- 0x00, 0x30, 0x04, 0xb0, 0x27, 0x21, 0x28, 0x00, 0x02, 0x21, 0x30, 0x80, 0x02,
- 0x40, 0x04, 0xa0, 0xa3, 0x3c, 0x00, 0x35, 0x8e, 0x0e, 0x00, 0x29, 0x96, 0x10,
- 0x00, 0x1e, 0x24, 0x14, 0x00, 0xbe, 0xaf, 0x48, 0x04, 0xa8, 0xa7, 0x50, 0x04,
- 0xa9, 0xa7, 0x50, 0x04, 0xb7, 0x97, 0x21, 0x20, 0xa0, 0x02, 0x4b, 0x2d, 0x00,
- 0x0c, 0x10, 0x00, 0xb7, 0xaf, 0x10, 0x00, 0x42, 0x26, 0x0e, 0x00, 0x23, 0x96,
- 0x0c, 0x00, 0x13, 0x8e, 0x24, 0xb0, 0x62, 0x00, 0x19, 0x00, 0x60, 0x16, 0x21,
- 0x90, 0xc0, 0x02, 0x0e, 0x10, 0x02, 0x24, 0x28, 0x00, 0xa2, 0xaf, 0x34, 0x00,
- 0xbe, 0xaf, 0x04, 0x00, 0x03, 0x8e, 0x08, 0x00, 0x05, 0x8e, 0x12, 0x00, 0x26,
- 0x96, 0x14, 0x00, 0x27, 0x96, 0x16, 0x00, 0x22, 0x96, 0x2c, 0x00, 0xa3, 0xaf,
- 0x30, 0x00, 0xa5, 0xaf, 0x10, 0x00, 0xa2, 0xaf, 0x14, 0x00, 0xa0, 0xaf, 0x38,
- 0x00, 0x25, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2d, 0x00, 0x0c, 0x28, 0x00,
- 0xa4, 0x27, 0x21, 0x10, 0x00, 0x00, 0x12, 0x00, 0x24, 0x96, 0x16, 0x00, 0x23,
- 0x96, 0x0a, 0x00, 0x25, 0x96, 0x24, 0x18, 0x64, 0x00, 0x12, 0x00, 0x23, 0xa6,
- 0x16, 0x2d, 0x00, 0x08, 0x0c, 0x00, 0x25, 0xa6, 0x30, 0x04, 0xa3, 0x8f, 0x01,
- 0x10, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10, 0x0d, 0x10, 0x02, 0x24, 0x1a, 0x00,
- 0x62, 0x10, 0x01, 0x00, 0x09, 0x24, 0xc3, 0x2c, 0x00, 0x08, 0x40, 0x04, 0xa9,
- 0xa3, 0x01, 0xa2, 0x05, 0x3c, 0x28, 0x00, 0xa3, 0xaf, 0x01, 0x00, 0x03, 0x24,
- 0x02, 0x00, 0x02, 0x24, 0x34, 0x00, 0xb3, 0xaf, 0x38, 0x00, 0xa3, 0xaf, 0x40,
- 0x00, 0xa2, 0xaf, 0x44, 0x00, 0xa2, 0xaf, 0x48, 0x00, 0xa3, 0xaf, 0x04, 0x00,
- 0x03, 0x8e, 0x12, 0x00, 0x26, 0x96, 0x08, 0x00, 0x02, 0x8e, 0x1c, 0x00, 0xa5,
- 0x34, 0x2c, 0x00, 0xa3, 0xaf, 0x30, 0x00, 0xa2, 0xaf, 0x00, 0x00, 0xa2, 0x90,
- 0x14, 0x00, 0x27, 0x96, 0x16, 0x00, 0x23, 0x96, 0x02, 0x11, 0x02, 0x00, 0x3c,
- 0x00, 0xa2, 0xaf, 0x10, 0x00, 0xa3, 0xaf, 0xb2, 0x2c, 0x00, 0x08, 0x14, 0x00,
- 0xb3, 0xaf, 0x21, 0x20, 0xa0, 0x02, 0x28, 0x04, 0xa5, 0x27, 0x21, 0x30, 0x80,
- 0x02, 0x21, 0x38, 0x40, 0x02, 0x04, 0x00, 0x02, 0x24, 0x10, 0x00, 0xb7, 0xaf,
- 0x4b, 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xa2, 0xaf, 0x04, 0x00, 0xc3, 0x26, 0x28,
- 0x04, 0xb4, 0x8f, 0x0c, 0x00, 0x02, 0x8e, 0x50, 0x04, 0xa9, 0x97, 0x28, 0x00,
- 0xa4, 0x27, 0x10, 0x00, 0xa2, 0xaf, 0x30, 0x04, 0xa5, 0x8f, 0x04, 0x00, 0x06,
- 0x8e, 0x08, 0x00, 0x07, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x2a, 0x00, 0x0c,
- 0x24, 0x90, 0x23, 0x01, 0x09, 0x00, 0x82, 0x2e, 0x4d, 0x00, 0x40, 0x10, 0x80,
- 0x10, 0x14, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x40, 0x1c,
- 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x28, 0x00, 0xa4, 0x27, 0x06, 0x2b, 0x00, 0x0c, 0x21, 0x28, 0x80, 0x02,
- 0xad, 0x2c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xa4, 0x27, 0x71,
- 0x2b, 0x00, 0x0c, 0x21, 0x28, 0x80, 0x02, 0xad, 0x2c, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x20, 0xa0, 0x02, 0x28, 0x04, 0xa5, 0x27, 0x48, 0x04, 0xa9,
- 0x97, 0x21, 0x38, 0x40, 0x02, 0x21, 0x30, 0x20, 0x01, 0x50, 0x04, 0xa9, 0x97,
- 0x04, 0x00, 0x02, 0x24, 0x14, 0x00, 0xa2, 0xaf, 0x4b, 0x2d, 0x00, 0x0c, 0x10,
- 0x00, 0xa9, 0xaf, 0x28, 0x04, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
- 0xc2, 0x2c, 0x06, 0x00, 0x40, 0x14, 0x28, 0x00, 0xa4, 0x27, 0x10, 0x00, 0x13,
- 0x24, 0x0e, 0x10, 0x02, 0x24, 0x28, 0x00, 0xa2, 0xaf, 0xad, 0x2c, 0x00, 0x08,
- 0x34, 0x00, 0xb3, 0xaf, 0x78, 0x2b, 0x00, 0x0c, 0x21, 0x28, 0x80, 0x02, 0xad,
- 0x2c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0xa0, 0x02, 0x28, 0x04,
- 0xa5, 0x27, 0x48, 0x04, 0xa9, 0x97, 0x21, 0x38, 0x40, 0x02, 0x21, 0x30, 0x20,
- 0x01, 0x50, 0x04, 0xa9, 0x97, 0x04, 0x00, 0x02, 0x24, 0x14, 0x00, 0xa2, 0xaf,
- 0x4b, 0x2d, 0x00, 0x0c, 0x10, 0x00, 0xa9, 0xaf, 0x28, 0x04, 0xa4, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x96, 0x2b, 0x00, 0x0c, 0x28, 0x00, 0xa5, 0x27, 0x12, 0x00,
- 0x26, 0x96, 0x14, 0x00, 0x27, 0x96, 0x16, 0x00, 0x22, 0x96, 0x14, 0x00, 0xb3,
- 0xaf, 0x10, 0x00, 0xa2, 0xaf, 0x38, 0x00, 0x25, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0x2d, 0x00, 0x0c, 0x28, 0x00, 0xa4, 0x27, 0x12, 0x00, 0x22, 0x96, 0x16,
- 0x00, 0x23, 0x96, 0x21, 0x10, 0x53, 0x00, 0x24, 0x18, 0x62, 0x00, 0x0c, 0x00,
- 0x22, 0x96, 0x12, 0x00, 0x23, 0xa6, 0x0e, 0x00, 0x23, 0x96, 0x21, 0x10, 0x53,
- 0x00, 0x24, 0x18, 0x62, 0x00, 0xc3, 0x2c, 0x00, 0x08, 0x0c, 0x00, 0x23, 0xa6,
- 0x01, 0x00, 0x09, 0x24, 0x40, 0x04, 0xa9, 0xa3, 0x40, 0x04, 0xa2, 0x93, 0x00,
- 0x00, 0x00, 0x00, 0x3b, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa0,
- 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x70, 0x90, 0x80, 0x00, 0x62,
- 0x90, 0x88, 0x00, 0x77, 0x90, 0x04, 0x00, 0x63, 0x26, 0xff, 0x00, 0x56, 0x30,
- 0xff, 0x00, 0x06, 0x32, 0x23, 0x10, 0xc6, 0x02, 0xff, 0xff, 0x42, 0x24, 0xff,
- 0x00, 0xf4, 0x32, 0x24, 0x10, 0x54, 0x00, 0x2b, 0x10, 0x43, 0x00, 0x07, 0x00,
- 0x40, 0x10, 0x28, 0x04, 0xa4, 0x27, 0x0c, 0x00, 0x22, 0x96, 0x0e, 0x00, 0x23,
- 0x96, 0x21, 0x10, 0x53, 0x00, 0x24, 0x18, 0x62, 0x00, 0x01, 0x2d, 0x00, 0x08,
- 0x0c, 0x00, 0x23, 0xa6, 0x21, 0x38, 0xc0, 0x02, 0x68, 0xa0, 0x85, 0x8f, 0x70,
- 0x00, 0x02, 0x24, 0x28, 0x04, 0xa2, 0xa3, 0x02, 0x12, 0x13, 0x00, 0x29, 0x04,
- 0xa2, 0xa3, 0x04, 0x00, 0x02, 0x24, 0x2a, 0x04, 0xb3, 0xa3, 0x2b, 0x04, 0xa0,
- 0xa3, 0x10, 0x00, 0xb4, 0xaf, 0x6c, 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xa2, 0xaf,
- 0x04, 0x00, 0x10, 0x26, 0x48, 0x04, 0xa9, 0x97, 0x3c, 0x00, 0x35, 0x8e, 0x0c,
- 0x00, 0x32, 0x96, 0x68, 0xa0, 0x82, 0x8f, 0x24, 0x80, 0xf0, 0x02, 0x14, 0x00,
- 0xb0, 0xaf, 0x18, 0x00, 0xb6, 0xaf, 0x1c, 0x00, 0xb4, 0xaf, 0x20, 0x00, 0xb3,
- 0xaf, 0x21, 0x28, 0x20, 0x01, 0x21, 0x20, 0xa0, 0x02, 0x50, 0x04, 0xa9, 0x97,
- 0x21, 0x30, 0x40, 0x02, 0x10, 0x00, 0xa2, 0xaf, 0xe6, 0x2d, 0x00, 0x0c, 0x21,
- 0x38, 0x20, 0x01, 0x21, 0x80, 0x13, 0x02, 0x50, 0xa0, 0x82, 0x8f, 0x24, 0x80,
- 0xf0, 0x02, 0x84, 0x00, 0x50, 0xa0, 0x0e, 0x00, 0x22, 0x96, 0x21, 0x18, 0x53,
- 0x02, 0x24, 0x10, 0x43, 0x00, 0x0c, 0x00, 0x22, 0xa6, 0x0a, 0x00, 0x23, 0x96,
- 0x0c, 0x00, 0x22, 0x96, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x62, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x22, 0x96, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff,
- 0x42, 0x30, 0x50, 0x00, 0x22, 0xa6, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x98, 0x00, 0x43, 0x90, 0x94, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x79, 0x2e, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0xa8, 0x26, 0x00, 0x0c, 0x28, 0x00, 0x04, 0x24, 0x21, 0x10,
- 0x00, 0x00, 0x7c, 0x04, 0xbf, 0x8f, 0x78, 0x04, 0xbe, 0x8f, 0x74, 0x04, 0xb7,
- 0x8f, 0x70, 0x04, 0xb6, 0x8f, 0x6c, 0x04, 0xb5, 0x8f, 0x68, 0x04, 0xb4, 0x8f,
- 0x64, 0x04, 0xb3, 0x8f, 0x60, 0x04, 0xb2, 0x8f, 0x5c, 0x04, 0xb1, 0x8f, 0x58,
- 0x04, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x80, 0x04, 0xbd, 0x27, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x02, 0x3c, 0x04, 0x40, 0x42,
- 0x34, 0x01, 0xa2, 0x03, 0x3c, 0x00, 0x00, 0x44, 0xa4, 0x27, 0x2d, 0x00, 0x08,
- 0x00, 0x00, 0x60, 0xa4, 0xd8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x1c,
- 0x00, 0xb3, 0xaf, 0x21, 0x98, 0xa0, 0x00, 0xff, 0xff, 0xc5, 0x30, 0x18, 0x00,
- 0xb2, 0xaf, 0x3c, 0x00, 0xb2, 0x8f, 0x38, 0x00, 0xa2, 0x97, 0xff, 0xff, 0xa3,
- 0x24, 0x20, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x23, 0x80, 0x43, 0x00,
- 0x2b, 0x10, 0x50, 0x02, 0x07, 0x00, 0x40, 0x14, 0x21, 0x88, 0x80, 0x00, 0x21,
- 0x28, 0x65, 0x02, 0x78, 0x11, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x02, 0x21, 0x88,
- 0x30, 0x02, 0x23, 0x90, 0x50, 0x02, 0x21, 0x30, 0x00, 0x00, 0x21, 0x20, 0x20,
- 0x02, 0xff, 0xff, 0xc5, 0x30, 0x21, 0x28, 0x65, 0x02, 0x78, 0x11, 0x00, 0x0c,
- 0x21, 0x30, 0x40, 0x02, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18,
- 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xb3,
- 0xaf, 0x21, 0x98, 0x80, 0x00, 0x14, 0x00, 0xb1, 0xaf, 0xff, 0xff, 0xe4, 0x30,
- 0x18, 0x00, 0xb2, 0xaf, 0x3c, 0x00, 0xb2, 0x8f, 0x38, 0x00, 0xa2, 0x97, 0xff,
- 0xff, 0x83, 0x24, 0x20, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x23, 0x80,
- 0x43, 0x00, 0x2b, 0x10, 0x50, 0x02, 0x08, 0x00, 0x40, 0x14, 0x21, 0x88, 0xa0,
- 0x00, 0x21, 0x20, 0x64, 0x02, 0x78, 0x11, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x02,
- 0x21, 0x88, 0x30, 0x02, 0x23, 0x90, 0x50, 0x02, 0x21, 0x38, 0x00, 0x00, 0xff,
- 0xff, 0xe4, 0x30, 0x21, 0x20, 0x64, 0x02, 0x21, 0x28, 0x20, 0x02, 0x78, 0x11,
- 0x00, 0x0c, 0x21, 0x30, 0x40, 0x02, 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0x21, 0x40, 0xa0, 0x00, 0xff,
- 0x00, 0xc6, 0x30, 0x80, 0x10, 0x06, 0x00, 0x21, 0x28, 0xa2, 0x00, 0xff, 0xff,
- 0xc6, 0x24, 0x10, 0x00, 0xa2, 0x93, 0x14, 0x00, 0xa7, 0x8f, 0x23, 0x30, 0x46,
- 0x00, 0x2b, 0x10, 0xe6, 0x00, 0x0d, 0x00, 0x40, 0x14, 0x21, 0x18, 0xe0, 0x00,
- 0x21, 0x18, 0xc0, 0x00, 0x07, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x82, 0x90, 0x01, 0x00, 0x84, 0x24, 0xff, 0xff, 0x63, 0x24, 0x00, 0x00,
- 0xa2, 0xac, 0xfb, 0xff, 0x60, 0x14, 0x04, 0x00, 0xa5, 0x24, 0x23, 0x38, 0xe6,
- 0x00, 0x21, 0x28, 0x00, 0x01, 0x21, 0x18, 0xe0, 0x00, 0x07, 0x00, 0x60, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x90, 0x01, 0x00, 0x84, 0x24, 0xff,
- 0xff, 0x63, 0x24, 0x00, 0x00, 0xa2, 0xac, 0xfb, 0xff, 0x60, 0x14, 0x04, 0x00,
- 0xa5, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x48, 0x80,
- 0x00, 0xff, 0x00, 0xe7, 0x30, 0x80, 0x10, 0x07, 0x00, 0x21, 0x20, 0x82, 0x00,
- 0xff, 0xff, 0xe7, 0x24, 0x10, 0x00, 0xa2, 0x93, 0x14, 0x00, 0xa8, 0x8f, 0x23,
- 0x30, 0x47, 0x00, 0x2b, 0x10, 0x06, 0x01, 0x0d, 0x00, 0x40, 0x14, 0x21, 0x18,
- 0x00, 0x01, 0x21, 0x18, 0xc0, 0x00, 0x07, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x82, 0x90, 0x04, 0x00, 0x84, 0x24, 0xff, 0xff, 0x63, 0x24,
- 0x00, 0x00, 0xa2, 0xa0, 0xfb, 0xff, 0x60, 0x14, 0x01, 0x00, 0xa5, 0x24, 0x23,
- 0x40, 0x06, 0x01, 0x21, 0x20, 0x20, 0x01, 0x21, 0x18, 0x00, 0x01, 0x07, 0x00,
- 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x90, 0x04, 0x00, 0x84,
- 0x24, 0xff, 0xff, 0x63, 0x24, 0x00, 0x00, 0xa2, 0xa0, 0xfb, 0xff, 0x60, 0x14,
- 0x01, 0x00, 0xa5, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0,
- 0xff, 0xbd, 0x27, 0x28, 0x00, 0xb4, 0xaf, 0x21, 0xa0, 0xc0, 0x00, 0x1c, 0x00,
- 0xb1, 0xaf, 0x60, 0x00, 0xb1, 0x8f, 0x54, 0x00, 0xa6, 0x97, 0x5c, 0x00, 0xa2,
- 0x97, 0x30, 0x00, 0xb6, 0xaf, 0x21, 0xb0, 0x80, 0x00, 0x34, 0x00, 0xb7, 0xaf,
- 0x50, 0x00, 0xb7, 0x8f, 0x21, 0x40, 0x80, 0x02, 0x20, 0x00, 0xb2, 0xaf, 0x21,
- 0x90, 0xe0, 0x00, 0x24, 0x00, 0xb3, 0xaf, 0x21, 0x98, 0xa0, 0x00, 0x2c, 0x00,
- 0xb5, 0xaf, 0x38, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0xff, 0xff, 0xc5,
- 0x30, 0xff, 0xff, 0xa3, 0x24, 0x23, 0x80, 0x43, 0x00, 0x2b, 0x10, 0x30, 0x02,
- 0x0c, 0x00, 0x40, 0x14, 0x21, 0xa8, 0x40, 0x02, 0x21, 0x28, 0xe5, 0x02, 0xff,
- 0x00, 0x66, 0x32, 0xff, 0x00, 0x07, 0x31, 0xff, 0x00, 0xa2, 0x32, 0x10, 0x00,
- 0xa2, 0xaf, 0x8d, 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xb0, 0xaf, 0x21, 0x30, 0x00,
- 0x00, 0x23, 0x88, 0x30, 0x02, 0x21, 0x10, 0x90, 0x02, 0x24, 0x40, 0x42, 0x02,
- 0x21, 0x20, 0xc0, 0x02, 0xff, 0xff, 0xc5, 0x30, 0x21, 0x28, 0xe5, 0x02, 0xff,
- 0x00, 0x66, 0x32, 0xff, 0x00, 0x07, 0x31, 0xff, 0x00, 0xa2, 0x32, 0x10, 0x00,
- 0xa2, 0xaf, 0x8d, 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xb1, 0xaf, 0x38, 0x00, 0xbf,
- 0x8f, 0x34, 0x00, 0xb7, 0x8f, 0x30, 0x00, 0xb6, 0x8f, 0x2c, 0x00, 0xb5, 0x8f,
- 0x28, 0x00, 0xb4, 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c,
- 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00,
- 0xbd, 0x27, 0xc0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xb1, 0xaf, 0x60, 0x00, 0xb1,
- 0x8f, 0x30, 0x00, 0xb6, 0xaf, 0x21, 0xb0, 0x80, 0x00, 0x24, 0x00, 0xb3, 0xaf,
- 0x54, 0x00, 0xb3, 0x8f, 0x21, 0x20, 0xc0, 0x00, 0x28, 0x00, 0xb4, 0xaf, 0x5c,
- 0x00, 0xb4, 0x8f, 0xff, 0xff, 0xe7, 0x30, 0x34, 0x00, 0xb7, 0xaf, 0x50, 0x00,
- 0xb7, 0x8f, 0xff, 0xff, 0x83, 0x30, 0x20, 0x00, 0xb2, 0xaf, 0x58, 0x00, 0xb2,
- 0x93, 0xff, 0xff, 0x62, 0x24, 0x18, 0x00, 0xb0, 0xaf, 0x23, 0x80, 0xe2, 0x00,
- 0x38, 0x00, 0xbf, 0xaf, 0x2c, 0x00, 0xb5, 0xaf, 0x21, 0x30, 0x60, 0x02, 0x2b,
- 0x10, 0x30, 0x02, 0x0d, 0x00, 0x40, 0x14, 0x21, 0xa8, 0x80, 0x02, 0x21, 0x20,
- 0xc3, 0x02, 0x21, 0x28, 0xe0, 0x02, 0xff, 0x00, 0xc6, 0x30, 0x21, 0x38, 0x40,
- 0x02, 0xff, 0x00, 0xa2, 0x32, 0x10, 0x00, 0xa2, 0xaf, 0x6c, 0x2d, 0x00, 0x0c,
- 0x14, 0x00, 0xb0, 0xaf, 0x21, 0x20, 0x00, 0x00, 0x23, 0x88, 0x30, 0x02, 0x21,
- 0x10, 0x70, 0x02, 0x24, 0x30, 0x82, 0x02, 0xff, 0xff, 0x84, 0x30, 0x21, 0x20,
- 0xc4, 0x02, 0x21, 0x28, 0xe0, 0x02, 0xff, 0x00, 0xc6, 0x30, 0x21, 0x38, 0x40,
- 0x02, 0xff, 0x00, 0xa2, 0x32, 0x10, 0x00, 0xa2, 0xaf, 0x6c, 0x2d, 0x00, 0x0c,
- 0x14, 0x00, 0xb1, 0xaf, 0x38, 0x00, 0xbf, 0x8f, 0x34, 0x00, 0xb7, 0x8f, 0x30,
- 0x00, 0xb6, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f, 0x24, 0x00,
- 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27, 0xc0, 0xff, 0xbd, 0x27,
- 0x34, 0x00, 0xb3, 0xaf, 0x21, 0x98, 0x80, 0x00, 0x30, 0x00, 0xb2, 0xaf, 0x21,
- 0x90, 0xc0, 0x00, 0x2c, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xe0, 0x00, 0x28, 0x00,
- 0xb0, 0xaf, 0x5c, 0x9e, 0x90, 0x8f, 0xff, 0x00, 0xa5, 0x30, 0x38, 0x00, 0xbf,
- 0xaf, 0x38, 0x00, 0x02, 0x8e, 0x12, 0x00, 0x03, 0x96, 0x14, 0x00, 0x04, 0x96,
- 0x16, 0x00, 0x08, 0x96, 0xff, 0x00, 0x46, 0x32, 0x18, 0x00, 0xa4, 0xaf, 0x6c,
- 0xa0, 0x84, 0x8f, 0xff, 0x00, 0x27, 0x32, 0x20, 0x00, 0xb3, 0xaf, 0x10, 0x00,
- 0xa2, 0xaf, 0x14, 0x00, 0xa3, 0xaf, 0xae, 0x2d, 0x00, 0x0c, 0x1c, 0x00, 0xa8,
- 0xaf, 0x21, 0x90, 0x53, 0x02, 0x12, 0x00, 0x02, 0x96, 0x16, 0x00, 0x03, 0x96,
- 0x21, 0x10, 0x53, 0x00, 0x24, 0x18, 0x62, 0x00, 0x50, 0xa0, 0x82, 0x8f, 0x24,
- 0x88, 0x32, 0x02, 0x12, 0x00, 0x03, 0xa6, 0x94, 0x00, 0x51, 0xa0, 0x38, 0x00,
- 0xbf, 0x8f, 0x34, 0x00, 0xb3, 0x8f, 0x30, 0x00, 0xb2, 0x8f, 0x2c, 0x00, 0xb1,
- 0x8f, 0x28, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27,
- 0xff, 0x00, 0x84, 0x30, 0xff, 0x00, 0xa5, 0x30, 0x23, 0x20, 0x85, 0x00, 0xff,
- 0x00, 0xc6, 0x30, 0x40, 0xa0, 0x83, 0x8f, 0x24, 0x20, 0x86, 0x00, 0x2b, 0x10,
- 0x83, 0x00, 0x04, 0x00, 0x40, 0x10, 0x23, 0x10, 0x64, 0x00, 0x40, 0xa0, 0x82,
- 0xaf, 0x56, 0x2e, 0x00, 0x08, 0x21, 0x10, 0x80, 0x00, 0x21, 0x20, 0x60, 0x00,
- 0x40, 0xa0, 0x80, 0xaf, 0x21, 0x10, 0x80, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xa0, 0x82, 0x8f, 0xe0, 0xff, 0xbd, 0x27, 0x1c, 0x00,
- 0xbf, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x88, 0x00, 0x45, 0x90, 0x50, 0xa0, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x46, 0x90, 0x50, 0xa0, 0x83, 0x8f,
- 0x04, 0x00, 0xc2, 0x24, 0x24, 0x80, 0xa2, 0x00, 0x80, 0x00, 0x62, 0x90, 0xff,
- 0x00, 0x03, 0x32, 0xff, 0x00, 0x47, 0x30, 0x04, 0x00, 0xe2, 0x24, 0x2a, 0x10,
- 0x62, 0x00, 0x03, 0x00, 0x40, 0x10, 0x2b, 0x10, 0x67, 0x00, 0x0a, 0x00, 0x40,
- 0x10, 0xff, 0xff, 0x02, 0x24, 0x04, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa5, 0xaf,
- 0x68, 0xa0, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x2d, 0x00, 0x0c, 0x14,
- 0x00, 0xa2, 0xaf, 0x50, 0xa0, 0x83, 0x8f, 0x21, 0x10, 0x00, 0x00, 0x84, 0x00,
- 0x70, 0xa0, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x20, 0x00, 0xbd, 0x27, 0x50, 0xa0, 0x82, 0x8f, 0xb0, 0xff, 0xbd, 0x27,
- 0x4c, 0x00, 0xbf, 0xaf, 0x48, 0x00, 0xbe, 0xaf, 0x44, 0x00, 0xb7, 0xaf, 0x40,
- 0x00, 0xb6, 0xaf, 0x3c, 0x00, 0xb5, 0xaf, 0x38, 0x00, 0xb4, 0xaf, 0x34, 0x00,
- 0xb3, 0xaf, 0x30, 0x00, 0xb2, 0xaf, 0x2c, 0x00, 0xb1, 0xaf, 0x28, 0x00, 0xb0,
- 0xaf, 0x98, 0x00, 0x5e, 0x90, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x94, 0x00, 0x53, 0x90, 0x50, 0xa0, 0x82, 0x8f, 0x40, 0xa0, 0x83, 0x8f, 0x9c,
- 0x00, 0x57, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x60, 0x10, 0xff, 0x00,
- 0xd2, 0x33, 0x21, 0x20, 0x40, 0x02, 0xff, 0x00, 0x71, 0x32, 0x21, 0x28, 0x20,
- 0x02, 0xff, 0x00, 0xf0, 0x32, 0x47, 0x2e, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x02,
- 0x21, 0x20, 0x40, 0x00, 0x21, 0x28, 0x40, 0x02, 0x21, 0x30, 0x20, 0x02, 0x1f,
- 0x2e, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x02, 0x11, 0x2f, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0xa5, 0x27, 0x21, 0x30, 0x40, 0x02, 0xff, 0x00, 0x67,
- 0x32, 0xff, 0x00, 0xf4, 0x32, 0x6c, 0xa0, 0x90, 0x8f, 0x04, 0x00, 0x15, 0x24,
- 0x10, 0x00, 0xb4, 0xaf, 0x14, 0x00, 0xb5, 0xaf, 0x8d, 0x2d, 0x00, 0x0c, 0x21,
- 0x20, 0x00, 0x02, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x40, 0xa4, 0x50, 0xa0,
- 0x82, 0x8f, 0x04, 0x00, 0x73, 0x26, 0x94, 0x00, 0x53, 0xa0, 0x20, 0x00, 0xa3,
- 0x93, 0x70, 0x00, 0x02, 0x24, 0x63, 0x00, 0x62, 0x14, 0x01, 0x00, 0x16, 0x24,
- 0x18, 0x00, 0xa5, 0x27, 0x21, 0x30, 0x40, 0x02, 0xff, 0x00, 0x71, 0x32, 0x6c,
- 0xa0, 0x90, 0x8f, 0x21, 0x00, 0xa2, 0x93, 0x22, 0x00, 0xa3, 0x93, 0x21, 0x38,
- 0x20, 0x02, 0x10, 0x00, 0xb4, 0xaf, 0x14, 0x00, 0xb5, 0xaf, 0x00, 0x12, 0x02,
- 0x00, 0x21, 0xa8, 0x43, 0x00, 0x8d, 0x2d, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0x18, 0x00, 0xa3, 0x8f, 0x05, 0x10, 0x02, 0x24, 0x2e, 0x00, 0x62, 0x10, 0x06,
- 0x10, 0x62, 0x2c, 0x05, 0x00, 0x40, 0x10, 0x04, 0x10, 0x02, 0x24, 0x0a, 0x00,
- 0x62, 0x10, 0xff, 0x00, 0xc2, 0x32, 0x05, 0x2f, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x06, 0x10, 0x02, 0x24, 0x18, 0x00, 0x62, 0x10, 0x09, 0x10, 0x02, 0x24,
- 0x34, 0x00, 0x62, 0x10, 0xff, 0x00, 0xc2, 0x32, 0x05, 0x2f, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x02, 0x80, 0xa0, 0x85, 0x27, 0x21, 0x30,
- 0x40, 0x02, 0x21, 0x38, 0x20, 0x02, 0x18, 0x00, 0x02, 0x24, 0x10, 0x00, 0xb4,
- 0xaf, 0x8d, 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xa2, 0xaf, 0x80, 0xa0, 0x84, 0x27,
- 0x6b, 0x33, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3c, 0x98,
- 0xbf, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x10, 0x01, 0x00,
- 0x02, 0x24, 0x84, 0x8b, 0x82, 0xaf, 0x05, 0x2f, 0x00, 0x08, 0xff, 0x00, 0xc2,
- 0x32, 0x21, 0x20, 0x00, 0x02, 0xf0, 0xa0, 0x85, 0x27, 0x21, 0x30, 0x40, 0x02,
- 0x21, 0x38, 0x20, 0x02, 0x24, 0x00, 0x02, 0x24, 0x10, 0x00, 0xb4, 0xaf, 0x8d,
- 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xa2, 0xaf, 0xf0, 0xa0, 0x84, 0x27, 0x81, 0x33,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x2f, 0x00, 0x08, 0xff, 0x00, 0xc2,
- 0x32, 0x21, 0x20, 0x00, 0x02, 0xf0, 0xa0, 0x85, 0x27, 0x21, 0x30, 0x40, 0x02,
- 0x21, 0x38, 0x20, 0x02, 0x24, 0x00, 0x02, 0x24, 0x10, 0x00, 0xb4, 0xaf, 0x8d,
- 0x2d, 0x00, 0x0c, 0x14, 0x00, 0xa2, 0xaf, 0x02, 0x80, 0x02, 0x3c, 0x08, 0xc0,
- 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x40, 0x14, 0xff, 0x00, 0xc2,
- 0x32, 0x01, 0x00, 0x02, 0x24, 0x80, 0x8b, 0x82, 0xaf, 0x04, 0x2f, 0x00, 0x08,
- 0x21, 0xb0, 0x00, 0x00, 0x40, 0xa0, 0x95, 0xaf, 0x21, 0x20, 0x40, 0x02, 0x21,
- 0x28, 0x20, 0x02, 0x47, 0x2e, 0x00, 0x0c, 0x21, 0x30, 0x80, 0x02, 0x21, 0xa8,
- 0x40, 0x00, 0xff, 0x00, 0xc2, 0x32, 0x07, 0x00, 0x40, 0x10, 0x21, 0x20, 0xa0,
- 0x02, 0x21, 0x28, 0xc0, 0x03, 0xff, 0x00, 0x66, 0x32, 0x1f, 0x2e, 0x00, 0x0c,
- 0x21, 0x38, 0xe0, 0x02, 0x11, 0x2f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x10, 0x75, 0x02, 0x50, 0xa0, 0x83, 0x8f, 0x24, 0x10, 0xe2, 0x02, 0x94, 0x00,
- 0x62, 0xa0, 0x4c, 0x00, 0xbf, 0x8f, 0x48, 0x00, 0xbe, 0x8f, 0x44, 0x00, 0xb7,
- 0x8f, 0x40, 0x00, 0xb6, 0x8f, 0x3c, 0x00, 0xb5, 0x8f, 0x38, 0x00, 0xb4, 0x8f,
- 0x34, 0x00, 0xb3, 0x8f, 0x30, 0x00, 0xb2, 0x8f, 0x2c, 0x00, 0xb1, 0x8f, 0x28,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x50, 0x00, 0xbd, 0x27, 0x50, 0xa0,
- 0x82, 0x8f, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x0f, 0x00, 0x10,
- 0x3c, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf,
- 0x84, 0x00, 0x43, 0x90, 0x50, 0xa0, 0x82, 0x8f, 0x40, 0x42, 0x10, 0x36, 0x80,
- 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x62, 0x10, 0x0f, 0x00,
- 0x11, 0x24, 0x01, 0xa2, 0x04, 0x3c, 0x2f, 0x00, 0x00, 0x12, 0x01, 0x00, 0x02,
- 0x24, 0x00, 0x00, 0x80, 0xa4, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x84, 0x00, 0x43, 0x90, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xff, 0x62, 0x14, 0xff, 0xff,
- 0x10, 0x26, 0x23, 0x00, 0x00, 0x12, 0x01, 0x00, 0x02, 0x24, 0x50, 0xa0, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x43, 0x90, 0x50, 0xa0, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x42, 0x90, 0xff, 0x00, 0x63, 0x30, 0xff,
- 0x00, 0x42, 0x30, 0x14, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa2,
- 0x12, 0x3c, 0x13, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x62,
- 0x10, 0x00, 0x00, 0x40, 0xa6, 0x79, 0x2e, 0x00, 0x0c, 0xff, 0xff, 0x31, 0x26,
- 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x43, 0x90, 0x50,
- 0xa0, 0x82, 0x8f, 0xff, 0xff, 0x10, 0x26, 0x94, 0x00, 0x42, 0x90, 0xff, 0x00,
- 0x63, 0x30, 0xff, 0x00, 0x42, 0x30, 0x03, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0xef, 0xff, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0x16,
- 0x01, 0x00, 0x02, 0x2e, 0x5c, 0x2f, 0x00, 0x08, 0x03, 0x00, 0x02, 0x24, 0x40,
- 0x10, 0x02, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00,
- 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd,
- 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x01, 0xa2, 0x05, 0x3c, 0x14, 0x00, 0xa5, 0x34,
- 0x50, 0xa0, 0x83, 0x8f, 0x01, 0xa2, 0x04, 0x3c, 0x10, 0x00, 0xbf, 0xaf, 0x00,
- 0x00, 0xa2, 0x94, 0x18, 0x00, 0x84, 0x34, 0x40, 0x00, 0x62, 0xa0, 0x50, 0xa0,
- 0x86, 0x8f, 0x00, 0x00, 0xa2, 0x94, 0x00, 0x00, 0x83, 0x94, 0x02, 0x12, 0x02,
- 0x00, 0x7f, 0x00, 0x42, 0x30, 0xc0, 0x19, 0x03, 0x00, 0x25, 0x10, 0x43, 0x00,
- 0x44, 0x00, 0xc2, 0xa0, 0x50, 0xa0, 0x83, 0x8f, 0x00, 0x00, 0x82, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x10, 0x02, 0x00, 0x48, 0x00, 0x62, 0xa0, 0x50, 0xa0,
- 0x83, 0x8f, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x42, 0x12, 0x02,
- 0x00, 0x4c, 0x00, 0x62, 0xa0, 0x10, 0x8a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x10, 0x8a, 0x82, 0xaf, 0x1a, 0x00, 0x42, 0x28, 0x10,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x82, 0x8f, 0x10, 0x8a,
- 0x80, 0xaf, 0x8c, 0x2f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x79, 0x2e, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x98, 0x00, 0x43, 0x90, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x94,
- 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, 0x43, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0xa8, 0x26, 0x00, 0x0c, 0x0a, 0x00, 0x04, 0x24, 0x10, 0x00, 0xbf,
- 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
- 0xff, 0xbd, 0x27, 0x00, 0xa2, 0x03, 0x3c, 0x04, 0x40, 0x63, 0x34, 0x76, 0x71,
- 0x02, 0x24, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0x0f, 0x00, 0x02, 0x3c,
- 0x40, 0x42, 0x42, 0x34, 0x01, 0xa2, 0x03, 0x3c, 0x00, 0x00, 0x60, 0xa4, 0xff,
- 0xff, 0x42, 0x24, 0xfd, 0xff, 0x40, 0x14, 0x21, 0x80, 0x00, 0x00, 0x0a, 0x00,
- 0x03, 0x24, 0x00, 0xa2, 0x12, 0x3c, 0x04, 0x40, 0x52, 0x36, 0x01, 0xa2, 0x11,
- 0x3c, 0x0a, 0x00, 0x02, 0x2a, 0x11, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x10, 0x1c, 0x02, 0x20, 0x8a, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5e, 0x42, 0x24, 0xd6, 0x2f, 0x00, 0x0c, 0x00, 0x00, 0x42, 0xa6, 0x21, 0x18,
- 0x40, 0x00, 0x14, 0x00, 0x60, 0x10, 0x0f, 0x00, 0x02, 0x3c, 0x40, 0x42, 0x42,
- 0x34, 0x00, 0x00, 0x20, 0xa6, 0xff, 0xff, 0x42, 0x24, 0xfd, 0xff, 0x40, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0xee, 0xff, 0x60, 0x14, 0x01, 0x00, 0x10, 0x26, 0x0b,
- 0x00, 0x60, 0x10, 0x00, 0xa2, 0x03, 0x3c, 0x04, 0x40, 0x63, 0x34, 0x38, 0x7c,
- 0x02, 0x24, 0x00, 0x00, 0x62, 0xa4, 0x4c, 0x00, 0x10, 0x3c, 0x40, 0x4b, 0x10,
- 0x36, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x40, 0xa4, 0xff, 0xff, 0x10, 0x26,
- 0xfd, 0xff, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x00, 0x00, 0x1c,
- 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00,
- 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x70, 0xff, 0xbd,
- 0x27, 0x88, 0x00, 0xbf, 0xaf, 0x84, 0x00, 0xb1, 0xaf, 0x88, 0x30, 0x00, 0x0c,
- 0x80, 0x00, 0xb0, 0xaf, 0x21, 0x88, 0x40, 0x00, 0xff, 0xff, 0x30, 0x32, 0xff,
- 0xff, 0x02, 0x34, 0x03, 0x00, 0x02, 0x16, 0x03, 0xa2, 0x07, 0x3c, 0x83, 0x30,
- 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x00, 0x04, 0xe7, 0x34, 0x03, 0xa2, 0x06,
- 0x3c, 0x00, 0x08, 0xc6, 0x34, 0x03, 0xa2, 0x05, 0x3c, 0x00, 0x0c, 0xa5, 0x34,
- 0x03, 0xa2, 0x04, 0x3c, 0xc0, 0x00, 0x84, 0x34, 0x03, 0xa2, 0x03, 0x3c, 0x50,
- 0xa0, 0x83, 0xaf, 0x54, 0xa0, 0x84, 0xaf, 0x50, 0xa0, 0x84, 0x8f, 0x02, 0xa2,
- 0x02, 0x3c, 0x60, 0xa0, 0x82, 0xaf, 0x04, 0xa2, 0x02, 0x3c, 0x70, 0xa0, 0x82,
- 0xaf, 0x58, 0xa0, 0x83, 0xaf, 0x68, 0xa0, 0x87, 0xaf, 0x6c, 0xa0, 0x86, 0xaf,
- 0x74, 0xa0, 0x85, 0xaf, 0x00, 0x00, 0x80, 0xa0, 0x50, 0xa0, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0xa0, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x40, 0xa0, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x4b, 0x40, 0x00, 0x0c, 0x0c, 0x00, 0x40, 0xa0, 0x2c, 0x8a, 0x84, 0x27,
- 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x06, 0x3c, 0xf0,
- 0x22, 0xc6, 0x24, 0x60, 0xa0, 0x84, 0x8f, 0x70, 0xa0, 0x85, 0x8f, 0x60, 0x74,
- 0x07, 0x24, 0x08, 0x31, 0x00, 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0x54, 0x8a, 0x84,
- 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa4, 0x27,
- 0x38, 0x00, 0xa5, 0x27, 0x50, 0x00, 0xa6, 0x27, 0x78, 0x00, 0xa7, 0x27, 0x1a,
- 0x35, 0x00, 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x18, 0x40, 0x00, 0x01, 0x00,
- 0x02, 0x24, 0x08, 0x00, 0x62, 0x10, 0x02, 0x00, 0x62, 0x28, 0x0c, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x8c, 0x8a, 0x84, 0x27, 0x1f, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0x8a, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8a,
- 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x8b, 0x84,
- 0x27, 0x83, 0x42, 0x00, 0x0c, 0x26, 0x00, 0x10, 0x3c, 0x60, 0x74, 0x05, 0x24,
- 0xff, 0xff, 0x26, 0x32, 0x20, 0x00, 0xa7, 0x27, 0xa0, 0x25, 0x10, 0x36, 0x70,
- 0xa0, 0x84, 0x8f, 0x38, 0x00, 0xa2, 0x27, 0x10, 0x00, 0xa2, 0xaf, 0x50, 0x00,
- 0xa2, 0x27, 0x14, 0x00, 0xa2, 0xaf, 0x78, 0x00, 0xa2, 0x27, 0xb7, 0x30, 0x00,
- 0x0c, 0x18, 0x00, 0xa2, 0xaf, 0x4b, 0x00, 0x04, 0x24, 0x01, 0xa2, 0x05, 0x3c,
- 0x60, 0xa0, 0x83, 0x8f, 0x01, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xa0, 0x50,
- 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x42, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x05, 0x00, 0x44, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0xa4, 0xff, 0xff, 0x10, 0x26, 0xf7, 0xff, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00,
- 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x42, 0x90, 0x00,
- 0x00, 0x00, 0x00, 0x26, 0x10, 0x44, 0x00, 0x01, 0x00, 0x45, 0x2c, 0x50, 0xa0,
- 0x82, 0x8f, 0x21, 0x20, 0xa0, 0x00, 0x08, 0x00, 0x43, 0x90, 0x4f, 0x00, 0x02,
- 0x24, 0x02, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xa4, 0x34,
- 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x43, 0x90, 0x31,
- 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x84, 0x34, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x90, 0x54, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x14, 0xff, 0x00, 0x83, 0x30,
- 0x08, 0x00, 0x84, 0x34, 0xff, 0x00, 0x83, 0x30, 0x0f, 0x00, 0x02, 0x24, 0x03,
- 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2d, 0x00, 0x0c, 0x7c, 0x79,
- 0x04, 0x24, 0x40, 0x8b, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x80, 0x00,
- 0x00, 0x00, 0xa2, 0x04, 0x3c, 0x00, 0x80, 0x84, 0x34, 0x01, 0xa2, 0x05, 0x3c,
- 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x12, 0xa5, 0x34, 0x3c, 0x00, 0x43, 0x90, 0x9f,
- 0x00, 0x02, 0x24, 0xc9, 0x99, 0x80, 0xa3, 0x00, 0x00, 0x82, 0xa0, 0xc8, 0x99,
- 0x83, 0xa3, 0x00, 0x00, 0xa0, 0xa0, 0x01, 0x00, 0x10, 0x26, 0x05, 0x00, 0x02,
- 0x2a, 0xfc, 0xff, 0x40, 0x14, 0x00, 0x02, 0xa5, 0x24, 0x00, 0xa2, 0x03, 0x3c,
- 0x00, 0x80, 0x63, 0x34, 0x70, 0x8b, 0x82, 0x93, 0x21, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x62, 0xa0, 0x07, 0x37, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x01, 0x00,
- 0x10, 0x26, 0x1e, 0x00, 0x02, 0x2a, 0xfb, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x62, 0x40, 0x00, 0x0c, 0x38, 0x00, 0xa4, 0x27, 0x21, 0x10, 0x00, 0x00,
- 0x88, 0x00, 0xbf, 0x8f, 0x84, 0x00, 0xb1, 0x8f, 0x80, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x90, 0x00, 0xbd, 0x27, 0x05, 0xa2, 0x02, 0x3c, 0x04, 0x00,
- 0x42, 0x34, 0x02, 0xa2, 0x03, 0x3c, 0x00, 0x00, 0x42, 0x90, 0x04, 0x00, 0x63,
- 0x34, 0x54, 0x00, 0x42, 0x38, 0x01, 0x00, 0x44, 0x2c, 0x00, 0x00, 0x62, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x30, 0x55, 0x00, 0x02, 0x24, 0x0e,
- 0x00, 0x62, 0x10, 0x54, 0x00, 0x05, 0x24, 0x56, 0x00, 0x62, 0x28, 0x05, 0x00,
- 0x40, 0x10, 0x56, 0x00, 0x02, 0x24, 0x07, 0x00, 0x65, 0x10, 0x04, 0x00, 0x02,
- 0x24, 0xa6, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x62, 0x10,
- 0x04, 0x00, 0x02, 0x24, 0xa6, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa5,
- 0x30, 0x00, 0x08, 0x02, 0x00, 0x84, 0x24, 0xa5, 0x30, 0x00, 0x08, 0x04, 0x00,
- 0x84, 0x24, 0x08, 0x00, 0x84, 0x24, 0x04, 0x00, 0x02, 0x24, 0x0d, 0x00, 0x82,
- 0x10, 0x05, 0x00, 0x82, 0x2c, 0x07, 0x00, 0x40, 0x10, 0x03, 0x00, 0x82, 0x2c,
- 0x08, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x10, 0x21,
- 0x10, 0x80, 0x00, 0xb5, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x02, 0x24, 0x03, 0x00, 0x82, 0x10, 0x21, 0x10, 0x80, 0x00, 0xff, 0xff, 0x04,
- 0x34, 0x21, 0x10, 0x80, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0xa7, 0x8f, 0x14, 0x00, 0xa8, 0x8f, 0x80, 0x10, 0x05, 0x00, 0xfc,
- 0xff, 0x03, 0x3c, 0x21, 0x10, 0x43, 0x00, 0x23, 0x20, 0x82, 0x00, 0x90, 0x01,
- 0x86, 0xa0, 0x20, 0x01, 0x86, 0x24, 0x10, 0x00, 0xe5, 0x24, 0x21, 0x18, 0x00,
- 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0xa2, 0x90, 0x01, 0x00, 0xa5, 0x24,
- 0x00, 0x00, 0xc2, 0xa0, 0xff, 0x00, 0x62, 0x30, 0x08, 0x00, 0x42, 0x2c, 0xf9,
- 0xff, 0x40, 0x14, 0x04, 0x00, 0xc6, 0x24, 0x40, 0x01, 0x86, 0x24, 0x10, 0x00,
- 0x05, 0x25, 0x21, 0x18, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0xa2,
- 0x90, 0x01, 0x00, 0xa5, 0x24, 0x00, 0x00, 0xc2, 0xa0, 0xff, 0x00, 0x62, 0x30,
- 0x14, 0x00, 0x42, 0x2c, 0xf9, 0xff, 0x40, 0x14, 0x04, 0x00, 0xc6, 0x24, 0x08,
- 0x00, 0xe0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x68, 0x8b,
- 0x86, 0x8f, 0x50, 0xa0, 0x82, 0x8f, 0x0f, 0x00, 0x03, 0x24, 0x14, 0x00, 0xbf,
- 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0xc4, 0x99, 0x83, 0xaf, 0xc0, 0x99, 0x86, 0xaf,
- 0x98, 0x00, 0x43, 0x90, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x94,
- 0x00, 0x42, 0x90, 0xff, 0x00, 0x65, 0x30, 0xff, 0x00, 0x44, 0x30, 0x1e, 0x00,
- 0xa4, 0x10, 0x21, 0x10, 0x00, 0x00, 0x1c, 0x00, 0xc0, 0x10, 0x01, 0xa2, 0x10,
- 0x3c, 0xc4, 0x99, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x10,
- 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x07, 0x00, 0xa4, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x79, 0x2e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x99,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0xc4, 0x99, 0x82,
- 0xaf, 0x50, 0xa0, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x43, 0x90,
- 0x50, 0xa0, 0x82, 0x8f, 0xff, 0x00, 0x65, 0x30, 0xc0, 0x99, 0x83, 0x8f, 0x94,
- 0x00, 0x42, 0x90, 0xff, 0xff, 0x63, 0x24, 0xff, 0x00, 0x44, 0x30, 0xc0, 0x99,
- 0x83, 0xaf, 0x03, 0x00, 0xa4, 0x10, 0x21, 0x10, 0x00, 0x00, 0xe6, 0xff, 0x60,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x61, 0x08, 0x24, 0x10, 0x00, 0xa3, 0x8f, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00,
- 0x80, 0xa0, 0x00, 0x00, 0x40, 0xa4, 0xff, 0xff, 0x08, 0x25, 0xfd, 0xff, 0x00,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x24, 0x06, 0x00, 0x62, 0x14,
- 0x2a, 0x10, 0x07, 0x01, 0x80, 0x18, 0x07, 0x00, 0x04, 0x00, 0x02, 0x3c, 0x23,
- 0x10, 0x43, 0x00, 0x21, 0x28, 0xa2, 0x00, 0x2a, 0x10, 0x07, 0x01, 0x0a, 0x00,
- 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa2, 0x04, 0x3c, 0x21, 0x18, 0xe6,
- 0x00, 0x00, 0x00, 0xc2, 0x90, 0x01, 0x00, 0xc6, 0x24, 0x00, 0x00, 0xa2, 0xa0,
- 0x04, 0x00, 0xa5, 0x24, 0x2a, 0x10, 0xc3, 0x00, 0xfa, 0xff, 0x40, 0x14, 0x00,
- 0x00, 0x80, 0xa4, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, 0x80,
- 0x00, 0x09, 0x00, 0x02, 0x24, 0x2b, 0x00, 0x02, 0x15, 0x21, 0x38, 0xa0, 0x00,
- 0x00, 0x01, 0xe7, 0x34, 0x01, 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34, 0x63,
- 0x00, 0x05, 0x24, 0xff, 0xff, 0x06, 0x24, 0xf8, 0x9e, 0x83, 0x8f, 0x3f, 0xff,
- 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, 0xf8, 0x9e, 0x83, 0xaf, 0x00, 0x00, 0x43,
- 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa6, 0x14, 0xff, 0xff, 0xa5, 0x24,
- 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8,
- 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e,
- 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4,
- 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34,
- 0x63, 0x00, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40,
- 0x00, 0x42, 0x38, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff,
- 0xa5, 0x24, 0xff, 0xff, 0xa4, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x02,
- 0x3c, 0x0c, 0x00, 0x42, 0x34, 0xf8, 0x9e, 0x83, 0x8f, 0x3f, 0xff, 0x04, 0x24,
- 0x24, 0x18, 0x64, 0x00, 0xf8, 0x9e, 0x83, 0xaf, 0x00, 0x00, 0x43, 0xa4, 0x01,
- 0xa2, 0x05, 0x3c, 0x0c, 0x00, 0xa5, 0x34, 0xff, 0xff, 0x04, 0x25, 0x01, 0x00,
- 0x03, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0x04, 0x18, 0x83, 0x00, 0x80, 0x00, 0x42,
- 0x34, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0xa2, 0xa4, 0xff, 0xff, 0x62, 0x30,
- 0x1c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa2, 0x04, 0x3c, 0x0c,
- 0x00, 0x84, 0x34, 0xdf, 0xff, 0x06, 0x24, 0xbf, 0xff, 0x05, 0x24, 0x24, 0x10,
- 0xe2, 0x00, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x9e, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x70, 0x31, 0x00, 0x08, 0x20, 0x00, 0x42, 0x34,
- 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x46, 0x00, 0xf8,
- 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x82, 0xa4, 0xff, 0xff, 0x63, 0x30, 0xf8, 0x9e,
- 0x82, 0x8f, 0x42, 0x18, 0x03, 0x00, 0x40, 0x00, 0x42, 0x34, 0xf8, 0x9e, 0x82,
- 0xaf, 0x00, 0x00, 0x82, 0xa4, 0x24, 0x10, 0x45, 0x00, 0xf8, 0x9e, 0x82, 0xaf,
- 0x00, 0x00, 0x82, 0xa4, 0xea, 0xff, 0x60, 0x14, 0xff, 0xff, 0x62, 0x30, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0x10, 0x00,
- 0x03, 0x24, 0x01, 0xa2, 0x04, 0x3c, 0x0c, 0x00, 0x84, 0x34, 0xbf, 0xff, 0x07,
- 0x24, 0xff, 0xff, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x00, 0x42, 0x34, 0xf8, 0x9e, 0x82, 0xaf, 0x07, 0x00, 0x60, 0x10, 0x00,
- 0x00, 0x82, 0xa4, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
- 0x42, 0x30, 0x02, 0x00, 0x40, 0x10, 0x40, 0x30, 0x06, 0x00, 0x01, 0x00, 0xc6,
- 0x34, 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x63, 0x24, 0x24, 0x10, 0x47, 0x00,
- 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x82, 0xa4, 0xee, 0xff, 0x65, 0x14, 0x01,
- 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34, 0x63, 0x00, 0x05, 0x24, 0xff, 0xff,
- 0x07, 0x24, 0xf8, 0x9e, 0x83, 0x8f, 0x7f, 0xff, 0x04, 0x24, 0x24, 0x18, 0x64,
- 0x00, 0xf8, 0x9e, 0x83, 0xaf, 0x00, 0x00, 0x43, 0xa4, 0xff, 0xff, 0xa5, 0x24,
- 0xff, 0xff, 0xa7, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c,
- 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff,
- 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x62,
- 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4, 0x14, 0xff, 0xff, 0xa5, 0x24,
- 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8,
- 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e,
- 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4,
- 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0x00, 0xa5, 0x24, 0x00, 0x14, 0x06, 0x00,
- 0x08, 0x00, 0xe0, 0x03, 0x03, 0x14, 0x02, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x10,
- 0x00, 0xbf, 0xaf, 0x3f, 0x00, 0x85, 0x30, 0x09, 0x00, 0x04, 0x24, 0x28, 0x31,
- 0x00, 0x0c, 0x80, 0x01, 0xa5, 0x34, 0x7f, 0x31, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x14, 0x02, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x03, 0x14, 0x02, 0x00,
- 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x18,
- 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x00, 0x1c, 0x00, 0xb3, 0xaf, 0x21, 0x98,
- 0xa0, 0x00, 0x20, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0xbd, 0x31, 0x00,
- 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0xff, 0xff, 0x71, 0x32, 0x00, 0x14, 0x02, 0x00,
- 0x03, 0x84, 0x02, 0x00, 0xf5, 0x00, 0x30, 0x12, 0x09, 0x00, 0x04, 0x24, 0x28,
- 0x31, 0x00, 0x0c, 0x30, 0x01, 0x05, 0x24, 0x27, 0x10, 0x10, 0x00, 0x24, 0x10,
- 0x22, 0x02, 0x72, 0x00, 0x40, 0x10, 0x3f, 0x00, 0x42, 0x32, 0xc0, 0x01, 0x52,
- 0x34, 0x09, 0x00, 0x04, 0x24, 0x28, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x40, 0x02,
- 0x01, 0xa2, 0x04, 0x3c, 0x0c, 0x00, 0x84, 0x34, 0x63, 0x00, 0x05, 0x24, 0xff,
- 0xff, 0x06, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0x3f, 0xff, 0x03, 0x24, 0x24, 0x10,
- 0x43, 0x00, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x82, 0xa4, 0xff, 0xff, 0xa5,
- 0x24, 0xff, 0xff, 0xa6, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x03, 0x3c,
- 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0xff,
- 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00,
- 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4, 0x14, 0xff, 0xff, 0xa5,
- 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24,
- 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8,
- 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff,
- 0xa4, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42,
- 0x34, 0xf8, 0x9e, 0x83, 0x8f, 0x01, 0x00, 0x05, 0x3c, 0x80, 0x00, 0x63, 0x34,
- 0x00, 0x00, 0x43, 0xa4, 0x00, 0x00, 0x42, 0x94, 0xf8, 0x9e, 0x83, 0xaf, 0x20,
- 0x00, 0x42, 0x30, 0x1f, 0x00, 0x40, 0x14, 0x9f, 0x86, 0xa5, 0x34, 0x01, 0xa2,
- 0x08, 0x3c, 0x66, 0x66, 0x06, 0x3c, 0x67, 0x66, 0xc6, 0x34, 0x01, 0xa2, 0x04,
- 0x3c, 0x0c, 0x00, 0x84, 0x34, 0xff, 0xff, 0x07, 0x24, 0x18, 0x00, 0xa6, 0x00,
- 0x00, 0x00, 0x00, 0xa5, 0xc3, 0x17, 0x05, 0x00, 0x10, 0x48, 0x00, 0x00, 0x83,
- 0x18, 0x09, 0x00, 0x23, 0x18, 0x62, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10,
- 0x43, 0x00, 0x40, 0x10, 0x02, 0x00, 0x06, 0x00, 0xa2, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x38,
- 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x82, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0x07,
- 0x00, 0xa7, 0x10, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x42, 0x30, 0xea, 0xff, 0x40, 0x10, 0x18, 0x00, 0xa6,
- 0x00, 0x01, 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34, 0x63, 0x00, 0x05, 0x24,
- 0xff, 0xff, 0x06, 0x24, 0xf8, 0x9e, 0x83, 0x8f, 0x3f, 0xff, 0x04, 0x24, 0x24,
- 0x18, 0x64, 0x00, 0xf8, 0x9e, 0x83, 0xaf, 0x00, 0x00, 0x43, 0xa4, 0xff, 0xff,
- 0xa5, 0x24, 0xff, 0xff, 0xa6, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x03,
- 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f,
- 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e, 0x82, 0xaf, 0x00,
- 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4, 0x14, 0xff, 0xff,
- 0xa5, 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05,
- 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38,
- 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff,
- 0xff, 0xa4, 0x14, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0x70, 0x32, 0xff, 0xff,
- 0x02, 0x34, 0x75, 0x00, 0x02, 0x12, 0x3f, 0x00, 0x42, 0x32, 0x40, 0x01, 0x52,
- 0x34, 0x09, 0x00, 0x04, 0x24, 0x28, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x40, 0x02,
- 0x10, 0x00, 0x04, 0x24, 0x28, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x01,
- 0xa2, 0x04, 0x3c, 0x0c, 0x00, 0x84, 0x34, 0x63, 0x00, 0x05, 0x24, 0xff, 0xff,
- 0x06, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0x3f, 0xff, 0x03, 0x24, 0x24, 0x10, 0x43,
- 0x00, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x82, 0xa4, 0xff, 0xff, 0xa5, 0x24,
- 0xff, 0xff, 0xa6, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c,
- 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff,
- 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x62,
- 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4, 0x14, 0xff, 0xff, 0xa5, 0x24,
- 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8,
- 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e,
- 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4,
- 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34,
- 0xf8, 0x9e, 0x83, 0x8f, 0x01, 0x00, 0x05, 0x3c, 0x80, 0x00, 0x63, 0x34, 0x00,
- 0x00, 0x43, 0xa4, 0x00, 0x00, 0x42, 0x94, 0xf8, 0x9e, 0x83, 0xaf, 0x20, 0x00,
- 0x42, 0x30, 0x1f, 0x00, 0x40, 0x14, 0x9f, 0x86, 0xa5, 0x34, 0x01, 0xa2, 0x08,
- 0x3c, 0x66, 0x66, 0x06, 0x3c, 0x67, 0x66, 0xc6, 0x34, 0x01, 0xa2, 0x04, 0x3c,
- 0x0c, 0x00, 0x84, 0x34, 0xff, 0xff, 0x07, 0x24, 0x18, 0x00, 0xa6, 0x00, 0x00,
- 0x00, 0x00, 0xa5, 0xc3, 0x17, 0x05, 0x00, 0x10, 0x48, 0x00, 0x00, 0x83, 0x18,
- 0x09, 0x00, 0x23, 0x18, 0x62, 0x00, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43,
- 0x00, 0x40, 0x10, 0x02, 0x00, 0x06, 0x00, 0xa2, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x38, 0xf8,
- 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x82, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0x07, 0x00,
- 0xa7, 0x10, 0x01, 0xa2, 0x02, 0x3c, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x42, 0x30, 0xea, 0xff, 0x40, 0x10, 0x18, 0x00, 0xa6, 0x00,
- 0x01, 0xa2, 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34, 0x63, 0x00, 0x05, 0x24, 0xff,
- 0xff, 0x06, 0x24, 0xf8, 0x9e, 0x83, 0x8f, 0x3f, 0xff, 0x04, 0x24, 0x24, 0x18,
- 0x64, 0x00, 0xf8, 0x9e, 0x83, 0xaf, 0x00, 0x00, 0x43, 0xa4, 0xff, 0xff, 0xa5,
- 0x24, 0xff, 0xff, 0xa6, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x01, 0xa2, 0x03, 0x3c,
- 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24, 0xf8, 0x9e, 0x82, 0x8f, 0xff,
- 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00,
- 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff, 0xa4, 0x14, 0xff, 0xff, 0xa5,
- 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x0c, 0x00, 0x63, 0x34, 0x63, 0x00, 0x05, 0x24,
- 0xf8, 0x9e, 0x82, 0x8f, 0xff, 0xff, 0x04, 0x24, 0x40, 0x00, 0x42, 0x38, 0xf8,
- 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x62, 0xa4, 0xff, 0xff, 0xa5, 0x24, 0xff, 0xff,
- 0xa4, 0x14, 0xff, 0xff, 0xa5, 0x24, 0x09, 0x00, 0x04, 0x24, 0x28, 0x31, 0x00,
- 0x0c, 0x00, 0x01, 0x05, 0x24, 0xbd, 0x31, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02,
- 0x20, 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00,
- 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80,
- 0x00, 0x1c, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0xbd, 0x31, 0x00, 0x0c,
- 0x10, 0x00, 0xb0, 0xaf, 0x03, 0x00, 0x24, 0x26, 0xbd, 0x31, 0x00, 0x0c, 0x21,
- 0x80, 0x40, 0x00, 0x00, 0x84, 0x10, 0x00, 0x03, 0x94, 0x10, 0x00, 0x00, 0x14,
- 0x02, 0x00, 0x03, 0x84, 0x02, 0x00, 0x0a, 0x00, 0x50, 0x12, 0x21, 0x10, 0x00,
- 0x02, 0xbd, 0x31, 0x00, 0x0c, 0x06, 0x00, 0x24, 0x26, 0x00, 0x14, 0x02, 0x00,
- 0x03, 0x14, 0x02, 0x00, 0x04, 0x00, 0x42, 0x12, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x00, 0x00, 0x1c, 0x00,
- 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27,
- 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x10, 0x00, 0xb0, 0xaf, 0xff,
- 0xff, 0xb0, 0x30, 0x18, 0x00, 0xbf, 0xaf, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28,
- 0x00, 0x02, 0x03, 0x00, 0x24, 0x26, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x02, 0x06, 0x00, 0x24, 0x26, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02,
- 0x18, 0x00, 0xbf, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xff, 0xff, 0x84, 0x38, 0xff, 0xff,
- 0x82, 0x30, 0x42, 0x10, 0x02, 0x00, 0xc0, 0x23, 0x04, 0x00, 0x25, 0x10, 0x44,
- 0x00, 0x26, 0x10, 0xa2, 0x00, 0x08, 0x00, 0xe0, 0x03, 0xff, 0xff, 0x42, 0x30,
- 0xf8, 0xff, 0xbd, 0x27, 0x21, 0x40, 0x80, 0x00, 0xff, 0xff, 0x06, 0x34, 0x0d,
- 0x00, 0xa0, 0x18, 0x21, 0x38, 0x00, 0x00, 0x00, 0x80, 0x09, 0x24, 0x01, 0x00,
- 0xe7, 0x24, 0x00, 0x00, 0x04, 0x95, 0x02, 0x00, 0x08, 0x25, 0xff, 0xff, 0xc3,
- 0x30, 0x42, 0x18, 0x03, 0x00, 0xc0, 0x13, 0x06, 0x00, 0x24, 0x10, 0x49, 0x00,
- 0x25, 0x18, 0x62, 0x00, 0x2a, 0x10, 0xe5, 0x00, 0xf6, 0xff, 0x40, 0x14, 0x26,
- 0x30, 0x83, 0x00, 0xff, 0xff, 0xc2, 0x30, 0x08, 0x00, 0xe0, 0x03, 0x08, 0x00,
- 0xbd, 0x27, 0xd0, 0xff, 0xbd, 0x27, 0x28, 0x00, 0xb4, 0xaf, 0x21, 0xa0, 0x80,
- 0x00, 0x24, 0x00, 0xb3, 0xaf, 0x21, 0x98, 0xa0, 0x00, 0x1c, 0x00, 0xb1, 0xaf,
- 0x21, 0x88, 0xc0, 0x00, 0x20, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x02, 0x18,
- 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x00, 0x00, 0x0a, 0x00, 0x60, 0x1a, 0x2c, 0x00,
- 0xbf, 0xaf, 0xff, 0xff, 0x24, 0x32, 0x00, 0x00, 0x45, 0x96, 0x01, 0x00, 0x10,
- 0x26, 0x01, 0x00, 0x31, 0x26, 0xca, 0x31, 0x00, 0x0c, 0x02, 0x00, 0x52, 0x26,
- 0x2a, 0x10, 0x13, 0x02, 0xf9, 0xff, 0x40, 0x14, 0xff, 0xff, 0x24, 0x32, 0x21,
- 0x20, 0x80, 0x02, 0x0d, 0x33, 0x00, 0x0c, 0x21, 0x28, 0x60, 0x02, 0xff, 0xff,
- 0x24, 0x32, 0xca, 0x31, 0x00, 0x0c, 0xff, 0xff, 0x45, 0x30, 0x2c, 0x00, 0xbf,
- 0x8f, 0x28, 0x00, 0xb4, 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f,
- 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30,
- 0x00, 0xbd, 0x27, 0xd0, 0xff, 0xbd, 0x27, 0x28, 0x00, 0xb4, 0xaf, 0x21, 0xa0,
- 0x80, 0x00, 0x24, 0x00, 0xb3, 0xaf, 0x21, 0x98, 0xa0, 0x00, 0x1c, 0x00, 0xb1,
- 0xaf, 0x21, 0x88, 0xc0, 0x00, 0x20, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x02,
- 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x00, 0x00, 0x09, 0x00, 0x60, 0x1a, 0x2c,
- 0x00, 0xbf, 0xaf, 0xbd, 0x31, 0x00, 0x0c, 0xff, 0xff, 0x24, 0x32, 0x00, 0x00,
- 0x42, 0xa6, 0x01, 0x00, 0x10, 0x26, 0x01, 0x00, 0x31, 0x26, 0x2a, 0x10, 0x13,
- 0x02, 0xf9, 0xff, 0x40, 0x14, 0x02, 0x00, 0x52, 0x26, 0xbd, 0x31, 0x00, 0x0c,
- 0xff, 0xff, 0x24, 0x32, 0x21, 0x20, 0x80, 0x02, 0x21, 0x80, 0x40, 0x00, 0x0d,
- 0x33, 0x00, 0x0c, 0x21, 0x28, 0x60, 0x02, 0x26, 0x80, 0x02, 0x02, 0xff, 0xff,
- 0x10, 0x32, 0x01, 0x00, 0x02, 0x2e, 0x2c, 0x00, 0xbf, 0x8f, 0x28, 0x00, 0xb4,
- 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f,
- 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0xe0,
- 0xff, 0xbd, 0x27, 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x10, 0x00,
- 0xa5, 0x27, 0x12, 0x00, 0xa6, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x1f, 0x34, 0x00,
- 0x0c, 0x14, 0x00, 0xa7, 0x27, 0x10, 0x00, 0xa4, 0x97, 0x12, 0x00, 0xa5, 0x97,
- 0x14, 0x00, 0xa6, 0x97, 0xb2, 0x34, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x04, 0x26, 0x04, 0x00, 0x05, 0x24, 0x21, 0x33, 0x00, 0x0c, 0x1b, 0x00,
- 0x06, 0x24, 0x21, 0x10, 0x00, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27,
- 0x20, 0x00, 0xbf, 0xaf, 0x18, 0x00, 0x82, 0x8c, 0x06, 0x00, 0x05, 0x24, 0x10,
- 0x00, 0xa2, 0xaf, 0x1c, 0x00, 0x82, 0x8c, 0x20, 0x00, 0x06, 0x24, 0x14, 0x00,
- 0xa2, 0xaf, 0x20, 0x00, 0x82, 0x8c, 0x10, 0x00, 0xa4, 0x27, 0x21, 0x33, 0x00,
- 0x0c, 0x18, 0x00, 0xa2, 0xaf, 0x20, 0x00, 0xbf, 0x8f, 0x21, 0x10, 0x00, 0x00,
- 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xff, 0xff, 0xe7, 0x30, 0x10,
- 0x00, 0xa8, 0x8f, 0x04, 0x00, 0x02, 0x24, 0x10, 0x00, 0x00, 0xad, 0x0d, 0x00,
- 0xe2, 0x10, 0x14, 0x00, 0x00, 0xad, 0x05, 0x00, 0xe2, 0x28, 0x05, 0x00, 0x40,
- 0x10, 0x02, 0x00, 0x02, 0x24, 0x08, 0x00, 0xe2, 0x10, 0xff, 0xff, 0xc2, 0x30,
- 0xc2, 0x33, 0x00, 0x08, 0xc0, 0x13, 0x02, 0x00, 0x08, 0x00, 0x02, 0x24, 0x1e,
- 0x00, 0xe2, 0x10, 0xff, 0xff, 0xc2, 0x30, 0xc2, 0x33, 0x00, 0x08, 0xc0, 0x13,
- 0x02, 0x00, 0x0c, 0x00, 0xa3, 0x30, 0x04, 0x00, 0x02, 0x24, 0x06, 0x00, 0x62,
- 0x10, 0x10, 0x00, 0x00, 0xad, 0x08, 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10,
- 0x00, 0x02, 0x02, 0x24, 0xb0, 0x33, 0x00, 0x08, 0x30, 0x00, 0xa5, 0x30, 0xb0,
- 0x33, 0x00, 0x08, 0x30, 0x00, 0xa5, 0x30, 0x10, 0x00, 0x02, 0xad, 0x30, 0x00,
- 0xa5, 0x30, 0x10, 0x00, 0x02, 0x24, 0x08, 0x00, 0xa2, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x02, 0x24, 0x0c, 0x00, 0xa2, 0x14, 0xff, 0xff, 0xc2, 0x30,
- 0x10, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x33, 0x00, 0x08, 0x10,
- 0x00, 0x02, 0xad, 0x10, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x33,
- 0x00, 0x08, 0x40, 0x00, 0x42, 0x34, 0x81, 0x04, 0x02, 0x24, 0x10, 0x00, 0x02,
- 0xad, 0xff, 0xff, 0xc2, 0x30, 0xc0, 0x13, 0x02, 0x00, 0x07, 0x00, 0x03, 0x3c,
- 0x00, 0x80, 0x63, 0x34, 0x24, 0x10, 0x43, 0x00, 0x02, 0x32, 0x04, 0x00, 0x10,
- 0x00, 0x03, 0x8d, 0x40, 0x00, 0xc5, 0x30, 0x25, 0x10, 0x62, 0x00, 0x21, 0x18,
- 0x80, 0x00, 0x05, 0x00, 0xa0, 0x10, 0x10, 0x00, 0x02, 0xad, 0x04, 0x00, 0xa0,
- 0x14, 0x00, 0x40, 0x42, 0x34, 0xd3, 0x33, 0x00, 0x08, 0x80, 0x00, 0xc2, 0x30,
- 0x00, 0x20, 0x42, 0x34, 0x10, 0x00, 0x02, 0xad, 0x80, 0x00, 0xc2, 0x30, 0x05,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x40, 0x14, 0xc2, 0x18,
- 0x03, 0x00, 0x19, 0x34, 0x00, 0x08, 0x07, 0x00, 0x03, 0x3c, 0x10, 0x00, 0x02,
- 0x8d, 0x18, 0x00, 0xc3, 0x30, 0x10, 0x00, 0x02, 0xad, 0x08, 0x00, 0x02, 0x24,
- 0x13, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x62, 0x28, 0x05,
- 0x00, 0x40, 0x10, 0x10, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x60, 0x10, 0x20, 0x00,
- 0xc2, 0x30, 0xfe, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x62,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x24, 0x0f, 0x00, 0x62, 0x10,
- 0x20, 0x00, 0xc2, 0x30, 0xfe, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x33, 0x00, 0x08, 0x14, 0x00,
- 0x02, 0xad, 0x14, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x33, 0x00,
- 0x08, 0x01, 0x00, 0x42, 0x34, 0x14, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00,
- 0xfc, 0x33, 0x00, 0x08, 0x02, 0x00, 0x42, 0x34, 0x14, 0x00, 0x02, 0x8d, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, 0x34, 0x14, 0x00, 0x02, 0xad, 0x20, 0x00,
- 0xc2, 0x30, 0x07, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40,
- 0x10, 0x07, 0x00, 0x03, 0x3c, 0x14, 0x00, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x00,
- 0x19, 0x34, 0x00, 0x08, 0x14, 0x00, 0x02, 0xad, 0x14, 0x00, 0x02, 0x8d, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x34, 0x18, 0x34, 0x00, 0x08, 0x14, 0x00,
- 0x02, 0xad, 0x07, 0x00, 0x63, 0x30, 0x10, 0x00, 0x02, 0x8d, 0xfd, 0xff, 0x63,
- 0x24, 0x00, 0x10, 0x42, 0x34, 0x10, 0x00, 0x02, 0xad, 0x40, 0x11, 0x03, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x14,
- 0x00, 0x03, 0x8d, 0x0a, 0x00, 0x42, 0x24, 0x25, 0x18, 0x62, 0x00, 0x14, 0x00,
- 0x03, 0xad, 0x07, 0x00, 0x03, 0x3c, 0x10, 0x00, 0x02, 0x8d, 0xff, 0xff, 0x63,
- 0x34, 0x24, 0x10, 0x43, 0x00, 0x10, 0x00, 0x02, 0xad, 0x08, 0x00, 0xe0, 0x03,
- 0x21, 0x10, 0x00, 0x00, 0x21, 0x58, 0x00, 0x00, 0x21, 0x18, 0x00, 0x00, 0x10,
- 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x48, 0x30, 0x06, 0x00,
- 0x00, 0x11, 0x21, 0x50, 0x00, 0x00, 0x40, 0x00, 0x02, 0x24, 0x06, 0x00, 0x02,
- 0x11, 0x01, 0x00, 0x48, 0x35, 0x30, 0x34, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x0a, 0x24, 0x2f, 0x34, 0x00, 0x08, 0x40, 0x00, 0x0b, 0x24, 0x10,
- 0x00, 0x0a, 0x24, 0x01, 0x00, 0x48, 0x35, 0x10, 0x00, 0x82, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0e, 0x49, 0x30, 0x06, 0x00, 0x20, 0x11, 0x21, 0x50, 0x00,
- 0x01, 0x00, 0x02, 0x02, 0x24, 0x05, 0x00, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x3d, 0x34, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x34, 0x00, 0x08, 0x04,
- 0x00, 0x0a, 0x35, 0x08, 0x00, 0x0a, 0x35, 0x10, 0x00, 0x82, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x2b, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x34, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x48, 0x30, 0x01, 0x00, 0x02, 0x24, 0x09, 0x00, 0x02, 0x11, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0x00, 0x11, 0x02, 0x00, 0x02, 0x24, 0x07, 0x00, 0x02,
- 0x11, 0x03, 0x00, 0x02, 0x24, 0x07, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x59, 0x34, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x59, 0x34, 0x00, 0x08, 0x08,
- 0x00, 0x63, 0x34, 0x59, 0x34, 0x00, 0x08, 0x10, 0x00, 0x63, 0x34, 0x18, 0x00,
- 0x63, 0x34, 0x14, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42,
- 0x30, 0x11, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x34, 0x00, 0x08,
- 0x20, 0x00, 0x63, 0x34, 0x14, 0x00, 0x88, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x90,
- 0x02, 0x02, 0x2d, 0x02, 0x00, 0x40, 0x14, 0x80, 0x00, 0x63, 0x34, 0x8f, 0x02,
- 0x08, 0x24, 0x60, 0xf6, 0x02, 0x3c, 0x99, 0x3d, 0x42, 0x34, 0x19, 0x00, 0x02,
- 0x01, 0x10, 0x60, 0x00, 0x00, 0xc2, 0x11, 0x0c, 0x00, 0x03, 0x00, 0x42, 0x24,
- 0xc0, 0x10, 0x02, 0x00, 0x25, 0x58, 0x62, 0x01, 0x10, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x48, 0x30, 0x00, 0x20, 0x02, 0x24, 0x10, 0x00,
- 0x02, 0x11, 0x01, 0x00, 0x62, 0x35, 0x01, 0x20, 0x02, 0x2d, 0x05, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x83, 0x34, 0x00, 0x08, 0x01, 0x00, 0x62, 0x35, 0x00, 0x40, 0x02, 0x24, 0x04,
- 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x24, 0x02, 0x00,
- 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x63, 0x34, 0x01, 0x00, 0x62,
- 0x35, 0x01, 0x00, 0x63, 0x34, 0x00, 0x1a, 0x03, 0x00, 0x25, 0x10, 0x43, 0x00,
- 0x00, 0x00, 0xa2, 0xa4, 0x00, 0x00, 0xca, 0xa4, 0x10, 0x00, 0x82, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0xc2, 0x13, 0x02, 0x00, 0x0f, 0x00, 0x42, 0x30, 0x00, 0x00,
- 0xe2, 0xa4, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xe0, 0xff, 0xbd,
- 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0xb1, 0xaf,
- 0x21, 0x88, 0xa0, 0x00, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0xc0, 0x00, 0x1c,
- 0x00, 0xbf, 0xaf, 0xbd, 0x31, 0x00, 0x0c, 0x10, 0x00, 0x04, 0x24, 0x11, 0x00,
- 0x04, 0x24, 0xbd, 0x31, 0x00, 0x0c, 0x00, 0x00, 0x02, 0xa6, 0x19, 0x00, 0x04,
- 0x24, 0xbd, 0x31, 0x00, 0x0c, 0x00, 0x00, 0x22, 0xa6, 0x12, 0x00, 0x04, 0x24,
- 0xbd, 0x31, 0x00, 0x0c, 0x00, 0x00, 0x42, 0xa6, 0x00, 0x00, 0x04, 0x96, 0x00,
- 0x00, 0x25, 0x96, 0x00, 0x00, 0x00, 0x00, 0x05, 0x33, 0x00, 0x0c, 0x21, 0x80,
- 0x40, 0x00, 0x00, 0x84, 0x10, 0x00, 0x03, 0x84, 0x10, 0x00, 0xff, 0xff, 0x42,
- 0x30, 0x26, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x2e, 0x1c, 0x00, 0xbf, 0x8f,
- 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27, 0x10, 0x00,
- 0xb0, 0xaf, 0x21, 0x80, 0xa0, 0x00, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0xc0,
- 0x00, 0x14, 0x00, 0xb1, 0xaf, 0xff, 0xff, 0x91, 0x30, 0x10, 0x00, 0x04, 0x24,
- 0x1c, 0x00, 0xbf, 0xaf, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x13,
- 0x00, 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x16, 0x00,
- 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x20, 0x02, 0x11, 0x00, 0x04,
- 0x24, 0xff, 0xff, 0x10, 0x32, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02,
- 0x14, 0x00, 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x17,
- 0x00, 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x21, 0x20,
- 0x20, 0x02, 0x05, 0x33, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x12, 0x00, 0x04,
- 0x24, 0xff, 0xff, 0x50, 0x30, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02,
- 0x15, 0x00, 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x18,
- 0x00, 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x19, 0x00,
- 0x04, 0x24, 0xca, 0x31, 0x00, 0x0c, 0xff, 0xff, 0x45, 0x32, 0x1c, 0x00, 0xbf,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10,
- 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00, 0x10, 0x00, 0x04, 0x26, 0x04, 0x00,
- 0x05, 0x24, 0x14, 0x00, 0xbf, 0xaf, 0x45, 0x33, 0x00, 0x0c, 0x1b, 0x00, 0x06,
- 0x24, 0x07, 0x00, 0x04, 0x3c, 0x10, 0x00, 0x03, 0x8e, 0xff, 0xff, 0x84, 0x34,
- 0x24, 0x18, 0x64, 0x00, 0x10, 0x00, 0x03, 0xae, 0x14, 0x00, 0xbf, 0x8f, 0x10,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xe8, 0xff,
- 0xbd, 0x27, 0x07, 0x00, 0x03, 0x3c, 0xff, 0xff, 0x63, 0x34, 0x04, 0x00, 0x05,
- 0x24, 0x10, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0x82, 0x8c, 0x1b, 0x00, 0x06, 0x24,
- 0x24, 0x10, 0x43, 0x00, 0x10, 0x00, 0x82, 0xac, 0x21, 0x33, 0x00, 0x0c, 0x10,
- 0x00, 0x84, 0x24, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00,
- 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xb0,
- 0xaf, 0x21, 0x80, 0x80, 0x00, 0x10, 0x00, 0xa4, 0x27, 0x06, 0x00, 0x05, 0x24,
- 0x24, 0x00, 0xbf, 0xaf, 0x45, 0x33, 0x00, 0x0c, 0x20, 0x00, 0x06, 0x24, 0x10,
- 0x00, 0x00, 0xae, 0x14, 0x00, 0x00, 0xae, 0x10, 0x00, 0xa3, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x03, 0xae, 0x14, 0x00, 0xa3, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x03, 0xae, 0x18, 0x00, 0xa3, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x03, 0xae, 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xc8, 0xff, 0xbd, 0x27, 0x24, 0x00,
- 0xb1, 0xaf, 0x21, 0x88, 0xa0, 0x00, 0x30, 0x00, 0xb4, 0xaf, 0x21, 0xa0, 0xc0,
- 0x00, 0x18, 0x00, 0xa4, 0x27, 0x1a, 0x00, 0xa5, 0x27, 0x28, 0x00, 0xb2, 0xaf,
- 0x48, 0x00, 0xb2, 0x97, 0x1c, 0x00, 0xa6, 0x27, 0x34, 0x00, 0xbf, 0xaf, 0x2c,
- 0x00, 0xb3, 0xaf, 0x8f, 0x34, 0x00, 0x0c, 0x20, 0x00, 0xb0, 0xaf, 0x2b, 0x80,
- 0x02, 0x00, 0x21, 0x98, 0x00, 0x02, 0xe3, 0x34, 0x00, 0x0c, 0x21, 0x20, 0x20,
- 0x02, 0x03, 0x00, 0x40, 0x10, 0x21, 0x18, 0x60, 0x02, 0x02, 0x00, 0x13, 0x36,
- 0x21, 0x18, 0x60, 0x02, 0x01, 0x00, 0x02, 0x24, 0x15, 0x00, 0x62, 0x10, 0x02,
- 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10, 0x04, 0x00, 0x62, 0x28, 0x07, 0x00,
- 0x60, 0x10, 0xff, 0xff, 0x47, 0x32, 0x5b, 0x35, 0x00, 0x08, 0x04, 0x00, 0x02,
- 0x24, 0x1f, 0x00, 0x40, 0x10, 0x21, 0x20, 0x20, 0x02, 0x51, 0x35, 0x00, 0x08,
- 0x18, 0x00, 0xa5, 0x27, 0x59, 0x69, 0x04, 0x24, 0x25, 0x00, 0x05, 0x24, 0x00,
- 0x80, 0x06, 0x34, 0x59, 0x69, 0x02, 0x24, 0x18, 0x00, 0xa2, 0xa7, 0x25, 0x00,
- 0x02, 0x24, 0x1a, 0x00, 0xa2, 0xa7, 0x00, 0x80, 0x02, 0x24, 0xb2, 0x34, 0x00,
- 0x0c, 0x1c, 0x00, 0xa2, 0xa7, 0x18, 0x00, 0xa4, 0x97, 0x1a, 0x00, 0xa5, 0x97,
- 0x1c, 0x00, 0xa6, 0x97, 0x21, 0x38, 0x40, 0x02, 0x91, 0x33, 0x00, 0x0c, 0x10,
- 0x00, 0xb1, 0xaf, 0xf4, 0x34, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x5a, 0x35,
- 0x00, 0x08, 0xff, 0xff, 0x47, 0x32, 0x1a, 0x00, 0xa6, 0x27, 0x1f, 0x34, 0x00,
- 0x0c, 0x1c, 0x00, 0xa7, 0x27, 0x18, 0x00, 0xa4, 0x97, 0x1a, 0x00, 0xa5, 0x97,
- 0x1c, 0x00, 0xa6, 0x97, 0xb2, 0x34, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x47, 0x32, 0x04, 0x00, 0x02, 0x24, 0x0c, 0x00, 0xe2, 0x10, 0x05, 0x00,
- 0xe2, 0x28, 0x05, 0x00, 0x40, 0x10, 0x02, 0x00, 0x02, 0x24, 0x08, 0x00, 0xe2,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x35, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x24, 0x1a, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x00, 0x8c,
- 0x35, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x25, 0x8e, 0x01, 0x00,
- 0x02, 0x24, 0x07, 0x00, 0xa3, 0x30, 0x20, 0x00, 0x62, 0x14, 0xf8, 0xff, 0x02,
- 0x3c, 0x38, 0x70, 0x42, 0x34, 0x21, 0x20, 0x20, 0x02, 0x24, 0x10, 0xa2, 0x00,
- 0x00, 0x80, 0x42, 0x34, 0xf4, 0x34, 0x00, 0x0c, 0x10, 0x00, 0x22, 0xae, 0x21,
- 0x20, 0x20, 0x02, 0x18, 0x00, 0xa5, 0x27, 0x1a, 0x00, 0xa6, 0x27, 0x1f, 0x34,
- 0x00, 0x0c, 0x1c, 0x00, 0xa7, 0x27, 0x18, 0x00, 0xa4, 0x97, 0x1a, 0x00, 0xa5,
- 0x97, 0x1c, 0x00, 0xa6, 0x97, 0xb2, 0x34, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x8c, 0x35, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x24, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x00, 0x82, 0x30, 0x09, 0x00, 0x40, 0x14, 0xf8, 0xff,
- 0x02, 0x3c, 0x38, 0x70, 0x42, 0x34, 0x01, 0x00, 0x03, 0x3c, 0x81, 0x84, 0x63,
- 0x34, 0x24, 0x10, 0x82, 0x00, 0x25, 0x10, 0x43, 0x00, 0x10, 0x00, 0x22, 0xae,
- 0xf4, 0x34, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x03, 0x35, 0x00, 0x0c, 0x21,
- 0x20, 0x80, 0x02, 0x07, 0x00, 0x40, 0x14, 0x21, 0x10, 0x60, 0x02, 0x21, 0x20,
- 0x80, 0x02, 0x18, 0x00, 0x80, 0xac, 0x1c, 0x00, 0x80, 0xac, 0x81, 0x33, 0x00,
- 0x0c, 0x20, 0x00, 0x80, 0xac, 0x21, 0x10, 0x60, 0x02, 0x34, 0x00, 0xbf, 0x8f,
- 0x30, 0x00, 0xb4, 0x8f, 0x2c, 0x00, 0xb3, 0x8f, 0x28, 0x00, 0xb2, 0x8f, 0x24,
- 0x00, 0xb1, 0x8f, 0x20, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00,
- 0xbd, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbd,
- 0x27, 0x00, 0xa2, 0x02, 0x3c, 0x00, 0x80, 0x42, 0x34, 0x1c, 0x00, 0xbf, 0xaf,
- 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x00,
- 0x00, 0x43, 0x90, 0x70, 0x8b, 0x82, 0x93, 0x27, 0x18, 0x03, 0x00, 0x26, 0x10,
- 0x43, 0x00, 0x1f, 0x00, 0x42, 0x30, 0x20, 0x00, 0x40, 0x10, 0x21, 0x18, 0x40,
- 0x00, 0x00, 0xa2, 0x12, 0x3c, 0x00, 0x80, 0x52, 0x36, 0x21, 0x80, 0x00, 0x00,
- 0xff, 0x00, 0x71, 0x30, 0x07, 0x10, 0x11, 0x02, 0x01, 0x00, 0x42, 0x30, 0x0d,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8b, 0x82, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x07, 0x10, 0x02, 0x02, 0x01, 0x00, 0x42, 0x30, 0x05, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x36, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0xc3, 0x35, 0x00, 0x08, 0x01, 0x00, 0x10, 0x26, 0xdc, 0x35, 0x00, 0x0c, 0x21,
- 0x20, 0x00, 0x02, 0x01, 0x00, 0x10, 0x26, 0x05, 0x00, 0x02, 0x2a, 0xee, 0xff,
- 0x40, 0x14, 0x07, 0x10, 0x11, 0x02, 0x00, 0x00, 0x43, 0x92, 0x70, 0x8b, 0x82,
- 0x93, 0x27, 0x18, 0x03, 0x00, 0x26, 0x10, 0x43, 0x00, 0x1f, 0x00, 0x42, 0x30,
- 0xe4, 0xff, 0x40, 0x14, 0x21, 0x18, 0x40, 0x00, 0x74, 0x8b, 0x84, 0x8f, 0xf2,
- 0x36, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x04, 0x3c, 0x70, 0x8b,
- 0x83, 0x93, 0x00, 0x80, 0x84, 0x34, 0x80, 0x00, 0x62, 0x34, 0x00, 0x00, 0x82,
- 0xa0, 0x00, 0x00, 0x83, 0xa0, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f,
- 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0xa8, 0xff, 0xbd, 0x27, 0x21, 0x40, 0x80, 0x00, 0x3c, 0x00,
- 0xb3, 0xaf, 0x21, 0x98, 0x00, 0x00, 0x00, 0xa2, 0x06, 0x3c, 0x04, 0x40, 0xc6,
- 0x34, 0x00, 0xa2, 0x04, 0x3c, 0x00, 0x40, 0x84, 0x34, 0x00, 0xa2, 0x05, 0x3c,
- 0x00, 0x80, 0xa5, 0x34, 0x21, 0x38, 0x00, 0x00, 0x01, 0xa2, 0x09, 0x3c, 0x54,
- 0x00, 0xbf, 0xaf, 0x50, 0x00, 0xbe, 0xaf, 0x4c, 0x00, 0xb7, 0xaf, 0x48, 0x00,
- 0xb6, 0xaf, 0x44, 0x00, 0xb5, 0xaf, 0x40, 0x00, 0xb4, 0xaf, 0x38, 0x00, 0xb2,
- 0xaf, 0x34, 0x00, 0xb1, 0xaf, 0x30, 0x00, 0xb0, 0xaf, 0x02, 0x80, 0x02, 0x3c,
- 0x21, 0x10, 0x48, 0x00, 0x31, 0xa9, 0x42, 0x90, 0xd0, 0x9a, 0x97, 0x8f, 0x70,
- 0x8b, 0x83, 0x93, 0x00, 0x39, 0x5e, 0x34, 0x01, 0x00, 0x02, 0x24, 0x04, 0x10,
- 0x02, 0x01, 0x25, 0x18, 0x62, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x00, 0x00, 0x80,
- 0xa4, 0x70, 0x8b, 0x83, 0xa3, 0x00, 0x00, 0xa3, 0xa0, 0x00, 0x00, 0x20, 0xa5,
- 0x01, 0x00, 0xe7, 0x24, 0x10, 0x27, 0xe2, 0x28, 0xfc, 0xff, 0x40, 0x14, 0x01,
- 0xa2, 0x03, 0x3c, 0x00, 0x12, 0x63, 0x34, 0x01, 0x00, 0x73, 0x36, 0x40, 0x12,
- 0x08, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x53, 0xa0, 0x01, 0x00, 0x12,
- 0x24, 0x01, 0xa2, 0x03, 0x3c, 0x21, 0x20, 0x40, 0x00, 0x01, 0x00, 0x05, 0x24,
- 0x21, 0x38, 0x00, 0x00, 0x00, 0x00, 0x60, 0xa4, 0x01, 0x00, 0xe7, 0x24, 0x10,
- 0x27, 0xe2, 0x28, 0xfc, 0xff, 0x40, 0x14, 0x04, 0x10, 0x45, 0x02, 0x25, 0x98,
- 0x62, 0x02, 0x00, 0x00, 0x93, 0xa0, 0x01, 0x00, 0x52, 0x26, 0x06, 0x00, 0x42,
- 0x2a, 0xf6, 0xff, 0x40, 0x14, 0x21, 0x38, 0x00, 0x00, 0x21, 0x98, 0x00, 0x00,
- 0x21, 0x90, 0x00, 0x00, 0x40, 0x10, 0x08, 0x00, 0x21, 0x10, 0x48, 0x00, 0x40,
- 0x10, 0x02, 0x00, 0x00, 0xa2, 0x0a, 0x3c, 0x04, 0x40, 0x4a, 0x35, 0x00, 0xa2,
- 0x14, 0x3c, 0x00, 0x40, 0x94, 0x36, 0x40, 0x42, 0x08, 0x00, 0x10, 0x00, 0xa2,
- 0xaf, 0x18, 0x00, 0xaa, 0xaf, 0x28, 0x00, 0xa8, 0xaf, 0x10, 0x00, 0xaa, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x52, 0x01, 0x02, 0x00, 0x01, 0x06, 0x21,
- 0x18, 0x00, 0x02, 0x0f, 0x00, 0x03, 0x26, 0x00, 0xa0, 0x05, 0x3c, 0x00, 0x10,
- 0xa5, 0x34, 0x01, 0x00, 0x0a, 0x24, 0x04, 0x50, 0x0a, 0x02, 0x03, 0x19, 0x03,
- 0x00, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00,
- 0x23, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03, 0x3c, 0x60,
- 0xcd, 0x63, 0x24, 0x21, 0xb0, 0x43, 0x00, 0xc0, 0x11, 0x10, 0x00, 0x21, 0xa8,
- 0x45, 0x00, 0x20, 0x00, 0xaa, 0xaf, 0x04, 0x00, 0xc3, 0x8e, 0x28, 0x00, 0xaa,
- 0x8f, 0xd4, 0x9a, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c,
- 0x21, 0x88, 0x6a, 0x00, 0x21, 0x20, 0x40, 0x00, 0x3b, 0x12, 0x00, 0x0c, 0x24,
- 0x00, 0xa0, 0xae, 0x21, 0x38, 0x00, 0x00, 0xff, 0x00, 0x64, 0x32, 0x01, 0x00,
- 0x0a, 0x24, 0x04, 0x10, 0x4a, 0x02, 0x25, 0x28, 0x82, 0x00, 0xd0, 0x9a, 0x82,
- 0x8f, 0x01, 0xa2, 0x01, 0x3c, 0x00, 0x00, 0x20, 0xa4, 0x23, 0x10, 0x57, 0x00,
- 0xf4, 0x01, 0x42, 0x2c, 0x06, 0x00, 0x40, 0x10, 0x80, 0x00, 0xc2, 0x37, 0x18,
- 0x00, 0xaa, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0x59, 0x36,
- 0x00, 0x08, 0x00, 0x00, 0x85, 0xa6, 0x18, 0x00, 0xaa, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0xa5, 0x00, 0x00, 0x84, 0xa6, 0xd0, 0x9a, 0x83, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x77, 0x00, 0xe8, 0x03, 0x42, 0x2c, 0x02,
- 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0xb8, 0x60, 0x00, 0x18, 0x00,
- 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x30, 0x1d, 0x00, 0x40,
- 0x10, 0x4c, 0x00, 0x02, 0x3c, 0x27, 0x10, 0x10, 0x00, 0x1c, 0x00, 0x30, 0xa2,
- 0x18, 0x00, 0x22, 0xa2, 0x1c, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x42, 0x30, 0x1a, 0x00, 0x50, 0x14, 0x01, 0x00, 0x0a, 0x24, 0x00, 0x37,
- 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xd4, 0x9a, 0x84, 0x8f, 0x32, 0x12, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0xa0, 0x02, 0x24, 0x00, 0x91, 0xac,
- 0x18, 0x00, 0xc3, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x60, 0x00, 0x21,
- 0x80, 0x40, 0x00, 0x74, 0x8b, 0x82, 0x8f, 0x20, 0x00, 0xaa, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x25, 0x10, 0x4a, 0x00, 0x74, 0x8b, 0x82, 0xaf, 0x3b, 0x12, 0x00,
- 0x0c, 0x21, 0x20, 0x00, 0x02, 0x86, 0x36, 0x00, 0x08, 0x01, 0x00, 0x0a, 0x24,
- 0x01, 0x00, 0xe7, 0x24, 0x3f, 0x4b, 0x42, 0x34, 0x2a, 0x10, 0x47, 0x00, 0xc4,
- 0xff, 0x40, 0x10, 0x01, 0x00, 0x0a, 0x24, 0x04, 0x10, 0x4a, 0x02, 0x25, 0x10,
- 0x62, 0x02, 0x21, 0x98, 0x40, 0x00, 0xff, 0x00, 0x42, 0x30, 0x01, 0x00, 0x52,
- 0x26, 0x00, 0x00, 0x82, 0xa6, 0x28, 0x00, 0xaa, 0x8f, 0x06, 0x00, 0x42, 0x2a,
- 0x20, 0x00, 0x4a, 0x25, 0x95, 0xff, 0x40, 0x14, 0x28, 0x00, 0xaa, 0xaf, 0x00,
- 0xa2, 0x06, 0x3c, 0x04, 0x40, 0xc6, 0x34, 0x00, 0xa2, 0x05, 0x3c, 0x00, 0x40,
- 0xa5, 0x34, 0x7c, 0x9b, 0x83, 0x97, 0x78, 0x9b, 0x84, 0x97, 0x21, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0xc3, 0xa4, 0x00, 0x00, 0xa4, 0xa4, 0x54, 0x00, 0xbf, 0x8f,
- 0x50, 0x00, 0xbe, 0x8f, 0x4c, 0x00, 0xb7, 0x8f, 0x48, 0x00, 0xb6, 0x8f, 0x44,
- 0x00, 0xb5, 0x8f, 0x40, 0x00, 0xb4, 0x8f, 0x3c, 0x00, 0xb3, 0x8f, 0x38, 0x00,
- 0xb2, 0x8f, 0x34, 0x00, 0xb1, 0x8f, 0x30, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0,
- 0x03, 0x58, 0x00, 0xbd, 0x27, 0xc8, 0xff, 0xbd, 0x27, 0x00, 0xa2, 0x05, 0x3c,
- 0x00, 0x80, 0xa5, 0x34, 0x1c, 0x00, 0xb3, 0xaf, 0x21, 0x98, 0x00, 0x00, 0x40,
- 0x10, 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, 0x24, 0x00, 0xb5, 0xaf, 0x40, 0xa8,
- 0x02, 0x00, 0x2c, 0x00, 0xb7, 0xaf, 0x02, 0x80, 0x17, 0x3c, 0x60, 0xcd, 0xf7,
- 0x26, 0x20, 0x00, 0xb4, 0xaf, 0x00, 0xa0, 0x14, 0x3c, 0x00, 0x10, 0x94, 0x36,
- 0x28, 0x00, 0xb6, 0xaf, 0x01, 0x00, 0x16, 0x24, 0x01, 0x00, 0x02, 0x24, 0x04,
- 0x10, 0x82, 0x00, 0x70, 0x8b, 0x83, 0x93, 0x27, 0x10, 0x02, 0x00, 0x30, 0x00,
- 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0,
- 0xaf, 0x24, 0x18, 0x62, 0x00, 0x70, 0x8b, 0x83, 0xa3, 0x00, 0x00, 0xa3, 0xa0,
- 0x21, 0x90, 0xb3, 0x02, 0x07, 0x37, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x02,
- 0x00, 0x41, 0x06, 0x21, 0x10, 0x40, 0x02, 0x0f, 0x00, 0x42, 0x26, 0x01, 0x00,
- 0x73, 0x26, 0x03, 0x11, 0x02, 0x00, 0x40, 0x88, 0x02, 0x00, 0x21, 0x88, 0x22,
- 0x02, 0x80, 0x88, 0x11, 0x00, 0x23, 0x88, 0x22, 0x02, 0x80, 0x88, 0x11, 0x00,
- 0x21, 0x88, 0x37, 0x02, 0xc0, 0x81, 0x12, 0x00, 0xd4, 0x9a, 0x84, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x0c, 0x21, 0x80, 0x14, 0x02, 0x21, 0x20,
- 0x00, 0x02, 0x24, 0x00, 0x80, 0xac, 0x54, 0x00, 0x80, 0xa0, 0x58, 0x00, 0x80,
- 0xa0, 0x18, 0x00, 0x23, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf8, 0x60, 0x00,
- 0x21, 0x80, 0x40, 0x00, 0x04, 0x10, 0x56, 0x02, 0x74, 0x8b, 0x83, 0x8f, 0x27,
- 0x10, 0x02, 0x00, 0x24, 0x18, 0x62, 0x00, 0x74, 0x8b, 0x83, 0xaf, 0x3b, 0x12,
- 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x06, 0x00, 0x62, 0x2a, 0xdc, 0xff, 0x40,
- 0x14, 0x21, 0x10, 0x00, 0x00, 0x30, 0x00, 0xbf, 0x8f, 0x2c, 0x00, 0xb7, 0x8f,
- 0x28, 0x00, 0xb6, 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c,
- 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00,
- 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00, 0xbd, 0x27, 0x21, 0x30, 0x80,
- 0x00, 0x21, 0x28, 0x00, 0x00, 0x80, 0x20, 0x05, 0x00, 0xc0, 0x18, 0x05, 0x00,
- 0x01, 0x00, 0xa5, 0x24, 0x50, 0xa0, 0x82, 0x8f, 0x06, 0x18, 0x66, 0x00, 0x21,
- 0x10, 0x44, 0x00, 0xa0, 0x00, 0x43, 0xa0, 0x04, 0x00, 0xa2, 0x28, 0xf7, 0xff,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0xa2, 0x03, 0x3c, 0x00, 0x1c, 0x63, 0x34, 0x80, 0x10, 0x04, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0x40, 0x00, 0x84, 0x34, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x44, 0xa4, 0x01, 0xa2, 0x03, 0x3c, 0x00, 0x1c, 0x63, 0x34, 0x80, 0x10,
- 0x04, 0x00, 0x21, 0x10, 0x43, 0x00, 0x3f, 0x00, 0x84, 0x30, 0x08, 0x00, 0xe0,
- 0x03, 0x00, 0x00, 0x44, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xd8, 0xff, 0xbd, 0x27, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x00, 0x24,
- 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x14, 0x00,
- 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x08, 0x00, 0x42, 0x8e, 0x21, 0x80, 0xa0,
- 0x00, 0x03, 0x00, 0x02, 0x16, 0x5b, 0x00, 0x11, 0x24, 0x26, 0x37, 0x00, 0x08,
- 0x5d, 0x00, 0x13, 0x24, 0x04, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x02, 0x16, 0x20, 0x00, 0x11, 0x24, 0x3c, 0x00, 0x11, 0x24, 0x26, 0x37,
- 0x00, 0x08, 0x3e, 0x00, 0x13, 0x24, 0x20, 0x00, 0x13, 0x24, 0xc0, 0x10, 0x10,
- 0x00, 0x23, 0x10, 0x50, 0x00, 0x40, 0xa0, 0x02, 0x00, 0xc0, 0x40, 0x00, 0x0c,
- 0x16, 0x00, 0x84, 0x26, 0x89, 0x40, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x80,
- 0x10, 0x10, 0x00, 0x21, 0x10, 0x52, 0x00, 0x10, 0x00, 0x46, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x03, 0x00, 0xc0, 0x10, 0x21, 0x20, 0x00, 0x00, 0xc6, 0x41, 0x00,
- 0x0c, 0x21, 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x20, 0x00, 0x84, 0x26,
- 0x89, 0x40, 0x00, 0x0c, 0x21, 0x20, 0x60, 0x02, 0x89, 0x40, 0x00, 0x0c, 0x20,
- 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x7c, 0x00, 0x04, 0x24, 0x24, 0x00,
- 0xbf, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x28, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x80, 0x00, 0x14, 0x00, 0xbf, 0xaf, 0xc0, 0x40, 0x00, 0x0c, 0x17, 0x00,
- 0x04, 0x24, 0x08, 0x00, 0x05, 0x8e, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0xa2, 0x14, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x8d, 0x84, 0x27,
- 0x5a, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8d, 0x84, 0x27, 0x83,
- 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x2a, 0x00,
- 0x04, 0x24, 0x04, 0x00, 0x05, 0x8e, 0x88, 0x8d, 0x84, 0x27, 0x83, 0x42, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x4c, 0x00, 0x04, 0x24,
- 0x21, 0x20, 0x00, 0x00, 0x90, 0x8d, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0x14, 0x00, 0xbf, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0xf8, 0xff, 0xbd, 0x27, 0x02, 0x80, 0x03,
- 0x3c, 0x50, 0x97, 0x63, 0x24, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x11, 0x00, 0x40, 0x10, 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x60, 0x00, 0x08,
- 0x00, 0xc3, 0x24, 0x05, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x78, 0x37, 0x00, 0x08, 0x08, 0x00, 0x62,
- 0xac, 0x08, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0xac,
- 0x00, 0x00, 0xc2, 0x90, 0x01, 0x00, 0xa5, 0x24, 0x2a, 0x10, 0xa2, 0x00, 0xf3,
- 0xff, 0x40, 0x14, 0x24, 0x00, 0x63, 0x24, 0x08, 0x00, 0xbd, 0x27, 0x08, 0x00,
- 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xbd, 0x27, 0x21, 0x30, 0x00,
- 0x00, 0x02, 0x80, 0x03, 0x3c, 0x50, 0x97, 0x63, 0x24, 0x00, 0x00, 0x62, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x10, 0x21, 0x20, 0x00, 0x00, 0x21,
- 0x38, 0x60, 0x00, 0x21, 0x28, 0x00, 0x00, 0xd0, 0x99, 0x83, 0x27, 0x02, 0x80,
- 0x02, 0x3c, 0x21, 0x10, 0x45, 0x00, 0x59, 0x97, 0x42, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xa0,
- 0x01, 0x00, 0x63, 0x24, 0x01, 0x00, 0xc6, 0x24, 0x00, 0x00, 0xe2, 0x90, 0x01,
- 0x00, 0x84, 0x24, 0x2a, 0x10, 0x82, 0x00, 0xf3, 0xff, 0x40, 0x14, 0x24, 0x00,
- 0xa5, 0x24, 0x0e, 0x00, 0xc2, 0x28, 0x0a, 0x00, 0x40, 0x10, 0xff, 0xff, 0xc4,
- 0x24, 0xd0, 0x99, 0x82, 0x27, 0x21, 0x18, 0xc2, 0x00, 0x02, 0x80, 0x05, 0x3c,
- 0xee, 0xb8, 0xa5, 0x24, 0x00, 0x00, 0x60, 0xa0, 0x01, 0x00, 0x63, 0x24, 0x2a,
- 0x10, 0x65, 0x00, 0xfc, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10,
- 0x80, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x08, 0x00, 0xbd, 0x27, 0x21, 0x30, 0x80,
- 0x00, 0x10, 0x00, 0xc2, 0x8c, 0x60, 0x8d, 0x83, 0x8f, 0x10, 0x00, 0xa2, 0xac,
- 0x14, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xa2, 0xac, 0x01,
- 0x00, 0x60, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00,
- 0x40, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x40,
- 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x40, 0xa0,
- 0x10, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x42, 0x30, 0x9b,
- 0x00, 0x40, 0x14, 0x01, 0x00, 0x02, 0x24, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x40, 0xac, 0x49, 0x00, 0x40, 0xa0, 0x60, 0x8d, 0x82,
- 0x8f, 0x01, 0x00, 0x04, 0x24, 0x25, 0x00, 0x44, 0xa0, 0x10, 0x00, 0xc2, 0x8c,
- 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x0e, 0x42, 0x30, 0x2b, 0x10, 0x02, 0x00, 0x2c,
- 0x00, 0x62, 0xac, 0x6d, 0x00, 0x64, 0xa0, 0x10, 0x00, 0xc2, 0x8c, 0x60, 0x8d,
- 0x83, 0x8f, 0xc0, 0x01, 0x42, 0x30, 0x2b, 0x10, 0x02, 0x00, 0x74, 0x00, 0x62,
- 0xac, 0xb5, 0x00, 0x64, 0xa0, 0x10, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x43, 0x30, 0x00, 0x20, 0x02, 0x24, 0x11, 0x00, 0x62, 0x10, 0x01,
- 0x20, 0x62, 0x2c, 0x05, 0x00, 0x40, 0x10, 0x00, 0x40, 0x02, 0x24, 0x09, 0x00,
- 0x60, 0x10, 0x07, 0x00, 0x04, 0x3c, 0xf4, 0x37, 0x00, 0x08, 0x00, 0x80, 0x84,
- 0x34, 0x0d, 0x00, 0x62, 0x10, 0x00, 0x60, 0x02, 0x24, 0x0f, 0x00, 0x62, 0x10,
- 0x07, 0x00, 0x04, 0x3c, 0xf4, 0x37, 0x00, 0x08, 0x00, 0x80, 0x84, 0x34, 0x60,
- 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x37, 0x00, 0x08, 0x02, 0x00,
- 0x02, 0x24, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x37, 0x00,
- 0x08, 0xbc, 0x00, 0x40, 0xac, 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0xf1, 0x37, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24, 0x60, 0x8d, 0x83, 0x8f, 0x03,
- 0x00, 0x02, 0x24, 0xbc, 0x00, 0x62, 0xac, 0x07, 0x00, 0x04, 0x3c, 0x00, 0x80,
- 0x84, 0x34, 0x60, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x03, 0x3c, 0xd9, 0x00, 0x40,
- 0xa0, 0x10, 0x00, 0xc2, 0x8c, 0x00, 0x80, 0x63, 0x34, 0x24, 0x10, 0x44, 0x00,
- 0x06, 0x00, 0x43, 0x14, 0x01, 0x00, 0x03, 0x24, 0x60, 0x8d, 0x83, 0x8f, 0x01,
- 0x00, 0x02, 0x24, 0xe0, 0x00, 0x62, 0xac, 0x28, 0x38, 0x00, 0x08, 0xfd, 0x00,
- 0x60, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x40,
- 0xac, 0xfd, 0x00, 0x43, 0xa0, 0x10, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x24, 0x18, 0x44, 0x00, 0x01, 0x00, 0x02, 0x3c, 0x17, 0x00, 0x62, 0x10, 0x2b,
- 0x10, 0x43, 0x00, 0x06, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x3c, 0x00, 0x80,
- 0x02, 0x34, 0x0a, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x28, 0x38, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, 0x34, 0x09, 0x00, 0x62, 0x10,
- 0x03, 0x00, 0x02, 0x3c, 0x0f, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24, 0x28,
- 0x38, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x28, 0x38, 0x00, 0x08, 0x04, 0x01, 0x40, 0xac, 0x60, 0x8d, 0x83,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x27, 0x38, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24,
- 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x27, 0x38, 0x00, 0x08, 0x02,
- 0x00, 0x02, 0x24, 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01,
- 0x62, 0xac, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x40,
- 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x40, 0xa0,
- 0x60, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x05, 0x24, 0x69, 0x01, 0x45, 0xa0, 0x10,
- 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x30, 0x11, 0x00,
- 0x40, 0x14, 0x01, 0x00, 0x02, 0x24, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x01, 0x40, 0xac, 0x8d, 0x01, 0x45, 0xa0, 0x14, 0x00, 0xc2, 0x8c,
- 0x60, 0x8d, 0x83, 0x8f, 0x03, 0x00, 0x42, 0x30, 0x94, 0x01, 0x62, 0xac, 0xb1,
- 0x01, 0x65, 0xa0, 0x14, 0x00, 0xc2, 0x8c, 0x60, 0x8d, 0x83, 0x8f, 0x82, 0x10,
- 0x02, 0x00, 0x01, 0x00, 0x42, 0x30, 0xb8, 0x01, 0x62, 0xac, 0x7d, 0x38, 0x00,
- 0x08, 0xd5, 0x01, 0x60, 0xa0, 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x8d, 0x01, 0x60, 0xa0, 0x60, 0x8d, 0x84, 0x8f, 0x70, 0x01, 0x62, 0xac, 0xb1,
- 0x01, 0x80, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x01,
- 0x45, 0xa0, 0x60, 0x8d, 0x83, 0x8f, 0x14, 0x00, 0xc2, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0xdc, 0x01, 0x62, 0xac, 0x90, 0x02, 0x42, 0x2c, 0x28, 0x00, 0x40, 0x14,
- 0x8f, 0x02, 0x02, 0x24, 0x7d, 0x38, 0x00, 0x08, 0xdc, 0x01, 0x62, 0xac, 0x60,
- 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x62, 0xac, 0x25, 0x00,
- 0x60, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x03, 0x24, 0x49, 0x00, 0x43,
- 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x40, 0xa0,
- 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x43, 0xa0, 0x60,
- 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x40, 0xa0, 0x60, 0x8d,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x40, 0xa0, 0x60, 0x8d, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x43, 0xa0, 0x60, 0x8d, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x43, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x69, 0x01, 0x43, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x8d, 0x01, 0x40, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0xb1, 0x01, 0x40, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0xd5, 0x01, 0x40, 0xa0, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd8,
- 0xff, 0xbd, 0x27, 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0xa0, 0x00, 0x70, 0x00,
- 0x02, 0x24, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x1c, 0x00, 0xb1,
- 0xaf, 0x00, 0x00, 0xc2, 0xa0, 0x02, 0x12, 0x10, 0x00, 0x01, 0x00, 0xc2, 0xa0,
- 0x02, 0x00, 0xd0, 0xa0, 0x03, 0x00, 0xc0, 0xa0, 0x50, 0xa0, 0x83, 0x8f, 0x04,
- 0x00, 0xc2, 0x24, 0x04, 0x00, 0xc4, 0xac, 0x0c, 0x00, 0x50, 0xac, 0x04, 0x00,
- 0x10, 0x26, 0x04, 0x00, 0x40, 0xac, 0x08, 0x00, 0x40, 0xac, 0x84, 0x00, 0x72,
- 0x90, 0x80, 0x00, 0x62, 0x90, 0x88, 0x00, 0x71, 0x90, 0xff, 0x00, 0x47, 0x30,
- 0xff, 0x00, 0x48, 0x32, 0x23, 0x10, 0xe8, 0x00, 0xff, 0xff, 0x42, 0x24, 0xff,
- 0x00, 0x23, 0x32, 0x24, 0x10, 0x43, 0x00, 0x2b, 0x10, 0x50, 0x00, 0x0c, 0x00,
- 0x40, 0x14, 0xff, 0xff, 0x02, 0x24, 0x21, 0x20, 0xc0, 0x00, 0x68, 0xa0, 0x85,
- 0x8f, 0x21, 0x30, 0x00, 0x01, 0x10, 0x00, 0xa3, 0xaf, 0x6c, 0x2d, 0x00, 0x0c,
- 0x14, 0x00, 0xb0, 0xaf, 0x21, 0x10, 0x00, 0x00, 0x21, 0x18, 0x50, 0x02, 0x50,
- 0xa0, 0x84, 0x8f, 0x24, 0x18, 0x23, 0x02, 0x84, 0x00, 0x83, 0xa0, 0x24, 0x00,
- 0xbf, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xc0, 0xff, 0xbd, 0x27,
- 0x38, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0x82, 0x8c, 0x14, 0x00, 0xa3, 0x27, 0x10,
- 0x00, 0x62, 0xac, 0x14, 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
- 0x62, 0xac, 0x18, 0x00, 0x82, 0x8c, 0x24, 0x00, 0x05, 0x24, 0x18, 0x00, 0x62,
- 0xac, 0x1c, 0x00, 0x82, 0x8c, 0x10, 0x00, 0xa6, 0x27, 0x1c, 0x00, 0x62, 0xac,
- 0x20, 0x00, 0x82, 0x8c, 0x05, 0x10, 0x04, 0x24, 0x7f, 0x38, 0x00, 0x0c, 0x20,
- 0x00, 0x62, 0xac, 0x38, 0x00, 0xbf, 0x8f, 0x40, 0x00, 0xbd, 0x27, 0x08, 0x00,
- 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xa3,
- 0x27, 0x18, 0x00, 0x05, 0x24, 0x30, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0x82, 0x8c,
- 0x10, 0x00, 0xa6, 0x27, 0x10, 0x00, 0x62, 0xac, 0x14, 0x00, 0x82, 0x8c, 0x04,
- 0x10, 0x04, 0x24, 0x7f, 0x38, 0x00, 0x0c, 0x14, 0x00, 0x62, 0xac, 0x30, 0x00,
- 0xbf, 0x8f, 0x38, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x8d, 0x85, 0x8f, 0x10, 0x00, 0x80, 0xac, 0x14, 0x00, 0x80, 0xac,
- 0x10, 0x00, 0x80, 0xac, 0x08, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x00, 0x40, 0x14, 0x80, 0x00, 0x02, 0x24, 0x2c, 0x00, 0xa2, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x18, 0x5c, 0x00, 0x94, 0x8d, 0x63,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x83, 0xac, 0x74, 0x00, 0xa2, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x08, 0x5c, 0x00, 0x9c,
- 0x8d, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x62, 0x00, 0x10, 0x00,
- 0x83, 0xac, 0xbc, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x02,
- 0x00, 0x21, 0x08, 0x5c, 0x00, 0xa4, 0x8d, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x18, 0x62, 0x00, 0x10, 0x00, 0x83, 0xac, 0xe0, 0x00, 0xa2, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x3c, 0xff, 0x38,
- 0x00, 0x08, 0x00, 0x80, 0x42, 0x34, 0x04, 0x01, 0xa2, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x08, 0x5c, 0x00, 0xb4, 0x8d, 0x22, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x62, 0x00, 0x10, 0x00, 0x82, 0xac, 0x60,
- 0x8d, 0x85, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0xa2, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0x15, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x82,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x82, 0xac, 0x94, 0x01, 0xa2, 0x8c,
- 0x14, 0x00, 0x83, 0x8c, 0x80, 0x10, 0x02, 0x00, 0x21, 0x08, 0x5c, 0x00, 0xc4,
- 0x8d, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x62, 0x00, 0x14, 0x00,
- 0x83, 0xac, 0xb8, 0x01, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x02,
- 0x00, 0x21, 0x08, 0x5c, 0x00, 0xd4, 0x8d, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x25, 0x18, 0x62, 0x00, 0x4e, 0x39, 0x00, 0x08, 0x14, 0x00, 0x83, 0xac, 0x10,
- 0x00, 0x82, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x34, 0x10, 0x00,
- 0x82, 0xac, 0xd8, 0x01, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x01, 0xa2,
- 0xac, 0x90, 0x02, 0x42, 0x2c, 0x02, 0x00, 0x40, 0x14, 0x8f, 0x02, 0x02, 0x24,
- 0xdc, 0x01, 0xa2, 0xac, 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xdc,
- 0x01, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x14, 0x01, 0x00,
- 0x02, 0x24, 0xdc, 0x01, 0x62, 0xac, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0xdc, 0x01, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x39, 0x00, 0x08,
- 0x14, 0x00, 0x82, 0xac, 0x01, 0x00, 0x03, 0x24, 0x10, 0x00, 0x82, 0xac, 0xb5,
- 0x00, 0xa3, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x00,
- 0x40, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x40,
- 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x40, 0xa0,
- 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x43, 0xa0, 0x60,
- 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x69, 0x01, 0x43, 0xa0, 0x60, 0x8d,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x01, 0x40, 0xa0, 0x60, 0x8d, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x40, 0xa0, 0x60, 0x8d, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0xd5, 0x01, 0x40, 0xa0, 0x08, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xa3, 0x05, 0x3c, 0xff, 0xa3, 0x07, 0x3c, 0xff, 0xff,
- 0xe7, 0x34, 0x21, 0x30, 0x00, 0x00, 0x52, 0x00, 0x0c, 0x24, 0x4f, 0x00, 0x0b,
- 0x24, 0x4d, 0x00, 0x0a, 0x24, 0x65, 0x00, 0x09, 0x24, 0x76, 0x00, 0x08, 0x24,
- 0x00, 0xa3, 0x03, 0x3c, 0x15, 0x00, 0x63, 0x34, 0x2b, 0x10, 0xa7, 0x00, 0x21,
- 0x00, 0x40, 0x10, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x16, 0x00, 0x8c, 0x14, 0x00, 0x00, 0x00, 0x00, 0xec, 0xff, 0x62,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x4b, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0xed, 0xff, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x4a, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xff, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
- 0x44, 0x14, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x62, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0x06, 0x00, 0x49, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x06, 0x24, 0x01, 0x00, 0x63, 0x24, 0xe2, 0xff, 0xc0, 0x10, 0x01, 0x00,
- 0xa5, 0x24, 0x2b, 0x10, 0xa7, 0x00, 0x02, 0x00, 0x40, 0x14, 0x16, 0x00, 0xa2,
- 0x24, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0xd8, 0xff, 0xbd, 0x27, 0x21, 0x20, 0x00, 0x00, 0x24, 0x00, 0xbf, 0xaf, 0x20,
- 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00,
- 0xb1, 0xaf, 0xbd, 0x31, 0x00, 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0x03, 0x00, 0x04,
- 0x24, 0xbd, 0x31, 0x00, 0x0c, 0x21, 0x88, 0x40, 0x00, 0x06, 0x00, 0x04, 0x24,
- 0xbd, 0x31, 0x00, 0x0c, 0x21, 0x90, 0x40, 0x00, 0x27, 0x20, 0x11, 0x00, 0x00,
- 0x1c, 0x04, 0x00, 0x42, 0x1c, 0x03, 0x00, 0xc0, 0x23, 0x04, 0x00, 0x25, 0x18,
- 0x64, 0x00, 0x26, 0xa0, 0x43, 0x02, 0x50, 0x39, 0x00, 0x0c, 0x21, 0x98, 0x40,
- 0x00, 0x02, 0x00, 0x40, 0x10, 0x30, 0x00, 0x10, 0x24, 0x00, 0x00, 0x50, 0x90,
- 0x4d, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01,
- 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x00, 0xdc, 0x8d, 0x86, 0x27, 0xc6, 0x41,
- 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x4d, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05,
- 0x24, 0x08, 0x41, 0x00, 0x0c, 0x02, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x00,
- 0x00, 0x8e, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x32,
- 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00,
- 0x06, 0x24, 0x10, 0x8e, 0x84, 0x27, 0x00, 0x2c, 0x11, 0x00, 0x83, 0x42, 0x00,
- 0x0c, 0x03, 0x2c, 0x05, 0x00, 0x30, 0x8e, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x02, 0x38, 0x8e, 0x84, 0x27, 0x00, 0x2c, 0x12, 0x00, 0x03,
- 0x2c, 0x05, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x01, 0x00, 0xa5, 0x24, 0x58, 0x8e,
- 0x84, 0x27, 0x00, 0x2c, 0x13, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x03, 0x2c, 0x05,
- 0x00, 0x78, 0x8e, 0x84, 0x27, 0x00, 0x2c, 0x14, 0x00, 0x83, 0x42, 0x00, 0x0c,
- 0x03, 0x2c, 0x05, 0x00, 0x21, 0x20, 0x00, 0x00, 0x98, 0x8e, 0x86, 0x27, 0xc6,
- 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x32, 0x00, 0x04, 0x24, 0x01, 0x00,
- 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0x00, 0xa0, 0x10,
- 0x3c, 0x00, 0x01, 0x10, 0x36, 0x14, 0x00, 0x05, 0x8e, 0xb4, 0x8e, 0x84, 0x27,
- 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05, 0x8e, 0xd4,
- 0x8e, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
- 0x05, 0x8e, 0xf4, 0x8e, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x20, 0x00, 0x05, 0x8e, 0x14, 0x8f, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x05, 0x8e, 0x34, 0x8f, 0x84, 0x27, 0x83,
- 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x05, 0x8e, 0x54, 0x8f,
- 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05,
- 0x8e, 0x74, 0x8f, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x05, 0x96, 0x94, 0x8f, 0x84, 0x27, 0x00, 0x2c, 0x05, 0x00, 0x83,
- 0x42, 0x00, 0x0c, 0x03, 0x2c, 0x05, 0x00, 0xb4, 0x8f, 0x84, 0x27, 0x83, 0x42,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb4,
- 0x8f, 0x1c, 0x00, 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f,
- 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0x38,
- 0xfe, 0xbd, 0x27, 0x10, 0x00, 0xa4, 0x27, 0x21, 0x28, 0x00, 0x00, 0xc0, 0x01,
- 0xbf, 0xaf, 0xbc, 0x01, 0xb3, 0xaf, 0xb8, 0x01, 0xb2, 0xaf, 0xb4, 0x01, 0xb1,
- 0xaf, 0x06, 0x2b, 0x00, 0x0c, 0xb0, 0x01, 0xb0, 0xaf, 0x4d, 0x00, 0x04, 0x24,
- 0x21, 0x28, 0x00, 0x00, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0xbc,
- 0x8f, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x88, 0x00, 0x00, 0x4d, 0x00,
- 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06,
- 0x24, 0x24, 0x00, 0xa5, 0x8f, 0xe0, 0x8f, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0xf8, 0x8f, 0x86, 0x27, 0xc6,
- 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x35, 0x00, 0x04, 0x24, 0x21, 0x28,
- 0x00, 0x00, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00,
- 0x00, 0x24, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x24, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x10, 0x04,
- 0x00, 0x12, 0x24, 0x10, 0x00, 0xb0, 0x27, 0x18, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x17, 0x00, 0x52, 0x14, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x05,
- 0x8e, 0x7c, 0x8d, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0xff, 0xff, 0xa5, 0x24,
- 0xc0, 0x40, 0x00, 0x0c, 0x07, 0x00, 0x04, 0x24, 0x21, 0x20, 0x00, 0x00, 0x28,
- 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0xc0, 0x40,
- 0x00, 0x0c, 0x15, 0x00, 0x04, 0x24, 0x20, 0x00, 0x05, 0x8e, 0x34, 0x90, 0x84,
- 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c,
- 0x1c, 0x00, 0x04, 0x24, 0x24, 0x00, 0x05, 0x8e, 0x38, 0x90, 0x84, 0x27, 0x83,
- 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xa2, 0x8f, 0x01, 0x00,
- 0x31, 0x26, 0x2b, 0x10, 0x22, 0x02, 0xe2, 0xff, 0x40, 0x14, 0x18, 0x00, 0x10,
- 0x26, 0x21, 0x20, 0x00, 0x00, 0x24, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x07, 0x00, 0x04, 0x24, 0x21,
- 0x20, 0x00, 0x00, 0x40, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28,
- 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x15, 0x00, 0x04, 0x24, 0x34, 0x90, 0x93,
- 0x27, 0x30, 0x00, 0xa5, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x83, 0x42, 0x00, 0x0c,
- 0x21, 0x20, 0x60, 0x02, 0xc0, 0x40, 0x00, 0x0c, 0x1c, 0x00, 0x04, 0x24, 0x7c,
- 0x8d, 0x90, 0x27, 0x34, 0x00, 0xa5, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x83, 0x42,
- 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xc0, 0x40, 0x00, 0x0c, 0x23, 0x00, 0x04,
- 0x24, 0x4c, 0x90, 0x92, 0x27, 0x38, 0x00, 0xa5, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x83, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x3c, 0x00, 0xa5, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0x21, 0x20,
- 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0xb4, 0x8f, 0x91, 0x27, 0xc6, 0x41, 0x00,
- 0x0c, 0x21, 0x30, 0x20, 0x02, 0xc0, 0x40, 0x00, 0x0c, 0x07, 0x00, 0x04, 0x24,
- 0x21, 0x20, 0x00, 0x00, 0x50, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x15, 0x00, 0x04, 0x24, 0x60, 0x00,
- 0xa5, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x60,
- 0x02, 0xc0, 0x40, 0x00, 0x0c, 0x1c, 0x00, 0x04, 0x24, 0x64, 0x00, 0xa5, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xc0,
- 0x40, 0x00, 0x0c, 0x23, 0x00, 0x04, 0x24, 0x68, 0x00, 0xa5, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x40, 0x02, 0x6c, 0x00, 0xa5,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02,
- 0x21, 0x20, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x30, 0x20, 0x02, 0xc0, 0x40, 0x00, 0x0c, 0x07, 0x00, 0x04, 0x24, 0x21, 0x20,
- 0x00, 0x00, 0x5c, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x15, 0x00, 0x04, 0x24, 0x21, 0x20, 0x00, 0x00,
- 0x21, 0x28, 0x00, 0x00, 0x6c, 0x90, 0x91, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x30, 0x20, 0x02, 0x48, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00,
- 0x00, 0x80, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x21, 0x20, 0x00, 0x00, 0x88, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x15, 0x00, 0x04, 0x24, 0x21, 0x20,
- 0x00, 0x00, 0x94, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x00, 0x48, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30,
- 0x05, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x80,
- 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x21, 0x20,
- 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0xa8, 0x90, 0x90, 0x27, 0xc6, 0x41, 0x00,
- 0x0c, 0x21, 0x30, 0x00, 0x02, 0xc0, 0x40, 0x00, 0x0c, 0x15, 0x00, 0x04, 0x24,
- 0x21, 0x20, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x30, 0x20, 0x02, 0x48, 0x00, 0xa2, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x42, 0x30, 0x05, 0x00, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x80, 0x90, 0x86,
- 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00,
- 0x21, 0x28, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x30, 0x00, 0x02, 0x35,
- 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x02, 0x00,
- 0x06, 0x24, 0xc0, 0x01, 0xbf, 0x8f, 0xbc, 0x01, 0xb3, 0x8f, 0xb8, 0x01, 0xb2,
- 0x8f, 0xb4, 0x01, 0xb1, 0x8f, 0xb0, 0x01, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0xc8, 0x01, 0xbd, 0x27, 0xd8, 0xff, 0xbd, 0x27, 0x4d, 0x00, 0x04, 0x24, 0x01,
- 0x00, 0x05, 0x24, 0x01, 0x00, 0x06, 0x24, 0x24, 0x00, 0xbf, 0xaf, 0x20, 0x00,
- 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1,
- 0xaf, 0x08, 0x41, 0x00, 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0xc0, 0x40, 0x00, 0x0c,
- 0x0f, 0x00, 0x04, 0x24, 0x21, 0x20, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0x02,
- 0x80, 0x02, 0x3c, 0x54, 0x97, 0x42, 0x24, 0x21, 0x98, 0x00, 0x00, 0x04, 0x00,
- 0x54, 0x24, 0x00, 0x00, 0x46, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00,
- 0x0c, 0x01, 0x00, 0x12, 0x24, 0x4d, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24,
- 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x00, 0xb4,
- 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x4d, 0x00,
- 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06,
- 0x24, 0xfc, 0x90, 0x84, 0x27, 0x02, 0x80, 0x02, 0x3c, 0x21, 0x10, 0x52, 0x00,
- 0xdf, 0xb8, 0x42, 0x90, 0x21, 0x28, 0x40, 0x02, 0xc0, 0x18, 0x02, 0x00, 0x21,
- 0x18, 0x62, 0x00, 0x80, 0x18, 0x03, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x88,
- 0x74, 0x00, 0x21, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x26, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c,
- 0x14, 0x00, 0x04, 0x24, 0x21, 0x20, 0x00, 0x00, 0x90, 0x8d, 0x86, 0x27, 0xc6,
- 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x22, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x0a, 0x00, 0x40, 0x14, 0x21, 0x80, 0x00, 0x00, 0x21, 0x20, 0x20,
- 0x02, 0x10, 0x37, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x01, 0x00, 0x10, 0x26,
- 0x04, 0x00, 0x02, 0x2e, 0xfb, 0xff, 0x40, 0x14, 0x21, 0x20, 0x20, 0x02, 0x1b,
- 0x3b, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, 0x45, 0x37, 0x00, 0x0c, 0x21, 0x20,
- 0x20, 0x02, 0x21, 0x20, 0x00, 0x00, 0x24, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00,
- 0x0c, 0x21, 0x28, 0x00, 0x00, 0x64, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x73, 0x26,
- 0x2b, 0x10, 0x53, 0x00, 0xd4, 0xff, 0x40, 0x10, 0x01, 0x00, 0x52, 0x26, 0x4d,
- 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00,
- 0x06, 0x24, 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3,
- 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f,
- 0x08, 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x21,
- 0x20, 0x00, 0x00, 0x04, 0x91, 0x86, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0xc6, 0x41,
- 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x4d, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00,
- 0x00, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x00,
- 0x01, 0x80, 0x06, 0x3c, 0x70, 0x1c, 0xc6, 0x24, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0x64, 0x8d, 0x85, 0x8f, 0x7c, 0x8d, 0x84, 0x27, 0x83, 0x42,
- 0x00, 0x0c, 0x01, 0x00, 0xa5, 0x24, 0x21, 0x20, 0x00, 0x00, 0x2c, 0x91, 0x86,
- 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f,
- 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x0a, 0x00, 0x02, 0x24, 0x24, 0x00,
- 0x82, 0x14, 0x21, 0x30, 0x00, 0x00, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x01, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xa2, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xa0, 0x14, 0x21, 0x20, 0x00, 0x00, 0x01,
- 0x80, 0x06, 0x3c, 0x80, 0x1d, 0xc6, 0x24, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28,
- 0x00, 0x00, 0x60, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x03, 0x24, 0x8d, 0x01, 0x43,
- 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x43, 0xa0,
- 0x60, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x06, 0x24, 0x72, 0x3b, 0x00, 0x08, 0xd5,
- 0x01, 0x40, 0xa0, 0x01, 0x80, 0x06, 0x3c, 0x44, 0x1e, 0xc6, 0x24, 0xc6, 0x41,
- 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x8d, 0x01, 0x40, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x01, 0x00, 0x06, 0x24,
- 0xb1, 0x01, 0x40, 0xa0, 0x60, 0x8d, 0x83, 0x8f, 0x01, 0x00, 0x02, 0x24, 0xd5,
- 0x01, 0x62, 0xa0, 0x10, 0x00, 0xbf, 0x8f, 0x21, 0x10, 0xc0, 0x00, 0x08, 0x00,
- 0xe0, 0x03, 0x18, 0x00, 0xbd, 0x27, 0x60, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x01, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x14,
- 0x01, 0x00, 0x02, 0x24, 0x8d, 0x01, 0x62, 0xa0, 0x60, 0x8d, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0xb1, 0x01, 0x62, 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x8b, 0x3b, 0x00, 0x08, 0xd5, 0x01, 0x40, 0xa0, 0x8d, 0x01, 0x60,
- 0xa0, 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x40, 0xa0,
- 0x60, 0x8d, 0x83, 0x8f, 0x01, 0x00, 0x02, 0x24, 0xd5, 0x01, 0x62, 0xa0, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xbd, 0x27, 0x24, 0x00,
- 0xb3, 0xaf, 0x21, 0x98, 0x80, 0x00, 0xc0, 0x10, 0x13, 0x00, 0x21, 0x10, 0x53,
- 0x00, 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03, 0x3c, 0x58, 0x97, 0x63, 0x24,
- 0x20, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x43, 0x00, 0x28, 0x00, 0xbf, 0xaf, 0x1c,
- 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf, 0x0c, 0x00, 0x45, 0x8e, 0x54, 0x91,
- 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42,
- 0x92, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00,
- 0x04, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21,
- 0x10, 0x52, 0x00, 0x10, 0x00, 0x46, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41,
- 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x74, 0x91, 0x84, 0x27, 0x83, 0x42, 0x00,
- 0x0c, 0x21, 0x88, 0x00, 0x00, 0x03, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x15, 0x00, 0x40, 0x10, 0x21, 0x20, 0x00, 0x00, 0x94, 0x91, 0x84, 0x27, 0x01,
- 0x00, 0x30, 0x26, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x02, 0x21, 0x20,
- 0x00, 0x00, 0x80, 0x10, 0x11, 0x00, 0x21, 0x10, 0x52, 0x00, 0x10, 0x00, 0x46,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x21, 0x20, 0x00, 0x00, 0x24, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0x03, 0x00, 0x42, 0x92, 0x21, 0x88, 0x00, 0x02, 0x2a, 0x10,
- 0x22, 0x02, 0xed, 0xff, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x9c, 0x91, 0x86,
- 0x27, 0xcf, 0x3b, 0x00, 0x08, 0x21, 0x28, 0x00, 0x00, 0x04, 0x00, 0x45, 0x8e,
- 0x38, 0x90, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x20, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0xf8, 0x91, 0x86, 0x27, 0xc6, 0x41,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x68, 0x8d, 0x93, 0xaf, 0x28, 0x00, 0xbf,
- 0x8f, 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f,
- 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0xe0,
- 0xff, 0xbd, 0x27, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x00, 0xc0, 0x10,
- 0x12, 0x00, 0x21, 0x10, 0x52, 0x00, 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03,
- 0x3c, 0x58, 0x97, 0x63, 0x24, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x43, 0x00,
- 0x1c, 0x00, 0xbf, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x02, 0x00, 0x22, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x3d, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xa5, 0x90, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xb0, 0x24, 0x06, 0x00, 0x00,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0x10, 0x50, 0x00, 0x07, 0x00, 0x40, 0x10, 0xcf, 0xff, 0xb0, 0x24, 0x03,
- 0x00, 0x25, 0x92, 0x58, 0x92, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x3c, 0x00, 0x08, 0xff, 0xff, 0x02, 0x24, 0x21, 0x20, 0x00,
- 0x00, 0xa8, 0x92, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x21, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x26, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xc6,
- 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x04, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x00, 0x50, 0x14, 0x21, 0x20, 0x00, 0x00, 0xc0, 0x92, 0x86,
- 0x27, 0x0b, 0x3c, 0x00, 0x08, 0x21, 0x28, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00,
- 0xd8, 0x92, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x20, 0x00, 0x00, 0x80, 0x10, 0x10, 0x00, 0x21, 0x10, 0x51, 0x00, 0x10, 0x00,
- 0x46, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x00, 0x21, 0x20, 0x00, 0x00, 0x24, 0x90, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x00, 0x04, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x19,
- 0x00, 0x50, 0x10, 0x21, 0x20, 0x40, 0x02, 0x4a, 0x3b, 0x00, 0x0c, 0x21, 0x28,
- 0x00, 0x02, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x37, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8d, 0x82, 0xaf, 0x34, 0x3c, 0x00, 0x08,
- 0x04, 0x00, 0x30, 0xae, 0x00, 0x00, 0xa2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x40, 0x10, 0x21, 0x30, 0x00, 0x00, 0x80, 0x10, 0x06, 0x00, 0x21, 0x10,
- 0x46, 0x00, 0x40, 0x30, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x90, 0x01, 0x00, 0xa5,
- 0x24, 0xd0, 0xff, 0xc2, 0x24, 0x00, 0x00, 0xa3, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0xf7, 0xff, 0x60, 0x14, 0x21, 0x30, 0x44, 0x00, 0x04, 0x00, 0x26, 0xae, 0x68,
- 0x8d, 0x80, 0xaf, 0xd3, 0x3a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10,
- 0x00, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1,
- 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27,
- 0xff, 0x00, 0x84, 0x30, 0x0a, 0x00, 0x80, 0x10, 0xff, 0xff, 0x02, 0x24, 0x64,
- 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x2b, 0x10,
- 0x44, 0x00, 0x04, 0x00, 0x40, 0x14, 0xff, 0xff, 0x02, 0x24, 0x02, 0x80, 0x02,
- 0x3c, 0x21, 0x10, 0x44, 0x00, 0xdf, 0xb8, 0x42, 0x90, 0x08, 0x00, 0xe0, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x82, 0xac, 0x14, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
- 0x82, 0xac, 0x18, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x82,
- 0xac, 0x1c, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x82, 0xac,
- 0x20, 0x00, 0xa2, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0x82, 0xac, 0xd8, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xb3, 0xaf, 0x21, 0x98,
- 0x80, 0x00, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0xa0, 0x00, 0x24, 0x00, 0xbf,
- 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0xb0, 0xaf,
- 0x10, 0x00, 0x63, 0x8e, 0x10, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0x62, 0x14, 0x21, 0x38, 0x00, 0x00, 0x14, 0x00, 0x63, 0x8e, 0x14, 0x00,
- 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x21, 0x08, 0xfc, 0x00, 0xd0, 0x99, 0x20, 0xa0, 0x01, 0x00, 0xe7, 0x24,
- 0x0e, 0x00, 0xe2, 0x2c, 0xfb, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21,
- 0x38, 0x00, 0x00, 0x21, 0x08, 0xfc, 0x00, 0xe0, 0x99, 0x20, 0xa0, 0x01, 0x00,
- 0xe7, 0x24, 0x20, 0x00, 0xe2, 0x2c, 0xfb, 0xff, 0x40, 0x14, 0x47, 0x00, 0x04,
- 0x24, 0x02, 0x00, 0x05, 0x24, 0x01, 0x00, 0x06, 0x24, 0xd8, 0x40, 0x00, 0x0c,
- 0x3e, 0x00, 0x07, 0x24, 0x21, 0x88, 0x00, 0x00, 0x10, 0x00, 0x63, 0x8e, 0x10,
- 0x00, 0x42, 0x8e, 0x02, 0x80, 0x10, 0x3c, 0x50, 0x99, 0x10, 0x26, 0x26, 0xa0,
- 0x62, 0x00, 0x00, 0x00, 0x08, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x14,
- 0x01, 0x13, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x94, 0x84, 0x8f,
- 0x10, 0x00, 0x63, 0x8e, 0x08, 0x00, 0x05, 0x8e, 0x04, 0x00, 0x06, 0x92, 0x10,
- 0x00, 0x42, 0x8e, 0x24, 0x18, 0x03, 0x01, 0x06, 0x38, 0xc3, 0x00, 0x24, 0x10,
- 0x02, 0x01, 0x06, 0x40, 0xc2, 0x00, 0x0c, 0x00, 0x03, 0x8e, 0x80, 0x10, 0x07,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x46, 0x8c, 0x80, 0x10, 0x08, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x47, 0x8c, 0x83, 0x42, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x31, 0x26, 0x08, 0x00, 0x22, 0x2a, 0xe6, 0xff,
- 0x40, 0x14, 0x10, 0x00, 0x10, 0x26, 0x10, 0x00, 0x62, 0x8e, 0x10, 0x00, 0x43,
- 0x8e, 0x00, 0x10, 0x42, 0x30, 0x00, 0x10, 0x63, 0x30, 0x17, 0x00, 0x43, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x60, 0x14, 0x01, 0x00, 0x03, 0x24, 0x60,
- 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x01, 0x43, 0xa0, 0x60, 0x8d,
- 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x43, 0xa0, 0x60, 0x8d, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x3c, 0x00, 0x08, 0xd5, 0x01, 0x40, 0xa0,
- 0x60, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x01, 0x40, 0xa0, 0x60,
- 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x40, 0xa0, 0x60, 0x8d,
- 0x83, 0x8f, 0x01, 0x00, 0x02, 0x24, 0xeb, 0x3c, 0x00, 0x08, 0xd5, 0x01, 0x62,
- 0xa0, 0x23, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x62, 0x8e,
- 0x14, 0x00, 0x43, 0x8e, 0x03, 0x00, 0x45, 0x30, 0x03, 0x00, 0x67, 0x30, 0x0b,
- 0x00, 0xa7, 0x10, 0x80, 0x18, 0x05, 0x00, 0x2c, 0x94, 0x82, 0x27, 0x21, 0x18,
- 0x62, 0x00, 0x00, 0x00, 0x66, 0x8c, 0x80, 0x18, 0x07, 0x00, 0x21, 0x18, 0x62,
- 0x00, 0xe8, 0x94, 0x84, 0x8f, 0x00, 0x00, 0x67, 0x8c, 0xd8, 0x8b, 0x85, 0x27,
- 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x63, 0x8e, 0x14,
- 0x00, 0x42, 0x8e, 0x04, 0x00, 0x63, 0x30, 0x04, 0x00, 0x42, 0x30, 0x17, 0x00,
- 0x62, 0x10, 0x82, 0x38, 0x03, 0x00, 0x01, 0x00, 0xe8, 0x2c, 0x18, 0x94, 0x82,
- 0x27, 0x80, 0x18, 0x07, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x66, 0x8c,
- 0x80, 0x18, 0x08, 0x00, 0x21, 0x18, 0x62, 0x00, 0xe8, 0x94, 0x84, 0x8f, 0x00,
- 0x00, 0x67, 0x8c, 0xec, 0x94, 0x85, 0x27, 0xe9, 0x3c, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x14, 0x00, 0x66, 0x8e, 0x14, 0x00, 0x47, 0x8e, 0x03, 0x00, 0xc3,
- 0x30, 0x03, 0x00, 0xe2, 0x30, 0x05, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xc0, 0x94, 0x84, 0x8f, 0x88, 0x8b, 0x85, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x00, 0x95, 0x86, 0x27, 0xc6, 0x41,
- 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x47, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05,
- 0x24, 0x01, 0x00, 0x06, 0x24, 0xd8, 0x40, 0x00, 0x0c, 0x3e, 0x00, 0x07, 0x24,
- 0x21, 0x20, 0x40, 0x02, 0xa8, 0x37, 0x00, 0x0c, 0x21, 0x28, 0x60, 0x02, 0x66,
- 0x37, 0x00, 0x0c, 0x01, 0x00, 0x04, 0x24, 0x80, 0x37, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0x8d, 0x83, 0x8f, 0x64, 0x8d, 0x82, 0xaf, 0x01, 0x00, 0x02,
- 0x24, 0x12, 0x00, 0x62, 0x10, 0x02, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0x3d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x24, 0x0d, 0x00,
- 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x17, 0x3d, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x89, 0x40, 0x00, 0x0c, 0x3a, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c,
- 0x20, 0x00, 0x04, 0x24, 0x17, 0x3d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3b,
- 0x3d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x17, 0x3d, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x94, 0x3d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x68, 0x8d, 0x80,
- 0xaf, 0x24, 0x00, 0xbf, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f,
- 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00,
- 0xbf, 0xaf, 0x89, 0x40, 0x00, 0x0c, 0x0d, 0x00, 0x04, 0x24, 0x28, 0x95, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x20, 0x5c, 0x00,
- 0x2c, 0x95, 0x84, 0x80, 0x89, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x28,
- 0x95, 0x84, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x24, 0x21, 0x18,
- 0x40, 0x00, 0x28, 0x95, 0x82, 0xaf, 0x02, 0x00, 0x41, 0x04, 0x21, 0x28, 0x40,
- 0x00, 0x04, 0x00, 0x83, 0x24, 0x83, 0x10, 0x03, 0x00, 0x80, 0x10, 0x02, 0x00,
- 0x23, 0x10, 0xa2, 0x00, 0x28, 0x95, 0x82, 0xaf, 0x10, 0x00, 0xbf, 0x8f, 0x18,
- 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xff,
- 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x32, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05,
- 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x00,
- 0x3c, 0x95, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x32,
- 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00,
- 0x06, 0x24, 0x21, 0x20, 0x00, 0x00, 0x60, 0x95, 0x86, 0x27, 0xc6, 0x41, 0x00,
- 0x0c, 0x21, 0x28, 0x00, 0x00, 0x32, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24,
- 0x08, 0x41, 0x00, 0x0c, 0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xbf, 0x8f, 0x18,
- 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
- 0xbd, 0x27, 0x1c, 0x00, 0xbf, 0xaf, 0x20, 0x3d, 0x00, 0x0c, 0x18, 0x00, 0xb0,
- 0xaf, 0xc0, 0x40, 0x00, 0x0c, 0x05, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3c,
- 0x10, 0xc0, 0x42, 0x8c, 0x21, 0x20, 0x00, 0x00, 0x18, 0x00, 0x43, 0x30, 0x42,
- 0x10, 0x03, 0x00, 0x21, 0x30, 0x5c, 0x00, 0xb8, 0x95, 0xc6, 0x8c, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00,
- 0x0c, 0x10, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3c, 0x10, 0xc0, 0x42, 0x8c,
- 0xb8, 0x95, 0x90, 0x27, 0x60, 0x00, 0x43, 0x30, 0x42, 0x19, 0x03, 0x00, 0x03,
- 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x14, 0x80, 0x10, 0x03, 0x00, 0x21, 0x20,
- 0x00, 0x00, 0x10, 0x96, 0x86, 0x27, 0x77, 0x3d, 0x00, 0x08, 0x21, 0x28, 0x00,
- 0x00, 0x21, 0x20, 0x00, 0x00, 0x21, 0x10, 0x50, 0x00, 0x00, 0x00, 0x46, 0x8c,
- 0x21, 0x28, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0,
- 0x40, 0x00, 0x0c, 0x1b, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3c, 0x10, 0xc0,
- 0x42, 0x8c, 0x21, 0x20, 0x00, 0x00, 0x04, 0x00, 0x42, 0x30, 0x21, 0x30, 0x5c,
- 0x00, 0xe8, 0x95, 0xc6, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x26, 0x00, 0x04, 0x24, 0x02,
- 0x80, 0x02, 0x3c, 0x10, 0xc0, 0x42, 0x8c, 0x21, 0x20, 0x00, 0x00, 0x03, 0x00,
- 0x43, 0x30, 0x80, 0x10, 0x03, 0x00, 0x21, 0x30, 0x5c, 0x00, 0x00, 0x96, 0xc6,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20,
- 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x32, 0x00,
- 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06,
- 0x24, 0x21, 0x20, 0x00, 0x00, 0x30, 0x96, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x00, 0x32, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x08,
- 0x41, 0x00, 0x0c, 0x01, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x00, 0x58, 0x96,
- 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x32, 0x00, 0x04,
- 0x24, 0x01, 0x00, 0x05, 0x24, 0x08, 0x41, 0x00, 0x0c, 0x02, 0x00, 0x06, 0x24,
- 0x21, 0x20, 0x00, 0x00, 0xa4, 0x96, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00,
- 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xbd, 0x27, 0x14, 0x00, 0xb1,
- 0xaf, 0x01, 0x00, 0x11, 0x24, 0x28, 0x00, 0xbf, 0xaf, 0x24, 0x00, 0xb5, 0xaf,
- 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x20,
- 0x3d, 0x00, 0x0c, 0x10, 0x00, 0xb0, 0xaf, 0x05, 0x00, 0x04, 0x24, 0x21, 0x80,
- 0x00, 0x00, 0x06, 0x00, 0x15, 0x24, 0x0c, 0x00, 0x14, 0x24, 0x50, 0xa0, 0x86,
- 0x8f, 0x12, 0x00, 0x13, 0x24, 0x1c, 0x00, 0xc2, 0x90, 0x18, 0x00, 0xc3, 0x90,
- 0x14, 0x00, 0xc5, 0x90, 0x00, 0x16, 0x02, 0x00, 0x00, 0x1c, 0x03, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x00, 0x2a, 0x05, 0x00, 0x10, 0x00, 0xc3, 0x90, 0x21, 0x10,
- 0x45, 0x00, 0xc0, 0x40, 0x00, 0x0c, 0x25, 0x90, 0x62, 0x00, 0x06, 0x00, 0x15,
- 0x12, 0x21, 0x20, 0x00, 0x00, 0x04, 0x00, 0x14, 0x12, 0x00, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x13, 0x16, 0x24, 0x10, 0x51, 0x02, 0x21, 0x20, 0x00, 0x00, 0x18,
- 0x97, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x24, 0x10,
- 0x51, 0x02, 0x08, 0x00, 0x40, 0x14, 0x52, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02,
- 0x3c, 0x14, 0xc0, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x51, 0x00,
- 0x02, 0x00, 0x40, 0x10, 0x2d, 0x00, 0x04, 0x24, 0x58, 0x00, 0x04, 0x24, 0x89,
- 0x40, 0x00, 0x0c, 0x40, 0x88, 0x11, 0x00, 0x01, 0x00, 0x10, 0x26, 0x18, 0x00,
- 0x02, 0x2a, 0xe7, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xbf,
- 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00, 0xb3, 0x8f,
- 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08,
- 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0xa0, 0xff, 0xbd, 0x27, 0x58, 0x00,
- 0xb4, 0xaf, 0x21, 0xa0, 0x80, 0x00, 0x5c, 0x00, 0xbf, 0xaf, 0x54, 0x00, 0xb3,
- 0xaf, 0x50, 0x00, 0xb2, 0xaf, 0x4c, 0x00, 0xb1, 0xaf, 0x48, 0x00, 0xb0, 0xaf,
- 0x00, 0x00, 0x83, 0x92, 0x20, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x62, 0x14, 0x21,
- 0x20, 0x00, 0x00, 0x20, 0x00, 0x06, 0x24, 0x21, 0x18, 0x80, 0x02, 0x2b, 0x10,
- 0x85, 0x00, 0x08, 0x00, 0x40, 0x10, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x62,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xff, 0x46, 0x10, 0x01, 0x00, 0x84, 0x24,
- 0x2b, 0x10, 0x85, 0x00, 0x06, 0x00, 0x40, 0x14, 0x21, 0x10, 0x84, 0x02, 0x1c,
- 0x97, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x3e,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00,
- 0x00, 0xf3, 0xff, 0x43, 0x24, 0x67, 0x00, 0x62, 0x2c, 0xbc, 0x00, 0x40, 0x10,
- 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08, 0x22, 0x00, 0x08,
- 0x1f, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x40,
- 0x10, 0x21, 0x20, 0x00, 0x00, 0x34, 0x97, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x00, 0x68, 0x8d, 0x83, 0x8f, 0x21, 0x20, 0x00, 0x00, 0xc0,
- 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x02, 0x80,
- 0x06, 0x3c, 0x21, 0x30, 0xc2, 0x00, 0x64, 0x97, 0xc6, 0x8c, 0x00, 0x00, 0x00,
- 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00,
- 0x4c, 0x97, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x68,
- 0x8d, 0x80, 0xaf, 0xd3, 0x3a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x3e,
- 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0x68, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00,
- 0x00, 0x19, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x84, 0x02,
- 0x00, 0x00, 0x44, 0x90, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0x84, 0x24, 0x3e,
- 0x3c, 0x00, 0x0c, 0xff, 0x00, 0x84, 0x30, 0x21, 0x20, 0x40, 0x00, 0xff, 0xff,
- 0x02, 0x24, 0x0b, 0x00, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00,
- 0x00, 0x54, 0x97, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x64, 0x8d, 0x85, 0x8f, 0x84, 0x97, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x01,
- 0x00, 0xa5, 0x24, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0x8d, 0x3b,
- 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80,
- 0x02, 0x21, 0x20, 0x40, 0x00, 0xd9, 0x3b, 0x00, 0x0c, 0x21, 0x28, 0x80, 0x02,
- 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0x01, 0x00, 0x02, 0x24, 0x78,
- 0x8d, 0x82, 0xaf, 0x3b, 0x3d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x69, 0x3e,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x39, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0xd3, 0x3a, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x2f, 0x3b, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd3,
- 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0x02, 0x00, 0x02, 0x24, 0x78, 0x8d,
- 0x82, 0xaf, 0x94, 0x3d, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa0, 0x84,
- 0x27, 0xaf, 0x38, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x3e, 0x00, 0x08,
- 0x21, 0x20, 0x80, 0x02, 0x07, 0x00, 0x02, 0x24, 0x24, 0x00, 0xa2, 0xaf, 0x0d,
- 0x10, 0x04, 0x24, 0x18, 0x00, 0x05, 0x24, 0x7f, 0x38, 0x00, 0x0c, 0x10, 0x00,
- 0xa6, 0x27, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0xf8, 0x39, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02,
- 0x66, 0x37, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x00, 0x30, 0x00, 0xb0, 0x27, 0xd4,
- 0x38, 0x00, 0x0c, 0x21, 0x20, 0x00, 0x02, 0xc5, 0x38, 0x00, 0x0c, 0x21, 0x20,
- 0x00, 0x02, 0x76, 0x3b, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x37, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8d, 0x82, 0xaf, 0xd3, 0x3a, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0x50,
- 0xa0, 0x83, 0x8f, 0xa4, 0x97, 0x84, 0x27, 0x0c, 0x01, 0x65, 0x90, 0x08, 0x01,
- 0x71, 0x90, 0x04, 0x01, 0x62, 0x90, 0x00, 0x01, 0x70, 0x90, 0x00, 0x12, 0x02,
- 0x00, 0x25, 0x80, 0x02, 0x02, 0x00, 0x2a, 0x05, 0x00, 0x25, 0x88, 0x25, 0x02,
- 0x21, 0x28, 0x20, 0x02, 0x14, 0x01, 0x62, 0x90, 0x10, 0x01, 0x72, 0x90, 0x00,
- 0x12, 0x02, 0x00, 0x83, 0x42, 0x00, 0x0c, 0x25, 0x90, 0x42, 0x02, 0xac, 0x97,
- 0x93, 0x27, 0x21, 0x20, 0x60, 0x02, 0x83, 0x42, 0x00, 0x0c, 0x21, 0x28, 0x20,
- 0x02, 0xb4, 0x97, 0x84, 0x27, 0xff, 0xff, 0x10, 0x32, 0x83, 0x42, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x02, 0x21, 0x20, 0x60, 0x02, 0x83, 0x42, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x02, 0xbc, 0x97, 0x84, 0x27, 0xff, 0xff, 0x52, 0x32, 0x83, 0x42,
- 0x00, 0x0c, 0x21, 0x28, 0x40, 0x02, 0xc4, 0x97, 0x84, 0x27, 0x83, 0x42, 0x00,
- 0x0c, 0x21, 0x28, 0x40, 0x02, 0x58, 0xa0, 0x82, 0x8f, 0x21, 0x88, 0x00, 0x00,
- 0x00, 0x01, 0x50, 0x24, 0xcc, 0x97, 0x84, 0x27, 0x00, 0x00, 0x05, 0x92, 0x04,
- 0x00, 0x10, 0x26, 0x83, 0x42, 0x00, 0x0c, 0x01, 0x00, 0x31, 0x26, 0x10, 0x00,
- 0x22, 0x2e, 0xf9, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x89, 0x40, 0x00,
- 0x0c, 0x0d, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x0a, 0x00, 0x04, 0x24,
- 0x89, 0x40, 0x00, 0x0c, 0x5b, 0x00, 0x04, 0x24, 0x74, 0xa0, 0x90, 0x8f, 0x21,
- 0x88, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82, 0x04, 0x00, 0x10, 0x26, 0x89, 0x40,
- 0x00, 0x0c, 0x01, 0x00, 0x31, 0x26, 0x14, 0x00, 0x22, 0x2e, 0xfa, 0xff, 0x40,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x5d, 0x00, 0x04, 0x24,
- 0x89, 0x40, 0x00, 0x0c, 0x0d, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x0a,
- 0x00, 0x04, 0x24, 0xd3, 0x3e, 0x00, 0x08, 0x21, 0x20, 0x80, 0x02, 0x21, 0x20,
- 0x00, 0x00, 0xd0, 0x97, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x00, 0x21, 0x20, 0x80, 0x02, 0x20, 0x00, 0x83, 0x24, 0x00, 0x00, 0x80, 0xa0,
- 0x01, 0x00, 0x84, 0x24, 0x2b, 0x10, 0x83, 0x00, 0xfc, 0xff, 0x40, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x78, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x3a, 0x00, 0x04,
- 0x24, 0x89, 0x40, 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24, 0x5c, 0x00, 0xbf, 0x8f,
- 0x58, 0x00, 0xb4, 0x8f, 0x54, 0x00, 0xb3, 0x8f, 0x50, 0x00, 0xb2, 0x8f, 0x4c,
- 0x00, 0xb1, 0x8f, 0x48, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x60, 0x00,
- 0xbd, 0x27, 0x0c, 0x9a, 0x83, 0x97, 0x0e, 0x9a, 0x82, 0x97, 0xe0, 0xff, 0xbd,
- 0x27, 0x18, 0x00, 0xbf, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0xa5, 0x00, 0x62, 0x10,
- 0x10, 0x00, 0xb0, 0xaf, 0xe0, 0x99, 0x91, 0x27, 0xb1, 0x40, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0x78, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
- 0x60, 0x10, 0x21, 0x80, 0x40, 0x00, 0x21, 0x20, 0x00, 0x00, 0xf0, 0x97, 0x86,
- 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x78, 0x8d, 0x83, 0x8f,
- 0x01, 0x00, 0x02, 0x24, 0x05, 0x00, 0x62, 0x10, 0x02, 0x00, 0x02, 0x24, 0x06,
- 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x00, 0x0a, 0x3f, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x98, 0x84, 0x27, 0x07, 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x98, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x20, 0x00, 0x00, 0x2c, 0x98, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21,
- 0x28, 0x00, 0x00, 0x78, 0x8d, 0x80, 0xaf, 0xff, 0x00, 0x03, 0x32, 0x0d, 0x00,
- 0x02, 0x24, 0x1f, 0x00, 0x62, 0x10, 0x0e, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40,
- 0x10, 0x08, 0x00, 0x02, 0x24, 0x0a, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x76, 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x24, 0x75,
- 0x00, 0x62, 0x10, 0x13, 0x00, 0x02, 0x24, 0x73, 0x00, 0x62, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x8d, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x40, 0x10, 0x08, 0x00, 0x04, 0x24,
- 0x21, 0x10, 0x51, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x40, 0xa0, 0x89,
- 0x40, 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x08, 0x00,
- 0x04, 0x24, 0x6c, 0x8d, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42,
- 0x24, 0x6c, 0x8d, 0x82, 0xaf, 0x8f, 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x89, 0x40, 0x00, 0x0c, 0x0a, 0x00, 0x04, 0x24, 0x00, 0x26, 0x10, 0x00, 0x89,
- 0x40, 0x00, 0x0c, 0x03, 0x26, 0x04, 0x00, 0x6c, 0x8d, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x10, 0x51, 0x00, 0x00, 0x00, 0x40, 0xa0, 0x6c, 0x8d, 0x85,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0x3d, 0x00, 0x0c, 0x21, 0x20, 0x20, 0x02, 0x6c, 0x8d, 0x80, 0xaf, 0x8f,
- 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x68, 0x8d, 0x83, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x2c, 0x00, 0x60, 0x10, 0x21, 0x20, 0x00, 0x00, 0x21, 0x28, 0x00,
- 0x00, 0x34, 0x97, 0x86, 0x27, 0xc0, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00,
- 0x80, 0x10, 0x02, 0x00, 0x02, 0x80, 0x03, 0x3c, 0x58, 0x97, 0x63, 0x24, 0xc6,
- 0x41, 0x00, 0x0c, 0x21, 0x80, 0x43, 0x00, 0x21, 0x20, 0x00, 0x00, 0x0c, 0x00,
- 0x06, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x00, 0x21, 0x20, 0x00, 0x00, 0x40, 0x98, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c,
- 0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x50, 0x00, 0x10, 0x00, 0x46,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00,
- 0x6b, 0x3f, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, 0x04, 0x00, 0x05, 0x8e, 0x7c,
- 0x8d, 0x84, 0x27, 0x83, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20,
- 0x00, 0x00, 0x4c, 0x97, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00,
- 0x00, 0x68, 0x8d, 0x80, 0xaf, 0x8f, 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x6c, 0x98, 0x86, 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x8f,
- 0x3f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x8d, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x42, 0x2c, 0x15, 0x00, 0x40, 0x10, 0xe0, 0xff, 0x02,
- 0x26, 0xff, 0x00, 0x42, 0x30, 0x60, 0x00, 0x42, 0x2c, 0x03, 0x00, 0x40, 0x10,
- 0x00, 0x26, 0x10, 0x00, 0x87, 0x3f, 0x00, 0x08, 0x03, 0x26, 0x04, 0x00, 0x89,
- 0x40, 0x00, 0x0c, 0x3c, 0x00, 0x04, 0x24, 0x34, 0x90, 0x84, 0x27, 0x83, 0x42,
- 0x00, 0x0c, 0xff, 0x00, 0x05, 0x32, 0x3e, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x62, 0x24, 0x6c, 0x8d, 0x82, 0xaf, 0x21, 0x08, 0x7c, 0x00, 0xe0,
- 0x99, 0x30, 0xa0, 0x0c, 0x9a, 0x83, 0x97, 0x0e, 0x9a, 0x82, 0x97, 0x00, 0x00,
- 0x00, 0x00, 0x5e, 0xff, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xbf,
- 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03,
- 0x20, 0x00, 0xbd, 0x27, 0x0c, 0x9a, 0x85, 0x97, 0x0e, 0x9a, 0x84, 0x97, 0xff,
- 0xff, 0xa3, 0x30, 0xff, 0xff, 0x82, 0x24, 0x31, 0x00, 0x62, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0x07, 0x3c, 0x84, 0x00, 0xe7, 0x34, 0x00, 0xa1, 0x06,
- 0x3c, 0x80, 0x00, 0xc6, 0x34, 0x11, 0x00, 0x0a, 0x24, 0x01, 0x00, 0x09, 0x24,
- 0x13, 0x00, 0x08, 0x24, 0x05, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x9a, 0x82, 0x97, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xa2, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xe2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x30, 0x1f, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xa2, 0x30, 0x04, 0x00, 0x4a, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x74, 0x8d, 0x89, 0xa3, 0xbc, 0x3f, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x74, 0x8d, 0x80,
- 0xa3, 0x0c, 0x9a, 0x83, 0x97, 0x00, 0x9a, 0x84, 0x8f, 0x01, 0x00, 0x62, 0x24,
- 0x21, 0x18, 0x64, 0x00, 0x0c, 0x9a, 0x82, 0xa7, 0x00, 0x00, 0x65, 0xa0, 0x0c,
- 0x9a, 0x83, 0x97, 0x08, 0x9a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10,
- 0x43, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x9a, 0x80,
- 0xa7, 0x0c, 0x9a, 0x85, 0x97, 0x0e, 0x9a, 0x84, 0x97, 0xff, 0xff, 0xa3, 0x30,
- 0xff, 0xff, 0x82, 0x24, 0xd8, 0xff, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x16, 0x9a, 0x83, 0x97, 0x14, 0x9a,
- 0x82, 0x97, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xa1, 0x08, 0x3c, 0x84, 0x00, 0x08, 0x35, 0x00, 0xa1, 0x07, 0x3c,
- 0x80, 0x00, 0xe7, 0x34, 0x21, 0x30, 0x40, 0x00, 0x04, 0x9a, 0x85, 0x8f, 0x10,
- 0x9a, 0x84, 0x8f, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x42, 0x30, 0x0d, 0x00, 0x40, 0x10, 0x01, 0x00, 0x62, 0x24, 0x21, 0x18, 0x65,
- 0x00, 0x16, 0x9a, 0x82, 0xa7, 0xff, 0xff, 0x42, 0x30, 0x00, 0x00, 0x63, 0x90,
- 0x2b, 0x10, 0x82, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0xe3, 0xa0, 0x16,
- 0x9a, 0x80, 0xa7, 0x16, 0x9a, 0x83, 0x97, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
- 0x66, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x84, 0x8b, 0x82, 0x8f, 0xe8, 0xff, 0xbd, 0x27, 0x07, 0x00, 0x40, 0x10,
- 0x10, 0x00, 0xbf, 0xaf, 0xa0, 0xa0, 0x84, 0x27, 0x80, 0xa0, 0x85, 0x27, 0x84,
- 0x8b, 0x80, 0xaf, 0x5c, 0x3c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x8d,
- 0x80, 0xaf, 0x80, 0x8b, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8b, 0x80, 0xaf, 0xc0, 0xa0, 0x84, 0x27,
- 0xf0, 0xa0, 0x85, 0x27, 0x4c, 0x3c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0x9a, 0x83, 0x97, 0x14, 0x9a, 0x82, 0x97, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x62, 0x10, 0x00, 0xa1, 0x02, 0x3c, 0x84, 0x00, 0x42, 0x34, 0x00, 0x00, 0x42,
- 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x07, 0x00, 0x40, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x74, 0x8d, 0x82, 0x93, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x3f, 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x00, 0x70, 0x98, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0x70, 0x98, 0x82, 0xaf, 0x05, 0x00, 0x42, 0x28, 0x2b, 0x00, 0x40, 0x14,
- 0x00, 0xa1, 0x02, 0x3c, 0x84, 0x00, 0x42, 0x34, 0x00, 0x00, 0x42, 0x90, 0x70,
- 0x98, 0x80, 0xaf, 0x01, 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x99, 0x3f, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x9a, 0x83,
- 0x97, 0x0e, 0x9a, 0x82, 0x97, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x62, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0xe9, 0x3e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x78,
- 0x8d, 0x83, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x74, 0x98, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
- 0x24, 0x74, 0x98, 0x82, 0xaf, 0x0b, 0x00, 0x42, 0x28, 0x11, 0x00, 0x40, 0x14,
- 0x01, 0x00, 0x02, 0x24, 0x74, 0x98, 0x80, 0xaf, 0x05, 0x00, 0x62, 0x10, 0x02,
- 0x00, 0x02, 0x24, 0x07, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x55, 0x3d, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x42, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x3d, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa0, 0x84, 0x27, 0xaf, 0x38, 0x00, 0x0c, 0x00,
- 0x00, 0x00, 0x00, 0xa8, 0x26, 0x00, 0x0c, 0x19, 0x00, 0x04, 0x24, 0x10, 0x00,
- 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x5c, 0x9e, 0x85, 0x8f, 0x01, 0x00, 0x02, 0x24, 0x74, 0x8d, 0x82, 0xa3,
- 0x80, 0xff, 0xa3, 0x24, 0x38, 0x00, 0x64, 0x8c, 0x16, 0x00, 0x62, 0x94, 0x70,
- 0x8d, 0x80, 0xaf, 0x0c, 0x9a, 0x80, 0xa7, 0x0e, 0x9a, 0x80, 0xa7, 0x14, 0x9a,
- 0x80, 0xa7, 0x16, 0x9a, 0x80, 0xa7, 0x18, 0xa1, 0x83, 0xaf, 0x14, 0xa1, 0x85,
- 0xaf, 0x04, 0x9a, 0x84, 0xaf, 0x3c, 0x00, 0x64, 0x8c, 0x0e, 0x00, 0x63, 0x94,
- 0xff, 0xff, 0x42, 0x24, 0x10, 0x9a, 0x82, 0xaf, 0xff, 0xff, 0x63, 0x24, 0x00,
- 0x9a, 0x84, 0xaf, 0x08, 0x9a, 0x83, 0xaf, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x0d, 0x00, 0x03,
- 0x24, 0x02, 0x80, 0x02, 0x3c, 0xed, 0xb8, 0x42, 0x24, 0x00, 0x00, 0x40, 0xa0,
- 0xff, 0xff, 0x63, 0x24, 0xfd, 0xff, 0x61, 0x04, 0xff, 0xff, 0x42, 0x24, 0xa0,
- 0xa0, 0x85, 0x27, 0xa8, 0x37, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x66, 0x37,
- 0x00, 0x0c, 0x01, 0x00, 0x04, 0x24, 0x80, 0x37, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x00, 0x64, 0x8d, 0x82, 0xaf, 0xd3, 0x3a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x2f, 0x3b, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x3a,
- 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24, 0x18, 0x9a,
- 0x84, 0x27, 0x03, 0x00, 0x05, 0x24, 0x01, 0x80, 0x06, 0x3c, 0xc0, 0xff, 0xc6,
- 0x24, 0x68, 0x8d, 0x80, 0xaf, 0x35, 0x26, 0x00, 0x0c, 0x21, 0x38, 0x00, 0x00,
- 0x18, 0x9a, 0x84, 0x27, 0x4f, 0x26, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x16, 0x9a, 0x86, 0x97, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xc0,
- 0x14, 0x21, 0x38, 0x80, 0x00, 0x14, 0x9a, 0x83, 0x97, 0x10, 0x9a, 0x82, 0x8f,
- 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x9a, 0x83, 0x97, 0xff, 0xff, 0xc2, 0x24, 0xff, 0xff, 0x65, 0x30, 0x19, 0x00,
- 0xa2, 0x10, 0x01, 0x00, 0x63, 0x24, 0x04, 0x9a, 0x82, 0x8f, 0x14, 0x9a, 0x83,
- 0xa7, 0x21, 0x10, 0x45, 0x00, 0x00, 0x00, 0x47, 0xa0, 0x14, 0x9a, 0x83, 0x97,
- 0x10, 0x9a, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x10, 0x43, 0x00, 0x02,
- 0x00, 0x40, 0x10, 0x00, 0x16, 0x04, 0x00, 0x14, 0x9a, 0x80, 0xa7, 0x03, 0x1e,
- 0x02, 0x00, 0x0d, 0x00, 0x02, 0x24, 0x04, 0x00, 0x62, 0x14, 0x0a, 0x00, 0x02,
- 0x24, 0x70, 0x8d, 0x80, 0xaf, 0xaf, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8d, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x70, 0x8d, 0x82, 0xaf, 0x08, 0x00,
- 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x9a, 0x82, 0x97, 0x00, 0x9a, 0x83,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x43, 0x00, 0x00, 0x00, 0x64, 0x90,
- 0x08, 0x9a, 0x83, 0x8f, 0x01, 0x00, 0x42, 0x24, 0x0e, 0x9a, 0x82, 0xa7, 0xff,
- 0xff, 0x42, 0x30, 0x2b, 0x18, 0x62, 0x00, 0x02, 0x00, 0x60, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x0e, 0x9a, 0x80, 0xa7, 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x80,
- 0x00, 0x70, 0x8d, 0x83, 0x8f, 0xd8, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xbf, 0xaf,
- 0x1c, 0x00, 0xb1, 0xaf, 0x2a, 0x10, 0x83, 0x00, 0x03, 0x00, 0x40, 0x10, 0x18,
- 0x00, 0xb0, 0xaf, 0xd3, 0x40, 0x00, 0x08, 0xff, 0xff, 0x02, 0x24, 0x23, 0x88,
- 0x83, 0x00, 0x07, 0x00, 0x20, 0x1a, 0x21, 0x80, 0x00, 0x00, 0x89, 0x40, 0x00,
- 0x0c, 0x20, 0x00, 0x04, 0x24, 0x01, 0x00, 0x10, 0x26, 0x2a, 0x10, 0x11, 0x02,
- 0xfb, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x00, 0x00, 0x20,
- 0x00, 0xbf, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18, 0x00, 0xb0, 0x8f, 0x08, 0x00,
- 0xe0, 0x03, 0x28, 0x00, 0xbd, 0x27, 0xc0, 0xff, 0xbd, 0x27, 0x30, 0x00, 0xb2,
- 0xaf, 0x21, 0x90, 0x80, 0x00, 0x2c, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xa0, 0x00,
- 0x34, 0x00, 0xb3, 0xaf, 0x21, 0x98, 0xc0, 0x00, 0x28, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0x00, 0x00, 0x38, 0x00, 0xb4, 0xaf, 0x21, 0xa0, 0xe0, 0x00, 0x09, 0x00,
- 0x20, 0x12, 0x3c, 0x00, 0xbf, 0xaf, 0x21, 0x20, 0x00, 0x00, 0x24, 0x90, 0x86,
- 0x27, 0xc6, 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x10, 0x26,
- 0x2b, 0x10, 0x11, 0x02, 0xfa, 0xff, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x08,
- 0x00, 0x40, 0x12, 0x21, 0x80, 0x00, 0x00, 0x00, 0x8e, 0x14, 0x00, 0x89, 0x40,
- 0x00, 0x0c, 0x03, 0x26, 0x11, 0x00, 0x01, 0x00, 0x10, 0x26, 0x2b, 0x10, 0x12,
- 0x02, 0xfb, 0xff, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x60, 0x12,
- 0x21, 0x80, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x24, 0x90, 0x86, 0x27, 0xc6,
- 0x41, 0x00, 0x0c, 0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x10, 0x26, 0x2b, 0x10,
- 0x13, 0x02, 0xfa, 0xff, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x3c, 0x00, 0xbf,
- 0x8f, 0x38, 0x00, 0xb4, 0x8f, 0x34, 0x00, 0xb3, 0x8f, 0x30, 0x00, 0xb2, 0x8f,
- 0x2c, 0x00, 0xb1, 0x8f, 0x28, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40,
- 0x00, 0xbd, 0x27, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0xd8, 0x40,
- 0x00, 0x0c, 0x2d, 0x00, 0x07, 0x24, 0x10, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xbd,
- 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xff, 0xbd, 0x27,
- 0x70, 0x00, 0xa2, 0x8f, 0x48, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0xe0, 0x00, 0x58,
- 0x00, 0xb4, 0xaf, 0x21, 0xa0, 0x00, 0x00, 0x54, 0x00, 0xb3, 0xaf, 0x21, 0x98,
- 0xc0, 0x00, 0x5c, 0x00, 0xbf, 0xaf, 0x50, 0x00, 0xb2, 0xaf, 0x07, 0x00, 0xa0,
- 0x10, 0x4c, 0x00, 0xb1, 0xaf, 0x06, 0x00, 0x41, 0x04, 0x33, 0x00, 0xb1, 0x27,
- 0x2d, 0x00, 0x14, 0x24, 0x03, 0x00, 0x00, 0x12, 0x23, 0x10, 0x02, 0x00, 0xff,
- 0xff, 0x10, 0x26, 0x33, 0x00, 0xb1, 0x27, 0x33, 0x00, 0xa0, 0xa3, 0x1b, 0x00,
- 0x44, 0x00, 0x02, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07,
- 0x00, 0x12, 0x18, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x21, 0x08, 0x5c, 0x00,
- 0x80, 0x98, 0x22, 0x90, 0xff, 0xff, 0x31, 0x26, 0x02, 0x00, 0x00, 0x12, 0x00,
- 0x00, 0x22, 0xa2, 0xff, 0xff, 0x10, 0x26, 0x21, 0x10, 0x60, 0x00, 0xf2, 0xff,
- 0x40, 0x14, 0x01, 0x00, 0x03, 0x24, 0x00, 0x16, 0x13, 0x00, 0x03, 0x16, 0x02,
- 0x00, 0x0b, 0x00, 0x43, 0x14, 0x21, 0x20, 0x80, 0x02, 0xff, 0xff, 0x10, 0x26,
- 0xff, 0xff, 0x02, 0x24, 0x07, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0x12, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24, 0xff, 0xff,
- 0x10, 0x26, 0xfc, 0xff, 0x12, 0x16, 0x21, 0x20, 0x80, 0x02, 0x04, 0x00, 0x80,
- 0x10, 0x00, 0x16, 0x13, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x16, 0x13, 0x00, 0x03, 0x16, 0x02, 0x00, 0x02, 0x00, 0x03, 0x24, 0x0e,
- 0x00, 0x43, 0x14, 0xff, 0xff, 0x02, 0x24, 0xff, 0xff, 0x10, 0x26, 0x0b, 0x00,
- 0x02, 0x12, 0xff, 0xff, 0x12, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x30, 0x00, 0x04,
- 0x24, 0xff, 0xff, 0x10, 0x26, 0x06, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00,
- 0x4d, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x04, 0x00, 0x89,
- 0x40, 0x00, 0x0c, 0x03, 0x26, 0x04, 0x00, 0x00, 0x00, 0x22, 0x82, 0x00, 0x00,
- 0x24, 0x92, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xff, 0x40, 0x14, 0x01, 0x00, 0x31,
- 0x26, 0xff, 0xff, 0x31, 0x26, 0x00, 0x16, 0x13, 0x00, 0x03, 0x16, 0x02, 0x00,
- 0x03, 0x00, 0x03, 0x24, 0x09, 0x00, 0x43, 0x14, 0xff, 0xff, 0x10, 0x26, 0xff,
- 0xff, 0x02, 0x24, 0x06, 0x00, 0x02, 0x12, 0xff, 0xff, 0x11, 0x24, 0x89, 0x40,
- 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24, 0xff, 0xff, 0x10, 0x26, 0xfc, 0xff, 0x11,
- 0x16, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0xbf, 0x8f, 0x58, 0x00, 0xb4, 0x8f,
- 0x54, 0x00, 0xb3, 0x8f, 0x50, 0x00, 0xb2, 0x8f, 0x4c, 0x00, 0xb1, 0x8f, 0x48,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x60, 0x00, 0xbd, 0x27, 0x75, 0x41,
- 0x00, 0x08, 0x21, 0x18, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x82,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x40, 0x14, 0x01, 0x00, 0x84, 0x24,
- 0x08, 0x00, 0xe0, 0x03, 0x21, 0x10, 0x60, 0x00, 0xd0, 0xff, 0xbd, 0x27, 0x24,
- 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xc0, 0x00, 0x28, 0x00, 0xbf, 0xaf, 0xbc, 0x41,
- 0x00, 0x08, 0x20, 0x00, 0xb0, 0xaf, 0xff, 0x00, 0x03, 0x32, 0x0a, 0x00, 0x02,
- 0x24, 0x0c, 0x00, 0x62, 0x10, 0x0b, 0x00, 0x62, 0x28, 0x05, 0x00, 0x40, 0x10,
- 0x09, 0x00, 0x02, 0x24, 0x10, 0x00, 0x62, 0x10, 0x20, 0x00, 0x62, 0x2c, 0x9c,
- 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02, 0x24, 0x07, 0x00,
- 0x62, 0x10, 0xff, 0x00, 0x03, 0x32, 0x9c, 0x41, 0x00, 0x08, 0x20, 0x00, 0x62,
- 0x2c, 0x89, 0x40, 0x00, 0x0c, 0x5c, 0x00, 0x04, 0x24, 0xba, 0x41, 0x00, 0x08,
- 0x6e, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x5c, 0x00, 0x04, 0x24, 0xba,
- 0x41, 0x00, 0x08, 0x72, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x5c, 0x00,
- 0x04, 0x24, 0xba, 0x41, 0x00, 0x08, 0x74, 0x00, 0x04, 0x24, 0x03, 0x00, 0x40,
- 0x14, 0xff, 0x00, 0x02, 0x24, 0x19, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x89, 0x40, 0x00, 0x0c, 0x5c, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x30,
- 0x00, 0x04, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x78, 0x00, 0x04, 0x24, 0xf0, 0x00,
- 0x02, 0x32, 0x02, 0x21, 0x02, 0x00, 0x0a, 0x00, 0x82, 0x28, 0x03, 0x00, 0x40,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0xae, 0x41, 0x00, 0x08, 0x30, 0x00, 0x84, 0x34,
- 0x37, 0x00, 0x84, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0f,
- 0x00, 0x04, 0x32, 0x0a, 0x00, 0x82, 0x28, 0x03, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0xba, 0x41, 0x00, 0x08, 0x30, 0x00, 0x84, 0x34, 0xba, 0x41, 0x00,
- 0x08, 0x37, 0x00, 0x84, 0x24, 0x00, 0x00, 0x24, 0x82, 0x00, 0x00, 0x00, 0x00,
- 0x89, 0x40, 0x00, 0x0c, 0x01, 0x00, 0x31, 0x26, 0x00, 0x00, 0x22, 0x82, 0x00,
- 0x00, 0x23, 0x92, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xff, 0x40, 0x14, 0x21, 0x80,
- 0x60, 0x00, 0x28, 0x00, 0xbf, 0x8f, 0x24, 0x00, 0xb1, 0x8f, 0x20, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0xc8, 0xff, 0xbd, 0x27,
- 0x28, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x00, 0x20, 0x00, 0xb0, 0xaf, 0x21,
- 0x80, 0xa0, 0x00, 0x24, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xc0, 0x00, 0x21, 0x20,
- 0x20, 0x02, 0x30, 0x00, 0xbf, 0xaf, 0x72, 0x41, 0x00, 0x0c, 0x2c, 0x00, 0xb3,
- 0xaf, 0x21, 0x20, 0x00, 0x00, 0x21, 0x18, 0x40, 0x00, 0x2a, 0x10, 0x70, 0x00,
- 0x02, 0x00, 0x40, 0x10, 0x21, 0x98, 0x40, 0x02, 0x23, 0x20, 0x03, 0x02, 0x00,
- 0x16, 0x12, 0x00, 0x03, 0x16, 0x02, 0x00, 0x01, 0x00, 0x03, 0x24, 0x0b, 0x00,
- 0x43, 0x14, 0x21, 0x80, 0x80, 0x00, 0xff, 0xff, 0x10, 0x26, 0xff, 0xff, 0x02,
- 0x24, 0x08, 0x00, 0x02, 0x12, 0x00, 0x16, 0x13, 0x00, 0xff, 0xff, 0x12, 0x24,
- 0x89, 0x40, 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24, 0xff, 0xff, 0x10, 0x26, 0xfc,
- 0xff, 0x12, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x13, 0x00, 0x03, 0x16,
- 0x02, 0x00, 0x02, 0x00, 0x03, 0x24, 0x0e, 0x00, 0x43, 0x14, 0xff, 0xff, 0x02,
- 0x24, 0xff, 0xff, 0x10, 0x26, 0x0b, 0x00, 0x02, 0x12, 0xff, 0xff, 0x12, 0x24,
- 0x89, 0x40, 0x00, 0x0c, 0x30, 0x00, 0x04, 0x24, 0xff, 0xff, 0x10, 0x26, 0x06,
- 0x00, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0xee, 0x41, 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x26, 0x04, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x03, 0x26, 0x04,
- 0x00, 0x00, 0x00, 0x22, 0x82, 0x00, 0x00, 0x24, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0xf9, 0xff, 0x40, 0x14, 0x01, 0x00, 0x31, 0x26, 0xff, 0xff, 0x31, 0x26, 0x00,
- 0x16, 0x13, 0x00, 0x03, 0x16, 0x02, 0x00, 0x03, 0x00, 0x03, 0x24, 0x09, 0x00,
- 0x43, 0x14, 0xff, 0xff, 0x10, 0x26, 0xff, 0xff, 0x02, 0x24, 0x06, 0x00, 0x02,
- 0x12, 0xff, 0xff, 0x11, 0x24, 0x89, 0x40, 0x00, 0x0c, 0x20, 0x00, 0x04, 0x24,
- 0xff, 0xff, 0x10, 0x26, 0xfc, 0xff, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, 0x30,
- 0x00, 0xbf, 0x8f, 0x2c, 0x00, 0xb3, 0x8f, 0x28, 0x00, 0xb2, 0x8f, 0x24, 0x00,
- 0xb1, 0x8f, 0x20, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00, 0xbd,
- 0x27, 0xd0, 0xff, 0xbd, 0x27, 0x1c, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0xa0, 0x00,
- 0x18, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x00, 0x00, 0x28, 0x00, 0xbf, 0xaf, 0x24,
- 0x00, 0xb3, 0xaf, 0x20, 0x00, 0xb2, 0xaf, 0x01, 0x00, 0x82, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x5e, 0x00, 0x40, 0x10, 0x21, 0x90, 0x00, 0x00, 0x01, 0x00, 0x93,
- 0x24, 0x00, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xff, 0x42, 0x24,
- 0x00, 0x16, 0x02, 0x00, 0x03, 0x1e, 0x02, 0x00, 0x54, 0x00, 0x62, 0x2c, 0x55,
- 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x01, 0x80, 0x01, 0x3c, 0x21, 0x08,
- 0x22, 0x00, 0xb0, 0x20, 0x22, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x42, 0x00, 0x08, 0x25, 0x00, 0x04, 0x24,
- 0x21, 0x20, 0x00, 0x00, 0x94, 0x98, 0x86, 0x27, 0x5f, 0x42, 0x00, 0x08, 0x21,
- 0x28, 0x00, 0x00, 0x00, 0x26, 0x11, 0x00, 0x45, 0x42, 0x00, 0x08, 0x03, 0x26,
- 0x04, 0x00, 0x10, 0x00, 0xb1, 0xaf, 0x02, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00,
- 0x00, 0x21, 0x30, 0x00, 0x02, 0x10, 0x41, 0x00, 0x0c, 0x21, 0x38, 0x40, 0x02,
- 0x45, 0x42, 0x00, 0x08, 0x42, 0x00, 0x04, 0x24, 0x10, 0x00, 0xb1, 0xaf, 0x08,
- 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x02, 0x10, 0x41,
- 0x00, 0x0c, 0x21, 0x38, 0x40, 0x02, 0x51, 0x00, 0x04, 0x24, 0x89, 0x40, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x00, 0x08, 0x01, 0x00, 0x62, 0x26,
- 0x10, 0x00, 0xb1, 0xaf, 0x0a, 0x00, 0x04, 0x24, 0x57, 0x42, 0x00, 0x08, 0x01,
- 0x00, 0x05, 0x24, 0x10, 0x00, 0xb1, 0xaf, 0x56, 0x42, 0x00, 0x08, 0x0a, 0x00,
- 0x04, 0x24, 0x21, 0x20, 0x00, 0x00, 0xa0, 0x98, 0x86, 0x27, 0xc6, 0x41, 0x00,
- 0x0c, 0x21, 0x28, 0x00, 0x00, 0x10, 0x00, 0xb1, 0xaf, 0x10, 0x00, 0x04, 0x24,
- 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x02, 0x10, 0x41, 0x00, 0x0c, 0x21,
- 0x38, 0x40, 0x02, 0x7c, 0x42, 0x00, 0x08, 0x01, 0x00, 0x62, 0x26, 0x21, 0x20,
- 0x00, 0x02, 0x21, 0x28, 0x40, 0x02, 0x21, 0x30, 0x20, 0x02, 0xc6, 0x41, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x00, 0x08, 0x01, 0x00, 0x62, 0x26,
- 0x21, 0x20, 0x00, 0x02, 0x21, 0x28, 0x40, 0x02, 0x7b, 0x41, 0x00, 0x0c, 0x21,
- 0x30, 0x20, 0x02, 0x7c, 0x42, 0x00, 0x08, 0x01, 0x00, 0x62, 0x26, 0x76, 0x42,
- 0x00, 0x08, 0x03, 0x00, 0x10, 0x24, 0x03, 0x00, 0x00, 0x16, 0x80, 0x10, 0x12,
- 0x00, 0x02, 0x00, 0x10, 0x24, 0x80, 0x10, 0x12, 0x00, 0x21, 0x10, 0x52, 0x00,
- 0x40, 0x10, 0x02, 0x00, 0x00, 0x00, 0x63, 0x82, 0xd0, 0xff, 0x42, 0x24, 0x02,
- 0x00, 0x00, 0x16, 0x21, 0x90, 0x43, 0x00, 0x01, 0x00, 0x10, 0x24, 0x01, 0x00,
- 0x73, 0x26, 0x00, 0x00, 0x62, 0x82, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xff, 0x40,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x24, 0x28, 0x00, 0xbf, 0x8f,
- 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0x00, 0x00,
- 0xa4, 0xaf, 0x04, 0x00, 0xa5, 0xaf, 0x08, 0x00, 0xa6, 0xaf, 0x0c, 0x00, 0xa7,
- 0xaf, 0xc8, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xb0, 0xaf, 0x21, 0x80, 0x80, 0x00,
- 0x24, 0x00, 0xb1, 0xaf, 0x34, 0x00, 0xbf, 0xaf, 0x30, 0x00, 0xb4, 0xaf, 0x2c,
- 0x00, 0xb3, 0xaf, 0x28, 0x00, 0xb2, 0xaf, 0x00, 0x00, 0x02, 0x82, 0x00, 0x00,
- 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x10, 0x3c, 0x00, 0xb1,
- 0x27, 0x25, 0x00, 0x14, 0x24, 0x45, 0x00, 0x13, 0x24, 0xfc, 0xff, 0x12, 0x24,
- 0x00, 0x16, 0x03, 0x00, 0x03, 0x26, 0x02, 0x00, 0x12, 0x00, 0x94, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x82, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x64, 0x10, 0x21, 0x20, 0x00, 0x02, 0x04, 0x00, 0x73, 0x14, 0x03, 0x00, 0x22,
- 0x26, 0x21, 0x20, 0x00, 0x02, 0xa8, 0x42, 0x00, 0x08, 0x21, 0x28, 0x00, 0x00,
- 0x24, 0x10, 0x52, 0x00, 0x04, 0x00, 0x51, 0x24, 0xfc, 0xff, 0x25, 0x8e, 0x21,
- 0x20, 0x00, 0x02, 0x12, 0x42, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xae, 0x42,
- 0x00, 0x08, 0x21, 0x80, 0x40, 0x00, 0x89, 0x40, 0x00, 0x0c, 0x01, 0x00, 0x10,
- 0x26, 0x00, 0x00, 0x02, 0x82, 0x00, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0xe6, 0xff, 0x40, 0x14, 0x00, 0x16, 0x03, 0x00, 0x34, 0x00, 0xbf, 0x8f, 0x30,
- 0x00, 0xb4, 0x8f, 0x2c, 0x00, 0xb3, 0x8f, 0x28, 0x00, 0xb2, 0x8f, 0x24, 0x00,
- 0xb1, 0x8f, 0x20, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x38, 0x00, 0xbd,
- 0x27, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x3c, 0x00,
- 0x10, 0x4a, 0x35, 0x01, 0x80, 0x0f, 0x3c, 0x00, 0x22, 0xef, 0x25, 0x01, 0xa2,
- 0x08, 0x3c, 0x0c, 0x00, 0x08, 0x35, 0xfb, 0xfe, 0x0e, 0x24, 0xff, 0xfe, 0x0d,
- 0x24, 0xe1, 0x00, 0x0c, 0x3c, 0xff, 0xfb, 0x0b, 0x24, 0x02, 0x00, 0xa9, 0x24,
- 0x00, 0x00, 0xa7, 0x94, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0xea, 0x00, 0x09,
- 0x00, 0x62, 0x2c, 0x2e, 0x00, 0x40, 0x10, 0x80, 0x10, 0x03, 0x00, 0x21, 0x10,
- 0x4f, 0x00, 0x00, 0x00, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0xfa, 0x42, 0x00, 0x08, 0x24, 0x10, 0x4e, 0x00, 0xf8, 0x9e, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x10, 0x4d, 0x00, 0xfa, 0x42, 0x00, 0x08, 0x04, 0x00,
- 0x42, 0x34, 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x42, 0x00,
- 0x08, 0x04, 0x01, 0x42, 0x34, 0x00, 0x00, 0x23, 0x95, 0x00, 0x00, 0xc2, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x62, 0x00, 0x12, 0x18, 0x00, 0x00, 0x42,
- 0x10, 0x03, 0x00, 0x21, 0x10, 0x4c, 0x00, 0x1b, 0x00, 0x43, 0x00, 0x02, 0x00,
- 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x12, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x43, 0x00, 0x08,
- 0x29, 0x00, 0x82, 0xa0, 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0x42, 0x00, 0x08, 0x24, 0x10, 0x4b, 0x00, 0xf8, 0x9e, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x42, 0x34, 0xf8, 0x9e, 0x82, 0xaf, 0x00, 0x00, 0x02,
- 0xa5, 0x02, 0x43, 0x00, 0x08, 0x04, 0x00, 0x29, 0x25, 0x00, 0x00, 0x23, 0x91,
- 0x21, 0x10, 0x87, 0x00, 0x00, 0x00, 0x43, 0xa0, 0x04, 0x00, 0x29, 0x25, 0xcb,
- 0x42, 0x00, 0x08, 0x04, 0x00, 0xa5, 0x24, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0xe8, 0xff, 0xbd, 0x27, 0x10, 0x00, 0xbf, 0xaf, 0x02, 0x80, 0x05,
- 0x3c, 0xd0, 0x99, 0xa5, 0x24, 0xc0, 0x42, 0x00, 0x0c, 0x00, 0xa1, 0x04, 0x3c,
- 0x00, 0xa1, 0x04, 0x3c, 0x02, 0x80, 0x05, 0x3c, 0x24, 0x9a, 0xa5, 0x24, 0xc0,
- 0x42, 0x00, 0x0c, 0x40, 0x00, 0x84, 0x34, 0x00, 0xa1, 0x04, 0x3c, 0x02, 0x80,
- 0x05, 0x3c, 0x78, 0x9a, 0xa5, 0x24, 0xc0, 0x42, 0x00, 0x0c, 0x00, 0x01, 0x84,
- 0x34, 0x00, 0xa1, 0x04, 0x3c, 0x02, 0x80, 0x05, 0x3c, 0x84, 0x9a, 0xa5, 0x24,
- 0xc0, 0x42, 0x00, 0x0c, 0x40, 0x01, 0x84, 0x34, 0x10, 0x00, 0xbf, 0x8f, 0x18,
- 0x00, 0xbd, 0x27, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
- 0xbd, 0x27, 0x18, 0x00, 0xb2, 0xaf, 0x21, 0x90, 0x80, 0x00, 0x14, 0x00, 0xb1,
- 0xaf, 0x21, 0x88, 0xa0, 0x00, 0x4d, 0x00, 0xc6, 0x2c, 0x1c, 0x00, 0xbf, 0xaf,
- 0x04, 0x00, 0xc0, 0x10, 0x10, 0x00, 0xb0, 0xaf, 0x4d, 0x00, 0x22, 0x2e, 0x05,
- 0x00, 0x40, 0x14, 0x00, 0xa1, 0x03, 0x3c, 0x64, 0x99, 0x84, 0x27, 0x20, 0x0c,
- 0x00, 0x0c, 0x57, 0x02, 0x05, 0x24, 0x00, 0xa1, 0x03, 0x3c, 0x40, 0x00, 0x63,
- 0x34, 0x40, 0x80, 0x11, 0x00, 0x21, 0x80, 0x11, 0x02, 0x80, 0x80, 0x10, 0x00,
- 0x02, 0x80, 0x02, 0x3c, 0x68, 0x9b, 0x42, 0x24, 0x21, 0x80, 0x02, 0x02, 0x80,
- 0x21, 0x12, 0x00, 0x00, 0x00, 0x05, 0x8e, 0x04, 0x00, 0x06, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0xc0, 0x42, 0x00, 0x0c, 0x21, 0x20, 0x83, 0x00, 0x08, 0x00, 0x02,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x40, 0x10, 0x01, 0xa2, 0x03, 0x3c,
- 0xf8, 0x9e, 0x82, 0x8f, 0x0c, 0x00, 0x63, 0x34, 0x02, 0x00, 0x42, 0x34, 0xf8,
- 0x9e, 0x82, 0xaf, 0x4d, 0x43, 0x00, 0x08, 0x00, 0x00, 0x62, 0xa4, 0x01, 0xa2,
- 0x02, 0x3c, 0x0c, 0x00, 0x42, 0x34, 0xf8, 0x9e, 0x83, 0x8f, 0xfd, 0xff, 0x04,
- 0x24, 0x24, 0x18, 0x64, 0x00, 0xf8, 0x9e, 0x83, 0xaf, 0x00, 0x00, 0x43, 0xa4,
- 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00, 0xbd, 0x27, 0x00, 0x00,
- 0x00, 0x00, 0x21, 0x38, 0x80, 0x00, 0xfd, 0xff, 0x03, 0x3c, 0x00, 0xff, 0x63,
- 0x34, 0x21, 0x18, 0xa3, 0x00, 0x40, 0x00, 0xe8, 0x8c, 0x1c, 0x00, 0xe4, 0x8c,
- 0x80, 0x11, 0x08, 0x00, 0x21, 0x20, 0x82, 0x00, 0x20, 0x00, 0xe2, 0x8c, 0x08,
- 0x00, 0xe9, 0x8c, 0x23, 0x18, 0x43, 0x00, 0x2b, 0x10, 0x66, 0x00, 0x0d, 0x00,
- 0x40, 0x10, 0x0e, 0x00, 0x82, 0x24, 0x02, 0x00, 0x82, 0xa4, 0x04, 0x00, 0x85,
- 0xac, 0x08, 0x00, 0x83, 0xa4, 0x0a, 0x00, 0x80, 0xa0, 0x20, 0x00, 0xe2, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x82, 0xac, 0x23, 0x10, 0xc3, 0x00, 0x14,
- 0x00, 0x82, 0xa4, 0x80, 0x00, 0x02, 0x24, 0x76, 0x43, 0x00, 0x08, 0x16, 0x00,
- 0x82, 0xa0, 0x0e, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82,
- 0xa4, 0x80, 0x00, 0x02, 0x24, 0x04, 0x00, 0x85, 0xac, 0x08, 0x00, 0x86, 0xa4,
- 0x0a, 0x00, 0x82, 0xa0, 0x14, 0x00, 0x80, 0xa4, 0x0e, 0x00, 0x82, 0x94, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x00, 0x22, 0xa5, 0x60, 0x00, 0x22, 0x91, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x07, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03,
- 0x3c, 0x78, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x86, 0x43, 0x00, 0x08, 0x00, 0x00, 0x62, 0xac, 0x02,
- 0x00, 0x02, 0x24, 0x60, 0x00, 0x22, 0xa1, 0x01, 0x00, 0x08, 0x25, 0x08, 0x00,
- 0x02, 0x29, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, 0x00,
- 0x00, 0x8c, 0x00, 0xe2, 0x8c, 0xd0, 0x9a, 0x83, 0x8f, 0x01, 0x00, 0x42, 0x24,
- 0x8c, 0x00, 0xe2, 0xac, 0x88, 0x00, 0xe2, 0x8c, 0x40, 0x00, 0xe8, 0xac, 0x78,
- 0x00, 0xe3, 0xac, 0x21, 0x10, 0x46, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x88, 0x00,
- 0xe2, 0xac, 0x04, 0x00, 0x86, 0x8c, 0x08, 0x00, 0x85, 0x8c, 0x11, 0x00, 0x02,
- 0x24, 0x18, 0x00, 0xc2, 0xa0, 0x01, 0x00, 0x02, 0x24, 0x29, 0x00, 0xa2, 0xa0,
- 0x38, 0x00, 0x83, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x03, 0x00, 0x21,
- 0x10, 0x43, 0x00, 0x18, 0x00, 0x83, 0x8c, 0x80, 0x10, 0x02, 0x00, 0x21, 0x18,
- 0x62, 0x00, 0x02, 0x00, 0x63, 0x24, 0x02, 0x00, 0x02, 0x24, 0x10, 0x00, 0xa3,
- 0xa4, 0x20, 0x00, 0xa2, 0xa0, 0x12, 0x00, 0x02, 0x24, 0x08, 0x00, 0xe0, 0x03,
- 0x18, 0x00, 0xc2, 0xa0, 0xc0, 0xff, 0xbd, 0x27, 0x20, 0x00, 0xb2, 0xaf, 0x21,
- 0x90, 0x80, 0x00, 0x3c, 0x00, 0xbf, 0xaf, 0x38, 0x00, 0xbe, 0xaf, 0x34, 0x00,
- 0xb7, 0xaf, 0x30, 0x00, 0xb6, 0xaf, 0x2c, 0x00, 0xb5, 0xaf, 0x28, 0x00, 0xb4,
- 0xaf, 0x24, 0x00, 0xb3, 0xaf, 0x1c, 0x00, 0xb1, 0xaf, 0x18, 0x00, 0xb0, 0xaf,
- 0x08, 0x00, 0x48, 0x8e, 0x34, 0x00, 0x44, 0x8e, 0x30, 0x00, 0x46, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x00, 0x86, 0x10, 0x10, 0x00, 0xa8, 0xaf, 0x40, 0x10,
- 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, 0x24, 0x00, 0x43, 0x8e, 0xc0, 0x28, 0x02,
- 0x00, 0x21, 0x18, 0xa3, 0x00, 0x10, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0x40, 0x14, 0x41, 0x00, 0x02, 0x24, 0x40, 0x00, 0x07, 0x24, 0x21,
- 0x18, 0xa0, 0x00, 0x01, 0x00, 0x84, 0x24, 0x03, 0x00, 0x87, 0x14, 0x18, 0x00,
- 0x63, 0x24, 0x21, 0x18, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x0a, 0x00, 0x86,
- 0x10, 0x41, 0x00, 0x02, 0x24, 0x24, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00,
- 0x21, 0x10, 0x62, 0x00, 0x10, 0x00, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x00, 0xf4,
- 0xff, 0x40, 0x10, 0x01, 0x00, 0x84, 0x24, 0xff, 0xff, 0x84, 0x24, 0x41, 0x00,
- 0x02, 0x24, 0x34, 0x00, 0x44, 0xae, 0x10, 0x00, 0xa8, 0x8f, 0xaa, 0xaa, 0x03,
- 0x3c, 0xab, 0xaa, 0x63, 0x34, 0x20, 0x00, 0x02, 0xa1, 0x10, 0x00, 0x02, 0x95,
- 0x18, 0x00, 0x50, 0x8e, 0xff, 0xff, 0x5e, 0x30, 0xff, 0xff, 0x02, 0x32, 0x23,
- 0x10, 0xc2, 0x03, 0x19, 0x00, 0x43, 0x00, 0x38, 0x00, 0x54, 0x8e, 0x3c, 0x00,
- 0x57, 0x8e, 0x10, 0x40, 0x00, 0x00, 0xc2, 0x88, 0x08, 0x00, 0x01, 0x02, 0x22,
- 0x2e, 0x05, 0x00, 0x40, 0x14, 0x40, 0x10, 0x11, 0x00, 0x70, 0x99, 0x84, 0x27,
- 0x20, 0x0c, 0x00, 0x0c, 0x0c, 0x01, 0x05, 0x24, 0x40, 0x10, 0x11, 0x00, 0x21,
- 0x10, 0x51, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x02, 0x02, 0x02, 0x00,
- 0x42, 0x24, 0xff, 0xff, 0x42, 0x30, 0x05, 0x00, 0xc2, 0x13, 0x23, 0x28, 0x34,
- 0x02, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x0d, 0x01, 0x05, 0x24,
- 0x23, 0x28, 0x34, 0x02, 0x01, 0x02, 0xa5, 0x24, 0x80, 0xff, 0x02, 0x3c, 0xe1,
- 0x3f, 0x42, 0x34, 0x19, 0x00, 0xa2, 0x00, 0xc0, 0x7f, 0x02, 0x3c, 0xf1, 0x1f,
- 0x42, 0x34, 0x10, 0x18, 0x00, 0x00, 0x23, 0x20, 0xf4, 0x02, 0x01, 0x02, 0x84,
- 0x24, 0x18, 0x00, 0x82, 0x00, 0x42, 0x1a, 0x03, 0x00, 0x40, 0x12, 0x03, 0x00,
- 0x21, 0x10, 0x43, 0x00, 0x23, 0x28, 0xa2, 0x00, 0xc3, 0x17, 0x04, 0x00, 0x10,
- 0x38, 0x00, 0x00, 0x03, 0x1a, 0x07, 0x00, 0x23, 0x18, 0x62, 0x00, 0x40, 0x12,
- 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x23, 0x20, 0x82, 0x00, 0x2b, 0x20, 0x85,
- 0x00, 0x05, 0x00, 0x80, 0x10, 0x21, 0xb0, 0x00, 0x00, 0x70, 0x99, 0x84, 0x27,
- 0x20, 0x0c, 0x00, 0x0c, 0x0e, 0x01, 0x05, 0x24, 0x21, 0xb0, 0x00, 0x00, 0x21,
- 0x98, 0x00, 0x00, 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x54, 0x00, 0x80, 0x10,
- 0x02, 0x00, 0x18, 0x00, 0x43, 0x8e, 0x21, 0x88, 0x40, 0x00, 0x21, 0x80, 0x71,
- 0x00, 0x04, 0x00, 0x15, 0x8e, 0x02, 0x00, 0x02, 0x26, 0xff, 0xff, 0x42, 0x30,
- 0xa8, 0x00, 0x5e, 0x10, 0x06, 0x00, 0xc2, 0x2a, 0x05, 0x00, 0x97, 0x12, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00,
- 0x0c, 0x20, 0x01, 0x05, 0x24, 0x01, 0x00, 0x94, 0x26, 0x01, 0x02, 0x82, 0x2a,
- 0x03, 0x00, 0x40, 0x14, 0x0c, 0x00, 0x31, 0x26, 0x21, 0x88, 0x00, 0x00, 0x21,
- 0xa0, 0x00, 0x00, 0x08, 0x00, 0x02, 0x96, 0x0a, 0x00, 0x10, 0x92, 0x00, 0x00,
- 0x00, 0x00, 0x0b, 0x00, 0x00, 0x16, 0x21, 0x98, 0x62, 0x02, 0x00, 0x01, 0x08,
- 0x24, 0x04, 0x00, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x99, 0x84, 0x27,
- 0x20, 0x0c, 0x00, 0x0c, 0x28, 0x01, 0x05, 0x24, 0x18, 0x00, 0x42, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x44, 0x00, 0x08, 0x21, 0x80, 0x51, 0x00, 0x80, 0x00,
- 0x02, 0x32, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x70, 0x99, 0x84,
- 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x2d, 0x01, 0x05, 0x24, 0xc0, 0x00, 0x42, 0x8e,
- 0xb8, 0x00, 0x43, 0x8e, 0x21, 0x10, 0x53, 0x00, 0x01, 0x00, 0x63, 0x24, 0xc0,
- 0x00, 0x42, 0xae, 0x7c, 0x00, 0x02, 0x32, 0x2e, 0x00, 0x40, 0x10, 0xb8, 0x00,
- 0x43, 0xae, 0x40, 0x00, 0x02, 0x32, 0x06, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03,
- 0x3c, 0x8c, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x20, 0x00, 0x02, 0x32, 0x06,
- 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x90, 0x0d, 0x63, 0x34, 0x00, 0x00,
- 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62,
- 0xac, 0x10, 0x00, 0x02, 0x32, 0x06, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c,
- 0x9c, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0x08, 0x00, 0x02, 0x32, 0x06, 0x00,
- 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x94, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac,
- 0x04, 0x00, 0x02, 0x32, 0x06, 0x00, 0x40, 0x10, 0x00, 0xa0, 0x03, 0x3c, 0x98,
- 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x42, 0x24, 0x00, 0x00, 0x62, 0xac, 0xc8, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x42, 0x24, 0xc3, 0x44, 0x00, 0x08, 0xc8, 0x00, 0x42, 0xae,
- 0x22, 0x33, 0x03, 0x3c, 0x00, 0x00, 0xa2, 0x8e, 0x00, 0x11, 0x63, 0x34, 0x12,
- 0x00, 0x43, 0x14, 0xfd, 0xff, 0x03, 0x3c, 0x00, 0xff, 0x63, 0x34, 0x21, 0x10,
- 0xb3, 0x02, 0x20, 0x00, 0x44, 0x8e, 0x21, 0x10, 0x43, 0x00, 0x23, 0x30, 0x44,
- 0x00, 0x04, 0x00, 0xc0, 0x18, 0x02, 0x00, 0x05, 0x3c, 0x00, 0x01, 0xa5, 0x34,
- 0x78, 0x11, 0x00, 0x0c, 0x21, 0x28, 0x85, 0x00, 0x21, 0x20, 0xa0, 0x02, 0x8e,
- 0x20, 0x00, 0x0c, 0x21, 0x28, 0x60, 0x02, 0x38, 0x00, 0x40, 0x10, 0x00, 0xa0,
- 0x03, 0x3c, 0xab, 0x44, 0x00, 0x08, 0xfc, 0x0d, 0x63, 0x34, 0xf4, 0x9f, 0x82,
- 0x8f, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x90, 0x1d, 0x00, 0x0c, 0x64, 0x00, 0x04, 0x24, 0xf4, 0x9f, 0x83, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x2a, 0x18, 0x62, 0x00, 0x03, 0x00, 0x60, 0x14, 0x00, 0xa0,
- 0x03, 0x3c, 0xab, 0x44, 0x00, 0x08, 0xd8, 0x0d, 0x63, 0x34, 0x30, 0x00, 0x50,
- 0x8e, 0x24, 0x00, 0x43, 0x8e, 0x40, 0x10, 0x10, 0x00, 0x21, 0x10, 0x50, 0x00,
- 0x01, 0x00, 0x10, 0x26, 0xc0, 0x10, 0x02, 0x00, 0x21, 0x88, 0x62, 0x00, 0x40,
- 0x00, 0x02, 0x24, 0x02, 0x00, 0x02, 0x16, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80,
- 0x00, 0x00, 0x34, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02,
- 0x16, 0x00, 0xa0, 0x03, 0x3c, 0xb0, 0x0d, 0x63, 0x34, 0x00, 0x00, 0x62, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xc3, 0x44, 0x00, 0x08, 0x00,
- 0x00, 0x62, 0xac, 0x10, 0x00, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
- 0x40, 0x10, 0x21, 0x20, 0x40, 0x02, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00,
- 0x0c, 0x82, 0x01, 0x05, 0x24, 0x21, 0x20, 0x40, 0x02, 0x38, 0x00, 0x42, 0x8e,
- 0x21, 0x28, 0x20, 0x02, 0x08, 0x00, 0x35, 0xae, 0x14, 0x00, 0x33, 0xae, 0xf1,
- 0x22, 0x00, 0x0c, 0x0c, 0x00, 0x22, 0xae, 0x10, 0x00, 0x22, 0x8e, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x50,
- 0xae, 0x38, 0x00, 0x54, 0xae, 0x13, 0x44, 0x00, 0x08, 0x01, 0x00, 0xd6, 0x26,
- 0x02, 0x00, 0x40, 0x14, 0x00, 0xa0, 0x02, 0x3c, 0x05, 0x00, 0x16, 0x24, 0x48,
- 0x0d, 0x42, 0x34, 0x80, 0x18, 0x16, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00,
- 0x62, 0x8c, 0x23, 0xb0, 0x97, 0x02, 0x01, 0x00, 0x42, 0x24, 0x02, 0x00, 0xc1,
- 0x06, 0x00, 0x00, 0x62, 0xac, 0x01, 0x02, 0xd6, 0x26, 0x01, 0x02, 0xc2, 0x2a,
- 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x70, 0x99, 0x84, 0x27, 0x20,
- 0x0c, 0x00, 0x0c, 0xa3, 0x01, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3c, 0x40, 0xf7,
- 0x42, 0x24, 0x80, 0x18, 0x16, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x62,
- 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x62, 0xac,
- 0x30, 0x00, 0x42, 0x8e, 0x34, 0x00, 0x43, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x43, 0x10, 0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0x24, 0x00,
- 0x43, 0x8e, 0xc0, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x0c, 0x00, 0x57,
- 0x8c, 0xf1, 0x44, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x42, 0x8e,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x10, 0x00, 0x02, 0x17, 0x24, 0xff,
- 0xff, 0x57, 0x24, 0x3c, 0x00, 0x42, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
- 0xe2, 0x12, 0x40, 0x10, 0x17, 0x00, 0x21, 0x10, 0x57, 0x00, 0x80, 0x10, 0x02,
- 0x00, 0x18, 0x00, 0x43, 0x8e, 0x10, 0x00, 0xa8, 0x8f, 0x21, 0x18, 0x62, 0x00,
- 0x02, 0x00, 0x63, 0x24, 0x14, 0x00, 0x03, 0xa5, 0x3c, 0x00, 0x57, 0xae, 0x10,
- 0x00, 0xa8, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x91, 0x02, 0x00,
- 0x03, 0x24, 0x22, 0x00, 0x42, 0x30, 0x0b, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xa0, 0x02, 0x3c, 0x80, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xac, 0x21,
- 0x00, 0x02, 0x24, 0x20, 0x00, 0x02, 0xa1, 0x95, 0x43, 0x00, 0x0c, 0x21, 0x20,
- 0x40, 0x02, 0x3c, 0x00, 0xbf, 0x8f, 0x38, 0x00, 0xbe, 0x8f, 0x34, 0x00, 0xb7,
- 0x8f, 0x30, 0x00, 0xb6, 0x8f, 0x2c, 0x00, 0xb5, 0x8f, 0x28, 0x00, 0xb4, 0x8f,
- 0x24, 0x00, 0xb3, 0x8f, 0x20, 0x00, 0xb2, 0x8f, 0x1c, 0x00, 0xb1, 0x8f, 0x18,
- 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x40, 0x00, 0xbd, 0x27, 0xd0, 0xff,
- 0xbd, 0x27, 0x14, 0x00, 0xb1, 0xaf, 0x21, 0x88, 0x80, 0x00, 0x00, 0xa0, 0x02,
- 0x3c, 0x44, 0x0d, 0x42, 0x34, 0x2c, 0x00, 0xbf, 0xaf, 0x28, 0x00, 0xb6, 0xaf,
- 0x24, 0x00, 0xb5, 0xaf, 0x20, 0x00, 0xb4, 0xaf, 0x1c, 0x00, 0xb3, 0xaf, 0x18,
- 0x00, 0xb2, 0xaf, 0x10, 0x00, 0xb0, 0xaf, 0x04, 0x00, 0x25, 0x8e, 0x00, 0x00,
- 0x43, 0x8c, 0x04, 0x00, 0xa4, 0x94, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43,
- 0xac, 0x08, 0x00, 0x26, 0x8e, 0x00, 0x80, 0x84, 0x30, 0x07, 0x00, 0x80, 0x10,
- 0x00, 0xa0, 0x02, 0x3c, 0xa4, 0x0d, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8c, 0x00,
- 0x80, 0x04, 0x34, 0x04, 0x00, 0xa4, 0xa4, 0x01, 0x00, 0x63, 0x24, 0x00, 0x00,
- 0x43, 0xac, 0x41, 0x00, 0x02, 0x24, 0x60, 0x00, 0xc2, 0xa0, 0x44, 0x00, 0x32,
- 0x8e, 0x50, 0x00, 0xc2, 0x94, 0x1c, 0x00, 0x30, 0x8e, 0x40, 0x00, 0x34, 0x8e,
- 0xff, 0xff, 0x55, 0x30, 0xff, 0xff, 0x02, 0x32, 0x23, 0x10, 0xa2, 0x02, 0x82,
- 0x99, 0x02, 0x00, 0x08, 0x00, 0x62, 0x2e, 0x05, 0x00, 0x40, 0x14, 0x80, 0x11,
- 0x13, 0x00, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x06, 0x02, 0x05,
- 0x24, 0x80, 0x11, 0x13, 0x00, 0x21, 0x18, 0x02, 0x02, 0x02, 0x00, 0x62, 0x24,
- 0xff, 0xff, 0x42, 0x30, 0x07, 0x00, 0xa2, 0x12, 0x0e, 0x00, 0x62, 0x24, 0xff,
- 0xff, 0x42, 0x30, 0x05, 0x00, 0xa2, 0x12, 0x23, 0x18, 0x72, 0x02, 0x70, 0x99,
- 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x0c, 0x02, 0x05, 0x24, 0x23, 0x18, 0x72,
- 0x02, 0x08, 0x00, 0x63, 0x24, 0x07, 0x00, 0x63, 0x30, 0x23, 0x10, 0x92, 0x02,
- 0x08, 0x00, 0x42, 0x24, 0x07, 0x00, 0x42, 0x30, 0x2b, 0x10, 0x43, 0x00, 0x05,
- 0x00, 0x40, 0x10, 0x21, 0xa0, 0x00, 0x00, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c,
- 0x00, 0x0c, 0x0e, 0x02, 0x05, 0x24, 0x21, 0xa0, 0x00, 0x00, 0x03, 0x00, 0x16,
- 0x24, 0x1c, 0x00, 0x23, 0x8e, 0x80, 0x11, 0x12, 0x00, 0x21, 0x80, 0x62, 0x00,
- 0x02, 0x00, 0x02, 0x26, 0xff, 0xff, 0x42, 0x30, 0x23, 0x10, 0xa2, 0x02, 0x40,
- 0x00, 0x42, 0x2c, 0x52, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
- 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x16, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x21, 0x02, 0x05, 0x24,
- 0x08, 0x00, 0x03, 0x96, 0x14, 0x00, 0x02, 0x96, 0x18, 0x00, 0x04, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x96, 0x10, 0x21, 0x98, 0x62, 0x00, 0x04, 0x00,
- 0x02, 0x24, 0x1f, 0x00, 0x82, 0x10, 0x01, 0x00, 0x02, 0x24, 0xa3, 0x45, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x10, 0x8e, 0x84, 0x00, 0x22, 0x8e,
- 0x08, 0x00, 0x03, 0x8e, 0xfc, 0xff, 0x42, 0x24, 0x23, 0x10, 0x43, 0x00, 0x84,
- 0x00, 0x22, 0xae, 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x42, 0x24, 0x0a, 0x00, 0x42, 0x2c, 0x04, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x3e, 0x02, 0x05, 0x24,
- 0x04, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x24, 0x1d,
- 0x00, 0x40, 0x14, 0x04, 0x00, 0x02, 0xae, 0xf0, 0x9f, 0x82, 0x8f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0xae, 0x64, 0x00, 0x22, 0x8e, 0xf0, 0x9f, 0x90,
- 0xaf, 0x01, 0x00, 0x42, 0x24, 0xaa, 0x45, 0x00, 0x08, 0x64, 0x00, 0x22, 0xae,
- 0x20, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x8c, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x56, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x99,
- 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x59, 0x02, 0x05, 0x24, 0x20, 0x00, 0x02,
- 0x8e, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x45, 0x00, 0x08, 0x10, 0x00, 0x40, 0xac,
- 0x18, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x70, 0x99, 0x84, 0x27, 0x20, 0x0c, 0x00, 0x0c, 0x5f, 0x02,
- 0x05, 0x24, 0x01, 0x00, 0x52, 0x26, 0x88, 0x00, 0x22, 0x8e, 0xa8, 0x00, 0x23,
- 0x8e, 0x23, 0x10, 0x53, 0x00, 0x88, 0x00, 0x22, 0xae, 0xb0, 0x00, 0x22, 0x8e,
- 0x01, 0x00, 0x63, 0x24, 0xa8, 0x00, 0x23, 0xae, 0x21, 0x10, 0x53, 0x00, 0xb0,
- 0x00, 0x22, 0xae, 0x08, 0x00, 0x42, 0x2e, 0xa9, 0xff, 0x40, 0x14, 0x01, 0x00,
- 0x94, 0x26, 0x5f, 0x45, 0x00, 0x08, 0x21, 0x90, 0x00, 0x00, 0xd0, 0x9a, 0x83,
- 0x8f, 0x8c, 0x00, 0x22, 0x8e, 0x44, 0x00, 0x32, 0xae, 0x23, 0x10, 0x54, 0x00,
- 0x78, 0x00, 0x23, 0xae, 0x8c, 0x00, 0x22, 0xae, 0x2c, 0x00, 0xbf, 0x8f, 0x28,
- 0x00, 0xb6, 0x8f, 0x24, 0x00, 0xb5, 0x8f, 0x20, 0x00, 0xb4, 0x8f, 0x1c, 0x00,
- 0xb3, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14, 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0,
- 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x30, 0x00, 0xbd, 0x27, 0xe0, 0xff, 0xbd, 0x27,
- 0x00, 0xa0, 0x04, 0x3c, 0x40, 0x0d, 0x84, 0x34, 0x00, 0xa1, 0x02, 0x3c, 0x1c,
- 0x00, 0xbf, 0xaf, 0x18, 0x00, 0xb2, 0xaf, 0x14, 0x00, 0xb1, 0xaf, 0x10, 0x00,
- 0xb0, 0xaf, 0x20, 0x00, 0x43, 0x94, 0x00, 0x00, 0x82, 0x8c, 0xff, 0xff, 0x70,
- 0x30, 0x01, 0x00, 0x42, 0x24, 0x1c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x82, 0xac,
- 0x02, 0x80, 0x11, 0x3c, 0x1c, 0xcc, 0x31, 0x26, 0x00, 0xa1, 0x12, 0x3c, 0x0c,
- 0x08, 0x02, 0x32, 0x05, 0x00, 0x40, 0x10, 0x03, 0x03, 0x02, 0x32, 0x02, 0x80,
- 0x04, 0x3c, 0x1a, 0x45, 0x00, 0x0c, 0xf0, 0xcb, 0x84, 0x24, 0x03, 0x03, 0x02,
- 0x32, 0x04, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3c,
- 0xa9, 0x43, 0x00, 0x0c, 0xf0, 0xcb, 0x84, 0x24, 0x00, 0x00, 0x22, 0x8e, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x65, 0x1c, 0x00, 0x0c, 0xd4, 0xff, 0x24, 0x26, 0x20, 0x00, 0x42,
- 0x96, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x50, 0x30, 0xe9, 0xff, 0x00, 0x16,
- 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xbf, 0x8f, 0x18, 0x00, 0xb2, 0x8f, 0x14,
- 0x00, 0xb1, 0x8f, 0x10, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x20, 0x00,
- 0xbd, 0x27, 0xb0, 0xff, 0xbd, 0x27, 0x00, 0xa0, 0x04, 0x3c, 0x40, 0x0d, 0x84,
- 0x34, 0x00, 0xa0, 0x05, 0x3c, 0x00, 0x0e, 0xa5, 0x34, 0x4c, 0x00, 0xbf, 0xaf,
- 0x48, 0x00, 0xbe, 0xaf, 0x44, 0x00, 0xb7, 0xaf, 0x40, 0x00, 0xb6, 0xaf, 0x3c,
- 0x00, 0xb5, 0xaf, 0x38, 0x00, 0xb4, 0xaf, 0x34, 0x00, 0xb3, 0xaf, 0x30, 0x00,
- 0xb2, 0xaf, 0x2c, 0x00, 0xb1, 0xaf, 0xa5, 0x1d, 0x00, 0x0c, 0x28, 0x00, 0xb0,
- 0xaf, 0x02, 0x80, 0x03, 0x3c, 0x44, 0xff, 0x63, 0x24, 0x00, 0xa0, 0x02, 0x3c,
- 0x25, 0x20, 0x62, 0x00, 0x00, 0x02, 0x82, 0x24, 0x26, 0x10, 0x44, 0x00, 0xff,
- 0xff, 0x03, 0x3c, 0x24, 0x10, 0x43, 0x00, 0x60, 0x9e, 0x84, 0xaf, 0x04, 0x00,
- 0x40, 0x10, 0x01, 0x00, 0x02, 0x3c, 0x21, 0x10, 0x82, 0x00, 0x24, 0x10, 0x43,
- 0x00, 0x60, 0x9e, 0x82, 0xaf, 0x60, 0x9e, 0x82, 0x8f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x45, 0x24, 0xec, 0x9f, 0x82, 0xaf, 0x0c, 0x1a, 0x42, 0x24, 0x26,
- 0x10, 0x45, 0x00, 0x24, 0x10, 0x43, 0x00, 0x60, 0x9e, 0x85, 0xaf, 0x04, 0x00,
- 0x40, 0x10, 0x01, 0x00, 0x02, 0x3c, 0x21, 0x10, 0xa2, 0x00, 0x24, 0x10, 0x43,
- 0x00, 0x60, 0x9e, 0x82, 0xaf, 0x02, 0x00, 0x05, 0x3c, 0x00, 0x14, 0xa5, 0x34,
- 0x02, 0x80, 0x14, 0x3c, 0xf0, 0xcb, 0x94, 0x26, 0x60, 0x9e, 0x86, 0x8f, 0x00,
- 0xff, 0x02, 0x24, 0x0b, 0x19, 0xc3, 0x24, 0x24, 0x18, 0x62, 0x00, 0x21, 0x28,
- 0x65, 0x00, 0xc4, 0x9f, 0x86, 0xaf, 0x60, 0x9e, 0x83, 0xaf, 0xbc, 0x9f, 0x83,
- 0xaf, 0x60, 0x9e, 0x85, 0xaf, 0xa5, 0x1d, 0x00, 0x0c, 0x21, 0x98, 0x00, 0x00,
- 0x06, 0x43, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x64, 0x9f, 0x82, 0x8f, 0x00,
- 0x00, 0x00, 0x00, 0x71, 0x00, 0x40, 0x18, 0x00, 0xa1, 0x0a, 0x3c, 0x02, 0x00,
- 0x09, 0x24, 0x1c, 0x00, 0x92, 0x26, 0x00, 0x01, 0x08, 0x24, 0x40, 0x00, 0x1e,
- 0x24, 0x21, 0xb8, 0x00, 0x00, 0x21, 0xb0, 0x00, 0x00, 0x21, 0xa8, 0x00, 0x00,
- 0x07, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3c, 0x50, 0xed, 0x42, 0x24, 0xbc,
- 0x9f, 0x83, 0x8f, 0x21, 0x10, 0xa2, 0x02, 0x08, 0x00, 0x42, 0xae, 0xec, 0x9f,
- 0x82, 0x8f, 0x21, 0x18, 0x76, 0x00, 0x04, 0x00, 0x43, 0xae, 0x40, 0x1a, 0x13,
- 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x42, 0xae, 0xc4, 0x9f, 0x82, 0x8f,
- 0x00, 0x00, 0x43, 0x8e, 0x21, 0x10, 0x57, 0x00, 0xce, 0x01, 0x65, 0x24, 0x02,
- 0x02, 0x64, 0x24, 0xfc, 0xff, 0x42, 0xae, 0xc0, 0x01, 0x62, 0x24, 0x02, 0x00,
- 0x63, 0x24, 0x02, 0x00, 0x43, 0xa4, 0x0e, 0x00, 0x43, 0xa4, 0xc0, 0xff, 0xa5,
- 0x24, 0xc0, 0xff, 0x84, 0x24, 0xff, 0xff, 0xc6, 0x24, 0xf4, 0xff, 0xa4, 0xa4,
- 0xfb, 0xff, 0xc0, 0x14, 0x00, 0x00, 0xa4, 0xa4, 0x02, 0x00, 0x04, 0x3c, 0x00,
- 0x02, 0x07, 0x24, 0x04, 0x00, 0x42, 0x8e, 0xfc, 0xff, 0x43, 0x8e, 0x21, 0x20,
- 0x44, 0x00, 0x02, 0x18, 0x65, 0x24, 0x0e, 0x18, 0x66, 0x24, 0x00, 0x18, 0x62,
- 0x24, 0x02, 0x00, 0x63, 0x24, 0x04, 0x00, 0x44, 0xac, 0x02, 0x00, 0x43, 0xa4,
- 0xf4, 0xff, 0xa5, 0x24, 0xf4, 0xff, 0xc6, 0x24, 0x00, 0xff, 0x84, 0x24, 0xff,
- 0xff, 0xe7, 0x24, 0x02, 0x00, 0xa4, 0xac, 0xfa, 0xff, 0xe0, 0x14, 0x00, 0x00,
- 0xa6, 0xa4, 0x21, 0x20, 0x60, 0x02, 0x21, 0x80, 0x0a, 0x01, 0x80, 0x00, 0x08,
- 0x25, 0x21, 0x88, 0xca, 0x03, 0x40, 0x00, 0xde, 0x27, 0x01, 0x00, 0x02, 0x24,
- 0x20, 0x00, 0x40, 0xae, 0x1c, 0x00, 0x42, 0xae, 0x00, 0x00, 0x8a, 0xae, 0x2c,
- 0x00, 0x45, 0x8e, 0x30, 0x00, 0x46, 0x8e, 0x0c, 0x18, 0xf7, 0x26, 0xe8, 0xff,
- 0x51, 0xae, 0xec, 0xff, 0x50, 0xae, 0x18, 0x00, 0xa8, 0xaf, 0x1c, 0x00, 0xa9,
- 0xaf, 0x1f, 0x43, 0x00, 0x0c, 0x20, 0x00, 0xaa, 0xaf, 0x00, 0x06, 0xb5, 0x26,
- 0xfc, 0xff, 0x42, 0x8e, 0x01, 0x00, 0x73, 0x26, 0x02, 0x00, 0x42, 0x24, 0x02,
- 0x14, 0x02, 0x00, 0x0c, 0x00, 0x02, 0xa2, 0xfc, 0xff, 0x42, 0x8e, 0x68, 0x01,
- 0x94, 0x26, 0x02, 0x00, 0x42, 0x24, 0x14, 0x00, 0x02, 0xa6, 0xfc, 0xff, 0x42,
- 0x8e, 0x02, 0x00, 0x03, 0x3c, 0x0e, 0x00, 0x42, 0x24, 0x10, 0x00, 0x02, 0xa6,
- 0x00, 0x01, 0x02, 0x24, 0x18, 0x00, 0x02, 0xa6, 0x00, 0x00, 0x42, 0x8e, 0x00,
- 0x14, 0x63, 0x34, 0x02, 0x00, 0x42, 0x24, 0x02, 0x14, 0x02, 0x00, 0x4c, 0x00,
- 0x02, 0xa2, 0x00, 0x00, 0x42, 0x8e, 0x21, 0xb0, 0xc3, 0x02, 0x02, 0x00, 0x42,
- 0x24, 0x50, 0x00, 0x02, 0xa6, 0x00, 0x00, 0x42, 0x8e, 0x68, 0x01, 0x52, 0x26,
- 0x02, 0x00, 0x42, 0x24, 0x54, 0x00, 0x02, 0xa6, 0x1c, 0x00, 0xa9, 0x8f, 0x12,
- 0x00, 0x02, 0x24, 0x20, 0x00, 0x09, 0xa2, 0x60, 0x00, 0x09, 0xa2, 0x18, 0x00,
- 0x22, 0xa2, 0x18, 0x00, 0x29, 0xa2, 0x64, 0x9f, 0x82, 0x8f, 0x18, 0x00, 0xa8,
- 0x8f, 0x20, 0x00, 0xaa, 0x8f, 0x2a, 0x10, 0x62, 0x02, 0x99, 0xff, 0x40, 0x14,
- 0x07, 0x00, 0x06, 0x24, 0x4c, 0x00, 0xbf, 0x8f, 0x48, 0x00, 0xbe, 0x8f, 0x44,
- 0x00, 0xb7, 0x8f, 0x40, 0x00, 0xb6, 0x8f, 0x3c, 0x00, 0xb5, 0x8f, 0x38, 0x00,
- 0xb4, 0x8f, 0x34, 0x00, 0xb3, 0x8f, 0x30, 0x00, 0xb2, 0x8f, 0x2c, 0x00, 0xb1,
- 0x8f, 0x28, 0x00, 0xb0, 0x8f, 0x08, 0x00, 0xe0, 0x03, 0x50, 0x00, 0xbd, 0x27,
- 0x2e, 0x2e, 0x2f, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
- 0x73, 0x00, 0x00, 0x88, 0x50, 0x00, 0x80, 0x88, 0x50, 0x00, 0x80, 0xa0, 0x57,
- 0x00, 0x80, 0xa0, 0x57, 0x00, 0x80, 0x98, 0x50, 0x00, 0x80, 0xc8, 0x50, 0x00,
- 0x80, 0xa0, 0x57, 0x00, 0x80, 0xac, 0x51, 0x00, 0x80, 0xc8, 0x51, 0x00, 0x80,
- 0xe4, 0x51, 0x00, 0x80, 0x00, 0x52, 0x00, 0x80, 0x1c, 0x52, 0x00, 0x80, 0x38,
- 0x52, 0x00, 0x80, 0x54, 0x52, 0x00, 0x80, 0x70, 0x52, 0x00, 0x80, 0xd0, 0x50,
- 0x00, 0x80, 0xc0, 0x53, 0x00, 0x80, 0xc0, 0x53, 0x00, 0x80, 0x30, 0x54, 0x00,
- 0x80, 0xd0, 0x53, 0x00, 0x80, 0xbc, 0x54, 0x00, 0x80, 0xf4, 0x54, 0x00, 0x80,
- 0x18, 0x55, 0x00, 0x80, 0x40, 0x55, 0x00, 0x80, 0x5c, 0x55, 0x00, 0x80, 0x78,
- 0x55, 0x00, 0x80, 0x94, 0x55, 0x00, 0x80, 0xb0, 0x55, 0x00, 0x80, 0xcc, 0x55,
- 0x00, 0x80, 0xe8, 0x55, 0x00, 0x80, 0x04, 0x56, 0x00, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xc8, 0x5f, 0x00, 0x80, 0x1c, 0x62, 0x00, 0x80, 0x40, 0x62, 0x00, 0x80,
- 0xa4, 0x62, 0x00, 0x80, 0x08, 0x63, 0x00, 0x80, 0x54, 0x63, 0x00, 0x80, 0x68,
- 0x63, 0x00, 0x80, 0x7c, 0x63, 0x00, 0x80, 0x90, 0x63, 0x00, 0x80, 0xa4, 0x63,
- 0x00, 0x80, 0xb8, 0x63, 0x00, 0x80, 0x04, 0x64, 0x00, 0x80, 0x14, 0x64, 0x00,
- 0x80, 0x34, 0x64, 0x00, 0x80, 0x44, 0x64, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0xf8, 0x64, 0x00, 0x80, 0xf8, 0x64, 0x00, 0x80, 0xf8, 0x64, 0x00, 0x80, 0xf8,
- 0x64, 0x00, 0x80, 0xf8, 0x64, 0x00, 0x80, 0xf8, 0x64, 0x00, 0x80, 0xf8, 0x64,
- 0x00, 0x80, 0xf8, 0x64, 0x00, 0x80, 0x10, 0x65, 0x00, 0x80, 0x24, 0x65, 0x00,
- 0x80, 0x3c, 0x66, 0x00, 0x80, 0xb4, 0x66, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80,
- 0xa4, 0x68, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80, 0xfc, 0x66, 0x00, 0x80, 0x2c,
- 0x67, 0x00, 0x80, 0x2c, 0x67, 0x00, 0x80, 0x2c, 0x67, 0x00, 0x80, 0x2c, 0x67,
- 0x00, 0x80, 0x58, 0x67, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80, 0xa4, 0x68, 0x00,
- 0x80, 0xa4, 0x68, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80,
- 0xa4, 0x68, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80, 0xa4, 0x68, 0x00, 0x80, 0xa4,
- 0x68, 0x00, 0x80, 0x94, 0x68, 0x00, 0x80, 0x9c, 0x68, 0x00, 0x80, 0xd0, 0x86,
- 0x00, 0x80, 0x58, 0x87, 0x00, 0x80, 0xa8, 0x87, 0x00, 0x80, 0x94, 0x87, 0x00,
- 0x80, 0x94, 0x87, 0x00, 0x80, 0x94, 0x87, 0x00, 0x80, 0x94, 0x87, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0xf4, 0xb1, 0x00, 0x80, 0x0c, 0xb3, 0x00, 0x80, 0x0c,
- 0xb3, 0x00, 0x80, 0x0c, 0xb3, 0x00, 0x80, 0x0c, 0xb3, 0x00, 0x80, 0x08, 0xb2,
- 0x00, 0x80, 0x1c, 0xb2, 0x00, 0x80, 0x04, 0xb3, 0x00, 0x80, 0x7c, 0xb2, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x43, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x54,
- 0x31, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x6f,
- 0x6e, 0x20, 0x20, 0x53, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20,
- 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0d, 0x0a, 0x41,
- 0x20, 0x3a, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x61, 0x6c,
- 0x61, 0x72, 0x6d, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x44, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
- 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68,
- 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2c, 0x0d,
- 0x0a, 0x42, 0x20, 0x3a, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20,
- 0x42, 0x49, 0x4f, 0x53, 0x2f, 0x4e, 0x56, 0x52, 0x41, 0x4d, 0x20, 0x69, 0x6e,
- 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x0d, 0x0a, 0x45,
- 0x20, 0x3a, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x65, 0x71,
- 0x75, 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x76, 0x69, 0x73,
- 0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x0d, 0x0a, 0x3f, 0x20, 0x6f,
- 0x72, 0x20, 0x48, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61,
- 0x79, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x20, 0x6d,
- 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x0d, 0x0a, 0x61, 0x20, 0x6e, 0x75,
- 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72,
- 0x61, 0x6e, 0x67, 0x65, 0x20, 0x31, 0x20, 0x74, 0x6f, 0x20, 0x00, 0x00, 0x20,
- 0x41, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x65,
- 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63,
- 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4c, 0x69,
- 0x6e, 0x65, 0x20, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x50, 0x61, 0x72,
- 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x68, 0x61, 0x73, 0x0d, 0x0a, 0x20,
- 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
- 0x65, 0x64, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x20,
- 0x42, 0x75, 0x69, 0x6c, 0x64, 0x2d, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x64,
- 0x20, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x20, 0x47, 0x61, 0x69,
- 0x6e, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x0d, 0x0a, 0x20, 0x70, 0x61, 0x72,
- 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20,
- 0x62, 0x65, 0x65, 0x6e, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e,
- 0x20, 0x59, 0x6f, 0x75, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
- 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x41, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75,
- 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
- 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x20, 0x54, 0x68, 0x65, 0x20, 0x4c,
- 0x69, 0x6e, 0x65, 0x20, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x2d, 0x6f, 0x75, 0x74,
- 0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76,
- 0x65, 0x72, 0x20, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74,
- 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x68,
- 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x64, 0x69,
- 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x20, 0x54, 0x68, 0x65,
- 0x20, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20,
- 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x68, 0x61, 0x73,
- 0x20, 0x62, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c,
- 0x65, 0x64, 0x2e, 0x20, 0x59, 0x6f, 0x75, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x0d,
- 0x0a, 0x20, 0x74, 0x6f, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x20, 0x69,
- 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0d, 0x0a, 0x00, 0x00,
- 0x00, 0x64, 0xf8, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80,
- 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38,
- 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb,
- 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00,
- 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80,
- 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38,
- 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb,
- 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00,
- 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80,
- 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38,
- 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0xd0, 0xf8,
- 0x00, 0x80, 0xd0, 0xf8, 0x00, 0x80, 0xd0, 0xf8, 0x00, 0x80, 0xd0, 0xf8, 0x00,
- 0x80, 0xd0, 0xf8, 0x00, 0x80, 0xd0, 0xf8, 0x00, 0x80, 0xd0, 0xf8, 0x00, 0x80,
- 0xd0, 0xf8, 0x00, 0x80, 0xd0, 0xf8, 0x00, 0x80, 0xd0, 0xf8, 0x00, 0x80, 0x28,
- 0xfa, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb,
- 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x84, 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00,
- 0x80, 0x54, 0xf9, 0x00, 0x80, 0x6c, 0xf9, 0x00, 0x80, 0x7c, 0xf9, 0x00, 0x80,
- 0x94, 0xf9, 0x00, 0x80, 0xd8, 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38,
- 0xfb, 0x00, 0x80, 0x84, 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb,
- 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00,
- 0x80, 0xb8, 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80,
- 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0xe8, 0xf9, 0x00, 0x80, 0x38,
- 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb,
- 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00,
- 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80,
- 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x54,
- 0xf9, 0x00, 0x80, 0x6c, 0xf9, 0x00, 0x80, 0x7c, 0xf9, 0x00, 0x80, 0x94, 0xf9,
- 0x00, 0x80, 0xd8, 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00,
- 0x80, 0x84, 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80,
- 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0xb8,
- 0xf9, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0x38, 0xfb,
- 0x00, 0x80, 0x38, 0xfb, 0x00, 0x80, 0xe8, 0xf9, 0x00, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x08, 0x01, 0x80,
- 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec,
- 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09,
- 0x01, 0x80, 0xa4, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01,
- 0x80, 0xac, 0x09, 0x01, 0x80, 0xb8, 0x09, 0x01, 0x80, 0xb8, 0x09, 0x01, 0x80,
- 0xb8, 0x09, 0x01, 0x80, 0xb8, 0x09, 0x01, 0x80, 0xb8, 0x09, 0x01, 0x80, 0xb8,
- 0x09, 0x01, 0x80, 0xb8, 0x09, 0x01, 0x80, 0xb8, 0x09, 0x01, 0x80, 0xb8, 0x09,
- 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01,
- 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80,
- 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec,
- 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xbc, 0x08, 0x01, 0x80, 0xec, 0x09,
- 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01,
- 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80,
- 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec,
- 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09,
- 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01,
- 0x80, 0xec, 0x09, 0x01, 0x80, 0x50, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80,
- 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec,
- 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09,
- 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xd8, 0x08, 0x01, 0x80, 0xcc, 0x08, 0x01,
- 0x80, 0x24, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80,
- 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec,
- 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xd8, 0x09, 0x01, 0x80, 0xec, 0x09,
- 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xf8, 0x08, 0x01, 0x80, 0xec, 0x09, 0x01,
- 0x80, 0xec, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0x70, 0x09, 0x01, 0x80,
- 0x8c, 0x09, 0x01, 0x80, 0x34, 0x09, 0x01, 0x80, 0xec, 0x09, 0x01, 0x80, 0xec,
- 0x09, 0x01, 0x80, 0x40, 0x09, 0x01, 0x80, 0x10, 0x0c, 0x01, 0x80, 0x8c, 0x0b,
- 0x01, 0x80, 0xf8, 0x0b, 0x01, 0x80, 0xf8, 0x0b, 0x01, 0x80, 0x58, 0x0b, 0x01,
- 0x80, 0x7c, 0x0b, 0x01, 0x80, 0x68, 0x0b, 0x01, 0x80, 0xcc, 0x0b, 0x01, 0x80,
- 0xdc, 0x0b, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x54, 0x39, 0x77, 0x3e, 0x38, 0x3e, 0x73, 0x39, 0x73,
- 0x39, 0x79, 0x06, 0x38, 0x6d, 0x79, 0x50, 0x39, 0x6d, 0x7c, 0x79, 0x79, 0x79,
- 0x6d, 0x6d, 0x71, 0x79, 0x71, 0x71, 0x38, 0x00, 0x00, 0x3f, 0x00, 0x06, 0x00,
- 0x5b, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x6d, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f,
- 0x00, 0x67, 0x00, 0x77, 0x00, 0x7c, 0x00, 0x58, 0x00, 0x5e, 0x00, 0x79, 0x00,
- 0x71, 0x00, 0x0c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x41, 0x0b, 0x00, 0x00, 0x0b,
- 0x00, 0x0c, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0c, 0x00, 0x74, 0x00,
- 0x04, 0x00, 0x6e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xe4, 0x00, 0x04,
- 0x00, 0x40, 0x00, 0x0c, 0x00, 0xb4, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x0c, 0x00, 0xe8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x00, 0x24, 0x00, 0x18, 0x5d, 0x10, 0x6f, 0x0d, 0x00, 0x0c,
- 0x00, 0x09, 0x00, 0x06, 0x00, 0x03, 0x80, 0x01, 0x00, 0x01, 0xc0, 0x00, 0x60,
- 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x30, 0x00, 0x08, 0x00, 0x06, 0x00,
- 0x04, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x02,
- 0x00, 0x10, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00,
- 0x28, 0x43, 0x29, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20,
- 0x31, 0x39, 0x39, 0x35, 0x2c, 0x20, 0x44, 0x69, 0x67, 0x69, 0x20, 0x49, 0x6e,
- 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x00, 0x00, 0xff, 0xff, 0x00, 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, 0xb9,
- 0x00, 0x01, 0x33, 0xf6, 0x8e, 0xde, 0xc7, 0x04, 0x06, 0x01, 0x46, 0x46, 0x8c,
- 0x0c, 0x46, 0x46, 0xe2, 0xf4, 0x2e, 0x8e, 0x1e, 0xbe, 0x00, 0x2e, 0x8e, 0x06,
- 0xbe, 0x00, 0xbf, 0x52, 0x02, 0xb9, 0x2a, 0x22, 0x2b, 0xcf, 0xd1, 0xe9, 0x41,
- 0x33, 0xc0, 0xf3, 0xab, 0xc7, 0x06, 0x18, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00,
- 0x50, 0x33, 0xc0, 0x50, 0xe8, 0x4b, 0x1d, 0xfa, 0x2e, 0xa3, 0x00, 0x00, 0x2e,
- 0xfe, 0x06, 0x02, 0x00, 0xf4, 0xeb, 0xf8, 0xe9, 0x00, 0x0a, 0x55, 0x8b, 0xec,
- 0x06, 0x57, 0x32, 0xe4, 0x8a, 0x46, 0x04, 0xc1, 0xe0, 0x02, 0x8b, 0xf8, 0x33,
- 0xc0, 0x8e, 0xc0, 0x8b, 0x46, 0x06, 0x9c, 0xfa, 0xfc, 0xab, 0x8c, 0xc8, 0xab,
- 0x9d, 0x5f, 0x07, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x50, 0x53, 0x51, 0x33, 0xc9,
- 0xeb, 0x10, 0xc4, 0x5e, 0x04, 0x03, 0xd9, 0x2e, 0x8a, 0x07, 0xc4, 0x5e, 0x06,
- 0x03, 0xd9, 0x88, 0x07, 0x41, 0x3b, 0x4e, 0x08, 0x7c, 0xeb, 0x59, 0x5b, 0x58,
- 0x5d, 0xc3, 0xcf, 0xc8, 0x04, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8b,
- 0xb5, 0xc6, 0x0e, 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xe9, 0x31, 0x02, 0x33, 0xd2,
- 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0xfe, 0xe8, 0x5b, 0x4c, 0x8b, 0x1e, 0x2a, 0x80,
- 0x8b, 0x0e, 0x28, 0x80, 0x23, 0xc8, 0x23, 0xda, 0x0b, 0xcb, 0x75, 0x68, 0x8b,
- 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x20,
- 0x00, 0x74, 0x03, 0xe9, 0x89, 0x00, 0x80, 0x3e, 0x93, 0x12, 0x05, 0x75, 0x11,
- 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x0f,
- 0x80, 0x00, 0xeb, 0x0e, 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00,
- 0x03, 0xd8, 0x83, 0x0f, 0x10, 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c,
- 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x21, 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x27, 0xfd, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x46,
- 0xfe, 0x50, 0xe8, 0xd2, 0x14, 0x83, 0xc4, 0x06, 0xeb, 0x37, 0xeb, 0x35, 0x8b,
- 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x01,
- 0x00, 0x74, 0x24, 0x6a, 0x00, 0x6a, 0x20, 0x8a, 0x46, 0xfe, 0x50, 0xe8, 0xaf,
- 0x14, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00,
- 0x03, 0xd8, 0x83, 0x27, 0xde, 0x8a, 0x46, 0xfe, 0x50, 0xe8, 0xc7, 0x11, 0x59,
- 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07,
- 0x20, 0x00, 0x75, 0x03, 0xe9, 0xd5, 0x00, 0x8b, 0x5e, 0xfe, 0x80, 0xbf, 0x82,
- 0x02, 0x00, 0x74, 0x1e, 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00,
- 0x03, 0xd8, 0x83, 0x27, 0xfd, 0x8b, 0x5e, 0xfe, 0xc6, 0x87, 0x82, 0x02, 0x00,
- 0xd1, 0xe3, 0xc7, 0x87, 0x9a, 0x02, 0x00, 0x00, 0x8b, 0x46, 0xfe, 0xd1, 0xe0,
- 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x80, 0x00, 0x74, 0x45, 0x8b,
- 0x5e, 0xfe, 0xd1, 0xe3, 0xff, 0x87, 0x9a, 0x02, 0x8b, 0x5e, 0xfe, 0xd1, 0xe3,
- 0x81, 0xbf, 0x9a, 0x02, 0xf0, 0x00, 0x73, 0x0f, 0xa0, 0x91, 0x12, 0x50, 0x8a,
- 0x46, 0xfe, 0x50, 0x56, 0xe8, 0xdb, 0x0f, 0xe9, 0x01, 0x01, 0x8b, 0x5e, 0xfe,
- 0xd1, 0xe3, 0xc7, 0x87, 0x9a, 0x02, 0x00, 0x00, 0x8b, 0x46, 0xfe, 0xd1, 0xe0,
- 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x27, 0x7f, 0xff, 0xe9, 0xe7, 0x00,
- 0xe9, 0xe4, 0x00, 0x8b, 0x46, 0xfe, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03,
- 0xd8, 0xf7, 0x07, 0x10, 0x00, 0x74, 0x3e, 0x8b, 0x5e, 0xfe, 0xd1, 0xe3, 0xc7,
- 0x87, 0x9a, 0x02, 0x00, 0x00, 0x8a, 0x46, 0xfe, 0x50, 0x56, 0xe8, 0x6b, 0x0f,
- 0x83, 0xc4, 0x04, 0xb4, 0x00, 0x25, 0x03, 0x00, 0x89, 0x46, 0xfc, 0xa0, 0x8d,
- 0x12, 0xb4, 0x00, 0x3b, 0x46, 0xfc, 0x74, 0x02, 0xeb, 0x96, 0x8b, 0x46, 0xfe,
- 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x27, 0xef, 0xe9, 0x98,
- 0x00, 0xe9, 0x95, 0x00, 0xa0, 0x8e, 0x12, 0xeb, 0x80, 0xe9, 0x8d, 0x00, 0x8a,
- 0x46, 0xfe, 0x50, 0x56, 0xe8, 0x30, 0x0f, 0x83, 0xc4, 0x04, 0xb4, 0x00, 0x25,
- 0x03, 0x00, 0x89, 0x46, 0xfc, 0x8a, 0x46, 0xfe, 0x50, 0x56, 0xe8, 0x31, 0x0f,
- 0x83, 0xc4, 0x04, 0xb4, 0x00, 0x25, 0x03, 0x00, 0xc1, 0xe0, 0x02, 0x09, 0x46,
- 0xfc, 0x8a, 0x46, 0xfe, 0x50, 0xe8, 0xe2, 0x0e, 0x59, 0x0a, 0xc0, 0x74, 0x04,
- 0x83, 0x4e, 0xfc, 0x10, 0x8b, 0x5e, 0xfe, 0x8a, 0x87, 0x52, 0x02, 0xb4, 0x00,
- 0x3b, 0x46, 0xfc, 0x75, 0x08, 0xd1, 0xe3, 0xff, 0x87, 0x9a, 0x02, 0xeb, 0x12,
- 0x8b, 0x5e, 0xfe, 0x8a, 0x46, 0xfc, 0x88, 0x87, 0x52, 0x02, 0xd1, 0xe3, 0xc7,
- 0x87, 0x9a, 0x02, 0x00, 0x00, 0x8b, 0x5e, 0xfe, 0xd1, 0xe3, 0x83, 0xbf, 0x9a,
- 0x02, 0x02, 0x72, 0x20, 0x56, 0xff, 0x76, 0xfe, 0x8b, 0x5e, 0xfe, 0xd1, 0xe3,
- 0xff, 0xb7, 0x9a, 0x02, 0x8b, 0x46, 0xfc, 0x25, 0x1f, 0x00, 0xd1, 0xe0, 0x8b,
- 0x1e, 0xca, 0x02, 0x03, 0xd8, 0xff, 0x17, 0x83, 0xc4, 0x06, 0xff, 0x46, 0xfe,
- 0x83, 0x7e, 0xfe, 0x18, 0x7d, 0x03, 0xe9, 0xc6, 0xfd, 0x5f, 0x5e, 0xc9, 0xc3,
- 0x55, 0x8b, 0xec, 0x6a, 0x00, 0x6a, 0x40, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0x02,
- 0x13, 0x83, 0xc4, 0x06, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x46, 0x04, 0x50, 0xe8,
- 0xf4, 0x12, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0x04, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c,
- 0x00, 0x03, 0xd8, 0x83, 0x27, 0xbf, 0x8b, 0x46, 0x04, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x20, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x8b,
- 0x46, 0x04, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x40,
- 0x00, 0x74, 0x38, 0x6a, 0x00, 0x6a, 0x40, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0xb4,
- 0x12, 0x83, 0xc4, 0x06, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x46, 0x04, 0x50, 0xe8,
- 0xa6, 0x12, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0x04, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c,
- 0x00, 0x03, 0xd8, 0x83, 0x27, 0xbf, 0x8b, 0x46, 0x04, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x20, 0x8b, 0x46, 0x04, 0xd1, 0xe0, 0x8b,
- 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x27, 0xfd, 0x83, 0x7e, 0x06, 0x00, 0x74,
- 0x0b, 0x8b, 0x5e, 0x04, 0xd1, 0xe3, 0xc7, 0x87, 0x9a, 0x02, 0x00, 0x00, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x6a, 0x00, 0x8a, 0x46,
- 0x06, 0x50, 0xe8, 0x3c, 0x0e, 0x83, 0xc4, 0x04, 0x6a, 0x02, 0x8a, 0x46, 0x06,
- 0x50, 0xff, 0x76, 0x08, 0xe8, 0xfa, 0x0d, 0x83, 0xc4, 0x06, 0x6a, 0x01, 0xff,
- 0x76, 0x06, 0xe8, 0x68, 0xff, 0x83, 0xc4, 0x04, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x83, 0x7e, 0x04, 0x02, 0x75, 0x31, 0x6a, 0x01, 0x8a, 0x46, 0x06, 0x50, 0xe8,
- 0x0b, 0x0e, 0x83, 0xc4, 0x04, 0x6a, 0x03, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76,
- 0x08, 0xe8, 0xc9, 0x0d, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b,
- 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x8b, 0x5e, 0x06, 0xc6, 0x87,
- 0x82, 0x02, 0x01, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75,
- 0x31, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0xcf, 0x0d, 0x83, 0xc4, 0x04,
- 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0x8d, 0x0d, 0x83,
- 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0x8b, 0x46, 0x06,
- 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x22, 0x6a, 0x00, 0x8a, 0x46,
- 0x06, 0x50, 0xe8, 0x93, 0x0d, 0x83, 0xc4, 0x04, 0x8b, 0x46, 0x06, 0xd1, 0xe0,
- 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x8b, 0x5e, 0x06, 0xc6,
- 0x87, 0x6a, 0x02, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02,
- 0x75, 0x49, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x66, 0x0d, 0x83, 0xc4,
- 0x04, 0x6a, 0x02, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0x24, 0x0d,
- 0x83, 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0x8b, 0x46,
- 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x8b,
- 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x40,
- 0x00, 0x74, 0x07, 0xff, 0x76, 0x06, 0xe8, 0x30, 0xfe, 0x59, 0x5d, 0xc3, 0x55,
- 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x3a, 0x6a, 0x00, 0x8a, 0x46, 0x06,
- 0x50, 0xe8, 0x12, 0x0d, 0x83, 0xc4, 0x04, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82,
- 0x02, 0x01, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8,
- 0x83, 0x0f, 0x02, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03,
- 0xd8, 0xf7, 0x07, 0x40, 0x00, 0x74, 0x07, 0xff, 0x76, 0x06, 0xe8, 0xeb, 0xfd,
- 0x59, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x0c, 0x6a,
- 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0xcd, 0x0c, 0x83, 0xc4, 0x04, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x74, 0x03, 0xe9, 0x97, 0x00, 0x8b,
- 0x5e, 0x06, 0x80, 0xbf, 0x82, 0x02, 0x00, 0x75, 0x05, 0xb8, 0x01, 0x00, 0xeb,
- 0x02, 0x33, 0xc0, 0x50, 0x8b, 0x5e, 0x06, 0x80, 0xbf, 0x6a, 0x02, 0x01, 0x76,
- 0x05, 0xb8, 0x01, 0x00, 0xeb, 0x02, 0x33, 0xc0, 0x5a, 0x85, 0xd0, 0x74, 0x13,
- 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x06, 0xe8, 0xba, 0x47, 0x09, 0x06,
- 0xca, 0x01, 0x09, 0x16, 0xcc, 0x01, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x6a, 0x02,
- 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x70, 0x0c, 0x83, 0xc4, 0x04,
- 0x6a, 0x02, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0x2e, 0x0c, 0x83,
- 0xc4, 0x06, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8,
- 0x83, 0x27, 0xfd, 0x8b, 0x5e, 0x06, 0x80, 0xbf, 0x82, 0x02, 0x00, 0x74, 0x21,
- 0xc6, 0x87, 0x82, 0x02, 0x00, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c,
- 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x40, 0x00, 0x74, 0x0b, 0x6a, 0x01, 0xff, 0x76,
- 0x06, 0xe8, 0x6e, 0xfd, 0x83, 0xc4, 0x04, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83,
- 0x7e, 0x04, 0x02, 0x75, 0x21, 0x8b, 0x5e, 0x06, 0xfe, 0x87, 0x6a, 0x02, 0x6a,
- 0x01, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x0a, 0x0c, 0x83, 0xc4, 0x04, 0x8b, 0x46,
- 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x08, 0x83, 0x7e, 0x04, 0x02, 0x75,
- 0x40, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0xe1, 0x0b, 0x83, 0xc4, 0x04,
- 0x6a, 0x02, 0x8a, 0x46, 0x06, 0x50, 0x56, 0xe8, 0xa1, 0x0b, 0x83, 0xc4, 0x06,
- 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07,
- 0x40, 0x00, 0x74, 0x09, 0xff, 0x76, 0x06, 0xe8, 0xc3, 0xfc, 0x59, 0xeb, 0x0d,
- 0x6a, 0x03, 0x8a, 0x46, 0x06, 0x50, 0x56, 0xe8, 0x7a, 0x0b, 0x83, 0xc4, 0x06,
- 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x27, 0x8b,
- 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0xfe, 0x87, 0x6a, 0x02, 0x6a, 0x01,
- 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x89, 0x0b, 0x83, 0xc4, 0x04, 0x8b, 0x46, 0x06,
- 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x0f, 0x82, 0x00, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x08, 0x8b,
- 0x5e, 0x06, 0x8a, 0x87, 0x82, 0x02, 0xb4, 0x00, 0x0b, 0xc0, 0x74, 0x0d, 0x3d,
- 0x01, 0x00, 0x74, 0x48, 0x3d, 0x02, 0x00, 0x74, 0x03, 0xe9, 0x9e, 0x00, 0x83,
- 0xfe, 0x02, 0x74, 0x03, 0xe9, 0x96, 0x00, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x6a,
- 0x02, 0x00, 0xc6, 0x87, 0x82, 0x02, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50,
- 0xe8, 0x32, 0x0b, 0x83, 0xc4, 0x04, 0x6a, 0x02, 0x8a, 0x46, 0x06, 0x50, 0x57,
- 0xe8, 0xf2, 0x0a, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x27, 0xfd, 0xeb, 0x60, 0xeb, 0x5e, 0x83, 0xfe,
- 0x02, 0x75, 0x27, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x02, 0x0b, 0x83,
- 0xc4, 0x04, 0x6a, 0x02, 0x8a, 0x46, 0x06, 0x50, 0x57, 0xe8, 0xc2, 0x0a, 0x83,
- 0xc4, 0x06, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8,
- 0x83, 0x27, 0xfd, 0x81, 0xfe, 0x40, 0x01, 0x76, 0x2c, 0x8b, 0x5e, 0x06, 0x80,
- 0xbf, 0x6a, 0x02, 0x01, 0x76, 0x13, 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e,
- 0x06, 0xe8, 0xfa, 0x45, 0x09, 0x06, 0xca, 0x01, 0x09, 0x16, 0xcc, 0x01, 0x8b,
- 0x5e, 0x06, 0xc6, 0x87, 0x6a, 0x02, 0x00, 0xc6, 0x87, 0x82, 0x02, 0x00, 0xeb,
- 0x00, 0x5f, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75,
- 0x49, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x02, 0x6a, 0x00, 0x8a, 0x46,
- 0x06, 0x50, 0xe8, 0x94, 0x0a, 0x83, 0xc4, 0x04, 0x8b, 0x46, 0x06, 0xd1, 0xe0,
- 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x40, 0x00, 0x74, 0x07, 0xff,
- 0x76, 0x06, 0xe8, 0x83, 0xfb, 0x59, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x27, 0xfd, 0x6a, 0x02, 0x8a, 0x46, 0x06, 0x50,
- 0xff, 0x76, 0x08, 0xe8, 0x2c, 0x0a, 0x83, 0xc4, 0x06, 0x5d, 0xc3, 0x55, 0x8b,
- 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x23, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82,
- 0x02, 0x02, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x40, 0x0a, 0x83, 0xc4,
- 0x04, 0x6a, 0x03, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0xfe, 0x09,
- 0x83, 0xc4, 0x06, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75,
- 0x32, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x02, 0x6a, 0x00, 0x8a, 0x46,
- 0x06, 0x50, 0xe8, 0x12, 0x0a, 0x83, 0xc4, 0x04, 0x8b, 0x46, 0x06, 0xd1, 0xe0,
- 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x0f, 0x82, 0x00, 0x6a, 0x03, 0x8a,
- 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0xc1, 0x09, 0x83, 0xc4, 0x06, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x8b, 0x5e, 0x06, 0x80, 0xbf, 0x82, 0x02, 0x01, 0x75,
- 0x05, 0xb8, 0x01, 0x00, 0xeb, 0x02, 0x33, 0xc0, 0x50, 0x8b, 0x5e, 0x06, 0x80,
- 0xbf, 0x6a, 0x02, 0x01, 0x76, 0x05, 0xb8, 0x01, 0x00, 0xeb, 0x02, 0x33, 0xc0,
- 0x5a, 0x85, 0xd0, 0x74, 0x13, 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x06,
- 0xe8, 0xea, 0x44, 0x09, 0x06, 0xca, 0x01, 0x09, 0x16, 0xcc, 0x01, 0x8b, 0x5e,
- 0x06, 0xc6, 0x87, 0x6a, 0x02, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8,
- 0xa0, 0x09, 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76,
- 0x08, 0xe8, 0x5e, 0x09, 0x83, 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82,
- 0x02, 0x00, 0x6a, 0x01, 0x53, 0xe8, 0xc6, 0xfa, 0x83, 0xc4, 0x04, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x08, 0x8b, 0x5e,
- 0x06, 0x8a, 0x87, 0x82, 0x02, 0xb4, 0x00, 0x0b, 0xc0, 0x74, 0x07, 0x3d, 0x01,
- 0x00, 0x74, 0x26, 0xeb, 0x2b, 0x83, 0xfe, 0x02, 0x72, 0x26, 0x6a, 0x03, 0x8a,
- 0x46, 0x06, 0x50, 0x57, 0xe8, 0x1a, 0x09, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0x06,
- 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0xeb, 0x09,
- 0xeb, 0x07, 0x83, 0xfe, 0x0a, 0x72, 0x02, 0xeb, 0xda, 0x5f, 0x5e, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x34, 0x8b, 0x5e, 0x06, 0xc6,
- 0x87, 0x6a, 0x02, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x13, 0x09,
- 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8,
- 0xd1, 0x08, 0x83, 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x00,
- 0x6a, 0x00, 0x53, 0xe8, 0x39, 0xfa, 0x83, 0xc4, 0x04, 0x5d, 0xc3, 0x55, 0x8b,
- 0xec, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x82, 0x02, 0xb4,
- 0x00, 0x3d, 0x01, 0x00, 0x74, 0x0c, 0x3d, 0x02, 0x00, 0x74, 0x36, 0x3d, 0x03,
- 0x00, 0x74, 0x3c, 0xeb, 0x42, 0x83, 0xfe, 0x02, 0x75, 0x3d, 0x6a, 0x00, 0x8a,
- 0x46, 0x06, 0x50, 0xe8, 0xbf, 0x08, 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46,
- 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0x7d, 0x08, 0x83, 0xc4, 0x06, 0x6a, 0x01,
- 0xff, 0x76, 0x06, 0xe8, 0xeb, 0xf9, 0x83, 0xc4, 0x04, 0xeb, 0x15, 0xeb, 0x13,
- 0x83, 0xfe, 0x02, 0x75, 0x0e, 0x6a, 0x00, 0xeb, 0xea, 0xeb, 0x08, 0x8b, 0x5e,
- 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56,
- 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x08, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x82,
- 0x02, 0xb4, 0x00, 0x0b, 0xc0, 0x74, 0x0d, 0x3d, 0x01, 0x00, 0x74, 0x37, 0x3d,
- 0x02, 0x00, 0x74, 0x7e, 0xe9, 0xa8, 0x00, 0x83, 0xfe, 0x04, 0x73, 0x03, 0xe9,
- 0xa0, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0x57, 0xe8, 0x1e, 0x08, 0x83,
- 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0x8b, 0x46, 0x06,
- 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0xeb, 0x7b,
- 0xeb, 0x79, 0x8b, 0xc6, 0x2d, 0x02, 0x00, 0xbb, 0xf0, 0x00, 0x33, 0xd2, 0xf7,
- 0xf3, 0x83, 0xfa, 0x50, 0x77, 0x1c, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x1e, 0x00,
- 0xb4, 0x00, 0x0b, 0xc0, 0x75, 0x2c, 0xc6, 0x87, 0x1e, 0x00, 0x01, 0xfe, 0x87,
- 0x6a, 0x02, 0x6a, 0x01, 0xeb, 0x13, 0xeb, 0xc1, 0x8b, 0x5e, 0x06, 0x80, 0xbf,
- 0x1e, 0x00, 0x00, 0x74, 0x13, 0xc6, 0x87, 0x1e, 0x00, 0x00, 0x6a, 0x00, 0x8a,
- 0x46, 0x06, 0x50, 0xe8, 0xef, 0x07, 0x83, 0xc4, 0x04, 0xeb, 0xa4, 0xeb, 0xa2,
- 0x83, 0xfe, 0x02, 0x75, 0x28, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0xda,
- 0x07, 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0x57, 0xe8, 0x9a,
- 0x07, 0x83, 0xc4, 0x06, 0x6a, 0x01, 0xff, 0x76, 0x06, 0xe8, 0x08, 0xf9, 0x83,
- 0xc4, 0x04, 0xeb, 0x02, 0xeb, 0x00, 0x5f, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x82, 0x02, 0xb4, 0x00,
- 0x0b, 0xc0, 0x74, 0x07, 0x3d, 0x01, 0x00, 0x74, 0x1b, 0xeb, 0x34, 0x83, 0xfe,
- 0x02, 0x72, 0x2f, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x03, 0x8b, 0x5e,
- 0x06, 0xc6, 0x87, 0x6a, 0x02, 0x00, 0xeb, 0x1d, 0xeb, 0x1b, 0x83, 0xfe, 0x02,
- 0x72, 0x16, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x75, 0x07, 0x83, 0xc4,
- 0x04, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x02, 0xeb, 0xd9, 0x5e, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x29, 0x6a, 0x00, 0x8a,
- 0x46, 0x06, 0x50, 0xe8, 0x53, 0x07, 0x83, 0xc4, 0x04, 0x6a, 0x03, 0x8a, 0x46,
- 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0x11, 0x07, 0x83, 0xc4, 0x06, 0x8b, 0x46,
- 0x06, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x8b, 0x5e, 0x06, 0x80, 0xbf, 0x82, 0x02, 0x01, 0x75,
- 0x05, 0xb8, 0x01, 0x00, 0xeb, 0x02, 0x33, 0xc0, 0x50, 0x8b, 0x5e, 0x06, 0x80,
- 0xbf, 0x6a, 0x02, 0x01, 0x76, 0x05, 0xb8, 0x01, 0x00, 0xeb, 0x02, 0x33, 0xc0,
- 0x5a, 0x85, 0xd0, 0x74, 0x13, 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x06,
- 0xe8, 0x2c, 0x42, 0x09, 0x06, 0xca, 0x01, 0x09, 0x16, 0xcc, 0x01, 0x8b, 0x5e,
- 0x06, 0xc6, 0x87, 0x6a, 0x02, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8,
- 0xe2, 0x06, 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76,
- 0x08, 0xe8, 0xa0, 0x06, 0x83, 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82,
- 0x02, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x82,
- 0x02, 0xb4, 0x00, 0x0b, 0xc0, 0x74, 0x07, 0x3d, 0x02, 0x00, 0x74, 0x5b, 0xeb,
- 0x64, 0x8b, 0x46, 0x04, 0x2d, 0x02, 0x00, 0xbb, 0xf0, 0x00, 0x33, 0xd2, 0xf7,
- 0xf3, 0x83, 0xfa, 0x50, 0x77, 0x1c, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x1e, 0x00,
- 0xb4, 0x00, 0x0b, 0xc0, 0x75, 0x2a, 0xc6, 0x87, 0x1e, 0x00, 0x01, 0xfe, 0x87,
- 0x6a, 0x02, 0x6a, 0x01, 0xeb, 0x13, 0xeb, 0x1b, 0x8b, 0x5e, 0x06, 0x80, 0xbf,
- 0x1e, 0x00, 0x00, 0x74, 0x11, 0xc6, 0x87, 0x1e, 0x00, 0x00, 0x6a, 0x00, 0x8a,
- 0x46, 0x06, 0x50, 0xe8, 0x69, 0x06, 0x83, 0xc4, 0x04, 0x8b, 0x46, 0x06, 0xd1,
- 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0xeb, 0x0b, 0x6a,
- 0x01, 0xff, 0x76, 0x06, 0xe8, 0x94, 0xf7, 0x83, 0xc4, 0x04, 0x5d, 0xc3, 0x55,
- 0x8b, 0xec, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x2b, 0x8b, 0x5e, 0x06, 0xc6, 0x87,
- 0x6a, 0x02, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x2f, 0x06, 0x83,
- 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0xe8, 0xed,
- 0x05, 0x83, 0xc4, 0x06, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x00, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x8b, 0x5e, 0x06, 0x8a, 0x87, 0x82, 0x02, 0xb4, 0x00,
- 0x8b, 0xd8, 0x83, 0xfb, 0x03, 0x77, 0x43, 0xd1, 0xe3, 0x2e, 0xff, 0xa7, 0x96,
- 0x0c, 0x6a, 0x01, 0xff, 0x76, 0x06, 0xe8, 0x37, 0xf7, 0x83, 0xc4, 0x04, 0xeb,
- 0x2f, 0x83, 0x7e, 0x04, 0x02, 0x75, 0x29, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50,
- 0xe8, 0xdd, 0x05, 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff,
- 0x76, 0x08, 0xe8, 0x9b, 0x05, 0x83, 0xc4, 0x06, 0xeb, 0xd0, 0xeb, 0x0a, 0xeb,
- 0xcc, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0x5d, 0xc3, 0x58, 0x0c,
- 0x65, 0x0c, 0x8a, 0x0c, 0x8c, 0x0c, 0x55, 0x8b, 0xec, 0x8b, 0x5e, 0x06, 0x8a,
- 0x87, 0x82, 0x02, 0xb4, 0x00, 0x0b, 0xc0, 0x74, 0x07, 0x3d, 0x02, 0x00, 0x74,
- 0x0c, 0xeb, 0x38, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x01, 0xeb, 0x2e,
- 0x83, 0x7e, 0x04, 0x02, 0x75, 0x28, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8,
- 0x83, 0x05, 0x83, 0xc4, 0x04, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76,
- 0x08, 0xe8, 0x41, 0x05, 0x83, 0xc4, 0x06, 0x6a, 0x01, 0xff, 0x76, 0x06, 0xe8,
- 0xaf, 0xf6, 0x83, 0xc4, 0x04, 0xeb, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83,
- 0x7e, 0x04, 0x02, 0x75, 0x1c, 0x8b, 0x5e, 0x06, 0xc6, 0x87, 0x1e, 0x00, 0x00,
- 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x48, 0x05, 0x83, 0xc4, 0x04, 0x8b,
- 0x5e, 0x06, 0xc6, 0x87, 0x82, 0x02, 0x02, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83,
- 0x7e, 0x04, 0x02, 0x75, 0x29, 0x6a, 0x00, 0x8a, 0x46, 0x06, 0x50, 0xe8, 0x29,
- 0x05, 0x83, 0xc4, 0x04, 0x6a, 0x03, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08,
- 0xe8, 0xe7, 0x04, 0x83, 0xc4, 0x06, 0x8b, 0x46, 0x06, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x02, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0xc7,
- 0x06, 0x50, 0xe0, 0x00, 0x00, 0xc7, 0x06, 0x52, 0xe0, 0x19, 0x00, 0xc7, 0x06,
- 0x54, 0xe0, 0x19, 0x00, 0xc7, 0x06, 0x56, 0xe0, 0x0b, 0xe0, 0xc7, 0x06, 0x58,
- 0xe0, 0x00, 0x00, 0xc7, 0x06, 0x5a, 0xe0, 0xe8, 0x03, 0xc7, 0x06, 0x5c, 0xe0,
- 0xe8, 0x03, 0xc7, 0x06, 0x5e, 0xe0, 0x0b, 0xe0, 0xc7, 0x06, 0x60, 0xe0, 0x00,
- 0x00, 0xc7, 0x06, 0x62, 0xe0, 0xa0, 0x0f, 0xc7, 0x06, 0x66, 0xe0, 0x01, 0xe0,
- 0x81, 0x26, 0x28, 0xe0, 0x0e, 0xff, 0x68, 0xc3, 0x0d, 0x6a, 0x08, 0xe8, 0x23,
- 0xf3, 0x83, 0xc4, 0x04, 0x68, 0x14, 0x0e, 0x6a, 0x12, 0xe8, 0x18, 0xf3, 0x83,
- 0xc4, 0x04, 0x68, 0x39, 0x0e, 0x6a, 0x13, 0xe8, 0x0d, 0xf3, 0x83, 0xc4, 0x04,
- 0x68, 0x5b, 0x0e, 0x6a, 0x0f, 0xe8, 0x02, 0xf3, 0x83, 0xc4, 0x04, 0x5d, 0xc3,
- 0x50, 0x53, 0x51, 0x52, 0x06, 0x1e, 0x56, 0x57, 0x55, 0x2e, 0x8b, 0x2e, 0xbe,
- 0x00, 0x8e, 0xdd, 0x8b, 0xec, 0xbe, 0x9c, 0x03, 0xe8, 0x05, 0x2e, 0xe8, 0xb8,
- 0x07, 0xf7, 0x06, 0x98, 0x12, 0x04, 0x00, 0x74, 0x1e, 0x8b, 0x44, 0x1e, 0x0b,
- 0x44, 0x20, 0x75, 0x13, 0x83, 0xbc, 0xc4, 0x0e, 0x00, 0x75, 0x0c, 0x80, 0x3e,
- 0x93, 0x12, 0x06, 0x77, 0x05, 0x56, 0xe8, 0x07, 0xf3, 0x59, 0xe8, 0x88, 0x00,
- 0xc7, 0x06, 0x22, 0xe0, 0x00, 0x80, 0x5d, 0x5f, 0x5e, 0x1f, 0x07, 0x5a, 0x59,
- 0x5b, 0x58, 0xcf, 0x50, 0x53, 0x51, 0x52, 0x06, 0x1e, 0x56, 0x57, 0x55, 0x2e,
- 0x8b, 0x2e, 0xbe, 0x00, 0x8e, 0xdd, 0x8b, 0xec, 0xe8, 0xd3, 0x2d, 0xc7, 0x06,
- 0x22, 0xe0, 0x00, 0x80, 0x5d, 0x5f, 0x5e, 0x1f, 0x07, 0x5a, 0x59, 0x5b, 0x58,
- 0xcf, 0x50, 0x53, 0x51, 0x52, 0x06, 0x1e, 0x56, 0x57, 0x55, 0x2e, 0x8b, 0x2e,
- 0xbe, 0x00, 0x8e, 0xdd, 0x8b, 0xec, 0xc7, 0x06, 0x22, 0xe0, 0x00, 0x80, 0x5d,
- 0x5f, 0x5e, 0x1f, 0x07, 0x5a, 0x59, 0x5b, 0x58, 0xcf, 0x50, 0x53, 0x51, 0x52,
- 0x06, 0x1e, 0x56, 0x57, 0x55, 0x2e, 0x8b, 0x2e, 0xbe, 0x00, 0x8e, 0xdd, 0x8b,
- 0xec, 0xb8, 0x40, 0x00, 0x8e, 0xc0, 0x26, 0xc7, 0x06, 0x2c, 0x00, 0x0f, 0x00,
- 0xa0, 0xfc, 0x87, 0xc7, 0x06, 0x22, 0xe0, 0x00, 0x80, 0x5d, 0x5f, 0x5e, 0x1f,
- 0x07, 0x5a, 0x59, 0x5b, 0x58, 0xcf, 0x55, 0x8b, 0xec, 0xa1, 0x96, 0x12, 0x8b,
- 0x16, 0x94, 0x12, 0x31, 0x16, 0x82, 0x01, 0x8b, 0x16, 0x82, 0x01, 0x31, 0x06,
- 0x84, 0x01, 0xa1, 0x84, 0x01, 0xa3, 0x80, 0x61, 0x89, 0x16, 0x7e, 0x61, 0x5d,
- 0xc3, 0xc8, 0x02, 0x00, 0x00, 0xa0, 0x20, 0x80, 0x88, 0x46, 0xff, 0xa0, 0x22,
- 0x80, 0x88, 0x46, 0xfe, 0x6a, 0x04, 0x50, 0x8a, 0x46, 0xff, 0x50, 0x68, 0xcc,
- 0x02, 0x68, 0x00, 0x81, 0xe8, 0xce, 0x00, 0x83, 0xc4, 0x0a, 0x8a, 0x46, 0xff,
- 0x04, 0x04, 0x22, 0x46, 0xfe, 0xa2, 0x20, 0x80, 0xe8, 0x4f, 0x02, 0xc9, 0xc3,
- 0xc8, 0x04, 0x00, 0x00, 0x56, 0x8b, 0x76, 0x04, 0xa0, 0x26, 0x80, 0x88, 0x46,
- 0xff, 0xa0, 0x27, 0x80, 0x88, 0x46, 0xfe, 0x80, 0x3c, 0x80, 0x73, 0x06, 0xc6,
- 0x46, 0xfd, 0x04, 0xeb, 0x04, 0xc6, 0x46, 0xfd, 0x08, 0xa0, 0x25, 0x80, 0x3a,
- 0x46, 0xff, 0x75, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x26, 0x8a, 0x46, 0xfd, 0xb4,
- 0x00, 0x50, 0x8a, 0x46, 0xfe, 0x50, 0x8a, 0x46, 0xff, 0x50, 0x68, 0x00, 0x82,
- 0x56, 0xe8, 0x14, 0x00, 0x83, 0xc4, 0x0a, 0x8a, 0x46, 0xff, 0x02, 0x46, 0xfd,
- 0x22, 0x46, 0xfe, 0xa2, 0x26, 0x80, 0x33, 0xc0, 0x5e, 0xc9, 0xc3, 0xc8, 0x04,
- 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8b, 0x76, 0x06, 0x89, 0x76, 0xfc,
- 0x8a, 0x46, 0x0a, 0xb4, 0x00, 0x40, 0x8a, 0x56, 0x08, 0xb6, 0x00, 0x2b, 0xc2,
- 0x89, 0x46, 0xfe, 0x8a, 0x46, 0x08, 0xb4, 0x00, 0x8b, 0xd6, 0x03, 0xd0, 0x8b,
- 0xf2, 0x8b, 0x46, 0x0c, 0x3b, 0x46, 0xfe, 0x72, 0x1c, 0x8b, 0x4e, 0xfe, 0xeb,
- 0x07, 0x8a, 0x05, 0x88, 0x04, 0x47, 0x46, 0x49, 0x0b, 0xc9, 0x77, 0xf5, 0x8b,
- 0x46, 0x0c, 0x2b, 0x46, 0xfe, 0x89, 0x46, 0x0c, 0x8b, 0x76, 0xfc, 0x8b, 0x4e,
- 0x0c, 0xeb, 0x07, 0x8a, 0x05, 0x88, 0x04, 0x47, 0x46, 0x49, 0x0b, 0xc9, 0x77,
- 0xf5, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x04, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76,
- 0x04, 0x8b, 0x7e, 0x06, 0x89, 0x76, 0xfc, 0x8a, 0x46, 0x0a, 0xb4, 0x00, 0x40,
- 0x8a, 0x56, 0x08, 0xb6, 0x00, 0x2b, 0xc2, 0x89, 0x46, 0xfe, 0x8a, 0x46, 0x08,
- 0xb4, 0x00, 0x8b, 0xd6, 0x03, 0xd0, 0x8b, 0xf2, 0x8b, 0x46, 0x0c, 0x3b, 0x46,
- 0xfe, 0x72, 0x1c, 0x8b, 0x4e, 0xfe, 0xeb, 0x07, 0x8a, 0x04, 0x88, 0x05, 0x46,
- 0x47, 0x49, 0x0b, 0xc9, 0x77, 0xf5, 0x8b, 0x46, 0x0c, 0x2b, 0x46, 0xfe, 0x89,
- 0x46, 0x0c, 0x8b, 0x76, 0xfc, 0x8b, 0x4e, 0x0c, 0xeb, 0x07, 0x8a, 0x04, 0x88,
- 0x05, 0x46, 0x47, 0x49, 0x0b, 0xc9, 0x77, 0xf5, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8,
- 0x04, 0x00, 0x00, 0xc6, 0x46, 0xfc, 0x70, 0x8b, 0x46, 0x06, 0xc1, 0xe8, 0x08,
- 0x88, 0x46, 0xfd, 0x8a, 0x46, 0x06, 0x88, 0x46, 0xfe, 0xc6, 0x46, 0xff, 0x00,
- 0x6a, 0x04, 0xa0, 0x27, 0x80, 0x50, 0x8a, 0x46, 0x04, 0x50, 0x68, 0x00, 0x82,
- 0x8d, 0x46, 0xfc, 0x50, 0xe8, 0x0d, 0xff, 0x83, 0xc4, 0x0a, 0xc9, 0xc3, 0xc8,
- 0x08, 0x00, 0x00, 0x56, 0x57, 0xa0, 0x26, 0x80, 0x88, 0x46, 0xff, 0xa0, 0x25,
- 0x80, 0x88, 0x46, 0xfe, 0xa0, 0x27, 0x80, 0x88, 0x46, 0xfd, 0xc7, 0x46, 0xf8,
- 0xa2, 0x12, 0x8b, 0x3e, 0xd4, 0x02, 0x83, 0x3e, 0xd4, 0x02, 0x00, 0x75, 0x23,
- 0xc7, 0x06, 0xd4, 0x02, 0x88, 0x0f, 0x8b, 0x3e, 0xd4, 0x02, 0xff, 0x36, 0xd4,
- 0x02, 0x8a, 0x46, 0xff, 0x50, 0xe8, 0x8f, 0xff, 0x83, 0xc4, 0x04, 0x8a, 0x46,
- 0xff, 0x04, 0x04, 0x22, 0x46, 0xfd, 0x88, 0x46, 0xff, 0x8a, 0x46, 0xfe, 0xb4,
- 0x00, 0x8a, 0x56, 0xff, 0xb6, 0x00, 0x2b, 0xc2, 0x48, 0x8a, 0x56, 0xfd, 0xb6,
- 0x00, 0x23, 0xc2, 0x8b, 0xf0, 0x39, 0x36, 0xd4, 0x02, 0x76, 0x0d, 0xa1, 0xd4,
- 0x02, 0x2b, 0xc6, 0xa3, 0xd4, 0x02, 0x89, 0x76, 0xfa, 0xeb, 0x0c, 0xa1, 0xd4,
- 0x02, 0x89, 0x46, 0xfa, 0x2b, 0x46, 0xfa, 0xa3, 0xd4, 0x02, 0xff, 0x76, 0xfa,
- 0x8a, 0x46, 0xfd, 0x50, 0x8a, 0x46, 0xff, 0x50, 0x68, 0x00, 0x82, 0xb8, 0x88,
- 0x0f, 0x2b, 0xc7, 0x8b, 0x56, 0xf8, 0x03, 0xd0, 0x52, 0xe8, 0x6c, 0xfe, 0x83,
- 0xc4, 0x0a, 0x8a, 0x46, 0xff, 0x02, 0x46, 0xfa, 0x22, 0x46, 0xfd, 0xa2, 0x26,
- 0x80, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0xa0, 0x26, 0x80, 0x88,
- 0x46, 0xff, 0xa0, 0x27, 0x80, 0x88, 0x46, 0xfe, 0xff, 0x76, 0x04, 0x8a, 0x46,
- 0xff, 0x50, 0xe8, 0x03, 0xff, 0x83, 0xc4, 0x04, 0x8a, 0x46, 0xff, 0x04, 0x04,
- 0x22, 0x46, 0xfe, 0x88, 0x46, 0xff, 0xff, 0x76, 0x04, 0x8a, 0x46, 0xfe, 0x50,
- 0x8a, 0x46, 0xff, 0x50, 0x68, 0x00, 0x82, 0xff, 0x76, 0x06, 0xe8, 0x1d, 0xfe,
- 0x83, 0xc4, 0x0a, 0x8a, 0x46, 0xff, 0x02, 0x46, 0x04, 0x22, 0x46, 0xfe, 0xa2,
- 0x26, 0x80, 0xc9, 0xc3, 0xc8, 0x06, 0x04, 0x00, 0x56, 0x57, 0xa0, 0x20, 0x80,
- 0x88, 0x46, 0xfb, 0xa0, 0x22, 0x80, 0x88, 0x46, 0xfa, 0xa0, 0xcd, 0x02, 0xb4,
- 0x00, 0xc1, 0xe0, 0x08, 0x8a, 0x16, 0xce, 0x02, 0xb6, 0x00, 0x03, 0xc2, 0x89,
- 0x46, 0xfe, 0x8d, 0x86, 0xfa, 0xfb, 0x89, 0x46, 0xfc, 0xff, 0x76, 0xfe, 0x8a,
- 0x46, 0xfa, 0x50, 0x8a, 0x46, 0xfb, 0x50, 0xff, 0x76, 0xfc, 0x68, 0x00, 0x81,
- 0xe8, 0x2e, 0xfe, 0x83, 0xc4, 0x0a, 0x8a, 0x46, 0xfb, 0x02, 0x46, 0xfe, 0x22,
- 0x46, 0xfa, 0xa2, 0x20, 0x80, 0x8d, 0x86, 0xfa, 0xfb, 0x8b, 0xf0, 0x8b, 0xfe,
- 0x83, 0x7d, 0x02, 0x00, 0x75, 0x16, 0x81, 0x3d, 0x09, 0x10, 0x75, 0x10, 0xc7,
- 0x46, 0xfe, 0x88, 0x0f, 0x8b, 0x46, 0xfe, 0xc7, 0x45, 0x0e, 0x00, 0x00, 0x89,
- 0x45, 0x0c, 0x56, 0xff, 0x76, 0xfe, 0xe8, 0xb7, 0x0e, 0x83, 0xc4, 0x04, 0x5f,
- 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0xb2, 0x00, 0xeb, 0x12, 0x8a, 0xc2, 0xb4,
- 0x00, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x27, 0xf0, 0x00,
- 0xfe, 0xc2, 0x80, 0xfa, 0x18, 0x72, 0xe9, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x33,
- 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x04, 0xe8, 0xa5, 0x3b, 0x8b, 0x1e, 0x12,
- 0x80, 0x8b, 0x0e, 0x10, 0x80, 0x23, 0xc8, 0x23, 0xda, 0x0b, 0xcb, 0x74, 0x04,
- 0xb0, 0x20, 0xeb, 0x02, 0xb0, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x8a, 0x46,
- 0x06, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x5e, 0x04, 0x03, 0xd8, 0x8a, 0x47, 0x40,
- 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x8a, 0x46, 0x06, 0xb4, 0x00, 0xd1, 0xe0, 0x8b,
- 0x5e, 0x04, 0x03, 0xd8, 0x8a, 0x87, 0xc0, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x8b, 0x4e, 0x04, 0x8a, 0x46, 0x06, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0xd9, 0x03,
- 0xd8, 0x8b, 0x87, 0xc0, 0x00, 0x25, 0xf0, 0x00, 0x8a, 0x56, 0x08, 0xb6, 0x00,
- 0x83, 0xe2, 0x0f, 0x0b, 0xc2, 0x8a, 0x56, 0x06, 0xb6, 0x00, 0xd1, 0xe2, 0x8b,
- 0xd9, 0x03, 0xda, 0x89, 0x87, 0xc0, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x80,
- 0x7e, 0x06, 0x00, 0x74, 0x15, 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x04,
- 0xe8, 0x1d, 0x3b, 0x09, 0x06, 0x94, 0x12, 0x09, 0x16, 0x96, 0x12, 0xeb, 0x17,
- 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x04, 0xe8, 0x08, 0x3b, 0xf7, 0xd0,
- 0xf7, 0xd2, 0x21, 0x06, 0x94, 0x12, 0x21, 0x16, 0x96, 0x12, 0xa1, 0x96, 0x12,
- 0x8b, 0x16, 0x94, 0x12, 0xa3, 0x06, 0x80, 0x89, 0x16, 0x04, 0x80, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x33, 0xd2, 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0x04, 0xe8, 0xde,
- 0x3a, 0x8b, 0x1e, 0x2a, 0x80, 0x8b, 0x0e, 0x28, 0x80, 0x23, 0xc8, 0x23, 0xda,
- 0x0b, 0xcb, 0x74, 0x05, 0xb8, 0x01, 0x00, 0xeb, 0x02, 0x33, 0xc0, 0x5d, 0xc3,
- 0xc8, 0x04, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x0a, 0x80,
- 0x7e, 0x06, 0x04, 0x76, 0x06, 0xb8, 0xff, 0xff, 0xe9, 0xc1, 0x00, 0x8a, 0x04,
- 0x32, 0x46, 0x08, 0x88, 0x46, 0xfc, 0x8a, 0x46, 0x08, 0x88, 0x04, 0x8a, 0x46,
- 0x06, 0xc0, 0xe0, 0x03, 0x88, 0x46, 0xfe, 0x04, 0x08, 0x88, 0x46, 0xfd, 0x8a,
- 0x46, 0xfe, 0x88, 0x46, 0xff, 0xe9, 0x90, 0x00, 0xf6, 0x46, 0xfc, 0x01, 0x74,
- 0x73, 0xf6, 0x46, 0x08, 0x01, 0x74, 0x11, 0x8a, 0x46, 0xff, 0xb4, 0x00, 0xd1,
- 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x09, 0x3f, 0xeb, 0x13, 0x8a, 0x46,
- 0xff, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x8b, 0xc7,
- 0xf7, 0xd0, 0x21, 0x07, 0x80, 0x7e, 0x0c, 0x00, 0x74, 0x43, 0x8a, 0x46, 0xff,
- 0x50, 0xe8, 0x64, 0x00, 0x59, 0x8a, 0x46, 0xff, 0x50, 0xe8, 0x58, 0xff, 0x59,
- 0x0b, 0xc0, 0x75, 0x2f, 0x8a, 0x46, 0xff, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x27, 0xf0, 0x00, 0x8a, 0x46, 0xff, 0xb4, 0x00,
- 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x20, 0x6a, 0x01,
- 0x6a, 0x20, 0x8a, 0x46, 0xff, 0x50, 0xe8, 0xfb, 0x02, 0x83, 0xc4, 0x06, 0x8a,
- 0x46, 0xfc, 0xb4, 0x00, 0xd1, 0xf8, 0x88, 0x46, 0xfc, 0x8a, 0x46, 0x08, 0xb4,
- 0x00, 0xd1, 0xf8, 0x88, 0x46, 0x08, 0xfe, 0x46, 0xff, 0x8a, 0x46, 0xff, 0x3a,
- 0x46, 0xfd, 0x73, 0x03, 0xe9, 0x65, 0xff, 0x33, 0xc0, 0x5f, 0x5e, 0xc9, 0xc3,
- 0xc8, 0x02, 0x00, 0x00, 0x56, 0x8b, 0x36, 0x62, 0x12, 0xa1, 0x98, 0x12, 0x89,
- 0x46, 0xfe, 0x83, 0x26, 0x98, 0x12, 0xfb, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1,
- 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x20, 0x00, 0x75, 0x03,
- 0xe9, 0x89, 0x00, 0x6a, 0x00, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0x84, 0xfe, 0x83,
- 0xc4, 0x04, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0xd8, 0xc7, 0x87,
- 0x9a, 0x02, 0x00, 0x00, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x02, 0x00, 0x74, 0x53, 0xa0, 0x93, 0x12,
- 0xb4, 0x00, 0x48, 0x8b, 0xd8, 0x83, 0xfb, 0x05, 0x77, 0x34, 0xd1, 0xe3, 0x2e,
- 0xff, 0xa7, 0x8a, 0x15, 0xeb, 0x2b, 0xeb, 0x19, 0xeb, 0x17, 0xeb, 0x25, 0xeb,
- 0x13, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03,
- 0xd8, 0x81, 0x0f, 0x80, 0x00, 0xeb, 0x10, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1,
- 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x10, 0xa0, 0x91, 0x12,
- 0x50, 0x8a, 0x46, 0x04, 0x50, 0x56, 0xe8, 0xdf, 0xfd, 0x83, 0xc4, 0x06, 0xe9,
- 0x30, 0x01, 0xa0, 0x8e, 0x12, 0xeb, 0xec, 0xe9, 0x28, 0x01, 0x8a, 0x46, 0x04,
- 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x40,
- 0x00, 0x75, 0x03, 0xe9, 0xb4, 0x00, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0,
- 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x02, 0x00, 0x75, 0x57, 0x6a,
- 0x00, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0xd2, 0xfd, 0x83, 0xc4, 0x04, 0xa0, 0x8e,
- 0x12, 0x50, 0x8a, 0x46, 0x04, 0x50, 0x56, 0xe8, 0x90, 0xfd, 0x83, 0xc4, 0x06,
- 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0xd8, 0xc7, 0x87, 0x9a, 0x02,
- 0x00, 0x00, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00,
- 0x03, 0xd8, 0xc7, 0x07, 0x20, 0x00, 0x6a, 0x00, 0x6a, 0x40, 0x8a, 0x46, 0x04,
- 0x50, 0xe8, 0xae, 0x01, 0x83, 0xc4, 0x06, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x46,
- 0x04, 0x50, 0xe8, 0xa0, 0x01, 0xe9, 0x72, 0xff, 0xa0, 0x93, 0x12, 0xb4, 0x00,
- 0x48, 0x8b, 0xd8, 0x83, 0xfb, 0x05, 0x76, 0x03, 0xe9, 0x98, 0x00, 0xd1, 0xe3,
- 0x2e, 0xff, 0xa7, 0x7e, 0x15, 0xe9, 0x8e, 0x00, 0xeb, 0x1a, 0xeb, 0x18, 0xe9,
- 0x87, 0x00, 0xeb, 0x13, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x81, 0x0f, 0x80, 0x00, 0xeb, 0x72, 0x8a, 0x46, 0x04,
- 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x0f, 0x10,
- 0xeb, 0x60, 0xeb, 0x5e, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0x1e,
- 0x1c, 0x00, 0x03, 0xd8, 0x83, 0x27, 0x9f, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1,
- 0xe0, 0x8b, 0x1e, 0x1c, 0x00, 0x03, 0xd8, 0xf7, 0x07, 0x02, 0x00, 0x75, 0x3b,
- 0x6a, 0x00, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0x0e, 0xfd, 0x83, 0xc4, 0x04, 0x8a,
- 0x46, 0x04, 0x50, 0xe8, 0x82, 0xfc, 0x59, 0x0a, 0xc0, 0x74, 0x05, 0xa0, 0x91,
- 0x12, 0xeb, 0x03, 0xa0, 0x8e, 0x12, 0x50, 0x8a, 0x46, 0x04, 0x50, 0x56, 0xe8,
- 0xbb, 0xfc, 0x83, 0xc4, 0x06, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xd1, 0xe0, 0x8b,
- 0xd8, 0xc7, 0x87, 0x9a, 0x02, 0x00, 0x00, 0x8b, 0x46, 0xfe, 0xa3, 0x98, 0x12,
- 0x5e, 0xc9, 0xc3, 0xe7, 0x14, 0xe9, 0x14, 0x75, 0x15, 0xee, 0x14, 0xf0, 0x14,
- 0x03, 0x15, 0x08, 0x14, 0x0a, 0x14, 0x33, 0x14, 0x0e, 0x14, 0x10, 0x14, 0x23,
- 0x14, 0xc8, 0x0c, 0x00, 0x00, 0x56, 0x57, 0xa1, 0x2a, 0x80, 0x8b, 0x16, 0x28,
- 0x80, 0x89, 0x46, 0xf8, 0x89, 0x56, 0xf6, 0xa1, 0x88, 0x01, 0x8b, 0x16, 0x86,
- 0x01, 0x33, 0x56, 0xf6, 0x33, 0x46, 0xf8, 0x89, 0x46, 0xfc, 0x89, 0x56, 0xfa,
- 0x0b, 0xd0, 0x75, 0x03, 0xe9, 0x96, 0x00, 0x8b, 0x36, 0x62, 0x12, 0xbf, 0x64,
- 0x12, 0x8d, 0x46, 0xf6, 0x89, 0x46, 0xfe, 0xc7, 0x46, 0xf4, 0x00, 0x00, 0xeb,
- 0x3f, 0x8b, 0x5e, 0xfe, 0x03, 0x5e, 0xf4, 0x8a, 0x07, 0xbb, 0x13, 0x00, 0x2b,
- 0x5e, 0xf4, 0x88, 0x01, 0xb4, 0x00, 0xbb, 0x13, 0x00, 0x2b, 0x5e, 0xf4, 0xd1,
- 0xe3, 0x89, 0x80, 0x80, 0x00, 0x8b, 0x5e, 0xfe, 0x03, 0x5e, 0xf4, 0x8a, 0x07,
- 0xbb, 0x17, 0x00, 0x2b, 0x5e, 0xf4, 0x88, 0x01, 0xb4, 0x00, 0xbb, 0x17, 0x00,
- 0x2b, 0x5e, 0xf4, 0xd1, 0xe3, 0x89, 0x80, 0x80, 0x00, 0xff, 0x46, 0xf4, 0x83,
- 0x7e, 0xf4, 0x04, 0x7c, 0xbb, 0x8b, 0x46, 0xf8, 0x8b, 0x56, 0xf6, 0x21, 0x56,
- 0xfa, 0x21, 0x46, 0xfc, 0xc7, 0x46, 0xf4, 0x00, 0x00, 0xeb, 0x24, 0x33, 0xd2,
- 0xb8, 0x01, 0x00, 0x8a, 0x4e, 0xf4, 0xe8, 0x48, 0x37, 0x8b, 0x5e, 0xfc, 0x8b,
- 0x4e, 0xfa, 0x23, 0xc8, 0x23, 0xda, 0x0b, 0xcb, 0x74, 0x08, 0x8a, 0x46, 0xf4,
- 0x50, 0xe8, 0x4b, 0xfd, 0x59, 0xff, 0x46, 0xf4, 0x83, 0x7e, 0xf4, 0x18, 0x7c,
- 0xd6, 0x8b, 0x46, 0xf8, 0x8b, 0x56, 0xf6, 0xa3, 0x88, 0x01, 0x89, 0x16, 0x86,
- 0x01, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x56, 0x80, 0x7e, 0x04,
- 0x1e, 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x5c, 0x8a, 0x4e, 0x04, 0x80, 0xe1,
- 0x07, 0xb0, 0x01, 0xd2, 0xe0, 0x88, 0x46, 0xfe, 0x8a, 0x46, 0x04, 0x24, 0xf8,
- 0x88, 0x46, 0xff, 0xb4, 0x00, 0xc1, 0xf8, 0x03, 0x88, 0x46, 0xff, 0x8a, 0x46,
- 0x06, 0xb4, 0x00, 0x3d, 0x20, 0x00, 0x74, 0x07, 0x3d, 0x40, 0x00, 0x74, 0x07,
- 0xeb, 0x0a, 0xbe, 0x1c, 0x80, 0xeb, 0x0a, 0xbe, 0x2c, 0x80, 0xeb, 0x05, 0xb8,
- 0xfe, 0xff, 0xeb, 0x1f, 0x8a, 0x46, 0xff, 0xb4, 0x00, 0x03, 0xf0, 0x8a, 0x14,
- 0x80, 0x7e, 0x08, 0x00, 0x74, 0x05, 0x0a, 0x56, 0xfe, 0xeb, 0x07, 0x8a, 0x46,
- 0xfe, 0xf6, 0xd0, 0x22, 0xd0, 0x88, 0x14, 0x33, 0xc0, 0x5e, 0xc9, 0xc3, 0xc8,
- 0x04, 0x00, 0x00, 0x56, 0xbe, 0x9c, 0x03, 0xa1, 0x62, 0x12, 0x89, 0x46, 0xfe,
- 0x83, 0x26, 0x98, 0x12, 0xfb, 0x81, 0x64, 0x02, 0xff, 0x7f, 0x83, 0x64, 0x04,
- 0xf8, 0xc7, 0x06, 0x96, 0x12, 0x00, 0x00, 0xc7, 0x06, 0x94, 0x12, 0x00, 0x00,
- 0x8a, 0x46, 0x04, 0xb4, 0x00, 0x48, 0x8b, 0xd8, 0x83, 0xfb, 0x05, 0x76, 0x03,
- 0xe9, 0x29, 0x01, 0xd1, 0xe3, 0x2e, 0xff, 0xa7, 0x96, 0x18, 0xc7, 0x06, 0xca,
- 0x02, 0x82, 0x00, 0xc6, 0x06, 0x93, 0x12, 0x01, 0xc6, 0x06, 0x92, 0x12, 0x22,
- 0x81, 0x4c, 0x02, 0x00, 0x80, 0x83, 0x4c, 0x04, 0x00, 0xc6, 0x06, 0x8d, 0x12,
- 0x03, 0xc6, 0x06, 0x8c, 0x12, 0x02, 0xc6, 0x06, 0x8b, 0x12, 0x00, 0xc6, 0x06,
- 0x8a, 0x12, 0x00, 0xc6, 0x06, 0x91, 0x12, 0x02, 0xc6, 0x06, 0x90, 0x12, 0x01,
- 0xc6, 0x06, 0x8f, 0x12, 0x00, 0xc6, 0x06, 0x8e, 0x12, 0x03, 0xe9, 0xe6, 0x00,
- 0xc7, 0x06, 0xca, 0x02, 0x82, 0x00, 0xc6, 0x06, 0x93, 0x12, 0x04, 0xc6, 0x06,
- 0x92, 0x12, 0x23, 0x83, 0x4c, 0x02, 0x00, 0x83, 0x4c, 0x04, 0x02, 0xc6, 0x06,
- 0x8d, 0x12, 0x02, 0xc6, 0x06, 0x8c, 0x12, 0x03, 0xc6, 0x06, 0x8b, 0x12, 0x00,
- 0xc6, 0x06, 0x8a, 0x12, 0x00, 0xc6, 0x06, 0x91, 0x12, 0x03, 0xc6, 0x06, 0x90,
- 0x12, 0x00, 0xc6, 0x06, 0x8f, 0x12, 0x00, 0xc6, 0x06, 0x8e, 0x12, 0x02, 0xe9,
- 0xa3, 0x00, 0xc7, 0x06, 0xca, 0x02, 0xc2, 0x00, 0xc6, 0x06, 0x93, 0x12, 0x05,
- 0xc6, 0x06, 0x92, 0x12, 0x22, 0x81, 0x4c, 0x02, 0x00, 0x80, 0x83, 0x4c, 0x04,
- 0x02, 0xc6, 0x06, 0x8d, 0x12, 0x02, 0xc6, 0x06, 0x8c, 0x12, 0x02, 0xc6, 0x06,
- 0x8b, 0x12, 0x00, 0xc6, 0x06, 0x8a, 0x12, 0x02, 0xc6, 0x06, 0x91, 0x12, 0x02,
- 0xc6, 0x06, 0x90, 0x12, 0x02, 0xc6, 0x06, 0x8f, 0x12, 0x02, 0xe9, 0x76, 0xff,
- 0xc7, 0x06, 0xca, 0x02, 0x02, 0x01, 0xc6, 0x06, 0x93, 0x12, 0x02, 0xc6, 0x06,
- 0x92, 0x12, 0x20, 0x83, 0x4c, 0x02, 0x00, 0x83, 0x4c, 0x04, 0x01, 0xeb, 0x18,
- 0xc7, 0x06, 0xca, 0x02, 0x42, 0x01, 0xc6, 0x06, 0x93, 0x12, 0x06, 0xc6, 0x06,
- 0x92, 0x12, 0x20, 0x83, 0x4c, 0x02, 0x00, 0x83, 0x4c, 0x04, 0x03, 0xc6, 0x06,
- 0x8d, 0x12, 0x00, 0xc6, 0x06, 0x8c, 0x12, 0x03, 0xc6, 0x06, 0x8b, 0x12, 0x03,
- 0xc6, 0x06, 0x8a, 0x12, 0x00, 0xc6, 0x06, 0x91, 0x12, 0x00, 0xc6, 0x06, 0x8e,
- 0x12, 0x03, 0xc6, 0x06, 0x8f, 0x12, 0x03, 0xc6, 0x06, 0x90, 0x12, 0x00, 0xeb,
- 0x08, 0xc7, 0x06, 0xca, 0x02, 0x3e, 0x00, 0xeb, 0x51, 0x80, 0x7e, 0x06, 0x00,
- 0x74, 0x23, 0xc7, 0x46, 0xfc, 0x00, 0x00, 0xeb, 0x16, 0xa0, 0x92, 0x12, 0xb4,
- 0x00, 0x8b, 0x56, 0xfc, 0xd1, 0xe2, 0x8b, 0x5e, 0xfe, 0x03, 0xda, 0x89, 0x87,
- 0xc0, 0x00, 0xff, 0x46, 0xfc, 0x83, 0x7e, 0xfc, 0x20, 0x7c, 0xe4, 0xe8, 0x41,
- 0xf9, 0x81, 0x3e, 0xca, 0x02, 0x3e, 0x00, 0x74, 0x18, 0xc7, 0x46, 0xfc, 0x00,
- 0x00, 0xeb, 0x0b, 0x8a, 0x46, 0xfc, 0x50, 0xe8, 0x16, 0xfb, 0x59, 0xff, 0x46,
- 0xfc, 0x83, 0x7e, 0xfc, 0x18, 0x7c, 0xef, 0x83, 0x0e, 0x98, 0x12, 0x04, 0x5e,
- 0xc9, 0xc3, 0x18, 0x17, 0xde, 0x17, 0x3a, 0x18, 0x5c, 0x17, 0x9f, 0x17, 0xf8,
- 0x17, 0x55, 0x8b, 0xec, 0x83, 0x3e, 0x18, 0x00, 0x00, 0x75, 0x10, 0xf6, 0x06,
- 0x00, 0x62, 0x01, 0x74, 0x09, 0x90, 0x90, 0x90, 0x90, 0xa0, 0x02, 0x62, 0xeb,
- 0x02, 0xb0, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x83, 0x3e, 0x18, 0x00, 0x00,
- 0x75, 0x1a, 0xeb, 0x08, 0x90, 0x90, 0x90, 0x90, 0xfe, 0x06, 0x0f, 0x80, 0xa0,
- 0x00, 0x62, 0xb4, 0x00, 0xa9, 0x04, 0x00, 0x74, 0xee, 0x8a, 0x46, 0x04, 0xa2,
- 0x02, 0x62, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0xeb, 0x08,
- 0x8a, 0x04, 0x50, 0xe8, 0xcb, 0xff, 0x59, 0x46, 0x80, 0x3c, 0x00, 0x75, 0xf3,
- 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0xc1, 0xf8,
- 0x04, 0x25, 0x0f, 0x00, 0x3d, 0x09, 0x00, 0x7e, 0x0e, 0x8a, 0x46, 0x04, 0xb4,
- 0x00, 0xc1, 0xf8, 0x04, 0x24, 0x0f, 0x04, 0x37, 0xeb, 0x0c, 0x8a, 0x46, 0x04,
- 0xb4, 0x00, 0xc1, 0xf8, 0x04, 0x24, 0x0f, 0x04, 0x30, 0x50, 0xe8, 0x90, 0xff,
- 0x59, 0x8a, 0x46, 0x04, 0xb4, 0x00, 0x25, 0x0f, 0x00, 0x3d, 0x09, 0x00, 0x7e,
- 0x09, 0x8a, 0x46, 0x04, 0x24, 0x0f, 0x04, 0x37, 0xeb, 0x07, 0x8a, 0x46, 0x04,
- 0x24, 0x0f, 0x04, 0x30, 0x50, 0xe8, 0x6e, 0xff, 0x59, 0x5d, 0xc3, 0x55, 0x8b,
- 0xec, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x0c, 0x25, 0x0f, 0x00, 0x3d, 0x09, 0x00,
- 0x76, 0x0c, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x0c, 0x24, 0x0f, 0x04, 0x37, 0xeb,
- 0x0a, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x0c, 0x24, 0x0f, 0x04, 0x30, 0x50, 0xe8,
- 0x40, 0xff, 0x59, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x08, 0x25, 0x0f, 0x00, 0x3d,
- 0x09, 0x00, 0x76, 0x0c, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x08, 0x24, 0x0f, 0x04,
- 0x37, 0xeb, 0x0a, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x08, 0x24, 0x0f, 0x04, 0x30,
- 0x50, 0xe8, 0x17, 0xff, 0x59, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x04, 0x25, 0x0f,
- 0x00, 0x3d, 0x09, 0x00, 0x76, 0x0c, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x04, 0x24,
- 0x0f, 0x04, 0x37, 0xeb, 0x0a, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x04, 0x24, 0x0f,
- 0x04, 0x30, 0x50, 0xe8, 0xee, 0xfe, 0x59, 0x8b, 0x46, 0x04, 0x25, 0x0f, 0x00,
- 0x3d, 0x09, 0x00, 0x76, 0x09, 0x8a, 0x46, 0x04, 0x24, 0x0f, 0x04, 0x37, 0xeb,
- 0x07, 0x8a, 0x46, 0x04, 0x24, 0x0f, 0x04, 0x30, 0x50, 0xe8, 0xce, 0xfe, 0x59,
- 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x46, 0x06,
- 0xc7, 0x46, 0x06, 0x00, 0x00, 0x89, 0x46, 0x04, 0x8b, 0x7e, 0x04, 0x57, 0xe8,
- 0x46, 0xff, 0x59, 0x56, 0xe8, 0x41, 0xff, 0x59, 0x5f, 0x5e, 0x5d, 0xc3, 0xc8,
- 0x02, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x06, 0x33, 0xf6, 0x8b, 0x46, 0x04,
- 0xbb, 0x10, 0x27, 0x33, 0xd2, 0xf7, 0xf3, 0x89, 0x46, 0xfe, 0x83, 0x7e, 0xfe,
- 0x00, 0x75, 0x09, 0x0b, 0xf6, 0x75, 0x05, 0x83, 0xff, 0x04, 0x76, 0x0d, 0x8a,
- 0x46, 0xfe, 0x04, 0x30, 0x50, 0xe8, 0x77, 0xfe, 0x59, 0xbe, 0x01, 0x00, 0x8b,
- 0x46, 0xfe, 0x69, 0xc0, 0x10, 0x27, 0x29, 0x46, 0x04, 0x8b, 0x46, 0x04, 0xbb,
- 0xe8, 0x03, 0x33, 0xd2, 0xf7, 0xf3, 0x89, 0x46, 0xfe, 0x83, 0x7e, 0xfe, 0x00,
- 0x75, 0x09, 0x0b, 0xf6, 0x75, 0x05, 0x83, 0xff, 0x03, 0x76, 0x0d, 0x8a, 0x46,
- 0xfe, 0x04, 0x30, 0x50, 0xe8, 0x44, 0xfe, 0x59, 0xbe, 0x01, 0x00, 0x8b, 0x46,
- 0xfe, 0x69, 0xc0, 0xe8, 0x03, 0x29, 0x46, 0x04, 0x8b, 0x46, 0x04, 0xbb, 0x64,
- 0x00, 0x33, 0xd2, 0xf7, 0xf3, 0x89, 0x46, 0xfe, 0x83, 0x7e, 0xfe, 0x00, 0x75,
- 0x09, 0x0b, 0xf6, 0x75, 0x05, 0x83, 0xff, 0x02, 0x76, 0x0d, 0x8a, 0x46, 0xfe,
- 0x04, 0x30, 0x50, 0xe8, 0x11, 0xfe, 0x59, 0xbe, 0x01, 0x00, 0x8b, 0x46, 0xfe,
- 0x6b, 0xc0, 0x64, 0x29, 0x46, 0x04, 0x8b, 0x46, 0x04, 0xbb, 0x0a, 0x00, 0x33,
- 0xd2, 0xf7, 0xf3, 0x89, 0x46, 0xfe, 0x83, 0x7e, 0xfe, 0x00, 0x75, 0x09, 0x0b,
- 0xf6, 0x75, 0x05, 0x83, 0xff, 0x01, 0x76, 0x0a, 0x8a, 0x46, 0xfe, 0x04, 0x30,
- 0x50, 0xe8, 0xdf, 0xfd, 0x59, 0x8b, 0x46, 0xfe, 0x6b, 0xc0, 0x0a, 0x29, 0x46,
- 0x04, 0x8a, 0x46, 0x04, 0x04, 0x30, 0x50, 0xe8, 0xcc, 0xfd, 0x59, 0x5f, 0x5e,
- 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0xc6, 0x46, 0xff, 0x80, 0xeb, 0x15, 0x8a,
- 0x46, 0xff, 0x84, 0x46, 0x04, 0x74, 0x04, 0x6a, 0x31, 0xeb, 0x02, 0x6a, 0x30,
- 0xe8, 0xac, 0xfd, 0x59, 0xd0, 0x6e, 0xff, 0x80, 0x7e, 0xff, 0x00, 0x75, 0xe5,
- 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x8b, 0x46, 0x04, 0xc1, 0xe8, 0x08, 0x50, 0xe8,
- 0xcc, 0xff, 0x59, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0xc4, 0xff, 0x59, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x68, 0x8a, 0x01, 0xe8, 0xa5, 0xfd, 0x59, 0x5d, 0xc3, 0x55,
- 0x8b, 0xec, 0x68, 0x8f, 0x01, 0xe8, 0x99, 0xfd, 0x59, 0x5d, 0xc3, 0x55, 0x8b,
- 0xec, 0x68, 0x94, 0x01, 0xe8, 0x8d, 0xfd, 0x59, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x68, 0x99, 0x01, 0xe8, 0x81, 0xfd, 0x59, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x68,
- 0x9e, 0x01, 0xe8, 0x75, 0xfd, 0x59, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x68, 0xa4,
- 0x01, 0xe8, 0x69, 0xfd, 0x59, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x68, 0xa9, 0x01,
- 0xe8, 0x5d, 0xfd, 0x59, 0x68, 0xae, 0x01, 0xe8, 0x56, 0xfd, 0x59, 0x5d, 0xc3,
- 0xc8, 0x0a, 0x00, 0x00, 0x56, 0xc6, 0x46, 0xf6, 0x1b, 0xc6, 0x46, 0xf7, 0x5b,
- 0xbe, 0x02, 0x00, 0x83, 0x7e, 0x04, 0x09, 0x76, 0x1f, 0x8b, 0x46, 0x04, 0xbb,
- 0x0a, 0x00, 0x33, 0xd2, 0xf7, 0xf3, 0x04, 0x30, 0x88, 0x42, 0xf6, 0x46, 0x8b,
- 0x46, 0x04, 0x33, 0xd2, 0xf7, 0xf3, 0x80, 0xc2, 0x30, 0x88, 0x52, 0xf6, 0xeb,
- 0x08, 0x8a, 0x46, 0x04, 0x04, 0x30, 0x88, 0x42, 0xf6, 0x46, 0xc6, 0x42, 0xf6,
- 0x3b, 0x46, 0x83, 0x7e, 0x06, 0x09, 0x76, 0x1f, 0x8b, 0x46, 0x06, 0xbb, 0x0a,
- 0x00, 0x33, 0xd2, 0xf7, 0xf3, 0x04, 0x30, 0x88, 0x42, 0xf6, 0x46, 0x8b, 0x46,
- 0x06, 0x33, 0xd2, 0xf7, 0xf3, 0x80, 0xc2, 0x30, 0x88, 0x52, 0xf6, 0xeb, 0x08,
- 0x8a, 0x46, 0x06, 0x04, 0x30, 0x88, 0x42, 0xf6, 0x46, 0xc6, 0x42, 0xf6, 0x48,
- 0x46, 0xc6, 0x42, 0xf6, 0x00, 0x8d, 0x46, 0xf6, 0x50, 0xe8, 0xd2, 0xfc, 0x59,
- 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x68, 0xb5, 0x01, 0xe8, 0xc5, 0xfc, 0x59,
- 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x68, 0xb9, 0x01, 0xe8, 0xb9, 0xfc, 0x59, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x80, 0x7e, 0x04, 0x0d, 0x75, 0x19, 0xc6, 0x06, 0xd6,
- 0x02, 0x01, 0xa0, 0xd6, 0x02, 0xb4, 0x00, 0x50, 0xa0, 0xd7, 0x02, 0xb4, 0x00,
- 0x50, 0xe8, 0x46, 0xff, 0x83, 0xc4, 0x04, 0xeb, 0x44, 0x80, 0x7e, 0x04, 0x0a,
- 0x75, 0x36, 0xfe, 0x06, 0xd7, 0x02, 0x80, 0x3e, 0xd7, 0x02, 0x11, 0x75, 0x29,
- 0xc6, 0x06, 0xd7, 0x02, 0x10, 0x6a, 0x01, 0x6a, 0x01, 0xe8, 0x24, 0xff, 0x83,
- 0xc4, 0x04, 0x68, 0xbd, 0x01, 0xe8, 0x6e, 0xfc, 0x59, 0x6a, 0x01, 0x6a, 0x10,
- 0xe8, 0x13, 0xff, 0x83, 0xc4, 0x04, 0x68, 0xc2, 0x01, 0xe8, 0x5d, 0xfc, 0x59,
- 0xeb, 0xb2, 0xeb, 0xb0, 0x8a, 0x46, 0x04, 0x50, 0xe8, 0x2b, 0xfc, 0x59, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0xeb, 0x08, 0x8a, 0x04, 0x50,
- 0xe8, 0x89, 0xff, 0x59, 0x46, 0x80, 0x3c, 0x00, 0x75, 0xf3, 0x5e, 0x5d, 0xc3,
- 0xc8, 0x02, 0x00, 0x00, 0xc6, 0x46, 0xff, 0x10, 0xeb, 0x14, 0x6a, 0x01, 0x8a,
- 0x46, 0xff, 0xb4, 0x00, 0x50, 0xe8, 0xcd, 0xfe, 0x83, 0xc4, 0x04, 0xe8, 0xa8,
- 0xfe, 0xfe, 0x4e, 0xff, 0x80, 0x7e, 0xff, 0x00, 0x75, 0xe6, 0xc6, 0x06, 0xd7,
- 0x02, 0x01, 0xc6, 0x06, 0xd6, 0x02, 0x01, 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00,
- 0xe8, 0x30, 0xff, 0xc6, 0x46, 0xff, 0x18, 0xeb, 0x14, 0x6a, 0x01, 0x8a, 0x46,
- 0xff, 0xb4, 0x00, 0x50, 0xe8, 0x9a, 0xfe, 0x83, 0xc4, 0x04, 0xe8, 0x75, 0xfe,
- 0xfe, 0x4e, 0xff, 0x80, 0x7e, 0xff, 0x12, 0x77, 0xe6, 0xe8, 0x19, 0xff, 0xc9,
- 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x56, 0x57, 0x33, 0xf6, 0x33, 0xff, 0xeb, 0x6e,
- 0x80, 0x7e, 0xff, 0x40, 0x72, 0x04, 0x80, 0x66, 0xff, 0xdf, 0x80, 0x7e, 0xff,
- 0x30, 0x72, 0x06, 0x80, 0x7e, 0xff, 0x39, 0x76, 0x0c, 0x80, 0x7e, 0xff, 0x41,
- 0x72, 0x32, 0x80, 0x7e, 0xff, 0x46, 0x77, 0x2c, 0xba, 0x10, 0x00, 0x8b, 0xc6,
- 0xf7, 0xea, 0x8b, 0xf0, 0x47, 0x8a, 0x46, 0xff, 0x50, 0xe8, 0x74, 0xfb, 0x59,
- 0x80, 0x7e, 0xff, 0x39, 0x77, 0x0a, 0x8a, 0x46, 0xff, 0xb4, 0x00, 0x05, 0xd0,
- 0xff, 0xeb, 0x08, 0x8a, 0x46, 0xff, 0xb4, 0x00, 0x05, 0xc9, 0xff, 0x03, 0xf0,
- 0x80, 0x7e, 0xff, 0x08, 0x75, 0x16, 0x0b, 0xff, 0x74, 0x12, 0x4f, 0xbb, 0x10,
- 0x00, 0x8b, 0xc6, 0x33, 0xd2, 0xf7, 0xf3, 0x8b, 0xf0, 0x6a, 0x08, 0xe8, 0x3e,
- 0xfb, 0x59, 0xfe, 0x06, 0x0f, 0x80, 0xe8, 0x18, 0xfb, 0x88, 0x46, 0xff, 0x3c,
- 0x0d, 0x75, 0x88, 0x8b, 0xc6, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00,
- 0x56, 0x57, 0x33, 0xf6, 0x33, 0xff, 0xeb, 0x48, 0x80, 0x7e, 0xff, 0x30, 0x72,
- 0x22, 0x80, 0x7e, 0xff, 0x39, 0x77, 0x1c, 0xba, 0x0a, 0x00, 0x8b, 0xc6, 0xf7,
- 0xea, 0x8b, 0xf0, 0x47, 0x8a, 0x46, 0xff, 0x50, 0xe8, 0x00, 0xfb, 0x59, 0x8a,
- 0x46, 0xff, 0xb4, 0x00, 0x05, 0xd0, 0xff, 0x03, 0xf0, 0x80, 0x7e, 0xff, 0x08,
- 0x75, 0x16, 0x0b, 0xff, 0x74, 0x12, 0x4f, 0xbb, 0x0a, 0x00, 0x8b, 0xc6, 0x33,
- 0xd2, 0xf7, 0xf3, 0x8b, 0xf0, 0x6a, 0x08, 0xe8, 0xda, 0xfa, 0x59, 0xfe, 0x06,
- 0x0f, 0x80, 0xe8, 0xb4, 0xfa, 0x88, 0x46, 0xff, 0x3c, 0x0d, 0x75, 0xae, 0x8b,
- 0xc6, 0x5f, 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0xe8, 0xe9, 0x00, 0xc7,
- 0x06, 0xa0, 0x12, 0x00, 0x81, 0xc6, 0x06, 0x22, 0x80, 0xff, 0xc6, 0x06, 0x21,
- 0x80, 0x00, 0xc6, 0x06, 0x20, 0x80, 0x00, 0xc7, 0x06, 0x9e, 0x12, 0x00, 0x82,
- 0xc6, 0x06, 0x27, 0x80, 0xff, 0xc6, 0x06, 0x26, 0x80, 0x00, 0xc6, 0x06, 0x25,
- 0x80, 0x00, 0xc7, 0x06, 0x9c, 0x12, 0x00, 0x83, 0xc7, 0x06, 0x44, 0x80, 0xff,
- 0x04, 0xc7, 0x06, 0x42, 0x80, 0x00, 0x00, 0xc7, 0x06, 0x40, 0x80, 0x00, 0x00,
- 0xc7, 0x06, 0x9a, 0x12, 0x00, 0x00, 0xfe, 0x06, 0x0f, 0x80, 0xa0, 0xfc, 0x87,
- 0xe8, 0xf6, 0xee, 0xc7, 0x06, 0x96, 0x12, 0x00, 0x00, 0xc7, 0x06, 0x94, 0x12,
- 0x00, 0x00, 0xc6, 0x06, 0x89, 0x12, 0x00, 0x33, 0xf6, 0xeb, 0x17, 0xfe, 0x06,
- 0x0f, 0x80, 0x56, 0xe8, 0xc4, 0x1c, 0x59, 0xa0, 0xc8, 0x01, 0xb4, 0x00, 0x8b,
- 0xde, 0xd1, 0xe3, 0x89, 0x87, 0x08, 0x80, 0x46, 0x83, 0xfe, 0x01, 0x7c, 0xe4,
- 0xc6, 0x06, 0x00, 0x80, 0x54, 0xc6, 0x06, 0x01, 0x80, 0x31, 0xc6, 0x06, 0x02,
- 0x80, 0x4f, 0xc6, 0x06, 0x03, 0x80, 0x4b, 0xc6, 0x06, 0x0d, 0x80, 0x01, 0xc6,
- 0x06, 0x0e, 0x80, 0x38, 0xfb, 0x6a, 0x01, 0x8b, 0x16, 0x82, 0x03, 0xa1, 0x80,
- 0x03, 0x25, 0x00, 0x80, 0x83, 0xe2, 0x07, 0xb1, 0x0f, 0xe8, 0xeb, 0x2e, 0x50,
- 0xe8, 0x1d, 0xf8, 0x83, 0xc4, 0x04, 0xfe, 0x06, 0x0f, 0x80, 0x80, 0x3e, 0xd4,
- 0x02, 0x00, 0x74, 0x05, 0xe8, 0x65, 0xf1, 0xeb, 0xf0, 0xa0, 0x21, 0x80, 0x3a,
- 0x06, 0x20, 0x80, 0x74, 0xe7, 0xa0, 0x26, 0x80, 0x3a, 0x06, 0x25, 0x80, 0x75,
- 0xde, 0xe8, 0xca, 0xef, 0xeb, 0xd9, 0xeb, 0xd7, 0x5e, 0x5d, 0xc3, 0xc8, 0x08,
- 0x00, 0x00, 0x6a, 0x10, 0x68, 0xd8, 0x02, 0x68, 0x64, 0x00, 0xe8, 0xe8, 0xe1,
- 0x83, 0xc4, 0x06, 0x6a, 0x08, 0x68, 0x84, 0x03, 0x68, 0x40, 0x00, 0xe8, 0xda,
- 0xe1, 0x83, 0xc4, 0x06, 0x6a, 0x04, 0x68, 0x80, 0x03, 0x68, 0x48, 0x00, 0xe8,
- 0xcc, 0xe1, 0x83, 0xc4, 0x06, 0x6a, 0x04, 0x68, 0x7c, 0x03, 0x68, 0x4c, 0x00,
- 0xe8, 0xbe, 0xe1, 0x83, 0xc4, 0x06, 0x6a, 0x14, 0x68, 0x58, 0x03, 0x68, 0x50,
- 0x00, 0xe8, 0xb0, 0xe1, 0x83, 0xc4, 0x06, 0x83, 0x26, 0x80, 0x03, 0xc0, 0x83,
- 0x26, 0x82, 0x03, 0xff, 0xa1, 0x80, 0x03, 0x25, 0xc0, 0x01, 0x89, 0x46, 0xfc,
- 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xb9, 0x03, 0x00, 0xbb, 0x4d, 0x20, 0x2e, 0x8b,
- 0x07, 0x3b, 0x46, 0xfc, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xfe,
- 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x12, 0x2e, 0xff, 0x67, 0x0c,
- 0x80, 0x0e, 0xc8, 0x01, 0x01, 0xeb, 0x07, 0xeb, 0x00, 0x80, 0x26, 0xc8, 0x01,
- 0xfe, 0xa1, 0x80, 0x03, 0x25, 0x00, 0x0e, 0x89, 0x46, 0xf8, 0xc7, 0x46, 0xfa,
- 0x00, 0x00, 0xb9, 0x03, 0x00, 0xbb, 0x3b, 0x20, 0x2e, 0x8b, 0x07, 0x3b, 0x46,
- 0xf8, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xfa, 0x74, 0x07, 0x83,
- 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x12, 0x2e, 0xff, 0x67, 0x0c, 0x80, 0x0e, 0xc8,
- 0x01, 0x02, 0xeb, 0x07, 0xeb, 0x00, 0x80, 0x26, 0xc8, 0x01, 0xfd, 0xa1, 0x80,
- 0x03, 0x25, 0x00, 0x10, 0x33, 0xd2, 0x0b, 0xd2, 0x75, 0x2b, 0x3d, 0x00, 0x10,
- 0x75, 0x26, 0x80, 0x26, 0xc8, 0x01, 0x7f, 0x83, 0x3e, 0x7e, 0x03, 0x00, 0x72,
- 0x1f, 0x77, 0x08, 0x81, 0x3e, 0x7c, 0x03, 0x8f, 0x02, 0x76, 0x15, 0xc7, 0x06,
- 0x7e, 0x03, 0x00, 0x00, 0xc7, 0x06, 0x7c, 0x03, 0x8f, 0x02, 0xeb, 0x07, 0xeb,
- 0x05, 0x80, 0x0e, 0xc8, 0x01, 0x80, 0xff, 0x36, 0x7e, 0x03, 0xff, 0x36, 0x7c,
- 0x03, 0xff, 0x36, 0x82, 0x03, 0xff, 0x36, 0x80, 0x03, 0xe8, 0x0c, 0x1b, 0x83,
- 0xc4, 0x08, 0xff, 0x36, 0x7e, 0x03, 0xff, 0x36, 0x7c, 0x03, 0xff, 0x36, 0x82,
- 0x03, 0xff, 0x36, 0x80, 0x03, 0xe8, 0x80, 0x2a, 0x83, 0xc4, 0x08, 0xff, 0x36,
- 0x7e, 0x03, 0xff, 0x36, 0x7c, 0x03, 0xff, 0x36, 0x82, 0x03, 0xff, 0x36, 0x80,
- 0x03, 0xe8, 0xa8, 0x0e, 0x83, 0xc4, 0x08, 0xc9, 0xc3, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x1f, 0xb4, 0x1f, 0xb6,
- 0x1f, 0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x6f, 0x1f, 0x76, 0x1f, 0x78, 0x1f, 0xc8, 0x02, 0x00, 0x00, 0x56, 0x57, 0x8b,
- 0x76, 0x06, 0x83, 0x7c, 0x06, 0x00, 0x72, 0x0a, 0x75, 0x06, 0x83, 0x7c, 0x04,
- 0x01, 0x72, 0x02, 0xeb, 0x49, 0x8b, 0x44, 0x04, 0x69, 0xc0, 0xeb, 0x0e, 0x05,
- 0x9c, 0x03, 0x89, 0x46, 0xfe, 0xbf, 0xce, 0x01, 0xeb, 0x30, 0x8b, 0x45, 0x02,
- 0x8b, 0x15, 0x3b, 0x44, 0x02, 0x75, 0x23, 0x3b, 0x14, 0x75, 0x1f, 0x83, 0x7c,
- 0x02, 0x00, 0x75, 0x06, 0x81, 0x3c, 0x0d, 0x10, 0x74, 0x08, 0x8b, 0x45, 0x04,
- 0x3b, 0x46, 0x04, 0x75, 0x0b, 0xff, 0x76, 0x06, 0xff, 0x76, 0xfe, 0xff, 0x55,
- 0x06, 0xeb, 0x24, 0x83, 0xc7, 0x08, 0x8b, 0x05, 0x0b, 0x45, 0x02, 0x75, 0xc9,
- 0xc7, 0x44, 0x02, 0x00, 0x00, 0xc7, 0x04, 0x0e, 0x10, 0xc7, 0x44, 0x0e, 0x00,
- 0x00, 0xc7, 0x44, 0x0c, 0x10, 0x00, 0x56, 0xff, 0x74, 0x0c, 0xe8, 0x06, 0xf0,
- 0x83, 0xc4, 0x04, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x04, 0x00, 0x00, 0x56, 0x8b,
- 0x76, 0x06, 0x8b, 0x44, 0x06, 0x8b, 0x54, 0x04, 0x89, 0x56, 0xfc, 0x89, 0x46,
- 0xfe, 0xb9, 0x02, 0x00, 0xbb, 0x44, 0x21, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfc,
- 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x04, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83, 0xc3,
- 0x02, 0xe2, 0xea, 0xeb, 0x24, 0x2e, 0xff, 0x67, 0x08, 0xc7, 0x44, 0x12, 0x00,
- 0x00, 0xc7, 0x44, 0x10, 0x0d, 0x00, 0xeb, 0x0a, 0xc7, 0x44, 0x12, 0x00, 0x00,
- 0xc7, 0x44, 0x10, 0x09, 0x00, 0xc7, 0x44, 0x16, 0x00, 0x00, 0xc7, 0x44, 0x14,
- 0x00, 0x00, 0x56, 0x6a, 0x18, 0xe8, 0xa3, 0xef, 0x83, 0xc4, 0x04, 0x5e, 0xc9,
- 0xc3, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x21, 0x24, 0x21,
- 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8b, 0x76, 0x06, 0x8b, 0x45,
- 0x04, 0x8b, 0x55, 0x02, 0x89, 0x44, 0x12, 0x89, 0x54, 0x10, 0x8b, 0x45, 0x08,
- 0x8b, 0x55, 0x06, 0x89, 0x44, 0x16, 0x89, 0x54, 0x14, 0x56, 0x6a, 0x18, 0xe8,
- 0x68, 0xef, 0x83, 0xc4, 0x04, 0x5f, 0x5e, 0x5d, 0xc3, 0xc8, 0x04, 0x00, 0x00,
- 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x06, 0xff, 0x75, 0x16, 0xff, 0x75,
- 0x14, 0xff, 0x75, 0x12, 0xff, 0x75, 0x10, 0x56, 0xe8, 0x94, 0x08, 0x83, 0xc4,
- 0x0a, 0x8b, 0x45, 0x10, 0x25, 0x00, 0x60, 0x89, 0x46, 0xfc, 0xc7, 0x46, 0xfe,
- 0x00, 0x00, 0xb9, 0x04, 0x00, 0xbb, 0x85, 0x22, 0x2e, 0x8b, 0x07, 0x3b, 0x46,
- 0xfc, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x08, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83,
- 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x37, 0x2e, 0xff, 0x67, 0x10, 0x6a, 0x00, 0x6a,
- 0x40, 0x56, 0xe8, 0x91, 0x09, 0x83, 0xc4, 0x06, 0x8b, 0x44, 0x04, 0x8b, 0x54,
- 0x02, 0x81, 0xe2, 0xff, 0x9f, 0x25, 0xff, 0xff, 0x89, 0x44, 0x04, 0x89, 0x54,
- 0x02, 0xeb, 0x13, 0x6a, 0x00, 0x6a, 0x00, 0xeb, 0x04, 0x6a, 0x00, 0x6a, 0x40,
- 0x56, 0xe8, 0x6b, 0x09, 0x83, 0xc4, 0x06, 0xeb, 0x00, 0x8b, 0x45, 0x10, 0x25,
- 0xc0, 0x01, 0x33, 0xd2, 0x8b, 0x5c, 0x02, 0x81, 0xe3, 0xc0, 0x01, 0x0b, 0xd2,
- 0x75, 0x04, 0x3b, 0xc3, 0x74, 0x0d, 0xff, 0x75, 0x12, 0xff, 0x75, 0x10, 0x56,
- 0xe8, 0x0c, 0x16, 0x83, 0xc4, 0x06, 0x8b, 0x45, 0x10, 0x25, 0x00, 0x0e, 0x33,
- 0xd2, 0x8b, 0x5c, 0x02, 0x81, 0xe3, 0x00, 0x0e, 0x0b, 0xd2, 0x75, 0x04, 0x3b,
- 0xc3, 0x74, 0x0d, 0xff, 0x75, 0x12, 0xff, 0x75, 0x10, 0x56, 0xe8, 0x10, 0x15,
- 0x83, 0xc4, 0x06, 0x8b, 0x45, 0x12, 0x8b, 0x55, 0x10, 0x81, 0xe2, 0x00, 0x80,
- 0x25, 0x07, 0x00, 0x8b, 0x5c, 0x04, 0x8b, 0x4c, 0x02, 0x81, 0xe1, 0x00, 0x80,
- 0x83, 0xe3, 0x07, 0x3b, 0xc3, 0x75, 0x04, 0x3b, 0xd1, 0x74, 0x0d, 0xff, 0x75,
- 0x12, 0xff, 0x75, 0x10, 0x56, 0xe8, 0x46, 0x09, 0x83, 0xc4, 0x06, 0x57, 0x56,
- 0xe8, 0xd2, 0xfe, 0x83, 0xc4, 0x04, 0x5f, 0x5e, 0xc9, 0xc3, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xcf, 0x21, 0xef, 0x21, 0xf5, 0x21, 0x02, 0x22, 0xc8, 0x04, 0x00, 0x00, 0x56,
- 0x8b, 0x4e, 0x04, 0xa1, 0x2a, 0x80, 0x8b, 0x16, 0x28, 0x80, 0x89, 0x46, 0xfe,
- 0x89, 0x56, 0xfc, 0xa1, 0x12, 0x80, 0x8b, 0x16, 0x10, 0x80, 0xf7, 0xd2, 0xf7,
- 0xd0, 0x8b, 0xd9, 0x89, 0x47, 0x10, 0x89, 0x57, 0x0e, 0x83, 0x67, 0x0e, 0xff,
- 0x81, 0x67, 0x10, 0xff, 0x7f, 0x8b, 0x46, 0xfe, 0x8b, 0x56, 0xfc, 0x21, 0x57,
- 0x0e, 0x21, 0x47, 0x10, 0xbe, 0x1c, 0x80, 0x8b, 0x44, 0x02, 0x8b, 0x14, 0x89,
- 0x47, 0x14, 0x89, 0x57, 0x12, 0x83, 0x67, 0x12, 0xff, 0x81, 0x67, 0x14, 0xff,
- 0x7f, 0x8b, 0x46, 0xfe, 0x8b, 0x56, 0xfc, 0x21, 0x57, 0x12, 0x21, 0x47, 0x14,
- 0xbe, 0x2c, 0x80, 0x8b, 0x44, 0x02, 0x8b, 0x14, 0x89, 0x47, 0x18, 0x89, 0x57,
- 0x16, 0x83, 0x67, 0x16, 0xff, 0x81, 0x67, 0x18, 0xff, 0x7f, 0x8b, 0x46, 0xfe,
- 0x8b, 0x56, 0xfc, 0x21, 0x57, 0x16, 0x21, 0x47, 0x18, 0x5e, 0xc9, 0xc3, 0xc8,
- 0x02, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x46, 0x04, 0x05, 0x12, 0x00, 0x8b, 0xf8,
- 0x8b, 0x46, 0x06, 0x05, 0x18, 0x00, 0x8b, 0xf0, 0xc7, 0x46, 0xfe, 0x1c, 0x80,
- 0x8a, 0x05, 0x3a, 0x04, 0x74, 0x12, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x04, 0x50,
- 0x6a, 0x00, 0xff, 0x76, 0xfe, 0xe8, 0x6a, 0xef, 0x83, 0xc4, 0x0a, 0x8a, 0x45,
- 0x01, 0x3a, 0x44, 0x01, 0x74, 0x15, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x44, 0x01,
- 0x50, 0x6a, 0x01, 0x8b, 0x46, 0xfe, 0x40, 0x50, 0xe8, 0x4d, 0xef, 0x83, 0xc4,
- 0x0a, 0x8a, 0x45, 0x02, 0x3a, 0x44, 0x02, 0x74, 0x17, 0x6a, 0x01, 0x6a, 0x20,
- 0x8a, 0x44, 0x02, 0x50, 0x6a, 0x02, 0x8b, 0x46, 0xfe, 0x05, 0x02, 0x00, 0x50,
- 0xe8, 0x2e, 0xef, 0x83, 0xc4, 0x0a, 0x8a, 0x45, 0x03, 0x3a, 0x44, 0x03, 0x74,
- 0x17, 0x6a, 0x01, 0x6a, 0x20, 0x8a, 0x44, 0x03, 0x50, 0x6a, 0x03, 0x8b, 0x46,
- 0xfe, 0x05, 0x03, 0x00, 0x50, 0xe8, 0x0f, 0xef, 0x83, 0xc4, 0x0a, 0x8b, 0x5e,
- 0x06, 0x8b, 0x47, 0x1a, 0x8b, 0x57, 0x18, 0x8b, 0x5e, 0x04, 0x89, 0x47, 0x14,
- 0x89, 0x57, 0x12, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x56, 0x57,
- 0x8b, 0x46, 0x04, 0x05, 0x16, 0x00, 0x8b, 0xf8, 0x8b, 0x46, 0x06, 0x05, 0x1c,
- 0x00, 0x8b, 0xf0, 0xc7, 0x46, 0xfe, 0x2c, 0x80, 0x8a, 0x05, 0x3a, 0x04, 0x74,
- 0x12, 0x6a, 0x01, 0x6a, 0x40, 0x8a, 0x04, 0x50, 0x6a, 0x00, 0xff, 0x76, 0xfe,
- 0xe8, 0xc6, 0xee, 0x83, 0xc4, 0x0a, 0x8a, 0x45, 0x01, 0x3a, 0x44, 0x01, 0x74,
- 0x15, 0x6a, 0x01, 0x6a, 0x40, 0x8a, 0x44, 0x01, 0x50, 0x6a, 0x01, 0x8b, 0x46,
- 0xfe, 0x40, 0x50, 0xe8, 0xa9, 0xee, 0x83, 0xc4, 0x0a, 0x8a, 0x45, 0x02, 0x3a,
- 0x44, 0x02, 0x74, 0x17, 0x6a, 0x01, 0x6a, 0x40, 0x8a, 0x44, 0x02, 0x50, 0x6a,
- 0x02, 0x8b, 0x46, 0xfe, 0x05, 0x02, 0x00, 0x50, 0xe8, 0x8a, 0xee, 0x83, 0xc4,
- 0x0a, 0x8a, 0x45, 0x03, 0x3a, 0x44, 0x03, 0x74, 0x17, 0x6a, 0x01, 0x6a, 0x40,
- 0x8a, 0x44, 0x03, 0x50, 0x6a, 0x03, 0x8b, 0x46, 0xfe, 0x05, 0x03, 0x00, 0x50,
- 0xe8, 0x6b, 0xee, 0x83, 0xc4, 0x0a, 0x8b, 0x5e, 0x06, 0x8b, 0x47, 0x1e, 0x8b,
- 0x57, 0x1c, 0x8b, 0x5e, 0x04, 0x89, 0x47, 0x18, 0x89, 0x57, 0x16, 0x5f, 0x5e,
- 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x06,
- 0x56, 0xe8, 0x23, 0xfe, 0x59, 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x89, 0x45,
- 0x12, 0x89, 0x55, 0x10, 0x8b, 0x44, 0x10, 0x8b, 0x54, 0x0e, 0x89, 0x45, 0x16,
- 0x89, 0x55, 0x14, 0x8b, 0x44, 0x14, 0x8b, 0x54, 0x12, 0x89, 0x45, 0x1a, 0x89,
- 0x55, 0x18, 0x8b, 0x44, 0x18, 0x8b, 0x54, 0x16, 0x89, 0x45, 0x1e, 0x89, 0x55,
- 0x1c, 0x8b, 0x44, 0x1c, 0x8b, 0x54, 0x1a, 0x89, 0x45, 0x22, 0x89, 0x55, 0x20,
- 0x57, 0x6a, 0x24, 0xe8, 0x24, 0xec, 0x83, 0xc4, 0x04, 0x5f, 0x5e, 0x5d, 0xc3,
- 0xc8, 0x08, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x7e, 0x06, 0x8b,
- 0x45, 0x10, 0x25, 0x03, 0x00, 0x89, 0x46, 0xfc, 0xc7, 0x46, 0xfe, 0x00, 0x00,
- 0xb9, 0x03, 0x00, 0xbb, 0xcd, 0x25, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfc, 0x75,
- 0x09, 0x2e, 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83, 0xc3, 0x02,
- 0xe2, 0xea, 0xeb, 0x2a, 0x2e, 0xff, 0x67, 0x0c, 0x6a, 0x00, 0x6a, 0x00, 0x56,
- 0xe8, 0x83, 0x0f, 0x83, 0xc4, 0x06, 0x6a, 0x00, 0x6a, 0x00, 0xeb, 0x0e, 0x6a,
- 0x00, 0x6a, 0x01, 0x56, 0xe8, 0x72, 0x0f, 0xeb, 0x08, 0x6a, 0x00, 0x6a, 0x02,
- 0x56, 0xe8, 0xfa, 0x0f, 0x83, 0xc4, 0x06, 0x8b, 0x45, 0x10, 0x25, 0x60, 0x00,
- 0x89, 0x46, 0xf8, 0xc7, 0x46, 0xfa, 0x00, 0x00, 0xb9, 0x02, 0x00, 0xbb, 0xc1,
- 0x25, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xf8, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x04,
- 0x3b, 0x46, 0xfa, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x10, 0x2e,
- 0xff, 0x67, 0x08, 0x6a, 0x01, 0x56, 0xe8, 0xd8, 0x0e, 0xeb, 0x13, 0x6a, 0x01,
- 0xeb, 0x0b, 0x6a, 0x00, 0x56, 0xe8, 0xcc, 0x0e, 0x83, 0xc4, 0x04, 0x6a, 0x00,
- 0x56, 0xe8, 0x6c, 0x0e, 0x83, 0xc4, 0x04, 0x56, 0xe8, 0x25, 0xfd, 0x59, 0x8b,
- 0x44, 0x14, 0x8b, 0x54, 0x12, 0x3b, 0x45, 0x1a, 0x75, 0x05, 0x3b, 0x55, 0x18,
- 0x74, 0x08, 0x57, 0x56, 0xe8, 0x95, 0xfd, 0x83, 0xc4, 0x04, 0x8b, 0x44, 0x18,
- 0x8b, 0x54, 0x16, 0x3b, 0x45, 0x1e, 0x75, 0x05, 0x3b, 0x55, 0x1c, 0x74, 0x08,
- 0x57, 0x56, 0xe8, 0x21, 0xfe, 0x83, 0xc4, 0x04, 0x8b, 0x45, 0x22, 0x8b, 0x55,
- 0x20, 0x89, 0x44, 0x1c, 0x89, 0x54, 0x1a, 0x57, 0x56, 0xe8, 0xb1, 0xfe, 0x83,
- 0xc4, 0x04, 0x5f, 0x5e, 0xc9, 0xc3, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x5e, 0x25, 0x56, 0x25, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x11, 0x25, 0x1b, 0x25, 0xc8, 0x16, 0x00,
- 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0x5e, 0x06, 0x8b, 0x47, 0x02, 0x8b,
- 0x17, 0xa3, 0xa4, 0x12, 0x89, 0x16, 0xa2, 0x12, 0x8b, 0x47, 0x06, 0x8b, 0x57,
- 0x04, 0xa3, 0xa8, 0x12, 0x89, 0x16, 0xa6, 0x12, 0x8b, 0x47, 0x0a, 0x8b, 0x57,
- 0x08, 0xa3, 0xac, 0x12, 0x89, 0x16, 0xaa, 0x12, 0x8b, 0x47, 0x0e, 0x8b, 0x57,
- 0x0c, 0xa3, 0xb0, 0x12, 0x89, 0x16, 0xae, 0x12, 0x8b, 0x44, 0x2e, 0x99, 0x89,
- 0x16, 0xb4, 0x12, 0xa3, 0xb2, 0x12, 0x80, 0x7c, 0x2d, 0x00, 0x74, 0x05, 0xb8,
- 0x60, 0x00, 0xeb, 0x05, 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x99, 0x89, 0x16, 0xb8,
- 0x12, 0xa3, 0xb6, 0x12, 0x8b, 0x44, 0x02, 0x25, 0x00, 0x0e, 0x89, 0x46, 0xfa,
- 0xc7, 0x46, 0xfc, 0x00, 0x00, 0xb9, 0x02, 0x00, 0xbb, 0x24, 0x29, 0x2e, 0x8b,
- 0x07, 0x3b, 0x46, 0xfa, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x04, 0x3b, 0x46, 0xfc,
- 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x20, 0x2e, 0xff, 0x67, 0x08,
- 0xc7, 0x06, 0xbc, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xba, 0x12, 0x03, 0x00, 0xeb,
- 0x1a, 0xc7, 0x06, 0xbc, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xba, 0x12, 0x02, 0x00,
- 0xeb, 0x0c, 0xc7, 0x06, 0xbc, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xba, 0x12, 0x01,
- 0x00, 0x8b, 0x44, 0x02, 0x25, 0xc0, 0x01, 0x89, 0x46, 0xf6, 0xc7, 0x46, 0xf8,
- 0x00, 0x00, 0xb9, 0x02, 0x00, 0xbb, 0x18, 0x29, 0x2e, 0x8b, 0x07, 0x3b, 0x46,
- 0xf6, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x04, 0x3b, 0x46, 0xf8, 0x74, 0x07, 0x83,
- 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x20, 0x2e, 0xff, 0x67, 0x08, 0xc7, 0x06, 0xc0,
- 0x12, 0x00, 0x00, 0xc7, 0x06, 0xbe, 0x12, 0x02, 0x00, 0xeb, 0x1a, 0xc7, 0x06,
- 0xc0, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xbe, 0x12, 0x05, 0x00, 0xeb, 0x0c, 0xc7,
- 0x06, 0xc0, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xbe, 0x12, 0x06, 0x00, 0xc7, 0x06,
- 0xc4, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xc2, 0x12, 0x01, 0x00, 0x8b, 0x44, 0x0a,
- 0x25, 0x03, 0x00, 0x89, 0x46, 0xf2, 0xc7, 0x46, 0xf4, 0x00, 0x00, 0xb9, 0x03,
- 0x00, 0xbb, 0x06, 0x29, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xf2, 0x75, 0x09, 0x2e,
- 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xf4, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea,
- 0xeb, 0x2e, 0x2e, 0xff, 0x67, 0x0c, 0xc7, 0x06, 0xc8, 0x12, 0x00, 0x00, 0xc7,
- 0x06, 0xc6, 0x12, 0x01, 0x00, 0xeb, 0x28, 0xc7, 0x06, 0xc8, 0x12, 0x00, 0x00,
- 0xc7, 0x06, 0xc6, 0x12, 0x02, 0x00, 0xeb, 0x1a, 0xc7, 0x06, 0xc8, 0x12, 0x00,
- 0x00, 0xc7, 0x06, 0xc6, 0x12, 0x03, 0x00, 0xeb, 0x0c, 0xc7, 0x06, 0xc8, 0x12,
- 0x00, 0x00, 0xc7, 0x06, 0xc6, 0x12, 0x04, 0x00, 0xc7, 0x06, 0xcc, 0x12, 0x00,
- 0x00, 0xc7, 0x06, 0xca, 0x12, 0x00, 0x00, 0x8b, 0x44, 0x1e, 0x25, 0x04, 0x00,
- 0x0d, 0x00, 0x00, 0x74, 0x0a, 0x83, 0x0e, 0xca, 0x12, 0x20, 0x83, 0x0e, 0xcc,
- 0x12, 0x00, 0x8b, 0x44, 0x1e, 0x25, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x0a,
- 0x83, 0x0e, 0xca, 0x12, 0x02, 0x83, 0x0e, 0xcc, 0x12, 0x00, 0x8b, 0x44, 0x1e,
- 0x25, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x0a, 0x83, 0x0e, 0xca, 0x12, 0x08,
- 0x83, 0x0e, 0xcc, 0x12, 0x00, 0x8b, 0x44, 0x0a, 0x25, 0x60, 0x00, 0x89, 0x46,
- 0xee, 0xc7, 0x46, 0xf0, 0x00, 0x00, 0xb9, 0x02, 0x00, 0xbb, 0xfa, 0x28, 0x2e,
- 0x8b, 0x07, 0x3b, 0x46, 0xee, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x04, 0x3b, 0x46,
- 0xf0, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x15, 0x2e, 0xff, 0x67,
- 0x08, 0x83, 0x0e, 0xca, 0x12, 0x04, 0xeb, 0x05, 0x83, 0x0e, 0xca, 0x12, 0x10,
- 0x83, 0x0e, 0xcc, 0x12, 0x00, 0xff, 0x34, 0xe8, 0xbb, 0x24, 0x59, 0x0b, 0xc0,
- 0x74, 0x0a, 0x83, 0x0e, 0xca, 0x12, 0x40, 0x83, 0x0e, 0xcc, 0x12, 0x00, 0xa1,
- 0xca, 0x12, 0x0b, 0x06, 0xcc, 0x12, 0x75, 0x0a, 0x83, 0x0e, 0xca, 0x12, 0x01,
- 0x83, 0x0e, 0xcc, 0x12, 0x00, 0xc7, 0x06, 0xd0, 0x12, 0x00, 0x00, 0xc7, 0x06,
- 0xce, 0x12, 0x02, 0x00, 0x8b, 0x44, 0x02, 0x25, 0x30, 0x00, 0x89, 0x46, 0xea,
- 0xc7, 0x46, 0xec, 0x00, 0x00, 0xb9, 0x03, 0x00, 0xbb, 0xe8, 0x28, 0x2e, 0x8b,
- 0x07, 0x3b, 0x46, 0xea, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xec,
- 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x2c, 0x2e, 0xff, 0x67, 0x0c,
- 0xc7, 0x06, 0xd4, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xd2, 0x12, 0x01, 0x00, 0xeb,
- 0x1a, 0xc7, 0x06, 0xd4, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xd2, 0x12, 0x02, 0x00,
- 0xeb, 0x0c, 0xc7, 0x06, 0xd4, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xd2, 0x12, 0x03,
- 0x00, 0xc7, 0x06, 0xd8, 0x12, 0x00, 0x00, 0xc7, 0x06, 0xd6, 0x12, 0x06, 0x00,
- 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd6, 0x03, 0xd0, 0x83,
- 0xc2, 0x30, 0x8b, 0xfa, 0x68, 0xda, 0x12, 0x52, 0xe8, 0x92, 0x00, 0x83, 0xc4,
- 0x04, 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xeb, 0x21, 0x8b, 0xc6, 0x05, 0x30, 0x00,
- 0x3b, 0xc7, 0x76, 0x04, 0x81, 0xc7, 0x18, 0x09, 0x8b, 0x46, 0xfe, 0x6b, 0xc0,
- 0x28, 0x05, 0x02, 0x13, 0x50, 0x57, 0xe8, 0x6d, 0x00, 0x83, 0xc4, 0x04, 0xff,
- 0x46, 0xfe, 0x83, 0xef, 0x18, 0x83, 0x7e, 0xfe, 0x60, 0x7c, 0xd6, 0x68, 0x02,
- 0x22, 0x8b, 0xc6, 0x05, 0x48, 0x09, 0x50, 0xe8, 0xce, 0x00, 0x83, 0xc4, 0x04,
- 0xe8, 0x4e, 0xe7, 0x5f, 0x5e, 0xc9, 0xc3, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x28, 0x60, 0x28, 0x6e, 0x28, 0x20,
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x27, 0xe5, 0x27, 0x00, 0x00,
- 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x27, 0x49,
- 0x27, 0x3b, 0x27, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x26,
- 0xc9, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x71, 0x26, 0x7f,
- 0x26, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x4e, 0x06, 0x8b, 0x04,
- 0x8b, 0xd9, 0xc7, 0x47, 0x02, 0x00, 0x00, 0x89, 0x07, 0x8b, 0x44, 0x06, 0xc7,
- 0x47, 0x06, 0x00, 0x00, 0x89, 0x47, 0x04, 0x8b, 0x04, 0xc7, 0x47, 0x0a, 0x00,
- 0x00, 0x89, 0x47, 0x08, 0x8b, 0x44, 0x02, 0xc7, 0x47, 0x0e, 0x00, 0x00, 0x89,
- 0x47, 0x0c, 0x8b, 0x44, 0x08, 0xc7, 0x47, 0x12, 0x00, 0x00, 0x89, 0x47, 0x10,
- 0x8b, 0x44, 0x16, 0x8b, 0x54, 0x14, 0x89, 0x47, 0x16, 0x89, 0x57, 0x14, 0x8b,
- 0x44, 0x0e, 0xc7, 0x47, 0x1a, 0x00, 0x00, 0x89, 0x47, 0x18, 0x8b, 0x44, 0x04,
- 0xc7, 0x47, 0x1e, 0x00, 0x00, 0x89, 0x47, 0x1c, 0x8b, 0x44, 0x0c, 0xc7, 0x47,
- 0x22, 0x00, 0x00, 0x89, 0x47, 0x20, 0x8b, 0x44, 0x12, 0x8b, 0x54, 0x10, 0x89,
- 0x47, 0x26, 0x89, 0x57, 0x24, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b,
- 0x4e, 0x04, 0x8b, 0x76, 0x06, 0x8b, 0xd9, 0x8b, 0x47, 0x02, 0x8b, 0x17, 0x89,
- 0x44, 0x02, 0x89, 0x14, 0x8b, 0x47, 0x0e, 0x8b, 0x57, 0x0c, 0x89, 0x44, 0x06,
- 0x89, 0x54, 0x04, 0x8b, 0x47, 0x02, 0x8b, 0x17, 0x89, 0x44, 0x0a, 0x89, 0x54,
- 0x08, 0x8b, 0x47, 0x06, 0x8b, 0x57, 0x04, 0x89, 0x44, 0x0e, 0x89, 0x54, 0x0c,
- 0x8b, 0x47, 0x12, 0x8b, 0x57, 0x10, 0x89, 0x44, 0x12, 0x89, 0x54, 0x10, 0x8b,
- 0x47, 0x26, 0x8b, 0x57, 0x24, 0x89, 0x44, 0x16, 0x89, 0x54, 0x14, 0x8b, 0x47,
- 0x1e, 0x8b, 0x57, 0x1c, 0x89, 0x44, 0x1a, 0x89, 0x54, 0x18, 0x8b, 0x47, 0x0a,
- 0x8b, 0x57, 0x08, 0x89, 0x44, 0x1e, 0x89, 0x54, 0x1c, 0x8b, 0x47, 0x1a, 0x8b,
- 0x57, 0x18, 0x89, 0x44, 0x22, 0x89, 0x54, 0x20, 0x8b, 0x47, 0x22, 0x8b, 0x57,
- 0x20, 0x89, 0x44, 0x26, 0x89, 0x54, 0x24, 0x5e, 0x5d, 0xc3, 0xc8, 0x02, 0x00,
- 0x00, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x04, 0x0b, 0xc0, 0x74, 0x0b, 0x3d, 0x01,
- 0x00, 0x75, 0x03, 0xe9, 0xc2, 0x00, 0xe9, 0x1c, 0x01, 0x8b, 0x46, 0x06, 0x25,
- 0x00, 0x10, 0x0d, 0x00, 0x00, 0x75, 0x39, 0x8a, 0x46, 0x0a, 0x24, 0x03, 0xc0,
- 0xe0, 0x03, 0x0c, 0x01, 0x88, 0x46, 0xff, 0x8b, 0x46, 0x0a, 0x25, 0x04, 0x00,
- 0x0d, 0x00, 0x00, 0x75, 0x04, 0x80, 0x4e, 0xff, 0x20, 0x8a, 0x46, 0xff, 0xa2,
- 0x4c, 0x02, 0xa2, 0x81, 0x60, 0xb0, 0x41, 0xa2, 0x4d, 0x02, 0xa2, 0x80, 0x60,
- 0x8b, 0x1c, 0xd1, 0xe3, 0x81, 0x8f, 0x08, 0x80, 0x80, 0x00, 0xeb, 0x4e, 0x83,
- 0x7e, 0x0c, 0x00, 0x72, 0x13, 0x77, 0x07, 0x81, 0x7e, 0x0a, 0x8f, 0x02, 0x76,
- 0x0a, 0xc7, 0x46, 0x0c, 0x00, 0x00, 0xc7, 0x46, 0x0a, 0x8f, 0x02, 0xc6, 0x46,
- 0xff, 0x41, 0x6a, 0x00, 0x68, 0x85, 0x00, 0xff, 0x76, 0x0c, 0xff, 0x76, 0x0a,
- 0xe8, 0x23, 0x22, 0x04, 0x03, 0xc0, 0xe0, 0x03, 0x08, 0x46, 0xff, 0x8a, 0x46,
- 0xff, 0xa2, 0x4d, 0x02, 0xa2, 0x80, 0x60, 0xb0, 0xb9, 0xa2, 0x4c, 0x02, 0xa2,
- 0x81, 0x60, 0x8b, 0x1c, 0xd1, 0xe3, 0x81, 0xa7, 0x08, 0x80, 0x7f, 0xff, 0x8b,
- 0x46, 0x0c, 0x8b, 0x56, 0x0a, 0x89, 0x44, 0x08, 0x89, 0x54, 0x06, 0x8b, 0x44,
- 0x04, 0x8b, 0x54, 0x02, 0x81, 0xe2, 0xff, 0xef, 0x25, 0xff, 0xff, 0x8b, 0x5e,
- 0x06, 0x81, 0xe3, 0x00, 0x10, 0x0b, 0xd3, 0x0d, 0x00, 0x00, 0x89, 0x44, 0x04,
- 0x89, 0x54, 0x02, 0xeb, 0x5d, 0x8b, 0x46, 0x06, 0x25, 0x00, 0x10, 0x33, 0xd2,
- 0x0b, 0xd2, 0x75, 0x51, 0x3d, 0x00, 0x10, 0x75, 0x4c, 0x83, 0x7e, 0x0c, 0x00,
- 0x72, 0x13, 0x77, 0x07, 0x81, 0x7e, 0x0a, 0x8f, 0x02, 0x76, 0x0a, 0xc7, 0x46,
- 0x0c, 0x00, 0x00, 0xc7, 0x46, 0x0a, 0x8f, 0x02, 0x6a, 0x00, 0x68, 0x85, 0x00,
- 0xff, 0x76, 0x0c, 0xff, 0x76, 0x0a, 0xe8, 0x9b, 0x21, 0x04, 0x03, 0xc0, 0xe0,
- 0x03, 0x0c, 0x01, 0x88, 0x46, 0xff, 0xa2, 0x88, 0x12, 0xa2, 0x00, 0x60, 0x8b,
- 0x46, 0x0c, 0x8b, 0x56, 0x0a, 0x89, 0x44, 0x08, 0x89, 0x54, 0x06, 0x81, 0x4c,
- 0x02, 0x00, 0x10, 0x83, 0x4c, 0x04, 0x00, 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec,
- 0x56, 0x8b, 0x76, 0x04, 0x83, 0x3c, 0x00, 0x75, 0x45, 0x8b, 0x46, 0x06, 0x0b,
- 0x46, 0x08, 0x75, 0x1b, 0x80, 0x26, 0x4c, 0x02, 0xbf, 0xa0, 0x4c, 0x02, 0xa2,
- 0x81, 0x60, 0x8b, 0x44, 0x04, 0x8b, 0x54, 0x02, 0x81, 0xe2, 0xff, 0x9f, 0x81,
- 0xca, 0x00, 0x20, 0xeb, 0x19, 0x80, 0x0e, 0x4c, 0x02, 0x40, 0xa0, 0x4c, 0x02,
- 0xa2, 0x81, 0x60, 0x8b, 0x44, 0x04, 0x8b, 0x54, 0x02, 0x81, 0xe2, 0xff, 0x9f,
- 0x81, 0xca, 0x00, 0x40, 0x25, 0xff, 0xff, 0x89, 0x44, 0x04, 0x89, 0x54, 0x02,
- 0x5e, 0x5d, 0xc3, 0xc8, 0x04, 0x00, 0x00, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x46,
- 0x08, 0x8b, 0x56, 0x06, 0x81, 0xe2, 0x00, 0x80, 0x25, 0x07, 0x00, 0x89, 0x56,
- 0xfc, 0x89, 0x46, 0xfe, 0xb9, 0x06, 0x00, 0xbb, 0x4c, 0x2c, 0x2e, 0x8b, 0x07,
- 0x3b, 0x46, 0xfc, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x0c, 0x3b, 0x46, 0xfe, 0x74,
- 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x54, 0x2e, 0xff, 0x67, 0x18, 0x6a,
- 0x01, 0x6a, 0x01, 0xe8, 0xd9, 0xea, 0x83, 0xc4, 0x04, 0xeb, 0x20, 0x6a, 0x01,
- 0x6a, 0x04, 0xeb, 0xf2, 0x6a, 0x01, 0x6a, 0x00, 0xeb, 0xec, 0x6a, 0x01, 0x6a,
- 0x05, 0xeb, 0xe6, 0x6a, 0x01, 0x6a, 0x02, 0xeb, 0xe0, 0x6a, 0x01, 0x6a, 0x06,
- 0xeb, 0xda, 0xeb, 0x24, 0x8b, 0x44, 0x04, 0x8b, 0x54, 0x02, 0x81, 0xe2, 0xff,
- 0x7f, 0x25, 0xf8, 0xff, 0x8b, 0x5e, 0x08, 0x8b, 0x4e, 0x06, 0x81, 0xe1, 0x00,
- 0x80, 0x83, 0xe3, 0x07, 0x0b, 0xd1, 0x0b, 0xc3, 0x89, 0x44, 0x04, 0x89, 0x54,
- 0x02, 0x5e, 0xc9, 0xc3, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00,
- 0x03, 0x00, 0x0b, 0x2c, 0xf9, 0x2b, 0x17, 0x2c, 0x05, 0x2c, 0x11, 0x2c, 0x1d,
- 0x2c, 0x55, 0x8b, 0xec, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x5d, 0xc3, 0xc8, 0x04,
- 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x06, 0x8b, 0x44, 0x12, 0x8b, 0x54, 0x10,
- 0x89, 0x56, 0xfc, 0x89, 0x46, 0xfe, 0xb9, 0x01, 0x00, 0xbb, 0xdb, 0x2c, 0x2e,
- 0x8b, 0x07, 0x3b, 0x46, 0xfc, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x02, 0x3b, 0x46,
- 0xfe, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x2a, 0x2e, 0xff, 0x67,
- 0x04, 0xeb, 0x24, 0x8b, 0xfe, 0xa1, 0xcc, 0x01, 0x8b, 0x16, 0xca, 0x01, 0x89,
- 0x45, 0x16, 0x89, 0x55, 0x14, 0x57, 0x6a, 0x18, 0xe8, 0x19, 0xe4, 0x83, 0xc4,
- 0x04, 0xc7, 0x06, 0xcc, 0x01, 0x00, 0x00, 0xc7, 0x06, 0xca, 0x01, 0x00, 0x00,
- 0x5f, 0x5e, 0xc9, 0xc3, 0x07, 0x00, 0x00, 0x00, 0xb3, 0x2c, 0xc8, 0x1c, 0x04,
- 0x00, 0x56, 0x8b, 0x76, 0x04, 0xc7, 0x86, 0xe6, 0xfb, 0x00, 0x00, 0xc7, 0x86,
- 0xe4, 0xfb, 0x0a, 0x10, 0x8b, 0x04, 0x99, 0x89, 0x96, 0xea, 0xfb, 0x89, 0x86,
- 0xe8, 0xfb, 0xc7, 0x86, 0xee, 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xec, 0xfb, 0x00,
- 0x00, 0xc7, 0x86, 0xf6, 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xf4, 0xfb, 0x04, 0x00,
- 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x89, 0x86, 0xfa, 0xfb, 0x89, 0x96, 0xf8,
- 0xfb, 0x8d, 0x86, 0xe4, 0xfb, 0x50, 0x68, 0x1c, 0x04, 0xe8, 0xb0, 0xe3, 0x83,
- 0xc4, 0x04, 0x5e, 0xc9, 0xc3, 0xc8, 0x1c, 0x04, 0x00, 0x56, 0x8b, 0x76, 0x04,
- 0xc7, 0x86, 0xe6, 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xe4, 0xfb, 0x0a, 0x10, 0x8b,
- 0x04, 0x99, 0x89, 0x96, 0xea, 0xfb, 0x89, 0x86, 0xe8, 0xfb, 0xc7, 0x86, 0xee,
- 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xec, 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xf6, 0xfb,
- 0x00, 0x00, 0xc7, 0x86, 0xf4, 0xfb, 0x02, 0x00, 0x8b, 0x44, 0x0c, 0x8b, 0x54,
- 0x0a, 0x89, 0x86, 0xfa, 0xfb, 0x89, 0x96, 0xf8, 0xfb, 0x8d, 0x86, 0xe4, 0xfb,
- 0x50, 0x68, 0x1c, 0x04, 0xe8, 0x5a, 0xe3, 0x83, 0xc4, 0x04, 0x5e, 0xc9, 0xc3,
- 0xc8, 0x1c, 0x04, 0x00, 0x56, 0x8b, 0x76, 0x04, 0xc7, 0x86, 0xe6, 0xfb, 0x00,
- 0x00, 0xc7, 0x86, 0xe4, 0xfb, 0x0a, 0x10, 0x8b, 0x04, 0x99, 0x89, 0x96, 0xea,
- 0xfb, 0x89, 0x86, 0xe8, 0xfb, 0xc7, 0x86, 0xee, 0xfb, 0x00, 0x00, 0xc7, 0x86,
- 0xec, 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xf6, 0xfb, 0x00, 0x00, 0xc7, 0x86, 0xf4,
- 0xfb, 0x01, 0x00, 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x89, 0x86, 0xfa, 0xfb,
- 0x89, 0x96, 0xf8, 0xfb, 0x8d, 0x86, 0xe4, 0xfb, 0x50, 0x68, 0x1c, 0x04, 0xe8,
- 0x04, 0xe3, 0x83, 0xc4, 0x04, 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0xbe,
- 0x9c, 0x03, 0x81, 0x64, 0x02, 0xff, 0xef, 0x83, 0x64, 0x04, 0xff, 0xf6, 0x46,
- 0x04, 0x80, 0x74, 0x15, 0x81, 0x4c, 0x02, 0x00, 0x10, 0x83, 0x4c, 0x04, 0x00,
- 0x8b, 0x1c, 0xd1, 0xe3, 0x81, 0xa7, 0x08, 0x80, 0x7f, 0xff, 0xeb, 0x74, 0x83,
- 0x4c, 0x02, 0x00, 0x83, 0x4c, 0x04, 0x00, 0x8b, 0x1c, 0xd1, 0xe3, 0x81, 0x8f,
- 0x08, 0x80, 0x80, 0x00, 0x81, 0x64, 0x02, 0xff, 0x9f, 0x83, 0x64, 0x04, 0xff,
- 0xf6, 0x46, 0x04, 0x40, 0x74, 0x07, 0x81, 0x4c, 0x02, 0x00, 0x40, 0xeb, 0x05,
- 0x81, 0x4c, 0x02, 0x00, 0x20, 0x83, 0x4c, 0x04, 0x00, 0x83, 0x64, 0x06, 0xf8,
- 0x83, 0x64, 0x08, 0xff, 0x8a, 0x4e, 0x04, 0x80, 0xe1, 0x38, 0x8a, 0xc1, 0xb4,
- 0x00, 0xc1, 0xf8, 0x03, 0x8a, 0xc8, 0xb4, 0x00, 0x99, 0x09, 0x44, 0x06, 0x09,
- 0x54, 0x08, 0x83, 0x64, 0x06, 0xfb, 0x83, 0x64, 0x08, 0xff, 0x8a, 0x46, 0x04,
- 0xb4, 0x00, 0x25, 0x20, 0x00, 0x3d, 0x20, 0x00, 0x75, 0x06, 0x83, 0x4c, 0x06,
- 0x00, 0xeb, 0x04, 0x83, 0x4c, 0x06, 0x04, 0x83, 0x4c, 0x08, 0x00, 0x5e, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8a, 0x4e, 0x04, 0xbe, 0x9c, 0x03, 0x8b, 0x44,
- 0x02, 0x25, 0x00, 0x10, 0x33, 0xd2, 0x0b, 0xd2, 0x75, 0x24, 0x3d, 0x00, 0x10,
- 0x75, 0x1f, 0x8a, 0xc1, 0xb4, 0x00, 0xc1, 0xf8, 0x03, 0x24, 0x07, 0x8a, 0xc8,
- 0x04, 0xfd, 0x8a, 0xc8, 0xb4, 0x00, 0x69, 0xc0, 0x85, 0x00, 0x05, 0x0a, 0x00,
- 0x99, 0x89, 0x54, 0x08, 0x89, 0x44, 0x06, 0x81, 0x64, 0x02, 0x3f, 0xfe, 0x83,
- 0x64, 0x04, 0xff, 0xf6, 0xc1, 0x40, 0x74, 0x06, 0x83, 0x4c, 0x02, 0x00, 0xeb,
- 0x04, 0x83, 0x4c, 0x02, 0x40, 0x83, 0x4c, 0x04, 0x00, 0x5e, 0x5d, 0xc3, 0xc8,
- 0x08, 0x00, 0x00, 0xc6, 0x06, 0x1f, 0x02, 0x00, 0x8b, 0x46, 0x04, 0x25, 0xc0,
- 0x01, 0x89, 0x46, 0xfc, 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xb9, 0x03, 0x00, 0xbb,
- 0x81, 0x2f, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfc, 0x75, 0x09, 0x2e, 0x8b, 0x47,
- 0x06, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x17,
- 0x2e, 0xff, 0x67, 0x0c, 0xc6, 0x06, 0x1f, 0x02, 0x60, 0xeb, 0x0c, 0xc6, 0x06,
- 0x1f, 0x02, 0x00, 0xeb, 0x05, 0xc6, 0x06, 0x1f, 0x02, 0x40, 0x8b, 0x46, 0x04,
- 0x25, 0x00, 0x0e, 0x89, 0x46, 0xf8, 0xc7, 0x46, 0xfa, 0x00, 0x00, 0xb9, 0x03,
- 0x00, 0xbb, 0x6f, 0x2f, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xf8, 0x75, 0x09, 0x2e,
- 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xfa, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea,
- 0xeb, 0x17, 0x2e, 0xff, 0x67, 0x0c, 0x80, 0x0e, 0x1f, 0x02, 0x01, 0xeb, 0x0c,
- 0x80, 0x0e, 0x1f, 0x02, 0x00, 0xeb, 0x05, 0x80, 0x0e, 0x1f, 0x02, 0x09, 0xc9,
- 0xc3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5a, 0x2f, 0x61, 0x2f, 0x68, 0x2f, 0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x2f, 0x1e, 0x2f, 0x25, 0x2f, 0x55, 0x8b,
- 0xec, 0x56, 0x57, 0x8b, 0x5e, 0x04, 0x8b, 0x07, 0x0b, 0xc0, 0x74, 0x07, 0x3d,
- 0x01, 0x00, 0x74, 0x07, 0xeb, 0x0a, 0xbf, 0x00, 0x88, 0xeb, 0x09, 0xbf, 0x00,
- 0x90, 0xeb, 0x04, 0x33, 0xc0, 0xeb, 0x6c, 0xc7, 0x85, 0x96, 0x00, 0x08, 0x00,
- 0xc7, 0x85, 0x96, 0x00, 0x00, 0x00, 0x33, 0xf6, 0xeb, 0x01, 0x46, 0x81, 0xfe,
- 0x10, 0x27, 0x7c, 0xf9, 0x33, 0xf6, 0xeb, 0x18, 0x8a, 0x84, 0x1e, 0x02, 0x8b,
- 0x5e, 0x04, 0x03, 0xde, 0x88, 0x87, 0xc8, 0x0e, 0xb4, 0x00, 0x8b, 0xde, 0xd1,
- 0xe3, 0x89, 0x81, 0x80, 0x00, 0x46, 0x83, 0xfe, 0x20, 0x7c, 0xe3, 0x33, 0xf6,
- 0xeb, 0x0e, 0xa0, 0x92, 0x12, 0xb4, 0x00, 0x8b, 0xde, 0xd1, 0xe3, 0x89, 0x81,
- 0xc0, 0x00, 0x46, 0x83, 0xfe, 0x20, 0x7c, 0xed, 0xff, 0x76, 0x04, 0xe8, 0x6c,
- 0x06, 0x59, 0xff, 0x76, 0x04, 0xe8, 0x9d, 0x06, 0x59, 0x6a, 0x20, 0x6a, 0x00,
- 0x68, 0xa0, 0x80, 0xe8, 0xec, 0x1d, 0x83, 0xc4, 0x06, 0x8b, 0xc7, 0x5f, 0x5e,
- 0x5d, 0xc3, 0xc8, 0x18, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8b, 0xbc,
- 0xc6, 0x0e, 0x8a, 0x44, 0x23, 0xb4, 0x00, 0x40, 0xbb, 0x04, 0x00, 0x99, 0xf7,
- 0xfb, 0x88, 0x54, 0x23, 0xff, 0x44, 0x2e, 0x8b, 0x44, 0x2e, 0x3d, 0x84, 0x03,
- 0x7e, 0x34, 0xc7, 0x44, 0x2e, 0x01, 0x00, 0x56, 0xe8, 0x59, 0x05, 0x59, 0x80,
- 0x7c, 0x2d, 0x00, 0x75, 0x0a, 0x80, 0x7c, 0x2c, 0x00, 0x75, 0x04, 0xc6, 0x44,
- 0x2d, 0x01, 0x6a, 0x18, 0x6a, 0x00, 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x6b, 0xc0,
- 0x18, 0x8b, 0xd6, 0x03, 0xd0, 0x83, 0xc2, 0x30, 0x52, 0xe8, 0x8b, 0x1d, 0x83,
- 0xc4, 0x06, 0x8a, 0x44, 0x23, 0xb4, 0x00, 0xd1, 0xe0, 0x8b, 0xd6, 0x03, 0xd0,
- 0x83, 0xc2, 0x24, 0x89, 0x56, 0xfc, 0x8b, 0x5e, 0xfc, 0xc6, 0x07, 0x00, 0x8a,
- 0x44, 0x23, 0x88, 0x47, 0x01, 0x8b, 0x44, 0x0a, 0x25, 0x03, 0x00, 0x33, 0xd2,
- 0x0b, 0xd2, 0x75, 0x09, 0x3d, 0x02, 0x00, 0x75, 0x04, 0x80, 0x4f, 0x01, 0x20,
- 0x8a, 0x45, 0x06, 0x88, 0x46, 0xf8, 0xa8, 0x40, 0x74, 0x06, 0x6a, 0x00, 0x6a,
- 0x01, 0xeb, 0x0a, 0xf6, 0x46, 0xf8, 0x80, 0x74, 0x0b, 0x6a, 0x00, 0x6a, 0x00,
- 0x56, 0xe8, 0xba, 0x03, 0x83, 0xc4, 0x06, 0x8b, 0x44, 0x20, 0x8b, 0x54, 0x1e,
- 0x89, 0x46, 0xf0, 0x89, 0x56, 0xee, 0x8a, 0x05, 0x88, 0x46, 0xfb, 0xb4, 0x00,
- 0xa9, 0x47, 0x00, 0x75, 0x25, 0x8b, 0x44, 0x1e, 0x25, 0x02, 0x00, 0x0d, 0x00,
- 0x00, 0x74, 0x0f, 0xf7, 0x45, 0x04, 0x01, 0x00, 0x75, 0x08, 0x83, 0x64, 0x1e,
- 0xfd, 0x83, 0x64, 0x20, 0xff, 0x83, 0x64, 0x1e, 0xbf, 0x83, 0x64, 0x20, 0xff,
- 0xe9, 0x45, 0x02, 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd6,
- 0x03, 0xd0, 0x83, 0xc2, 0x30, 0x89, 0x56, 0xfe, 0x8b, 0x04, 0xc1, 0xe0, 0x04,
- 0x05, 0xa0, 0x80, 0x89, 0x46, 0xe8, 0x8a, 0x45, 0x02, 0x88, 0x46, 0xfa, 0xa8,
- 0x09, 0x74, 0x07, 0x8b, 0x5e, 0xfc, 0x80, 0x4f, 0x01, 0x40, 0x8a, 0x45, 0x04,
- 0x88, 0x46, 0xf9, 0xa8, 0x01, 0x74, 0x0a, 0x83, 0x4c, 0x1e, 0x02, 0x83, 0x4c,
- 0x20, 0x00, 0xeb, 0x08, 0x83, 0x64, 0x1e, 0xfd, 0x83, 0x64, 0x20, 0xff, 0xf6,
- 0x46, 0xf8, 0x01, 0x74, 0x31, 0x8b, 0x5e, 0xfc, 0x80, 0x0f, 0x40, 0x8b, 0x5e,
- 0xfe, 0xff, 0x47, 0x0e, 0x8b, 0x45, 0x24, 0x25, 0xff, 0x00, 0xc1, 0xe0, 0x08,
- 0x8b, 0x55, 0x26, 0x81, 0xe2, 0xff, 0x00, 0x0b, 0xd0, 0x89, 0x56, 0xea, 0x8b,
- 0x46, 0xea, 0x01, 0x47, 0x10, 0x83, 0x57, 0x12, 0x00, 0x8b, 0x5e, 0xe8, 0x01,
- 0x47, 0x0e, 0x8a, 0x46, 0xf8, 0xb4, 0x00, 0x8b, 0x5e, 0xfc, 0x8a, 0x57, 0x01,
- 0xb6, 0x00, 0x83, 0xe2, 0x40, 0xf7, 0xda, 0x1b, 0xd2, 0x42, 0x23, 0xc2, 0xa9,
- 0x02, 0x00, 0x74, 0x10, 0x80, 0x4f, 0x01, 0x80, 0x8b, 0x45, 0x28, 0x25, 0xff,
- 0x00, 0x8b, 0x5e, 0xe8, 0x01, 0x47, 0x0c, 0xf6, 0x46, 0xf8, 0x18, 0x74, 0x0c,
- 0x8b, 0x5e, 0xfc, 0x80, 0x0f, 0x02, 0x8b, 0x5e, 0xfe, 0xff, 0x47, 0x08, 0x8b,
- 0x45, 0x0c, 0x25, 0xff, 0x00, 0xc1, 0xe0, 0x08, 0x8b, 0x55, 0x0e, 0x81, 0xe2,
- 0xff, 0x00, 0x0b, 0xd0, 0x89, 0x56, 0xf4, 0x8b, 0xc2, 0x0b, 0xc0, 0x74, 0x65,
- 0x83, 0x7e, 0xf4, 0x01, 0x75, 0x09, 0x8b, 0x5e, 0xfc, 0x80, 0x4f, 0x01, 0x10,
- 0xeb, 0x40, 0x83, 0x7e, 0xf4, 0x05, 0x7f, 0x09, 0x8b, 0x5e, 0xfc, 0x80, 0x4f,
- 0x01, 0x04, 0xeb, 0x31, 0x83, 0x7e, 0xf4, 0x0a, 0x7f, 0x08, 0x8b, 0x5e, 0xfc,
- 0x80, 0x0f, 0x80, 0xeb, 0x23, 0x83, 0x7e, 0xf4, 0x64, 0x7f, 0x08, 0x8b, 0x5e,
- 0xfc, 0x80, 0x0f, 0x20, 0xeb, 0x15, 0x81, 0x7e, 0xf4, 0x3f, 0x01, 0x7f, 0x08,
- 0x8b, 0x5e, 0xfc, 0x80, 0x0f, 0x04, 0xeb, 0x06, 0x8b, 0x5e, 0xfc, 0x80, 0x0f,
- 0x01, 0x8b, 0x46, 0xf4, 0x99, 0x8b, 0x5e, 0xfe, 0x01, 0x47, 0x14, 0x11, 0x57,
- 0x16, 0x8b, 0x5e, 0xe8, 0x8b, 0x46, 0xf4, 0x01, 0x47, 0x02, 0x8a, 0x45, 0x08,
- 0x88, 0x46, 0xf7, 0xa8, 0x01, 0x74, 0x1c, 0x8b, 0x45, 0x16, 0x25, 0xff, 0x00,
- 0x89, 0x46, 0xea, 0x8a, 0x45, 0x14, 0x88, 0x46, 0xed, 0x8b, 0x5e, 0xfe, 0x8b,
- 0x46, 0xea, 0x01, 0x07, 0x8b, 0x5e, 0xe8, 0x01, 0x07, 0xf6, 0x46, 0xf7, 0x02,
- 0x74, 0x1e, 0x8b, 0x45, 0x1a, 0x25, 0xff, 0x00, 0x89, 0x46, 0xea, 0x8a, 0x45,
- 0x18, 0x88, 0x46, 0xed, 0x8b, 0x5e, 0xfe, 0x8b, 0x46, 0xea, 0x01, 0x47, 0x04,
- 0x8b, 0x5e, 0xe8, 0x01, 0x47, 0x04, 0xf6, 0x46, 0xf7, 0x04, 0x74, 0x1e, 0x8b,
- 0x45, 0x1e, 0x25, 0xff, 0x00, 0x89, 0x46, 0xea, 0x8a, 0x45, 0x1c, 0x88, 0x46,
- 0xed, 0x8b, 0x5e, 0xfe, 0x8b, 0x46, 0xea, 0x01, 0x47, 0x06, 0x8b, 0x5e, 0xe8,
- 0x01, 0x47, 0x08, 0xf6, 0x46, 0xfa, 0x40, 0x74, 0x2a, 0x8b, 0x45, 0x22, 0x25,
- 0xff, 0x00, 0x89, 0x46, 0xea, 0x8a, 0x45, 0x20, 0x88, 0x46, 0xed, 0x8b, 0x5e,
- 0xfe, 0x8b, 0x46, 0xea, 0x01, 0x47, 0x02, 0x8b, 0x5e, 0xe8, 0x01, 0x47, 0x0a,
- 0xff, 0x76, 0xfe, 0x56, 0xe8, 0xda, 0x03, 0x83, 0xc4, 0x04, 0xeb, 0x08, 0x83,
- 0x64, 0x1e, 0xbf, 0x83, 0x64, 0x20, 0xff, 0x8b, 0x45, 0x10, 0x25, 0xff, 0x00,
- 0xc1, 0xe0, 0x08, 0x8b, 0x55, 0x12, 0x81, 0xe2, 0xff, 0x00, 0x0b, 0xd0, 0x89,
- 0x56, 0xf2, 0x8b, 0xc2, 0x0b, 0xc0, 0x74, 0x35, 0x8b, 0x46, 0xf2, 0x99, 0x01,
- 0x84, 0x70, 0x09, 0x8b, 0x84, 0x70, 0x09, 0x11, 0x94, 0x72, 0x09, 0x8b, 0x94,
- 0x72, 0x09, 0x83, 0xfa, 0x0f, 0x72, 0x13, 0x77, 0x05, 0x3d, 0x40, 0x42, 0x76,
- 0x0c, 0xc7, 0x84, 0x72, 0x09, 0x0f, 0x00, 0xc7, 0x84, 0x70, 0x09, 0x40, 0x42,
- 0x8b, 0x5e, 0xe8, 0x8b, 0x46, 0xf2, 0x01, 0x47, 0x06, 0x8b, 0x44, 0x1a, 0x25,
- 0x01, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x05, 0x56, 0xe8, 0x38, 0xfa, 0x59, 0xa0,
- 0x1e, 0x02, 0x88, 0x84, 0xc8, 0x0e, 0xb4, 0x00, 0x89, 0x85, 0x80, 0x00, 0x83,
- 0x64, 0x0a, 0xe7, 0x83, 0x64, 0x0c, 0xff, 0x8b, 0x44, 0x1e, 0x25, 0x07, 0x00,
- 0x0d, 0x00, 0x00, 0x74, 0x2a, 0x8b, 0x44, 0x1e, 0x25, 0x04, 0x00, 0x0d, 0x00,
- 0x00, 0x74, 0x06, 0x83, 0x4c, 0x0a, 0x18, 0xeb, 0x15, 0x8b, 0x44, 0x1e, 0x25,
- 0x02, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x06, 0x83, 0x4c, 0x0a, 0x08, 0xeb, 0x04,
- 0x83, 0x4c, 0x0a, 0x10, 0x83, 0x4c, 0x0c, 0x00, 0x56, 0xe8, 0xeb, 0x09, 0x59,
- 0x8b, 0x44, 0x1a, 0x25, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x19, 0x8b, 0x44,
- 0x20, 0x8b, 0x54, 0x1e, 0x33, 0x56, 0xee, 0x33, 0x46, 0xf0, 0x83, 0xe2, 0x07,
- 0x83, 0xca, 0x00, 0x74, 0x05, 0x56, 0xe8, 0x6f, 0xf9, 0x59, 0x5f, 0x5e, 0xc9,
- 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x9c, 0xc6, 0x0e, 0x33,
- 0xc0, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x83, 0x7e,
- 0x06, 0x00, 0x74, 0x24, 0x80, 0x8c, 0xcb, 0x0e, 0x01, 0x83, 0x4c, 0x1e, 0x10,
- 0x83, 0x4c, 0x20, 0x00, 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x83, 0xe2, 0x9f,
- 0x83, 0xca, 0x20, 0x25, 0xff, 0xff, 0x89, 0x44, 0x0c, 0x89, 0x54, 0x0a, 0xeb,
- 0x15, 0x80, 0xa4, 0xcb, 0x0e, 0xfe, 0x83, 0x64, 0x1e, 0xef, 0x83, 0x64, 0x20,
- 0xff, 0x83, 0x64, 0x0a, 0x9f, 0x83, 0x64, 0x0c, 0xff, 0x8a, 0x84, 0xcb, 0x0e,
- 0xb4, 0x00, 0x8b, 0x9c, 0xc6, 0x0e, 0x89, 0x87, 0x86, 0x00, 0x5e, 0x5d, 0xc3,
- 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x83, 0x7e, 0x06, 0x00, 0x74, 0x24,
- 0x80, 0x8c, 0xcb, 0x0e, 0x20, 0x83, 0x4c, 0x1e, 0x20, 0x83, 0x4c, 0x20, 0x00,
- 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x83, 0xe2, 0x9f, 0x83, 0xca, 0x40, 0x25,
- 0xff, 0xff, 0x89, 0x44, 0x0c, 0x89, 0x54, 0x0a, 0xeb, 0x15, 0x80, 0xa4, 0xcb,
- 0x0e, 0xdf, 0x83, 0x64, 0x1e, 0xdf, 0x83, 0x64, 0x20, 0xff, 0x83, 0x64, 0x0a,
- 0x9f, 0x83, 0x64, 0x0c, 0xff, 0x8a, 0x84, 0xcb, 0x0e, 0xb4, 0x00, 0x8b, 0x9c,
- 0xc6, 0x0e, 0x89, 0x87, 0x86, 0x00, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56,
- 0x8b, 0x76, 0x04, 0x8b, 0x44, 0x0a, 0x25, 0x03, 0x00, 0x33, 0xd2, 0x33, 0x46,
- 0x06, 0x33, 0x56, 0x08, 0x0b, 0xc2, 0x74, 0x76, 0x8b, 0x46, 0x06, 0x0b, 0x46,
- 0x08, 0x74, 0x3a, 0x8a, 0x84, 0xcc, 0x0e, 0x24, 0xcf, 0x0c, 0x10, 0x88, 0x84,
- 0xcc, 0x0e, 0x8a, 0x84, 0xcc, 0x0e, 0xb4, 0x00, 0x8b, 0x9c, 0xc6, 0x0e, 0x89,
- 0x87, 0x88, 0x00, 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x83, 0xe2, 0xfc, 0x83,
- 0xca, 0x01, 0x25, 0xff, 0xff, 0x89, 0x44, 0x0c, 0x89, 0x54, 0x0a, 0x8b, 0x1c,
- 0xd1, 0xe3, 0x83, 0x8f, 0x08, 0x80, 0x40, 0xeb, 0x24, 0x80, 0xa4, 0xcc, 0x0e,
- 0xcf, 0x8a, 0x84, 0xcc, 0x0e, 0xb4, 0x00, 0x8b, 0x9c, 0xc6, 0x0e, 0x89, 0x87,
- 0x88, 0x00, 0x83, 0x64, 0x0a, 0xfc, 0x83, 0x64, 0x0c, 0xff, 0x8b, 0x1c, 0xd1,
- 0xe3, 0x83, 0xa7, 0x08, 0x80, 0xbf, 0x8b, 0x44, 0x1a, 0x25, 0x04, 0x00, 0x0d,
- 0x00, 0x00, 0x74, 0x05, 0x56, 0xe8, 0xc8, 0xf7, 0x59, 0x5e, 0x5d, 0xc3, 0x55,
- 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x44, 0x0a, 0x25, 0x03, 0x00, 0x33,
- 0xd2, 0x33, 0x46, 0x06, 0x33, 0x56, 0x08, 0x0b, 0xc2, 0x74, 0x76, 0x8b, 0x46,
- 0x06, 0x0b, 0x46, 0x08, 0x74, 0x3a, 0x8a, 0x84, 0xcc, 0x0e, 0x24, 0xcf, 0x0c,
- 0x20, 0x88, 0x84, 0xcc, 0x0e, 0x8a, 0x84, 0xcc, 0x0e, 0xb4, 0x00, 0x8b, 0x9c,
- 0xc6, 0x0e, 0x89, 0x87, 0x88, 0x00, 0x8b, 0x44, 0x0c, 0x8b, 0x54, 0x0a, 0x83,
- 0xe2, 0xfc, 0x83, 0xca, 0x02, 0x25, 0xff, 0xff, 0x89, 0x44, 0x0c, 0x89, 0x54,
- 0x0a, 0x8b, 0x1c, 0xd1, 0xe3, 0x83, 0x8f, 0x08, 0x80, 0x40, 0xeb, 0x24, 0x80,
- 0xa4, 0xcc, 0x0e, 0xcf, 0x8a, 0x84, 0xcc, 0x0e, 0xb4, 0x00, 0x8b, 0x9c, 0xc6,
- 0x0e, 0x89, 0x87, 0x88, 0x00, 0x83, 0x64, 0x0a, 0xfc, 0x83, 0x64, 0x0c, 0xff,
- 0x8b, 0x1c, 0xd1, 0xe3, 0x83, 0xa7, 0x08, 0x80, 0xbf, 0x8b, 0x44, 0x1a, 0x25,
- 0x04, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x05, 0x56, 0xe8, 0x36, 0xf7, 0x59, 0x5e,
- 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8a, 0x44, 0x2c,
- 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd6, 0x03, 0xd0, 0x83, 0xc2, 0x30, 0x8b,
- 0xca, 0x8a, 0x44, 0x2c, 0xfe, 0x44, 0x2c, 0x3c, 0x60, 0x72, 0x04, 0xc6, 0x44,
- 0x2c, 0x00, 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd6, 0x03,
- 0xd0, 0x83, 0xc2, 0x30, 0x8b, 0xfa, 0x8b, 0xd9, 0x8b, 0x07, 0x2b, 0x05, 0x01,
- 0x84, 0x48, 0x09, 0x83, 0x94, 0x4a, 0x09, 0x00, 0x8b, 0x47, 0x02, 0x2b, 0x45,
- 0x02, 0x01, 0x84, 0x4c, 0x09, 0x83, 0x94, 0x4e, 0x09, 0x00, 0x8b, 0x47, 0x04,
- 0x2b, 0x45, 0x04, 0x01, 0x84, 0x50, 0x09, 0x83, 0x94, 0x52, 0x09, 0x00, 0x8b,
- 0x47, 0x06, 0x2b, 0x45, 0x06, 0x01, 0x84, 0x54, 0x09, 0x83, 0x94, 0x56, 0x09,
- 0x00, 0x8b, 0x47, 0x08, 0x2b, 0x45, 0x08, 0x01, 0x84, 0x58, 0x09, 0x83, 0x94,
- 0x5a, 0x09, 0x00, 0x8b, 0x47, 0x0a, 0x2b, 0x45, 0x0a, 0x01, 0x84, 0x5c, 0x09,
- 0x83, 0x94, 0x5e, 0x09, 0x00, 0x8b, 0x47, 0x0c, 0x2b, 0x45, 0x0c, 0x01, 0x84,
- 0x60, 0x09, 0x83, 0x94, 0x62, 0x09, 0x00, 0x8b, 0x47, 0x0e, 0x2b, 0x45, 0x0e,
- 0x01, 0x84, 0x64, 0x09, 0x83, 0x94, 0x66, 0x09, 0x00, 0x8b, 0x47, 0x16, 0x8b,
- 0x57, 0x14, 0x2b, 0x55, 0x14, 0x1b, 0x45, 0x16, 0x01, 0x94, 0x6c, 0x09, 0x11,
- 0x84, 0x6e, 0x09, 0x5f, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76,
- 0x04, 0xc6, 0x44, 0x2c, 0x00, 0xc7, 0x44, 0x2e, 0x01, 0x00, 0xc6, 0x44, 0x2d,
- 0x00, 0x68, 0x18, 0x09, 0x6a, 0x00, 0x8b, 0xc6, 0x05, 0x30, 0x00, 0x50, 0xe8,
- 0x70, 0x17, 0x83, 0xc4, 0x06, 0x6a, 0x28, 0x6a, 0x00, 0x8b, 0xc6, 0x05, 0x48,
- 0x09, 0x50, 0xe8, 0x60, 0x17, 0x83, 0xc4, 0x06, 0x5e, 0x5d, 0xc3, 0x55, 0x8b,
- 0xec, 0x8b, 0x5e, 0x04, 0xc7, 0x87, 0x72, 0x09, 0x00, 0x00, 0xc7, 0x87, 0x70,
- 0x09, 0x00, 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b, 0x7e, 0x04,
- 0x8b, 0x76, 0x06, 0x8b, 0x45, 0x1e, 0x25, 0x40, 0x00, 0x0d, 0x00, 0x00, 0x75,
- 0x7a, 0x83, 0x7d, 0x2e, 0x0a, 0x7d, 0x05, 0x8b, 0x45, 0x2e, 0xeb, 0x03, 0xb8,
- 0x0a, 0x00, 0x8b, 0xc8, 0x39, 0x4c, 0x06, 0x73, 0x05, 0x8b, 0x44, 0x06, 0xeb,
- 0x02, 0x8b, 0xc1, 0x29, 0x44, 0x06, 0x83, 0xf9, 0x0a, 0x74, 0x4e, 0xb8, 0x0a,
- 0x00, 0x2b, 0xc1, 0x8b, 0xc8, 0x8b, 0xc6, 0x83, 0xee, 0x18, 0x8b, 0xd7, 0x83,
- 0xc2, 0x30, 0x3b, 0xc2, 0x75, 0x04, 0x81, 0xc6, 0x18, 0x09, 0x39, 0x4c, 0x06,
- 0x73, 0x05, 0x8b, 0x44, 0x06, 0xeb, 0x02, 0x8b, 0xc1, 0x29, 0x44, 0x06, 0x8b,
- 0xc1, 0x99, 0x3b, 0x95, 0x56, 0x09, 0x72, 0x12, 0x77, 0x06, 0x3b, 0x85, 0x54,
- 0x09, 0x76, 0x0a, 0x8b, 0x95, 0x56, 0x09, 0x8b, 0x85, 0x54, 0x09, 0xeb, 0x03,
- 0x8b, 0xc1, 0x99, 0x29, 0x85, 0x54, 0x09, 0x19, 0x95, 0x56, 0x09, 0x83, 0x4d,
- 0x1e, 0x40, 0x83, 0x4d, 0x20, 0x00, 0x5f, 0x5e, 0x5d, 0xc3, 0xc8, 0x04, 0x00,
- 0x00, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x46, 0x06, 0x25, 0x00, 0x0e, 0x89, 0x46,
- 0xfc, 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xb9, 0x03, 0x00, 0xbb, 0x1d, 0x38, 0x2e,
- 0x8b, 0x07, 0x3b, 0x46, 0xfc, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x06, 0x3b, 0x46,
- 0xfe, 0x74, 0x08, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xe9, 0x8e, 0x00, 0x2e, 0xff,
- 0x67, 0x0c, 0x80, 0xa4, 0xc9, 0x0e, 0xe0, 0x80, 0x8c, 0xc9, 0x0e, 0x01, 0x8a,
- 0x84, 0xc9, 0x0e, 0xb4, 0x00, 0x8b, 0x9c, 0xc6, 0x0e, 0x89, 0x87, 0x82, 0x00,
- 0x8b, 0x1c, 0xd1, 0xe3, 0x83, 0x8f, 0x08, 0x80, 0x02, 0xeb, 0x48, 0x80, 0xa4,
- 0xc9, 0x0e, 0xe0, 0x80, 0x8c, 0xc9, 0x0e, 0x00, 0x8a, 0x84, 0xc9, 0x0e, 0xb4,
- 0x00, 0x8b, 0x9c, 0xc6, 0x0e, 0x89, 0x87, 0x82, 0x00, 0x8b, 0x1c, 0xd1, 0xe3,
- 0x83, 0xa7, 0x08, 0x80, 0xfd, 0xeb, 0x25, 0x80, 0xa4, 0xc9, 0x0e, 0xe0, 0x80,
- 0x8c, 0xc9, 0x0e, 0x09, 0x8a, 0x84, 0xc9, 0x0e, 0xb4, 0x00, 0x8b, 0x9c, 0xc6,
- 0x0e, 0x89, 0x87, 0x82, 0x00, 0x8b, 0x1c, 0xd1, 0xe3, 0x83, 0x8f, 0x08, 0x80,
- 0xfd, 0xeb, 0x02, 0xeb, 0x1f, 0x8b, 0x44, 0x04, 0x8b, 0x54, 0x02, 0x81, 0xe2,
- 0xff, 0xf1, 0x25, 0xff, 0xff, 0x8b, 0x5e, 0x06, 0x81, 0xe3, 0x00, 0x0e, 0x0b,
- 0xd3, 0x0d, 0x00, 0x00, 0x89, 0x44, 0x04, 0x89, 0x54, 0x02, 0x5e, 0xc9, 0xc3,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
- 0x37, 0xb3, 0x37, 0xd6, 0x37, 0xc8, 0x04, 0x00, 0x00, 0x56, 0x8b, 0x76, 0x04,
- 0x8b, 0x46, 0x06, 0x25, 0xc0, 0x01, 0x89, 0x46, 0xfc, 0xc7, 0x46, 0xfe, 0x00,
- 0x00, 0xb9, 0x03, 0x00, 0xbb, 0xe1, 0x38, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfc,
- 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x06, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83, 0xc3,
- 0x02, 0xe2, 0xea, 0xeb, 0x7b, 0x2e, 0xff, 0x67, 0x0c, 0x80, 0xa4, 0xc9, 0x0e,
- 0x1f, 0x80, 0x8c, 0xc9, 0x0e, 0x60, 0x8a, 0x84, 0xc9, 0x0e, 0xb4, 0x00, 0x8b,
- 0x9c, 0xc6, 0x0e, 0x89, 0x87, 0x82, 0x00, 0x8b, 0x1c, 0xd1, 0xe3, 0x83, 0x8f,
- 0x08, 0x80, 0x01, 0xeb, 0x35, 0x80, 0xa4, 0xc9, 0x0e, 0x1f, 0x80, 0x8c, 0xc9,
- 0x0e, 0x00, 0x8a, 0x84, 0xc9, 0x0e, 0xeb, 0x0e, 0x80, 0xa4, 0xc9, 0x0e, 0x1f,
- 0x80, 0x8c, 0xc9, 0x0e, 0x40, 0x8a, 0x84, 0xc9, 0x0e, 0xb4, 0x00, 0x8b, 0x9c,
- 0xc6, 0x0e, 0x89, 0x87, 0x82, 0x00, 0x8b, 0x1c, 0xd1, 0xe3, 0x83, 0xa7, 0x08,
- 0x80, 0xfe, 0xeb, 0x02, 0xeb, 0x1f, 0x8b, 0x44, 0x04, 0x8b, 0x54, 0x02, 0x81,
- 0xe2, 0x3f, 0xfe, 0x25, 0xff, 0xff, 0x8b, 0x5e, 0x06, 0x81, 0xe3, 0xc0, 0x01,
- 0x0b, 0xd3, 0x0d, 0x00, 0x00, 0x89, 0x44, 0x04, 0x89, 0x54, 0x02, 0x5e, 0xc9,
- 0xc3, 0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x67, 0x38, 0x8a, 0x38, 0x9a, 0x38, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04,
- 0x33, 0xc9, 0xeb, 0x25, 0x8b, 0xd9, 0x69, 0xdb, 0x0c, 0x01, 0xc7, 0x80, 0x86,
- 0x09, 0x00, 0x00, 0xc7, 0x80, 0x84, 0x09, 0x00, 0x00, 0x8b, 0xd9, 0x69, 0xdb,
- 0x0c, 0x01, 0xc7, 0x80, 0x8a, 0x09, 0x00, 0x00, 0xc7, 0x80, 0x88, 0x09, 0x00,
- 0x00, 0x41, 0x83, 0xf9, 0x04, 0x7c, 0xd6, 0xc7, 0x84, 0xb6, 0x0d, 0x00, 0x00,
- 0xc7, 0x84, 0xb4, 0x0d, 0x00, 0x00, 0xc7, 0x84, 0xba, 0x0d, 0x00, 0x00, 0xc7,
- 0x84, 0xb8, 0x0d, 0x00, 0x00, 0x33, 0xc0, 0x33, 0xd2, 0x89, 0x84, 0x7a, 0x09,
- 0x89, 0x94, 0x78, 0x09, 0x89, 0x84, 0x76, 0x09, 0x89, 0x94, 0x74, 0x09, 0xc7,
- 0x84, 0x82, 0x09, 0x00, 0x00, 0xc7, 0x84, 0x80, 0x09, 0x00, 0x00, 0xc7, 0x84,
- 0x7e, 0x09, 0x00, 0x00, 0xc7, 0x84, 0x7c, 0x09, 0x03, 0x00, 0xc6, 0x84, 0xea,
- 0x0e, 0x00, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x8b,
- 0x44, 0x02, 0x25, 0x00, 0x0e, 0x33, 0xd2, 0x0b, 0xd2, 0x75, 0x0a, 0x3d, 0x00,
- 0x02, 0x75, 0x05, 0x56, 0xe8, 0x04, 0x00, 0x59, 0x5e, 0x5d, 0xc3, 0xc8, 0x0e,
- 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04, 0xc6, 0x46, 0xf2, 0x38, 0xc6, 0x46,
- 0xf3, 0x01, 0xc6, 0x46, 0xf4, 0x03, 0x33, 0xff, 0x8a, 0x44, 0x23, 0xb4, 0x00,
- 0x89, 0x46, 0xfe, 0xeb, 0x1a, 0x8b, 0x5e, 0xfe, 0x83, 0xe3, 0x03, 0xd1, 0xe3,
- 0x8b, 0x40, 0x24, 0x8b, 0xdf, 0xd1, 0xe3, 0x8d, 0x56, 0xf5, 0x03, 0xda, 0x89,
- 0x07, 0x47, 0xff, 0x4e, 0xfe, 0x83, 0xff, 0x04, 0x72, 0xe1, 0x6a, 0x0b, 0x8d,
- 0x46, 0xf2, 0x50, 0x56, 0xe8, 0xa6, 0x00, 0x83, 0xc4, 0x06, 0x5f, 0x5e, 0xc9,
- 0xc3, 0xc8, 0x06, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x46, 0x04, 0x05, 0xb4, 0x0d,
- 0x8b, 0xf0, 0x83, 0x7c, 0x02, 0x00, 0x77, 0x0a, 0x73, 0x03, 0xe9, 0x82, 0x00,
- 0x83, 0x3c, 0x0a, 0x72, 0x7d, 0x83, 0x7c, 0x06, 0x00, 0x75, 0x0f, 0x83, 0x7c,
- 0x04, 0x01, 0x75, 0x09, 0x56, 0xff, 0x76, 0x04, 0xe8, 0xf7, 0x03, 0xeb, 0x65,
- 0xc7, 0x46, 0xfa, 0x01, 0x00, 0x8a, 0x44, 0x08, 0x88, 0x46, 0xfd, 0xc7, 0x46,
- 0xfe, 0x01, 0x00, 0x8b, 0xc6, 0x05, 0x09, 0x00, 0x8b, 0xf8, 0xeb, 0x2d, 0x8a,
- 0x05, 0x3a, 0x46, 0xfd, 0x74, 0x1f, 0x83, 0x7e, 0xfa, 0x0a, 0x7c, 0x0d, 0x8a,
- 0x46, 0xfd, 0x50, 0xff, 0x76, 0x04, 0xe8, 0xed, 0x01, 0x83, 0xc4, 0x04, 0xc7,
- 0x46, 0xfa, 0x00, 0x00, 0x8a, 0x05, 0x88, 0x46, 0xfd, 0xeb, 0x03, 0xff, 0x46,
- 0xfa, 0xff, 0x46, 0xfe, 0x47, 0x8b, 0x46, 0xfe, 0x99, 0x3b, 0x54, 0x02, 0x72,
- 0xca, 0x75, 0x04, 0x3b, 0x04, 0x72, 0xc4, 0x83, 0x7e, 0xfa, 0x0a, 0x7c, 0x0d,
- 0x8a, 0x46, 0xfd, 0x50, 0xff, 0x76, 0x04, 0xe8, 0xb8, 0x01, 0x83, 0xc4, 0x04,
- 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04,
- 0x8b, 0x7e, 0x08, 0x8b, 0x84, 0x76, 0x09, 0x8b, 0x94, 0x74, 0x09, 0x83, 0xc2,
- 0x01, 0x15, 0x00, 0x00, 0x83, 0xe2, 0x03, 0x33, 0xc0, 0x3b, 0x84, 0x7a, 0x09,
- 0x75, 0x0c, 0x3b, 0x94, 0x78, 0x09, 0x75, 0x06, 0xff, 0x06, 0x3e, 0x02, 0xeb,
- 0x5d, 0x8b, 0x84, 0x74, 0x09, 0x69, 0xc0, 0x0c, 0x01, 0x8b, 0xd6, 0x03, 0xd0,
- 0x81, 0xc2, 0x84, 0x09, 0x89, 0x56, 0xfe, 0x81, 0xff, 0x04, 0x01, 0x7e, 0x03,
- 0xbf, 0x04, 0x01, 0x8b, 0xc7, 0x99, 0x8b, 0x5e, 0xfe, 0x89, 0x57, 0x02, 0x89,
- 0x07, 0xc7, 0x47, 0x06, 0x00, 0x00, 0xc7, 0x47, 0x04, 0x00, 0x00, 0x57, 0xff,
- 0x76, 0x06, 0x8b, 0x46, 0xfe, 0x05, 0x08, 0x00, 0x50, 0xe8, 0xd0, 0x12, 0x83,
- 0xc4, 0x06, 0x8b, 0x84, 0x76, 0x09, 0x8b, 0x94, 0x74, 0x09, 0x83, 0xc2, 0x01,
- 0x15, 0x00, 0x00, 0x83, 0xe2, 0x03, 0xc7, 0x84, 0x76, 0x09, 0x00, 0x00, 0x89,
- 0x94, 0x74, 0x09, 0x5f, 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x8b, 0x46, 0x06,
- 0x8b, 0x56, 0x04, 0xa3, 0x42, 0x02, 0x89, 0x16, 0x40, 0x02, 0x8b, 0x46, 0x0a,
- 0x8b, 0x56, 0x08, 0xa3, 0x46, 0x02, 0x89, 0x16, 0x44, 0x02, 0x5d, 0xc3, 0xc8,
- 0x02, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8b, 0xc7, 0x69, 0xc0, 0xeb,
- 0x0e, 0x05, 0x9c, 0x03, 0x8b, 0xf0, 0x68, 0xeb, 0x0e, 0x6a, 0x00, 0x50, 0xe8,
- 0xb7, 0x12, 0x83, 0xc4, 0x06, 0x89, 0x3c, 0x57, 0xe8, 0xc1, 0x10, 0x59, 0x56,
- 0xe8, 0x33, 0xf4, 0x59, 0x89, 0x84, 0xc6, 0x0e, 0x57, 0xe8, 0xdc, 0x0b, 0x59,
- 0x89, 0x84, 0xe8, 0x0e, 0xa1, 0x42, 0x02, 0x8b, 0x16, 0x40, 0x02, 0x89, 0x44,
- 0x04, 0x89, 0x54, 0x02, 0xa1, 0x46, 0x02, 0x8b, 0x16, 0x44, 0x02, 0x89, 0x44,
- 0x08, 0x89, 0x54, 0x06, 0xa1, 0x4a, 0x02, 0x8b, 0x16, 0x48, 0x02, 0x89, 0x44,
- 0x0c, 0x89, 0x54, 0x0a, 0xc7, 0x44, 0x20, 0x00, 0x00, 0xc7, 0x44, 0x1e, 0x04,
- 0x00, 0xc6, 0x44, 0x23, 0x00, 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xeb, 0x17, 0x8b,
- 0x5e, 0xfe, 0xd1, 0xe3, 0xc6, 0x40, 0x24, 0x00, 0x8b, 0x5e, 0xfe, 0xd1, 0xe3,
- 0x8a, 0x46, 0xfe, 0x88, 0x40, 0x25, 0xff, 0x46, 0xfe, 0x83, 0x7e, 0xfe, 0x04,
- 0x7c, 0xe3, 0xc7, 0x84, 0xc4, 0x0e, 0x80, 0x02, 0x56, 0xe8, 0xa6, 0xfa, 0x59,
- 0x56, 0xe8, 0xd9, 0xfa, 0x59, 0x56, 0xe8, 0x18, 0xfd, 0x59, 0x5f, 0x5e, 0xc9,
- 0xc3, 0x55, 0x8b, 0xec, 0xa1, 0x9e, 0x03, 0x25, 0x00, 0x0e, 0x33, 0xd2, 0x0b,
- 0xd2, 0x75, 0x08, 0x3d, 0x00, 0x02, 0x75, 0x03, 0xe8, 0x87, 0x0b, 0xe8, 0x9a,
- 0x00, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x33, 0xf6, 0xeb, 0x27, 0x8b,
- 0xc6, 0x69, 0xc0, 0xeb, 0x0e, 0x05, 0x9c, 0x03, 0x8b, 0xf8, 0x50, 0xe8, 0x12,
- 0xf4, 0x59, 0x8b, 0x45, 0x02, 0x25, 0x00, 0x0e, 0x33, 0xd2, 0x0b, 0xd2, 0x75,
- 0x0a, 0x3d, 0x00, 0x02, 0x75, 0x05, 0x57, 0xe8, 0x4a, 0xfd, 0x59, 0x46, 0x83,
- 0xfe, 0x01, 0x7c, 0xd4, 0x5f, 0x5e, 0x5d, 0xc3, 0xc8, 0x02, 0x00, 0x00, 0x56,
- 0x8b, 0x76, 0x04, 0x8a, 0x46, 0x06, 0xb4, 0x00, 0x89, 0x46, 0xfe, 0xb9, 0x04,
- 0x00, 0xbb, 0x84, 0x3c, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83,
- 0xc3, 0x02, 0xe2, 0xf3, 0xeb, 0x27, 0x2e, 0xff, 0x67, 0x08, 0x6a, 0x00, 0x6a,
- 0x01, 0x56, 0xe8, 0x25, 0xf8, 0x83, 0xc4, 0x06, 0xeb, 0x16, 0x6a, 0x00, 0x6a,
- 0x00, 0xeb, 0xf1, 0x6a, 0x00, 0x6a, 0x02, 0xeb, 0x04, 0x6a, 0x00, 0x6a, 0x00,
- 0x56, 0xe8, 0x9e, 0xf8, 0xeb, 0xe5, 0x5e, 0xc9, 0xc3, 0x0e, 0x00, 0x14, 0x00,
- 0x32, 0x00, 0x38, 0x00, 0x5e, 0x3c, 0x71, 0x3c, 0x77, 0x3c, 0x6b, 0x3c, 0xc8,
- 0x02, 0x00, 0x00, 0x56, 0x57, 0x33, 0xff, 0xe9, 0xe4, 0x00, 0x8b, 0xc7, 0x69,
- 0xc0, 0xeb, 0x0e, 0x05, 0x9c, 0x03, 0x8b, 0xf0, 0x57, 0xe8, 0x01, 0x10, 0x59,
- 0x89, 0x46, 0xfe, 0x0b, 0xc0, 0x74, 0x0a, 0x83, 0x4c, 0x0a, 0x04, 0x83, 0x4c,
- 0x0c, 0x00, 0xeb, 0x08, 0x83, 0x64, 0x0a, 0xfb, 0x83, 0x64, 0x0c, 0xff, 0x83,
- 0x7e, 0xfe, 0x00, 0x75, 0x09, 0x56, 0xe8, 0xfb, 0xf6, 0x59, 0x0b, 0xc0, 0x74,
- 0x5c, 0x83, 0x84, 0xc4, 0x0e, 0x04, 0x8b, 0x84, 0xc4, 0x0e, 0x3d, 0x90, 0x01,
- 0x7d, 0x03, 0xe9, 0x95, 0x00, 0x8b, 0x44, 0x1e, 0x25, 0x04, 0x00, 0x0d, 0x00,
- 0x00, 0x75, 0x36, 0x6a, 0x01, 0x56, 0xe8, 0xe4, 0xf6, 0x83, 0xc4, 0x04, 0x8a,
- 0x44, 0x2c, 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd8, 0xff, 0x40, 0x3a, 0x83,
- 0x4c, 0x1e, 0x04, 0x83, 0x4c, 0x20, 0x00, 0x83, 0x4c, 0x0a, 0x18, 0x83, 0x4c,
- 0x0c, 0x00, 0x8b, 0x44, 0x1a, 0x25, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x05,
- 0x56, 0xe8, 0x0f, 0xf0, 0x59, 0xc7, 0x84, 0xc4, 0x0e, 0x80, 0x02, 0xeb, 0x4c,
- 0xeb, 0x4a, 0x83, 0xbc, 0xc4, 0x0e, 0x00, 0x74, 0x43, 0xff, 0x8c, 0xc4, 0x0e,
- 0x7d, 0x06, 0xc7, 0x84, 0xc4, 0x0e, 0x00, 0x00, 0x81, 0xbc, 0xc4, 0x0e, 0x90,
- 0x01, 0x75, 0x2f, 0x6a, 0x00, 0x56, 0xe8, 0x89, 0xf6, 0x83, 0xc4, 0x04, 0x81,
- 0xac, 0xc4, 0x0e, 0xa0, 0x00, 0x83, 0x64, 0x1e, 0xfb, 0x83, 0x64, 0x20, 0xff,
- 0x83, 0x64, 0x0a, 0xe7, 0x83, 0x64, 0x0c, 0xff, 0x8b, 0x44, 0x1a, 0x25, 0x02,
- 0x00, 0x0d, 0x00, 0x00, 0x74, 0x05, 0x56, 0xe8, 0xbb, 0xef, 0x59, 0x56, 0xe8,
- 0x0e, 0x00, 0x59, 0x47, 0x83, 0xff, 0x01, 0x7d, 0x03, 0xe9, 0x14, 0xff, 0x5f,
- 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x76, 0x04, 0x8b, 0x44, 0x0a,
- 0x25, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x05, 0xba, 0x00, 0x02, 0xeb, 0x02,
- 0x33, 0xd2, 0x8b, 0x44, 0x1e, 0x25, 0x07, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x23,
- 0x8b, 0x44, 0x1e, 0x25, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x74, 0x05, 0x83, 0xca,
- 0x04, 0xeb, 0x13, 0x8b, 0x44, 0x1e, 0x25, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x74,
- 0x05, 0x83, 0xca, 0x08, 0xeb, 0x03, 0x83, 0xca, 0x10, 0x83, 0xbc, 0xc4, 0x0e,
- 0x00, 0x74, 0x18, 0x8b, 0x44, 0x1e, 0x25, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x75,
- 0x0d, 0x8a, 0x44, 0x22, 0xfe, 0x44, 0x22, 0xa8, 0x08, 0x74, 0x03, 0x83, 0xca,
- 0x04, 0x8b, 0x1c, 0xd1, 0xe3, 0x8b, 0x87, 0x08, 0x80, 0x25, 0xe3, 0xfd, 0x0b,
- 0xc2, 0x8b, 0x1c, 0xd1, 0xe3, 0x89, 0x87, 0x08, 0x80, 0x5e, 0x5d, 0xc3, 0xc8,
- 0x04, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8b, 0x5e, 0x06, 0x83, 0x7f,
- 0x02, 0x00, 0x74, 0x03, 0xe9, 0xe6, 0x00, 0x83, 0x3f, 0x06, 0x74, 0x03, 0xe9,
- 0xde, 0x00, 0x8b, 0x46, 0x06, 0x05, 0x08, 0x00, 0x8b, 0xf0, 0x80, 0x3c, 0xc3,
- 0x74, 0x03, 0xe9, 0xce, 0x00, 0x80, 0x7c, 0x01, 0x08, 0x74, 0x03, 0xe9, 0xc5,
- 0x00, 0x8a, 0x44, 0x04, 0xb4, 0x00, 0x89, 0x46, 0xfe, 0xb9, 0x05, 0x00, 0xbb,
- 0x50, 0x3f, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfe, 0x74, 0x08, 0x83, 0xc3, 0x02,
- 0xe2, 0xf3, 0xe9, 0xa7, 0x00, 0x2e, 0xff, 0x67, 0x0a, 0xeb, 0x03, 0xe9, 0x9e,
- 0x00, 0x8a, 0x44, 0x05, 0xb4, 0x00, 0x89, 0x46, 0xfc, 0xb9, 0x11, 0x00, 0xbb,
- 0x0c, 0x3f, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfc, 0x74, 0x07, 0x83, 0xc3, 0x02,
- 0xe2, 0xf3, 0xeb, 0x77, 0x2e, 0xff, 0x67, 0x22, 0x6a, 0x00, 0x6a, 0x02, 0x57,
- 0xe8, 0x8a, 0xf6, 0x83, 0xc4, 0x06, 0x6a, 0x00, 0xeb, 0x66, 0x6a, 0x00, 0x6a,
- 0x00, 0xeb, 0xef, 0x57, 0xe8, 0xd3, 0xf7, 0xeb, 0x16, 0x6a, 0x00, 0x56, 0x57,
- 0xe8, 0x6e, 0x01, 0xeb, 0x56, 0x6a, 0x00, 0x56, 0x57, 0xe8, 0x70, 0x02, 0xeb,
- 0x4d, 0x57, 0xe8, 0xf3, 0xf7, 0x59, 0xeb, 0xd7, 0x6a, 0x01, 0x6a, 0x00, 0x56,
- 0x57, 0xe8, 0xac, 0x02, 0xeb, 0x26, 0x6a, 0x02, 0xeb, 0xf3, 0x6a, 0x00, 0x56,
- 0x57, 0xe8, 0xac, 0x03, 0xeb, 0x2e, 0x6a, 0x01, 0xeb, 0x0e, 0x6a, 0x02, 0xeb,
- 0x0a, 0x6a, 0x03, 0xeb, 0x06, 0x6a, 0x04, 0xeb, 0x02, 0x6a, 0x05, 0x6a, 0x00,
- 0x56, 0x57, 0xe8, 0xc4, 0x05, 0x83, 0xc4, 0x08, 0xeb, 0x13, 0x6a, 0x00, 0x56,
- 0x57, 0xe8, 0x0d, 0x08, 0xeb, 0x07, 0x6a, 0x08, 0x56, 0x57, 0xe8, 0xec, 0x00,
- 0x83, 0xc4, 0x06, 0x5f, 0x5e, 0xc9, 0xc3, 0x01, 0x00, 0x02, 0x00, 0x40, 0x00,
- 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x64, 0x00, 0x65, 0x00, 0x67, 0x00, 0x6b,
- 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0xc2, 0x00, 0xc4, 0x00,
- 0xe7, 0x00, 0x8b, 0x3e, 0x9a, 0x3e, 0xa6, 0x3e, 0xa0, 0x3e, 0xaf, 0x3e, 0xb8,
- 0x3e, 0xbf, 0x3e, 0xca, 0x3e, 0xce, 0x3e, 0xd7, 0x3e, 0xdb, 0x3e, 0xdf, 0x3e,
- 0xe3, 0x3e, 0xe7, 0x3e, 0xa0, 0x3e, 0xb8, 0x3e, 0xf5, 0x3e, 0x41, 0x00, 0x42,
- 0x00, 0x59, 0x00, 0x5a, 0x00, 0x80, 0x00, 0x6a, 0x3e, 0x6a, 0x3e, 0x6a, 0x3e,
- 0x6a, 0x3e, 0x6a, 0x3e, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x56, 0x04, 0x8b, 0x76,
- 0x06, 0x8a, 0xc2, 0x24, 0xff, 0x88, 0x04, 0x46, 0x8b, 0xc2, 0xc1, 0xe8, 0x08,
- 0x24, 0xff, 0x88, 0x04, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x8b,
- 0x4e, 0x04, 0x8b, 0x76, 0x06, 0x8b, 0x7e, 0x08, 0xc6, 0x04, 0x81, 0xc6, 0x44,
- 0x01, 0x08, 0x8a, 0x45, 0x02, 0x88, 0x44, 0x02, 0x8a, 0x46, 0x0a, 0x88, 0x44,
- 0x03, 0x8a, 0x45, 0x03, 0x88, 0x44, 0x04, 0x8a, 0x45, 0x04, 0x88, 0x44, 0x05,
- 0x8a, 0x45, 0x05, 0x88, 0x44, 0x06, 0x8b, 0xd9, 0x8b, 0x47, 0x0a, 0x25, 0x03,
- 0x00, 0x33, 0xd2, 0x0b, 0xd2, 0x75, 0x09, 0x3d, 0x02, 0x00, 0x75, 0x04, 0xb0,
- 0x82, 0xeb, 0x02, 0xb0, 0x00, 0x50, 0x8b, 0xd9, 0x8b, 0x47, 0x0a, 0x25, 0x18,
- 0x00, 0x33, 0xd2, 0x0b, 0xd2, 0x75, 0x09, 0x3d, 0x18, 0x00, 0x75, 0x04, 0xb0,
- 0xc0, 0xeb, 0x02, 0xb0, 0x00, 0x5a, 0x0a, 0xd0, 0x88, 0x54, 0x07, 0x5f, 0x5e,
- 0x5d, 0xc3, 0xc8, 0x08, 0x00, 0x00, 0x56, 0x8b, 0x76, 0x04, 0x8a, 0x46, 0x08,
- 0x50, 0xff, 0x76, 0x06, 0x8d, 0x46, 0xf8, 0x50, 0x56, 0xe8, 0x79, 0xff, 0x83,
- 0xc4, 0x08, 0x6a, 0x08, 0x8d, 0x46, 0xf8, 0x50, 0x56, 0xe8, 0x6f, 0xfa, 0x83,
- 0xc4, 0x06, 0x5e, 0xc9, 0xc3, 0xc8, 0x28, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76,
- 0x04, 0x8a, 0x46, 0x08, 0x50, 0xff, 0x76, 0x06, 0x8d, 0x46, 0xd8, 0x50, 0x56,
- 0xe8, 0x4e, 0xff, 0x83, 0xc4, 0x08, 0x80, 0x7c, 0x2d, 0x00, 0x74, 0x05, 0xb8,
- 0x60, 0x00, 0xeb, 0x05, 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x89, 0x46, 0xfe, 0x8a,
- 0x44, 0x2c, 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd6, 0x03, 0xd0, 0x83, 0xc2,
- 0x30, 0x8b, 0xfa, 0x8d, 0x46, 0xe0, 0x50, 0xff, 0x74, 0x2e, 0xe8, 0x00, 0xff,
- 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xe2, 0x50, 0xff, 0x35, 0xe8, 0xf4, 0xfe, 0x83,
- 0xc4, 0x04, 0x8d, 0x46, 0xe4, 0x50, 0xff, 0x75, 0x02, 0xe8, 0xe7, 0xfe, 0x83,
- 0xc4, 0x04, 0x8a, 0x46, 0xfe, 0x88, 0x46, 0xe6, 0x8d, 0x46, 0xe7, 0x50, 0x83,
- 0xbc, 0x4a, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbc, 0x48, 0x09, 0xff,
- 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x84, 0x48, 0x09, 0x50, 0xe8,
- 0xbd, 0xfe, 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xe9, 0x50, 0x83, 0xbc, 0x4e, 0x09,
- 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbc, 0x4c, 0x09, 0xff, 0x76, 0x05, 0xb8,
- 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x84, 0x4c, 0x09, 0x50, 0xe8, 0x99, 0xfe, 0x83,
- 0xc4, 0x04, 0xc7, 0x46, 0xfc, 0x00, 0x00, 0xeb, 0x37, 0x8b, 0xc6, 0x05, 0x30,
- 0x00, 0x3b, 0xc7, 0x76, 0x04, 0x81, 0xc7, 0x18, 0x09, 0x8b, 0x46, 0xfc, 0xd1,
- 0xe0, 0x8d, 0x56, 0xeb, 0x03, 0xc2, 0x50, 0xff, 0x35, 0xe8, 0x72, 0xfe, 0x83,
- 0xc4, 0x04, 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x56, 0xf3, 0x03, 0xc2, 0x50,
- 0xff, 0x75, 0x02, 0xe8, 0x5e, 0xfe, 0x83, 0xc4, 0x04, 0xff, 0x46, 0xfc, 0x83,
- 0xef, 0x18, 0x83, 0x7e, 0xfc, 0x04, 0x7c, 0xc0, 0x6a, 0x23, 0x8d, 0x46, 0xd8,
- 0x50, 0x56, 0xe8, 0x65, 0xf9, 0x83, 0xc4, 0x06, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8,
- 0x0a, 0x00, 0x00, 0x56, 0x8b, 0x76, 0x04, 0x8a, 0x46, 0x08, 0x50, 0xff, 0x76,
- 0x06, 0x8d, 0x46, 0xf6, 0x50, 0x56, 0xe8, 0x44, 0xfe, 0x83, 0xc4, 0x08, 0x8d,
- 0x46, 0xfe, 0x50, 0x83, 0xbc, 0x72, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83,
- 0xbc, 0x70, 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x84,
- 0x70, 0x09, 0x50, 0xe8, 0x03, 0xfe, 0x83, 0xc4, 0x04, 0x6a, 0x0a, 0x8d, 0x46,
- 0xf6, 0x50, 0x56, 0xe8, 0x16, 0xf9, 0x83, 0xc4, 0x06, 0x5e, 0xc9, 0xc3, 0xc8,
- 0xd8, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04, 0x8a, 0x46, 0x08, 0x50, 0xff,
- 0x76, 0x06, 0x8d, 0x86, 0x28, 0xff, 0x50, 0x56, 0xe8, 0xf4, 0xfd, 0x83, 0xc4,
- 0x08, 0x80, 0x7c, 0x2d, 0x00, 0x74, 0x05, 0xb8, 0x60, 0x00, 0xeb, 0x05, 0x8a,
- 0x44, 0x2c, 0xb4, 0x00, 0x89, 0x46, 0xfe, 0x8a, 0x44, 0x2c, 0xb4, 0x00, 0x6b,
- 0xc0, 0x18, 0x8b, 0xd6, 0x03, 0xd0, 0x83, 0xc2, 0x30, 0x8b, 0xfa, 0x8d, 0x86,
- 0x30, 0xff, 0x50, 0xff, 0x74, 0x2e, 0xe8, 0xa5, 0xfd, 0x83, 0xc4, 0x04, 0x8d,
- 0x86, 0x32, 0xff, 0x50, 0xff, 0x35, 0xe8, 0x98, 0xfd, 0x83, 0xc4, 0x04, 0x8d,
- 0x86, 0x34, 0xff, 0x50, 0xff, 0x75, 0x02, 0xe8, 0x8a, 0xfd, 0x83, 0xc4, 0x04,
- 0x8a, 0x46, 0xfe, 0x88, 0x86, 0x36, 0xff, 0x8d, 0x86, 0x37, 0xff, 0x50, 0x83,
- 0xbc, 0x4a, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbc, 0x48, 0x09, 0xff,
- 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x84, 0x48, 0x09, 0x50, 0xe8,
- 0x5e, 0xfd, 0x83, 0xc4, 0x04, 0x8d, 0x86, 0x39, 0xff, 0x50, 0x83, 0xbc, 0x4e,
- 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbc, 0x4c, 0x09, 0xff, 0x76, 0x05,
- 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x84, 0x4c, 0x09, 0x50, 0xe8, 0x39, 0xfd,
- 0x83, 0xc4, 0x04, 0xc7, 0x46, 0xfc, 0x00, 0x00, 0xeb, 0x30, 0x8b, 0xc6, 0x05,
- 0x30, 0x00, 0x3b, 0xc7, 0x76, 0x04, 0x81, 0xc7, 0x18, 0x09, 0x8b, 0x46, 0xfc,
- 0xd1, 0xe0, 0x8d, 0x96, 0x3b, 0xff, 0x03, 0xc2, 0x50, 0x80, 0x7e, 0x0a, 0x01,
- 0x75, 0x04, 0x8b, 0x05, 0xeb, 0x03, 0x8b, 0x45, 0x02, 0x50, 0xe8, 0x05, 0xfd,
- 0x83, 0xc4, 0x04, 0xff, 0x46, 0xfc, 0x83, 0xef, 0x18, 0x83, 0x7e, 0xfc, 0x60,
- 0x7c, 0xc7, 0x68, 0xd3, 0x00, 0x8d, 0x86, 0x28, 0xff, 0x50, 0x56, 0xe8, 0x0a,
- 0xf8, 0x83, 0xc4, 0x06, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x4e, 0x00, 0x00, 0x56,
- 0x57, 0x8b, 0x7e, 0x04, 0x8a, 0x46, 0x08, 0x50, 0xff, 0x76, 0x06, 0x8d, 0x46,
- 0xb2, 0x50, 0x57, 0xe8, 0xe8, 0xfc, 0x83, 0xc4, 0x08, 0x80, 0x7d, 0x2d, 0x00,
- 0x74, 0x05, 0xb8, 0x60, 0x00, 0xeb, 0x05, 0x8a, 0x45, 0x2c, 0xb4, 0x00, 0x89,
- 0x46, 0xfe, 0x8a, 0x45, 0x2c, 0xb4, 0x00, 0x6b, 0xc0, 0x18, 0x8b, 0xd7, 0x03,
- 0xd0, 0x83, 0xc2, 0x30, 0x8b, 0xf2, 0x8d, 0x46, 0xba, 0x50, 0xff, 0x75, 0x2e,
- 0xe8, 0x9a, 0xfc, 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xbc, 0x50, 0xff, 0x34, 0xe8,
- 0x8e, 0xfc, 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xbe, 0x50, 0xff, 0x74, 0x02, 0xe8,
- 0x81, 0xfc, 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xc0, 0x50, 0xff, 0x74, 0x04, 0xe8,
- 0x74, 0xfc, 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xc2, 0x50, 0xff, 0x74, 0x06, 0xe8,
- 0x67, 0xfc, 0x83, 0xc4, 0x04, 0x81, 0x7c, 0x08, 0xff, 0x00, 0x76, 0x04, 0xb0,
- 0xff, 0xeb, 0x03, 0x8a, 0x44, 0x08, 0x88, 0x46, 0xed, 0x81, 0x7c, 0x0a, 0xff,
- 0x00, 0x76, 0x04, 0xb0, 0xff, 0xeb, 0x03, 0x8a, 0x44, 0x0a, 0x88, 0x46, 0xee,
- 0x8a, 0x46, 0xfe, 0x88, 0x46, 0xc4, 0x8d, 0x46, 0xc5, 0x50, 0x83, 0xbd, 0x4a,
- 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbd, 0x48, 0x09, 0xff, 0x76, 0x05,
- 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x85, 0x48, 0x09, 0x50, 0xe8, 0x1b, 0xfc,
- 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xc7, 0x50, 0x83, 0xbd, 0x4e, 0x09, 0x00, 0x72,
- 0x0e, 0x77, 0x07, 0x83, 0xbd, 0x4c, 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff,
- 0xeb, 0x04, 0x8b, 0x85, 0x4c, 0x09, 0x50, 0xe8, 0xf7, 0xfb, 0x83, 0xc4, 0x04,
- 0x8d, 0x46, 0xc9, 0x50, 0x83, 0xbd, 0x52, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07,
- 0x83, 0xbd, 0x50, 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b,
- 0x85, 0x50, 0x09, 0x50, 0xe8, 0xd3, 0xfb, 0x83, 0xc4, 0x04, 0x8d, 0x46, 0xcb,
- 0x50, 0x83, 0xbd, 0x56, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbd, 0x54,
- 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x85, 0x54, 0x09,
- 0x50, 0xe8, 0xaf, 0xfb, 0x83, 0xc4, 0x04, 0x83, 0xbd, 0x5a, 0x09, 0x00, 0x72,
- 0x0e, 0x77, 0x08, 0x81, 0xbd, 0x58, 0x09, 0xff, 0x00, 0x76, 0x04, 0xb0, 0xff,
- 0xeb, 0x04, 0x8a, 0x85, 0x58, 0x09, 0x88, 0x46, 0xef, 0x83, 0xbd, 0x5e, 0x09,
- 0x00, 0x72, 0x0e, 0x77, 0x08, 0x81, 0xbd, 0x5c, 0x09, 0xff, 0x00, 0x76, 0x04,
- 0xb0, 0xff, 0xeb, 0x04, 0x8a, 0x85, 0x5c, 0x09, 0x88, 0x46, 0xf0, 0xc7, 0x46,
- 0xfc, 0x00, 0x00, 0xe9, 0x97, 0x00, 0x8b, 0xc7, 0x05, 0x30, 0x00, 0x3b, 0xc6,
- 0x76, 0x04, 0x81, 0xc6, 0x18, 0x09, 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x56,
- 0xcd, 0x03, 0xc2, 0x50, 0xff, 0x34, 0xe8, 0x4f, 0xfb, 0x83, 0xc4, 0x04, 0x8b,
- 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x56, 0xd5, 0x03, 0xc2, 0x50, 0xff, 0x74, 0x02,
- 0xe8, 0x3b, 0xfb, 0x83, 0xc4, 0x04, 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x56,
- 0xdd, 0x03, 0xc2, 0x50, 0xff, 0x74, 0x04, 0xe8, 0x27, 0xfb, 0x83, 0xc4, 0x04,
- 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x56, 0xe5, 0x03, 0xc2, 0x50, 0xff, 0x74,
- 0x06, 0xe8, 0x13, 0xfb, 0x83, 0xc4, 0x04, 0x8b, 0x5e, 0xfc, 0xd1, 0xe3, 0x8d,
- 0x46, 0xf1, 0x03, 0xd8, 0x53, 0x81, 0x7c, 0x08, 0xff, 0x00, 0x76, 0x04, 0xb0,
- 0xff, 0xeb, 0x03, 0x8a, 0x44, 0x08, 0x5b, 0x88, 0x07, 0x8b, 0x5e, 0xfc, 0xd1,
- 0xe3, 0x8d, 0x46, 0xf2, 0x03, 0xd8, 0x53, 0x81, 0x7c, 0x0a, 0xff, 0x00, 0x76,
- 0x04, 0xb0, 0xff, 0xeb, 0x03, 0x8a, 0x44, 0x0a, 0x5b, 0x88, 0x07, 0xff, 0x46,
- 0xfc, 0x83, 0xee, 0x18, 0x83, 0x7e, 0xfc, 0x04, 0x7d, 0x03, 0xe9, 0x5d, 0xff,
- 0xb0, 0x00, 0x88, 0x46, 0xfa, 0x88, 0x46, 0xf9, 0x6a, 0x49, 0x8d, 0x46, 0xb2,
- 0x50, 0x57, 0xe8, 0xd7, 0xf5, 0x83, 0xc4, 0x06, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8,
- 0xe4, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8a, 0x46, 0x08, 0x50, 0xff,
- 0x76, 0x06, 0x8d, 0x86, 0x1c, 0xff, 0x50, 0x57, 0xe8, 0xb4, 0xfa, 0x83, 0xc4,
- 0x08, 0x80, 0x7d, 0x2d, 0x00, 0x74, 0x05, 0xb8, 0x60, 0x00, 0xeb, 0x05, 0x8a,
- 0x45, 0x2c, 0xb4, 0x00, 0x89, 0x46, 0xfe, 0x8a, 0x45, 0x2c, 0xb4, 0x00, 0x6b,
- 0xc0, 0x18, 0x8b, 0xd7, 0x03, 0xd0, 0x83, 0xc2, 0x30, 0x8b, 0xf2, 0x8d, 0x86,
- 0x24, 0xff, 0x50, 0xff, 0x75, 0x2e, 0xe8, 0x65, 0xfa, 0x83, 0xc4, 0x04, 0x8d,
- 0x86, 0x26, 0xff, 0x50, 0xff, 0x34, 0xe8, 0x58, 0xfa, 0x83, 0xc4, 0x04, 0x8d,
- 0x86, 0x28, 0xff, 0x50, 0xff, 0x74, 0x02, 0xe8, 0x4a, 0xfa, 0x83, 0xc4, 0x04,
- 0x8d, 0x86, 0x2a, 0xff, 0x50, 0xff, 0x74, 0x04, 0xe8, 0x3c, 0xfa, 0x83, 0xc4,
- 0x04, 0x8d, 0x86, 0x2c, 0xff, 0x50, 0xff, 0x74, 0x06, 0xe8, 0x2e, 0xfa, 0x83,
- 0xc4, 0x04, 0x81, 0x7c, 0x08, 0xff, 0x00, 0x76, 0x04, 0xb0, 0xff, 0xeb, 0x03,
- 0x8a, 0x44, 0x08, 0x88, 0x46, 0xf7, 0x81, 0x7c, 0x0a, 0xff, 0x00, 0x76, 0x04,
- 0xb0, 0xff, 0xeb, 0x03, 0x8a, 0x44, 0x0a, 0x88, 0x46, 0xf8, 0x8a, 0x46, 0xfe,
- 0x88, 0x86, 0x2e, 0xff, 0x8d, 0x86, 0x2f, 0xff, 0x50, 0x83, 0xbd, 0x4a, 0x09,
- 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83, 0xbd, 0x48, 0x09, 0xff, 0x76, 0x05, 0xb8,
- 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x85, 0x48, 0x09, 0x50, 0xe8, 0xe0, 0xf9, 0x83,
- 0xc4, 0x04, 0x8d, 0x86, 0x31, 0xff, 0x50, 0x83, 0xbd, 0x4e, 0x09, 0x00, 0x72,
- 0x0e, 0x77, 0x07, 0x83, 0xbd, 0x4c, 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff,
- 0xeb, 0x04, 0x8b, 0x85, 0x4c, 0x09, 0x50, 0xe8, 0xbb, 0xf9, 0x83, 0xc4, 0x04,
- 0x8d, 0x86, 0x33, 0xff, 0x50, 0x83, 0xbd, 0x52, 0x09, 0x00, 0x72, 0x0e, 0x77,
- 0x07, 0x83, 0xbd, 0x50, 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04,
- 0x8b, 0x85, 0x50, 0x09, 0x50, 0xe8, 0x96, 0xf9, 0x83, 0xc4, 0x04, 0x8d, 0x86,
- 0x35, 0xff, 0x50, 0x83, 0xbd, 0x56, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x07, 0x83,
- 0xbd, 0x54, 0x09, 0xff, 0x76, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x04, 0x8b, 0x85,
- 0x54, 0x09, 0x50, 0xe8, 0x71, 0xf9, 0x83, 0xc4, 0x04, 0x83, 0xbd, 0x5a, 0x09,
- 0x00, 0x72, 0x0e, 0x77, 0x08, 0x81, 0xbd, 0x58, 0x09, 0xff, 0x00, 0x76, 0x04,
- 0xb0, 0xff, 0xeb, 0x04, 0x8a, 0x85, 0x58, 0x09, 0x88, 0x46, 0xf9, 0x83, 0xbd,
- 0x5e, 0x09, 0x00, 0x72, 0x0e, 0x77, 0x08, 0x81, 0xbd, 0x5c, 0x09, 0xff, 0x00,
- 0x76, 0x04, 0xb0, 0xff, 0xeb, 0x04, 0x8a, 0x85, 0x5c, 0x09, 0x88, 0x46, 0xfa,
- 0xc7, 0x46, 0xfc, 0x00, 0x00, 0xe9, 0xaa, 0x00, 0x8b, 0xc7, 0x05, 0x30, 0x00,
- 0x3b, 0xc6, 0x76, 0x04, 0x81, 0xc6, 0x18, 0x09, 0x8a, 0x46, 0x0a, 0xb4, 0x00,
- 0x48, 0x8b, 0xd8, 0x83, 0xfb, 0x04, 0x76, 0x03, 0xe9, 0x8a, 0x00, 0xd1, 0xe3,
- 0x2e, 0xff, 0xa7, 0xff, 0x46, 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x96, 0x37,
- 0xff, 0x03, 0xc2, 0x50, 0xff, 0x34, 0xe8, 0xf9, 0xf8, 0x83, 0xc4, 0x04, 0xeb,
- 0x6d, 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x96, 0x37, 0xff, 0x03, 0xc2, 0x50,
- 0xff, 0x74, 0x02, 0xeb, 0xe7, 0x8b, 0x46, 0xfc, 0xd1, 0xe0, 0x8d, 0x96, 0x37,
- 0xff, 0x03, 0xc2, 0x50, 0xff, 0x74, 0x04, 0xeb, 0xd6, 0x8b, 0x46, 0xfc, 0xd1,
- 0xe0, 0x8d, 0x96, 0x37, 0xff, 0x03, 0xc2, 0x50, 0xff, 0x74, 0x06, 0xeb, 0xc5,
- 0x8b, 0x5e, 0xfc, 0xd1, 0xe3, 0x8d, 0x86, 0x37, 0xff, 0x03, 0xd8, 0x53, 0x81,
- 0x7c, 0x08, 0xff, 0x00, 0x76, 0x04, 0xb0, 0xff, 0xeb, 0x03, 0x8a, 0x44, 0x08,
- 0x5b, 0x88, 0x07, 0x8b, 0x5e, 0xfc, 0xd1, 0xe3, 0x8d, 0x86, 0x38, 0xff, 0x03,
- 0xd8, 0x53, 0x81, 0x7c, 0x0a, 0xff, 0x00, 0x76, 0x04, 0xb0, 0xff, 0xeb, 0x03,
- 0x8a, 0x44, 0x0a, 0x5b, 0x88, 0x07, 0xff, 0x46, 0xfc, 0x83, 0xee, 0x18, 0x83,
- 0x7e, 0xfc, 0x60, 0x7d, 0x03, 0xe9, 0x4a, 0xff, 0x68, 0xdf, 0x00, 0x8d, 0x86,
- 0x1c, 0xff, 0x50, 0x57, 0xe8, 0x8c, 0xf3, 0x83, 0xc4, 0x06, 0x5f, 0x5e, 0xc9,
- 0xc3, 0x5a, 0x46, 0x70, 0x46, 0x81, 0x46, 0x92, 0x46, 0xa3, 0x46, 0xc8, 0x14,
- 0x00, 0x00, 0x56, 0x8b, 0x76, 0x04, 0x8a, 0x46, 0x08, 0x50, 0xff, 0x76, 0x06,
- 0x8d, 0x46, 0xec, 0x50, 0x56, 0xe8, 0x61, 0xf8, 0x83, 0xc4, 0x08, 0xc6, 0x46,
- 0xf4, 0x02, 0x6a, 0x0a, 0x6a, 0x00, 0x8d, 0x46, 0xf5, 0x50, 0xe8, 0xd7, 0x06,
- 0x83, 0xc4, 0x06, 0x6a, 0x13, 0x8d, 0x46, 0xec, 0x50, 0x56, 0xe8, 0x45, 0xf3,
- 0x83, 0xc4, 0x06, 0x5e, 0xc9, 0xc3, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x46, 0x04,
- 0x0b, 0xc0, 0x74, 0x02, 0xeb, 0x05, 0xbe, 0x00, 0x98, 0xeb, 0x04, 0x33, 0xc0,
- 0xeb, 0x20, 0xc7, 0x44, 0x5e, 0x9c, 0x00, 0xc7, 0x44, 0x58, 0x00, 0x00, 0xc7,
- 0x44, 0x44, 0x9e, 0x00, 0xc7, 0x44, 0x5c, 0x88, 0x00, 0xc7, 0x44, 0x42, 0x41,
- 0x00, 0xc7, 0x44, 0x40, 0x04, 0x00, 0x8b, 0xc6, 0x5e, 0x5d, 0xc3, 0xc8, 0x02,
- 0x00, 0x00, 0xa0, 0x40, 0x98, 0x88, 0x46, 0xff, 0xa0, 0x48, 0x98, 0x88, 0x46,
- 0xfe, 0x80, 0x7e, 0xff, 0x00, 0x75, 0x06, 0x80, 0x7e, 0xfe, 0x00, 0x74, 0x11,
- 0x8a, 0x46, 0xfe, 0x50, 0x8a, 0x46, 0xff, 0x50, 0x68, 0x9c, 0x03, 0xe8, 0x0c,
- 0x00, 0x83, 0xc4, 0x06, 0x68, 0x9c, 0x03, 0xe8, 0x0f, 0x02, 0x59, 0xc9, 0xc3,
- 0xc8, 0x0e, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x7e, 0x04, 0x8b, 0xb5, 0xe8, 0x0e,
- 0x89, 0x76, 0xfa, 0x8b, 0xc7, 0x05, 0xb4, 0x0d, 0x89, 0x46, 0xfe, 0x8b, 0x5e,
- 0xfe, 0x03, 0x07, 0x05, 0x08, 0x00, 0x89, 0x46, 0xfc, 0x8b, 0x44, 0x4e, 0x89,
- 0x46, 0xf6, 0xf6, 0x46, 0x06, 0x80, 0x75, 0x03, 0xe9, 0x23, 0x01, 0xf7, 0x46,
- 0xf6, 0x01, 0x00, 0x75, 0x03, 0xe9, 0xa4, 0x00, 0xf7, 0x46, 0xf6, 0xa0, 0x00,
- 0x75, 0x03, 0xe9, 0x80, 0x00, 0xf7, 0x46, 0xf6, 0x40, 0x00, 0x75, 0x79, 0x8b,
- 0x44, 0x5a, 0x25, 0xff, 0x00, 0xc1, 0xe0, 0x08, 0x8b, 0x54, 0x4a, 0x81, 0xe2,
- 0xff, 0x00, 0x0b, 0xd0, 0x4a, 0x89, 0x56, 0xf4, 0x81, 0x7e, 0xf4, 0x04, 0x01,
- 0x77, 0x40, 0xc7, 0x47, 0x06, 0x00, 0x00, 0xc7, 0x47, 0x04, 0x01, 0x00, 0x8b,
- 0x46, 0xf4, 0x2b, 0x07, 0x89, 0x46, 0xf2, 0xc7, 0x46, 0xf8, 0x00, 0x00, 0xeb,
- 0x10, 0x8b, 0x5e, 0xfa, 0x8a, 0x07, 0x8b, 0x5e, 0xfc, 0x88, 0x07, 0xff, 0x46,
- 0xfc, 0xff, 0x46, 0xf8, 0x8b, 0x46, 0xf8, 0x3b, 0x46, 0xf2, 0x72, 0xe8, 0x8b,
- 0x46, 0xf2, 0x8b, 0x5e, 0xfe, 0x01, 0x07, 0x83, 0x57, 0x02, 0x00, 0xe9, 0x8b,
- 0x00, 0x8a, 0x85, 0xea, 0x0e, 0xb4, 0x00, 0x0d, 0x40, 0x00, 0x89, 0x44, 0x42,
- 0x83, 0x85, 0xc0, 0x0e, 0x01, 0x83, 0x95, 0xc2, 0x0e, 0x00, 0xe9, 0x83, 0x00,
- 0xe9, 0x80, 0x00, 0x8a, 0x85, 0xea, 0x0e, 0xb4, 0x00, 0x0d, 0x40, 0x00, 0x89,
- 0x44, 0x42, 0x83, 0x85, 0xc0, 0x0e, 0x01, 0x83, 0x95, 0xc2, 0x0e, 0x00, 0xeb,
- 0x68, 0xeb, 0x66, 0x8b, 0x5e, 0xfe, 0xc7, 0x47, 0x06, 0x00, 0x00, 0xc7, 0x47,
- 0x04, 0x02, 0x00, 0x8b, 0x44, 0x5a, 0x25, 0xff, 0x00, 0xc1, 0xe0, 0x08, 0x8b,
- 0x54, 0x4a, 0x81, 0xe2, 0xff, 0x00, 0x0b, 0xd0, 0x4a, 0x89, 0x56, 0xf4, 0xc7,
- 0x46, 0xf8, 0x00, 0x00, 0xeb, 0x10, 0x8b, 0x5e, 0xfa, 0x8a, 0x07, 0x8b, 0x5e,
- 0xfc, 0x88, 0x07, 0xff, 0x46, 0xfc, 0xff, 0x46, 0xf8, 0x8b, 0x46, 0xf4, 0x25,
- 0x1f, 0x00, 0x3b, 0x46, 0xf8, 0x77, 0xe5, 0x8b, 0x46, 0xf4, 0x25, 0x1f, 0x00,
- 0x8b, 0x5e, 0xfe, 0xc7, 0x47, 0x02, 0x00, 0x00, 0x89, 0x07, 0x8a, 0x85, 0xea,
- 0x0e, 0xb4, 0x00, 0x0d, 0x80, 0x00, 0x89, 0x44, 0x42, 0x57, 0xe8, 0xec, 0xf0,
- 0x59, 0x8b, 0x5e, 0xfe, 0xc7, 0x47, 0x02, 0x00, 0x00, 0xc7, 0x07, 0x00, 0x00,
- 0xe9, 0x95, 0x00, 0xf6, 0x46, 0x06, 0x40, 0x75, 0x03, 0xe9, 0x8c, 0x00, 0x8b,
- 0x5e, 0xfe, 0x8b, 0x47, 0x02, 0x8b, 0x17, 0x83, 0xc2, 0x20, 0x15, 0x00, 0x00,
- 0x0b, 0xc0, 0x72, 0x0f, 0x75, 0x06, 0x81, 0xfa, 0x04, 0x01, 0x72, 0x07, 0xf7,
- 0x46, 0xf6, 0x40, 0x00, 0x74, 0x49, 0xc7, 0x46, 0xf8, 0x00, 0x00, 0xeb, 0x10,
- 0x8b, 0x5e, 0xfa, 0x8a, 0x07, 0x8b, 0x5e, 0xfc, 0x88, 0x07, 0xff, 0x46, 0xfc,
- 0xff, 0x46, 0xf8, 0x83, 0x7e, 0xf8, 0x20, 0x7c, 0xea, 0x8b, 0x5e, 0xfe, 0x83,
- 0x07, 0x20, 0x83, 0x57, 0x02, 0x00, 0x8a, 0x85, 0xea, 0x0e, 0xb4, 0x00, 0x0d,
- 0x80, 0x00, 0x89, 0x44, 0x42, 0xf7, 0x46, 0xf6, 0x01, 0x00, 0x75, 0x31, 0xc7,
- 0x47, 0x06, 0x00, 0x00, 0xc7, 0x47, 0x04, 0x02, 0x00, 0xe9, 0x7b, 0xff, 0xeb,
- 0x22, 0x83, 0x85, 0xc0, 0x0e, 0x01, 0x83, 0x95, 0xc2, 0x0e, 0x00, 0x8b, 0x5e,
- 0xfe, 0xc7, 0x47, 0x02, 0x00, 0x00, 0xc7, 0x07, 0x00, 0x00, 0x8a, 0x85, 0xea,
- 0x0e, 0xb4, 0x00, 0x0d, 0x40, 0x00, 0x89, 0x44, 0x42, 0xf6, 0x46, 0x08, 0x10,
- 0x74, 0x18, 0x8a, 0x85, 0xea, 0x0e, 0xb4, 0x00, 0x0d, 0x40, 0x00, 0x89, 0x44,
- 0x42, 0x8b, 0x5e, 0xfe, 0xc7, 0x47, 0x02, 0x00, 0x00, 0xc7, 0x07, 0x00, 0x00,
- 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x08, 0x00, 0x00, 0x56, 0x57, 0x8b, 0x76, 0x04,
- 0x8b, 0xbc, 0xe8, 0x0e, 0x8a, 0x45, 0x42, 0x88, 0x46, 0xfd, 0x8b, 0x84, 0x76,
- 0x09, 0x8b, 0x94, 0x74, 0x09, 0x3b, 0x84, 0x7a, 0x09, 0x75, 0x09, 0x3b, 0x94,
- 0x78, 0x09, 0x75, 0x03, 0xe9, 0xb2, 0x00, 0xf6, 0x46, 0xfd, 0x40, 0x75, 0x03,
- 0xe9, 0xa9, 0x00, 0x8b, 0x84, 0x78, 0x09, 0x69, 0xc0, 0x0c, 0x01, 0x8b, 0xd6,
- 0x03, 0xd0, 0x81, 0xc2, 0x84, 0x09, 0x89, 0x56, 0xfe, 0x8b, 0x5e, 0xfe, 0x8b,
- 0x07, 0x2b, 0x84, 0x80, 0x09, 0x89, 0x46, 0xf8, 0x8b, 0x46, 0xfe, 0x03, 0x84,
- 0x80, 0x09, 0x05, 0x08, 0x00, 0x89, 0x46, 0xfa, 0x83, 0x7e, 0xf8, 0x20, 0x7e,
- 0x2e, 0x33, 0xc9, 0xeb, 0x0d, 0x8b, 0x5e, 0xfa, 0x8a, 0x07, 0xb4, 0x00, 0x89,
- 0x05, 0xff, 0x46, 0xfa, 0x41, 0x83, 0xf9, 0x20, 0x7c, 0xee, 0x8a, 0x84, 0xea,
- 0x0e, 0xb4, 0x00, 0x0d, 0x08, 0x00, 0x89, 0x45, 0x42, 0x83, 0x84, 0x80, 0x09,
- 0x20, 0x83, 0x94, 0x82, 0x09, 0x00, 0xeb, 0x49, 0x33, 0xc9, 0xeb, 0x0d, 0x8b,
- 0x5e, 0xfa, 0x8a, 0x07, 0xb4, 0x00, 0x89, 0x05, 0xff, 0x46, 0xfa, 0x41, 0x3b,
- 0x4e, 0xf8, 0x7c, 0xee, 0x8a, 0x84, 0xea, 0x0e, 0xb4, 0x00, 0x0d, 0x0a, 0x00,
- 0x89, 0x45, 0x42, 0xc7, 0x84, 0x82, 0x09, 0x00, 0x00, 0xc7, 0x84, 0x80, 0x09,
- 0x00, 0x00, 0x8b, 0x84, 0x7a, 0x09, 0x8b, 0x94, 0x78, 0x09, 0x83, 0xc2, 0x01,
- 0x15, 0x00, 0x00, 0x83, 0xe2, 0x03, 0xc7, 0x84, 0x7a, 0x09, 0x00, 0x00, 0x89,
- 0x94, 0x78, 0x09, 0x5f, 0x5e, 0xc9, 0xc3, 0xc8, 0x0c, 0x00, 0x00, 0x80, 0x26,
- 0x4d, 0x02, 0xbf, 0x8b, 0x46, 0x04, 0x25, 0xc0, 0x01, 0x33, 0xd2, 0x0b, 0xd2,
- 0x75, 0x0c, 0x3d, 0x40, 0x00, 0x75, 0x07, 0x80, 0x0e, 0x4d, 0x02, 0x00, 0xeb,
- 0x05, 0x80, 0x0e, 0x4d, 0x02, 0x40, 0x80, 0x26, 0x4c, 0x02, 0xbf, 0x8b, 0x46,
- 0x04, 0x25, 0x00, 0x60, 0x89, 0x46, 0xfc, 0xc7, 0x46, 0xfe, 0x00, 0x00, 0xb9,
- 0x04, 0x00, 0xbb, 0x04, 0x4c, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xfc, 0x75, 0x09,
- 0x2e, 0x8b, 0x47, 0x08, 0x3b, 0x46, 0xfe, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2,
- 0xea, 0xeb, 0x14, 0x2e, 0xff, 0x67, 0x10, 0x80, 0x0e, 0x4c, 0x02, 0x40, 0xeb,
- 0x09, 0x80, 0x0e, 0x4c, 0x02, 0x00, 0xeb, 0x02, 0xeb, 0xf0, 0x80, 0x26, 0x4c,
- 0x02, 0x7f, 0x8b, 0x46, 0x04, 0x25, 0x00, 0x10, 0x33, 0xd2, 0x0b, 0xd2, 0x75,
- 0x23, 0x3d, 0x00, 0x10, 0x75, 0x1e, 0x80, 0x0e, 0x4c, 0x02, 0x80, 0x52, 0x68,
- 0x85, 0x00, 0xff, 0x76, 0x0a, 0xff, 0x76, 0x08, 0xe8, 0xa8, 0x01, 0x04, 0x03,
- 0xc0, 0xe0, 0x03, 0x08, 0x06, 0x4d, 0x02, 0xe9, 0x95, 0x00, 0x80, 0x0e, 0x4c,
- 0x02, 0x00, 0x80, 0x26, 0x4c, 0x02, 0xe7, 0x8b, 0x46, 0x08, 0x25, 0x03, 0x00,
- 0x89, 0x46, 0xf8, 0xc7, 0x46, 0xfa, 0x00, 0x00, 0xb9, 0x04, 0x00, 0xbb, 0xec,
- 0x4b, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xf8, 0x75, 0x09, 0x2e, 0x8b, 0x47, 0x08,
- 0x3b, 0x46, 0xfa, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x1e, 0x2e,
- 0xff, 0x67, 0x10, 0x80, 0x0e, 0x4c, 0x02, 0x00, 0xeb, 0x13, 0x80, 0x0e, 0x4c,
- 0x02, 0x08, 0xeb, 0x0c, 0x80, 0x0e, 0x4c, 0x02, 0x10, 0xeb, 0x05, 0x80, 0x0e,
- 0x4c, 0x02, 0x18, 0x80, 0x26, 0x4c, 0x02, 0xdf, 0x8b, 0x46, 0x08, 0x25, 0x04,
- 0x00, 0x89, 0x46, 0xf4, 0xc7, 0x46, 0xf6, 0x00, 0x00, 0xb9, 0x02, 0x00, 0xbb,
- 0xe0, 0x4b, 0x2e, 0x8b, 0x07, 0x3b, 0x46, 0xf4, 0x75, 0x09, 0x2e, 0x8b, 0x47,
- 0x04, 0x3b, 0x46, 0xf6, 0x74, 0x07, 0x83, 0xc3, 0x02, 0xe2, 0xea, 0xeb, 0x10,
- 0x2e, 0xff, 0x67, 0x08, 0x80, 0x0e, 0x4c, 0x02, 0x20, 0xeb, 0x05, 0x80, 0x0e,
- 0x4c, 0x02, 0x00, 0x80, 0x0e, 0x4d, 0x02, 0x01, 0x80, 0x0e, 0x4c, 0x02, 0x01,
- 0xc9, 0xc3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x4b, 0xcf,
- 0x4b, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x79, 0x4b, 0x80, 0x4b, 0x87, 0x4b, 0x8e, 0x4b, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfb, 0x4a, 0x02, 0x4b, 0x09, 0x4b, 0x0b, 0x4b, 0x55, 0x8b, 0xec,
- 0x8b, 0x46, 0x04, 0x0b, 0xc0, 0x74, 0x07, 0x3d, 0x01, 0x00, 0x74, 0x45, 0xeb,
- 0x79, 0xc6, 0x06, 0x81, 0x60, 0x06, 0xc6, 0x06, 0x80, 0x60, 0x06, 0x33, 0xd2,
- 0xeb, 0x01, 0x42, 0x81, 0xfa, 0xf4, 0x01, 0x7c, 0xf9, 0xc6, 0x06, 0x81, 0x60,
- 0x00, 0xc6, 0x06, 0x80, 0x60, 0x00, 0x33, 0xd2, 0xeb, 0x01, 0x42, 0x81, 0xfa,
- 0xf4, 0x01, 0x7c, 0xf9, 0xa0, 0x4c, 0x02, 0xa2, 0x81, 0x60, 0xa0, 0x4d, 0x02,
- 0xa2, 0x80, 0x60, 0x33, 0xd2, 0xeb, 0x01, 0x42, 0x81, 0xfa, 0xf4, 0x01, 0x7c,
- 0xf9, 0xeb, 0x3b, 0xc6, 0x06, 0x00, 0x60, 0x06, 0x33, 0xd2, 0xeb, 0x01, 0x42,
- 0x81, 0xfa, 0xf4, 0x01, 0x7c, 0xf9, 0xc6, 0x06, 0x00, 0x60, 0x00, 0x33, 0xd2,
- 0xeb, 0x01, 0x42, 0x81, 0xfa, 0xf4, 0x01, 0x7c, 0xf9, 0xa0, 0x4c, 0x02, 0xa2,
- 0x88, 0x12, 0xa2, 0x00, 0x60, 0x33, 0xd2, 0xeb, 0x01, 0x42, 0x81, 0xfa, 0xf4,
- 0x01, 0x7c, 0xf9, 0xeb, 0x05, 0xb8, 0xff, 0xff, 0xeb, 0x02, 0x33, 0xc0, 0x5d,
- 0xc3, 0x55, 0x8b, 0xec, 0xa0, 0x00, 0x60, 0xb4, 0x00, 0x50, 0x83, 0x7e, 0x04,
- 0x00, 0x74, 0x05, 0xb8, 0x10, 0x00, 0xeb, 0x03, 0xb8, 0x40, 0x00, 0x8b, 0xd0,
- 0x58, 0x23, 0xc2, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0xb0, 0x00, 0x5d, 0xc3, 0x59,
- 0x0e, 0x51, 0x33, 0xc9, 0xeb, 0x16, 0x59, 0x0e, 0x51, 0xb9, 0x01, 0x00, 0xeb,
- 0x0e, 0x59, 0x0e, 0x51, 0xb9, 0x02, 0x00, 0xeb, 0x06, 0x59, 0x0e, 0x51, 0xb9,
- 0x03, 0x00, 0x55, 0x56, 0x57, 0x8b, 0xec, 0x8b, 0xf9, 0x8b, 0x46, 0x0a, 0x8b,
- 0x56, 0x0c, 0x8b, 0x5e, 0x0e, 0x8b, 0x4e, 0x10, 0x0b, 0xc9, 0x75, 0x08, 0x0b,
- 0xd2, 0x74, 0x69, 0x0b, 0xdb, 0x74, 0x65, 0xf7, 0xc7, 0x01, 0x00, 0x75, 0x1c,
- 0x0b, 0xd2, 0x79, 0x0a, 0xf7, 0xda, 0xf7, 0xd8, 0x83, 0xda, 0x00, 0x83, 0xcf,
- 0x0c, 0x0b, 0xc9, 0x79, 0x0a, 0xf7, 0xd9, 0xf7, 0xdb, 0x83, 0xd9, 0x00, 0x83,
- 0xf7, 0x04, 0x8b, 0xe9, 0xb9, 0x20, 0x00, 0x57, 0x33, 0xff, 0x33, 0xf6, 0xd1,
- 0xe0, 0xd1, 0xd2, 0xd1, 0xd6, 0xd1, 0xd7, 0x3b, 0xfd, 0x72, 0x0b, 0x77, 0x04,
- 0x3b, 0xf3, 0x72, 0x05, 0x2b, 0xf3, 0x1b, 0xfd, 0x40, 0xe2, 0xe7, 0x5b, 0xf7,
- 0xc3, 0x02, 0x00, 0x74, 0x06, 0x8b, 0xc6, 0x8b, 0xd7, 0xd1, 0xeb, 0xf7, 0xc3,
- 0x04, 0x00, 0x74, 0x07, 0xf7, 0xda, 0xf7, 0xd8, 0x83, 0xda, 0x00, 0x5f, 0x5e,
- 0x5d, 0xca, 0x08, 0x00, 0xf7, 0xf3, 0xf7, 0xc7, 0x02, 0x00, 0x74, 0x01, 0x92,
- 0x33, 0xd2, 0xeb, 0xed, 0x5b, 0x0e, 0x53, 0x80, 0xf9, 0x10, 0x73, 0x10, 0x8b,
- 0xd8, 0xd3, 0xe0, 0xd3, 0xe2, 0xf6, 0xd9, 0x80, 0xc1, 0x10, 0xd3, 0xeb, 0x0b,
- 0xd3, 0xcb, 0x80, 0xe9, 0x10, 0x92, 0x33, 0xc0, 0xd3, 0xe2, 0xcb, 0x5b, 0x0e,
- 0x53, 0x80, 0xf9, 0x10, 0x73, 0x10, 0x8b, 0xda, 0xd3, 0xe8, 0xd3, 0xea, 0xf6,
- 0xd9, 0x80, 0xc1, 0x10, 0xd3, 0xe3, 0x0b, 0xc3, 0xcb, 0x80, 0xe9, 0x10, 0x92,
- 0x33, 0xd2, 0xd3, 0xe8, 0xcb, 0x55, 0x8b, 0xec, 0x56, 0x57, 0x1e, 0x07, 0x8b,
- 0x7e, 0x04, 0x8b, 0x76, 0x06, 0x8b, 0x4e, 0x08, 0xd1, 0xe9, 0xfc, 0xf3, 0xa5,
- 0x73, 0x01, 0xa4, 0x8b, 0x46, 0x04, 0x5f, 0x5e, 0x5d, 0xc3, 0x55, 0x8b, 0xec,
- 0x57, 0x1e, 0x07, 0x8b, 0x7e, 0x04, 0x8b, 0x4e, 0x06, 0x8a, 0x46, 0x08, 0x8a,
- 0xe0, 0xfc, 0xf7, 0xc7, 0x01, 0x00, 0x74, 0x04, 0xe3, 0x09, 0xaa, 0x49, 0xd1,
- 0xe9, 0xf3, 0xab, 0x73, 0x01, 0xaa, 0x5f, 0x5d, 0xc3, 0x55, 0x8b, 0xec, 0x56,
- 0x8b, 0x76, 0x04, 0x8a, 0x46, 0x06, 0x50, 0xff, 0x76, 0x08, 0x56, 0xe8, 0xc8,
- 0xff, 0x83, 0xc4, 0x06, 0x8b, 0xc6, 0x5e, 0x5d, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x55,
- 0x4c, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
- 0x22, 0x2a, 0x22, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x34, 0x04, 0x70, 0x04,
- 0x34, 0x04, 0x70, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x34,
- 0x04, 0x70, 0x04, 0x34, 0x04, 0x70, 0x04, 0xac, 0x04, 0x2d, 0x05, 0xac, 0x04,
- 0x2d, 0x05, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09,
- 0x04, 0x09, 0x04, 0x09, 0x04, 0x2e, 0x06, 0x89, 0x05, 0x72, 0x05, 0x89, 0x05,
- 0xd9, 0x04, 0xd9, 0x04, 0xd9, 0x04, 0xd9, 0x04, 0x5a, 0x06, 0x5a, 0x06, 0x5a,
- 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x25, 0x08,
- 0x5a, 0x06, 0x25, 0x08, 0x5a, 0x06, 0x25, 0x08, 0x5a, 0x06, 0xf7, 0x07, 0x5a,
- 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06, 0x5a, 0x06,
- 0x5a, 0x06, 0x5a, 0x06, 0xaa, 0x06, 0x5a, 0x06, 0xdc, 0x06, 0x5a, 0x06, 0x5a,
- 0x06, 0x5a, 0x06, 0xa3, 0x07, 0x5a, 0x06, 0x16, 0x0d, 0x20, 0x0b, 0x20, 0x0b,
- 0x16, 0x0d, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20,
- 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x3e, 0x0c, 0xef, 0x0c, 0x3e, 0x0c, 0xef, 0x0c,
- 0x08, 0x0c, 0x8b, 0x0b, 0x08, 0x0c, 0x8b, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20,
- 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b, 0x20, 0x0b,
- 0x9e, 0x0c, 0x20, 0x0b, 0x9e, 0x0c, 0xec, 0x0a, 0x62, 0x08, 0xec, 0x0a, 0x62,
- 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08,
- 0x62, 0x08, 0x62, 0x08, 0x63, 0x09, 0x9a, 0x0a, 0x63, 0x09, 0x9a, 0x0a, 0x24,
- 0x09, 0xd6, 0x08, 0x24, 0x09, 0xd6, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08,
- 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0x62, 0x08, 0xc9,
- 0x09, 0x62, 0x08, 0xc9, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1b, 0x5b, 0x30, 0x6d, 0x00, 0x1b, 0x5b, 0x35, 0x6d, 0x00, 0x1b, 0x5b, 0x32,
- 0x6d, 0x00, 0x1b, 0x5b, 0x37, 0x6d, 0x00, 0x1b, 0x5b, 0x32, 0x37, 0x6d, 0x00,
- 0x1b, 0x5b, 0x30, 0x4b, 0x00, 0x1b, 0x5b, 0x32, 0x4a, 0x00, 0x1b, 0x5b, 0x31,
- 0x3b, 0x31, 0x48, 0x00, 0x1b, 0x5b, 0x73, 0x00, 0x1b, 0x5b, 0x75, 0x00, 0x1b,
- 0x5b, 0x31, 0x4d, 0x00, 0x1b, 0x5b, 0x31, 0x4c, 0x00, 0x00, 0x87, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x18, 0x00, 0xe2, 0x20, 0x03, 0x10,
- 0x00, 0x00, 0x18, 0x00, 0x50, 0x21, 0x04, 0x10, 0x00, 0x00, 0x18, 0x00, 0x80,
- 0x21, 0x05, 0x10, 0x00, 0x00, 0x24, 0x00, 0x6b, 0x24, 0x06, 0x10, 0x00, 0x00,
- 0x24, 0x00, 0xc4, 0x24, 0x09, 0x10, 0x00, 0x00, 0x88, 0x0f, 0xdf, 0x25, 0x0b,
- 0x10, 0x00, 0x00, 0x1c, 0x00, 0x70, 0x2c, 0x0c, 0x10, 0x00, 0x00, 0x1c, 0x00,
- 0x75, 0x2c, 0x0d, 0x10, 0x00, 0x00, 0x14, 0x00, 0x7a, 0x2c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x61, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x08, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
- 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x69,
- 0x59, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0xb4, 0xd5, 0x9e, 0x73, 0x52, 0x7b, 0x50, 0x79, 0x4e, 0x75, 0x4c, 0x9f, 0xb1,
- 0x05, 0xd2, 0xec, 0x73, 0x45, 0xb0, 0x40, 0xd0, 0xe0, 0x71, 0x3f, 0x32, 0xe4,
- 0x9e, 0x76, 0x3a, 0x7a, 0x38, 0x78, 0x36, 0x9f, 0xb1, 0x05, 0xd2, 0xec, 0x72,
- 0x2f, 0xd0, 0xe4, 0x70, 0x2b, 0xfa, 0xb8, 0xff, 0xff, 0xf9, 0x73, 0x24, 0x8b,
- 0xd8, 0x8b, 0xcb, 0x8b, 0xd1, 0x8e, 0xc2, 0x8c, 0xc6, 0x8e, 0xde, 0x8c, 0xdf,
- 0x8e, 0xd7, 0x8c, 0xd5, 0x8b, 0xe5, 0x73, 0x07, 0x33, 0xc5, 0x75, 0x0a, 0xf8,
- 0xeb, 0xe3, 0x0b, 0xc5, 0x74, 0x21, 0xbd, 0x01, 0x00, 0x2e, 0xc7, 0x06, 0xf8,
- 0x03, 0x20, 0x43, 0x2e, 0xc7, 0x06, 0xfa, 0x03, 0x50, 0x55, 0x2e, 0xc7, 0x06,
- 0xfc, 0x03, 0x20, 0x42, 0x2e, 0xc7, 0x06, 0xfe, 0x03, 0x41, 0x44, 0xeb, 0xe2,
- 0x2e, 0xc7, 0x06, 0xf0, 0x03, 0xeb, 0xfe, 0xfc, 0xfa, 0xba, 0xa0, 0xff, 0xb8,
- 0x38, 0xf0, 0xef, 0xba, 0xa2, 0xff, 0xb8, 0xf8, 0x0f, 0xef, 0xba, 0xa8, 0xff,
- 0xb8, 0xfa, 0x81, 0xef, 0xba, 0xa6, 0xff, 0xb8, 0xfa, 0x13, 0xef, 0xba, 0xa4,
- 0xff, 0xb8, 0x38, 0x10, 0xef, 0xb8, 0x80, 0x11, 0xba, 0xfe, 0xff, 0xef, 0x2e,
- 0xa1, 0xc2, 0x01, 0x2e, 0x3b, 0x06, 0xc0, 0x01, 0x74, 0x1e, 0x2e, 0xc7, 0x06,
- 0xf8, 0x03, 0x20, 0x49, 0x2e, 0xc7, 0x06, 0xfa, 0x03, 0x47, 0x4d, 0x2e, 0xc7,
- 0x06, 0xfc, 0x03, 0x20, 0x42, 0x2e, 0xc7, 0x06, 0xfe, 0x03, 0x41, 0x44, 0xeb,
- 0xe2, 0xb8, 0x00, 0x0a, 0x8e, 0xc0, 0x8c, 0xc8, 0x8e, 0xd8, 0xbe, 0xc6, 0x01,
- 0xb9, 0x12, 0x00, 0x26, 0xa0, 0x00, 0x62, 0x90, 0x90, 0xac, 0x26, 0xa2, 0x00,
- 0x62, 0x90, 0x90, 0xac, 0x26, 0xa2, 0x00, 0x62, 0x90, 0x90, 0xe2, 0xf0, 0xb8,
- 0x00, 0x0a, 0x8e, 0xd8, 0xbe, 0x00, 0x80, 0x8b, 0xfe, 0xbb, 0xff, 0xff, 0x33,
- 0xd2, 0xb9, 0xfe, 0x03, 0x8b, 0xc3, 0xab, 0xad, 0x3b, 0xc3, 0x74, 0x05, 0x83,
- 0xcd, 0x02, 0xeb, 0x15, 0x8b, 0xc2, 0x83, 0xee, 0x02, 0x83, 0xef, 0x02, 0xab,
- 0xad, 0x3b, 0xc2, 0x74, 0x05, 0x83, 0xcd, 0x02, 0xeb, 0x02, 0xe2, 0xde, 0xbf,
- 0x00, 0x80, 0xb8, 0x4f, 0x4b, 0xf7, 0xc5, 0x02, 0x00, 0x74, 0x03, 0xb8, 0x42,
- 0x44, 0xab, 0xb8, 0x44, 0x50, 0xab, 0xf7, 0xc5, 0x02, 0x00, 0x74, 0x08, 0x8b,
- 0xc6, 0x2d, 0x02, 0x00, 0xab, 0xad, 0xab, 0xb8, 0x00, 0x0a, 0x8e, 0xd0, 0xbc,
- 0xe8, 0x3f, 0x2e, 0xa1, 0xbe, 0x01, 0x8b, 0xd8, 0x83, 0xe3, 0xf0, 0x25, 0x0f,
- 0x00, 0x74, 0x03, 0x83, 0xc3, 0x10, 0x2e, 0xa1, 0xc4, 0x01, 0x8b, 0xd0, 0x83,
- 0xe2, 0xf0, 0x25, 0x0f, 0x00, 0x74, 0x03, 0x83, 0xc2, 0x10, 0x8c, 0xc8, 0x8b,
- 0xcb, 0x03, 0xca, 0xc1, 0xe9, 0x04, 0x2b, 0xc1, 0x8e, 0xd8, 0x33, 0xf6, 0xb8,
- 0x40, 0x00, 0x8e, 0xc0, 0x33, 0xff, 0x2e, 0x8b, 0x0e, 0xbe, 0x01, 0x41, 0xd1,
- 0xe9, 0xf3, 0xa5, 0x8c, 0xc8, 0x8b, 0xca, 0xc1, 0xe9, 0x04, 0x2b, 0xc1, 0x8e,
- 0xd8, 0xb8, 0x00, 0x0a, 0x8e, 0xc0, 0x33, 0xf6, 0x33, 0xff, 0x2e, 0x8b, 0x0e,
- 0xc4, 0x01, 0x41, 0xd1, 0xe9, 0xf3, 0xa5, 0x8c, 0xc0, 0x8e, 0xd8, 0xea, 0x74,
- 0x00, 0x40, 0x00, 0x23, 0x4e, 0x52, 0x02, 0x52, 0x02, 0x2a, 0x22, 0x04, 0x44,
- 0x03, 0xc0, 0x05, 0x60, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x50, 0x0c, 0x18, 0x0d,
- 0x00, 0x0e, 0x02, 0x0f, 0x00, 0x03, 0xc1, 0x05, 0x68, 0x0e, 0x03, 0x0f, 0x00,
- 0x01, 0x00, 0x01, 0x10, 0x00, 0x30, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x44, 0x69,
- 0x67, 0x69, 0x20, 0x31, 0x39, 0x39, 0x35, 0x32, 0x31, 0x0e, 0x00, 0x00, 0x00,
- 0x54, 0xac, 0x01, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xac, 0x01, 0x80, 0x44, 0xac, 0x01, 0x80, 0x40, 0xac,
- 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x30, 0xac, 0x01, 0x80, 0x2c, 0xac, 0x01, 0x80, 0x28, 0xac, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0xac, 0x01,
- 0x80, 0x10, 0xac, 0x01, 0x80, 0x04, 0xac, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf8, 0xab, 0x01, 0x80, 0xf4, 0xab,
- 0x01, 0x80, 0xec, 0xab, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0xdc, 0xab, 0x01, 0x80, 0xd4, 0xab, 0x01, 0x80, 0xcc,
- 0xab, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x05, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0xbc, 0xab, 0x01, 0x80, 0xb4, 0xab, 0x01, 0x80, 0xa8, 0xab, 0x01, 0x80,
- 0xa0, 0xab, 0x01, 0x80, 0x98, 0xab, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x88, 0xab,
- 0x01, 0x80, 0x7c, 0xab, 0x01, 0x80, 0x78, 0xab, 0x01, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0xab, 0x01, 0x80, 0x64,
- 0xab, 0x01, 0x80, 0x60, 0xab, 0x01, 0x80, 0x54, 0xab, 0x01, 0x80, 0x4c, 0xab,
- 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0xab, 0x01, 0x80, 0x34, 0xab, 0x01, 0x80,
- 0x78, 0xab, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x24, 0xab, 0x01, 0x80, 0x20, 0xab, 0x01, 0x80, 0x14, 0xab, 0x01,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0a, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xab, 0x01, 0x80, 0x00, 0xab, 0x01, 0x80, 0xf8, 0xaa, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xe8, 0xaa, 0x01, 0x80,
- 0xe4, 0xaa, 0x01, 0x80, 0xdc, 0xaa, 0x01, 0x80, 0xd4, 0xaa, 0x01, 0x80, 0xcc,
- 0xaa, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xbc, 0xaa, 0x01, 0x80, 0xb0, 0xaa, 0x01,
- 0x80, 0xa4, 0xaa, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
- 0x00, 0x00, 0x00, 0x98, 0xaa, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb3, 0x01, 0x80,
- 0x00, 0xb2, 0x01, 0x80, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x94,
- 0xb3, 0x01, 0x80, 0x24, 0xb2, 0x01, 0x80, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0xdc, 0xab, 0x01, 0x80, 0x40, 0xb2, 0x01, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x06, 0x00, 0x00, 0x00, 0xf8, 0xab, 0x01, 0x80, 0x58, 0xb2, 0x01, 0x80,
- 0x00, 0x0e, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x84, 0xb3, 0x01, 0x80, 0x80,
- 0xb2, 0x01, 0x80, 0x00, 0x10, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x78, 0xb3,
- 0x01, 0x80, 0x08, 0xb3, 0x01, 0x80, 0x00, 0x60, 0x00, 0x00, 0x0d, 0x00, 0x00,
- 0x00, 0x60, 0xb3, 0x01, 0x80, 0x90, 0xb2, 0x01, 0x80, 0x00, 0x80, 0x07, 0x00,
- 0x0f, 0x00, 0x00, 0x00, 0x4c, 0xb3, 0x01, 0x80, 0xa0, 0xb2, 0x01, 0x80, 0x20,
- 0x01, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0xe0, 0x01,
- 0x00, 0x00, 0x29, 0x01, 0x03, 0x00, 0x69, 0x01, 0x03, 0x00, 0xa9, 0x01, 0x03,
- 0x00, 0xe9, 0x01, 0x03, 0x00, 0x58, 0x00, 0x21, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x28, 0x00, 0xcc, 0x00, 0x29, 0x00,
- 0xbb, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x10, 0x00, 0x11, 0x00, 0x80,
- 0x00, 0x00, 0xf0, 0x00, 0x00, 0x18, 0x00, 0x01, 0x00, 0x18, 0x00, 0x11, 0x00,
- 0x1c, 0x00, 0x87, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07,
- 0xf0, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00,
- 0x00, 0x00, 0x29, 0x00, 0x02, 0x00, 0x30, 0x00, 0x12, 0x00, 0x31, 0x00, 0x1f,
- 0x00, 0x34, 0x00, 0x0e, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x11, 0x00, 0x80, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25,
- 0x00, 0x00, 0x00, 0x28, 0x00, 0x7e, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x21, 0x00,
- 0x14, 0x00, 0x28, 0x00, 0x60, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x21, 0x00, 0x14,
- 0x00, 0x28, 0x00, 0x40, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x06, 0xf0, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x41, 0x00, 0x01,
- 0xf0, 0x02, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x06, 0xf0,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x45,
- 0x00, 0x01, 0xf0, 0x20, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x05,
- 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x20, 0x00,
- 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x04, 0xf0, 0x00,
- 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00,
- 0x20, 0x00, 0x20, 0x00, 0x2c, 0x00, 0x60, 0x00, 0x2d, 0x00, 0x43, 0x00, 0x01,
- 0xf0, 0x08, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x08, 0xf0,
- 0x00, 0x00, 0x20, 0x00, 0x28, 0x00, 0x2c, 0x00, 0x60, 0x00, 0x2d, 0x00, 0x44,
- 0x00, 0x01, 0xf0, 0x10, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
- 0x08, 0xf0, 0x00, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x2c, 0x00, 0x60, 0x00, 0x2d,
- 0x00, 0x43, 0x00, 0x01, 0xf0, 0x08, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x20, 0x00, 0xc8, 0x00, 0x2c, 0x00, 0x60,
- 0x00, 0x2d, 0x00, 0x44, 0x00, 0x01, 0xf0, 0x10, 0x00, 0x04, 0xf0, 0x00, 0x00,
- 0x00, 0xf0, 0x00, 0x00, 0xac, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x9b, 0x01, 0x80, 0x10, 0xb8, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x4c, 0x9b, 0x01, 0x80, 0x18, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xac, 0x9a, 0x01, 0x80, 0xc0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0xac, 0x9a, 0x01, 0x80, 0xc8, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac,
- 0x9a, 0x01, 0x80, 0xd0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac, 0x9a,
- 0x01, 0x80, 0xe0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac, 0x9a, 0x01,
- 0x80, 0xe8, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac, 0x9a, 0x01, 0x80,
- 0xf0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac, 0x9a, 0x01, 0x80, 0x00,
- 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac, 0x9a, 0x01, 0x80, 0x08, 0xb8,
- 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80, 0x10, 0xb8, 0x01,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80, 0x18, 0xb8, 0x01, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80, 0x20, 0xb8, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80, 0x28, 0xb8, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xc0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xc8, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0x9a, 0x01, 0x80, 0xd0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0,
- 0x9a, 0x01, 0x80, 0xe0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a,
- 0x01, 0x80, 0xe8, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01,
- 0x80, 0xf0, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80,
- 0x00, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08,
- 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x10, 0xb8,
- 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x18, 0xb8, 0x01,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x20, 0xb8, 0x01, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x28, 0xb8, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80, 0x30, 0xb8, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80, 0x38, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0x90, 0x9a, 0x01, 0x80, 0x40, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0x9a, 0x01, 0x80, 0x30, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0,
- 0x9a, 0x01, 0x80, 0x38, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a,
- 0x01, 0x80, 0x40, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01,
- 0x80, 0xd8, 0xb7, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80,
- 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xc0,
- 0xb7, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xc8, 0xb7,
- 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xd0, 0xb7, 0x01,
- 0x80, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xd8, 0xb7, 0x01, 0x80,
- 0x01, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xe0, 0xb7, 0x01, 0x80, 0x01,
- 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xe8, 0xb7, 0x01, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xf0, 0xb7, 0x01, 0x80, 0x01, 0x00, 0x00,
- 0x00, 0xe0, 0x9a, 0x01, 0x80, 0xf8, 0xb7, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00,
- 0xe0, 0x9a, 0x01, 0x80, 0x00, 0xb8, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0xe0,
- 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x9a,
- 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01,
- 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80,
- 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08,
- 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8,
- 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0,
- 0x9a, 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a,
- 0x01, 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9a, 0x01,
- 0x80, 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x14, 0x9b, 0x01, 0x80,
- 0x08, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9b, 0x01, 0x80, 0x08,
- 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x14, 0x9b, 0x01, 0x80, 0x10, 0xb8,
- 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9b, 0x01, 0x80, 0x10, 0xb8, 0x01,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x14, 0x9b, 0x01, 0x80, 0x18, 0xb8, 0x01, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9b, 0x01, 0x80, 0x18, 0xb8, 0x01, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x9b, 0x01, 0x80, 0x20, 0xb8, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x4c, 0x9b, 0x01, 0x80, 0x20, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xf8, 0x9a, 0x01, 0x80, 0x48, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x9b, 0x01, 0x80, 0x48, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x90,
- 0x9a, 0x01, 0x80, 0x48, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9a,
- 0x01, 0x80, 0x50, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01,
- 0x80, 0x58, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9a, 0x01, 0x80,
- 0x60, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x9a, 0x01, 0x80, 0x68,
- 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xac, 0x9a, 0x01, 0x80, 0xd8, 0xb7,
- 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0xac, 0x9a, 0x01, 0x80, 0xf0, 0xb7, 0x01,
- 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x84, 0x36, 0x00, 0x80, 0x10, 0x36, 0x00, 0x80, 0x54,
- 0x36, 0x00, 0x80, 0x84, 0x36, 0x00, 0x80, 0x98, 0x3d, 0x00, 0x80, 0x90, 0x3b,
- 0x00, 0x80, 0x98, 0x3d, 0x00, 0x80, 0x18, 0x3c, 0x00, 0x80, 0xb4, 0x38, 0x00,
- 0x80, 0xe0, 0x37, 0x00, 0x80, 0xb4, 0x38, 0x00, 0x80, 0xd0, 0x3d, 0x00, 0x80,
- 0x24, 0x37, 0x00, 0x80, 0x24, 0x37, 0x00, 0x80, 0x24, 0x37, 0x00, 0x80, 0x24,
- 0x37, 0x00, 0x80, 0xb8, 0x36, 0x00, 0x80, 0xb8, 0x36, 0x00, 0x80, 0xb8, 0x36,
- 0x00, 0x80, 0xb8, 0x36, 0x00, 0x80, 0xb8, 0x36, 0x00, 0x80, 0xb8, 0x36, 0x00,
- 0x80, 0xb8, 0x36, 0x00, 0x80, 0xb8, 0x36, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80,
- 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54,
- 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37,
- 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00,
- 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80,
- 0x54, 0x37, 0x00, 0x80, 0x54, 0x37, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0,
- 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e,
- 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00,
- 0x80, 0x90, 0x3f, 0x00, 0x80, 0xac, 0x3f, 0x00, 0x80, 0x4c, 0x40, 0x00, 0x80,
- 0x24, 0x40, 0x00, 0x80, 0x38, 0x40, 0x00, 0x80, 0x98, 0x40, 0x00, 0x80, 0xa0,
- 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e,
- 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00,
- 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80,
- 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0,
- 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e,
- 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44,
- 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f,
- 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00,
- 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80,
- 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44,
- 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f,
- 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00,
- 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80,
- 0x44, 0x3f, 0x00, 0x80, 0x44, 0x3f, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0xe0, 0x3e, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00,
- 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80,
- 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c,
- 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f,
- 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00,
- 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80,
- 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c,
- 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0x7c, 0x3f,
- 0x00, 0x80, 0x7c, 0x3f, 0x00, 0x80, 0xf4, 0x3e, 0x00, 0x80, 0x08, 0x3f, 0x00,
- 0x80, 0x1c, 0x3f, 0x00, 0x80, 0x30, 0x3f, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80,
- 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0,
- 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e,
- 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00,
- 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80,
- 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0,
- 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e,
- 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00,
- 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80,
- 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0,
- 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80,
- 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c,
- 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e,
- 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00, 0x80, 0x9c, 0x3e, 0x00,
- 0x80, 0x9c, 0x3e, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80,
- 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac,
- 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xdc, 0x3c,
- 0x00, 0x80, 0x58, 0x3d, 0x00, 0x80, 0xec, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00,
- 0x80, 0xac, 0x3c, 0x00, 0x80, 0x20, 0x3d, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80,
- 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac,
- 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c,
- 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00,
- 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80,
- 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c,
- 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00,
- 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80,
- 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98,
- 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c,
- 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00,
- 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80,
- 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98, 0x3c, 0x00, 0x80, 0x98,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00,
- 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80,
- 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac,
- 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c,
- 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00,
- 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80,
- 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac,
- 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c,
- 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00,
- 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80,
- 0xac, 0x3c, 0x00, 0x80, 0xac, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00,
- 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80,
- 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8,
- 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c, 0x00, 0x80, 0xa8, 0x3c,
- 0x00, 0x80, 0x8c, 0x39, 0x00, 0x80, 0x40, 0x43, 0x00, 0x80, 0x90, 0x42, 0x00,
- 0x80, 0x90, 0x42, 0x00, 0x80, 0x8c, 0x39, 0x00, 0x80, 0x40, 0x43, 0x00, 0x80,
- 0x90, 0x42, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0x8c, 0x39, 0x00, 0x80, 0x40,
- 0x43, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0x8c, 0x39,
- 0x00, 0x80, 0x40, 0x43, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0x90, 0x42, 0x00,
- 0x80, 0x50, 0x39, 0x00, 0x80, 0x40, 0x43, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80,
- 0x90, 0x42, 0x00, 0x80, 0x5c, 0x43, 0x00, 0x80, 0x40, 0x43, 0x00, 0x80, 0x90,
- 0x42, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0xd8, 0x41, 0x00, 0x80, 0x40, 0x43,
- 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0xa8, 0x41, 0x00,
- 0x80, 0x40, 0x43, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80, 0x90, 0x42, 0x00, 0x80,
- 0xa0, 0x3e, 0x00, 0x80, 0xcc, 0x3f, 0x00, 0x80, 0xe4, 0x3f, 0x00, 0x80, 0xec,
- 0x3f, 0x00, 0x80, 0xa0, 0x3e, 0x00, 0x80, 0xe8, 0x40, 0x00, 0x80, 0xf4, 0x40,
- 0x00, 0x80, 0xfc, 0x40, 0x00, 0x80, 0x2e, 0x2e, 0x2f, 0x63, 0x6f, 0x6e, 0x63,
- 0x64, 0x69, 0x73, 0x70, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
- 0x2e, 0x2f, 0x63, 0x6f, 0x6e, 0x63, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x63, 0x00,
- 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x63, 0x6f, 0x6e, 0x63, 0x70, 0x72, 0x6f, 0x74,
- 0x2e, 0x63, 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
- 0x6e, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x2e, 0x2e, 0x2f,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x63, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e,
- 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00,
- 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x2e, 0x2e, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x72,
- 0x69, 0x6e, 0x74, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x32, 0x2e, 0x32, 0x20, 0x30, 0x38, 0x2f, 0x31, 0x37, 0x2f,
- 0x39, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x06, 0x5b, 0x4f,
- 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67, 0x00, 0x00, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
- 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61,
- 0x72, 0x64, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x52, 0x65, 0x74, 0x72,
- 0x69, 0x65, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72,
- 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x4e,
- 0x56, 0x52, 0x41, 0x4d, 0x2e, 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00,
- 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x2e, 0x2e, 0x75, 0x73,
- 0x69, 0x6e, 0x67, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x73,
- 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00,
- 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x62, 0x65, 0x20, 0x73, 0x75, 0x72,
- 0x65, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x63, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0d, 0x0a,
- 0x00, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65,
- 0x74, 0x65, 0x72, 0x73, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x76,
- 0x61, 0x6c, 0x69, 0x64, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6e, 0x65,
- 0x63, 0x61, 0x72, 0x64, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76,
- 0x65, 0x2e, 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x69,
- 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
- 0x69, 0x76, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x20, 0x4f,
- 0x2e, 0x4b, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x40,
- 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x4c, 0x65, 0x6e,
- 0x67, 0x74, 0x68, 0x00, 0x48, 0x69, 0x67, 0x68, 0x2f, 0x33, 0x36, 0x64, 0x42,
- 0x00, 0x00, 0x00, 0x4c, 0x6f, 0x77, 0x2f, 0x32, 0x36, 0x64, 0x42, 0x00, 0x00,
- 0x00, 0x00, 0x52, 0x63, 0x76, 0x20, 0x47, 0x61, 0x69, 0x6e, 0x20, 0x4c, 0x69,
- 0x6d, 0x69, 0x74, 0x00, 0x00, 0x2d, 0x32, 0x32, 0x2e, 0x35, 0x64, 0x42, 0x00,
- 0x2d, 0x31, 0x35, 0x64, 0x42, 0x00, 0x00, 0x00, 0x2d, 0x37, 0x2e, 0x35, 0x64,
- 0x42, 0x00, 0x00, 0x30, 0x64, 0x42, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x2d, 0x4f, 0x75, 0x74, 0x00, 0x00, 0x53, 0x68, 0x6f,
- 0x72, 0x74, 0x00, 0x00, 0x00, 0x4c, 0x6f, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00,
- 0x53, 0x70, 0x61, 0x6e, 0x20, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x4e,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x32,
- 0x00, 0x00, 0x45, 0x31, 0x20, 0x53, 0x69, 0x67, 0x2e, 0x20, 0x50, 0x72, 0x6f,
- 0x74, 0x2e, 0x00, 0x00, 0x00, 0x41, 0x6e, 0x61, 0x6c, 0x6f, 0x67, 0x00, 0x00,
- 0x45, 0x31, 0x20, 0x53, 0x69, 0x67, 0x2e, 0x20, 0x4d, 0x65, 0x74, 0x68, 0x6f,
- 0x64, 0x00, 0x00, 0x57, 0x69, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6d,
- 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x4c, 0x53, 0x00,
- 0x00, 0x47, 0x53, 0x00, 0x00, 0x54, 0x31, 0x20, 0x53, 0x69, 0x67, 0x2e, 0x20,
- 0x50, 0x72, 0x6f, 0x74, 0x2e, 0x00, 0x00, 0x00, 0x50, 0x52, 0x49, 0x00, 0x52,
- 0x6f, 0x62, 0x62, 0x65, 0x64, 0x42, 0x69, 0x74, 0x00, 0x00, 0x00, 0x54, 0x31,
- 0x20, 0x53, 0x69, 0x67, 0x2e, 0x20, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x00,
- 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x52, 0x65, 0x63, 0x65,
- 0x69, 0x76, 0x65, 0x00, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x75, 0x74, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x69,
- 0x74, 0x74, 0x65, 0x72, 0x20, 0x41, 0x74, 0x74, 0x6e, 0x2e, 0x00, 0x00, 0x00,
- 0x00, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65,
- 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x53, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x00, 0x00, 0x00, 0x00, 0x42, 0x38, 0x5a, 0x53, 0x00, 0x00,
- 0x00, 0x00, 0x41, 0x4d, 0x49, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x43, 0x6f,
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x4e, 0x6f, 0x6e, 0x2d, 0x43, 0x52, 0x43, 0x27,
- 0x64, 0x00, 0x00, 0x00, 0x43, 0x52, 0x43, 0x27, 0x64, 0x00, 0x00, 0x00, 0x45,
- 0x31, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x46, 0x6d, 0x74, 0x2e, 0x00,
- 0x00, 0x00, 0x45, 0x53, 0x46, 0x00, 0x44, 0x34, 0x00, 0x00, 0x54, 0x31, 0x20,
- 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x46, 0x6d, 0x74, 0x2e, 0x00, 0x00, 0x00,
- 0x45, 0x31, 0x00, 0x00, 0x54, 0x31, 0x00, 0x00, 0x46, 0x72, 0x61, 0x6d, 0x65,
- 0x20, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20,
- 0x42, 0x61, 0x6e, 0x6b, 0x20, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x58, 0x97, 0x01, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x64,
- 0x00, 0x00, 0x5b, 0x25, 0x64, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x25, 0x64,
- 0x3e, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x42, 0x61, 0x6e, 0x6b, 0x20, 0x53, 0x79,
- 0x73, 0x74, 0x65, 0x6d, 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x00, 0x00, 0x00, 0x00,
- 0x49, 0x6e, 0x66, 0x6f, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x4e, 0x56, 0x52,
- 0x41, 0x4d, 0x00, 0x45, 0x45, 0x50, 0x52, 0x4f, 0x4d, 0x20, 0x72, 0x65, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x3a, 0x20, 0x25, 0x78, 0x20, 0x00, 0x00, 0x25, 0x63, 0x0d, 0x0a,
- 0x00, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x49, 0x44, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x3a, 0x20, 0x25, 0x64, 0x0d, 0x0a, 0x00, 0x4e, 0x56, 0x52,
- 0x41, 0x4d, 0x20, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x64, 0x20,
- 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x3a, 0x20, 0x25, 0x78,
- 0x0d, 0x0a, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, 0x20, 0x43, 0x6f, 0x6d, 0x70,
- 0x75, 0x74, 0x65, 0x64, 0x20, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75,
- 0x6d, 0x20, 0x3a, 0x20, 0x25, 0x78, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x49, 0x6e,
- 0x66, 0x6f, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x42, 0x49, 0x4f, 0x53, 0x20,
- 0x64, 0x61, 0x74, 0x61, 0x20, 0x61, 0x72, 0x65, 0x61, 0x00, 0x00, 0x4d, 0x65,
- 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x25,
- 0x64, 0x0d, 0x0a, 0x00, 0x44, 0x61, 0x74, 0x61, 0x20, 0x63, 0x61, 0x63, 0x68,
- 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x3a, 0x20, 0x25, 0x64, 0x0d, 0x0a, 0x00, 0x49, 0x6e, 0x73,
- 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x63, 0x68,
- 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x25, 0x64,
- 0x0d, 0x0a, 0x00, 0x45, 0x45, 0x50, 0x52, 0x4f, 0x4d, 0x20, 0x49, 0x44, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x3a, 0x20, 0x25, 0x78, 0x0d, 0x0a, 0x00, 0x45, 0x45, 0x50, 0x52,
- 0x4f, 0x4d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x25, 0x78, 0x0d,
- 0x0a, 0x00, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x72, 0x65,
- 0x76, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x3a, 0x20, 0x25, 0x78, 0x0d, 0x0a, 0x00, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x6f, 0x72, 0x20, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x20, 0x49, 0x44,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x25, 0x64, 0x0d, 0x0a,
- 0x00, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x49, 0x44, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x3a, 0x20, 0x25, 0x64, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
- 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x42, 0x61, 0x6e, 0x6b, 0x20, 0x45, 0x71, 0x75,
- 0x69, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x00, 0x25,
- 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x20,
- 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x73, 0x6c, 0x6f,
- 0x74, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x57,
- 0x20, 0x52, 0x65, 0x76, 0x20, 0x53, 0x57, 0x20, 0x52, 0x65, 0x76, 0x0d, 0x0a,
- 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, 0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x43,
- 0x61, 0x72, 0x64, 0x00, 0x00, 0x25, 0x78, 0x00, 0x00, 0x25, 0x64, 0x0d, 0x0a,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x62, 0x6f, 0x61,
- 0x72, 0x64, 0x00, 0x25, 0x64, 0x2e, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x43,
- 0x61, 0x72, 0x64, 0x00, 0x00, 0x00, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x53,
- 0x75, 0x70, 0x70, 0x6c, 0x79, 0x0d, 0x0a, 0x00, 0x00, 0x50, 0x6f, 0x77, 0x65,
- 0x72, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x32, 0x20, 0x69, 0x73,
- 0x20, 0x00, 0x00, 0x6e, 0x6f, 0x74, 0x20, 0x00, 0x00, 0x00, 0x00, 0x69, 0x6e,
- 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x0d, 0x0a, 0x00, 0x50, 0x6f, 0x77,
- 0x65, 0x72, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x31, 0x20, 0x69,
- 0x73, 0x20, 0x00, 0x00, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x0d, 0x0a,
- 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
- 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x20, 0x50, 0x6f,
- 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x3e, 0x3d, 0x73, 0x65, 0x6c, 0x65, 0x63,
- 0x74, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0x5d, 0x3d, 0x61,
- 0x63, 0x74, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x25, 0x64, 0x29,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
- 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66,
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e,
- 0x67, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x68, 0x61,
- 0x6e, 0x67, 0x65, 0x20, 0x69, 0x74, 0x73, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63,
- 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
- 0x65, 0x72, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20, 0x63, 0x75,
- 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66,
- 0x6f, 0x72, 0x20, 0x25, 0x73, 0x20, 0x69, 0x73, 0x20, 0x00, 0x00, 0x00, 0x00,
- 0x0d, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c,
- 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x3a,
- 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x25, 0x64, 0x29, 0x20, 0x20, 0x00, 0x00,
- 0x00, 0x48, 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74,
- 0x6f, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65,
- 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x6e, 0x63, 0x68, 0x61,
- 0x6e, 0x67, 0x65, 0x64, 0x2c, 0x0d, 0x0a, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6c,
- 0x65, 0x63, 0x74, 0x20, 0x61, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20,
- 0x74, 0x6f, 0x20, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65,
- 0x20, 0x6e, 0x65, 0x77, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0d, 0x0a, 0x00,
- 0x00, 0x00, 0x48, 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
- 0x74, 0x6f, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
- 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x6e, 0x63, 0x68,
- 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x0d, 0x0a, 0x65, 0x6e,
- 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x55, 0x73, 0x65, 0x20, 0x42, 0x61, 0x63,
- 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x72, 0x61,
- 0x73, 0x65, 0x29, 0x0d, 0x0a, 0x00, 0x00, 0x54, 0x68, 0x61, 0x74, 0x20, 0x69,
- 0x73, 0x6e, 0x27, 0x74, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20,
- 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50, 0x6c,
- 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x0d, 0x0a,
- 0x61, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74,
- 0x68, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x31, 0x20, 0x74, 0x6f,
- 0x20, 0x25, 0x64, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20,
- 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x20, 0x66, 0x6f, 0x72, 0x20, 0x00, 0x00, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69,
- 0x6e, 0x73, 0x20, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20,
- 0x61, 0x73, 0x20, 0x00, 0x00, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65,
- 0x6e, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
- 0x00, 0x00, 0x00, 0x44, 0xac, 0x01, 0x80, 0x40, 0xac, 0x01, 0x80, 0x20, 0xb2,
- 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80, 0x20, 0xb2, 0x01,
- 0x80, 0x20, 0xb2, 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80, 0x3f, 0x00, 0x00, 0x00,
- 0x34, 0xb2, 0x01, 0x80, 0x2c, 0xb2, 0x01, 0x80, 0x41, 0x63, 0x74, 0x69, 0x76,
- 0x65, 0x00, 0x00, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00,
- 0x00, 0x00, 0xd4, 0xab, 0x01, 0x80, 0xcc, 0xab, 0x01, 0x80, 0x50, 0xb2, 0x01,
- 0x80, 0x20, 0xb2, 0x01, 0x80, 0x54, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x00,
- 0xf4, 0xab, 0x01, 0x80, 0xec, 0xab, 0x01, 0x80, 0x78, 0xb2, 0x01, 0x80, 0x20,
- 0xb2, 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80, 0x20, 0xb2,
- 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80, 0x48, 0x44, 0x42, 0x33, 0x00, 0x00, 0x00,
- 0x00, 0x88, 0xb2, 0x01, 0x80, 0x28, 0xac, 0x01, 0x80, 0x44, 0x34, 0x2f, 0x53,
- 0x46, 0x00, 0x00, 0x00, 0xa8, 0xab, 0x01, 0x80, 0xa0, 0xab, 0x01, 0x80, 0xb4,
- 0xab, 0x01, 0x80, 0x98, 0xab, 0x01, 0x80, 0x00, 0xb3, 0x01, 0x80, 0xf0, 0xb2,
- 0x01, 0x80, 0xe0, 0xb2, 0x01, 0x80, 0x78, 0xab, 0x01, 0x80, 0xd8, 0xb2, 0x01,
- 0x80, 0xcc, 0xb2, 0x01, 0x80, 0xc0, 0xb2, 0x01, 0x80, 0x20, 0xb2, 0x01, 0x80,
- 0x57, 0x69, 0x6e, 0x6b, 0x2d, 0x45, 0x26, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x6f, 0x6f, 0x70, 0x2d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x43, 0x4f,
- 0x2d, 0x47, 0x53, 0x00, 0x00, 0x00, 0x49, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61,
- 0x74, 0x65, 0x2d, 0x45, 0x26, 0x4d, 0x00, 0x00, 0x00, 0x47, 0x72, 0x6f, 0x75,
- 0x6e, 0x64, 0x2d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x28,
- 0x4e, 0x6f, 0x6e, 0x65, 0x29, 0x00, 0x00, 0x1c, 0xb3, 0x01, 0x80, 0x10, 0xb3,
- 0x01, 0x80, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x2d, 0x48, 0x61, 0x75, 0x6c, 0x00,
- 0x00, 0x4c, 0x6f, 0x6e, 0x67, 0x2d, 0x48, 0x61, 0x75, 0x6c, 0x00, 0x00, 0x00,
- 0x38, 0xb3, 0x01, 0x80, 0x30, 0xb3, 0x01, 0x80, 0x48, 0x69, 0x67, 0x68, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x6f, 0x77, 0x00, 0xe4, 0xaa, 0x01, 0x80, 0xdc, 0xaa,
- 0x01, 0x80, 0xd4, 0xaa, 0x01, 0x80, 0xcc, 0xaa, 0x01, 0x80, 0x53, 0x69, 0x67,
- 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
- 0x6f, 0x6c, 0x00, 0x00, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x20, 0x41, 0x74,
- 0x74, 0x65, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x61, 0x74,
- 0x68, 0x00, 0x53, 0x70, 0x61, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00,
- 0x00, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x44, 0x26, 0x49, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x70, 0x61, 0x6e, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x00,
- 0x00, 0x00, 0x54, 0x68, 0x65, 0x20, 0x25, 0x73, 0x20, 0x68, 0x61, 0x73, 0x20,
- 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
- 0x25, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x25, 0x64, 0x0d, 0x0a, 0x00, 0x00, 0xac,
- 0xb3, 0x01, 0x80, 0x54, 0x68, 0x65, 0x20, 0x25, 0x73, 0x20, 0x68, 0x61, 0x73,
- 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d,
- 0x20, 0x25, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x25, 0x73, 0x0d, 0x0a, 0x00, 0x00,
- 0xd4, 0xb3, 0x01, 0x80, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x20,
- 0x47, 0x61, 0x69, 0x6e, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x00, 0x0d, 0x0a,
- 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x43, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65,
- 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x7c, 0x00,
- 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x42, 0x61, 0x6e, 0x6b,
- 0x20, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
- 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x69, 0x74,
- 0x20, 0x61, 0x6e, 0x79, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x43,
- 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
- 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x63, 0x76, 0x41, 0x6c, 0x61,
- 0x72, 0x6d, 0x20, 0x20, 0x20, 0x54, 0x78, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x20,
- 0x20, 0x20, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x00, 0x00, 0x00,
- 0xf0, 0xb4, 0x01, 0x80, 0xe8, 0xb4, 0x01, 0x80, 0xe0, 0xb4, 0x01, 0x80, 0xd8,
- 0xb4, 0x01, 0x80, 0x52, 0x65, 0x64, 0x20, 0x20, 0x20, 0x00, 0x00, 0x42, 0x6c,
- 0x75, 0x65, 0x20, 0x20, 0x00, 0x00, 0x59, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x00,
- 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x20, 0x20, 0x00, 0x00, 0x08, 0xb5, 0x01, 0x80,
- 0x00, 0xb5, 0x01, 0x80, 0x4c, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x20, 0x00, 0x50,
- 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x00, 0x38, 0xb5, 0x01, 0x80, 0x30, 0xb5,
- 0x01, 0x80, 0x28, 0xb5, 0x01, 0x80, 0x20, 0xb5, 0x01, 0x80, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x00,
- 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x20, 0x20, 0x00, 0x4e, 0x6f, 0x6e, 0x65, 0x20,
- 0x20, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x42, 0x61, 0x6e, 0x6b, 0x20, 0x53, 0x69,
- 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x69,
- 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20,
- 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61,
- 0x79, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x3d, 0x4f, 0x66,
- 0x66, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x20, 0x2d, 0x3d, 0x4f, 0x6e, 0x68, 0x6f,
- 0x6f, 0x6b, 0x20, 0x20, 0x52, 0x3d, 0x52, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67,
- 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x31,
- 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x32, 0x20, 0x20, 0x43, 0x61, 0x72,
- 0x64, 0x20, 0x33, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x20, 0x34, 0x0d, 0x0a,
- 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x20, 0x20, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x20, 0x20, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x20, 0x20, 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x0d, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x20, 0x20,
- 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x20, 0x20, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x20, 0x20, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x0d, 0x0a, 0x0d, 0x0a,
- 0x00, 0x20, 0x20, 0x00, 0x00, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20,
- 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x21, 0x0d, 0x0a, 0x3a, 0x20, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x69, 0x6e, 0x67,
- 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x00, 0x00,
- 0x00, 0x0d, 0x0a, 0x3a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x54, 0x68, 0x61, 0x74,
- 0x20, 0x69, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69,
- 0x64, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20,
- 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65,
- 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x61, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72,
- 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65,
- 0x20, 0x31, 0x20, 0x74, 0x6f, 0x20, 0x25, 0x64, 0x0d, 0x0a, 0x00, 0x68, 0x65,
- 0x61, 0x64, 0x3d, 0x25, 0x64, 0x00, 0x20, 0x28, 0x25, 0x78, 0x29, 0x20, 0x00,
- 0x00, 0x74, 0x61, 0x69, 0x6c, 0x3d, 0x25, 0x64, 0x00, 0x6d, 0x61, 0x78, 0x3d,
- 0x25, 0x64, 0x00, 0x00, 0x20, 0x28, 0x25, 0x78, 0x29, 0x0d, 0x0a, 0x00, 0x25,
- 0x78, 0x20, 0x00, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6e,
- 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x0d, 0x0a,
- 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x20, 0x64, 0x69, 0x73, 0x70,
- 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x00, 0x20, 0x41, 0x6c, 0x61, 0x72, 0x6d,
- 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x00, 0x00, 0x20, 0x53, 0x69,
- 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x20, 0x00, 0x00, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65,
- 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x3a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a,
- 0x54, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x20,
- 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20,
- 0x00, 0x00, 0x00, 0x3a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d,
- 0x00, 0x00, 0x00, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x09, 0x00, 0x00, 0x14, 0x00, 0x00,
- 0x00, 0xc0, 0x12, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x00, 0x40, 0x38, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00,
- 0x4b, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x64, 0x00,
- 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x6f, 0xfa, 0x00,
- 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0xfa, 0x00, 0x00, 0x00,
- 0x38, 0xc1, 0x01, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x70, 0x82, 0x03, 0x00, 0x58,
- 0x02, 0x00, 0x00, 0xe0, 0x04, 0x07, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xa8, 0x0d,
- 0x0e, 0x00, 0x40, 0x06, 0x00, 0x00, 0xc8, 0xc0, 0x12, 0x00, 0x40, 0x06, 0x00,
- 0x00, 0x00, 0x20, 0x1c, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x80, 0x25, 0x00,
- 0x40, 0x06, 0x00, 0x00, 0x00, 0x40, 0x38, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00,
- 0x20, 0x1c, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x80, 0x25, 0x00, 0xa0, 0x0f,
- 0x00, 0x00, 0x00, 0x40, 0x38, 0x00, 0x88, 0x13, 0x00, 0x00, 0x00, 0x80, 0x70,
- 0x00, 0x88, 0x13, 0x00, 0x00, 0x80, 0x96, 0x98, 0x00, 0x88, 0x13, 0x00, 0x00,
- 0x4d, 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x00,
- 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x73, 0x63, 0x61, 0x70, 0x72, 0x6f, 0x74,
- 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x86, 0x15, 0x8b, 0x40, 0x28, 0x23,
- 0x29, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x33, 0x2e, 0x37, 0x20, 0x20, 0x39, 0x2f, 0x32, 0x30, 0x2f, 0x39,
- 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x72, 0x61,
- 0x6e, 0x67, 0x65, 0x2e, 0x63, 0x20, 0x20, 0x31, 0x2e, 0x31, 0x20, 0x20, 0x35,
- 0x2f, 0x31, 0x38, 0x2f, 0x39, 0x32, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f,
- 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33,
- 0x2e, 0x38, 0x20, 0x20, 0x34, 0x2f, 0x31, 0x38, 0x2f, 0x39, 0x34, 0x00, 0x40,
- 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x6b, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x32, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61,
- 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f, 0x30, 0x33, 0x2f, 0x32,
- 0x35, 0x20, 0x32, 0x31, 0x3a, 0x34, 0x36, 0x3a, 0x34, 0x39, 0x20, 0x24, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x62, 0x69, 0x6f, 0x73, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x32, 0x2e, 0x38, 0x20, 0x20, 0x36, 0x2f, 0x33,
- 0x30, 0x2f, 0x39, 0x32, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63,
- 0x64, 0x69, 0x73, 0x70, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x34,
- 0x20, 0x20, 0x39, 0x2f, 0x32, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x63, 0x6f, 0x6e, 0x63, 0x66, 0x65, 0x70, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x25, 0x49, 0x25, 0x20, 0x20, 0x25, 0x47, 0x25, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x73, 0x20, 0x20,
- 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39,
- 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e, 0x63, 0x6d, 0x61, 0x69,
- 0x6e, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x32, 0x2e, 0x34, 0x20, 0x20, 0x33,
- 0x2f, 0x34, 0x2f, 0x39, 0x32, 0x00, 0x40, 0x28, 0x23, 0x29, 0x63, 0x6f, 0x6e,
- 0x63, 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e,
- 0x31, 0x20, 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28,
- 0x23, 0x29, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x24, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e,
- 0x31, 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31,
- 0x39, 0x39, 0x36, 0x2f, 0x31, 0x30, 0x2f, 0x32, 0x38, 0x20, 0x31, 0x39, 0x3a,
- 0x33, 0x32, 0x3a, 0x33, 0x38, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x64,
- 0x65, 0x66, 0x73, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x33, 0x2e, 0x33, 0x20, 0x20, 0x31, 0x2f, 0x39, 0x2f, 0x39, 0x35, 0x00, 0x40,
- 0x28, 0x23, 0x29, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x68, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x38, 0x20, 0x20, 0x34, 0x2f, 0x31, 0x34,
- 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29, 0x65, 0x78, 0x63, 0x65, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20,
- 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x66, 0x65, 0x70, 0x6d, 0x73, 0x67, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x32, 0x2e, 0x33, 0x20, 0x20, 0x38, 0x2f, 0x31, 0x33, 0x2f, 0x39, 0x32,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x66, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2e, 0x68,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x20, 0x34, 0x2f,
- 0x36, 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29, 0x68, 0x6f, 0x73, 0x74,
- 0x63, 0x6f, 0x6d, 0x6d, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x33,
- 0x20, 0x20, 0x33, 0x2f, 0x32, 0x32, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x69, 0x75, 0x73, 0x63, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x32, 0x2e, 0x33, 0x20, 0x20, 0x35, 0x2f, 0x32, 0x34, 0x2f, 0x39,
- 0x32, 0x00, 0x40, 0x28, 0x23, 0x29, 0x6d, 0x62, 0x63, 0x6f, 0x6e, 0x2e, 0x6d,
- 0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x20, 0x38,
- 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x6d, 0x69,
- 0x64, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24,
- 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x32,
- 0x20, 0x24, 0x20, 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39,
- 0x39, 0x37, 0x2f, 0x30, 0x35, 0x2f, 0x31, 0x35, 0x20, 0x32, 0x33, 0x3a, 0x32,
- 0x38, 0x3a, 0x33, 0x36, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x6d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32,
- 0x2e, 0x31, 0x20, 0x20, 0x33, 0x2f, 0x31, 0x2f, 0x39, 0x32, 0x00, 0x40, 0x28,
- 0x23, 0x29, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x33, 0x2e, 0x31, 0x20, 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f,
- 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x73,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x31, 0x20, 0x20,
- 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x70,
- 0x62, 0x75, 0x73, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x33, 0x2e, 0x32, 0x20, 0x20, 0x34, 0x2f, 0x36, 0x2f, 0x39, 0x34, 0x00, 0x40,
- 0x28, 0x23, 0x29, 0x70, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x31, 0x36, 0x20, 0x20, 0x31, 0x2f, 0x39,
- 0x2f, 0x39, 0x35, 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x72, 0x69, 0x6e, 0x74,
- 0x66, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x52, 0x65, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x20, 0x24, 0x20,
- 0x20, 0x24, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x31, 0x39, 0x39, 0x37, 0x2f,
- 0x30, 0x34, 0x2f, 0x30, 0x32, 0x20, 0x31, 0x37, 0x3a, 0x31, 0x34, 0x3a, 0x30,
- 0x36, 0x20, 0x24, 0x00, 0x40, 0x28, 0x23, 0x29, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x63, 0x6f, 0x6c, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20,
- 0x20, 0x38, 0x2f, 0x32, 0x33, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x68, 0x20, 0x20, 0x20,
- 0x20, 0x33, 0x2e, 0x31, 0x20, 0x20, 0x34, 0x2f, 0x31, 0x39, 0x2f, 0x39, 0x33,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x31, 0x30, 0x20, 0x20, 0x31,
- 0x30, 0x2f, 0x31, 0x37, 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29, 0x72,
- 0x77, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x32, 0x2e, 0x31, 0x20, 0x20, 0x33, 0x2f, 0x31, 0x2f, 0x39, 0x32, 0x00, 0x40,
- 0x28, 0x23, 0x29, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x20, 0x34, 0x2f, 0x36, 0x2f,
- 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x61, 0x2e, 0x68, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x34, 0x20, 0x20,
- 0x34, 0x2f, 0x31, 0x39, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73,
- 0x63, 0x61, 0x70, 0x72, 0x6f, 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x33, 0x2e, 0x32, 0x20, 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00,
- 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x68, 0x65, 0x64, 0x2e, 0x63, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20, 0x20, 0x38, 0x2f, 0x32,
- 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23, 0x29, 0x73, 0x63, 0x68, 0x65,
- 0x64, 0x2e, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x31,
- 0x20, 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40, 0x28, 0x23,
- 0x29, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x33, 0x2e, 0x33, 0x20, 0x20, 0x37, 0x2f, 0x37, 0x2f, 0x39, 0x33,
- 0x00, 0x40, 0x28, 0x23, 0x29, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x68, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x35, 0x20, 0x20, 0x31, 0x30,
- 0x2f, 0x31, 0x37, 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29, 0x74, 0x69,
- 0x6d, 0x65, 0x72, 0x69, 0x6e, 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20, 0x33,
- 0x2e, 0x31, 0x20, 0x20, 0x38, 0x2f, 0x32, 0x30, 0x2f, 0x39, 0x33, 0x00, 0x40,
- 0x28, 0x23, 0x29, 0x75, 0x61, 0x72, 0x74, 0x2e, 0x63, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x38, 0x20, 0x20, 0x35, 0x2f, 0x32, 0x34,
- 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29, 0x75, 0x61, 0x72, 0x74, 0x2e,
- 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x2e, 0x32, 0x20,
- 0x20, 0x39, 0x2f, 0x31, 0x32, 0x2f, 0x39, 0x34, 0x00, 0x40, 0x28, 0x23, 0x29,
- 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x33, 0x2e, 0x33, 0x20, 0x20, 0x37, 0x2f, 0x31, 0x2f, 0x39, 0x34, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 8317cd8..0f7dd7c 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -279,7 +279,7 @@ TUNABLE_INT("hw.igb.enable_aim", &igb_enable_aim);
static int igb_low_latency = IGB_LOW_LATENCY;
TUNABLE_INT("hw.igb.low_latency", &igb_low_latency);
static int igb_ave_latency = IGB_AVE_LATENCY;
-TUNABLE_INT("hw.igb.ave_latency", &igb_low_latency);
+TUNABLE_INT("hw.igb.ave_latency", &igb_ave_latency);
static int igb_bulk_latency = IGB_BULK_LATENCY;
TUNABLE_INT("hw.igb.bulk_latency", &igb_bulk_latency);
diff --git a/sys/dev/exca/exca.c b/sys/dev/exca/exca.c
index 6edae38..f90a3e7 100644
--- a/sys/dev/exca/exca.c
+++ b/sys/dev/exca/exca.c
@@ -179,43 +179,39 @@ exca_do_mem_map(struct exca_softc *sc, int win)
struct mem_map_index_st *map;
struct pccard_mem_handle *mem;
uint32_t offset;
- int mem8 = 1 /* mem->kind == PCCARD_A_MEM_ATTR */;
+ uint32_t mem16;
+ uint32_t attrmem;
map = &mem_map_index[win];
mem = &sc->mem[win];
+ mem16 = (mem->kind & PCCARD_MEM_16BIT) ?
+ EXCA_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT : 0;
+ attrmem = (mem->kind & PCCARD_MEM_ATTR) ?
+ EXCA_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0;
offset = ((mem->cardaddr >> EXCA_CARDMEM_ADDRX_SHIFT) -
(mem->addr >> EXCA_SYSMEM_ADDRX_SHIFT)) & 0x3fff;
exca_putb(sc, map->sysmem_start_lsb,
- (mem->addr >> EXCA_SYSMEM_ADDRX_SHIFT) & 0xff);
+ mem->addr >> EXCA_SYSMEM_ADDRX_SHIFT);
exca_putb(sc, map->sysmem_start_msb,
((mem->addr >> (EXCA_SYSMEM_ADDRX_SHIFT + 8)) &
- EXCA_SYSMEM_ADDRX_START_MSB_ADDR_MASK) |
- (mem8 ? 0 : EXCA_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT));
+ EXCA_SYSMEM_ADDRX_START_MSB_ADDR_MASK) | mem16);
exca_putb(sc, map->sysmem_stop_lsb,
- ((mem->addr + mem->realsize - 1) >>
- EXCA_SYSMEM_ADDRX_SHIFT) & 0xff);
+ (mem->addr + mem->realsize - 1) >> EXCA_SYSMEM_ADDRX_SHIFT);
exca_putb(sc, map->sysmem_stop_msb,
(((mem->addr + mem->realsize - 1) >>
(EXCA_SYSMEM_ADDRX_SHIFT + 8)) &
EXCA_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
EXCA_SYSMEM_ADDRX_STOP_MSB_WAIT2);
-
- exca_putb(sc, map->sysmem_win,
- (mem->addr >> EXCA_MEMREG_WIN_SHIFT) & 0xff);
+ exca_putb(sc, map->sysmem_win, mem->addr >> EXCA_MEMREG_WIN_SHIFT);
exca_putb(sc, map->cardmem_lsb, offset & 0xff);
- exca_putb(sc, map->cardmem_msb, (((offset >> 8) & 0xff) &
- EXCA_CARDMEM_ADDRX_MSB_ADDR_MASK) |
- ((mem->kind == PCCARD_A_MEM_ATTR) ?
- EXCA_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0));
+ exca_putb(sc, map->cardmem_msb, ((offset >> 8) &
+ EXCA_CARDMEM_ADDRX_MSB_ADDR_MASK) | attrmem);
-#ifdef EXCA_DEBUG
- if (mem->kind == PCCARD_A_MEM_ATTR)
- printf("attribtue memory\n");
- else
- printf("common memory\n");
-#endif
+ DPRINTF("%s %d-bit memory",
+ mem->kind & PCCARD_MEM_ATTR ? "attribute" : "common",
+ mem->kind & PCCARD_MEM_16BIT ? 16 : 8);
exca_setb(sc, EXCA_ADDRWIN_ENABLE, map->memenable |
EXCA_ADDRWIN_ENABLE_MEMCS16);
@@ -230,11 +226,11 @@ exca_do_mem_map(struct exca_softc *sc, int win)
r5 = exca_getb(sc, map->cardmem_msb);
r6 = exca_getb(sc, map->cardmem_lsb);
r7 = exca_getb(sc, map->sysmem_win);
- printf("exca_do_mem_map win %d: %02x%02x %02x%02x "
- "%02x%02x %02x (%08x+%06x.%06x*%06x)\n",
+ printf("exca_do_mem_map win %d: %#02x%#02x %#02x%#02x "
+ "%#02x%#02x %#02x (%#08x+%#06x.%#06x*%#06x) flags %#x\n",
win, r1, r2, r3, r4, r5, r6, r7,
mem->addr, mem->size, mem->realsize,
- mem->cardaddr);
+ mem->cardaddr, mem->kind);
}
#endif
}
@@ -260,10 +256,20 @@ exca_mem_map(struct exca_softc *sc, int kind, struct resource *res)
}
if (win >= EXCA_MEM_WINS)
return (ENOSPC);
- if (((rman_get_start(res) >> EXCA_MEMREG_WIN_SHIFT) & 0xff) != 0 &&
- (sc->flags & EXCA_HAS_MEMREG_WIN) == 0) {
- device_printf(sc->dev, "Does not support mapping above 24M.");
- return (EINVAL);
+ if (sc->flags & EXCA_HAS_MEMREG_WIN) {
+#ifdef _LP64
+ if (rman_get_start(res) >> (EXCA_MEMREG_WIN_SHIFT + 8) != 0) {
+ device_printf(sc->dev,
+ "Does not support mapping above 4GB.");
+ return (EINVAL);
+ }
+#endif
+ } else {
+ if (rman_get_start(res) >> EXCA_MEMREG_WIN_SHIFT != 0) {
+ device_printf(sc->dev,
+ "Does not support mapping above 16M.");
+ return (EINVAL);
+ }
}
sc->mem[win].cardaddr = 0;
@@ -342,7 +348,21 @@ exca_mem_set_flags(struct exca_softc *sc, struct resource *res, uint32_t flags)
return (ENOENT);
}
- sc->mem[win].kind = flags;
+ switch (flags)
+ {
+ case PCCARD_A_MEM_ATTR:
+ sc->mem[win].kind |= PCCARD_MEM_ATTR;
+ break;
+ case PCCARD_A_MEM_COM:
+ sc->mem[win].kind &= ~PCCARD_MEM_ATTR;
+ break;
+ case PCCARD_A_MEM_16BIT:
+ sc->mem[win].kind |= PCCARD_MEM_16BIT;
+ break;
+ case PCCARD_A_MEM_8BIT:
+ sc->mem[win].kind &= ~PCCARD_MEM_16BIT;
+ break;
+ }
exca_do_mem_map(sc, win);
return (0);
}
@@ -801,7 +821,7 @@ exca_activate_resource(struct exca_softc *exca, device_t child, int type,
err = exca_io_map(exca, PCCARD_WIDTH_AUTO, res);
break;
case SYS_RES_MEMORY:
- err = exca_mem_map(exca, PCCARD_A_MEM_COM, res);
+ err = exca_mem_map(exca, 0, res);
break;
}
if (err)
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c
index ae0d5d3..8137df6 100644
--- a/sys/dev/firewire/firewire.c
+++ b/sys/dev/firewire/firewire.c
@@ -430,6 +430,31 @@ firewire_attach(device_t dev)
fwdev_makedev(sc);
+ fc->crom_src_buf = (struct crom_src_buf *)malloc(
+ sizeof(struct crom_src_buf),
+ M_FW, M_NOWAIT | M_ZERO);
+ if (fc->crom_src_buf == NULL) {
+ device_printf(fc->dev, "%s: Malloc Failure crom src buff\n", __func__);
+ return ENOMEM;
+ }
+ fc->topology_map = (struct fw_topology_map *)malloc(
+ sizeof(struct fw_topology_map),
+ M_FW, M_NOWAIT | M_ZERO);
+ if (fc->topology_map == NULL) {
+ device_printf(fc->dev, "%s: Malloc Failure topology map\n", __func__);
+ free(fc->crom_src_buf, M_FW);
+ return ENOMEM;
+ }
+ fc->speed_map = (struct fw_speed_map *)malloc(
+ sizeof(struct fw_speed_map),
+ M_FW, M_NOWAIT | M_ZERO);
+ if (fc->speed_map == NULL) {
+ device_printf(fc->dev, "%s: Malloc Failure speed map\n", __func__);
+ free(fc->crom_src_buf, M_FW);
+ free(fc->topology_map, M_FW);
+ return ENOMEM;
+ }
+
mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF);
mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF);
CALLOUT_INIT(&fc->timeout_callout);
@@ -451,7 +476,9 @@ firewire_attach(device_t dev)
bus_generic_attach(dev);
/* bus_reset */
+ FW_GLOCK(fc);
fw_busreset(fc, FWBUSNOTREADY);
+ FW_GUNLOCK(fc);
fc->ibr(fc);
return 0;
@@ -642,11 +669,6 @@ fw_init_crom(struct firewire_comm *fc)
{
struct crom_src *src;
- fc->crom_src_buf = (struct crom_src_buf *)
- malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO);
- if (fc->crom_src_buf == NULL)
- return;
-
src = &fc->crom_src_buf->src;
bzero(src, sizeof(struct crom_src));
@@ -663,7 +685,7 @@ fw_init_crom(struct firewire_comm *fc)
src->businfo.cyc_clk_acc = 100;
src->businfo.max_rec = fc->maxrec;
src->businfo.max_rom = MAXROM_4;
- src->businfo.generation = 1;
+ src->businfo.generation = 0;
src->businfo.link_spd = fc->speed;
src->businfo.eui64.hi = fc->eui.hi;
@@ -682,9 +704,6 @@ fw_reset_crom(struct firewire_comm *fc)
struct crom_src *src;
struct crom_chunk *root;
- if (fc->crom_src_buf == NULL)
- fw_init_crom(fc);
-
buf = fc->crom_src_buf;
src = fc->crom_src;
root = fc->crom_root;
@@ -715,18 +734,18 @@ fw_busreset(struct firewire_comm *fc, uint32_t new_status)
struct firewire_dev_comm *fdc;
struct crom_src *src;
device_t *devlistp;
- void *newrom;
int i, devcnt;
- switch(fc->status){
- case FWBUSMGRELECT:
+ FW_GLOCK_ASSERT(fc);
+ if (fc->status == FWBUSMGRELECT)
callout_stop(&fc->bmr_callout);
- break;
- default:
- break;
- }
+
fc->status = new_status;
fw_reset_csr(fc);
+
+ if (fc->status == FWBUSNOTREADY)
+ fw_init_crom(fc);
+
fw_reset_crom(fc);
if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) {
@@ -739,19 +758,19 @@ fw_busreset(struct firewire_comm *fc, uint32_t new_status)
free(devlistp, M_TEMP);
}
- newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO);
src = &fc->crom_src_buf->src;
- crom_load(src, (uint32_t *)newrom, CROMSIZE);
- if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
- /* bump generation and reload */
- src->businfo.generation ++;
- /* generation must be between 0x2 and 0xF */
- if (src->businfo.generation < 2)
- src->businfo.generation ++;
- crom_load(src, (uint32_t *)newrom, CROMSIZE);
- bcopy(newrom, (void *)fc->config_rom, CROMSIZE);
- }
- free(newrom, M_FW);
+ /*
+ * If the old config rom needs to be overwritten,
+ * bump the businfo.generation indicator to
+ * indicate that we need to be reprobed
+ */
+ if (bcmp(src, fc->config_rom, CROMSIZE) != 0) {
+ /* generation is a 2 bit field */
+ /* valid values are only from 0 - 3 */
+ src->businfo.generation = 1;
+ bcopy(src, (void *)fc->config_rom, CROMSIZE);
+ } else
+ src->businfo.generation = 0;
}
/* Call once after reboot */
@@ -807,13 +826,7 @@ void fw_init(struct firewire_comm *fc)
fc->ir[i]->maxq = FWMAXQUEUE;
fc->it[i]->maxq = FWMAXQUEUE;
}
-/* Initialize csr registers */
- fc->topology_map = (struct fw_topology_map *)malloc(
- sizeof(struct fw_topology_map),
- M_FW, M_NOWAIT | M_ZERO);
- fc->speed_map = (struct fw_speed_map *)malloc(
- sizeof(struct fw_speed_map),
- M_FW, M_NOWAIT | M_ZERO);
+
CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
CSRARC(fc, TOPO_MAP + 4) = 1;
CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
@@ -1559,7 +1572,7 @@ fw_explore_node(struct fw_device *dfwdev)
/* unchanged ? */
if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) {
if (firewire_debug)
- printf("node%d: crom unchanged\n", node);
+ device_printf(fc->dev, "node%d: crom unchanged\n", node);
return (0);
}
diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c
index 1c2573b..258ba1b 100644
--- a/sys/dev/firewire/fwohci.c
+++ b/sys/dev/firewire/fwohci.c
@@ -1003,7 +1003,7 @@ again:
if (maxdesc < db_tr->dbcnt) {
maxdesc = db_tr->dbcnt;
if (firewire_debug)
- device_printf(sc->fc.dev, "maxdesc: %d\n", maxdesc);
+ device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc);
}
/* last db */
LAST_DB(db_tr, db);
@@ -1842,6 +1842,7 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
struct firewire_comm *fc = (struct firewire_comm *)sc;
uint32_t node_id, plen;
+ FW_GLOCK_ASSERT(fc);
if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
fc->status = FWBUSRESET;
/* Disable bus reset interrupt until sid recv. */
@@ -1884,8 +1885,8 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
plen = OREAD(sc, OHCI_SID_CNT);
fc->nodeid = node_id & 0x3f;
- device_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
- node_id, (plen >> 16) & 0xff);
+ device_printf(fc->dev, "node_id=0x%08x, SelfID Count=%d, ",
+ fc->nodeid, (plen >> 16) & 0xff);
if (!(node_id & OHCI_NODE_VALID)) {
printf("Bus reset failure\n");
goto sidout;
@@ -1996,9 +1997,11 @@ fwohci_task_busreset(void *arg, int pending)
{
struct fwohci_softc *sc = (struct fwohci_softc *)arg;
+ FW_GLOCK(&sc->fc);
fw_busreset(&sc->fc, FWBUSRESET);
OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
+ FW_GUNLOCK(&sc->fc);
}
static void
@@ -2010,6 +2013,10 @@ fwohci_task_sid(void *arg, int pending)
int i, plen;
+ /*
+ * We really should have locking
+ * here. Not sure why it's not
+ */
plen = OREAD(sc, OHCI_SID_CNT);
if (plen & OHCI_SID_ERR) {
@@ -2029,14 +2036,13 @@ fwohci_task_sid(void *arg, int pending)
}
for (i = 0; i < plen / 4; i ++)
buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i+1]);
-#if 1 /* XXX needed?? */
+
/* pending all pre-bus_reset packets */
fwohci_txd(sc, &sc->atrq);
fwohci_txd(sc, &sc->atrs);
fwohci_arcv(sc, &sc->arrs, -1);
fwohci_arcv(sc, &sc->arrq, -1);
fw_drain_txq(fc);
-#endif
fw_sidrcv(fc, buf, plen);
free(buf, M_FW);
}
@@ -2061,6 +2067,7 @@ fwohci_check_stat(struct fwohci_softc *sc)
{
uint32_t stat, irstat, itstat;
+ FW_GLOCK_ASSERT(&sc->fc);
stat = OREAD(sc, FWOHCI_INTSTAT);
if (stat == 0xffffffff) {
device_printf(sc->fc.dev,
@@ -2090,29 +2097,24 @@ fwohci_check_stat(struct fwohci_softc *sc)
return (FILTER_HANDLED);
}
-int
-fwohci_filt(void *arg)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)arg;
-
- if (!(sc->intmask & OHCI_INT_EN)) {
- /* polling mode */
- return (FILTER_STRAY);
- }
- return (fwohci_check_stat(sc));
-}
-
void
fwohci_intr(void *arg)
{
- fwohci_filt(arg);
+ struct fwohci_softc *sc = (struct fwohci_softc *)arg;
+
+ FW_GLOCK(&sc->fc);
+ fwohci_check_stat(sc);
+ FW_GUNLOCK(&sc->fc);
}
void
fwohci_poll(struct firewire_comm *fc, int quick, int count)
{
struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+
+ FW_GLOCK(fc);
fwohci_check_stat(sc);
+ FW_GUNLOCK(fc);
}
static void
@@ -2466,6 +2468,7 @@ fwohci_ibr(struct firewire_comm *fc)
device_printf(fc->dev, "Initiate bus reset\n");
sc = (struct fwohci_softc *)fc;
+ FW_GLOCK(fc);
/*
* Make sure our cached values from the config rom are
* initialised.
@@ -2486,6 +2489,7 @@ fwohci_ibr(struct firewire_comm *fc)
fun |= FW_PHY_ISBR | FW_PHY_RHB;
fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
#endif
+ FW_GUNLOCK(fc);
}
void
diff --git a/sys/dev/firewire/fwohci_pci.c b/sys/dev/firewire/fwohci_pci.c
index b21bb28..ea46dbc 100644
--- a/sys/dev/firewire/fwohci_pci.c
+++ b/sys/dev/firewire/fwohci_pci.c
@@ -334,14 +334,11 @@ fwohci_pci_attach(device_t self)
return ENXIO;
}
-
err = bus_setup_intr(self, sc->irq_res,
- INTR_TYPE_NET | INTR_MPSAFE,
-#if FWOHCI_INTFILT
- fwohci_filt, NULL, sc, &sc->ih);
-#else
- NULL, (driver_intr_t *) fwohci_intr, sc, &sc->ih);
-#endif
+ INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, (driver_intr_t *) fwohci_intr,
+ sc, &sc->ih);
+
#if defined(__DragonFly__) || __FreeBSD_version < 500000
/* XXX splcam() should mask this irq for sbp.c*/
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_CAM,
diff --git a/sys/dev/firewire/fwohcivar.h b/sys/dev/firewire/fwohcivar.h
index d0ee9f6..6f97290 100644
--- a/sys/dev/firewire/fwohcivar.h
+++ b/sys/dev/firewire/fwohcivar.h
@@ -37,12 +37,6 @@
#include <sys/taskqueue.h>
-#if defined(__DragonFly__) || __FreeBSD_version < 700043
-#define FWOHCI_INTFILT 0
-#else
-#define FWOHCI_INTFILT 1
-#endif
-
typedef struct fwohci_softc {
struct firewire_comm fc;
bus_space_tag_t bst;
@@ -84,7 +78,6 @@ typedef struct fwohci_softc {
} fwohci_softc_t;
void fwohci_intr (void *arg);
-int fwohci_filt (void *arg);
int fwohci_init (struct fwohci_softc *, device_t);
void fwohci_poll (struct firewire_comm *, int, int);
void fwohci_reset (struct fwohci_softc *, device_t);
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c
index b4d89d5..e13ec85 100644
--- a/sys/dev/firewire/sbp.c
+++ b/sys/dev/firewire/sbp.c
@@ -493,6 +493,7 @@ END_DEBUG
/* lost device */
sbp_cam_detach_sdev(sdev);
sbp_free_sdev(sdev);
+ target->luns[lun] = NULL;
}
}
@@ -781,7 +782,9 @@ END_DEBUG
SBP_UNLOCK(sbp);
}
sdev->status = SBP_DEV_RETRY;
- sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET);
+ sbp_cam_detach_sdev(sdev);
+ sbp_free_sdev(sdev);
+ target->luns[i] = NULL;
break;
case SBP_DEV_PROBE:
case SBP_DEV_TOATTACH:
@@ -1255,11 +1258,18 @@ END_DEBUG
htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
+ /*
+ * sbp_xfer_free() will attempt to acquire
+ * the SBP lock on entrance. Also, this removes
+ * a LOR between the firewire layer and sbp
+ */
+ SBP_UNLOCK(sdev->target->sbp);
if(fw_asyreq(xfer->fc, -1, xfer) != 0){
sbp_xfer_free(xfer);
ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ocb->ccb);
}
+ SBP_LOCK(sdev->target->sbp);
}
static void
@@ -2123,6 +2133,7 @@ sbp_free_sdev(struct sbp_dev *sdev)
sdev->ocb[i].dmamap);
fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma);
free(sdev, M_SBP);
+ sdev = NULL;
}
static void
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 9a6851c..4a21ad0 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -255,7 +255,7 @@ static int fxp_serial_ifmedia_upd(struct ifnet *ifp);
static void fxp_serial_ifmedia_sts(struct ifnet *ifp,
struct ifmediareq *ifmr);
static int fxp_miibus_readreg(device_t dev, int phy, int reg);
-static void fxp_miibus_writereg(device_t dev, int phy, int reg,
+static int fxp_miibus_writereg(device_t dev, int phy, int reg,
int value);
static void fxp_load_ucode(struct fxp_softc *sc);
static int sysctl_int_range(SYSCTL_HANDLER_ARGS,
@@ -2545,7 +2545,8 @@ fxp_new_rfabuf(struct fxp_softc *sc, struct fxp_rx *rxp)
return (error);
}
- bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map);
+ if (rxp->rx_mbuf != NULL)
+ bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map);
tmp_map = sc->spare_map;
sc->spare_map = rxp->rx_map;
rxp->rx_map = tmp_map;
@@ -2641,7 +2642,7 @@ fxp_miibus_readreg(device_t dev, int phy, int reg)
return (value & 0xffff);
}
-static void
+static int
fxp_miibus_writereg(device_t dev, int phy, int reg, int value)
{
struct fxp_softc *sc = device_get_softc(dev);
@@ -2657,6 +2658,7 @@ fxp_miibus_writereg(device_t dev, int phy, int reg, int value)
if (count <= 0)
device_printf(dev, "fxp_miibus_writereg: timed out\n");
+ return (0);
}
static int
diff --git a/sys/dev/hifn/hifn7751.c b/sys/dev/hifn/hifn7751.c
index d3a66e6..c227f77 100644
--- a/sys/dev/hifn/hifn7751.c
+++ b/sys/dev/hifn/hifn7751.c
@@ -98,7 +98,7 @@ static int hifn_attach(device_t);
static int hifn_detach(device_t);
static int hifn_suspend(device_t);
static int hifn_resume(device_t);
-static void hifn_shutdown(device_t);
+static int hifn_shutdown(device_t);
static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
static int hifn_freesession(device_t, u_int64_t);
@@ -691,12 +691,13 @@ hifn_detach(device_t dev)
* Stop all chip I/O so that the kernel's probe routines don't
* get confused by errant DMAs when rebooting.
*/
-static void
+static int
hifn_shutdown(device_t dev)
{
#ifdef notyet
hifn_stop(device_get_softc(dev));
#endif
+ return (0);
}
/*
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index 8d17679..214e42c 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -530,9 +530,11 @@ struct iap_event_descr {
#define IAP_F_CC2 (1 << 1) /* CPU: Core2 family */
#define IAP_F_CC2E (1 << 2) /* CPU: Core2 Extreme only */
#define IAP_F_CA (1 << 3) /* CPU: Atom */
-#define IAP_F_FM (1 << 4) /* Fixed mask */
+#define IAP_F_I7 (1 << 4) /* CPU: Core i7 */
+#define IAP_F_FM (1 << 5) /* Fixed mask */
-#define IAP_F_ALLCPUS (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA)
+#define IAP_F_ALLCPUS \
+ (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA | IAP_F_I7)
/* Sub fields of UMASK that this event supports. */
#define IAP_M_CORE (1 << 0) /* Core specificity */
@@ -569,13 +571,13 @@ static struct iap_event_descr iap_events[] = {
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),
+ IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
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),
+ IAPDESCR(04H_01H, 0x04, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
IAPDESCR(04H_02H, 0x04, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(04H_08H, 0x04, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -590,8 +592,8 @@ static struct iap_event_descr iap_events[] = {
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),
- IAPDESCR(08H_02H, 0x08, 0x02, 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),
+ 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_05H, 0x08, 0x05, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_06H, 0x08, 0x06, IAP_F_FM | IAP_F_CA),
@@ -599,15 +601,15 @@ static struct iap_event_descr iap_events[] = {
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(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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(0CH_01H, 0x0C, 0x01, IAP_F_FM | IAP_F_CC2),
+ IAPDESCR(0CH_01H, 0x0C, 0x01, IAP_F_FM | IAP_F_CC2 | IAP_F_I7),
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),
+ IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
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),
@@ -615,20 +617,20 @@ static struct iap_event_descr iap_events[] = {
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),
+ IAPDESCR(12H_01H, 0x12, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
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),
+ IAPDESCR(13H_01H, 0x13, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
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),
+ IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
IAPDESCR(18H_00H, 0x18, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
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),
+ IAPDESCR(19H_01H, 0x19, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
IAPDESCR(19H_02H, 0x19, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(21H, 0x21, IAP_M_CORE, IAP_F_ALLCPUS),
@@ -674,7 +676,7 @@ static struct iap_event_descr iap_events[] = {
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),
+ 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),
@@ -685,8 +687,8 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(48H_00H, 0x48, 0x00, 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),
- IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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(4BH_00H, 0x4B, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
IAPDESCR(4BH_01H, 0x4B, 0x01, IAP_F_FM | IAP_F_ALLCPUS),
@@ -760,8 +762,8 @@ static struct iap_event_descr iap_events[] = {
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),
- IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA),
+ 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(81H_00H, 0x81, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
@@ -816,10 +818,10 @@ static struct iap_event_descr iap_events[] = {
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),
+ 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),
+ 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),
@@ -835,8 +837,8 @@ static struct iap_event_descr iap_events[] = {
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),
- IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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(C0H_08H, 0xC0, 0x08, IAP_F_FM | IAP_F_CC2E),
@@ -845,22 +847,22 @@ 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),
- IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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_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),
- IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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),
- IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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(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),
@@ -872,11 +874,11 @@ static struct iap_event_descr iap_events[] = {
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),
- IAPDESCR(C7H_02H, 0xC7, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C7H_04H, 0xC7, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C7H_08H, 0xC7, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C7H_10H, 0xC7, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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_1FH, 0xC7, 0x1F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C8H_00H, 0xC8, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
@@ -889,15 +891,15 @@ 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),
- IAPDESCR(CBH_02H, 0xCB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CBH_04H, 0xCB, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CBH_08H, 0xCB, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CBH_10H, 0xCB, 0x10, IAP_F_FM | 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(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),
+ 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),
@@ -905,20 +907,20 @@ static struct iap_event_descr iap_events[] = {
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),
- IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ 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(D2H_10H, 0xD2, 0x10, IAP_F_FM | IAP_F_CC2E),
- IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
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),
+ IAPDESCR(D5H_01H, 0xD5, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7),
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),
@@ -951,7 +953,7 @@ 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),
+ IAPDESCR(E0H_01H, 0xE0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7),
IAPDESCR(E2H_00H, 0xE2, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(E4H_00H, 0xE4, 0x00, IAP_F_FM | IAP_F_ALLCPUS),
@@ -960,7 +962,244 @@ static struct iap_event_descr iap_events[] = {
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)
+ 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(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),
};
static const int niap_events = sizeof(iap_events) / sizeof(iap_events[0]);
@@ -1113,6 +1352,9 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
case PMC_CPU_INTEL_CORE2EXTREME:
cpuflag = IAP_F_CC2 | IAP_F_CC2E;
break;
+ case PMC_CPU_INTEL_COREI7:
+ cpuflag = IAP_F_I7;
+ break;
}
for (n = 0, ie = iap_events; n < niap_events; n++, ie++)
diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c
index 49031c3..cb2834f 100644
--- a/sys/dev/hwpmc/hwpmc_intel.c
+++ b/sys/dev/hwpmc/hwpmc_intel.c
@@ -130,6 +130,10 @@ pmc_intel_initialize(void)
cputype = PMC_CPU_INTEL_ATOM;
nclasses = 3;
break;
+ case 0x1A:
+ cputype = PMC_CPU_INTEL_COREI7;
+ nclasses = 3;
+ break;
}
break;
#if defined(__i386__) || defined(__amd64__)
@@ -169,6 +173,7 @@ pmc_intel_initialize(void)
case PMC_CPU_INTEL_CORE:
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
+ case PMC_CPU_INTEL_COREI7:
error = pmc_core_initialize(pmc_mdep, ncpus);
break;
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index 430d95d..05078af 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -738,10 +738,245 @@ __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_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)
#define PMC_EV_IAP_FIRST PMC_EV_IAP_EVENT_02H_81H
-#define PMC_EV_IAP_LAST PMC_EV_IAP_EVENT_F8H_00H
+#define PMC_EV_IAP_LAST PMC_EV_IAP_EVENT_FDH_40H
/*
* Map "architectural" event names to event ids.
@@ -1378,6 +1613,309 @@ __PMC_EV_ALIAS("UOPS_RETIRED.STD_STA", IAP_EVENT_C2H_02H) \
__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.
+ */
+#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("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)
+
/* timestamp counters. */
#define __PMC_EV_TSC() \
__PMC_EV(TSC, TSC)
diff --git a/sys/dev/ichsmb/ichsmb.c b/sys/dev/ichsmb/ichsmb.c
index d902442..5ff54db 100644
--- a/sys/dev/ichsmb/ichsmb.c
+++ b/sys/dev/ichsmb/ichsmb.c
@@ -182,7 +182,7 @@ ichsmb_quick(device_t dev, u_char slave, int how)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_QUICK;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | (how == SMB_QREAD ?
+ slave | (how == SMB_QREAD ?
ICH_XMIT_SLVA_READ : ICH_XMIT_SLVA_WRITE));
bus_write_1(sc->io_res, ICH_HST_CNT,
ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
@@ -208,7 +208,7 @@ ichsmb_sendb(device_t dev, u_char slave, char byte)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_WRITE);
+ slave | ICH_XMIT_SLVA_WRITE);
bus_write_1(sc->io_res, ICH_HST_CMD, byte);
bus_write_1(sc->io_res, ICH_HST_CNT,
ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
@@ -230,7 +230,7 @@ ichsmb_recvb(device_t dev, u_char slave, char *byte)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_READ);
+ slave | ICH_XMIT_SLVA_READ);
bus_write_1(sc->io_res, ICH_HST_CNT,
ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR)
@@ -253,7 +253,7 @@ ichsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_WRITE);
+ slave | ICH_XMIT_SLVA_WRITE);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_D0, byte);
bus_write_1(sc->io_res, ICH_HST_CNT,
@@ -277,7 +277,7 @@ ichsmb_writew(device_t dev, u_char slave, char cmd, short word)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_WRITE);
+ slave | ICH_XMIT_SLVA_WRITE);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_D0, word & 0xff);
bus_write_1(sc->io_res, ICH_D1, word >> 8);
@@ -301,7 +301,7 @@ ichsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_READ);
+ slave | ICH_XMIT_SLVA_READ);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_HST_CNT,
ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
@@ -324,7 +324,7 @@ ichsmb_readw(device_t dev, u_char slave, char cmd, short *word)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_READ);
+ slave | ICH_XMIT_SLVA_READ);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_HST_CNT,
ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
@@ -352,7 +352,7 @@ ichsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_PROC_CALL;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_WRITE);
+ slave | ICH_XMIT_SLVA_WRITE);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_D0, sdata & 0xff);
bus_write_1(sc->io_res, ICH_D1, sdata >> 8);
@@ -403,7 +403,7 @@ ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_WRITE);
+ slave | ICH_XMIT_SLVA_WRITE);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_D0, count);
bus_write_1(sc->io_res, ICH_BLOCK_DB, buf[0]);
@@ -434,7 +434,7 @@ ichsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
mtx_lock(&sc->mutex);
sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK;
bus_write_1(sc->io_res, ICH_XMIT_SLVA,
- (slave << 1) | ICH_XMIT_SLVA_READ);
+ slave | ICH_XMIT_SLVA_READ);
bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
bus_write_1(sc->io_res, ICH_D0, *count); /* XXX? */
bus_write_1(sc->io_res, ICH_HST_CNT,
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index a85effe..0005db4 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -101,6 +101,17 @@ int ndisusb_halt = 1;
SYSCTL_INT(_hw_ndisusb, OID_AUTO, halt, CTLFLAG_RW, &ndisusb_halt, 0,
"Halt NDIS USB driver when it's attached");
+/* 0 - 30 dBm to mW conversion table */
+const uint16_t dBm2mW[] = {
+ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
+ 3, 4, 4, 4, 5, 6, 6, 7, 8, 9,
+ 10, 11, 13, 14, 16, 18, 20, 22, 25, 28,
+ 32, 35, 40, 45, 50, 56, 63, 71, 79, 89,
+ 100, 112, 126, 141, 158, 178, 200, 224, 251, 282,
+ 316, 355, 398, 447, 501, 562, 631, 708, 794, 891,
+ 1000
+};
+
MODULE_DEPEND(ndis, ether, 1, 1, 1);
MODULE_DEPEND(ndis, wlan, 1, 1, 1);
MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
@@ -739,7 +750,7 @@ ndis_attach(dev)
ic->ic_ifp = ifp;
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_DS;
- ic->ic_caps = IEEE80211_C_STA | IEEE80211_C_IBSS;
+ ic->ic_caps = IEEE80211_C_STA | IEEE80211_C_IBSS | IEEE80211_C_TXPMGT;
setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
len = 0;
r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
@@ -855,13 +866,13 @@ nonettypes:
IEEE80211_RATE_BASIC|22);
}
if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
- TESTSETRATE(IEEE80211_MODE_11G, 47);
+ TESTSETRATE(IEEE80211_MODE_11G, 48);
TESTSETRATE(IEEE80211_MODE_11G, 72);
TESTSETRATE(IEEE80211_MODE_11G, 96);
TESTSETRATE(IEEE80211_MODE_11G, 108);
}
if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
- TESTSETRATE(IEEE80211_MODE_11A, 47);
+ TESTSETRATE(IEEE80211_MODE_11A, 48);
TESTSETRATE(IEEE80211_MODE_11A, 72);
TESTSETRATE(IEEE80211_MODE_11A, 96);
TESTSETRATE(IEEE80211_MODE_11A, 108);
@@ -2312,6 +2323,13 @@ ndis_setstate_80211(sc)
arg = NDIS_80211_POWERMODE_CAM;
ndis_set_info(sc, OID_802_11_POWER_MODE, &arg, &len);
+ /* Set TX power */
+ if (ic->ic_txpowlimit < sizeof(dBm2mW)) {
+ len = sizeof(arg);
+ arg = dBm2mW[ic->ic_txpowlimit];
+ ndis_set_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
+ }
+
/*
* Default encryption mode to off, authentication
* to open and privacy to 'accept everything.'
@@ -2778,6 +2796,17 @@ ndis_getstate_80211(sc)
ic->ic_flags |= IEEE80211_F_PMGTON;
}
+ /* Get TX power */
+ len = sizeof(arg);
+ rval = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len);
+
+ if (!rval) {
+ for (i = 0; i < sizeof(dBm2mW); i++)
+ if (dBm2mW[i] >= arg)
+ break;
+ ic->ic_txpowlimit = i;
+ }
+
/*
* Use the current association information to reflect
* what channel we're on.
diff --git a/sys/dev/iicbus/ad7418.c b/sys/dev/iicbus/ad7418.c
index fe4abb8..3875307 100644
--- a/sys/dev/iicbus/ad7418.c
+++ b/sys/dev/iicbus/ad7418.c
@@ -82,7 +82,7 @@ ad7418_probe(device_t dev)
{
/* XXX really probe? */
device_set_desc(dev, "Analog Devices AD7418 ADC");
- return (0);
+ return (BUS_PROBE_NOWILDCARD);
}
static int
diff --git a/sys/dev/iicbus/ds1672.c b/sys/dev/iicbus/ds1672.c
index a2c4577..1169271 100644
--- a/sys/dev/iicbus/ds1672.c
+++ b/sys/dev/iicbus/ds1672.c
@@ -61,7 +61,7 @@ ds1672_probe(device_t dev)
{
/* XXX really probe? */
device_set_desc(dev, "Dallas Semiconductor DS1672 RTC");
- return (0);
+ return (BUS_PROBE_NOWILDCARD);
}
static int
diff --git a/sys/dev/iicbus/icee.c b/sys/dev/iicbus/icee.c
index 29a27b1..93c03ad 100644
--- a/sys/dev/iicbus/icee.c
+++ b/sys/dev/iicbus/icee.c
@@ -86,7 +86,7 @@ icee_probe(device_t dev)
{
/* XXX really probe? -- not until we know the size... */
device_set_desc(dev, "I2C EEPROM");
- return (0);
+ return (BUS_PROBE_NOWILDCARD);
}
static int
diff --git a/sys/dev/iicbus/if_ic.c b/sys/dev/iicbus/if_ic.c
index 1c48f71..2457a9f 100644
--- a/sys/dev/iicbus/if_ic.c
+++ b/sys/dev/iicbus/if_ic.c
@@ -153,7 +153,7 @@ ic_alloc_buffers(struct ic_softc *sc, int mtu)
static int
icprobe(device_t dev)
{
- return (0);
+ return (BUS_PROBE_NOWILDCARD);
}
/*
diff --git a/sys/dev/iicbus/iic.c b/sys/dev/iicbus/iic.c
index 6d3cb63..673d635 100644
--- a/sys/dev/iicbus/iic.c
+++ b/sys/dev/iicbus/iic.c
@@ -116,7 +116,11 @@ iic_identify(driver_t *driver, device_t parent)
static int
iic_probe(device_t dev)
{
+ if (iicbus_get_addr(dev) > 0)
+ return (ENXIO);
+
device_set_desc(dev, "I2C generic I/O");
+
return (0);
}
@@ -364,6 +368,11 @@ iicioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
}
free(usrbufs, M_TEMP);
break;
+
+ case I2CRPTSTART:
+ error = iicbus_repeated_start(parent, s->slave, 0);
+ break;
+
default:
error = ENOTTY;
}
diff --git a/sys/dev/iicbus/iic.h b/sys/dev/iicbus/iic.h
index 471f976..bc29fa0 100644
--- a/sys/dev/iicbus/iic.h
+++ b/sys/dev/iicbus/iic.h
@@ -60,5 +60,6 @@ struct iic_rdwr_data {
#define I2CWRITE _IOW('i', 4, struct iiccmd) /* send data */
#define I2CREAD _IOW('i', 5, struct iiccmd) /* receive data */
#define I2CRDWR _IOW('i', 6, struct iic_rdwr_data) /* General read/write interface */
+#define I2CRPTSTART _IOW('i', 7, struct iiccmd) /* repeated start */
#endif
diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c
index de64874..a0c73a3 100644
--- a/sys/dev/iicbus/iicbus.c
+++ b/sys/dev/iicbus/iicbus.c
@@ -53,7 +53,9 @@ iicbus_probe(device_t dev)
{
device_set_desc(dev, "Philips I2C bus");
- return (0);
+
+ /* Allow other subclasses to override this driver. */
+ return (BUS_PROBE_GENERIC);
}
#if SCAN_IICBUS
@@ -266,3 +268,5 @@ driver_t iicbus_driver = {
devclass_t iicbus_devclass;
MODULE_VERSION(iicbus, IICBUS_MODVER);
+DRIVER_MODULE(iicbus, iichb, iicbus_driver, iicbus_devclass, 0, 0);
+
diff --git a/sys/dev/iicbus/iicsmb.c b/sys/dev/iicbus/iicsmb.c
index 196735c..a442a23 100644
--- a/sys/dev/iicbus/iicsmb.c
+++ b/sys/dev/iicbus/iicsmb.c
@@ -149,7 +149,7 @@ static int
iicsmb_probe(device_t dev)
{
device_set_desc(dev, "SMBus over I2C bridge");
- return (0);
+ return (BUS_PROBE_NOWILDCARD);
}
static int
diff --git a/sys/dev/ipmi/ipmi_acpi.c b/sys/dev/ipmi/ipmi_acpi.c
index e2518eb..1bd3a64 100644
--- a/sys/dev/ipmi/ipmi_acpi.c
+++ b/sys/dev/ipmi/ipmi_acpi.c
@@ -104,7 +104,7 @@ ipmi_acpi_attach(device_t dev)
case SSIF_MODE:
if (ACPI_FAILURE(acpi_GetInteger(devh, "_ADR", &flags)))
return (ENXIO);
- info.address = flags >> 1;
+ info.address = flags;
device_printf(dev, "SSIF interface not supported on ACPI\n");
return (0);
default:
diff --git a/sys/dev/ipmi/ipmi_smbios.c b/sys/dev/ipmi/ipmi_smbios.c
index d9fcff8..31424d6 100644
--- a/sys/dev/ipmi/ipmi_smbios.c
+++ b/sys/dev/ipmi/ipmi_smbios.c
@@ -154,10 +154,10 @@ smbios_t38_proc_info(uint8_t *p, char **table, struct ipmi_get_info *info)
case SSIF_MODE:
if ((s->base_address & 0xffffffffffffff00) != 0) {
printf("SMBIOS: Invalid SSIF SMBus address, using BMC I2C slave address instead\n");
- info->address = s->i2c_slave_address >> 1;
+ info->address = s->i2c_slave_address;
break;
}
- info->address = IPMI_BAR_ADDR(s->base_address) >> 1;
+ info->address = IPMI_BAR_ADDR(s->base_address);
break;
default:
return;
diff --git a/sys/dev/kbdmux/kbdmux.c b/sys/dev/kbdmux/kbdmux.c
index a979def..7a47683 100644
--- a/sys/dev/kbdmux/kbdmux.c
+++ b/sys/dev/kbdmux/kbdmux.c
@@ -1363,7 +1363,7 @@ kbdmux_modevent(module_t mod, int type, void *data)
break;
}
- return (0);
+ return (error);
}
DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c
index a5a722b..c52778c 100644
--- a/sys/dev/lmc/if_lmc.c
+++ b/sys/dev/lmc/if_lmc.c
@@ -5643,10 +5643,11 @@ fbsd_detach(device_t dev)
return 0; /* no error */
}
-static void
+static int
fbsd_shutdown(device_t dev)
{
shutdown_card(device_get_softc(dev));
+ return 0;
}
static int
diff --git a/sys/dev/lmc/if_lmc.h b/sys/dev/lmc/if_lmc.h
index c78b162..a2127d7 100644
--- a/sys/dev/lmc/if_lmc.h
+++ b/sys/dev/lmc/if_lmc.h
@@ -1642,7 +1642,7 @@ static void detach_card(softc_t *);
#ifdef __FreeBSD__
static int fbsd_probe(device_t);
static int fbsd_detach(device_t);
-static void fbsd_shutdown(device_t);
+static int fbsd_shutdown(device_t);
static int fbsd_attach(device_t);
#endif /* __FreeBSD__ */
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index bb9e64b..99b18b1 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -1133,13 +1133,15 @@ xmdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread
mdinit(sc);
return (0);
case MDIOCDETACH:
- if (mdio->md_mediasize != 0 || mdio->md_options != 0)
+ if (mdio->md_mediasize != 0 ||
+ (mdio->md_options & ~MD_FORCE) != 0)
return (EINVAL);
sc = mdfind(mdio->md_unit);
if (sc == NULL)
return (ENOENT);
- if (sc->opencount != 0 && !(sc->flags & MD_FORCE))
+ if (sc->opencount != 0 && !(sc->flags & MD_FORCE) &&
+ !(mdio->md_options & MD_FORCE))
return (EBUSY);
return (mddestroy(sc, td));
case MDIOCQUERY:
diff --git a/sys/dev/mge/if_mge.c b/sys/dev/mge/if_mge.c
index 1d9bda5..8555090 100644
--- a/sys/dev/mge/if_mge.c
+++ b/sys/dev/mge/if_mge.c
@@ -69,14 +69,11 @@ __FBSDID("$FreeBSD$");
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
-#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
-#define MGE_VER2 1
-#endif
-
#define MV_PHY_ADDR_BASE 8
#include <dev/mge/if_mgevar.h>
#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
#include "miibus_if.h"
@@ -103,6 +100,10 @@ static void mge_start_locked(struct ifnet *ifp);
static void mge_watchdog(struct mge_softc *sc);
static int mge_ioctl(struct ifnet *ifp, u_long command, caddr_t data);
+static uint32_t mge_tfut_ipg(uint32_t val, int ver);
+static uint32_t mge_rx_ipg(uint32_t val, int ver);
+static void mge_ver_params(struct mge_softc *sc);
+
static void mge_intrs_ctrl(struct mge_softc *sc, int enable);
static void mge_intr_rx(void *arg);
static void mge_intr_rx_locked(struct mge_softc *sc, int count);
@@ -206,6 +207,57 @@ mge_get_mac_address(struct mge_softc *sc, uint8_t *addr)
addr[5] = (mac_l & 0x000000ff);
}
+static uint32_t
+mge_tfut_ipg(uint32_t val, int ver)
+{
+
+ switch (ver) {
+ case 1:
+ return ((val & 0x3fff) << 4);
+ case 2:
+ default:
+ return ((val & 0xffff) << 4);
+ }
+}
+
+static uint32_t
+mge_rx_ipg(uint32_t val, int ver)
+{
+
+ switch (ver) {
+ case 1:
+ return ((val & 0x3fff) << 8);
+ case 2:
+ default:
+ return (((val & 0x8000) << 10) | ((val & 0x7fff) << 7));
+ }
+}
+
+static void
+mge_ver_params(struct mge_softc *sc)
+{
+ uint32_t d, r;
+
+ soc_id(&d, &r);
+ if (d == MV_DEV_88F6281 || d == MV_DEV_MV78100) {
+ sc->mge_ver = 2;
+ sc->mge_mtu = 0x4e8;
+ sc->mge_tfut_ipg_max = 0xFFFF;
+ sc->mge_rx_ipg_max = 0xFFFF;
+ sc->mge_tx_arb_cfg = 0xFC0000FF;
+ sc->mge_tx_tok_cfg = 0xFFFF7FFF;
+ sc->mge_tx_tok_cnt = 0x3FFFFFFF;
+ } else {
+ sc->mge_ver = 1;
+ sc->mge_mtu = 0x458;
+ sc->mge_tfut_ipg_max = 0x3FFF;
+ sc->mge_rx_ipg_max = 0x3FFF;
+ sc->mge_tx_arb_cfg = 0x000000FF;
+ sc->mge_tx_tok_cfg = 0x3FFFFFFF;
+ sc->mge_tx_tok_cnt = 0x3FFFFFFF;
+ }
+}
+
static void
mge_set_mac_address(struct mge_softc *sc)
{
@@ -564,6 +616,9 @@ mge_attach(device_t dev)
if (device_get_unit(dev) == 0)
sc_mge0 = sc;
+ /* Set chip version-dependent parameters */
+ mge_ver_params(sc);
+
/* Initialize mutexes */
mtx_init(&sc->transmit_lock, device_get_nameunit(dev), "mge TX lock", MTX_DEF);
mtx_init(&sc->receive_lock, device_get_nameunit(dev), "mge RX lock", MTX_DEF);
@@ -797,23 +852,25 @@ mge_init_locked(void *arg)
/* Setup multicast filters */
mge_setup_multicast(sc);
-#if defined(MGE_VER2)
- MGE_WRITE(sc, MGE_PORT_SERIAL_CTRL1, MGE_RGMII_EN);
- MGE_WRITE(sc, MGE_FIXED_PRIO_CONF, MGE_FIXED_PRIO_EN(0));
-#endif
+ if (sc->mge_ver == 2) {
+ MGE_WRITE(sc, MGE_PORT_SERIAL_CTRL1, MGE_RGMII_EN);
+ MGE_WRITE(sc, MGE_FIXED_PRIO_CONF, MGE_FIXED_PRIO_EN(0));
+ }
+
/* Initialize TX queue configuration registers */
- MGE_WRITE(sc, MGE_TX_TOKEN_COUNT(0), MGE_TX_TOKEN_Q0_DFLT);
- MGE_WRITE(sc, MGE_TX_TOKEN_CONF(0), MGE_TX_TOKEN_Q0_DFLT);
- MGE_WRITE(sc, MGE_TX_ARBITER_CONF(0), MGE_TX_ARB_Q0_DFLT);
+ MGE_WRITE(sc, MGE_TX_TOKEN_COUNT(0), sc->mge_tx_tok_cnt);
+ MGE_WRITE(sc, MGE_TX_TOKEN_CONF(0), sc->mge_tx_tok_cfg);
+ MGE_WRITE(sc, MGE_TX_ARBITER_CONF(0), sc->mge_tx_arb_cfg);
+ /* Clear TX queue configuration registers for unused queues */
for (i = 1; i < 7; i++) {
- MGE_WRITE(sc, MGE_TX_TOKEN_COUNT(i), MGE_TX_TOKEN_Q1_7_DFLT);
- MGE_WRITE(sc, MGE_TX_TOKEN_CONF(i), MGE_TX_TOKEN_Q1_7_DFLT);
- MGE_WRITE(sc, MGE_TX_ARBITER_CONF(i), MGE_TX_ARB_Q1_7_DFLT);
+ MGE_WRITE(sc, MGE_TX_TOKEN_COUNT(i), 0);
+ MGE_WRITE(sc, MGE_TX_TOKEN_CONF(i), 0);
+ MGE_WRITE(sc, MGE_TX_ARBITER_CONF(i), 0);
}
/* Set default MTU */
- MGE_WRITE(sc, MGE_MTU, MGE_MTU_DEFAULT);
+ MGE_WRITE(sc, sc->mge_mtu, 0);
/* Port configuration */
MGE_WRITE(sc, MGE_PORT_CONFIG,
@@ -1688,12 +1745,12 @@ mge_set_rxic(struct mge_softc *sc)
{
uint32_t reg;
- if (sc->rx_ic_time > MGE_SDMA_RX_IPG_MAX)
- sc->rx_ic_time = MGE_SDMA_RX_IPG_MAX;
+ if (sc->rx_ic_time > sc->mge_rx_ipg_max)
+ sc->rx_ic_time = sc->mge_rx_ipg_max;
reg = MGE_READ(sc, MGE_SDMA_CONFIG);
- reg &= ~MGE_SDMA_RX_IPG(MGE_SDMA_RX_IPG_MAX);
- reg |= MGE_SDMA_RX_IPG(sc->rx_ic_time);
+ reg &= ~mge_rx_ipg(sc->mge_rx_ipg_max, sc->mge_ver);
+ reg |= mge_rx_ipg(sc->rx_ic_time, sc->mge_ver);
MGE_WRITE(sc, MGE_SDMA_CONFIG, reg);
}
@@ -1702,12 +1759,12 @@ mge_set_txic(struct mge_softc *sc)
{
uint32_t reg;
- if (sc->tx_ic_time > MGE_TX_FIFO_URGENT_TRSH_IPG_MAX)
- sc->tx_ic_time = MGE_TX_FIFO_URGENT_TRSH_IPG_MAX;
+ if (sc->tx_ic_time > sc->mge_tfut_ipg_max)
+ sc->tx_ic_time = sc->mge_tfut_ipg_max;
reg = MGE_READ(sc, MGE_TX_FIFO_URGENT_TRSH);
- reg &= ~MGE_TX_FIFO_URGENT_TRSH_IPG(MGE_TX_FIFO_URGENT_TRSH_IPG_MAX);
- reg |= MGE_TX_FIFO_URGENT_TRSH_IPG(sc->tx_ic_time);
+ reg &= ~mge_tfut_ipg(sc->mge_tfut_ipg_max, sc->mge_ver);
+ reg |= mge_tfut_ipg(sc->tx_ic_time, sc->mge_ver);
MGE_WRITE(sc, MGE_TX_FIFO_URGENT_TRSH, reg);
}
@@ -1715,9 +1772,10 @@ static int
mge_sysctl_ic(SYSCTL_HANDLER_ARGS)
{
struct mge_softc *sc = (struct mge_softc *)arg1;
- uint32_t time = (arg2 == MGE_IC_RX) ? sc->rx_ic_time : sc->tx_ic_time;
+ uint32_t time;
int error;
+ time = (arg2 == MGE_IC_RX) ? sc->rx_ic_time : sc->tx_ic_time;
error = sysctl_handle_int(oidp, &time, 0, req);
if (error != 0)
return(error);
diff --git a/sys/dev/mge/if_mgevar.h b/sys/dev/mge/if_mgevar.h
index 652c254..90d702b 100644
--- a/sys/dev/mge/if_mgevar.h
+++ b/sys/dev/mge/if_mgevar.h
@@ -91,6 +91,14 @@ struct mge_softc {
uint32_t tx_ic_time;
struct mge_desc_wrapper mge_tx_desc[MGE_TX_DESC_NUM];
struct mge_desc_wrapper mge_rx_desc[MGE_RX_DESC_NUM];
+
+ uint32_t mge_tfut_ipg_max; /* TX FIFO Urgent Threshold */
+ uint32_t mge_rx_ipg_max;
+ uint32_t mge_tx_arb_cfg;
+ uint32_t mge_tx_tok_cfg;
+ uint32_t mge_tx_tok_cnt;
+ uint16_t mge_mtu;
+ int mge_ver;
};
@@ -183,15 +191,6 @@ struct mge_softc {
#define MGE_SDMA_RX_BYTE_SWAP (1 << 4)
#define MGE_SDMA_TX_BYTE_SWAP (1 << 5)
#define MGE_SDMA_DESC_SWAP_MODE (1 << 6)
-#if defined(MGE_VER2)
-#define MGE_SDMA_RX_IPG_MAX 0xFFFF
-#define MGE_SDMA_RX_IPG(val) ((((val) & 0x8000) << 10) | \
- (((val) & 0x7fff) << 7))
-#else
-#define MGE_SDMA_RX_IPG_MAX 0x3FFF
-#define MGE_SDMA_RX_IPG(val) (((val) & 0x3fff) << 8)
-#endif
-
#define MGE_PORT_SERIAL_CTRL 0x43c
#define PORT_SERIAL_ENABLE (1 << 0) /* serial port enable */
@@ -248,13 +247,6 @@ struct mge_softc {
#define MGE_COLLISION_LIMIT(val) (((val) & 0x3f) << 16)
#define MGE_DROP_ODD_PREAMBLE (1 << 22)
-#if defined(MGE_VER2)
-#define MGE_MTU 0x4e8
-#else
-#define MGE_MTU 0x458
-#endif
-#define MGE_MTU_DEFAULT 0x0
-
#define MGE_PORT_INT_CAUSE 0x460
#define MGE_PORT_INT_MASK 0x468
#define MGE_PORT_INT_RX (1 << 0)
@@ -277,13 +269,6 @@ struct mge_softc {
#define MGE_RX_FIFO_URGENT_TRSH 0x470
#define MGE_TX_FIFO_URGENT_TRSH 0x474
-#if defined(MGE_VER2)
-#define MGE_TX_FIFO_URGENT_TRSH_IPG_MAX 0xFFFF
-#define MGE_TX_FIFO_URGENT_TRSH_IPG(vl) (((vl) & 0xFFFF) << 4)
-#else
-#define MGE_TX_FIFO_URGENT_TRSH_IPG_MAX 0x3FFF
-#define MGE_TX_FIFO_URGENT_TRSH_IPG(vl) (((vl) & 0x3FFF) << 4)
-#endif
#define MGE_FIXED_PRIO_CONF 0x4dc
#define MGE_FIXED_PRIO_EN(q) (1 << (q))
@@ -300,12 +285,7 @@ struct mge_softc {
#define MGE_TX_TOKEN_COUNT(q) (0x700 + ((q)<<4))
#define MGE_TX_TOKEN_CONF(q) (0x704 + ((q)<<4))
-#define MGE_TX_TOKEN_Q0_DFLT 0x3fffffff
-#define MGE_TX_TOKEN_Q1_7_DFLT 0x0
-
#define MGE_TX_ARBITER_CONF(q) (0x704 + ((q)<<4))
-#define MGE_TX_ARB_Q0_DFLT 0xff
-#define MGE_TX_ARB_Q1_7_DFLT 0x0
#define MGE_MCAST_REG_NUMBER 64
#define MGE_DA_FILTER_SPEC_MCAST(i) (0x1400 + ((i) << 2))
diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c
index 2b2d6ab..0ec6ac7 100644
--- a/sys/dev/mmc/mmc.c
+++ b/sys/dev/mmc/mmc.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/endian.h>
+#include <sys/sysctl.h>
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
@@ -104,6 +105,11 @@ struct mmc_ivars {
#define CMD_RETRIES 3
+SYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver");
+
+static int mmc_debug;
+SYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RW, &mmc_debug, 0, "Debug level");
+
/* bus entry points */
static int mmc_probe(device_t dev);
static int mmc_attach(device_t dev);
@@ -233,7 +239,7 @@ mmc_acquire_bus(device_t busdev, device_t dev)
sc->last_rca = rca;
/* Prepare bus width for the new card. */
ivar = device_get_ivars(dev);
- if (bootverbose) {
+ if (bootverbose || mmc_debug) {
device_printf(busdev,
"setting bus width to %d bits\n",
(ivar->bus_width == bus_width_4) ? 4 :
@@ -315,11 +321,21 @@ mmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req)
req->done = mmc_wakeup;
req->done_data = sc;
+ if (mmc_debug > 1) {
+ device_printf(sc->dev, "REQUEST: CMD%d arg %#x flags %#x",
+ req->cmd->opcode, req->cmd->arg, req->cmd->flags);
+ if (req->cmd->data) {
+ printf(" data %d\n", (int)req->cmd->data->len);
+ } else
+ printf("\n");
+ }
MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
MMC_LOCK(sc);
while ((req->flags & MMC_REQ_DONE) == 0)
msleep(req, &sc->sc_mtx, 0, "mmcreq", 0);
MMC_UNLOCK(sc);
+ if (mmc_debug > 2 || (mmc_debug > 1 && req->cmd->error))
+ device_printf(sc->dev, "RESULT: %d\n", req->cmd->error);
return (0);
}
@@ -340,7 +356,6 @@ mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
memset(cmd->resp, 0, sizeof(cmd->resp));
cmd->retries = retries;
mreq.cmd = cmd;
-/* printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */
mmc_wait_for_req(sc, &mreq);
return (cmd->error);
}
@@ -555,7 +570,8 @@ mmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index, uint8_t value)
}
static int
-mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, uint8_t *res)
+mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value,
+ uint8_t *res)
{
int err;
struct mmc_command cmd;
@@ -563,11 +579,11 @@ mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, ui
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
-
memset(res, 0, 64);
+
cmd.opcode = SD_SWITCH_FUNC;
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
- cmd.arg = mode << 31;
+ cmd.arg = mode << 31; /* 0 - check, 1 - set */
cmd.arg |= 0x00FFFFFF;
cmd.arg &= ~(0xF << (grp * 4));
cmd.arg |= value << (grp * 4);
@@ -584,11 +600,11 @@ mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, ui
static int
mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
{
+ struct mmc_command cmd;
int err;
+ uint8_t value;
if (mmcbr_get_mode(sc->dev) == mode_sd) {
- struct mmc_command cmd;
-
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = ACMD_SET_BUS_WIDTH;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
@@ -604,8 +620,6 @@ mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
}
err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
} else {
- uint8_t value;
-
switch (width) {
case bus_width_1:
value = EXT_CSD_BUS_WIDTH_1;
@@ -619,7 +633,8 @@ mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
default:
return (MMC_ERR_INVALID);
}
- err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, value);
+ err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+ value);
}
return (err);
}
@@ -629,6 +644,7 @@ mmc_set_timing(struct mmc_softc *sc, int timing)
{
int err;
uint8_t value;
+ u_char switch_res[64];
switch (timing) {
case bus_timing_normal:
@@ -640,14 +656,12 @@ mmc_set_timing(struct mmc_softc *sc, int timing)
default:
return (MMC_ERR_INVALID);
}
- if (mmcbr_get_mode(sc->dev) == mode_sd) {
- u_char switch_res[64];
-
- err = mmc_sd_switch(sc, 1, 0, value, switch_res);
- } else {
+ if (mmcbr_get_mode(sc->dev) == mode_sd)
+ err = mmc_sd_switch(sc, SD_SWITCH_MODE_SET, SD_SWITCH_GROUP1,
+ value, switch_res);
+ else
err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, value);
- }
return (err);
}
@@ -749,9 +763,10 @@ mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
cid->oid = mmc_get_bits(raw_cid, 128, 104, 16);
for (i = 0; i < 5; i++)
cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
+ cid->pnm[5] = 0;
cid->prv = mmc_get_bits(raw_cid, 128, 56, 8);
cid->psn = mmc_get_bits(raw_cid, 128, 24, 32);
- cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2001;
+ cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2000;
cid->mdt_month = mmc_get_bits(raw_cid, 128, 8, 4);
}
@@ -766,6 +781,7 @@ mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
cid->oid = mmc_get_bits(raw_cid, 128, 104, 8);
for (i = 0; i < 6; i++)
cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
+ cid->pnm[6] = 0;
cid->prv = mmc_get_bits(raw_cid, 128, 48, 8);
cid->psn = mmc_get_bits(raw_cid, 128, 16, 32);
cid->mdt_month = mmc_get_bits(raw_cid, 128, 12, 4);
@@ -1060,6 +1076,29 @@ mmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp)
}
static void
+mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard)
+{
+ device_printf(dev, "Card at relative address %d%s:\n",
+ ivar->rca, newcard ? " added" : "");
+ device_printf(dev, " card: %s%s (0x%x/0x%x/\"%s\" rev %d.%d "
+ "m/d %02d.%04d s/n %08x)\n",
+ ivar->mode == mode_sd ? "SD" : "MMC",
+ ivar->high_cap ? " High Capacity" : "",
+ ivar->cid.mid, ivar->cid.oid,
+ ivar->cid.pnm, ivar->cid.prv >> 4, ivar->cid.prv & 0x0f,
+ ivar->cid.mdt_month, ivar->cid.mdt_year, ivar->cid.psn);
+ device_printf(dev, " bus: %ubit, %uMHz%s\n",
+ (ivar->bus_width == bus_width_1 ? 1 :
+ (ivar->bus_width == bus_width_4 ? 4 : 8)),
+ (ivar->timing == bus_timing_hs ?
+ ivar->hs_tran_speed : ivar->tran_speed) / 1000000,
+ ivar->timing == bus_timing_hs ? ", high speed timing" : "");
+ device_printf(dev, " memory: %u blocks, erase sector %u blocks%s\n",
+ ivar->sec_count, ivar->erase_sector,
+ ivar->read_only ? ", read-only" : "");
+}
+
+static void
mmc_discover_cards(struct mmc_softc *sc)
{
struct mmc_ivars *ivar = NULL;
@@ -1071,6 +1110,8 @@ mmc_discover_cards(struct mmc_softc *sc)
uint16_t rca = 2;
u_char switch_res[64];
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Probing cards\n");
while (1) {
err = mmc_all_send_cid(sc, raw_cid);
if (err == MMC_ERR_TIMEOUT)
@@ -1090,6 +1131,11 @@ mmc_discover_cards(struct mmc_softc *sc)
}
}
free(devlist, M_TEMP);
+ if (bootverbose || mmc_debug) {
+ device_printf(sc->dev, "%sard detected (CID %08x%08x%08x%08x)\n",
+ newcard ? "New c" : "C",
+ raw_cid[0], raw_cid[1], raw_cid[2], raw_cid[3]);
+ }
if (newcard) {
ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF,
M_WAITOK | M_ZERO);
@@ -1100,6 +1146,7 @@ mmc_discover_cards(struct mmc_softc *sc)
if (mmcbr_get_ro(sc->dev))
ivar->read_only = 1;
ivar->bus_width = bus_width_1;
+ ivar->timing = bus_timing_normal;
ivar->mode = mmcbr_get_mode(sc->dev);
if (ivar->mode == mode_sd) {
mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid);
@@ -1118,13 +1165,15 @@ mmc_discover_cards(struct mmc_softc *sc)
mmc_select_card(sc, ivar->rca);
mmc_app_send_scr(sc, ivar->rca, ivar->raw_scr);
mmc_app_decode_scr(ivar->raw_scr, &ivar->scr);
- /* Get card switch capabilities. */
+ /* Get card switch capabilities (command class 10). */
if ((ivar->scr.sda_vsn >= 1) &&
(ivar->csd.ccc & (1<<10))) {
- mmc_sd_switch(sc, 0, 0, 0xF, switch_res);
+ mmc_sd_switch(sc, SD_SWITCH_MODE_CHECK,
+ SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE,
+ switch_res);
if (switch_res[13] & 2) {
ivar->timing = bus_timing_hs;
- ivar->hs_tran_speed = 50000000;
+ ivar->hs_tran_speed = SD_MAX_HS;
}
}
mmc_app_sd_status(sc, ivar->rca, ivar->raw_sd_status);
@@ -1139,6 +1188,8 @@ mmc_discover_cards(struct mmc_softc *sc)
if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) &&
(ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
ivar->bus_width = bus_width_4;
+ if (bootverbose || mmc_debug)
+ mmc_log_card(sc->dev, ivar, newcard);
if (newcard) {
/* Add device. */
child = device_add_child(sc->dev, NULL, -1);
@@ -1174,10 +1225,10 @@ mmc_discover_cards(struct mmc_softc *sc)
ivar->timing = bus_timing_hs;
if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
& EXT_CSD_CARD_TYPE_52)
- ivar->hs_tran_speed = 52000000;
+ ivar->hs_tran_speed = MMC_TYPE_52_MAX_HS;
else if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
& EXT_CSD_CARD_TYPE_26)
- ivar->hs_tran_speed = 26000000;
+ ivar->hs_tran_speed = MMC_TYPE_26_MAX_HS;
else
ivar->hs_tran_speed = ivar->tran_speed;
/* Find max supported bus width. */
@@ -1194,6 +1245,8 @@ mmc_discover_cards(struct mmc_softc *sc)
ivar->bus_width = bus_width_1;
ivar->timing = bus_timing_normal;
}
+ if (bootverbose || mmc_debug)
+ mmc_log_card(sc->dev, ivar, newcard);
if (newcard) {
/* Add device. */
child = device_add_child(sc->dev, NULL, -1);
@@ -1214,6 +1267,9 @@ mmc_rescan_cards(struct mmc_softc *sc)
for (i = 0; i < devcount; i++) {
ivar = device_get_ivars(devlist[i]);
if (mmc_select_card(sc, ivar->rca)) {
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Card at relative address %d lost.\n",
+ ivar->rca);
device_delete_child(sc->dev, devlist[i]);
free(ivar, M_DEVBUF);
}
@@ -1233,6 +1289,9 @@ mmc_delete_cards(struct mmc_softc *sc)
return (err);
for (i = 0; i < devcount; i++) {
ivar = device_get_ivars(devlist[i]);
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Card at relative address %d deleted.\n",
+ ivar->rca);
device_delete_child(sc->dev, devlist[i]);
free(ivar, M_DEVBUF);
}
@@ -1255,17 +1314,30 @@ mmc_go_discovery(struct mmc_softc *sc)
mmcbr_set_mode(dev, mode_sd);
mmc_power_up(sc);
mmcbr_set_bus_mode(dev, pushpull);
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Probing bus\n");
mmc_idle_cards(sc);
err = mmc_send_if_cond(sc, 1);
+ if ((bootverbose || mmc_debug) && err == 0)
+ device_printf(sc->dev, "SD 2.0 interface conditions: OK\n");
if (mmc_send_app_op_cond(sc, err ? 0 : MMC_OCR_CCS, &ocr) !=
MMC_ERR_NONE) {
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "SD probe: failed\n");
/*
* Failed, try MMC
*/
mmcbr_set_mode(dev, mode_mmc);
- if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
+ if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) {
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "MMC probe: failed\n");
ocr = 0; /* Failed both, powerdown. */
- }
+ } else if (bootverbose || mmc_debug)
+ device_printf(sc->dev,
+ "MMC probe: OK (OCR: 0x%08x)\n", ocr);
+ } else if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "SD probe: OK (OCR: 0x%08x)\n", ocr);
+
mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
if (mmcbr_get_ocr(dev) != 0)
mmc_idle_cards(sc);
@@ -1279,6 +1351,8 @@ mmc_go_discovery(struct mmc_softc *sc)
* Make sure that we have a mutually agreeable voltage to at least
* one card on the bus.
*/
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Current OCR: 0x%08x\n", mmcbr_get_ocr(dev));
if (mmcbr_get_ocr(dev) == 0) {
mmc_delete_cards(sc);
mmc_power_down(sc);
@@ -1326,7 +1400,7 @@ mmc_calculate_clock(struct mmc_softc *sc)
max_timing = ivar->timing;
if (ivar->tran_speed < max_dtr)
max_dtr = ivar->tran_speed;
- if (ivar->hs_tran_speed < max_dtr)
+ if (ivar->hs_tran_speed < max_hs_dtr)
max_hs_dtr = ivar->hs_tran_speed;
}
for (i = 0; i < nkid; i++) {
@@ -1340,7 +1414,7 @@ mmc_calculate_clock(struct mmc_softc *sc)
free(kids, M_TEMP);
if (max_timing == bus_timing_hs)
max_dtr = max_hs_dtr;
- if (bootverbose) {
+ if (bootverbose || mmc_debug) {
device_printf(sc->dev,
"setting transfer rate to %d.%03dMHz%s\n",
max_dtr / 1000000, (max_dtr / 1000) % 1000,
@@ -1454,5 +1528,5 @@ static driver_t mmc_driver = {
static devclass_t mmc_devclass;
-DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, 0, 0);
+DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL);
+DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL);
diff --git a/sys/dev/mmc/mmcreg.h b/sys/dev/mmc/mmcreg.h
index aef2a3d..8ce9dff 100644
--- a/sys/dev/mmc/mmcreg.h
+++ b/sys/dev/mmc/mmcreg.h
@@ -97,6 +97,7 @@ struct mmc_command {
#define MMC_ERR_FAILED 4
#define MMC_ERR_INVALID 5
#define MMC_ERR_NO_MEMORY 6
+#define MMC_ERR_MAX 6
struct mmc_data *data; /* Data segment with cmd */
struct mmc_request *mrq; /* backpointer to request */
};
@@ -287,7 +288,6 @@ struct mmc_request {
/*
* EXT_CSD fields
*/
-
#define EXT_CSD_ERASE_GRP_DEF 175 /* R/W */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */
@@ -300,7 +300,6 @@ struct mmc_request {
/*
* EXT_CSD field definitions
*/
-
#define EXT_CSD_CMD_SET_NORMAL 1
#define EXT_CSD_CMD_SET_SECURE 2
#define EXT_CSD_CMD_SET_CPSECURE 4
@@ -312,12 +311,27 @@ struct mmc_request {
#define EXT_CSD_BUS_WIDTH_4 1
#define EXT_CSD_BUS_WIDTH_8 2
+#define MMC_TYPE_26_MAX_HS 26000000
+#define MMC_TYPE_52_MAX_HS 52000000
+
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
+/*
+ * SD Switch
+ */
+#define SD_SWITCH_MODE_CHECK 0
+#define SD_SWITCH_MODE_SET 1
+#define SD_SWITCH_GROUP1 0
+#define SD_SWITCH_NORMAL_MODE 0
+#define SD_SWITCH_HS_MODE 1
+#define SD_SWITCH_NOCHANGE 0xF
+
+#define SD_MAX_HS 50000000
+
/* OCR bits */
/*
diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c
index 445df55..1b44333 100644
--- a/sys/dev/mpt/mpt.c
+++ b/sys/dev/mpt/mpt.c
@@ -1637,7 +1637,7 @@ mpt_read_extcfg_header(struct mpt_softc *mpt, int PageVersion, int PageNumber,
rslt->PageVersion = cfgp->Header.PageVersion;
rslt->PageNumber = cfgp->Header.PageNumber;
rslt->PageType = cfgp->Header.PageType;
- rslt->ExtPageLength = cfgp->ExtPageLength;
+ rslt->ExtPageLength = le16toh(cfgp->ExtPageLength);
rslt->ExtPageType = cfgp->ExtPageType;
error = 0;
break;
@@ -1668,7 +1668,7 @@ mpt_read_extcfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress,
req = mpt_get_request(mpt, sleep_ok);
if (req == NULL) {
- mpt_prt(mpt, "mpt_read_cfg_page: Get request failed!\n");
+ mpt_prt(mpt, "mpt_read_extcfg_page: Get request failed!\n");
return (-1);
}
@@ -2025,6 +2025,7 @@ mpt_read_config_info_ioc(struct mpt_softc *mpt)
mpt_raid_free_mem(mpt);
return (EIO);
}
+ mpt2host_config_page_ioc3(mpt->ioc_page3);
mpt_raid_wakeup(mpt);
return (0);
}
@@ -2760,6 +2761,7 @@ mpt_enable_ioc(struct mpt_softc *mpt, int portenable)
void
mpt2host_sge_simple_union(SGE_SIMPLE_UNION *sge)
{
+
MPT_2_HOST32(sge, FlagsLength);
MPT_2_HOST32(sge, u.Address64.Low);
MPT_2_HOST32(sge, u.Address64.High);
@@ -2768,6 +2770,7 @@ mpt2host_sge_simple_union(SGE_SIMPLE_UNION *sge)
void
mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *rp)
{
+
MPT_2_HOST16(rp, MsgVersion);
MPT_2_HOST16(rp, HeaderVersion);
MPT_2_HOST32(rp, MsgContext);
@@ -2794,6 +2797,7 @@ mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *rp)
void
mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *pfp)
{
+
MPT_2_HOST16(pfp, Reserved);
MPT_2_HOST16(pfp, Reserved1);
MPT_2_HOST32(pfp, MsgContext);
@@ -2809,20 +2813,139 @@ mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *pfp)
MPT_2_HOST16(pfp, Reserved4);
MPT_2_HOST32(pfp, Reserved5);
}
+
void
mpt2host_config_page_ioc2(CONFIG_PAGE_IOC_2 *ioc2)
{
int i;
- ioc2->CapabilitiesFlags = htole32(ioc2->CapabilitiesFlags);
+
+ MPT_2_HOST32(ioc2, CapabilitiesFlags);
for (i = 0; i < MPI_IOC_PAGE_2_RAID_VOLUME_MAX; i++) {
MPT_2_HOST16(ioc2, RaidVolume[i].Reserved3);
}
}
void
+mpt2host_config_page_ioc3(CONFIG_PAGE_IOC_3 *ioc3)
+{
+
+ MPT_2_HOST16(ioc3, Reserved2);
+}
+
+void
+mpt2host_config_page_scsi_port_0(CONFIG_PAGE_SCSI_PORT_0 *sp0)
+{
+
+ MPT_2_HOST32(sp0, Capabilities);
+ MPT_2_HOST32(sp0, PhysicalInterface);
+}
+
+void
+mpt2host_config_page_scsi_port_1(CONFIG_PAGE_SCSI_PORT_1 *sp1)
+{
+
+ MPT_2_HOST32(sp1, Configuration);
+ MPT_2_HOST32(sp1, OnBusTimerValue);
+ MPT_2_HOST16(sp1, IDConfig);
+}
+
+void
+host2mpt_config_page_scsi_port_1(CONFIG_PAGE_SCSI_PORT_1 *sp1)
+{
+
+ HOST_2_MPT32(sp1, Configuration);
+ HOST_2_MPT32(sp1, OnBusTimerValue);
+ HOST_2_MPT16(sp1, IDConfig);
+}
+
+void
+mpt2host_config_page_scsi_port_2(CONFIG_PAGE_SCSI_PORT_2 *sp2)
+{
+ int i;
+
+ MPT_2_HOST32(sp2, PortFlags);
+ MPT_2_HOST32(sp2, PortSettings);
+ for (i = 0; i < sizeof(sp2->DeviceSettings) /
+ sizeof(*sp2->DeviceSettings); i++) {
+ MPT_2_HOST16(sp2, DeviceSettings[i].DeviceFlags);
+ }
+}
+
+void
+mpt2host_config_page_scsi_device_0(CONFIG_PAGE_SCSI_DEVICE_0 *sd0)
+{
+
+ MPT_2_HOST32(sd0, NegotiatedParameters);
+ MPT_2_HOST32(sd0, Information);
+}
+
+void
+mpt2host_config_page_scsi_device_1(CONFIG_PAGE_SCSI_DEVICE_1 *sd1)
+{
+
+ MPT_2_HOST32(sd1, RequestedParameters);
+ MPT_2_HOST32(sd1, Reserved);
+ MPT_2_HOST32(sd1, Configuration);
+}
+
+void
+host2mpt_config_page_scsi_device_1(CONFIG_PAGE_SCSI_DEVICE_1 *sd1)
+{
+
+ HOST_2_MPT32(sd1, RequestedParameters);
+ HOST_2_MPT32(sd1, Reserved);
+ HOST_2_MPT32(sd1, Configuration);
+}
+
+void
+mpt2host_config_page_fc_port_0(CONFIG_PAGE_FC_PORT_0 *fp0)
+{
+
+ MPT_2_HOST32(fp0, Flags);
+ MPT_2_HOST32(fp0, PortIdentifier);
+ MPT_2_HOST32(fp0, WWNN.Low);
+ MPT_2_HOST32(fp0, WWNN.High);
+ MPT_2_HOST32(fp0, WWPN.Low);
+ MPT_2_HOST32(fp0, WWPN.High);
+ MPT_2_HOST32(fp0, SupportedServiceClass);
+ MPT_2_HOST32(fp0, SupportedSpeeds);
+ MPT_2_HOST32(fp0, CurrentSpeed);
+ MPT_2_HOST32(fp0, MaxFrameSize);
+ MPT_2_HOST32(fp0, FabricWWNN.Low);
+ MPT_2_HOST32(fp0, FabricWWNN.High);
+ MPT_2_HOST32(fp0, FabricWWPN.Low);
+ MPT_2_HOST32(fp0, FabricWWPN.High);
+ MPT_2_HOST32(fp0, DiscoveredPortsCount);
+ MPT_2_HOST32(fp0, MaxInitiators);
+}
+
+void
+mpt2host_config_page_fc_port_1(CONFIG_PAGE_FC_PORT_1 *fp1)
+{
+
+ MPT_2_HOST32(fp1, Flags);
+ MPT_2_HOST32(fp1, NoSEEPROMWWNN.Low);
+ MPT_2_HOST32(fp1, NoSEEPROMWWNN.High);
+ MPT_2_HOST32(fp1, NoSEEPROMWWPN.Low);
+ MPT_2_HOST32(fp1, NoSEEPROMWWPN.High);
+}
+
+void
+host2mpt_config_page_fc_port_1(CONFIG_PAGE_FC_PORT_1 *fp1)
+{
+
+ HOST_2_MPT32(fp1, Flags);
+ HOST_2_MPT32(fp1, NoSEEPROMWWNN.Low);
+ HOST_2_MPT32(fp1, NoSEEPROMWWNN.High);
+ HOST_2_MPT32(fp1, NoSEEPROMWWPN.Low);
+ HOST_2_MPT32(fp1, NoSEEPROMWWPN.High);
+}
+
+void
mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *volp)
{
int i;
+
MPT_2_HOST16(volp, VolumeStatus.Reserved);
MPT_2_HOST16(volp, VolumeSettings.Settings);
MPT_2_HOST32(volp, MaxLBA);
@@ -2836,8 +2959,21 @@ mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *volp)
}
void
+mpt2host_config_page_raid_phys_disk_0(CONFIG_PAGE_RAID_PHYS_DISK_0 *rpd0)
+{
+
+ MPT_2_HOST32(rpd0, Reserved1);
+ MPT_2_HOST16(rpd0, PhysDiskStatus.Reserved);
+ MPT_2_HOST32(rpd0, MaxLBA);
+ MPT_2_HOST16(rpd0, ErrorData.Reserved);
+ MPT_2_HOST16(rpd0, ErrorData.ErrorCount);
+ MPT_2_HOST16(rpd0, ErrorData.SmartCount);
+}
+
+void
mpt2host_mpi_raid_vol_indicator(MPI_RAID_VOL_INDICATOR *vi)
{
+
MPT_2_HOST16(vi, TotalBlocks.High);
MPT_2_HOST16(vi, TotalBlocks.Low);
MPT_2_HOST16(vi, BlocksRemaining.High);
diff --git a/sys/dev/mpt/mpt.h b/sys/dev/mpt/mpt.h
index 56a0239..6817c47 100644
--- a/sys/dev/mpt/mpt.h
+++ b/sys/dev/mpt/mpt.h
@@ -317,14 +317,39 @@ void mpt2host_sge_simple_union(SGE_SIMPLE_UNION *);
void mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *);
void mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *);
void mpt2host_config_page_ioc2(CONFIG_PAGE_IOC_2 *);
+void mpt2host_config_page_ioc3(CONFIG_PAGE_IOC_3 *);
+void mpt2host_config_page_scsi_port_0(CONFIG_PAGE_SCSI_PORT_0 *);
+void mpt2host_config_page_scsi_port_1(CONFIG_PAGE_SCSI_PORT_1 *);
+void host2mpt_config_page_scsi_port_1(CONFIG_PAGE_SCSI_PORT_1 *);
+void mpt2host_config_page_scsi_port_2(CONFIG_PAGE_SCSI_PORT_2 *);
+void mpt2host_config_page_scsi_device_0(CONFIG_PAGE_SCSI_DEVICE_0 *);
+void mpt2host_config_page_scsi_device_1(CONFIG_PAGE_SCSI_DEVICE_1 *);
+void host2mpt_config_page_scsi_device_1(CONFIG_PAGE_SCSI_DEVICE_1 *);
+void mpt2host_config_page_fc_port_0(CONFIG_PAGE_FC_PORT_0 *);
+void mpt2host_config_page_fc_port_1(CONFIG_PAGE_FC_PORT_1 *);
+void host2mpt_config_page_fc_port_1(CONFIG_PAGE_FC_PORT_1 *);
void mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *);
+void mpt2host_config_page_raid_phys_disk_0(CONFIG_PAGE_RAID_PHYS_DISK_0 *);
void mpt2host_mpi_raid_vol_indicator(MPI_RAID_VOL_INDICATOR *);
#else
#define mpt2host_sge_simple_union(x) do { ; } while (0)
#define mpt2host_iocfacts_reply(x) do { ; } while (0)
#define mpt2host_portfacts_reply(x) do { ; } while (0)
#define mpt2host_config_page_ioc2(x) do { ; } while (0)
+#define mpt2host_config_page_ioc3(x) do { ; } while (0)
+#define mpt2host_config_page_scsi_port_0(x) do { ; } while (0)
+#define mpt2host_config_page_scsi_port_1(x) do { ; } while (0)
+#define host2mpt_config_page_scsi_port_1(x) do { ; } while (0)
+#define mpt2host_config_page_scsi_port_2(x) do { ; } while (0)
+#define mpt2host_config_page_scsi_device_0(x) do { ; } while (0)
+#define mpt2host_config_page_scsi_device_1(x) do { ; } while (0)
+#define host2mpt_config_page_scsi_device_1(x) do { ; } while (0)
+#define mpt2host_config_page_fc_port_0(x) do { ; } while (0)
+#define mpt2host_config_page_fc_port_1(x) do { ; } while (0)
+#define host2mpt_config_page_fc_port_1(x) do { ; } while (0)
#define mpt2host_config_page_raid_vol_0(x) do { ; } while (0)
+#define mpt2host_config_page_raid_phys_disk_0(x) \
+ do { ; } while (0)
#define mpt2host_mpi_raid_vol_indicator(x) do { ; } while (0)
#endif
diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c
index eab2083..9f28925 100644
--- a/sys/dev/mpt/mpt_cam.c
+++ b/sys/dev/mpt/mpt_cam.c
@@ -437,6 +437,7 @@ mpt_read_config_info_fc(struct mpt_softc *mpt)
mpt_prt(mpt, "failed to read FC Port Page 0\n");
return (-1);
}
+ mpt2host_config_page_fc_port_0(&mpt->mpt_fcport_page0);
mpt->mpt_fcport_speed = mpt->mpt_fcport_page0.CurrentSpeed;
@@ -527,13 +528,14 @@ mpt_set_initial_config_fc(struct mpt_softc *mpt)
mpt_prt(mpt, "failed to read FC page 1\n");
return (mpt_fc_reset_link(mpt, 1));
}
+ mpt2host_config_page_fc_port_1(&fc);
/*
* Check our flags to make sure we support the role we want.
*/
doit = 0;
role = 0;
- fl = le32toh(fc.Flags);;
+ fl = fc.Flags;
if (fl & MPI_FCPORTPAGE1_FLAGS_PROT_FCP_INIT) {
role |= MPT_ROLE_INITIATOR;
@@ -587,7 +589,8 @@ mpt_set_initial_config_fc(struct mpt_softc *mpt)
}
if (doit) {
- fc.Flags = htole32(fl);
+ fc.Flags = fl;
+ host2mpt_config_page_fc_port_1(&fc);
r = mpt_write_cfg_page(mpt,
MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM, 0, &fc.Header,
sizeof(fc), FALSE, 5000);
@@ -982,6 +985,7 @@ mpt_read_config_info_spi(struct mpt_softc *mpt)
if (rv) {
mpt_prt(mpt, "failed to read SPI Port Page 0\n");
} else {
+ mpt2host_config_page_scsi_port_0(&mpt->mpt_port_page0);
mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
"SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
mpt->mpt_port_page0.Capabilities,
@@ -993,6 +997,7 @@ mpt_read_config_info_spi(struct mpt_softc *mpt)
if (rv) {
mpt_prt(mpt, "failed to read SPI Port Page 1\n");
} else {
+ mpt2host_config_page_scsi_port_1(&mpt->mpt_port_page1);
mpt_lprt(mpt, MPT_PRT_DEBUG,
"SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
mpt->mpt_port_page1.Configuration,
@@ -1008,6 +1013,7 @@ mpt_read_config_info_spi(struct mpt_softc *mpt)
"Port Page 2: Flags %x Settings %x\n",
mpt->mpt_port_page2.PortFlags,
mpt->mpt_port_page2.PortSettings);
+ mpt2host_config_page_scsi_port_2(&mpt->mpt_port_page2);
for (i = 0; i < 16; i++) {
mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
" Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
@@ -1026,6 +1032,7 @@ mpt_read_config_info_spi(struct mpt_softc *mpt)
"cannot read SPI Target %d Device Page 0\n", i);
continue;
}
+ mpt2host_config_page_scsi_device_0(&mpt->mpt_dev_page0[i]);
mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
"target %d page 0: Negotiated Params %x Information %x\n",
i, mpt->mpt_dev_page0[i].NegotiatedParameters,
@@ -1039,6 +1046,7 @@ mpt_read_config_info_spi(struct mpt_softc *mpt)
"cannot read SPI Target %d Device Page 1\n", i);
continue;
}
+ mpt2host_config_page_scsi_device_1(&mpt->mpt_dev_page1[i]);
mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
"target %d page 1: Requested Params %x Configuration %x\n",
i, mpt->mpt_dev_page1[i].RequestedParameters,
@@ -1068,6 +1076,7 @@ mpt_set_initial_config_spi(struct mpt_softc *mpt)
"be %x\n", mpt->mpt_port_page1.Configuration, pp1val);
tmp = mpt->mpt_port_page1;
tmp.Configuration = pp1val;
+ host2mpt_config_page_scsi_port_1(&tmp);
error = mpt_write_cur_cfg_page(mpt, 0,
&tmp.Header, sizeof(tmp), FALSE, 5000);
if (error) {
@@ -1078,6 +1087,7 @@ mpt_set_initial_config_spi(struct mpt_softc *mpt)
if (error) {
return (-1);
}
+ mpt2host_config_page_scsi_port_1(&tmp);
if (tmp.Configuration != pp1val) {
mpt_prt(mpt,
"failed to reset SPI Port Page 1 Config value\n");
@@ -1432,7 +1442,8 @@ bad:
memset(se, 0, sizeof (*se));
se->Address.Low = htole32(dm_segs->ds_addr & 0xffffffff);
if (sizeof(bus_addr_t) > 4) {
- se->Address.High = ((uint64_t) dm_segs->ds_addr) >> 32;
+ se->Address.High =
+ htole32(((uint64_t)dm_segs->ds_addr) >> 32);
}
MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
tf = flags;
@@ -1507,9 +1518,9 @@ bad:
chain_list_addr += cur_off;
if (sizeof (bus_addr_t) > 4) {
ce->Address.High =
- htole32((uint32_t) ((uint64_t)chain_list_addr >> 32));
+ htole32(((uint64_t)chain_list_addr) >> 32);
}
- ce->Address.Low = htole32((uint32_t) chain_list_addr);
+ ce->Address.Low = htole32(chain_list_addr & 0xffffffff);
ce->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT |
MPI_SGE_FLAGS_64_BIT_ADDRESSING;
@@ -1536,6 +1547,7 @@ bad:
ce->Length = (this_seg_lim - seg) *
sizeof (SGE_SIMPLE64);
}
+ ce->Length = htole16(ce->Length);
/*
* Fill in the chain list SGE elements with our segment data.
@@ -1546,7 +1558,8 @@ bad:
*/
while (seg < this_seg_lim) {
memset(se, 0, sizeof (*se));
- se->Address.Low = htole32(dm_segs->ds_addr);
+ se->Address.Low = htole32(dm_segs->ds_addr &
+ 0xffffffff);
if (sizeof (bus_addr_t) > 4) {
se->Address.High =
htole32(((uint64_t)dm_segs->ds_addr) >> 32);
@@ -1830,7 +1843,7 @@ bad:
uint32_t tf;
memset(se, 0,sizeof (*se));
- se->Address = dm_segs->ds_addr;
+ se->Address = htole32(dm_segs->ds_addr);
@@ -1908,7 +1921,7 @@ bad:
- ce->Address = chain_list_addr;
+ ce->Address = htole32(chain_list_addr);
ce->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
@@ -1935,6 +1948,7 @@ bad:
ce->Length = (this_seg_lim - seg) *
sizeof (SGE_SIMPLE32);
}
+ ce->Length = htole16(ce->Length);
/*
* Fill in the chain list SGE elements with our segment data.
@@ -1945,7 +1959,7 @@ bad:
*/
while (seg < this_seg_lim) {
memset(se, 0, sizeof (*se));
- se->Address = dm_segs->ds_addr;
+ se->Address = htole32(dm_segs->ds_addr);
@@ -2193,6 +2207,7 @@ mpt_start(struct cam_sim *sim, union ccb *ccb)
mpt_req->Control |= MPI_SCSIIO_CONTROL_NO_DISCONNECT;
}
}
+ mpt_req->Control = htole32(mpt_req->Control);
/* Copy the scsi command block into place */
if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
@@ -2317,7 +2332,7 @@ mpt_bus_reset(struct mpt_softc *mpt, target_id_t tgt, lun_id_t lun,
error = mpt_wait_req(mpt, mpt->tmf_req, REQ_STATE_DONE,
REQ_STATE_DONE, sleep_ok, 5000);
- status = mpt->tmf_req->IOCStatus;
+ status = le16toh(mpt->tmf_req->IOCStatus);
response = mpt->tmf_req->ResponseCode;
mpt->tmf_req->state = REQ_STATE_FREE;
@@ -2524,10 +2539,11 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req,
struct cam_sim *sim;
struct cam_path *tmppath;
struct ccb_relsim crs;
- PTR_EVENT_DATA_QUEUE_FULL pqf =
- (PTR_EVENT_DATA_QUEUE_FULL) msg->Data;
+ PTR_EVENT_DATA_QUEUE_FULL pqf;
lun_id_t lun_id;
+ pqf = (PTR_EVENT_DATA_QUEUE_FULL)msg->Data;
+ pqf->CurrentDepth = le16toh(pqf->CurrentDepth);
mpt_prt(mpt, "QUEUE FULL EVENT: Bus 0x%02x Target 0x%02x Depth "
"%d\n", pqf->Bus, pqf->TargetID, pqf->CurrentDepth);
if (mpt->phydisk_sim) {
@@ -3086,9 +3102,10 @@ mpt_scsi_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
&& (ccb->ccb_h.flags & (CAM_SENSE_PHYS | CAM_SENSE_PTR)) == 0) {
ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
ccb->csio.sense_resid =
- ccb->csio.sense_len - scsi_io_reply->SenseCount;
+ ccb->csio.sense_len - le32toh(scsi_io_reply->SenseCount);
bcopy(req->sense_vbuf, &ccb->csio.sense_data,
- min(ccb->csio.sense_len, scsi_io_reply->SenseCount));
+ min(ccb->csio.sense_len,
+ le32toh(scsi_io_reply->SenseCount)));
}
if ((sstate & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) != 0) {
@@ -3776,6 +3793,8 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
mpt_prt(mpt, "can't get tgt %d config page 0\n", tgt);
return (rv);
}
+ mpt2host_config_page_scsi_device_0(&tmp);
+
MPTLOCK_2_CAMLOCK(mpt);
mpt_lprt(mpt, MPT_PRT_DEBUG,
"mpt_get_spi_settings[%d]: current NP %x Info %x\n", tgt,
@@ -3905,6 +3924,7 @@ mpt_update_spi_config(struct mpt_softc *mpt, int tgt)
"mpt_update_spi_config[%d].page1: Requested Params 0x%08x\n",
tgt, mpt->mpt_dev_page1[tgt].RequestedParameters);
tmp = mpt->mpt_dev_page1[tgt];
+ host2mpt_config_page_scsi_device_1(&tmp);
rv = mpt_write_cur_cfg_page(mpt, tgt,
&tmp.Header, sizeof(tmp), FALSE, 5000);
if (rv) {
@@ -4156,7 +4176,7 @@ mpt_recover_commands(struct mpt_softc *mpt)
error = mpt_wait_req(mpt, mpt->tmf_req, REQ_STATE_DONE,
REQ_STATE_DONE, TRUE, 500);
- status = mpt->tmf_req->IOCStatus;
+ status = le16toh(mpt->tmf_req->IOCStatus);
response = mpt->tmf_req->ResponseCode;
mpt->tmf_req->state = REQ_STATE_FREE;
diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c
index cde0fec..0d5e03a 100644
--- a/sys/dev/mpt/mpt_raid.c
+++ b/sys/dev/mpt/mpt_raid.c
@@ -564,7 +564,7 @@ mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
action_result = REQ_TO_RAID_ACTION_RESULT(req);
memcpy(&action_result->action_data, &reply->ActionData,
sizeof(action_result->action_data));
- action_result->action_status = reply->ActionStatus;
+ action_result->action_status = le16toh(reply->ActionStatus);
return (TRUE);
}
@@ -583,7 +583,7 @@ mpt_issue_raid_req(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
rap = req->req_vbuf;
memset(rap, 0, sizeof *rap);
rap->Action = Action;
- rap->ActionDataWord = ActionDataWord;
+ rap->ActionDataWord = htole32(ActionDataWord);
rap->Function = MPI_FUNCTION_RAID_ACTION;
rap->VolumeID = vol->config_page->VolumeID;
rap->VolumeBus = vol->config_page->VolumeBus;
@@ -592,12 +592,13 @@ mpt_issue_raid_req(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
else
rap->PhysDiskNum = 0xFF;
se = (SGE_SIMPLE32 *)&rap->ActionDataSGE;
- se->Address = addr;
+ se->Address = htole32(addr);
MPI_pSGE_SET_LENGTH(se, len);
MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_END_OF_LIST |
write ? MPI_SGE_FLAGS_HOST_TO_IOC : MPI_SGE_FLAGS_IOC_TO_HOST));
+ se->FlagsLength = htole32(se->FlagsLength);
rap->MsgContext = htole32(req->index | raid_handler_id);
mpt_check_doorbell(mpt);
@@ -1226,6 +1227,7 @@ mpt_refresh_raid_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
mpt_prt(mpt, "mpt_refresh_raid_disk: "
"Failed to read RAID Disk Page(%d)\n",
ioc_disk->PhysDiskNum);
+ mpt2host_config_page_raid_phys_disk_0(&mpt_disk->config_page);
}
static void
@@ -1354,6 +1356,7 @@ mpt_refresh_raid_data(struct mpt_softc *mpt)
"mpt_refresh_raid_data: Failed to read IOC Page 3\n");
return (-1);
}
+ mpt2host_config_page_ioc3(mpt->ioc_page3);
ioc_disk = mpt->ioc_page3->PhysDisk;
ioc_last_disk = ioc_disk + mpt->ioc_page3->NumPhysDisks;
@@ -1384,6 +1387,7 @@ mpt_refresh_raid_data(struct mpt_softc *mpt)
"Failed to read IOC Page 2\n");
return (-1);
}
+ mpt2host_config_page_ioc2(mpt->ioc_page2);
ioc_vol = mpt->ioc_page2->RaidVolume;
ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
diff --git a/sys/dev/mpt/mpt_user.c b/sys/dev/mpt/mpt_user.c
index a87b330..971c262 100644
--- a/sys/dev/mpt/mpt_user.c
+++ b/sys/dev/mpt/mpt_user.c
@@ -256,7 +256,7 @@ mpt_user_read_cfg_header(struct mpt_softc *mpt,
params.PageLength = 0;
params.PageNumber = page_req->header.PageNumber;
params.PageType = page_req->header.PageType;
- params.PageAddress = page_req->page_address;
+ params.PageAddress = le32toh(page_req->page_address);
error = mpt_issue_cfg_req(mpt, req, &params, /*addr*/0, /*len*/0,
TRUE, 5000);
if (error != 0) {
@@ -270,7 +270,7 @@ mpt_user_read_cfg_header(struct mpt_softc *mpt,
return (ETIMEDOUT);
}
- page_req->ioc_status = req->IOCStatus;
+ page_req->ioc_status = htole16(req->IOCStatus);
if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) {
cfgp = req->req_vbuf;
bcopy(&cfgp->Header, &page_req->header,
@@ -301,15 +301,15 @@ mpt_user_read_cfg_page(struct mpt_softc *mpt, struct mpt_cfg_page_req *page_req,
params.PageLength = hdr->PageLength;
params.PageNumber = hdr->PageNumber;
params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK;
- params.PageAddress = page_req->page_address;
+ params.PageAddress = le32toh(page_req->page_address);
error = mpt_issue_cfg_req(mpt, req, &params, mpt_page->paddr,
- page_req->len, TRUE, 5000);
+ le32toh(page_req->len), TRUE, 5000);
if (error != 0) {
mpt_prt(mpt, "mpt_user_read_cfg_page timed out\n");
return (ETIMEDOUT);
}
- page_req->ioc_status = req->IOCStatus;
+ page_req->ioc_status = htole16(req->IOCStatus);
if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS)
bus_dmamap_sync(mpt_page->tag, mpt_page->map,
BUS_DMASYNC_POSTREAD);
@@ -337,7 +337,7 @@ mpt_user_read_extcfg_header(struct mpt_softc *mpt,
params.PageLength = 0;
params.PageNumber = ext_page_req->header.PageNumber;
params.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- params.PageAddress = ext_page_req->page_address;
+ params.PageAddress = le32toh(ext_page_req->page_address);
params.ExtPageType = ext_page_req->header.ExtPageType;
params.ExtPageLength = 0;
error = mpt_issue_cfg_req(mpt, req, &params, /*addr*/0, /*len*/0,
@@ -353,7 +353,7 @@ mpt_user_read_extcfg_header(struct mpt_softc *mpt,
return (ETIMEDOUT);
}
- ext_page_req->ioc_status = req->IOCStatus;
+ ext_page_req->ioc_status = htole16(req->IOCStatus);
if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) {
cfgp = req->req_vbuf;
ext_page_req->header.PageVersion = cfgp->Header.PageVersion;
@@ -387,17 +387,17 @@ mpt_user_read_extcfg_page(struct mpt_softc *mpt,
params.PageLength = 0;
params.PageNumber = hdr->PageNumber;
params.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- params.PageAddress = ext_page_req->page_address;
+ params.PageAddress = le32toh(ext_page_req->page_address);
params.ExtPageType = hdr->ExtPageType;
params.ExtPageLength = hdr->ExtPageLength;
error = mpt_issue_cfg_req(mpt, req, &params, mpt_page->paddr,
- ext_page_req->len, TRUE, 5000);
+ le32toh(ext_page_req->len), TRUE, 5000);
if (error != 0) {
mpt_prt(mpt, "mpt_user_read_extcfg_page timed out\n");
return (ETIMEDOUT);
}
- ext_page_req->ioc_status = req->IOCStatus;
+ ext_page_req->ioc_status = htole16(req->IOCStatus);
if ((req->IOCStatus & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS)
bus_dmamap_sync(mpt_page->tag, mpt_page->map,
BUS_DMASYNC_POSTREAD);
@@ -446,7 +446,7 @@ mpt_user_write_cfg_page(struct mpt_softc *mpt,
params.PageVersion = hdr->PageVersion;
params.PageLength = hdr->PageLength;
params.PageNumber = hdr->PageNumber;
- params.PageAddress = page_req->page_address;
+ params.PageAddress = le32toh(page_req->page_address);
#if 0
/* Restore stripped out attributes */
hdr->PageType |= hdr_attr;
@@ -455,13 +455,13 @@ mpt_user_write_cfg_page(struct mpt_softc *mpt,
params.PageType = hdr->PageType;
#endif
error = mpt_issue_cfg_req(mpt, req, &params, mpt_page->paddr,
- page_req->len, TRUE, 5000);
+ le32toh(page_req->len), TRUE, 5000);
if (error != 0) {
mpt_prt(mpt, "mpt_write_cfg_page timed out\n");
return (ETIMEDOUT);
}
- page_req->ioc_status = req->IOCStatus;
+ page_req->ioc_status = htole16(req->IOCStatus);
mpt_free_request(mpt, req);
return (0);
}
@@ -536,14 +536,15 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act,
if (mpt_page->vaddr != NULL && raid_act->len != 0) {
bus_dmamap_sync(mpt_page->tag, mpt_page->map,
BUS_DMASYNC_PREWRITE);
- se->Address = mpt_page->paddr;
- MPI_pSGE_SET_LENGTH(se, raid_act->len);
+ se->Address = htole32(mpt_page->paddr);
+ MPI_pSGE_SET_LENGTH(se, le32toh(raid_act->len));
MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_END_OF_LIST |
raid_act->write ? MPI_SGE_FLAGS_HOST_TO_IOC :
MPI_SGE_FLAGS_IOC_TO_HOST));
}
+ se->FlagsLength = htole32(se->FlagsLength);
rap->MsgContext = htole32(req->index | user_handler_id);
mpt_check_doorbell(mpt);
@@ -559,7 +560,7 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act,
return (error);
}
- raid_act->ioc_status = req->IOCStatus;
+ raid_act->ioc_status = htole16(req->IOCStatus);
if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
mpt_free_request(mpt, req);
return (0);
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 2b84cad..2620f9f 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -156,6 +156,8 @@ static int msi_disable = 0;
TUNABLE_INT("hw.msk.msi_disable", &msi_disable);
static int legacy_intr = 0;
TUNABLE_INT("hw.msk.legacy_intr", &legacy_intr);
+static int jumbo_disable = 0;
+TUNABLE_INT("hw.msk.jumbo_disable", &jumbo_disable);
#define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP)
@@ -267,9 +269,9 @@ static void msk_dmamap_cb(void *, bus_dma_segment_t *, int, int);
static int msk_status_dma_alloc(struct msk_softc *);
static void msk_status_dma_free(struct msk_softc *);
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_jalloc(struct msk_if_softc *);
-static void msk_jfree(void *, void *);
+static void msk_rx_dma_jfree(struct msk_if_softc *);
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 *);
@@ -289,6 +291,11 @@ static void msk_setmulti(struct msk_if_softc *);
static void msk_setvlan(struct msk_if_softc *, struct ifnet *);
static void msk_setpromisc(struct msk_if_softc *);
+static void msk_stats_clear(struct msk_if_softc *);
+static void msk_stats_update(struct msk_if_softc *);
+static int msk_sysctl_stat32(SYSCTL_HANDLER_ARGS);
+static int msk_sysctl_stat64(SYSCTL_HANDLER_ARGS);
+static void msk_sysctl_node(struct msk_if_softc *);
static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
static int sysctl_hw_msk_proc_limit(SYSCTL_HANDLER_ARGS);
@@ -830,24 +837,15 @@ msk_jumbo_newbuf(struct msk_if_softc *sc_if, int idx)
bus_dma_segment_t segs[1];
bus_dmamap_t map;
int nsegs;
- void *buf;
- MGETHDR(m, M_DONTWAIT, MT_DATA);
+ m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
if (m == NULL)
return (ENOBUFS);
- buf = msk_jalloc(sc_if);
- if (buf == NULL) {
- m_freem(m);
- return (ENOBUFS);
- }
- /* Attach the buffer to the mbuf. */
- MEXTADD(m, buf, MSK_JLEN, msk_jfree, buf,
- (struct msk_if_softc *)sc_if, 0, EXT_NET_DRV);
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
return (ENOBUFS);
}
- m->m_pkthdr.len = m->m_len = MSK_JLEN;
+ m->m_len = m->m_pkthdr.len = MJUM9BYTES;
if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0)
m_adj(m, ETHER_ALIGN);
#ifndef __NO_STRICT_ALIGNMENT
@@ -936,20 +934,20 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
switch(command) {
case SIOCSIFMTU:
- if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN) {
- error = EINVAL;
- break;
- }
- if (sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_FE &&
- ifr->ifr_mtu > MSK_MAX_FRAMELEN) {
+ if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN)
error = EINVAL;
- break;
+ else if (ifp->if_mtu != ifr->ifr_mtu) {
+ if ((sc_if->msk_flags & MSK_FLAG_NOJUMBO) != 0 &&
+ ifr->ifr_mtu > ETHERMTU)
+ error = EINVAL;
+ else {
+ MSK_IF_LOCK(sc_if);
+ ifp->if_mtu = ifr->ifr_mtu;
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ msk_init_locked(sc_if);
+ MSK_IF_UNLOCK(sc_if);
+ }
}
- MSK_IF_LOCK(sc_if);
- ifp->if_mtu = ifr->ifr_mtu;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
- msk_init_locked(sc_if);
- MSK_IF_UNLOCK(sc_if);
break;
case SIOCSIFFLAGS:
MSK_IF_LOCK(sc_if);
@@ -1007,7 +1005,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
else
ifp->if_hwassist &= ~CSUM_TSO;
}
- if (sc_if->msk_framesize > MSK_MAX_FRAMELEN &&
+ if (ifp->if_mtu > ETHERMTU &&
sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U) {
/*
* In Yukon EC Ultra, TSO & checksum offload is not
@@ -1442,9 +1440,15 @@ msk_attach(device_t dev)
callout_init_mtx(&sc_if->msk_tick_ch, &sc_if->msk_softc->msk_mtx, 0);
TASK_INIT(&sc_if->msk_link_task, 0, msk_link_task, sc_if);
+ msk_sysctl_node(sc_if);
+
+ /* Disable jumbo frame for Yukon FE. */
+ if (sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_FE)
+ sc_if->msk_flags |= MSK_FLAG_NOJUMBO;
if ((error = msk_txrx_dma_alloc(sc_if) != 0))
goto fail;
+ msk_rx_dma_jalloc(sc_if);
ifp = sc_if->msk_ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
@@ -1519,9 +1523,6 @@ msk_attach(device_t dev)
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
- sc_if->msk_framesize = ifp->if_mtu + ETHER_HDR_LEN +
- ETHER_VLAN_ENCAP_LEN;
-
/*
* Do miibus setup.
*/
@@ -1829,6 +1830,7 @@ msk_detach(device_t dev)
* }
*/
+ msk_rx_dma_jfree(sc_if);
msk_txrx_dma_free(sc_if);
bus_generic_detach(dev);
@@ -1989,16 +1991,9 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
struct msk_dmamap_arg ctx;
struct msk_txdesc *txd;
struct msk_rxdesc *rxd;
- struct msk_rxdesc *jrxd;
- struct msk_jpool_entry *entry;
- uint8_t *ptr;
bus_size_t rxalign;
int error, i;
- mtx_init(&sc_if->msk_jlist_mtx, "msk_jlist_mtx", NULL, MTX_DEF);
- SLIST_INIT(&sc_if->msk_jfree_listhead);
- SLIST_INIT(&sc_if->msk_jinuse_listhead);
-
/* Create parent DMA tag. */
/*
* XXX
@@ -2070,42 +2065,6 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
goto fail;
}
- /* Create tag for jumbo Rx ring. */
- error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
- MSK_RING_ALIGN, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MSK_JUMBO_RX_RING_SZ, /* maxsize */
- 1, /* nsegments */
- MSK_JUMBO_RX_RING_SZ, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc_if->msk_cdata.msk_jumbo_rx_ring_tag);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to create jumbo Rx ring DMA tag\n");
- goto fail;
- }
-
- /* Create tag for jumbo buffer blocks. */
- error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
- PAGE_SIZE, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MSK_JMEM, /* maxsize */
- 1, /* nsegments */
- MSK_JMEM, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc_if->msk_cdata.msk_jumbo_tag);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to create jumbo Rx buffer block DMA tag\n");
- goto fail;
- }
-
/* Create tag for Tx buffers. */
error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
1, 0, /* alignment, boundary */
@@ -2149,24 +2108,6 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
goto fail;
}
- /* Create tag for jumbo Rx buffers. */
- error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
- PAGE_SIZE, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MCLBYTES * MSK_MAXRXSEGS, /* maxsize */
- MSK_MAXRXSEGS, /* nsegments */
- MSK_JLEN, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc_if->msk_cdata.msk_jumbo_rx_tag);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to create jumbo Rx DMA tag\n");
- goto fail;
- }
-
/* Allocate DMA'able memory and load the DMA map for Tx ring. */
error = bus_dmamem_alloc(sc_if->msk_cdata.msk_tx_ring_tag,
(void **)&sc_if->msk_rdata.msk_tx_ring, BUS_DMA_WAITOK |
@@ -2209,29 +2150,6 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
}
sc_if->msk_rdata.msk_rx_ring_paddr = ctx.msk_busaddr;
- /* Allocate DMA'able memory and load the DMA map for jumbo Rx ring. */
- error = bus_dmamem_alloc(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
- (void **)&sc_if->msk_rdata.msk_jumbo_rx_ring,
- BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
- &sc_if->msk_cdata.msk_jumbo_rx_ring_map);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to allocate DMA'able memory for jumbo Rx ring\n");
- goto fail;
- }
-
- ctx.msk_busaddr = 0;
- error = bus_dmamap_load(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
- sc_if->msk_cdata.msk_jumbo_rx_ring_map,
- sc_if->msk_rdata.msk_jumbo_rx_ring, MSK_JUMBO_RX_RING_SZ,
- msk_dmamap_cb, &ctx, 0);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to load DMA'able memory for jumbo Rx ring\n");
- goto fail;
- }
- sc_if->msk_rdata.msk_jumbo_rx_ring_paddr = ctx.msk_busaddr;
-
/* Create DMA maps for Tx buffers. */
for (i = 0; i < MSK_TX_RING_CNT; i++) {
txd = &sc_if->msk_cdata.msk_txdesc[i];
@@ -2264,12 +2182,98 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
goto fail;
}
}
+
+fail:
+ return (error);
+}
+
+static int
+msk_rx_dma_jalloc(struct msk_if_softc *sc_if)
+{
+ struct msk_dmamap_arg ctx;
+ struct msk_rxdesc *jrxd;
+ bus_size_t rxalign;
+ int error, i;
+
+ if (jumbo_disable != 0 || (sc_if->msk_flags & MSK_FLAG_NOJUMBO) != 0) {
+ sc_if->msk_flags |= MSK_FLAG_NOJUMBO;
+ device_printf(sc_if->msk_if_dev,
+ "disabling jumbo frame support\n");
+ sc_if->msk_flags |= MSK_FLAG_NOJUMBO;
+ return (0);
+ }
+ /* Create tag for jumbo Rx ring. */
+ error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
+ MSK_RING_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MSK_JUMBO_RX_RING_SZ, /* maxsize */
+ 1, /* nsegments */
+ MSK_JUMBO_RX_RING_SZ, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc_if->msk_cdata.msk_jumbo_rx_ring_tag);
+ if (error != 0) {
+ device_printf(sc_if->msk_if_dev,
+ "failed to create jumbo Rx ring DMA tag\n");
+ goto jumbo_fail;
+ }
+
+ rxalign = 1;
+ /*
+ * Workaround hardware hang which seems to happen when Rx buffer
+ * is not aligned on multiple of FIFO word(8 bytes).
+ */
+ if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) != 0)
+ rxalign = MSK_RX_BUF_ALIGN;
+ /* Create tag for jumbo Rx buffers. */
+ error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
+ rxalign, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MJUM9BYTES, /* maxsize */
+ 1, /* nsegments */
+ MJUM9BYTES, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc_if->msk_cdata.msk_jumbo_rx_tag);
+ if (error != 0) {
+ device_printf(sc_if->msk_if_dev,
+ "failed to create jumbo Rx DMA tag\n");
+ goto jumbo_fail;
+ }
+
+ /* Allocate DMA'able memory and load the DMA map for jumbo Rx ring. */
+ error = bus_dmamem_alloc(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
+ (void **)&sc_if->msk_rdata.msk_jumbo_rx_ring,
+ BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
+ &sc_if->msk_cdata.msk_jumbo_rx_ring_map);
+ if (error != 0) {
+ device_printf(sc_if->msk_if_dev,
+ "failed to allocate DMA'able memory for jumbo Rx ring\n");
+ goto jumbo_fail;
+ }
+
+ ctx.msk_busaddr = 0;
+ error = bus_dmamap_load(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
+ sc_if->msk_cdata.msk_jumbo_rx_ring_map,
+ sc_if->msk_rdata.msk_jumbo_rx_ring, MSK_JUMBO_RX_RING_SZ,
+ msk_dmamap_cb, &ctx, 0);
+ if (error != 0) {
+ device_printf(sc_if->msk_if_dev,
+ "failed to load DMA'able memory for jumbo Rx ring\n");
+ goto jumbo_fail;
+ }
+ sc_if->msk_rdata.msk_jumbo_rx_ring_paddr = ctx.msk_busaddr;
+
/* Create DMA maps for jumbo Rx buffers. */
if ((error = bus_dmamap_create(sc_if->msk_cdata.msk_jumbo_rx_tag, 0,
&sc_if->msk_cdata.msk_jumbo_rx_sparemap)) != 0) {
device_printf(sc_if->msk_if_dev,
"failed to create spare jumbo Rx dmamap\n");
- goto fail;
+ goto jumbo_fail;
}
for (i = 0; i < MSK_JUMBO_RX_RING_CNT; i++) {
jrxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[i];
@@ -2280,54 +2284,17 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
if (error != 0) {
device_printf(sc_if->msk_if_dev,
"failed to create jumbo Rx dmamap\n");
- goto fail;
+ goto jumbo_fail;
}
}
- /* Allocate DMA'able memory and load the DMA map for jumbo buf. */
- error = bus_dmamem_alloc(sc_if->msk_cdata.msk_jumbo_tag,
- (void **)&sc_if->msk_rdata.msk_jumbo_buf,
- BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
- &sc_if->msk_cdata.msk_jumbo_map);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to allocate DMA'able memory for jumbo buf\n");
- goto fail;
- }
-
- ctx.msk_busaddr = 0;
- error = bus_dmamap_load(sc_if->msk_cdata.msk_jumbo_tag,
- sc_if->msk_cdata.msk_jumbo_map, sc_if->msk_rdata.msk_jumbo_buf,
- MSK_JMEM, msk_dmamap_cb, &ctx, 0);
- if (error != 0) {
- device_printf(sc_if->msk_if_dev,
- "failed to load DMA'able memory for jumbobuf\n");
- goto fail;
- }
- sc_if->msk_rdata.msk_jumbo_buf_paddr = ctx.msk_busaddr;
-
- /*
- * Now divide it up into 9K pieces and save the addresses
- * in an array.
- */
- ptr = sc_if->msk_rdata.msk_jumbo_buf;
- for (i = 0; i < MSK_JSLOTS; i++) {
- sc_if->msk_cdata.msk_jslots[i] = ptr;
- ptr += MSK_JLEN;
- entry = malloc(sizeof(struct msk_jpool_entry),
- M_DEVBUF, M_WAITOK);
- if (entry == NULL) {
- device_printf(sc_if->msk_if_dev,
- "no memory for jumbo buffers!\n");
- error = ENOMEM;
- goto fail;
- }
- entry->slot = i;
- SLIST_INSERT_HEAD(&sc_if->msk_jfree_listhead, entry,
- jpool_entries);
- }
+ return (0);
-fail:
+jumbo_fail:
+ msk_rx_dma_jfree(sc_if);
+ device_printf(sc_if->msk_if_dev, "disabling jumbo frame support "
+ "due to resource shortage\n");
+ sc_if->msk_flags |= MSK_FLAG_NOJUMBO;
return (error);
}
@@ -2336,39 +2303,8 @@ msk_txrx_dma_free(struct msk_if_softc *sc_if)
{
struct msk_txdesc *txd;
struct msk_rxdesc *rxd;
- struct msk_rxdesc *jrxd;
- struct msk_jpool_entry *entry;
int i;
- MSK_JLIST_LOCK(sc_if);
- while ((entry = SLIST_FIRST(&sc_if->msk_jinuse_listhead))) {
- device_printf(sc_if->msk_if_dev,
- "asked to free buffer that is in use!\n");
- SLIST_REMOVE_HEAD(&sc_if->msk_jinuse_listhead, jpool_entries);
- SLIST_INSERT_HEAD(&sc_if->msk_jfree_listhead, entry,
- jpool_entries);
- }
-
- while (!SLIST_EMPTY(&sc_if->msk_jfree_listhead)) {
- entry = SLIST_FIRST(&sc_if->msk_jfree_listhead);
- SLIST_REMOVE_HEAD(&sc_if->msk_jfree_listhead, jpool_entries);
- free(entry, M_DEVBUF);
- }
- MSK_JLIST_UNLOCK(sc_if);
-
- /* Destroy jumbo buffer block. */
- if (sc_if->msk_cdata.msk_jumbo_map)
- bus_dmamap_unload(sc_if->msk_cdata.msk_jumbo_tag,
- sc_if->msk_cdata.msk_jumbo_map);
-
- if (sc_if->msk_rdata.msk_jumbo_buf) {
- bus_dmamem_free(sc_if->msk_cdata.msk_jumbo_tag,
- sc_if->msk_rdata.msk_jumbo_buf,
- sc_if->msk_cdata.msk_jumbo_map);
- sc_if->msk_rdata.msk_jumbo_buf = NULL;
- sc_if->msk_cdata.msk_jumbo_map = NULL;
- }
-
/* Tx ring. */
if (sc_if->msk_cdata.msk_tx_ring_tag) {
if (sc_if->msk_cdata.msk_tx_ring_map)
@@ -2399,21 +2335,6 @@ msk_txrx_dma_free(struct msk_if_softc *sc_if)
bus_dma_tag_destroy(sc_if->msk_cdata.msk_rx_ring_tag);
sc_if->msk_cdata.msk_rx_ring_tag = NULL;
}
- /* Jumbo Rx ring. */
- if (sc_if->msk_cdata.msk_jumbo_rx_ring_tag) {
- if (sc_if->msk_cdata.msk_jumbo_rx_ring_map)
- bus_dmamap_unload(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
- sc_if->msk_cdata.msk_jumbo_rx_ring_map);
- if (sc_if->msk_cdata.msk_jumbo_rx_ring_map &&
- sc_if->msk_rdata.msk_jumbo_rx_ring)
- bus_dmamem_free(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
- sc_if->msk_rdata.msk_jumbo_rx_ring,
- sc_if->msk_cdata.msk_jumbo_rx_ring_map);
- sc_if->msk_rdata.msk_jumbo_rx_ring = NULL;
- sc_if->msk_cdata.msk_jumbo_rx_ring_map = NULL;
- bus_dma_tag_destroy(sc_if->msk_cdata.msk_jumbo_rx_ring_tag);
- sc_if->msk_cdata.msk_jumbo_rx_ring_tag = NULL;
- }
/* Tx buffers. */
if (sc_if->msk_cdata.msk_tx_tag) {
for (i = 0; i < MSK_TX_RING_CNT; i++) {
@@ -2445,6 +2366,33 @@ msk_txrx_dma_free(struct msk_if_softc *sc_if)
bus_dma_tag_destroy(sc_if->msk_cdata.msk_rx_tag);
sc_if->msk_cdata.msk_rx_tag = NULL;
}
+ if (sc_if->msk_cdata.msk_parent_tag) {
+ bus_dma_tag_destroy(sc_if->msk_cdata.msk_parent_tag);
+ sc_if->msk_cdata.msk_parent_tag = NULL;
+ }
+}
+
+static void
+msk_rx_dma_jfree(struct msk_if_softc *sc_if)
+{
+ struct msk_rxdesc *jrxd;
+ int i;
+
+ /* Jumbo Rx ring. */
+ if (sc_if->msk_cdata.msk_jumbo_rx_ring_tag) {
+ if (sc_if->msk_cdata.msk_jumbo_rx_ring_map)
+ bus_dmamap_unload(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
+ sc_if->msk_cdata.msk_jumbo_rx_ring_map);
+ if (sc_if->msk_cdata.msk_jumbo_rx_ring_map &&
+ sc_if->msk_rdata.msk_jumbo_rx_ring)
+ bus_dmamem_free(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
+ sc_if->msk_rdata.msk_jumbo_rx_ring,
+ sc_if->msk_cdata.msk_jumbo_rx_ring_map);
+ sc_if->msk_rdata.msk_jumbo_rx_ring = NULL;
+ sc_if->msk_cdata.msk_jumbo_rx_ring_map = NULL;
+ bus_dma_tag_destroy(sc_if->msk_cdata.msk_jumbo_rx_ring_tag);
+ sc_if->msk_cdata.msk_jumbo_rx_ring_tag = NULL;
+ }
/* Jumbo Rx buffers. */
if (sc_if->msk_cdata.msk_jumbo_rx_tag) {
for (i = 0; i < MSK_JUMBO_RX_RING_CNT; i++) {
@@ -2464,69 +2412,6 @@ msk_txrx_dma_free(struct msk_if_softc *sc_if)
bus_dma_tag_destroy(sc_if->msk_cdata.msk_jumbo_rx_tag);
sc_if->msk_cdata.msk_jumbo_rx_tag = NULL;
}
-
- if (sc_if->msk_cdata.msk_parent_tag) {
- bus_dma_tag_destroy(sc_if->msk_cdata.msk_parent_tag);
- sc_if->msk_cdata.msk_parent_tag = NULL;
- }
- mtx_destroy(&sc_if->msk_jlist_mtx);
-}
-
-/*
- * Allocate a jumbo buffer.
- */
-static void *
-msk_jalloc(struct msk_if_softc *sc_if)
-{
- struct msk_jpool_entry *entry;
-
- MSK_JLIST_LOCK(sc_if);
-
- entry = SLIST_FIRST(&sc_if->msk_jfree_listhead);
-
- if (entry == NULL) {
- MSK_JLIST_UNLOCK(sc_if);
- return (NULL);
- }
-
- SLIST_REMOVE_HEAD(&sc_if->msk_jfree_listhead, jpool_entries);
- SLIST_INSERT_HEAD(&sc_if->msk_jinuse_listhead, entry, jpool_entries);
-
- MSK_JLIST_UNLOCK(sc_if);
-
- return (sc_if->msk_cdata.msk_jslots[entry->slot]);
-}
-
-/*
- * Release a jumbo buffer.
- */
-static void
-msk_jfree(void *buf, void *args)
-{
- struct msk_if_softc *sc_if;
- struct msk_jpool_entry *entry;
- int i;
-
- /* Extract the softc struct pointer. */
- sc_if = (struct msk_if_softc *)args;
- KASSERT(sc_if != NULL, ("%s: can't find softc pointer!", __func__));
-
- MSK_JLIST_LOCK(sc_if);
- /* Calculate the slot this buffer belongs to. */
- i = ((vm_offset_t)buf
- - (vm_offset_t)sc_if->msk_rdata.msk_jumbo_buf) / MSK_JLEN;
- KASSERT(i >= 0 && i < MSK_JSLOTS,
- ("%s: asked to free buffer that we don't manage!", __func__));
-
- entry = SLIST_FIRST(&sc_if->msk_jinuse_listhead);
- KASSERT(entry != NULL, ("%s: buffer not in use!", __func__));
- entry->slot = i;
- SLIST_REMOVE_HEAD(&sc_if->msk_jinuse_listhead, jpool_entries);
- SLIST_INSERT_HEAD(&sc_if->msk_jfree_listhead, entry, jpool_entries);
- if (SLIST_EMPTY(&sc_if->msk_jinuse_listhead))
- wakeup(sc_if);
-
- MSK_JLIST_UNLOCK(sc_if);
}
static int
@@ -2608,17 +2493,14 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
*/
if (m->m_pkthdr.len < MSK_MIN_FRAMELEN &&
(m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
- uint16_t csum;
-
m = m_pullup(m, offset + sizeof(struct tcphdr));
if (m == NULL) {
*m_head = NULL;
return (ENOBUFS);
}
- csum = in_cksum_skip(m, ntohs(ip->ip_len) + offset -
- (ip->ip_hl << 2), offset);
*(uint16_t *)(m->m_data + offset +
- m->m_pkthdr.csum_data) = csum;
+ m->m_pkthdr.csum_data) = in_cksum_skip(m,
+ m->m_pkthdr.len, offset);
m->m_pkthdr.csum_flags &= ~CSUM_TCP;
}
if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
@@ -3331,7 +3213,7 @@ msk_rxput(struct msk_if_softc *sc_if)
struct msk_softc *sc;
sc = sc_if->msk_softc;
- if (sc_if->msk_framesize >(MCLBYTES - ETHER_HDR_LEN))
+ if (sc_if->msk_framesize > (MCLBYTES - MSK_RX_BUF_ALIGN))
bus_dmamap_sync(
sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
sc_if->msk_cdata.msk_jumbo_rx_ring_map,
@@ -3398,7 +3280,8 @@ msk_handle_events(struct msk_softc *sc)
sc_if->msk_vtag = ntohs(len);
break;
case OP_RXSTAT:
- if (sc_if->msk_framesize > (MCLBYTES - ETHER_HDR_LEN))
+ if (sc_if->msk_framesize >
+ (MCLBYTES - MSK_RX_BUF_ALIGN))
msk_jumbo_rxeof(sc_if, status, len);
else
msk_rxeof(sc_if, status, len);
@@ -3636,9 +3519,12 @@ msk_init_locked(struct msk_if_softc *sc_if)
/* Cancel pending I/O and free all Rx/Tx buffers. */
msk_stop(sc_if);
- sc_if->msk_framesize = ifp->if_mtu + ETHER_HDR_LEN +
- ETHER_VLAN_ENCAP_LEN;
- if (sc_if->msk_framesize > MSK_MAX_FRAMELEN &&
+ if (ifp->if_mtu < ETHERMTU)
+ sc_if->msk_framesize = ETHERMTU;
+ else
+ sc_if->msk_framesize = ifp->if_mtu;
+ sc_if->msk_framesize += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ if (ifp->if_mtu > ETHERMTU &&
sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U) {
/*
* In Yukon EC Ultra, TSO & checksum offload is not
@@ -3664,15 +3550,8 @@ msk_init_locked(struct msk_if_softc *sc_if)
/* Dummy read the Interrupt Source Register. */
CSR_READ_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_SRC));
- /* Set MIB Clear Counter Mode. */
- gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR);
- GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR);
- /* Read all MIB Counters with Clear Mode set. */
- for (i = 0; i < GM_MIB_CNT_SIZE; i++)
- GMAC_READ_2(sc, sc_if->msk_port, GM_MIB_CNT_BASE + 8 * i);
- /* Clear MIB Clear Counter Mode. */
- gmac &= ~GM_PAR_MIB_CLR;
- GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac);
+ /* Clear MIB stats. */
+ msk_stats_clear(sc_if);
/* Disable FCS. */
GMAC_WRITE_2(sc, sc_if->msk_port, GM_RX_CTRL, GM_RXCR_CRC_DIS);
@@ -3691,7 +3570,7 @@ msk_init_locked(struct msk_if_softc *sc_if)
gmac = DATA_BLIND_VAL(DATA_BLIND_DEF) |
GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
- if (sc_if->msk_framesize > MSK_MAX_FRAMELEN)
+ if (ifp->if_mtu > ETHERMTU)
gmac |= GM_SMOD_JUMBO_ENA;
GMAC_WRITE_2(sc, sc_if->msk_port, GM_SERIAL_MODE, gmac);
@@ -3746,7 +3625,7 @@ msk_init_locked(struct msk_if_softc *sc_if)
MSK_ECU_LLPP);
CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, RX_GMF_UP_THR),
MSK_ECU_ULPP);
- if (sc_if->msk_framesize > MSK_MAX_FRAMELEN) {
+ if (ifp->if_mtu > ETHERMTU) {
/*
* Set Tx GMAC FIFO Almost Empty Threshold.
*/
@@ -3806,7 +3685,7 @@ msk_init_locked(struct msk_if_softc *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);
- if (sc_if->msk_framesize > (MCLBYTES - ETHER_HDR_LEN)) {
+ 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,
MSK_JUMBO_RX_RING_CNT - 1);
@@ -3958,6 +3837,8 @@ msk_stop(struct msk_if_softc *sc_if)
GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, val);
/* Read again to ensure writing. */
GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL);
+ /* Update stats and clear counters. */
+ msk_stats_update(sc_if);
/* Stop Tx BMU. */
CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_CSR), BMU_STOP);
@@ -4073,6 +3954,295 @@ msk_stop(struct msk_if_softc *sc_if)
sc_if->msk_link = 0;
}
+/*
+ * When GM_PAR_MIB_CLR bit of GM_PHY_ADDR is set, reading lower
+ * counter clears high 16 bits of the counter such that accessing
+ * lower 16 bits should be the last operation.
+ */
+#define MSK_READ_MIB32(x, y) \
+ (((uint32_t)GMAC_READ_2(sc, x, (y) + 4)) << 16) + \
+ (uint32_t)GMAC_READ_2(sc, x, y)
+#define MSK_READ_MIB64(x, y) \
+ (((uint64_t)MSK_READ_MIB32(x, (y) + 8)) << 32) + \
+ (uint64_t)MSK_READ_MIB32(x, y)
+
+static void
+msk_stats_clear(struct msk_if_softc *sc_if)
+{
+ struct msk_softc *sc;
+ uint32_t reg;
+ uint16_t gmac;
+ int i;
+
+ MSK_IF_LOCK_ASSERT(sc_if);
+
+ sc = sc_if->msk_softc;
+ /* Set MIB Clear Counter Mode. */
+ gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR);
+ GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR);
+ /* Read all MIB Counters with Clear Mode set. */
+ for (i = GM_RXF_UC_OK; i <= GM_TXE_FIFO_UR; i++)
+ reg = MSK_READ_MIB32(sc_if->msk_port, i);
+ /* Clear MIB Clear Counter Mode. */
+ gmac &= ~GM_PAR_MIB_CLR;
+ GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac);
+}
+
+static void
+msk_stats_update(struct msk_if_softc *sc_if)
+{
+ struct msk_softc *sc;
+ struct ifnet *ifp;
+ struct msk_hw_stats *stats;
+ uint16_t gmac;
+ uint32_t reg;
+
+ MSK_IF_LOCK_ASSERT(sc_if);
+
+ ifp = sc_if->msk_ifp;
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ return;
+ sc = sc_if->msk_softc;
+ stats = &sc_if->msk_stats;
+ /* Set MIB Clear Counter Mode. */
+ gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR);
+ GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR);
+
+ /* Rx stats. */
+ stats->rx_ucast_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_UC_OK);
+ stats->rx_bcast_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_BC_OK);
+ stats->rx_pause_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_MPAUSE);
+ stats->rx_mcast_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_MC_OK);
+ stats->rx_crc_errs +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_FCS_ERR);
+ reg = MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SPARE1);
+ stats->rx_good_octets +=
+ MSK_READ_MIB64(sc_if->msk_port, GM_RXO_OK_LO);
+ stats->rx_bad_octets +=
+ MSK_READ_MIB64(sc_if->msk_port, GM_RXO_ERR_LO);
+ stats->rx_runts +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SHT);
+ stats->rx_runt_errs +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXE_FRAG);
+ stats->rx_pkts_64 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_64B);
+ stats->rx_pkts_65_127 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_127B);
+ stats->rx_pkts_128_255 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_255B);
+ stats->rx_pkts_256_511 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_511B);
+ stats->rx_pkts_512_1023 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_1023B);
+ stats->rx_pkts_1024_1518 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_1518B);
+ stats->rx_pkts_1519_max +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_MAX_SZ);
+ stats->rx_pkts_too_long +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_LNG_ERR);
+ stats->rx_pkts_jabbers +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXF_JAB_PKT);
+ reg = MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SPARE2);
+ stats->rx_fifo_oflows +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_RXE_FIFO_OV);
+ reg = MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SPARE3);
+
+ /* Tx stats. */
+ stats->tx_ucast_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_UC_OK);
+ stats->tx_bcast_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_BC_OK);
+ stats->tx_pause_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MPAUSE);
+ stats->tx_mcast_frames +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MC_OK);
+ stats->tx_octets +=
+ MSK_READ_MIB64(sc_if->msk_port, GM_TXO_OK_LO);
+ stats->tx_pkts_64 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_64B);
+ stats->tx_pkts_65_127 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_127B);
+ stats->tx_pkts_128_255 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_255B);
+ stats->tx_pkts_256_511 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_511B);
+ stats->tx_pkts_512_1023 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_1023B);
+ stats->tx_pkts_1024_1518 +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_1518B);
+ stats->tx_pkts_1519_max +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MAX_SZ);
+ reg = MSK_READ_MIB32(sc_if->msk_port, GM_TXF_SPARE1);
+ stats->tx_colls +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_COL);
+ stats->tx_late_colls +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_LAT_COL);
+ stats->tx_excess_colls +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_ABO_COL);
+ stats->tx_multi_colls +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MUL_COL);
+ stats->tx_single_colls +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXF_SNG_COL);
+ stats->tx_underflows +=
+ MSK_READ_MIB32(sc_if->msk_port, GM_TXE_FIFO_UR);
+ /* Clear MIB Clear Counter Mode. */
+ gmac &= ~GM_PAR_MIB_CLR;
+ GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac);
+}
+
+static int
+msk_sysctl_stat32(SYSCTL_HANDLER_ARGS)
+{
+ struct msk_softc *sc;
+ struct msk_if_softc *sc_if;
+ uint32_t result, *stat;
+ int off;
+
+ sc_if = (struct msk_if_softc *)arg1;
+ sc = sc_if->msk_softc;
+ off = arg2;
+ stat = (uint32_t *)((uint8_t *)&sc_if->msk_stats + off);
+
+ MSK_IF_LOCK(sc_if);
+ result = MSK_READ_MIB32(sc_if->msk_port, GM_MIB_CNT_BASE + off * 2);
+ result += *stat;
+ MSK_IF_UNLOCK(sc_if);
+
+ return (sysctl_handle_int(oidp, &result, 0, req));
+}
+
+static int
+msk_sysctl_stat64(SYSCTL_HANDLER_ARGS)
+{
+ struct msk_softc *sc;
+ struct msk_if_softc *sc_if;
+ uint64_t result, *stat;
+ int off;
+
+ sc_if = (struct msk_if_softc *)arg1;
+ sc = sc_if->msk_softc;
+ off = arg2;
+ stat = (uint64_t *)((uint8_t *)&sc_if->msk_stats + off);
+
+ MSK_IF_LOCK(sc_if);
+ result = MSK_READ_MIB64(sc_if->msk_port, GM_MIB_CNT_BASE + off * 2);
+ result += *stat;
+ MSK_IF_UNLOCK(sc_if);
+
+ return (sysctl_handle_quad(oidp, &result, 0, req));
+}
+
+#undef MSK_READ_MIB32
+#undef MSK_READ_MIB64
+
+#define MSK_SYSCTL_STAT32(sc, c, o, p, n, d) \
+ SYSCTL_ADD_PROC(c, p, OID_AUTO, o, CTLTYPE_UINT | CTLFLAG_RD, \
+ sc, offsetof(struct msk_hw_stats, n), msk_sysctl_stat32, \
+ "IU", d)
+#define MSK_SYSCTL_STAT64(sc, c, o, p, n, d) \
+ SYSCTL_ADD_PROC(c, p, OID_AUTO, o, CTLTYPE_UINT | CTLFLAG_RD, \
+ sc, offsetof(struct msk_hw_stats, n), msk_sysctl_stat64, \
+ "Q", d)
+
+static void
+msk_sysctl_node(struct msk_if_softc *sc_if)
+{
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid_list *child, *schild;
+ struct sysctl_oid *tree;
+
+ ctx = device_get_sysctl_ctx(sc_if->msk_if_dev);
+ child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc_if->msk_if_dev));
+
+ tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+ NULL, "MSK Statistics");
+ schild = child = SYSCTL_CHILDREN(tree);
+ tree = SYSCTL_ADD_NODE(ctx, schild, OID_AUTO, "rx", CTLFLAG_RD,
+ NULL, "MSK RX Statistics");
+ child = SYSCTL_CHILDREN(tree);
+ MSK_SYSCTL_STAT32(sc_if, ctx, "ucast_frames",
+ child, rx_ucast_frames, "Good unicast frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "bcast_frames",
+ child, rx_bcast_frames, "Good broadcast frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "pause_frames",
+ child, rx_pause_frames, "Pause frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "mcast_frames",
+ child, rx_mcast_frames, "Multicast frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "crc_errs",
+ child, rx_crc_errs, "CRC errors");
+ MSK_SYSCTL_STAT64(sc_if, ctx, "good_octets",
+ child, rx_good_octets, "Good octets");
+ MSK_SYSCTL_STAT64(sc_if, ctx, "bad_octets",
+ child, rx_bad_octets, "Bad octets");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_64",
+ child, rx_pkts_64, "64 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_65_127",
+ child, rx_pkts_65_127, "65 to 127 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_128_255",
+ child, rx_pkts_128_255, "128 to 255 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_256_511",
+ child, rx_pkts_256_511, "256 to 511 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_512_1023",
+ child, rx_pkts_512_1023, "512 to 1023 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1024_1518",
+ child, rx_pkts_1024_1518, "1024 to 1518 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1519_max",
+ child, rx_pkts_1519_max, "1519 to max frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_too_long",
+ child, rx_pkts_too_long, "frames too long");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "jabbers",
+ child, rx_pkts_jabbers, "Jabber errors");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "jabbers",
+ child, rx_fifo_oflows, "FIFO overflows");
+
+ tree = SYSCTL_ADD_NODE(ctx, schild, OID_AUTO, "tx", CTLFLAG_RD,
+ NULL, "MSK TX Statistics");
+ child = SYSCTL_CHILDREN(tree);
+ MSK_SYSCTL_STAT32(sc_if, ctx, "ucast_frames",
+ child, tx_ucast_frames, "Unicast frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "bcast_frames",
+ child, tx_bcast_frames, "Broadcast frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "pause_frames",
+ child, tx_pause_frames, "Pause frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "mcast_frames",
+ child, tx_mcast_frames, "Multicast frames");
+ MSK_SYSCTL_STAT64(sc_if, ctx, "octets",
+ child, tx_octets, "Octets");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_64",
+ child, tx_pkts_64, "64 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_65_127",
+ child, tx_pkts_65_127, "65 to 127 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_128_255",
+ child, tx_pkts_128_255, "128 to 255 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_256_511",
+ child, tx_pkts_256_511, "256 to 511 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_512_1023",
+ child, tx_pkts_512_1023, "512 to 1023 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1024_1518",
+ child, tx_pkts_1024_1518, "1024 to 1518 bytes frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1519_max",
+ child, tx_pkts_1519_max, "1519 to max frames");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "colls",
+ child, tx_colls, "Collisions");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "late_colls",
+ child, tx_late_colls, "Late collisions");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "excess_colls",
+ child, tx_excess_colls, "Excessive collisions");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "multi_colls",
+ child, tx_multi_colls, "Multiple collisions");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "single_colls",
+ child, tx_single_colls, "Single collisions");
+ MSK_SYSCTL_STAT32(sc_if, ctx, "underflows",
+ child, tx_underflows, "FIFO underflows");
+}
+
+#undef MSK_SYSCTL_STAT32
+#undef MSK_SYSCTL_STAT64
+
static int
sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
{
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index c0bd90e..09b0d0c 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -1614,6 +1614,8 @@
(GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */
#define GM_RXF_FCS_ERR \
(GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */
+#define GM_RXF_SPARE1 \
+ (GM_MIB_CNT_BASE + 40) /* Rx spare 1 */
#define GM_RXO_OK_LO \
(GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */
#define GM_RXO_OK_HI \
@@ -1644,8 +1646,12 @@
(GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
#define GM_RXF_JAB_PKT \
(GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
+#define GM_RXF_SPARE2 \
+ (GM_MIB_CNT_BASE + 168) /* Rx spare 2 */
#define GM_RXE_FIFO_OV \
(GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
+#define GM_RXF_SPARE3 \
+ (GM_MIB_CNT_BASE + 184) /* Rx spare 3 */
#define GM_TXF_UC_OK \
(GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
#define GM_TXF_BC_OK \
@@ -1672,6 +1678,8 @@
(GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
#define GM_TXF_MAX_SZ \
(GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
+#define GM_TXF_SPARE1 \
+ (GM_MIB_CNT_BASE + 296) /* Tx spare 1 */
#define GM_TXF_COL \
(GM_MIB_CNT_BASE + 304) /* Tx Collision */
#define GM_TXF_LAT_COL \
@@ -2164,7 +2172,6 @@ struct msk_stat_desc {
#define MSK_MAXTXSEGS 32
#define MSK_TSO_MAXSGSIZE 4096
#define MSK_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
-#define MSK_MAXRXSEGS 32
/*
* It seems that the hardware requires extra decriptors(LEs) to offload
@@ -2191,20 +2198,6 @@ struct msk_stat_desc {
#define MSK_MAX_FRAMELEN \
(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN - ETHER_CRC_LEN)
#define MSK_MIN_FRAMELEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
-#define MSK_JSLOTS ((MSK_RX_RING_CNT * 3) / 2)
-
-#define MSK_JRAWLEN (MSK_JUMBO_FRAMELEN + ETHER_ALIGN)
-#define MSK_JLEN (MSK_JRAWLEN + (sizeof(uint64_t) - \
- (MSK_JRAWLEN % sizeof(uint64_t))))
-#define MSK_JPAGESZ PAGE_SIZE
-#define MSK_RESID \
- (MSK_JPAGESZ - (MSK_JLEN * MSK_JSLOTS) % MSK_JPAGESZ)
-#define MSK_JMEM ((MSK_JLEN * MSK_JSLOTS) + MSK_RESID)
-
-struct msk_jpool_entry {
- int slot;
- SLIST_ENTRY(msk_jpool_entry) jpool_entries;
-};
struct msk_txdesc {
struct mbuf *tx_m;
@@ -2230,10 +2223,6 @@ struct msk_chain_data {
bus_dmamap_t msk_rx_ring_map;
bus_dmamap_t msk_rx_sparemap;
bus_dma_tag_t msk_jumbo_rx_tag;
- bus_dma_tag_t msk_jumbo_tag;
- bus_dmamap_t msk_jumbo_map;
- bus_dma_tag_t msk_jumbo_mtag;
- caddr_t msk_jslots[MSK_JSLOTS];
struct msk_rxdesc msk_jumbo_rxdesc[MSK_JUMBO_RX_RING_CNT];
bus_dma_tag_t msk_jumbo_rx_ring_tag;
bus_dmamap_t msk_jumbo_rx_ring_map;
@@ -2255,8 +2244,6 @@ struct msk_ring_data {
bus_addr_t msk_rx_ring_paddr;
struct msk_rx_desc *msk_jumbo_rx_ring;
bus_addr_t msk_jumbo_rx_ring_paddr;
- void *msk_jumbo_buf;
- bus_addr_t msk_jumbo_buf_paddr;
};
#define MSK_TX_RING_ADDR(sc, i) \
@@ -2291,6 +2278,52 @@ struct msk_ring_data {
/* Forward decl. */
struct msk_if_softc;
+struct msk_hw_stats {
+ /* Rx stats. */
+ uint32_t rx_ucast_frames;
+ uint32_t rx_bcast_frames;
+ uint32_t rx_pause_frames;
+ uint32_t rx_mcast_frames;
+ uint32_t rx_crc_errs;
+ uint32_t rx_spare1;
+ uint64_t rx_good_octets;
+ uint64_t rx_bad_octets;
+ uint32_t rx_runts;
+ uint32_t rx_runt_errs;
+ uint32_t rx_pkts_64;
+ uint32_t rx_pkts_65_127;
+ uint32_t rx_pkts_128_255;
+ uint32_t rx_pkts_256_511;
+ uint32_t rx_pkts_512_1023;
+ uint32_t rx_pkts_1024_1518;
+ uint32_t rx_pkts_1519_max;
+ uint32_t rx_pkts_too_long;
+ uint32_t rx_pkts_jabbers;
+ uint32_t rx_spare2;
+ uint32_t rx_fifo_oflows;
+ uint32_t rx_spare3;
+ /* Tx stats. */
+ uint32_t tx_ucast_frames;
+ uint32_t tx_bcast_frames;
+ uint32_t tx_pause_frames;
+ uint32_t tx_mcast_frames;
+ uint64_t tx_octets;
+ uint32_t tx_pkts_64;
+ uint32_t tx_pkts_65_127;
+ uint32_t tx_pkts_128_255;
+ uint32_t tx_pkts_256_511;
+ uint32_t tx_pkts_512_1023;
+ uint32_t tx_pkts_1024_1518;
+ uint32_t tx_pkts_1519_max;
+ uint32_t tx_spare1;
+ uint32_t tx_colls;
+ uint32_t tx_late_colls;
+ uint32_t tx_excess_colls;
+ uint32_t tx_multi_colls;
+ uint32_t tx_single_colls;
+ uint32_t tx_underflows;
+};
+
/* Softc for the Marvell Yukon II controller. */
struct msk_softc {
struct resource *msk_res[1]; /* I/O resource */
@@ -2352,6 +2385,7 @@ struct msk_if_softc {
int msk_link;
uint32_t msk_flags;
#define MSK_FLAG_RAMBUF 0x0010
+#define MSK_FLAG_NOJUMBO 0x0020
struct callout msk_tick_ch;
int msk_watchdog_timer;
uint32_t msk_txq; /* Tx. Async Queue offset */
@@ -2360,19 +2394,14 @@ struct msk_if_softc {
struct msk_chain_data msk_cdata;
struct msk_ring_data msk_rdata;
struct msk_softc *msk_softc; /* parent controller */
+ struct msk_hw_stats msk_stats;
struct task msk_link_task;
struct task msk_tx_task;
int msk_if_flags;
int msk_detach;
uint16_t msk_vtag; /* VLAN tag id. */
- SLIST_HEAD(__msk_jfreehead, msk_jpool_entry) msk_jfree_listhead;
- SLIST_HEAD(__msk_jinusehead, msk_jpool_entry) msk_jinuse_listhead;
- struct mtx msk_jlist_mtx;
};
-#define MSK_JLIST_LOCK(_sc) mtx_lock(&(_sc)->msk_jlist_mtx)
-#define MSK_JLIST_UNLOCK(_sc) mtx_unlock(&(_sc)->msk_jlist_mtx)
-
#define MSK_TIMEOUT 1000
#define MSK_PHY_POWERUP 1
#define MSK_PHY_POWERDOWN 0
diff --git a/sys/dev/my/if_my.c b/sys/dev/my/if_my.c
index c94f084..65c0dcc 100644
--- a/sys/dev/my/if_my.c
+++ b/sys/dev/my/if_my.c
@@ -127,7 +127,7 @@ static void my_init(void *);
static void my_init_locked(struct my_softc *);
static void my_stop(struct my_softc *);
static void my_watchdog(struct ifnet *);
-static void my_shutdown(device_t);
+static int my_shutdown(device_t);
static int my_ifmedia_upd(struct ifnet *);
static void my_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static u_int16_t my_phy_readreg(struct my_softc *, int);
@@ -1753,7 +1753,7 @@ my_stop(struct my_softc * sc)
* Stop all chip I/O so that the kernel's probe routines don't get confused
* by errant DMAs when rebooting.
*/
-static void
+static int
my_shutdown(device_t dev)
{
struct my_softc *sc;
@@ -1762,5 +1762,5 @@ my_shutdown(device_t dev)
MY_LOCK(sc);
my_stop(sc);
MY_UNLOCK(sc);
- return;
+ return 0;
}
diff --git a/sys/dev/nve/if_nve.c b/sys/dev/nve/if_nve.c
index ee65029..a0746c1 100644
--- a/sys/dev/nve/if_nve.c
+++ b/sys/dev/nve/if_nve.c
@@ -147,7 +147,7 @@ static int nve_ifmedia_upd(struct ifnet *);
static void nve_ifmedia_upd_locked(struct ifnet *);
static void nve_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static int nve_miibus_readreg(device_t, int, int);
-static void nve_miibus_writereg(device_t, int, int, int);
+static int nve_miibus_writereg(device_t, int, int, int);
static void nve_dmamap_cb(void *, bus_dma_segment_t *, int, int);
static void nve_dmamap_tx_cb(void *, bus_dma_segment_t *, int, bus_size_t, int);
@@ -1292,7 +1292,7 @@ nve_miibus_readreg(device_t dev, int phy, int reg)
}
/* miibus Write PHY register wrapper - calls Nvidia API entry point */
-static void
+static int
nve_miibus_writereg(device_t dev, int phy, int reg, int data)
{
struct nve_softc *sc = device_get_softc(dev);
@@ -1303,7 +1303,7 @@ nve_miibus_writereg(device_t dev, int phy, int reg, int data)
DEBUGOUT(NVE_DEBUG_MII, "nve: nve_miibus_writereg - exit\n");
- return;
+ return 0;
}
/* Watchdog timer to prevent PHY lockups */
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index 19de2b97..1cc5207 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -146,18 +146,6 @@ ofw_bus_gen_get_type(device_t bus, device_t dev)
return (obd->obd_type);
}
-static int
-ofw_bus_searchprop(phandle_t node, char *propname, void *buf, int buflen)
-{
- int rv;
-
- for (; node != 0; node = OF_parent(node)) {
- if ((rv = OF_getprop(node, propname, buf, buflen)) != -1)
- return (rv);
- }
- return (-1);
-}
-
void
ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
{
@@ -249,17 +237,16 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
mptr = imap;
i = imapsz;
- tsz = physsz + intrsz + sizeof(phandle_t) + rintrsz;
while (i > 0) {
- KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map"));
bcopy(mptr + physsz + intrsz, &parent, sizeof(parent));
- if (ofw_bus_searchprop(parent, "#interrupt-cells",
+ if (OF_searchprop(parent, "#interrupt-cells",
&pintrsz, sizeof(pintrsz)) == -1)
pintrsz = 1; /* default */
pintrsz *= sizeof(pcell_t);
- if (pintrsz != rintrsz)
- panic("ofw_bus_search_intrmap: expected interrupt cell "
- "size incorrect: %d > %d", rintrsz, pintrsz);
+
+ /* Compute the map stride size */
+ tsz = physsz + intrsz + sizeof(phandle_t) + pintrsz;
+ KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map"));
/*
* XXX: Apple hardware uses a second cell to set information
diff --git a/sys/dev/ofw/ofw_iicbus.c b/sys/dev/ofw/ofw_iicbus.c
new file mode 100644
index 0000000..fc752b6
--- /dev/null
+++ b/sys/dev/ofw/ofw_iicbus.c
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 2009, Nathan Whitehorn <nwhitehorn@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 unmodified, 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/bus.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include "iicbus_if.h"
+
+/* Methods */
+static device_probe_t ofw_iicbus_probe;
+static device_attach_t ofw_iicbus_attach;
+static device_t ofw_iicbus_add_child(device_t dev, int order, const char *name,
+ int unit);
+static const struct ofw_bus_devinfo *ofw_iicbus_get_devinfo(device_t bus,
+ device_t dev);
+
+static device_method_t ofw_iicbus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ofw_iicbus_probe),
+ DEVMETHOD(device_attach, ofw_iicbus_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+ DEVMETHOD(bus_add_child, ofw_iicbus_add_child),
+
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, ofw_iicbus_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
+ { 0, 0 }
+};
+
+struct ofw_iicbus_devinfo {
+ struct iicbus_ivar opd_dinfo;
+ struct ofw_bus_devinfo opd_obdinfo;
+};
+
+static devclass_t ofwiicbus_devclass;
+
+DEFINE_CLASS_1(iicbus, ofw_iicbus_driver, ofw_iicbus_methods,
+ sizeof(struct iicbus_softc), iicbus_driver);
+DRIVER_MODULE(ofw_iicbus, iichb, ofw_iicbus_driver, ofwiicbus_devclass, 0, 0);
+MODULE_VERSION(ofw_iicbus, 1);
+MODULE_DEPEND(ofw_iicbus, iicbus, 1, 1, 1);
+
+static int
+ofw_iicbus_probe(device_t dev)
+{
+
+ if (ofw_bus_get_node(dev) == 0)
+ return (ENXIO);
+ device_set_desc(dev, "OFW I2C bus");
+
+ return (0);
+}
+
+static int
+ofw_iicbus_attach(device_t dev)
+{
+ struct iicbus_softc *sc = IICBUS_SOFTC(dev);
+ struct ofw_iicbus_devinfo *dinfo;
+ phandle_t node, child;
+ device_t childdev;
+ uint32_t addr;
+
+ sc->dev = dev;
+ mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF);
+ iicbus_reset(dev, IIC_FASTEST, 0, NULL);
+
+ bus_generic_probe(dev);
+ bus_enumerate_hinted_children(dev);
+
+ /*
+ * Attach those children represented in the device tree.
+ */
+
+ node = ofw_bus_get_node(dev);
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if (OF_getprop(child, "reg", &addr, sizeof(addr)) == -1)
+ continue;
+
+ /*
+ * Now set up the I2C and OFW bus layer devinfo and add it
+ * to the bus.
+ */
+
+ dinfo = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (dinfo == NULL)
+ continue;
+ dinfo->opd_dinfo.addr = addr;
+ if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
+ 0) {
+ free(dinfo, M_DEVBUF);
+ continue;
+ }
+ childdev = device_add_child(dev, NULL, -1);
+ device_set_ivars(childdev, dinfo);
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+static device_t
+ofw_iicbus_add_child(device_t dev, int order, const char *name, int unit)
+{
+ device_t child;
+ struct ofw_iicbus_devinfo *devi;
+
+ child = device_add_child_ordered(dev, order, name, unit);
+ if (child == NULL)
+ return (child);
+ devi = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (devi == NULL) {
+ device_delete_child(dev, child);
+ return (0);
+ }
+
+ /* NULL all the OFW-related parts of the ivars for non-OFW children */
+
+ devi->opd_obdinfo.obd_node = -1;
+ devi->opd_obdinfo.obd_name = NULL;
+ devi->opd_obdinfo.obd_compat = NULL;
+ devi->opd_obdinfo.obd_type = NULL;
+ devi->opd_obdinfo.obd_model = NULL;
+
+ device_set_ivars(child, devi);
+
+ return (child);
+}
+
+static const struct ofw_bus_devinfo *
+ofw_iicbus_get_devinfo(device_t bus, device_t dev)
+{
+ struct ofw_iicbus_devinfo *dinfo;
+
+ dinfo = device_get_ivars(dev);
+ return (&dinfo->opd_obdinfo);
+}
+
diff --git a/sys/dev/ofw/openfirm.c b/sys/dev/ofw/openfirm.c
index c7b2203..4c33c9f 100644
--- a/sys/dev/ofw/openfirm.c
+++ b/sys/dev/ofw/openfirm.c
@@ -220,6 +220,23 @@ OF_getprop(phandle_t package, const char *propname, void *buf, size_t buflen)
}
/*
+ * Resursively search the node and its parent for the given property, working
+ * downward from the node to the device tree root. Returns the value of the
+ * first match.
+ */
+ssize_t
+OF_searchprop(phandle_t node, char *propname, void *buf, size_t len)
+{
+ ssize_t rv;
+
+ for (; node != 0; node = OF_parent(node)) {
+ if ((rv = OF_getprop(node, propname, buf, len)) != -1)
+ return (rv);
+ }
+ return (-1);
+}
+
+/*
* Store the value of a property of a package into newly allocated memory
* (using the M_OFWPROP malloc pool and M_WAITOK). elsz is the size of a
* single element, the number of elements is return in number.
diff --git a/sys/dev/ofw/openfirm.h b/sys/dev/ofw/openfirm.h
index 08a0544..614c4b2 100644
--- a/sys/dev/ofw/openfirm.h
+++ b/sys/dev/ofw/openfirm.h
@@ -104,6 +104,8 @@ phandle_t OF_parent(phandle_t node);
ssize_t OF_getproplen(phandle_t node, const char *propname);
ssize_t OF_getprop(phandle_t node, const char *propname, void *buf,
size_t len);
+ssize_t OF_searchprop(phandle_t node, char *propname, void *buf,
+ size_t len);
ssize_t OF_getprop_alloc(phandle_t node, const char *propname,
int elsz, void **buf);
int OF_nextprop(phandle_t node, const char *propname, char *buf,
diff --git a/sys/dev/pccard/card_if.m b/sys/dev/pccard/card_if.m
index 3cf814c..43919e3 100644
--- a/sys/dev/pccard/card_if.m
+++ b/sys/dev/pccard/card_if.m
@@ -93,7 +93,7 @@ METHOD int detach_card {
#
# Find "dev" in the passed table of devices. Return it or NULL.
#
-METHOD struct pccard_product * do_product_lookup {
+METHOD const struct pccard_product * do_product_lookup {
device_t bus;
device_t dev;
const struct pccard_product *tab;
diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c
index e6b896b..61b4563 100644
--- a/sys/dev/pccard/pccard.c
+++ b/sys/dev/pccard/pccard.c
@@ -105,14 +105,14 @@ static int pccard_get_resource(device_t dev, device_t child, int type,
static void pccard_delete_resource(device_t dev, device_t child, int type,
int rid);
static int pccard_set_res_flags(device_t dev, device_t child, int type,
- int rid, uint32_t flags);
+ int rid, u_long flags);
static int pccard_set_memory_offset(device_t dev, device_t child, int rid,
uint32_t offset, uint32_t *deltap);
static int pccard_probe_and_attach_child(device_t dev, device_t child,
struct pccard_function *pf);
static void pccard_probe_nomatch(device_t cbdev, device_t child);
static int pccard_read_ivar(device_t bus, device_t child, int which,
- u_char *result);
+ uintptr_t *result);
static void pccard_driver_added(device_t dev, driver_t *driver);
static struct resource *pccard_alloc_resource(device_t dev,
device_t child, int type, int *rid, u_long start,
@@ -173,7 +173,7 @@ pccard_set_default_descr(device_t dev)
if (pccard_get_product(dev, &prod))
return (0);
str = malloc(100, M_DEVBUF, M_WAITOK);
- snprintf(str, 100, "vendor=0x%x product=0x%x", vendor, prod);
+ snprintf(str, 100, "vendor=%#x product=%#x", vendor, prod);
device_set_desc_copy(dev, str);
free(str, M_DEVBUF);
}
@@ -297,8 +297,8 @@ pccard_probe_and_attach_child(device_t dev, device_t child,
if (pccard_function_enable(pf) == 0 &&
pccard_set_default_descr(child) == 0 &&
device_attach(child) == 0) {
- DEVPRINTF((sc->dev, "function %d CCR at %d offset %x mask %x: "
- "%x %x %x %x, %x %x %x %x, %x\n",
+ DEVPRINTF((sc->dev, "function %d CCR at %d offset %#x "
+ "mask %#x: %#x %#x %#x %#x, %#x %#x %#x %#x, %#x\n",
pf->number, pf->pf_ccr_window, pf->pf_ccr_offset,
pf->ccr_mask, pccard_ccr_read(pf, 0x00),
pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04),
@@ -506,7 +506,7 @@ pccard_function_init(struct pccard_function *pf, int entry)
end = start + cfe->iospace[i].length - 1;
else
end = ~0UL;
- DEVPRINTF((bus, "I/O rid %d start %lx end %lx\n",
+ DEVPRINTF((bus, "I/O rid %d start %#lx end %#lx\n",
i, start, end));
rid = i;
len = cfe->iospace[i].length;
@@ -528,7 +528,7 @@ pccard_function_init(struct pccard_function *pf, int entry)
end = start + cfe->memspace[i].length - 1;
else
end = ~0UL;
- DEVPRINTF((bus, "Memory rid %d start %lx end %lx\n",
+ DEVPRINTF((bus, "Memory rid %d start %#lx end %#lx\n",
i, start, end));
rid = i;
len = cfe->memspace[i].length;
@@ -594,7 +594,7 @@ pccard_function_free(struct pccard_function *pf)
device_printf(pf->sc->dev,
"function_free: Resource still owned by "
"child, oops. "
- "(type=%d, rid=%d, addr=%lx)\n",
+ "(type=%d, rid=%d, addr=%#lx)\n",
rle->type, rle->rid,
rman_get_start(rle->res));
BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev),
@@ -689,7 +689,7 @@ pccard_function_enable(struct pccard_function *pf)
&pf->ccr_rid, 0, ~0, PCCARD_MEM_PAGE_SIZE, RF_ACTIVE);
if (!pf->ccr_res)
goto bad;
- DEVPRINTF((dev, "ccr_res == %lx-%lx, base=%x\n",
+ DEVPRINTF((dev, "ccr_res == %#lx-%#lx, base=%#x\n",
rman_get_start(pf->ccr_res), rman_get_end(pf->ccr_res),
pf->ccr_base));
CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
@@ -726,8 +726,8 @@ pccard_function_enable(struct pccard_function *pf)
if (pccard_debug) {
STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) {
device_printf(tmp->sc->dev,
- "function %d CCR at %d offset %x: "
- "%x %x %x %x, %x %x %x %x, %x\n",
+ "function %d CCR at %d offset %#x: "
+ "%#x %#x %#x %#x, %#x %#x %#x %#x, %#x\n",
tmp->number, tmp->pf_ccr_window,
tmp->pf_ccr_offset,
pccard_ccr_read(tmp, 0x00),
@@ -972,7 +972,7 @@ pccard_delete_resource(device_t dev, device_t child, int type, int rid)
static int
pccard_set_res_flags(device_t dev, device_t child, int type, int rid,
- uint32_t flags)
+ u_long flags)
{
return (CARD_SET_RES_FLAGS(device_get_parent(dev), child, type,
rid, flags));
@@ -1055,7 +1055,7 @@ pccard_child_pnpinfo_str(device_t bus, device_t child, char *buf,
}
static int
-pccard_read_ivar(device_t bus, device_t child, int which, u_char *result)
+pccard_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
{
struct pccard_ivar *devi = PCCARD_IVAR(child);
struct pccard_function *pf = devi->pf;
@@ -1185,7 +1185,7 @@ pccard_release_resource(device_t dev, device_t child, int type, int rid,
if (!rle) {
device_printf(dev, "Allocated resource not found, "
- "%d %x %lx %lx\n",
+ "%d %#x %#lx %#lx\n",
type, rid, rman_get_start(r), rman_get_size(r));
return ENOENT;
}
diff --git a/sys/dev/pccard/pccard_cis.c b/sys/dev/pccard/pccard_cis.c
index 4a83d95..605ea17 100644
--- a/sys/dev/pccard/pccard_cis.c
+++ b/sys/dev/pccard/pccard_cis.c
@@ -151,7 +151,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
tuple.memh = rman_get_bushandle(res);
tuple.ptr = 0;
- DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n",
+ DPRINTF(("cis mem map %#x (resource: %#lx)\n",
(unsigned int) tuple.memh, rman_get_start(res)));
tuple.mult = 2;
@@ -230,7 +230,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
longlink_common = (tuple.code ==
CISTPL_LONGLINK_C) ? 1 : 0;
longlink_addr = pccard_tuple_read_4(&tuple, 0);
- DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
+ DPRINTF(("CISTPL_LONGLINK_%s %#lx\n",
longlink_common ? "C" : "A",
longlink_addr));
break;
@@ -264,8 +264,8 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
addr = tuple.ptr + offset;
- DPRINTF(("CISTPL_CHECKSUM addr=%lx "
- "len=%lx cksum=%x",
+ DPRINTF(("CISTPL_CHECKSUM addr=%#lx "
+ "len=%#lx cksum=%#x",
addr, length, cksum));
/*
@@ -286,7 +286,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
tuple.memh,
addr + tuple.mult * i);
if (cksum != (sum & 0xff)) {
- DPRINTF((" failed sum=%x\n",
+ DPRINTF((" failed sum=%#x\n",
sum));
device_printf(dev,
"CIS checksum failed\n");
@@ -361,7 +361,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
mfc[i].addr =
pccard_tuple_read_4(&tuple,
1 + 5 * i + 1);
- DPRINTF((" %s:%lx",
+ DPRINTF((" %s:%#lx",
mfc[i].common ? "common" :
"attr", mfc[i].addr));
}
@@ -386,11 +386,11 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
{
int i;
- DPRINTF((" %02x %02x", tuple.code,
+ DPRINTF((" %#02x %#02x", tuple.code,
tuple.length));
for (i = 0; i < tuple.length; i++) {
- DPRINTF((" %02x",
+ DPRINTF((" %#02x",
pccard_tuple_read_1(&tuple, i)));
if ((i % 16) == 13)
DPRINTF(("\n"));
@@ -416,7 +416,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY,
rid, longlink_common ?
PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
- DPRINTF(("cis mem map %x\n",
+ DPRINTF(("cis mem map %#x\n",
(unsigned int) tuple.memh));
tuple.mult = longlink_common ? 1 : 2;
tuple.ptr = longlink_addr;
@@ -427,7 +427,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY,
rid, mfc[mfc_index].common ?
PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
- DPRINTF(("cis mem map %x\n",
+ DPRINTF(("cis mem map %#x\n",
(unsigned int) tuple.memh));
/* set parse state, and point at the next one */
tuple.mult = mfc[mfc_index].common ? 1 : 2;
@@ -441,7 +441,7 @@ pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
if (tuple.code != CISTPL_LINKTARGET) {
DPRINTF(("CISTPL_LINKTARGET expected, "
- "code %02x observed\n", tuple.code));
+ "code %#02x observed\n", tuple.code));
continue;
}
tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
@@ -504,7 +504,7 @@ pccard_print_cis(device_t dev)
}
printf("\n");
- device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
+ device_printf(dev, "Manufacturer code %#x, product %#x\n",
card->manufacturer, card->product);
STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
@@ -552,7 +552,7 @@ pccard_print_cis(device_t dev)
break;
}
- printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask);
+ printf(", ccr addr %#x mask %#x\n", pf->ccr_base, pf->ccr_mask);
STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
device_printf(dev, "function %d, config table entry "
@@ -570,15 +570,15 @@ pccard_print_cis(device_t dev)
break;
}
- printf("; irq mask %x", cfe->irqmask);
+ printf("; irq mask %#x", cfe->irqmask);
if (cfe->num_iospace) {
- printf("; iomask %lx, iospace", cfe->iomask);
+ printf("; iomask %#lx, iospace", cfe->iomask);
for (i = 0; i < cfe->num_iospace; i++) {
- printf(" %lx", cfe->iospace[i].start);
+ printf(" %#lx", cfe->iospace[i].start);
if (cfe->iospace[i].length)
- printf("-%lx",
+ printf("-%#lx",
cfe->iospace[i].start +
cfe->iospace[i].length - 1);
}
@@ -587,14 +587,14 @@ pccard_print_cis(device_t dev)
printf("; memspace");
for (i = 0; i < cfe->num_memspace; i++) {
- printf(" %lx",
+ printf(" %#lx",
cfe->memspace[i].cardaddr);
if (cfe->memspace[i].length)
- printf("-%lx",
+ printf("-%#lx",
cfe->memspace[i].cardaddr +
cfe->memspace[i].length - 1);
if (cfe->memspace[i].hostaddr)
- printf("@%lx",
+ printf("@%#lx",
cfe->memspace[i].hostaddr);
}
}
@@ -1264,7 +1264,7 @@ pccard_parse_cis_tuple(const struct pccard_tuple *tuple, void *arg)
DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
break;
default:
- DPRINTF(("unhandled CISTPL %x\n", tuple->code));
+ DPRINTF(("unhandled CISTPL %#x\n", tuple->code));
break;
}
@@ -1283,6 +1283,8 @@ decode_funce(const struct pccard_tuple *tuple, struct pccard_function *pf)
if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
pf->pf_funce_disk_interface
= pccard_tuple_read_1(tuple, 1);
+ pf->pf_funce_disk_power
+ = pccard_tuple_read_1(tuple, 2);
}
break;
case PCCARD_FUNCTION_NETWORK:
diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h
index 82d4025..ddd5609 100644
--- a/sys/dev/pccard/pccardvar.h
+++ b/sys/dev/pccard/pccardvar.h
@@ -69,6 +69,10 @@ struct pccard_mem_handle {
int kind;
};
+/* Bits for kind */
+#define PCCARD_MEM_16BIT 1 /* 1 -> 16bit 0 -> 8bit */
+#define PCCARD_MEM_ATTR 2 /* 1 -> attribute mem 0 -> common */
+
#define PCCARD_WIDTH_AUTO 0
#define PCCARD_WIDTH_IO8 1
#define PCCARD_WIDTH_IO16 2
diff --git a/sys/dev/pccard/pccardvarp.h b/sys/dev/pccard/pccardvarp.h
index e418730..576238b 100644
--- a/sys/dev/pccard/pccardvarp.h
+++ b/sys/dev/pccard/pccardvarp.h
@@ -75,7 +75,23 @@ struct pccard_config_entry {
};
struct pccard_funce_disk {
- int pfd_interface;
+ uint8_t pfd_interface;
+#define PFD_I_V_MASK 0x3
+#define PFD_I_V_NONE_REQUIRED 0x0
+#define PFD_I_V_REQ_MOD_ACC 0x1
+#define PFD_I_V_REQ_ACC 0x2
+#define PFD_I_V_REQ_ALWYS 0x1
+#define PFD_I_S 0x4 /* 0 rotating, 1 silicon */
+#define PFD_I_U 0x8 /* SN Uniq? */
+#define PFD_I_D 0x10 /* 0 - 1 drive, 1 - 2 drives */
+ uint8_t pfd_power;
+#define PFD_P_P0 0x1
+#define PFD_P_P1 0x2
+#define PFD_P_P2 0x4
+#define PFD_P_P3 0x8
+#define PFD_P_N 0x10 /* 3f7/377 excluded? */
+#define PFD_P_E 0x20 /* Index bit supported? */
+#define PFD_P_I 0x40 /* twincard */
};
struct pccard_funce_lan {
@@ -119,6 +135,7 @@ struct pccard_function {
union pccard_funce pf_funce; /* CISTPL_FUNCE */
#define pf_funce_disk_interface pf_funce.pfv_disk.pfd_interface
+#define pf_funce_disk_power pf_funce.pfv_disk.pfd_power
#define pf_funce_lan_nid pf_funce.pfv_lan.pfl_nid
#define pf_funce_lan_nidlen pf_funce.pfv_lan.pfl_nidlen
};
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c
index 7991e32..861352e 100644
--- a/sys/dev/pccbb/pccbb.c
+++ b/sys/dev/pccbb/pccbb.c
@@ -175,7 +175,7 @@ static int cbb_cardbus_release_resource(device_t brdev, device_t child,
int type, int rid, struct resource *res);
static int cbb_cardbus_power_enable_socket(device_t brdev,
device_t child);
-static void cbb_cardbus_power_disable_socket(device_t brdev,
+static int cbb_cardbus_power_disable_socket(device_t brdev,
device_t child);
static int cbb_func_filt(void *arg);
static void cbb_func_intr(void *arg);
@@ -998,11 +998,12 @@ cbb_cardbus_power_enable_socket(device_t brdev, device_t child)
return (0);
}
-static void
+static int
cbb_cardbus_power_disable_socket(device_t brdev, device_t child)
{
cbb_power(brdev, CARD_OFF);
cbb_cardbus_reset(brdev, child, 0);
+ return (0);
}
/************************************************************************/
@@ -1262,7 +1263,7 @@ cbb_pcic_power_enable_socket(device_t brdev, device_t child)
return (0);
}
-static void
+static int
cbb_pcic_power_disable_socket(device_t brdev, device_t child)
{
struct cbb_softc *sc = device_get_softc(brdev);
@@ -1282,6 +1283,7 @@ cbb_pcic_power_disable_socket(device_t brdev, device_t child)
/* enable CSC interrupts */
exca_putb(&sc->exca[0], EXCA_INTR, EXCA_INTR_ENABLE);
+ return (0);
}
/************************************************************************/
@@ -1295,18 +1297,16 @@ cbb_power_enable_socket(device_t brdev, device_t child)
if (sc->flags & CBB_16BIT_CARD)
return (cbb_pcic_power_enable_socket(brdev, child));
- else
- return (cbb_cardbus_power_enable_socket(brdev, child));
+ return (cbb_cardbus_power_enable_socket(brdev, child));
}
-void
+int
cbb_power_disable_socket(device_t brdev, device_t child)
{
struct cbb_softc *sc = device_get_softc(brdev);
if (sc->flags & CBB_16BIT_CARD)
- cbb_pcic_power_disable_socket(brdev, child);
- else
- cbb_cardbus_power_disable_socket(brdev, child);
+ return (cbb_pcic_power_disable_socket(brdev, child));
+ return (cbb_cardbus_power_disable_socket(brdev, child));
}
static int
@@ -1404,7 +1404,7 @@ cbb_pcic_release_resource(device_t brdev, device_t child, int type,
int
cbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid,
- uint32_t flags)
+ u_long flags)
{
struct cbb_softc *sc = device_get_softc(brdev);
struct resource *res;
@@ -1579,9 +1579,9 @@ cbb_resume(device_t self)
}
int
-cbb_child_present(device_t self)
+cbb_child_present(device_t parent, device_t child)
{
- struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(self);
+ struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(parent);
uint32_t sockstate;
sockstate = cbb_get(sc, CBB_SOCKET_STATE);
diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c
index 86e52b2..b8582b7 100644
--- a/sys/dev/pccbb/pccbb_pci.c
+++ b/sys/dev/pccbb/pccbb_pci.c
@@ -785,20 +785,17 @@ cbb_maxslots(device_t brdev)
}
static uint32_t
-cbb_read_config(device_t brdev, int b, int s, int f, int reg, int width)
+cbb_read_config(device_t brdev, u_int b, u_int s, u_int f, u_int reg, int width)
{
- uint32_t rv;
-
/*
* Pass through to the next ppb up the chain (i.e. our grandparent).
*/
- rv = PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)),
- b, s, f, reg, width);
- return (rv);
+ return (PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)),
+ b, s, f, reg, width));
}
static void
-cbb_write_config(device_t brdev, int b, int s, int f, int reg, uint32_t val,
+cbb_write_config(device_t brdev, u_int b, u_int s, u_int f, u_int reg, uint32_t val,
int width)
{
/*
diff --git a/sys/dev/pccbb/pccbbvar.h b/sys/dev/pccbb/pccbbvar.h
index a7b6aa6..a38e82e 100644
--- a/sys/dev/pccbb/pccbbvar.h
+++ b/sys/dev/pccbb/pccbbvar.h
@@ -116,7 +116,7 @@ struct resource *cbb_alloc_resource(device_t brdev, device_t child,
int type, int *rid, u_long start, u_long end, u_long count,
u_int flags);
void cbb_child_detached(device_t brdev, device_t child);
-int cbb_child_present(device_t self);
+int cbb_child_present(device_t parent, device_t child);
int cbb_deactivate_resource(device_t brdev, device_t child,
int type, int rid, struct resource *r);
int cbb_detach(device_t brdev);
@@ -126,10 +126,10 @@ void cbb_event_thread(void *arg);
int cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
uint32_t cardaddr, uint32_t *deltap);
int cbb_pcic_set_res_flags(device_t brdev, device_t child, int type,
- int rid, uint32_t flags);
+ int rid, u_long flags);
int cbb_power(device_t brdev, int volts);
int cbb_power_enable_socket(device_t brdev, device_t child);
-void cbb_power_disable_socket(device_t brdev, device_t child);
+int cbb_power_disable_socket(device_t brdev, device_t child);
int cbb_read_ivar(device_t brdev, device_t child, int which,
uintptr_t *result);
int cbb_release_resource(device_t brdev, device_t child,
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 295e68d..633c4d5 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -2291,9 +2291,27 @@ pci_add_map(device_t pcib, device_t bus, device_t dev,
struct resource *res;
map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
+
+ /*
+ * Disable decoding via the command register before
+ * determining the BARs length since we will be placing them
+ * in a weird state.
+ */
+ cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
+ PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND,
+ cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2);
+
+ /*
+ * Determine the BAR's length by writing all 1's. The bottom
+ * log_2(size) bits of the BAR will stick as 0 when we read
+ * the value back.
+ */
PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4);
testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
+
+ /* Restore the BAR and command register. */
PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4);
+ PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
if (PCI_BAR_MEM(map))
type = SYS_RES_MEMORY;
@@ -2626,7 +2644,7 @@ pci_probe(device_t dev)
device_set_desc(dev, "PCI bus");
/* Allow other subclasses to override this driver. */
- return (-1000);
+ return (BUS_PROBE_GENERIC);
}
static int
diff --git a/sys/dev/pci/pci_user.c b/sys/dev/pci/pci_user.c
index b7ae55a..ed75353 100644
--- a/sys/dev/pci/pci_user.c
+++ b/sys/dev/pci/pci_user.c
@@ -307,7 +307,10 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
struct pci_conf_io *cio;
struct pci_devinfo *dinfo;
struct pci_io *io;
+ struct pci_bar_io *bio;
struct pci_match_conf *pattern_buf;
+ struct resource_list_entry *rle;
+ uint32_t value;
size_t confsz, iolen, pbufsz;
int error, ionum, i, num_patterns;
#ifdef PRE7_COMPAT
@@ -319,11 +322,11 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
io_old = NULL;
pattern_buf_old = NULL;
- if (!(flag & FWRITE) &&
- (cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD))
+ if (!(flag & FWRITE) && cmd != PCIOCGETBAR &&
+ cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD)
return EPERM;
#else
- if (!(flag & FWRITE) && cmd != PCIOCGETCONF)
+ if (!(flag & FWRITE) && cmd != PCIOCGETBAR && cmd != PCIOCGETCONF)
return EPERM;
#endif
@@ -669,6 +672,70 @@ getconfexit:
}
break;
+ case PCIOCGETBAR:
+ bio = (struct pci_bar_io *)data;
+
+ /*
+ * Assume that the user-level bus number is
+ * in fact the physical PCI bus number.
+ */
+ pcidev = pci_find_dbsf(bio->pbi_sel.pc_domain,
+ bio->pbi_sel.pc_bus, bio->pbi_sel.pc_dev,
+ bio->pbi_sel.pc_func);
+ if (pcidev == NULL) {
+ error = ENODEV;
+ break;
+ }
+ dinfo = device_get_ivars(pcidev);
+
+ /*
+ * Look for a resource list entry matching the requested BAR.
+ *
+ * XXX: This will not find BARs that are not initialized, but
+ * maybe that is ok?
+ */
+ rle = resource_list_find(&dinfo->resources, SYS_RES_MEMORY,
+ bio->pbi_reg);
+ if (rle == NULL)
+ rle = resource_list_find(&dinfo->resources,
+ SYS_RES_IOPORT, bio->pbi_reg);
+ if (rle == NULL || rle->res == NULL) {
+ error = EINVAL;
+ break;
+ }
+
+ /*
+ * Ok, we have a resource for this BAR. Read the lower
+ * 32 bits to get any flags.
+ */
+ value = pci_read_config(pcidev, bio->pbi_reg, 4);
+ if (PCI_BAR_MEM(value)) {
+ if (rle->type != SYS_RES_MEMORY) {
+ error = EINVAL;
+ break;
+ }
+ value &= ~PCIM_BAR_MEM_BASE;
+ } else {
+ if (rle->type != SYS_RES_IOPORT) {
+ error = EINVAL;
+ break;
+ }
+ value &= ~PCIM_BAR_IO_BASE;
+ }
+ bio->pbi_base = rman_get_start(rle->res) | value;
+ bio->pbi_length = rman_get_size(rle->res);
+
+ /*
+ * Check the command register to determine if this BAR
+ * is enabled.
+ */
+ value = pci_read_config(pcidev, PCIR_COMMAND, 2);
+ if (rle->type == SYS_RES_MEMORY)
+ bio->pbi_enabled = (value & PCIM_CMD_MEMEN) != 0;
+ else
+ bio->pbi_enabled = (value & PCIM_CMD_PORTEN) != 0;
+ error = 0;
+ break;
default:
error = ENOTTY;
break;
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index e9ba5e7..0b69ca4 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -117,7 +117,7 @@
#define PCIR_BARS 0x10
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
-#define PCI_MAX_BAR_0 5 /* Number of standard bars */
+#define PCIR_MAX_BAR_0 5
#define PCI_RID2BAR(rid) (((rid) - PCIR_BARS) / 4)
#define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE)
#define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE)
@@ -158,6 +158,7 @@
/* config registers for header type 1 (PCI-to-PCI bridge) devices */
+#define PCIR_MAX_BAR_1 1
#define PCIR_SECSTAT_1 0x1e
#define PCIR_PRIBUS_1 0x18
@@ -188,6 +189,7 @@
/* config registers for header type 2 (CardBus) devices */
+#define PCIR_MAX_BAR_2 0
#define PCIR_CAP_PTR_2 0x14
#define PCIR_SECSTAT_2 0x16
diff --git a/sys/dev/pcn/if_pcn.c b/sys/dev/pcn/if_pcn.c
index eccbda0..f863cfc 100644
--- a/sys/dev/pcn/if_pcn.c
+++ b/sys/dev/pcn/if_pcn.c
@@ -144,7 +144,7 @@ static void pcn_init(void *);
static void pcn_init_locked(struct pcn_softc *);
static void pcn_stop(struct pcn_softc *);
static void pcn_watchdog(struct ifnet *);
-static void pcn_shutdown(device_t);
+static int pcn_shutdown(device_t);
static int pcn_ifmedia_upd(struct ifnet *);
static void pcn_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -1446,7 +1446,7 @@ pcn_watchdog(ifp)
pcn_init_locked(sc);
if (ifp->if_snd.ifq_head != NULL)
- pcn_start(ifp);
+ pcn_start_locked(ifp);
PCN_UNLOCK(sc);
@@ -1458,8 +1458,7 @@ pcn_watchdog(ifp)
* RX and TX lists.
*/
static void
-pcn_stop(sc)
- struct pcn_softc *sc;
+pcn_stop(struct pcn_softc *sc)
{
register int i;
struct ifnet *ifp;
@@ -1510,9 +1509,8 @@ pcn_stop(sc)
* Stop all chip I/O so that the kernel's probe routines don't
* get confused by errant DMAs when rebooting.
*/
-static void
-pcn_shutdown(dev)
- device_t dev;
+static int
+pcn_shutdown(device_t dev)
{
struct pcn_softc *sc;
@@ -1523,5 +1521,5 @@ pcn_shutdown(dev)
pcn_stop(sc);
PCN_UNLOCK(sc);
- return;
+ return 0;
}
diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c
index 5d6417f..3ff11df 100644
--- a/sys/dev/ppbus/if_plip.c
+++ b/sys/dev/ppbus/if_plip.c
@@ -152,8 +152,12 @@ struct lp_data {
int sc_iferrs;
struct resource *res_irq;
+ void *sc_intr_cookie;
};
+static struct mtx lp_tables_lock;
+MTX_SYSINIT(lp_tables, &lp_tables_lock, "plip tables", MTX_DEF);
+
/* Tables for the lp# interface */
static u_char *txmith;
#define txmitl (txmith + (1 * LPIPTBLSIZE))
@@ -170,13 +174,41 @@ static int lpinittables(void);
static int lpioctl(struct ifnet *, u_long, caddr_t);
static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
+static void lpstop(struct lp_data *);
static void lp_intr(void *);
+static int lp_module_handler(module_t, int, void *);
#define DEVTOSOFTC(dev) \
((struct lp_data *)device_get_softc(dev))
static devclass_t lp_devclass;
+static int
+lp_module_handler(module_t mod, int what, void *arg)
+{
+
+ switch (what) {
+ case MOD_UNLOAD:
+ mtx_lock(&lp_tables_lock);
+ if (txmith != NULL) {
+ free(txmith, M_DEVBUF);
+ txmith = NULL;
+ }
+ if (ctxmith != NULL) {
+ free(ctxmith, M_DEVBUF);
+ ctxmith = NULL;
+ }
+ mtx_unlock(&lp_tables_lock);
+ break;
+ case MOD_LOAD:
+ case MOD_QUIESCE:
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+ return (0);
+}
+
static void
lp_identify(driver_t *driver, device_t parent)
{
@@ -201,7 +233,7 @@ lp_attach(device_t dev)
{
struct lp_data *lp = DEVTOSOFTC(dev);
struct ifnet *ifp;
- int rid = 0;
+ int error, rid = 0;
lp->sc_dev = dev;
@@ -224,8 +256,7 @@ lp_attach(device_t dev)
ifp->if_softc = lp;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = LPMTU;
- ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST |
- IFF_NEEDSGIANT;
+ ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
ifp->if_ioctl = lpioctl;
ifp->if_output = lpoutput;
ifp->if_hdrlen = 0;
@@ -235,8 +266,39 @@ lp_attach(device_t dev)
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
+ /*
+ * Attach our interrupt handler. It is only called while we
+ * own the ppbus.
+ */
+ error = bus_setup_intr(dev, lp->res_irq, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, lp_intr, lp, &lp->sc_intr_cookie);
+ if (error) {
+ bpfdetach(ifp);
+ if_detach(ifp);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, lp->res_irq);
+ device_printf(dev, "Unable to register interrupt handler\n");
+ return (error);
+ }
+
return (0);
}
+
+static int
+lp_detach(device_t dev)
+{
+ struct lp_data *sc = device_get_softc(dev);
+ device_t ppbus = device_get_parent(dev);
+
+ ppb_lock(ppbus);
+ lpstop(sc);
+ ppb_unlock(ppbus);
+ bpfdetach(sc->sc_ifp);
+ if_detach(sc->sc_ifp);
+ bus_teardown_intr(dev, sc->res_irq, sc->sc_intr_cookie);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->res_irq);
+ return (0);
+}
+
/*
* Build the translation tables for the LPIP (BSD unix) protocol.
* We don't want to calculate these nasties in our tight loop, so we
@@ -247,17 +309,22 @@ lpinittables(void)
{
int i;
+ mtx_lock(&lp_tables_lock);
if (txmith == NULL)
txmith = malloc(4 * LPIPTBLSIZE, M_DEVBUF, M_NOWAIT);
- if (txmith == NULL)
+ if (txmith == NULL) {
+ mtx_unlock(&lp_tables_lock);
return (1);
+ }
if (ctxmith == NULL)
ctxmith = malloc(4 * LPIPTBLSIZE, M_DEVBUF, M_NOWAIT);
- if (ctxmith == NULL)
+ if (ctxmith == NULL) {
+ mtx_unlock(&lp_tables_lock);
return (1);
+ }
for (i = 0; i < LPIPTBLSIZE; i++) {
ctxmith[i] = (i & 0xF0) >> 4;
@@ -272,10 +339,61 @@ lpinittables(void)
trecvh[i] = ((~i) & 0x80) | ((i & 0x38) << 1);
trecvl[i] = (((~i) & 0x80) >> 4) | ((i & 0x38) >> 3);
}
+ mtx_unlock(&lp_tables_lock);
return (0);
}
+static void
+lpstop(struct lp_data *sc)
+{
+ device_t ppbus = device_get_parent(sc->sc_dev);
+
+ ppb_assert_locked(ppbus);
+ ppb_wctr(ppbus, 0x00);
+ sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ free(sc->sc_ifbuf, M_DEVBUF);
+ sc->sc_ifbuf = NULL;
+
+ /* IFF_UP is not set, try to release the bus anyway */
+ ppb_release_bus(ppbus, sc->sc_dev);
+}
+
+static int
+lpinit_locked(struct ifnet *ifp)
+{
+ struct lp_data *sc = ifp->if_softc;
+ device_t dev = sc->sc_dev;
+ device_t ppbus = device_get_parent(dev);
+ int error;
+
+ ppb_assert_locked(ppbus);
+ error = ppb_request_bus(ppbus, dev, PPB_DONTWAIT);
+ if (error)
+ return (error);
+
+ /* Now IFF_UP means that we own the bus */
+ ppb_set_mode(ppbus, PPB_COMPATIBLE);
+
+ if (lpinittables()) {
+ ppb_release_bus(ppbus, dev);
+ return (ENOBUFS);
+ }
+
+ sc->sc_ifbuf = malloc(sc->sc_ifp->if_mtu + MLPIPHDRLEN,
+ M_DEVBUF, M_NOWAIT);
+ if (sc->sc_ifbuf == NULL) {
+ ppb_release_bus(ppbus, dev);
+ return (ENOBUFS);
+ }
+
+ ppb_wctr(ppbus, IRQENABLE);
+
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ return (0);
+}
+
/*
* Process an ioctl request.
*/
@@ -288,7 +406,6 @@ lpioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ifaddr *ifa = (struct ifaddr *)data;
struct ifreq *ifr = (struct ifreq *)data;
u_char *ptr;
- void *ih;
int error;
switch (cmd) {
@@ -301,67 +418,32 @@ lpioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_flags |= IFF_UP;
/* FALLTHROUGH */
case SIOCSIFFLAGS:
+ error = 0;
+ ppb_lock(ppbus);
if ((!(ifp->if_flags & IFF_UP)) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-
- ppb_wctr(ppbus, 0x00);
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-
- /* IFF_UP is not set, try to release the bus anyway */
- ppb_release_bus(ppbus, dev);
- break;
- }
- if (((ifp->if_flags & IFF_UP)) &&
- (!(ifp->if_drv_flags & IFF_DRV_RUNNING))) {
+ (ifp->if_drv_flags & IFF_DRV_RUNNING))
+ lpstop(sc);
+ else if (((ifp->if_flags & IFF_UP)) &&
+ (!(ifp->if_drv_flags & IFF_DRV_RUNNING)))
+ error = lpinit_locked(ifp);
+ ppb_unlock(ppbus);
+ return (error);
- /* XXX
- * Should the request be interruptible?
- */
- if ((error = ppb_request_bus(ppbus, dev, PPB_WAIT |
- PPB_INTR)))
- return (error);
-
- /* Now IFF_UP means that we own the bus */
- ppb_set_mode(ppbus, PPB_COMPATIBLE);
-
- if (lpinittables()) {
- ppb_release_bus(ppbus, dev);
- return (ENOBUFS);
- }
-
- sc->sc_ifbuf = malloc(sc->sc_ifp->if_mtu + MLPIPHDRLEN,
- M_DEVBUF, M_WAITOK);
- if (sc->sc_ifbuf == NULL) {
- ppb_release_bus(ppbus, dev);
+ case SIOCSIFMTU:
+ ppb_lock(ppbus);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ ptr = malloc(ifr->ifr_mtu + MLPIPHDRLEN, M_DEVBUF,
+ M_NOWAIT);
+ if (ptr == NULL) {
+ ppb_unlock(ppbus);
return (ENOBUFS);
}
-
- /*
- * Attach our interrupt handler. It is
- * detached later when the bus is released.
- */
- if ((error = bus_setup_intr(dev, sc->res_irq,
- INTR_TYPE_NET, NULL, lp_intr, dev, &ih))) {
- ppb_release_bus(ppbus, dev);
- return (error);
- }
-
- ppb_wctr(ppbus, IRQENABLE);
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- }
- break;
-
- case SIOCSIFMTU:
- ptr = sc->sc_ifbuf;
- sc->sc_ifbuf = malloc(ifr->ifr_mtu + MLPIPHDRLEN, M_DEVBUF,
- M_NOWAIT);
- if (sc->sc_ifbuf == NULL) {
+ if (sc->sc_ifbuf)
+ free(sc->sc_ifbuf, M_DEVBUF);
sc->sc_ifbuf = ptr;
- return (ENOBUFS);
}
- if (ptr)
- free(ptr, M_DEVBUF);
sc->sc_ifp->if_mtu = ifr->ifr_mtu;
+ ppb_unlock(ppbus);
break;
case SIOCGIFMTU:
@@ -417,14 +499,14 @@ clpinbyte(int spin, device_t ppbus)
{
u_char c, cl;
- while((ppb_rstr(ppbus) & CLPIP_SHAKE))
+ while ((ppb_rstr(ppbus) & CLPIP_SHAKE))
if (!--spin) {
return (-1);
}
cl = ppb_rstr(ppbus);
ppb_wdtr(ppbus, 0x10);
- while(!(ppb_rstr(ppbus) & CLPIP_SHAKE))
+ while (!(ppb_rstr(ppbus) & CLPIP_SHAKE))
if (!--spin) {
return (-1);
}
@@ -445,16 +527,14 @@ lptap(struct ifnet *ifp, struct mbuf *m)
static void
lp_intr(void *arg)
{
- device_t dev = (device_t)arg;
- device_t ppbus = device_get_parent(dev);
- struct lp_data *sc = DEVTOSOFTC(dev);
- int len, s, j;
+ struct lp_data *sc = arg;
+ device_t ppbus = device_get_parent(sc->sc_dev);
+ int len, j;
u_char *bp;
u_char c, cl;
struct mbuf *top;
- s = splhigh();
-
+ ppb_assert_locked(ppbus);
if (sc->sc_ifp->if_flags & IFF_LINK0) {
/* Ack. the request */
@@ -500,13 +580,15 @@ lp_intr(void *arg)
top = m_devget(sc->sc_ifbuf + CLPIPHDRLEN, len, 0, sc->sc_ifp,
0);
if (top) {
+ ppb_unlock(ppbus);
if (bpf_peers_present(sc->sc_ifp->if_bpf))
lptap(sc->sc_ifp, top);
/* mbuf is free'd on failure. */
netisr_queue(NETISR_IP, top);
+ ppb_lock(ppbus);
}
- goto done;
+ return;
}
while ((ppb_rstr(ppbus) & LPIP_SHAKE)) {
len = sc->sc_ifp->if_mtu + LPIPHDRLEN;
@@ -517,7 +599,7 @@ lp_intr(void *arg)
ppb_wdtr(ppbus, 8);
j = LPMAXSPIN2;
- while((ppb_rstr(ppbus) & LPIP_SHAKE))
+ while ((ppb_rstr(ppbus) & LPIP_SHAKE))
if (!--j)
goto err;
@@ -550,14 +632,16 @@ lp_intr(void *arg)
top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, sc->sc_ifp,
0);
if (top) {
+ ppb_unlock(ppbus);
if (bpf_peers_present(sc->sc_ifp->if_bpf))
lptap(sc->sc_ifp, top);
/* mbuf is free'd on failure. */
netisr_queue(NETISR_IP, top);
+ ppb_lock(ppbus);
}
}
- goto done;
+ return;
err:
ppb_wdtr(ppbus, 0);
@@ -575,9 +659,6 @@ err:
sc->sc_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
sc->sc_iferrs = 0;
}
-
-done:
- splx(s);
}
static __inline int
@@ -602,7 +683,7 @@ lpoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct lp_data *sc = ifp->if_softc;
device_t dev = sc->sc_dev;
device_t ppbus = device_get_parent(dev);
- int s, err;
+ int err;
struct mbuf *mm;
u_char *cp = "\0\0";
u_char chksum = 0;
@@ -611,19 +692,18 @@ lpoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
/* We need a sensible value if we abort */
cp++;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ppb_lock(ppbus);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
err = 1; /* assume we're aborting because of an error */
- s = splhigh();
-
/* Suspend (on laptops) or receive-errors might have taken us offline */
ppb_wctr(ppbus, IRQENABLE);
if (ifp->if_flags & IFF_LINK0) {
if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) {
lprintf("&");
- lp_intr(dev);
+ lp_intr(sc);
}
/* Alert other end to pending packet */
@@ -681,6 +761,7 @@ lpoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
err = 0; /* No errors */
nend:
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
if (err) { /* if we didn't timeout... */
ifp->if_oerrors++;
lprintf("X");
@@ -695,15 +776,15 @@ lpoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) {
lprintf("^");
- lp_intr(dev);
+ lp_intr(sc);
}
- (void) splx(s);
+ ppb_unlock(ppbus);
return (0);
}
if (ppb_rstr(ppbus) & LPIP_SHAKE) {
lprintf("&");
- lp_intr(dev);
+ lp_intr(sc);
}
if (lpoutbyte(0x08, LPMAXSPIN1, ppbus))
@@ -726,6 +807,7 @@ end:
--cp;
ppb_wdtr(ppbus, txmitl[*cp] ^ 0x17);
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
if (err) { /* if we didn't timeout... */
ifp->if_oerrors++;
lprintf("X");
@@ -740,10 +822,10 @@ end:
if (ppb_rstr(ppbus) & LPIP_SHAKE) {
lprintf("^");
- lp_intr(dev);
+ lp_intr(sc);
}
- (void) splx(s);
+ ppb_unlock(ppbus);
return (0);
}
@@ -752,6 +834,7 @@ static device_method_t lp_methods[] = {
DEVMETHOD(device_identify, lp_identify),
DEVMETHOD(device_probe, lp_probe),
DEVMETHOD(device_attach, lp_attach),
+ DEVMETHOD(device_detach, lp_detach),
{ 0, 0 }
};
@@ -762,5 +845,5 @@ static driver_t lp_driver = {
sizeof(struct lp_data),
};
-DRIVER_MODULE(plip, ppbus, lp_driver, lp_devclass, 0, 0);
+DRIVER_MODULE(plip, ppbus, lp_driver, lp_devclass, lp_module_handler, 0);
MODULE_DEPEND(plip, ppbus, 1, 1, 1);
diff --git a/sys/dev/ppbus/immio.c b/sys/dev/ppbus/immio.c
index bd0c0c9..8b0c8de 100644
--- a/sys/dev/ppbus/immio.c
+++ b/sys/dev/ppbus/immio.c
@@ -606,6 +606,7 @@ imm_attach(struct vpoio_data *vpo)
/*
* Initialize mode dependent in/out microsequences
*/
+ ppb_lock(ppbus);
if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT)))
goto error;
@@ -632,6 +633,7 @@ imm_attach(struct vpoio_data *vpo)
ppb_release_bus(ppbus, vpo->vpo_dev);
error:
+ ppb_unlock(ppbus);
return (error);
}
diff --git a/sys/dev/ppbus/lpbb.c b/sys/dev/ppbus/lpbb.c
index 87ce6c7..872db24 100644
--- a/sys/dev/ppbus/lpbb.c
+++ b/sys/dev/ppbus/lpbb.c
@@ -103,16 +103,16 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
case IIC_REQUEST_BUS:
/* request the ppbus */
how = *(int *)data;
- mtx_lock(&Giant);
+ ppb_lock(ppbus);
error = ppb_request_bus(ppbus, dev, how);
- mtx_unlock(&Giant);
+ ppb_unlock(ppbus);
break;
case IIC_RELEASE_BUS:
/* release the ppbus */
- mtx_lock(&Giant);
+ ppb_lock(ppbus);
error = ppb_release_bus(ppbus, dev);
- mtx_unlock(&Giant);
+ ppb_unlock(ppbus);
break;
default:
@@ -129,25 +129,38 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
#define ALIM 0x20
#define I2CKEY 0x50
+/* Reset bus by setting SDA first and then SCL. */
+static void
+lpbb_reset_bus(device_t dev)
+{
+ device_t ppbus = device_get_parent(dev);
+
+ ppb_assert_locked(ppbus);
+ ppb_wdtr(ppbus, (u_char)~SDA_out);
+ ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) | SCL_out));
+}
+
static int
lpbb_getscl(device_t dev)
{
+ device_t ppbus = device_get_parent(dev);
int rval;
- mtx_lock(&Giant);
- rval = ((ppb_rstr(device_get_parent(dev)) & SCL_in) == SCL_in);
- mtx_unlock(&Giant);
+ ppb_lock(ppbus);
+ rval = ((ppb_rstr(ppbus) & SCL_in) == SCL_in);
+ ppb_unlock(ppbus);
return (rval);
}
static int
lpbb_getsda(device_t dev)
{
+ device_t ppbus = device_get_parent(dev);
int rval;
- mtx_lock(&Giant);
- rval = ((ppb_rstr(device_get_parent(dev)) & SDA_in) == SDA_in);
- mtx_unlock(&Giant);
+ ppb_lock(ppbus);
+ rval = ((ppb_rstr(ppbus) & SDA_in) == SDA_in);
+ ppb_unlock(ppbus);
return (rval);
}
@@ -156,12 +169,12 @@ lpbb_setsda(device_t dev, char val)
{
device_t ppbus = device_get_parent(dev);
- mtx_lock(&Giant);
+ ppb_lock(ppbus);
if (val == 0)
ppb_wdtr(ppbus, (u_char)SDA_out);
else
ppb_wdtr(ppbus, (u_char)~SDA_out);
- mtx_unlock(&Giant);
+ ppb_unlock(ppbus);
}
static void
@@ -169,12 +182,12 @@ lpbb_setscl(device_t dev, unsigned char val)
{
device_t ppbus = device_get_parent(dev);
- mtx_lock(&Giant);
+ ppb_lock(ppbus);
if (val == 0)
ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) & ~SCL_out));
else
ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) | SCL_out));
- mtx_unlock(&Giant);
+ ppb_unlock(ppbus);
}
static int
@@ -182,23 +195,24 @@ lpbb_detect(device_t dev)
{
device_t ppbus = device_get_parent(dev);
+ ppb_lock(ppbus);
if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
+ ppb_unlock(ppbus);
device_printf(dev, "can't allocate ppbus\n");
return (0);
}
- /* reset bus */
- lpbb_setsda(dev, 1);
- lpbb_setscl(dev, 1);
+ lpbb_reset_bus(dev);
if ((ppb_rstr(ppbus) & I2CKEY) ||
((ppb_rstr(ppbus) & ALIM) != ALIM)) {
-
ppb_release_bus(ppbus, dev);
+ ppb_unlock(ppbus);
return (0);
}
ppb_release_bus(ppbus, dev);
+ ppb_unlock(ppbus);
return (1);
}
@@ -208,18 +222,17 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
{
device_t ppbus = device_get_parent(dev);
- mtx_lock(&Giant);
+ ppb_lock(ppbus);
if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
+ ppb_unlock(ppbus);
device_printf(dev, "can't allocate ppbus\n");
return (0);
}
- /* reset bus */
- lpbb_setsda(dev, 1);
- lpbb_setscl(dev, 1);
+ lpbb_reset_bus(dev);
ppb_release_bus(ppbus, dev);
- mtx_unlock(&Giant);
+ ppb_unlock(ppbus);
return (IIC_ENOADDR);
}
diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c
index 3659252..6da65f1 100644
--- a/sys/dev/ppbus/lpt.c
+++ b/sys/dev/ppbus/lpt.c
@@ -105,9 +105,9 @@ static int volatile lptflag = 1;
#define BUFSTATSIZE 32
struct lpt_data {
- device_t dev;
- struct cdev *cdev;
- struct cdev *cdev_bypass;
+ device_t sc_dev;
+ struct cdev *sc_cdev;
+ struct cdev *sc_cdev_bypass;
short sc_state;
/* default case: negative prime, negative ack, handshake strobe,
prime once */
@@ -130,9 +130,10 @@ struct lpt_data {
#define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */
#define LP_ENABLE_EXT 0x10 /* we shall use advanced mode when possible */
u_char sc_backoff ; /* time to call lptout() again */
+ struct callout sc_timer;
- struct resource *intr_resource; /* interrupt resource */
- void *intr_cookie; /* interrupt registration cookie */
+ struct resource *sc_intr_resource; /* interrupt resource */
+ void *sc_intr_cookie; /* interrupt cookie */
};
#define LPT_NAME "lpt" /* our official name */
@@ -144,8 +145,7 @@ static int lpt_detect(device_t dev);
#define DEVTOSOFTC(dev) \
((struct lpt_data *)device_get_softc(dev))
-static void lptintr(device_t dev);
-static void lpt_intr(void *arg); /* without spls */
+static void lptintr(void *arg);
static devclass_t lpt_devclass;
@@ -183,7 +183,6 @@ static d_ioctl_t lptioctl;
static struct cdevsw lpt_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
.d_open = lptopen,
.d_close = lptclose,
.d_read = lptread,
@@ -199,13 +198,17 @@ lpt_request_ppbus(device_t dev, int how)
struct lpt_data *sc = DEVTOSOFTC(dev);
int error;
+ /*
+ * We might already have the bus for a write(2) after an interrupted
+ * write(2) call.
+ */
+ ppb_assert_locked(ppbus);
if (sc->sc_state & HAVEBUS)
return (0);
- /* we have the bus only if the request succeded */
- if ((error = ppb_request_bus(ppbus, dev, how)) == 0)
+ error = ppb_request_bus(ppbus, dev, how);
+ if (error == 0)
sc->sc_state |= HAVEBUS;
-
return (error);
}
@@ -216,9 +219,12 @@ lpt_release_ppbus(device_t dev)
struct lpt_data *sc = DEVTOSOFTC(dev);
int error = 0;
- if ((error = ppb_release_bus(ppbus, dev)) == 0)
- sc->sc_state &= ~HAVEBUS;
-
+ ppb_assert_locked(ppbus);
+ if (sc->sc_state & HAVEBUS) {
+ error = ppb_release_bus(ppbus, dev);
+ if (error == 0)
+ sc->sc_state &= ~HAVEBUS;
+ }
return (error);
}
@@ -306,24 +312,25 @@ lpt_detect(device_t dev)
status = 1; /* assume success */
+ ppb_lock(ppbus);
if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
- printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
- status = 0;
- goto end_probe;
+ ppb_unlock(ppbus);
+ device_printf(dev, "cannot alloc ppbus (%d)!\n", error);
+ return (0);
}
for (i = 0; i < 18 && status; i++)
if (!lpt_port_test(ppbus, testbyte[i], 0xff)) {
status = 0;
- goto end_probe;
+ break;
}
-end_probe:
/* write 0's to control and data ports */
ppb_wdtr(ppbus, 0);
ppb_wctr(ppbus, 0);
lpt_release_ppbus(dev);
+ ppb_unlock(ppbus);
return (status);
}
@@ -363,21 +370,33 @@ lpt_attach(device_t dev)
int error;
sc->sc_primed = 0; /* not primed yet */
+ ppb_init_callout(ppbus, &sc->sc_timer, 0);
+ ppb_lock(ppbus);
if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
- printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
+ ppb_unlock(ppbus);
+ device_printf(dev, "cannot alloc ppbus (%d)!\n", error);
return (0);
}
ppb_wctr(ppbus, LPC_NINIT);
-
- /* check if we can use interrupt, should be done by ppc stuff */
- lprintf(("oldirq %x\n", sc->sc_irq));
+ lpt_release_ppbus(dev);
+ ppb_unlock(ppbus);
/* declare our interrupt handler */
- sc->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ sc->sc_intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE);
- if (sc->intr_resource) {
+ if (sc->sc_intr_resource) {
+ error = bus_setup_intr(dev, sc->sc_intr_resource,
+ INTR_TYPE_TTY | INTR_MPSAFE, NULL, lptintr, sc,
+ &sc->sc_intr_cookie);
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ, rid,
+ sc->sc_intr_resource);
+ device_printf(dev,
+ "Unable to register interrupt handler\n");
+ return (error);
+ }
sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
device_printf(dev, "Interrupt-driven port\n");
} else {
@@ -386,17 +405,17 @@ lpt_attach(device_t dev)
}
lprintf(("irq %x\n", sc->sc_irq));
- lpt_release_ppbus(dev);
-
- sc->dev = dev;
- sc->cdev = make_dev(&lpt_cdevsw, unit,
+ sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
+ sc->sc_statbuf = malloc(BUFSTATSIZE, M_DEVBUF, M_WAITOK);
+ sc->sc_dev = dev;
+ sc->sc_cdev = make_dev(&lpt_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d", unit);
- sc->cdev->si_drv1 = sc;
- sc->cdev->si_drv2 = 0;
- sc->cdev_bypass = make_dev(&lpt_cdevsw, unit,
+ sc->sc_cdev->si_drv1 = sc;
+ sc->sc_cdev->si_drv2 = 0;
+ sc->sc_cdev_bypass = make_dev(&lpt_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d.ctl", unit);
- sc->cdev_bypass->si_drv1 = sc;
- sc->cdev_bypass->si_drv2 = (void *)LP_BYPASS;
+ sc->sc_cdev_bypass->si_drv1 = sc;
+ sc->sc_cdev_bypass->si_drv2 = (void *)LP_BYPASS;
return (0);
}
@@ -404,15 +423,21 @@ static int
lpt_detach(device_t dev)
{
struct lpt_data *sc = DEVTOSOFTC(dev);
+ device_t ppbus = device_get_parent(dev);
- destroy_dev(sc->cdev);
- destroy_dev(sc->cdev_bypass);
+ destroy_dev(sc->sc_cdev);
+ destroy_dev(sc->sc_cdev_bypass);
+ ppb_lock(ppbus);
lpt_release_ppbus(dev);
- if (sc->intr_resource != 0) {
- BUS_TEARDOWN_INTR(device_get_parent(dev), dev,
- sc->intr_resource, sc->intr_cookie);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->intr_resource);
+ ppb_unlock(ppbus);
+ callout_drain(&sc->sc_timer);
+ if (sc->sc_intr_resource != NULL) {
+ bus_teardown_intr(dev, sc->sc_intr_resource,
+ sc->sc_intr_cookie);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_intr_resource);
}
+ free(sc->sc_inbuf, M_DEVBUF);
+ free(sc->sc_statbuf, M_DEVBUF);
return (0);
}
@@ -420,18 +445,19 @@ lpt_detach(device_t dev)
static void
lptout(void *arg)
{
- device_t dev = (device_t)arg;
- struct lpt_data *sc = DEVTOSOFTC(dev);
-#ifdef LPT_DEBUG
+ struct lpt_data *sc = arg;
+ device_t dev = sc->sc_dev;
+#if defined(INVARIANTS) || defined(LPT_DEBUG)
device_t ppbus = device_get_parent(dev);
#endif
+ ppb_assert_locked(ppbus);
lprintf(("T %x ", ppb_rstr(ppbus)));
if (sc->sc_state & OPEN) {
sc->sc_backoff++;
if (sc->sc_backoff > hz/LPTOUTMAX)
sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
- timeout(lptout, (caddr_t)dev, sc->sc_backoff);
+ callout_reset(&sc->sc_timer, sc->sc_backoff, lptout, sc);
} else
sc->sc_state &= ~TOUT;
@@ -442,7 +468,7 @@ lptout(void *arg)
* Avoid possible hangs due to missed interrupts
*/
if (sc->sc_xfercnt) {
- lptintr(dev);
+ lptintr(sc);
} else {
sc->sc_state &= ~OBUSY;
wakeup(dev);
@@ -458,17 +484,19 @@ lptout(void *arg)
static int
lptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
{
- int s;
int trys, err;
struct lpt_data *sc = dev->si_drv1;
- device_t lptdev = sc->dev;
+ device_t lptdev = sc->sc_dev;
device_t ppbus = device_get_parent(lptdev);
if (!sc)
return (ENXIO);
+ ppb_lock(ppbus);
if (sc->sc_state) {
- lprintf((LPT_NAME ": still open %x\n", sc->sc_state));
+ lprintf(("%s: still open %x\n", device_get_nameunit(lptdev),
+ sc->sc_state));
+ ppb_unlock(ppbus);
return(EBUSY);
} else
sc->sc_state |= LPTINIT;
@@ -478,6 +506,7 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
/* Check for open with BYPASS flag set. */
if (sc->sc_flags & LP_BYPASS) {
sc->sc_state = OPEN;
+ ppb_unlock(ppbus);
return(0);
}
@@ -485,11 +514,12 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) {
/* give it a chance to try later */
sc->sc_state = 0;
+ ppb_unlock(ppbus);
return (err);
}
- s = spltty();
- lprintf((LPT_NAME " flags 0x%x\n", sc->sc_flags));
+ lprintf(("%s flags 0x%x\n", device_get_nameunit(lptdev),
+ sc->sc_flags));
/* set IRQ status according to ENABLE_IRQ flag
*/
@@ -514,21 +544,21 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
do {
/* ran out of waiting for the printer */
if (trys++ >= LPINITRDY*4) {
- splx(s);
sc->sc_state = 0;
lprintf(("status %x\n", ppb_rstr(ppbus)));
lpt_release_ppbus(lptdev);
+ ppb_unlock(ppbus);
return (EBUSY);
}
/* wait 1/4 second, give up if we get a signal */
- if (tsleep(lptdev, LPPRI|PCATCH, "lptinit", hz/4) !=
- EWOULDBLOCK) {
+ if (ppb_sleep(ppbus, lptdev, LPPRI | PCATCH, "lptinit",
+ hz / 4) != EWOULDBLOCK) {
sc->sc_state = 0;
- splx(s);
lpt_release_ppbus(lptdev);
+ ppb_unlock(ppbus);
return (EBUSY);
}
@@ -548,22 +578,20 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
ppb_wctr(ppbus, sc->sc_control);
sc->sc_state = OPEN;
- sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
- sc->sc_statbuf = malloc(BUFSTATSIZE, M_DEVBUF, M_WAITOK);
sc->sc_xfercnt = 0;
- splx(s);
-
- /* release the ppbus */
- lpt_release_ppbus(lptdev);
/* only use timeout if using interrupt */
lprintf(("irq %x\n", sc->sc_irq));
if (sc->sc_irq & LP_USE_IRQ) {
sc->sc_state |= TOUT;
- timeout(lptout, (caddr_t)lptdev,
- (sc->sc_backoff = hz/LPTOUTINITIAL));
+ sc->sc_backoff = hz / LPTOUTINITIAL;
+ callout_reset(&sc->sc_timer, sc->sc_backoff, lptout, sc);
}
+ /* release the ppbus */
+ lpt_release_ppbus(lptdev);
+ ppb_unlock(ppbus);
+
lprintf(("opened.\n"));
return(0);
}
@@ -578,17 +606,21 @@ static int
lptclose(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct lpt_data *sc = dev->si_drv1;
- device_t lptdev = sc->dev;
+ device_t lptdev = sc->sc_dev;
device_t ppbus = device_get_parent(lptdev);
int err;
- if (sc->sc_flags & LP_BYPASS)
+ ppb_lock(ppbus);
+ if (sc->sc_flags & LP_BYPASS) {
+ sc->sc_state = 0;
+ ppb_unlock(ppbus);
goto end_close;
+ }
- if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
+ if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) {
+ ppb_unlock(ppbus);
return (err);
-
- sc->sc_state &= ~OPEN;
+ }
/* if the last write was interrupted, don't complete it */
if ((!(sc->sc_state & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ))
@@ -596,22 +628,23 @@ lptclose(struct cdev *dev, int flags, int fmt, struct thread *td)
(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
(LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt)
/* wait 1/4 second, give up if we get a signal */
- if (tsleep(lptdev, LPPRI|PCATCH,
- "lpclose", hz) != EWOULDBLOCK)
+ if (ppb_sleep(ppbus, lptdev, LPPRI | PCATCH, "lpclose",
+ hz) != EWOULDBLOCK)
break;
+ sc->sc_state &= ~OPEN;
+ callout_stop(&sc->sc_timer);
ppb_wctr(ppbus, LPC_NINIT);
- free(sc->sc_inbuf, M_DEVBUF);
- free(sc->sc_statbuf, M_DEVBUF);
+ sc->sc_state = 0;
+ sc->sc_xfercnt = 0;
-end_close:
- /* release the bus anyway
+ /*
* unregistration of interrupt forced by release
*/
lpt_release_ppbus(lptdev);
+ ppb_unlock(ppbus);
- sc->sc_state = 0;
- sc->sc_xfercnt = 0;
+end_close:
lprintf(("closed.\n"));
return(0);
}
@@ -625,13 +658,14 @@ end_close:
* This code is only used when we are polling the port
*/
static int
-lpt_pushbytes(device_t dev)
+lpt_pushbytes(struct lpt_data *sc)
{
- struct lpt_data *sc = DEVTOSOFTC(dev);
+ device_t dev = sc->sc_dev;
device_t ppbus = device_get_parent(dev);
int spin, err, tic;
char ch;
+ ppb_assert_locked(ppbus);
lprintf(("p"));
/* loop for every character .. */
while (sc->sc_xfercnt > 0) {
@@ -660,7 +694,7 @@ lpt_pushbytes(device_t dev)
*/
if (tic > MAX_SLEEP)
tic = MAX_SLEEP;
- err = tsleep(dev, LPPRI,
+ err = ppb_sleep(ppbus, dev, LPPRI,
LPT_NAME "poll", tic);
if (err != EWOULDBLOCK) {
return (err);
@@ -686,7 +720,7 @@ static int
lptread(struct cdev *dev, struct uio *uio, int ioflag)
{
struct lpt_data *sc = dev->si_drv1;
- device_t lptdev = sc->dev;
+ device_t lptdev = sc->sc_dev;
device_t ppbus = device_get_parent(lptdev);
int error = 0, len;
@@ -695,8 +729,11 @@ lptread(struct cdev *dev, struct uio *uio, int ioflag)
return (EPERM);
}
- if ((error = ppb_1284_negociate(ppbus, PPB_NIBBLE, 0)))
+ ppb_lock(ppbus);
+ if ((error = ppb_1284_negociate(ppbus, PPB_NIBBLE, 0))) {
+ ppb_unlock(ppbus);
return (error);
+ }
/* read data in an other buffer, read/write may be simultaneous */
len = 0;
@@ -710,12 +747,16 @@ lptread(struct cdev *dev, struct uio *uio, int ioflag)
if (!len)
goto error; /* no more data */
- if ((error = uiomove(sc->sc_statbuf, len, uio)))
+ ppb_unlock(ppbus);
+ error = uiomove(sc->sc_statbuf, len, uio);
+ ppb_lock(ppbus);
+ if (error)
goto error;
}
error:
ppb_1284_terminate(ppbus);
+ ppb_unlock(ppbus);
return (error);
}
@@ -732,36 +773,30 @@ lptwrite(struct cdev *dev, struct uio *uio, int ioflag)
register unsigned n;
int err;
struct lpt_data *sc = dev->si_drv1;
- device_t lptdev = sc->dev;
+ device_t lptdev = sc->sc_dev;
device_t ppbus = device_get_parent(lptdev);
if (sc->sc_flags & LP_BYPASS) {
/* we can't do writes in bypass mode */
- return(EPERM);
+ return (EPERM);
}
/* request the ppbus only if we don't have it already */
- /* XXX interrupt registration?! */
- if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
+ ppb_lock(ppbus);
+ if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) {
+ ppb_unlock(ppbus);
return (err);
-
- /* if interrupts are working, register the handler */
- if (sc->sc_irq & LP_USE_IRQ) {
- /* register our interrupt handler */
- err = bus_setup_intr(lptdev, sc->intr_resource,
- INTR_TYPE_TTY, NULL, lpt_intr, lptdev,
- &sc->intr_cookie);
- if (err) {
- device_printf(lptdev, "handler registration failed, polled mode.\n");
- sc->sc_irq &= ~LP_USE_IRQ;
- }
}
sc->sc_state &= ~INTERRUPTED;
while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
sc->sc_cp = sc->sc_inbuf;
- uiomove(sc->sc_cp, n, uio);
- sc->sc_xfercnt = n ;
+ ppb_unlock(ppbus);
+ err = uiomove(sc->sc_cp, n, uio);
+ ppb_lock(ppbus);
+ if (err)
+ break;
+ sc->sc_xfercnt = n;
if (sc->sc_irq & LP_ENABLE_EXT) {
/* try any extended mode */
@@ -775,15 +810,17 @@ lptwrite(struct cdev *dev, struct uio *uio, int ioflag)
break;
case EINTR:
sc->sc_state |= INTERRUPTED;
- return(err);
+ ppb_unlock(ppbus);
+ return (err);
case EINVAL:
/* advanced mode not avail */
log(LOG_NOTICE,
"%s: advanced mode not avail, polling\n",
- device_get_nameunit(sc->dev));
+ device_get_nameunit(sc->sc_dev));
break;
default:
- return(err);
+ ppb_unlock(ppbus);
+ return (err);
}
} else while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
lprintf(("i"));
@@ -791,13 +828,14 @@ lptwrite(struct cdev *dev, struct uio *uio, int ioflag)
/* give it one */
if ((sc->sc_state & OBUSY) == 0){
lprintf(("\nC %d. ", sc->sc_xfercnt));
- lptintr(lptdev);
+ lptintr(sc);
}
lprintf(("W "));
if (sc->sc_state & OBUSY)
- if ((err = tsleep(lptdev,
+ if ((err = ppb_sleep(ppbus, lptdev,
LPPRI|PCATCH, LPT_NAME "write", 0))) {
sc->sc_state |= INTERRUPTED;
+ ppb_unlock(ppbus);
return(err);
}
}
@@ -806,38 +844,37 @@ lptwrite(struct cdev *dev, struct uio *uio, int ioflag)
if (!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
lprintf(("p"));
- err = lpt_pushbytes(lptdev);
+ err = lpt_pushbytes(sc);
- if (err)
- return(err);
+ if (err) {
+ ppb_unlock(ppbus);
+ return (err);
+ }
}
}
/* we have not been interrupted, release the ppbus */
lpt_release_ppbus(lptdev);
+ ppb_unlock(ppbus);
- return(0);
+ return (err);
}
/*
- * lpt_intr -- handle printer interrupts which occur when the printer is
+ * lptintr -- handle printer interrupts which occur when the printer is
* ready to accept another char.
*
* do checking for interrupted write call.
*/
static void
-lpt_intr(void *arg)
+lptintr(void *arg)
{
- device_t lptdev = (device_t)arg;
+ struct lpt_data *sc = arg;
+ device_t lptdev = sc->sc_dev;
device_t ppbus = device_get_parent(lptdev);
- struct lpt_data *sc = DEVTOSOFTC(lptdev);
int sts = 0;
int i;
- /* we must own the bus to use it */
- if ((sc->sc_state & HAVEBUS) == 0)
- return;
-
/*
* Is printer online and ready for output?
*
@@ -883,27 +920,18 @@ lpt_intr(void *arg)
lprintf(("sts %x ", sts));
}
-static void
-lptintr(device_t dev)
-{
- /* call the interrupt at required spl level */
- int s = spltty();
-
- lpt_intr(dev);
-
- splx(s);
- return;
-}
-
static int
lptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td)
{
int error = 0;
struct lpt_data *sc = dev->si_drv1;
+ device_t ppbus;
u_char old_sc_irq; /* old printer IRQ status */
switch (cmd) {
case LPT_IRQ :
+ ppbus = device_get_parent(sc->sc_dev);
+ ppb_lock(ppbus);
if (sc->sc_irq & LP_HAS_IRQ) {
/*
* NOTE:
@@ -915,7 +943,7 @@ lptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
* this gets syslog'd.
*/
old_sc_irq = sc->sc_irq;
- switch(*(int*)data) {
+ switch (*(int*)data) {
case 0:
sc->sc_irq &= (~LP_ENABLE_IRQ);
break;
@@ -939,13 +967,14 @@ lptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
if (old_sc_irq != sc->sc_irq )
log(LOG_NOTICE, "%s: switched to %s %s mode\n",
- device_get_nameunit(sc->dev),
+ device_get_nameunit(sc->sc_dev),
(sc->sc_irq & LP_ENABLE_IRQ)?
"interrupt-driven":"polled",
(sc->sc_irq & LP_ENABLE_EXT)?
"extended":"standard");
} else /* polled port */
error = EOPNOTSUPP;
+ ppb_unlock(ppbus);
break;
default:
error = ENODEV;
diff --git a/sys/dev/ppbus/pcfclock.c b/sys/dev/ppbus/pcfclock.c
index a969a84..e59a891 100644
--- a/sys/dev/ppbus/pcfclock.c
+++ b/sys/dev/ppbus/pcfclock.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
struct pcfclock_data {
device_t dev;
struct cdev *cdev;
- int count;
};
static devclass_t pcfclock_devclass;
@@ -65,7 +64,6 @@ static d_read_t pcfclock_read;
static struct cdevsw pcfclock_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
.d_open = pcfclock_open,
.d_close = pcfclock_close,
.d_read = pcfclock_read,
@@ -159,13 +157,11 @@ pcfclock_open(struct cdev *dev, int flag, int fms, struct thread *td)
if (!sc)
return (ENXIO);
- if ((res = ppb_request_bus(ppbus, pcfclockdev,
- (flag & O_NONBLOCK) ? PPB_DONTWAIT : PPB_WAIT)))
- return (res);
-
- sc->count++;
-
- return (0);
+ ppb_lock(ppbus);
+ res = ppb_request_bus(ppbus, pcfclockdev,
+ (flag & O_NONBLOCK) ? PPB_DONTWAIT : PPB_WAIT);
+ ppb_unlock(ppbus);
+ return (res);
}
static int
@@ -175,9 +171,9 @@ pcfclock_close(struct cdev *dev, int flags, int fmt, struct thread *td)
device_t pcfclockdev = sc->dev;
device_t ppbus = device_get_parent(pcfclockdev);
- sc->count--;
- if (sc->count == 0)
- ppb_release_bus(ppbus, pcfclockdev);
+ ppb_lock(ppbus);
+ ppb_release_bus(ppbus, pcfclockdev);
+ ppb_unlock(ppbus);
return (0);
}
@@ -240,7 +236,7 @@ pcfclock_read_data(struct cdev *dev, char *buf, ssize_t bits)
waitfor = 100;
for (i = 0; i <= bits; i++) {
/* wait for clock, maximum (waitfor*100) usec */
- while(!CLOCK_OK && --waitfor > 0)
+ while (!CLOCK_OK && --waitfor > 0)
DELAY(100);
/* timed out? */
@@ -297,13 +293,17 @@ static int
pcfclock_read(struct cdev *dev, struct uio *uio, int ioflag)
{
struct pcfclock_data *sc = dev->si_drv1;
+ device_t ppbus;
char buf[18];
int error = 0;
if (uio->uio_resid < 18)
return (ERANGE);
+ ppbus = device_get_parent(sc->dev);
+ ppb_lock(ppbus);
error = pcfclock_read_dev(dev, buf, PCFCLOCK_MAX_RETRIES);
+ ppb_unlock(ppbus);
if (error) {
device_printf(sc->dev, "no PCF found\n");
diff --git a/sys/dev/ppbus/ppb_1284.c b/sys/dev/ppbus/ppb_1284.c
index 28ee321..e909e8e 100644
--- a/sys/dev/ppbus/ppb_1284.c
+++ b/sys/dev/ppbus/ppb_1284.c
@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
#include "opt_ppb_1284.h"
#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -92,8 +94,10 @@ ppb_1284_reset_error(device_t bus, int state)
int
ppb_1284_get_state(device_t bus)
{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
- return (DEVTOSOFTC(bus)->state);
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
+ return (ppb->state);
}
/*
@@ -108,6 +112,7 @@ ppb_1284_set_state(device_t bus, int state)
/* call ppb_1284_reset_error() if you absolutly want to change
* the state from PPB_ERROR to another */
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
if ((ppb->state != PPB_ERROR) &&
(ppb->error == PPB_NO_ERROR)) {
ppb->state = state;
diff --git a/sys/dev/ppbus/ppb_base.c b/sys/dev/ppbus/ppb_base.c
index c288616..30c42a4 100644
--- a/sys/dev/ppbus/ppb_base.c
+++ b/sys/dev/ppbus/ppb_base.c
@@ -28,9 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
#include <sys/bus.h>
#include <dev/ppbus/ppbconf.h>
@@ -54,9 +56,12 @@ int
ppb_poll_bus(device_t bus, int max,
char mask, char status, int how)
{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
int i, j, error;
char r;
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
+
/* try at least up to 10ms */
for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) {
for (i = 0; i < 10000; i++) {
@@ -72,21 +77,11 @@ ppb_poll_bus(device_t bus, int max,
if ((ppb_rstr(bus) & mask) == status)
return (0);
- switch (how) {
- case PPB_NOINTR:
- /* wait 10 ms */
- pause("ppbpoll", hz/100);
- break;
-
- case PPB_INTR:
- default:
- /* wait 10 ms */
- if (((error = tsleep((caddr_t)bus, PPBPRI | PCATCH,
- "ppbpoll", hz/100)) != EWOULDBLOCK) != 0) {
- return (error);
- }
- break;
- }
+ /* wait 10 ms */
+ error = mtx_sleep((caddr_t)bus, ppb->ppc_lock, PPBPRI |
+ (how == PPB_NOINTR ? 0 : PCATCH), "ppbpoll", hz/100);
+ if (error != EWOULDBLOCK)
+ return (error);
}
}
@@ -101,8 +96,12 @@ ppb_poll_bus(device_t bus, int max,
int
ppb_get_epp_protocol(device_t bus)
{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+#endif
uintptr_t protocol;
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol);
return (protocol);
@@ -118,6 +117,7 @@ ppb_get_mode(device_t bus)
struct ppb_data *ppb = DEVTOSOFTC(bus);
/* XXX yet device mode = ppbus mode = chipset mode */
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
return (ppb->mode);
}
@@ -132,6 +132,7 @@ ppb_set_mode(device_t bus, int mode)
struct ppb_data *ppb = DEVTOSOFTC(bus);
int old_mode = ppb_get_mode(bus);
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
if (PPBUS_SETMODE(device_get_parent(bus), mode))
return (-1);
@@ -149,6 +150,11 @@ ppb_set_mode(device_t bus, int mode)
int
ppb_write(device_t bus, char *buf, int len, int how)
{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+#endif
+
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
return (PPBUS_WRITE(device_get_parent(bus), buf, len, how));
}
@@ -160,6 +166,11 @@ ppb_write(device_t bus, char *buf, int len, int how)
int
ppb_reset_epp_timeout(device_t bus)
{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+#endif
+
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
return(PPBUS_RESET_EPP(device_get_parent(bus)));
}
@@ -171,6 +182,11 @@ ppb_reset_epp_timeout(device_t bus)
int
ppb_ecp_sync(device_t bus)
{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+#endif
+
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
return (PPBUS_ECP_SYNC(device_get_parent(bus)));
}
@@ -182,8 +198,13 @@ ppb_ecp_sync(device_t bus)
int
ppb_get_status(device_t bus, struct ppb_status *status)
{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+#endif
register char r;
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
+
r = status->status = ppb_rstr(bus);
status->timeout = r & TIMEOUT;
@@ -195,3 +216,45 @@ ppb_get_status(device_t bus, struct ppb_status *status)
return (0);
}
+
+void
+ppb_lock(device_t bus)
+{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
+ mtx_lock(ppb->ppc_lock);
+}
+
+void
+ppb_unlock(device_t bus)
+{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
+ mtx_unlock(ppb->ppc_lock);
+}
+
+void
+_ppb_assert_locked(device_t bus, const char *file, int line)
+{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
+ _mtx_assert(ppb->ppc_lock, MA_OWNED, file, line);
+#endif
+}
+
+void
+ppb_init_callout(device_t bus, struct callout *c, int flags)
+{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
+ callout_init_mtx(c, ppb->ppc_lock, flags);
+}
+
+int
+ppb_sleep(device_t bus, void *wchan, int priority, const char *wmesg, int timo)
+{
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
+
+ return (mtx_sleep(wchan, ppb->ppc_lock, priority, wmesg, timo));
+}
diff --git a/sys/dev/ppbus/ppb_msq.c b/sys/dev/ppbus/ppb_msq.c
index a02f9e1..89be014 100644
--- a/sys/dev/ppbus/ppb_msq.c
+++ b/sys/dev/ppbus/ppb_msq.c
@@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -115,9 +117,13 @@ mode2xfer(device_t bus, struct ppb_device *ppbdev, int opcode)
int
ppb_MS_init(device_t bus, device_t dev, struct ppb_microseq *loop, int opcode)
{
+#ifdef INVARIANTS
+ struct ppb_data *ppb = device_get_softc(bus);
+#endif
struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
struct ppb_xfer *xfer = mode2xfer(bus, ppbdev, opcode);
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
xfer->loop = loop;
return (0);
@@ -265,6 +271,7 @@ ppb_MS_microseq(device_t bus, device_t dev, struct ppb_microseq *msq, int *ret)
MS_RET(0)
};
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
if (ppb->ppb_owner != dev)
return (EACCES);
diff --git a/sys/dev/ppbus/ppbconf.c b/sys/dev/ppbus/ppbconf.c
index 196e2b8..a994355 100644
--- a/sys/dev/ppbus/ppbconf.c
+++ b/sys/dev/ppbus/ppbconf.c
@@ -33,7 +33,9 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/rman.h>
@@ -50,6 +52,8 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_PPBUSDEV, "ppbusdev", "Parallel Port bus device");
+static int ppbus_intr(void *arg);
+
/*
* Device methods
*/
@@ -375,13 +379,38 @@ end_scan:
static int
ppbus_attach(device_t dev)
{
+ struct ppb_data *ppb = device_get_softc(dev);
+ int error, rid;
+
+ error = BUS_READ_IVAR(device_get_parent(dev), dev, PPC_IVAR_LOCK,
+ (uintptr_t *)&ppb->ppc_lock);
+ if (error) {
+ device_printf(dev, "Unable to fetch parent's lock\n");
+ return (error);
+ }
+
+ rid = 0;
+ ppb->ppc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE);
+ if (ppb->ppc_irq_res != NULL) {
+ mtx_lock(ppb->ppc_lock);
+ error = BUS_WRITE_IVAR(device_get_parent(dev), dev,
+ PPC_IVAR_INTR_HANDLER, (uintptr_t)&ppbus_intr);
+ mtx_unlock(ppb->ppc_lock);
+ if (error) {
+ device_printf(dev, "Unable to set interrupt handler\n");
+ return (error);
+ }
+ }
/* Locate our children */
bus_generic_probe(dev);
#ifndef DONTPROBE_1284
/* detect IEEE1284 compliant devices */
+ mtx_lock(ppb->ppc_lock);
ppb_scan_bus(dev);
+ mtx_unlock(ppb->ppc_lock);
#endif /* !DONTPROBE_1284 */
/* launch attachment of the added children */
@@ -412,26 +441,43 @@ ppbus_detach(device_t dev)
}
static int
+ppbus_intr(void *arg)
+{
+ struct ppb_device *ppbdev;
+ struct ppb_data *ppb = arg;
+
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
+ if (ppb->ppb_owner == NULL)
+ return (ENOENT);
+
+ ppbdev = device_get_ivars(ppb->ppb_owner);
+ if (ppbdev->intr_hook == NULL)
+ return (ENOENT);
+
+ ppbdev->intr_hook(ppbdev->intr_arg);
+ return (0);
+}
+
+static int
ppbus_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep)
{
- int error;
- struct ppb_data *ppb = DEVTOSOFTC(bus);
struct ppb_device *ppbdev = device_get_ivars(child);
+ struct ppb_data *ppb = DEVTOSOFTC(bus);
- /* a device driver must own the bus to register an interrupt */
- if (ppb->ppb_owner != child)
+ /* We do not support filters. */
+ if (filt != NULL || ihand == NULL)
return (EINVAL);
- if ((error = BUS_SETUP_INTR(device_get_parent(bus), child, r, flags,
- filt, ihand, arg, cookiep)))
- return (error);
+ /* Can only attach handlers to the parent device's resource. */
+ if (ppb->ppc_irq_res != r)
+ return (EINVAL);
- /* store the resource and the cookie for eventually forcing
- * handler unregistration
- */
- ppbdev->intr_cookie = *cookiep;
- ppbdev->intr_resource = r;
+ mtx_lock(ppb->ppc_lock);
+ ppbdev->intr_hook = ihand;
+ ppbdev->intr_arg = arg;
+ *cookiep = ppbdev;
+ mtx_unlock(ppb->ppc_lock);
return (0);
}
@@ -439,19 +485,19 @@ ppbus_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
static int
ppbus_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
{
+ struct ppb_device *ppbdev = device_get_ivars(child);
struct ppb_data *ppb = DEVTOSOFTC(bus);
- struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(child);
- /* a device driver must own the bus to unregister an interrupt */
- if ((ppb->ppb_owner != child) || (ppbdev->intr_cookie != ih) ||
- (ppbdev->intr_resource != r))
+ mtx_lock(ppb->ppc_lock);
+ if (ppbdev != ih || ppb->ppc_irq_res != r) {
+ mtx_unlock(ppb->ppc_lock);
return (EINVAL);
+ }
- ppbdev->intr_cookie = 0;
- ppbdev->intr_resource = 0;
+ ppbdev->intr_hook = NULL;
+ mtx_unlock(ppb->ppc_lock);
- /* pass unregistration to the upper layer */
- return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, ih));
+ return (0);
}
/*
@@ -464,27 +510,26 @@ ppbus_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
int
ppb_request_bus(device_t bus, device_t dev, int how)
{
- int s, error = 0;
struct ppb_data *ppb = DEVTOSOFTC(bus);
struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
+ int error = 0;
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
while (!error) {
- s = splhigh();
if (ppb->ppb_owner) {
- splx(s);
-
switch (how) {
- case (PPB_WAIT | PPB_INTR):
- error = tsleep(ppb, PPBPRI|PCATCH, "ppbreq", 0);
+ case PPB_WAIT | PPB_INTR:
+ error = mtx_sleep(ppb, ppb->ppc_lock,
+ PPBPRI | PCATCH, "ppbreq", 0);
break;
- case (PPB_WAIT | PPB_NOINTR):
- error = tsleep(ppb, PPBPRI, "ppbreq", 0);
+ case PPB_WAIT | PPB_NOINTR:
+ error = mtx_sleep(ppb, ppb->ppc_lock, PPBPRI,
+ "ppbreq", 0);
break;
default:
return (EWOULDBLOCK);
- break;
}
} else {
@@ -499,7 +544,6 @@ ppb_request_bus(device_t bus, device_t dev, int how)
if (ppbdev->ctx.valid)
ppb_set_mode(bus, ppbdev->ctx.mode);
- splx(s);
return (0);
}
}
@@ -515,24 +559,12 @@ ppb_request_bus(device_t bus, device_t dev, int how)
int
ppb_release_bus(device_t bus, device_t dev)
{
- int s, error;
struct ppb_data *ppb = DEVTOSOFTC(bus);
struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
- if (ppbdev->intr_resource != 0)
- /* force interrupt handler unregistration when the ppbus is released */
- if ((error = BUS_TEARDOWN_INTR(bus, dev, ppbdev->intr_resource,
- ppbdev->intr_cookie)))
- return (error);
-
- s = splhigh();
- if (ppb->ppb_owner != dev) {
- splx(s);
+ mtx_assert(ppb->ppc_lock, MA_OWNED);
+ if (ppb->ppb_owner != dev)
return (EACCES);
- }
-
- ppb->ppb_owner = 0;
- splx(s);
/* save the context of the device */
ppbdev->ctx.mode = ppb_get_mode(bus);
@@ -540,6 +572,8 @@ ppb_release_bus(device_t bus, device_t dev)
/* ok, now the context of the device is valid */
ppbdev->ctx.valid = 1;
+ ppb->ppb_owner = 0;
+
/* wakeup waiting processes */
wakeup(ppb);
diff --git a/sys/dev/ppbus/ppbconf.h b/sys/dev/ppbus/ppbconf.h
index 482d34f..c898482 100644
--- a/sys/dev/ppbus/ppbconf.h
+++ b/sys/dev/ppbus/ppbconf.h
@@ -29,6 +29,35 @@
#ifndef __PPBCONF_H
#define __PPBCONF_H
+#define n(flags) (~(flags) & (flags))
+
+/*
+ * Parallel Port Chipset control bits.
+ */
+#define STROBE 0x01
+#define AUTOFEED 0x02
+#define nINIT 0x04
+#define SELECTIN 0x08
+#define IRQENABLE 0x10
+#define PCD 0x20
+
+#define nSTROBE n(STROBE)
+#define nAUTOFEED n(AUTOFEED)
+#define INIT n(nINIT)
+#define nSELECTIN n(SELECTIN)
+#define nPCD n(PCD)
+
+/*
+ * Parallel Port Chipset status bits.
+ */
+#define TIMEOUT 0x01
+#define nFAULT 0x08
+#define SELECT 0x10
+#define PERROR 0x20
+#define nACK 0x40
+#define nBUSY 0x80
+
+#ifdef _KERNEL
#include <sys/queue.h>
/*
@@ -59,34 +88,6 @@
#define PPB_IN_NIBBLE_MODE(bus) (ppb_get_mode (bus) & PPB_NIBBLE)
#define PPB_IN_PS2_MODE(bus) (ppb_get_mode (bus) & PPB_PS2)
-#define n(flags) (~(flags) & (flags))
-
-/*
- * Parallel Port Chipset control bits.
- */
-#define STROBE 0x01
-#define AUTOFEED 0x02
-#define nINIT 0x04
-#define SELECTIN 0x08
-#define IRQENABLE 0x10
-#define PCD 0x20
-
-#define nSTROBE n(STROBE)
-#define nAUTOFEED n(AUTOFEED)
-#define INIT n(nINIT)
-#define nSELECTIN n(SELECTIN)
-#define nPCD n(PCD)
-
-/*
- * Parallel Port Chipset status bits.
- */
-#define TIMEOUT 0x01
-#define nFAULT 0x08
-#define SELECT 0x10
-#define PERROR 0x20
-#define nACK 0x40
-#define nBUSY 0x80
-
/*
* Structure to store status information.
*/
@@ -199,8 +200,8 @@ struct ppb_device {
struct ppb_xfer
put_xfer[PPB_MAX_XFER];
- struct resource *intr_resource;
- void *intr_cookie;
+ driver_intr_t *intr_hook;
+ void *intr_arg;
};
/* EPP standards */
@@ -209,6 +210,8 @@ struct ppb_device {
/* Parallel Port Chipset IVARS */ /* elsewhere XXX */
#define PPC_IVAR_EPP_PROTO 0
+#define PPC_IVAR_LOCK 1
+#define PPC_IVAR_INTR_HANDLER 2
/*
* Maximum size of the PnP info string
@@ -239,15 +242,26 @@ struct ppb_data {
int mode; /* IEEE 1284-1994 mode
* NIBBLE, PS2, EPP or ECP */
- void *ppb_owner; /* device which owns the bus */
+ device_t ppb_owner; /* device which owns the bus */
+
+ struct mtx *ppc_lock; /* lock of parent device */
+ struct resource *ppc_irq_res;
};
-#ifdef _KERNEL
+struct callout;
+
+typedef int (*ppc_intr_handler)(void *);
+
extern int ppb_attach_device(device_t);
extern int ppb_request_bus(device_t, device_t, int);
extern int ppb_release_bus(device_t, device_t);
/* bus related functions */
+extern void ppb_lock(device_t);
+extern void ppb_unlock(device_t);
+extern void _ppb_assert_locked(device_t, const char *, int);
+extern void ppb_init_callout(device_t, struct callout *, int);
+extern int ppb_sleep(device_t, void *, int, const char *, int);
extern int ppb_get_status(device_t, struct ppb_status *);
extern int ppb_poll_bus(device_t, int, char, char, int);
extern int ppb_reset_epp_timeout(device_t);
@@ -256,12 +270,12 @@ extern int ppb_get_epp_protocol(device_t);
extern int ppb_set_mode(device_t, int); /* returns old mode */
extern int ppb_get_mode(device_t); /* returns current mode */
extern int ppb_write(device_t, char *, int, int);
-#endif /* _KERNEL */
-
-/*
- * These are defined as macros for speedup.
-#define ppb_get_base_addr(dev) ((dev)->ppb->ppb_link->base)
-#define ppb_get_epp_protocol(dev) ((dev)->ppb->ppb_link->epp_protocol)
- */
+#ifdef INVARIANTS
+#define ppb_assert_locked(dev) _ppb_assert_locked(dev, __FILE__, __LINE__)
+#else
+#define ppb_assert_locked(dev)
#endif
+#endif /* _KERNEL */
+
+#endif /* !__PPBCONF_H */
diff --git a/sys/dev/ppbus/ppi.c b/sys/dev/ppbus/ppi.c
index 8c168d8..2ee8fa6 100644
--- a/sys/dev/ppbus/ppi.c
+++ b/sys/dev/ppbus/ppi.c
@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/sx.h>
#include <sys/uio.h>
#include <sys/fcntl.h>
@@ -47,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ppbus/ppb_msq.h>
#ifdef PERIPH_1284
+#include <sys/malloc.h>
#include <dev/ppbus/ppb_1284.h>
#endif
@@ -61,11 +64,10 @@ __FBSDID("$FreeBSD$");
struct ppi_data {
device_t ppi_device;
struct cdev *ppi_cdev;
+ struct sx ppi_lock;
int ppi_flags;
#define HAVE_PPBUS (1<<0)
-#define HAD_PPBUS (1<<1)
- int ppi_count;
int ppi_mode; /* IEEE1284 mode */
char ppi_buffer[BUFSIZE];
@@ -80,6 +82,10 @@ struct ppi_data {
static devclass_t ppi_devclass;
+#ifdef PERIPH_1284
+static void ppiintr(void *arg);
+#endif
+
static d_open_t ppiopen;
static d_close_t ppiclose;
static d_ioctl_t ppiioctl;
@@ -88,7 +94,6 @@ static d_read_t ppiread;
static struct cdevsw ppi_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
.d_open = ppiopen,
.d_close = ppiclose,
.d_read = ppiread,
@@ -160,13 +165,27 @@ ppi_attach(device_t dev)
{
struct ppi_data *ppi = DEVTOSOFTC(dev);
#ifdef PERIPH_1284
- int rid = 0;
+ int error, rid = 0;
/* declare our interrupt handler */
ppi->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
+ if (ppi->intr_resource) {
+ /* register our interrupt handler */
+ error = bus_setup_intr(dev, ppi->intr_resource,
+ INTR_TYPE_TTY | INTR_MPSAFE, NULL, ppiintr, dev,
+ &ppi->intr_cookie);
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ, rid,
+ ppi->intr_resource);
+ device_printf(dev,
+ "Unable to register interrupt handler\n");
+ return (error);
+ }
+ }
#endif /* PERIPH_1284 */
+ sx_init(&ppi->ppi_lock, "ppi");
ppi->ppi_cdev = make_dev(&ppi_cdevsw, device_get_unit(dev),
UID_ROOT, GID_WHEEL,
0600, "ppi%d", device_get_unit(dev));
@@ -180,6 +199,22 @@ ppi_attach(device_t dev)
return (0);
}
+static int
+ppi_detach(device_t dev)
+{
+ struct ppi_data *ppi = DEVTOSOFTC(dev);
+
+ destroy_dev(ppi->ppi_cdev);
+#ifdef PERIPH_1284
+ if (ppi->intr_resource != NULL) {
+ bus_teardown_intr(dev, ppi->intr_resource, ppi->intr_cookie);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, ppi->intr_resource);
+ }
+#endif
+ sx_destroy(&ppi->ppi_lock);
+ return (0);
+}
+
#ifdef PERIPH_1284
/*
* Cable
@@ -200,6 +235,7 @@ ppiintr(void *arg)
device_t ppbus = device_get_parent(ppidev);
struct ppi_data *ppi = DEVTOSOFTC(ppidev);
+ ppb_assert_locked(ppbus);
ppi_disable_intr(ppidev);
switch (ppb_1284_get_state(ppbus)) {
@@ -259,24 +295,20 @@ ppiopen(struct cdev *dev, int flags, int fmt, struct thread *td)
device_t ppbus = device_get_parent(ppidev);
int res;
+ sx_xlock(&ppi->ppi_lock);
if (!(ppi->ppi_flags & HAVE_PPBUS)) {
- if ((res = ppb_request_bus(ppbus, ppidev,
- (flags & O_NONBLOCK) ? PPB_DONTWAIT :
- (PPB_WAIT | PPB_INTR))))
+ ppb_lock(ppbus);
+ res = ppb_request_bus(ppbus, ppidev,
+ (flags & O_NONBLOCK) ? PPB_DONTWAIT : PPB_WAIT | PPB_INTR);
+ ppb_unlock(ppbus);
+ if (res) {
+ sx_xunlock(&ppi->ppi_lock);
return (res);
+ }
ppi->ppi_flags |= HAVE_PPBUS;
-
-#ifdef PERIPH_1284
- if (ppi->intr_resource) {
- /* register our interrupt handler */
- bus_setup_intr(ppidev, ppi->intr_resource,
- INTR_TYPE_TTY, NULL, ppiintr, dev,
- &ppi->intr_cookie);
- }
-#endif /* PERIPH_1284 */
}
- ppi->ppi_count += 1;
+ sx_xunlock(&ppi->ppi_lock);
return (0);
}
@@ -288,28 +320,28 @@ ppiclose(struct cdev *dev, int flags, int fmt, struct thread *td)
device_t ppidev = ppi->ppi_device;
device_t ppbus = device_get_parent(ppidev);
- ppi->ppi_count --;
- if (!ppi->ppi_count) {
-
+ sx_xlock(&ppi->ppi_lock);
+ ppb_lock(ppbus);
#ifdef PERIPH_1284
- switch (ppb_1284_get_state(ppbus)) {
- case PPB_PERIPHERAL_IDLE:
- ppb_peripheral_terminate(ppbus, 0);
- break;
- case PPB_REVERSE_IDLE:
- case PPB_EPP_IDLE:
- case PPB_ECP_FORWARD_IDLE:
- default:
- ppb_1284_terminate(ppbus);
- break;
- }
+ switch (ppb_1284_get_state(ppbus)) {
+ case PPB_PERIPHERAL_IDLE:
+ ppb_peripheral_terminate(ppbus, 0);
+ break;
+ case PPB_REVERSE_IDLE:
+ case PPB_EPP_IDLE:
+ case PPB_ECP_FORWARD_IDLE:
+ default:
+ ppb_1284_terminate(ppbus);
+ break;
+ }
#endif /* PERIPH_1284 */
- /* unregistration of interrupt forced by release */
- ppb_release_bus(ppbus, ppidev);
+ /* unregistration of interrupt forced by release */
+ ppb_release_bus(ppbus, ppidev);
+ ppb_unlock(ppbus);
- ppi->ppi_flags &= ~HAVE_PPBUS;
- }
+ ppi->ppi_flags &= ~HAVE_PPBUS;
+ sx_xunlock(&ppi->ppi_lock);
return (0);
}
@@ -330,7 +362,11 @@ ppiread(struct cdev *dev, struct uio *uio, int ioflag)
device_t ppidev = ppi->ppi_device;
device_t ppbus = device_get_parent(ppidev);
int len, error = 0;
+ char *buffer;
+ buffer = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
+
+ ppb_lock(ppbus);
switch (ppb_1284_get_state(ppbus)) {
case PPB_PERIPHERAL_IDLE:
ppb_peripheral_terminate(ppbus, 0);
@@ -346,11 +382,14 @@ ppiread(struct cdev *dev, struct uio *uio, int ioflag)
/* XXX Wait 2 seconds to let the remote host some
* time to terminate its interrupt
*/
- tsleep(ppi, PPBPRI, "ppiread", 2*hz);
+ ppb_sleep(ppbus, ppi, PPBPRI, "ppiread", 2 * hz);
if ((error = ppb_1284_negociate(ppbus,
- ppi->ppi_mode = PPB_BYTE, 0)))
+ ppi->ppi_mode = PPB_BYTE, 0))) {
+ ppb_unlock(ppbus);
+ free(buffer, M_DEVBUF);
return (error);
+ }
}
break;
@@ -367,11 +406,11 @@ ppiread(struct cdev *dev, struct uio *uio, int ioflag)
/* read data */
len = 0;
while (uio->uio_resid) {
- if ((error = ppb_1284_read(ppbus, ppi->ppi_mode,
- ppi->ppi_buffer, min(BUFSIZE, uio->uio_resid),
- &len))) {
+ error = ppb_1284_read(ppbus, ppi->ppi_mode,
+ buffer, min(BUFSIZE, uio->uio_resid), &len);
+ ppb_unlock(ppbus);
+ if (error)
goto error;
- }
if (!len)
goto error; /* no more data */
@@ -379,12 +418,14 @@ ppiread(struct cdev *dev, struct uio *uio, int ioflag)
#ifdef DEBUG_1284
printf("d");
#endif
- if ((error = uiomove(ppi->ppi_buffer, len, uio)))
+ if ((error = uiomove(buffer, len, uio)))
goto error;
+ ppb_lock(ppbus);
}
+ ppb_unlock(ppbus);
error:
-
+ free(buffer, M_DEVBUF);
#else /* PERIPH_1284 */
int error = ENODEV;
#endif
@@ -413,6 +454,7 @@ ppiwrite(struct cdev *dev, struct uio *uio, int ioflag)
device_t ppidev = ppi->ppi_device;
device_t ppbus = device_get_parent(ppidev);
int len, error = 0, sent;
+ char *buffer;
#if 0
int ret;
@@ -425,18 +467,26 @@ ppiwrite(struct cdev *dev, struct uio *uio, int ioflag)
MS_RET(0)
};
+ buffer = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
+ ppb_lock(ppbus);
+
/* negotiate ECP mode */
if (ppb_1284_negociate(ppbus, PPB_ECP, 0)) {
printf("ppiwrite: ECP negotiation failed\n");
}
while (!error && (len = min(uio->uio_resid, BUFSIZE))) {
- uiomove(ppi->ppi_buffer, len, uio);
+ ppb_unlock(ppbus);
+ uiomove(buffer, len, uio);
- ppb_MS_init_msq(msq, 2, ADDRESS, ppi->ppi_buffer, LENGTH, len);
+ ppb_MS_init_msq(msq, 2, ADDRESS, buffer, LENGTH, len);
+ ppb_lock(ppbus);
error = ppb_MS_microseq(ppbus, msq, &ret);
}
+#else
+ buffer = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
+ ppb_lock(ppbus);
#endif
/* we have to be peripheral to be able to send data, so
@@ -454,7 +504,7 @@ ppiwrite(struct cdev *dev, struct uio *uio, int ioflag)
ppi_enable_intr(ppidev);
/* sleep until IEEE1284 negotiation starts */
- error = tsleep(ppi, PCATCH | PPBPRI, "ppiwrite", 0);
+ error = ppb_sleep(ppbus, ppi, PCATCH | PPBPRI, "ppiwrite", 0);
switch (error) {
case 0:
@@ -473,9 +523,11 @@ ppiwrite(struct cdev *dev, struct uio *uio, int ioflag)
/* negotiation done, write bytes to master host */
while ((len = min(uio->uio_resid, BUFSIZE)) != 0) {
- uiomove(ppi->ppi_buffer, len, uio);
+ ppb_unlock(ppbus);
+ uiomove(buffer, len, uio);
+ ppb_lock(ppbus);
if ((error = byte_peripheral_write(ppbus,
- ppi->ppi_buffer, len, &sent)))
+ buffer, len, &sent)))
goto error;
#ifdef DEBUG_1284
printf("d");
@@ -483,7 +535,8 @@ ppiwrite(struct cdev *dev, struct uio *uio, int ioflag)
}
error:
-
+ ppb_unlock(ppbus);
+ free(buffer, M_DEVBUF);
#else /* PERIPH_1284 */
int error = ENODEV;
#endif
@@ -500,6 +553,7 @@ ppiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
int error = 0;
u_int8_t *val = (u_int8_t *)data;
+ ppb_lock(ppbus);
switch (cmd) {
case PPIGDATA: /* get data register */
@@ -548,6 +602,7 @@ ppiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
error = ENOTTY;
break;
}
+ ppb_unlock(ppbus);
return (error);
}
@@ -557,6 +612,7 @@ static device_method_t ppi_methods[] = {
DEVMETHOD(device_identify, ppi_identify),
DEVMETHOD(device_probe, ppi_probe),
DEVMETHOD(device_attach, ppi_attach),
+ DEVMETHOD(device_detach, ppi_detach),
{ 0, 0 }
};
diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c
index 606c179..7a360d1 100644
--- a/sys/dev/ppbus/pps.c
+++ b/sys/dev/ppbus/pps.c
@@ -18,9 +18,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/module.h>
+#include <sys/sx.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/timepps.h>
@@ -43,15 +45,15 @@ struct pps_data {
device_t ppsdev;
device_t ppbus;
int busy;
- struct callout_handle timeout;
+ struct callout timeout;
int lastdata;
- struct mtx mtx;
+ struct sx lock;
struct resource *intr_resource; /* interrupt resource */
void *intr_cookie; /* interrupt registration cookie */
};
-static int ppsintr(void *arg);
+static void ppsintr(void *arg);
static void ppshcpoll(void *arg);
#define DEVTOSOFTC(dev) \
@@ -107,18 +109,29 @@ ppsattach(device_t dev)
struct pps_data *sc = DEVTOSOFTC(dev);
device_t ppbus = device_get_parent(dev);
struct cdev *d;
- int i, unit, rid = 0;
-
- mtx_init(&sc->mtx, device_get_nameunit(dev), "pps", MTX_SPIN);
+ int error, i, unit, rid = 0;
/* declare our interrupt handler */
sc->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE);
/* interrupts seem mandatory */
- if (sc->intr_resource == NULL)
+ if (sc->intr_resource == NULL) {
+ device_printf(dev, "Unable to allocate interrupt resource\n");
return (ENXIO);
+ }
+
+ error = bus_setup_intr(dev, sc->intr_resource,
+ INTR_TYPE_TTY | INTR_MPSAFE, NULL, ppsintr,
+ sc, &sc->intr_cookie);
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->intr_resource);
+ device_printf(dev, "Unable to register interrupt handler\n");
+ return (error);
+ }
+ sx_init(&sc->lock, "pps");
+ ppb_init_callout(ppbus, &sc->timeout, 0);
sc->ppsdev = dev;
sc->ppbus = ppbus;
unit = device_get_unit(ppbus);
@@ -130,8 +143,11 @@ ppsattach(device_t dev)
d->si_drv2 = (void*)0;
pps_init(&sc->pps[0]);
- if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT))
+ ppb_lock(ppbus);
+ if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
+ ppb_unlock(ppbus);
return (0);
+ }
do {
i = ppb_set_mode(sc->ppbus, PPB_EPP);
@@ -168,6 +184,7 @@ ppsattach(device_t dev)
ppstry(ppbus, 0x55, 0xff);
ppstry(ppbus, 0xaa, 0xff);
ppstry(ppbus, 0xff, 0xff);
+ ppb_unlock(ppbus);
for (i = 1; i < 9; i++) {
d = make_dev(&pps_cdevsw, unit + 0x10000 * i,
@@ -178,9 +195,11 @@ ppsattach(device_t dev)
d->si_drv2 = (void *)(intptr_t)i;
pps_init(&sc->pps[i]);
}
+ ppb_lock(ppbus);
} while (0);
i = ppb_set_mode(sc->ppbus, PPB_COMPATIBLE);
ppb_release_bus(ppbus, dev);
+ ppb_unlock(ppbus);
return (0);
}
@@ -189,22 +208,24 @@ static int
ppsopen(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct pps_data *sc = dev->si_drv1;
+ device_t ppbus = sc->ppbus;
int subdev = (intptr_t)dev->si_drv2;
- int error, i;
+ int i;
+ /*
+ * The sx lock is here solely to serialize open()'s to close
+ * the race of concurrent open()'s when pps(4) doesn't own the
+ * ppbus.
+ */
+ sx_xlock(&sc->lock);
+ ppb_lock(ppbus);
if (!sc->busy) {
device_t ppsdev = sc->ppsdev;
- device_t ppbus = sc->ppbus;
- if (ppb_request_bus(ppbus, ppsdev, PPB_WAIT|PPB_INTR))
+ if (ppb_request_bus(ppbus, ppsdev, PPB_WAIT|PPB_INTR)) {
+ ppb_unlock(ppbus);
+ sx_xunlock(&sc->lock);
return (EINTR);
-
- /* attach the interrupt handler */
- if ((error = bus_setup_intr(ppsdev, sc->intr_resource,
- (INTR_TYPE_TTY | INTR_MPSAFE), ppsintr, NULL,
- sc, &sc->intr_cookie))) {
- ppb_release_bus(ppbus, ppsdev);
- return (error);
}
i = ppb_set_mode(sc->ppbus, PPB_PS2);
@@ -214,10 +235,13 @@ ppsopen(struct cdev *dev, int flags, int fmt, struct thread *td)
ppb_wctr(ppbus, i);
}
if (subdev > 0 && !(sc->busy & ~1)) {
- sc->timeout = timeout(ppshcpoll, sc, 1);
+ /* XXX: Timeout of 1? hz/100 instead perhaps? */
+ callout_reset(&sc->timeout, 1, ppshcpoll, sc);
sc->lastdata = ppb_rdtr(sc->ppbus);
}
sc->busy |= (1 << subdev);
+ ppb_unlock(ppbus);
+ sx_xunlock(&sc->lock);
return(0);
}
@@ -227,10 +251,12 @@ ppsclose(struct cdev *dev, int flags, int fmt, struct thread *td)
struct pps_data *sc = dev->si_drv1;
int subdev = (intptr_t)dev->si_drv2;
+ sx_xlock(&sc->lock);
sc->pps[subdev].ppsparam.mode = 0; /* PHK ??? */
+ ppb_lock(sc->ppbus);
sc->busy &= ~(1 << subdev);
if (subdev > 0 && !(sc->busy & ~1))
- untimeout(ppshcpoll, sc, sc->timeout);
+ callout_stop(&sc->timeout);
if (!sc->busy) {
device_t ppsdev = sc->ppsdev;
device_t ppbus = sc->ppbus;
@@ -238,10 +264,11 @@ ppsclose(struct cdev *dev, int flags, int fmt, struct thread *td)
ppb_wdtr(ppbus, 0);
ppb_wctr(ppbus, 0);
- /* Note: the interrupt handler is automatically detached */
ppb_set_mode(ppbus, PPB_COMPATIBLE);
ppb_release_bus(ppbus, ppsdev);
}
+ ppb_unlock(sc->ppbus);
+ sx_xunlock(&sc->lock);
return(0);
}
@@ -251,10 +278,7 @@ ppshcpoll(void *arg)
struct pps_data *sc = arg;
int i, j, k, l;
- if (!(sc->busy & ~1))
- return;
- mtx_lock_spin(&sc->mtx);
- sc->timeout = timeout(ppshcpoll, sc, 1);
+ KASSERT(sc->busy & ~1, ("pps polling w/o opened devices"));
i = ppb_rdtr(sc->ppbus);
if (i == sc->lastdata)
return;
@@ -269,25 +293,24 @@ ppshcpoll(void *arg)
k += k;
}
sc->lastdata = i;
- mtx_unlock_spin(&sc->mtx);
+ callout_reset(&sc->timeout, 1, ppshcpoll, sc);
}
-static int
+static void
ppsintr(void *arg)
{
struct pps_data *sc = (struct pps_data *)arg;
+ ppb_assert_locked(sc->ppbus);
pps_capture(&sc->pps[0]);
if (!(ppb_rstr(sc->ppbus) & nACK))
- return (FILTER_STRAY);
+ return;
+
if (sc->pps[0].ppsparam.mode & PPS_ECHOASSERT)
ppb_wctr(sc->ppbus, IRQENABLE | AUTOFEED);
- mtx_lock_spin(&sc->mtx);
pps_event(&sc->pps[0], PPS_CAPTUREASSERT);
- mtx_unlock_spin(&sc->mtx);
if (sc->pps[0].ppsparam.mode & PPS_ECHOASSERT)
ppb_wctr(sc->ppbus, IRQENABLE);
- return (FILTER_HANDLED);
}
static int
@@ -297,9 +320,9 @@ ppsioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
int subdev = (intptr_t)dev->si_drv2;
int err;
- mtx_lock_spin(&sc->mtx);
+ ppb_lock(sc->ppbus);
err = pps_ioctl(cmd, data, &sc->pps[subdev]);
- mtx_unlock_spin(&sc->mtx);
+ ppb_unlock(sc->ppbus);
return (err);
}
diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c
index d0a8241..f63ff49 100644
--- a/sys/dev/ppbus/vpo.c
+++ b/sys/dev/ppbus/vpo.c
@@ -104,6 +104,7 @@ vpo_identify(driver_t *driver, device_t parent)
static int
vpo_probe(device_t dev)
{
+ device_t ppbus = device_get_parent(dev);
struct vpo_data *vpo;
int error;
@@ -112,6 +113,7 @@ vpo_probe(device_t dev)
/* check ZIP before ZIP+ or imm_probe() will send controls to
* the printer or whatelse connected to the port */
+ ppb_lock(ppbus);
if ((error = vpoio_probe(dev, &vpo->vpo_io)) == 0) {
vpo->vpo_isplus = 0;
device_set_desc(dev,
@@ -121,8 +123,10 @@ vpo_probe(device_t dev)
device_set_desc(dev,
"Iomega Matchmaker Parallel to SCSI interface");
} else {
+ ppb_unlock(ppbus);
return (error);
}
+ ppb_unlock(ppbus);
return (0);
}
@@ -134,6 +138,8 @@ static int
vpo_attach(device_t dev)
{
struct vpo_data *vpo = DEVTOSOFTC(dev);
+ device_t ppbus = device_get_parent(dev);
+ struct ppb_data *ppb = device_get_softc(ppbus); /* XXX: layering */
struct cam_devq *devq;
int error;
@@ -156,17 +162,20 @@ vpo_attach(device_t dev)
return (ENXIO);
vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo,
- device_get_unit(dev), &Giant,
+ device_get_unit(dev), ppb->ppc_lock,
/*untagged*/1, /*tagged*/0, devq);
if (vpo->sim == NULL) {
cam_simq_free(devq);
return (ENXIO);
}
+ ppb_lock(ppbus);
if (xpt_bus_register(vpo->sim, dev, /*bus*/0) != CAM_SUCCESS) {
cam_sim_free(vpo->sim, /*free_devq*/TRUE);
+ ppb_unlock(ppbus);
return (ENXIO);
}
+ ppb_unlock(ppbus);
/* all went ok */
@@ -211,13 +220,10 @@ static void
vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio)
{
int errno; /* error in errno.h */
- int s;
#ifdef VP0_DEBUG
int i;
#endif
- s = splcam();
-
if (vpo->vpo_isplus) {
errno = imm_do_scsi(&vpo->vpo_io, VP0_INITIATOR,
csio->ccb_h.target_id,
@@ -246,7 +252,7 @@ vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio)
if (errno) {
/* connection to ppbus interrupted */
csio->ccb_h.status = CAM_CMD_TIMEOUT;
- goto error;
+ return;
}
/* if a timeout occured, no sense */
@@ -256,7 +262,7 @@ vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio)
vpo->vpo_error);
csio->ccb_h.status = CAM_CMD_TIMEOUT;
- goto error;
+ return;
}
/* check scsi status */
@@ -317,24 +323,22 @@ vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio)
csio->ccb_h.status = CAM_SCSI_STATUS_ERROR;
}
- goto error;
+ return;
}
csio->resid = csio->dxfer_len - vpo->vpo_count;
csio->ccb_h.status = CAM_REQ_CMP;
-
-error:
- splx(s);
-
- return;
}
static void
vpo_action(struct cam_sim *sim, union ccb *ccb)
{
-
struct vpo_data *vpo = (struct vpo_data *)sim->softc;
+#ifdef INVARIANTS
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
+ ppb_assert_locked(ppbus);
+#endif
switch (ccb->ccb_h.func_code) {
case XPT_SCSI_IO:
{
diff --git a/sys/dev/ppbus/vpoio.c b/sys/dev/ppbus/vpoio.c
index 7d8354a..62af869 100644
--- a/sys/dev/ppbus/vpoio.c
+++ b/sys/dev/ppbus/vpoio.c
@@ -609,6 +609,7 @@ vpoio_attach(struct vpoio_data *vpo)
/*
* Initialize mode dependent in/out microsequences
*/
+ ppb_lock(ppbus);
if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT)))
goto error;
@@ -636,6 +637,7 @@ vpoio_attach(struct vpoio_data *vpo)
ppb_release_bus(ppbus, vpo->vpo_dev);
error:
+ ppb_unlock(ppbus);
return (error);
}
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index b318932..1322a33 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -34,9 +34,11 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/interrupt.h>
#include <sys/module.h>
#include <sys/malloc.h>
+#include <sys/mutex.h>
#include <sys/proc.h>
#include <machine/bus.h>
@@ -113,29 +115,30 @@ static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
/*
* ppc_ecp_sync() XXX
*/
-void
+int
ppc_ecp_sync(device_t dev)
{
int i, r;
struct ppc_data *ppc = DEVTOSOFTC(dev);
+ PPC_ASSERT_LOCKED(ppc);
if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP))
- return;
+ return 0;
r = r_ecr(ppc);
if ((r & 0xe0) != PPC_ECR_EPP)
- return;
+ return 0;
for (i = 0; i < 100; i++) {
r = r_ecr(ppc);
if (r & 0x1)
- return;
+ return 0;
DELAY(100);
}
device_printf(dev, "ECP sync failed as data still present in FIFO.\n");
- return;
+ return 0;
}
/*
@@ -474,7 +477,7 @@ ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never for
/* First try to change the port address to that requested... */
- switch(ppc->ppc_base) {
+ switch (ppc->ppc_base) {
case 0x378:
val &= 0xfc;
break;
@@ -1320,6 +1323,7 @@ ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
#define INCR_PC (mi ++) /* increment program counter */
+ PPC_ASSERT_LOCKED(ppc);
mi = *p_msq;
for (;;) {
switch (mi->opcode) {
@@ -1388,8 +1392,11 @@ ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
break;
case MS_OP_ADELAY:
- if (mi->arg[0].i)
+ if (mi->arg[0].i) {
+ PPC_UNLOCK(ppc);
pause("ppbdelay", mi->arg[0].i * (hz/1000));
+ PPC_LOCK(ppc);
+ }
INCR_PC;
break;
@@ -1521,8 +1528,10 @@ ppcintr(void *arg)
* XXX: If DMA is in progress should we just complete that w/o
* doing this?
*/
- if (ppc->ppc_child_handlers > 0) {
- intr_event_execute_handlers(curproc, ppc->ppc_intr_event);
+ PPC_LOCK(ppc);
+ if (ppc->ppc_intr_hook != NULL &&
+ ppc->ppc_intr_hook(ppc->ppc_intr_arg) == 0) {
+ PPC_UNLOCK(ppc);
return;
}
@@ -1536,6 +1545,7 @@ ppcintr(void *arg)
/* don't use ecp mode with IRQENABLE set */
if (ctr & IRQENABLE) {
+ PPC_UNLOCK(ppc);
return;
}
@@ -1550,6 +1560,7 @@ ppcintr(void *arg)
ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
} else {
/* shall be handled by underlying layers XXX */
+ PPC_UNLOCK(ppc);
return;
}
}
@@ -1585,6 +1596,7 @@ ppcintr(void *arg)
/* classic interrupt I/O */
ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
}
+ PPC_UNLOCK(ppc);
return;
}
@@ -1601,14 +1613,15 @@ ppc_write(device_t dev, char *buf, int len, int how)
return (EINVAL);
}
-void
+int
ppc_reset_epp(device_t dev)
{
struct ppc_data *ppc = DEVTOSOFTC(dev);
+ PPC_ASSERT_LOCKED(ppc);
ppc_reset_epp_timeout(ppc);
- return;
+ return 0;
}
int
@@ -1616,6 +1629,7 @@ ppc_setmode(device_t dev, int mode)
{
struct ppc_data *ppc = DEVTOSOFTC(dev);
+ PPC_ASSERT_LOCKED(ppc);
switch (ppc->ppc_type) {
case PPC_TYPE_SMCLIKE:
return (ppc_smclike_setmode(ppc, mode));
@@ -1796,9 +1810,10 @@ int
ppc_attach(device_t dev)
{
struct ppc_data *ppc = DEVTOSOFTC(dev);
- device_t ppbus;
int error;
+ mtx_init(&ppc->ppc_lock, device_get_nameunit(dev), "ppc", MTX_DEF);
+
device_printf(dev, "%s chipset (%s) in %s mode%s\n",
ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
@@ -1809,36 +1824,25 @@ ppc_attach(device_t dev)
ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
if (ppc->res_irq) {
- /*
- * Create an interrupt event to manage the handlers of
- * child devices.
- */
- error = intr_event_create(&ppc->ppc_intr_event, ppc, 0, -1,
- NULL, NULL, NULL, NULL, "%s:", device_get_nameunit(dev));
- if (error) {
- device_printf(dev,
- "failed to create interrupt event: %d\n", error);
- return (error);
- }
-
/* default to the tty mask for registration */ /* XXX */
- error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY,
- NULL, ppcintr, ppc, &ppc->intr_cookie);
+ error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY |
+ INTR_MPSAFE, NULL, ppcintr, ppc, &ppc->intr_cookie);
if (error) {
device_printf(dev,
"failed to register interrupt handler: %d\n",
error);
+ mtx_destroy(&ppc->ppc_lock);
return (error);
}
}
/* add ppbus as a child of this isa to parallel bridge */
- ppbus = device_add_child(dev, "ppbus", -1);
+ ppc->ppbus = device_add_child(dev, "ppbus", -1);
/*
* Probe the ppbus and attach devices found.
*/
- device_probe_and_attach(ppbus);
+ device_probe_and_attach(ppc->ppbus);
return (0);
}
@@ -1876,6 +1880,8 @@ ppc_detach(device_t dev)
ppc->res_drq);
}
+ mtx_destroy(&ppc->ppc_lock);
+
return (0);
}
@@ -1884,6 +1890,7 @@ ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
{
struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
+ PPC_ASSERT_LOCKED(ppc);
switch (iop) {
case PPB_OUTSB_EPP:
bus_write_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt);
@@ -1953,8 +1960,38 @@ ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
switch (index) {
case PPC_IVAR_EPP_PROTO:
+ PPC_ASSERT_LOCKED(ppc);
*val = (u_long)ppc->ppc_epp;
break;
+ case PPC_IVAR_LOCK:
+ *val = (uintptr_t)&ppc->ppc_lock;
+ break;
+ default:
+ return (ENOENT);
+ }
+
+ return (0);
+}
+
+int
+ppc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
+{
+ struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
+
+ switch (index) {
+ case PPC_IVAR_INTR_HANDLER:
+ PPC_ASSERT_LOCKED(ppc);
+ if (dev != ppc->ppbus)
+ return (EINVAL);
+ if (val == 0) {
+ ppc->ppc_intr_hook = NULL;
+ break;
+ }
+ if (ppc->ppc_intr_hook != NULL)
+ return (EBUSY);
+ ppc->ppc_intr_hook = (void *)val;
+ ppc->ppc_intr_arg = device_get_softc(dev);
+ break;
default:
return (ENOENT);
}
@@ -2001,47 +2038,4 @@ ppc_release_resource(device_t bus, device_t child, int type, int rid,
return (EINVAL);
}
-/*
- * If a child wants to add a handler for our IRQ, add it to our interrupt
- * event. Otherwise, fail the request.
- */
-int
-ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
- driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep)
-{
- struct ppc_data *ppc = DEVTOSOFTC(bus);
- int error;
-
- if (r != ppc->res_irq)
- return (EINVAL);
-
- /* We don't allow filters. */
- if (filt != NULL)
- return (EINVAL);
-
- error = intr_event_add_handler(ppc->ppc_intr_event,
- device_get_nameunit(child), NULL, ihand, arg, intr_priority(flags),
- flags, cookiep);
- if (error == 0)
- ppc->ppc_child_handlers++;
- return (error);
-}
-
-int
-ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie)
-{
- struct ppc_data *ppc = DEVTOSOFTC(bus);
- int error;
-
- if (r != ppc->res_irq)
- return (EINVAL);
-
- KASSERT(intr_handler_source(cookie) == ppc,
- ("ppc_teardown_intr: source mismatch"));
- error = intr_event_remove_handler(cookie);
- if (error == 0)
- ppc->ppc_child_handlers--;
- return (error);
-}
-
MODULE_DEPEND(ppc, ppbus, 1, 1, 1);
diff --git a/sys/dev/ppc/ppc_acpi.c b/sys/dev/ppc/ppc_acpi.c
index 032f196..b0a30b4 100644
--- a/sys/dev/ppc/ppc_acpi.c
+++ b/sys/dev/ppc/ppc_acpi.c
@@ -63,8 +63,7 @@ static device_method_t ppc_acpi_methods[] = {
/* bus interface */
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
- DEVMETHOD(bus_setup_intr, ppc_setup_intr),
- DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
+ DEVMETHOD(bus_write_ivar, ppc_write_ivar),
DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
DEVMETHOD(bus_release_resource, ppc_release_resource),
diff --git a/sys/dev/ppc/ppc_isa.c b/sys/dev/ppc/ppc_isa.c
index 5ac6990..14424a3 100644
--- a/sys/dev/ppc/ppc_isa.c
+++ b/sys/dev/ppc/ppc_isa.c
@@ -32,7 +32,9 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/malloc.h>
@@ -56,12 +58,11 @@ static device_method_t ppc_isa_methods[] = {
/* device interface */
DEVMETHOD(device_probe, ppc_isa_probe),
DEVMETHOD(device_attach, ppc_isa_attach),
- DEVMETHOD(device_detach, ppc_attach),
+ DEVMETHOD(device_detach, ppc_detach),
/* bus interface */
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
- DEVMETHOD(bus_setup_intr, ppc_setup_intr),
- DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
+ DEVMETHOD(bus_write_ivar, ppc_write_ivar),
DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
DEVMETHOD(bus_release_resource, ppc_release_resource),
@@ -143,6 +144,7 @@ ppc_isa_write(device_t dev, char *buf, int len, int how)
int s, error = 0;
int spin;
+ PPC_ASSERT_LOCKED(ppc);
if (!(ppc->ppc_avm & PPB_ECP))
return (EINVAL);
if (ppc->ppc_dmachan == 0)
@@ -215,7 +217,8 @@ ppc_isa_write(device_t dev, char *buf, int len, int how)
*/
do {
/* release CPU */
- error = tsleep(ppc, PPBPRI | PCATCH, "ppcdma", 0);
+ error = mtx_sleep(ppc, &ppc->ppc_lock, PPBPRI | PCATCH,
+ "ppcdma", 0);
} while (error == EWOULDBLOCK);
splx(s);
@@ -244,7 +247,8 @@ ppc_isa_write(device_t dev, char *buf, int len, int how)
#ifdef PPC_DEBUG
printf("Z");
#endif
- error = tsleep(ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
+ error = mtx_sleep(ppc, &ppc->ppc_lock, PPBPRI | PCATCH,
+ "ppcfifo", hz / 100);
if (error != EWOULDBLOCK) {
#ifdef PPC_DEBUG
printf("I");
diff --git a/sys/dev/ppc/ppc_pci.c b/sys/dev/ppc/ppc_pci.c
index a64a3fd..991de1f 100644
--- a/sys/dev/ppc/ppc_pci.c
+++ b/sys/dev/ppc/ppc_pci.c
@@ -53,8 +53,7 @@ static device_method_t ppc_pci_methods[] = {
/* bus interface */
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
- DEVMETHOD(bus_setup_intr, ppc_setup_intr),
- DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
+ DEVMETHOD(bus_write_ivar, ppc_write_ivar),
DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
DEVMETHOD(bus_release_resource, ppc_release_resource),
diff --git a/sys/dev/ppc/ppc_puc.c b/sys/dev/ppc/ppc_puc.c
index 0aec89c..361d9b7 100644
--- a/sys/dev/ppc/ppc_puc.c
+++ b/sys/dev/ppc/ppc_puc.c
@@ -55,8 +55,7 @@ static device_method_t ppc_puc_methods[] = {
/* bus interface */
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
- DEVMETHOD(bus_setup_intr, ppc_setup_intr),
- DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
+ DEVMETHOD(bus_write_ivar, ppc_write_ivar),
DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
DEVMETHOD(bus_release_resource, ppc_release_resource),
diff --git a/sys/dev/ppc/ppcreg.h b/sys/dev/ppc/ppcreg.h
index 0e69dd9..a729503 100644
--- a/sys/dev/ppc/ppcreg.h
+++ b/sys/dev/ppc/ppcreg.h
@@ -29,6 +29,9 @@
#ifndef __PPCREG_H
#define __PPCREG_H
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+
/*
* Parallel Port Chipset type.
*/
@@ -108,10 +111,16 @@ struct ppc_data {
void *intr_cookie;
- struct intr_event *ppc_intr_event;
- int ppc_child_handlers;
+ ppc_intr_handler ppc_intr_hook;
+ void *ppc_intr_arg;
+
+ struct mtx ppc_lock;
};
+#define PPC_LOCK(data) mtx_lock(&(data)->ppc_lock)
+#define PPC_UNLOCK(data) mtx_unlock(&(data)->ppc_lock)
+#define PPC_ASSERT_LOCKED(data) mtx_assert(&(data)->ppc_lock, MA_OWNED)
+
/*
* Parallel Port Chipset registers.
*/
diff --git a/sys/dev/ppc/ppcvar.h b/sys/dev/ppc/ppcvar.h
index 18c159f..faff75a 100644
--- a/sys/dev/ppc/ppcvar.h
+++ b/sys/dev/ppc/ppcvar.h
@@ -32,6 +32,7 @@ int ppc_probe(device_t dev, int rid);
int ppc_attach(device_t dev);
int ppc_detach(device_t dev);
int ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val);
+int ppc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val);
int ppc_read(device_t, char *, int, int);
int ppc_write(device_t, char *, int, int);
@@ -39,15 +40,12 @@ int ppc_write(device_t, char *, int, int);
u_char ppc_io(device_t, int, u_char *, int, u_char);
int ppc_exec_microseq(device_t, struct ppb_microseq **);
-int ppc_setup_intr(device_t, device_t, struct resource *, int,
- driver_filter_t *filt, void (*)(void *), void *, void **);
-int ppc_teardown_intr(device_t, device_t, struct resource *, void *);
struct resource *ppc_alloc_resource(device_t bus, device_t child, int type,
int *rid, u_long start, u_long end, u_long count, u_int flags);
int ppc_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r);
-void ppc_reset_epp(device_t);
-void ppc_ecp_sync(device_t);
+int ppc_reset_epp(device_t);
+int ppc_ecp_sync(device_t);
int ppc_setmode(device_t, int);
extern devclass_t ppc_devclass;
diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c
index a73dcf2..3546439 100644
--- a/sys/dev/puc/pucdata.c
+++ b/sys/dev/puc/pucdata.c
@@ -530,6 +530,12 @@ const struct puc_cfg puc_pci_devices[] = {
PUC_PORT_8S, 0x18, 0, 8,
},
+ { 0x1393, 0x1682, 0xffff, 0,
+ "Moxa Technologies, CP-168EL/PCIe",
+ DEFAULT_RCLK * 8,
+ PUC_PORT_8S, 0x18, 0, 8,
+ },
+
{ 0x13a8, 0x0158, 0xffff, 0,
"Cronyx Omega2-PCI",
DEFAULT_RCLK * 8,
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 21b8251..69fda14 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -199,9 +199,10 @@ static struct rl_hwrev re_hwrevs[] = {
{ RL_HWREV_8169, RL_8169, "8169"},
{ RL_HWREV_8169S, RL_8169, "8169S"},
{ RL_HWREV_8110S, RL_8169, "8110S"},
- { RL_HWREV_8169_8110SB, RL_8169, "8169SB"},
- { RL_HWREV_8169_8110SC, RL_8169, "8169SC"},
- { RL_HWREV_8169_8110SBL, RL_8169, "8169SBL"},
+ { RL_HWREV_8169_8110SB, RL_8169, "8169SB/8110SB"},
+ { RL_HWREV_8169_8110SC, RL_8169, "8169SC/8110SC"},
+ { RL_HWREV_8169_8110SBL, RL_8169, "8169SBL/8110SBL"},
+ { RL_HWREV_8169_8110SCE, RL_8169, "8169SC/8110SC"},
{ RL_HWREV_8100, RL_8139, "8100"},
{ RL_HWREV_8101, RL_8139, "8101"},
{ RL_HWREV_8100E, RL_8169, "8100E"},
@@ -266,7 +267,7 @@ static int re_miibus_readreg (device_t, int, int);
static int re_miibus_writereg (device_t, int, int, int);
static void re_miibus_statchg (device_t);
-static void re_setmulti (struct rl_softc *);
+static void re_set_rxmode (struct rl_softc *);
static void re_reset (struct rl_softc *);
static void re_setwol (struct rl_softc *);
static void re_clrwol (struct rl_softc *);
@@ -418,14 +419,14 @@ re_gmii_readreg(device_t dev, int phy, int reg)
CSR_WRITE_4(sc, RL_PHYAR, reg << 16);
- for (i = 0; i < RL_TIMEOUT; i++) {
+ for (i = 0; i < RL_PHY_TIMEOUT; i++) {
rval = CSR_READ_4(sc, RL_PHYAR);
if (rval & RL_PHYAR_BUSY)
break;
DELAY(100);
}
- if (i == RL_TIMEOUT) {
+ if (i == RL_PHY_TIMEOUT) {
device_printf(sc->rl_dev, "PHY read failed\n");
return (0);
}
@@ -445,14 +446,14 @@ re_gmii_writereg(device_t dev, int phy, int reg, int data)
CSR_WRITE_4(sc, RL_PHYAR, (reg << 16) |
(data & RL_PHYAR_PHYDATA) | RL_PHYAR_BUSY);
- for (i = 0; i < RL_TIMEOUT; i++) {
+ for (i = 0; i < RL_PHY_TIMEOUT; i++) {
rval = CSR_READ_4(sc, RL_PHYAR);
if (!(rval & RL_PHYAR_BUSY))
break;
DELAY(100);
}
- if (i == RL_TIMEOUT) {
+ if (i == RL_PHY_TIMEOUT) {
device_printf(sc->rl_dev, "PHY write failed\n");
return (0);
}
@@ -607,26 +608,23 @@ re_miibus_statchg(device_t dev)
}
/*
- * Program the 64-bit multicast hash filter.
+ * Set the RX configuration and 64-bit multicast hash filter.
*/
static void
-re_setmulti(struct rl_softc *sc)
+re_set_rxmode(struct rl_softc *sc)
{
struct ifnet *ifp;
- int h = 0;
- u_int32_t hashes[2] = { 0, 0 };
struct ifmultiaddr *ifma;
- u_int32_t rxfilt;
- int mcnt = 0;
+ uint32_t hashes[2] = { 0, 0 };
+ uint32_t h, rxfilt;
RL_LOCK_ASSERT(sc);
ifp = sc->rl_ifp;
+ rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
- rxfilt = CSR_READ_4(sc, RL_RXCFG);
- rxfilt &= ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_MULTI);
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
+ if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
if (ifp->if_flags & IFF_PROMISC)
rxfilt |= RL_RXCFG_RX_ALLPHYS;
/*
@@ -635,17 +633,10 @@ re_setmulti(struct rl_softc *sc)
* promiscuous mode.
*/
rxfilt |= RL_RXCFG_RX_MULTI;
- CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
- CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF);
- CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF);
- return;
+ hashes[0] = hashes[1] = 0xffffffff;
+ goto done;
}
- /* first, zot all the existing hash bits */
- CSR_WRITE_4(sc, RL_MAR0, 0);
- CSR_WRITE_4(sc, RL_MAR4, 0);
-
- /* now program new ones */
IF_ADDR_LOCK(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
@@ -656,31 +647,29 @@ re_setmulti(struct rl_softc *sc)
hashes[0] |= (1 << h);
else
hashes[1] |= (1 << (h - 32));
- mcnt++;
}
IF_ADDR_UNLOCK(ifp);
- if (mcnt)
+ if (hashes[0] != 0 || hashes[1] != 0) {
+ /*
+ * For some unfathomable reason, RealTek decided to
+ * reverse the order of the multicast hash registers
+ * in the PCI Express parts. This means we have to
+ * write the hash pattern in reverse order for those
+ * devices.
+ */
+ if ((sc->rl_flags & RL_FLAG_PCIE) != 0) {
+ h = bswap32(hashes[0]);
+ hashes[0] = bswap32(hashes[1]);
+ hashes[1] = h;
+ }
rxfilt |= RL_RXCFG_RX_MULTI;
- else
- rxfilt &= ~RL_RXCFG_RX_MULTI;
+ }
+done:
+ CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
+ CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
-
- /*
- * For some unfathomable reason, RealTek decided to reverse
- * the order of the multicast hash registers in the PCI Express
- * parts. This means we have to write the hash pattern in reverse
- * order for those devices.
- */
-
- if ((sc->rl_flags & RL_FLAG_INVMAR) != 0) {
- CSR_WRITE_4(sc, RL_MAR0, bswap32(hashes[1]));
- CSR_WRITE_4(sc, RL_MAR4, bswap32(hashes[0]));
- } else {
- CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
- CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
- }
}
static void
@@ -700,12 +689,10 @@ re_reset(struct rl_softc *sc)
if (i == RL_TIMEOUT)
device_printf(sc->rl_dev, "reset never completed!\n");
- if ((sc->rl_flags & RL_FLAG_PHY8169) != 0)
- CSR_WRITE_1(sc, 0x82, 1);
- if ((sc->rl_flags & RL_FLAG_PHY8110S) != 0) {
+ if ((sc->rl_flags & RL_FLAG_MACRESET) != 0)
CSR_WRITE_1(sc, 0x82, 1);
- re_gmii_writereg(sc->rl_dev, 1, 0x0B, 0);
- }
+ if (sc->rl_hwrev == RL_HWREV_8169S)
+ re_gmii_writereg(sc->rl_dev, 1, 0x0b, 0);
}
#ifdef RE_DIAG
@@ -1221,12 +1208,22 @@ re_attach(device_t dev)
hw_rev = re_hwrevs;
hwrev = CSR_READ_4(sc, RL_TXCFG);
- device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000);
+ switch (hwrev & 0x70000000) {
+ case 0x00000000:
+ case 0x10000000:
+ device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0xfc800000);
+ hwrev &= (RL_TXCFG_HWREV | 0x80000000);
+ break;
+ default:
+ device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000);
+ hwrev &= RL_TXCFG_HWREV;
+ break;
+ }
device_printf(dev, "MAC rev. 0x%08x\n", hwrev & 0x00700000);
- hwrev &= RL_TXCFG_HWREV;
while (hw_rev->rl_desc != NULL) {
if (hw_rev->rl_rev == hwrev) {
sc->rl_type = hw_rev->rl_type;
+ sc->rl_hwrev = hw_rev->rl_rev;
break;
}
hw_rev++;
@@ -1241,27 +1238,23 @@ re_attach(device_t dev)
case RL_HWREV_8139CPLUS:
sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_FASTETHER;
break;
- case RL_HWREV_8110S:
- sc->rl_flags |= RL_FLAG_PHY8110S;
- break;
case RL_HWREV_8100E:
case RL_HWREV_8101E:
- sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR |
- RL_FLAG_PHYWAKE | RL_FLAG_FASTETHER;
+ sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_PHYWAKE |
+ RL_FLAG_FASTETHER;
break;
case RL_HWREV_8102E:
case RL_HWREV_8102EL:
- sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR |
- RL_FLAG_PHYWAKE | RL_FLAG_PAR | RL_FLAG_DESCV2 |
- RL_FLAG_MACSTAT | RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP;
+ sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_PHYWAKE |
+ RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
+ RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP;
break;
case RL_HWREV_8168_SPIN1:
case RL_HWREV_8168_SPIN2:
sc->rl_flags |= RL_FLAG_WOLRXENB;
/* FALLTHROUGH */
case RL_HWREV_8168_SPIN3:
- sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE |
- RL_FLAG_MACSTAT;
+ sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_MACSTAT;
break;
case RL_HWREV_8168C_SPIN2:
sc->rl_flags |= RL_FLAG_MACSLEEP;
@@ -1272,9 +1265,8 @@ re_attach(device_t dev)
/* FALLTHROUGH */
case RL_HWREV_8168CP:
case RL_HWREV_8168D:
- sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE |
- RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
- RL_FLAG_CMDSTOP;
+ sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
+ RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP;
/*
* These controllers support jumbo frame but it seems
* that enabling it requires touching additional magic
@@ -1287,14 +1279,16 @@ re_attach(device_t dev)
*/
sc->rl_flags |= RL_FLAG_NOJUMBO;
break;
- case RL_HWREV_8169:
- case RL_HWREV_8169S:
- sc->rl_flags |= RL_FLAG_PHY8169;
- break;
case RL_HWREV_8169_8110SB:
- case RL_HWREV_8169_8110SC:
case RL_HWREV_8169_8110SBL:
- sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHY8169;
+ case RL_HWREV_8169_8110SC:
+ case RL_HWREV_8169_8110SCE:
+ sc->rl_flags |= RL_FLAG_PHYWAKE;
+ /* FALLTHROUGH */
+ case RL_HWREV_8169:
+ case RL_HWREV_8169S:
+ case RL_HWREV_8110S:
+ sc->rl_flags |= RL_FLAG_MACRESET;
break;
default:
break;
@@ -2498,7 +2492,7 @@ re_init_locked(struct rl_softc *sc)
{
struct ifnet *ifp = sc->rl_ifp;
struct mii_data *mii;
- u_int32_t rxcfg = 0;
+ uint32_t reg;
uint16_t cfg;
union {
uint32_t align_dummy;
@@ -2534,6 +2528,17 @@ re_init_locked(struct rl_softc *sc)
} else
cfg |= RL_CPLUSCMD_RXENB | RL_CPLUSCMD_TXENB;
CSR_WRITE_2(sc, RL_CPLUS_CMD, cfg);
+ if (sc->rl_hwrev == RL_HWREV_8169_8110SC ||
+ sc->rl_hwrev == RL_HWREV_8169_8110SCE) {
+ reg = 0x000fff00;
+ if ((CSR_READ_1(sc, RL_CFG2) & RL_CFG2_PCI66MHZ) != 0)
+ reg |= 0x000000ff;
+ if (sc->rl_hwrev == RL_HWREV_8169_8110SCE)
+ reg |= 0x00f00000;
+ CSR_WRITE_4(sc, 0x7c, reg);
+ /* Disable interrupt mitigation. */
+ CSR_WRITE_2(sc, 0xe2, 0);
+ }
/*
* Disable TSO if interface MTU size is greater than MSS
* allowed in controller.
@@ -2583,7 +2588,7 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
/*
- * Set the initial TX and RX configuration.
+ * Set the initial TX configuration.
*/
if (sc->rl_testmode) {
if (sc->rl_type == RL_8169)
@@ -2597,32 +2602,10 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_1(sc, RL_EARLY_TX_THRESH, 16);
- CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG);
-
- /* Set the individual bit to receive frames for this host only. */
- rxcfg = CSR_READ_4(sc, RL_RXCFG);
- rxcfg |= RL_RXCFG_RX_INDIV;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxcfg |= RL_RXCFG_RX_ALLPHYS;
- else
- rxcfg &= ~RL_RXCFG_RX_ALLPHYS;
- CSR_WRITE_4(sc, RL_RXCFG, rxcfg);
-
- /*
- * Set capture broadcast bit to capture broadcast frames.
- */
- if (ifp->if_flags & IFF_BROADCAST)
- rxcfg |= RL_RXCFG_RX_BROAD;
- else
- rxcfg &= ~RL_RXCFG_RX_BROAD;
- CSR_WRITE_4(sc, RL_RXCFG, rxcfg);
-
/*
- * Program the multicast filter, if necessary.
+ * Set the initial RX configuration.
*/
- re_setmulti(sc);
+ re_set_rxmode(sc);
#ifdef DEVICE_POLLING
/*
@@ -2761,7 +2744,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
if (((ifp->if_flags ^ sc->rl_if_flags)
& (IFF_PROMISC | IFF_ALLMULTI)) != 0)
- re_setmulti(sc);
+ re_set_rxmode(sc);
} else
re_init_locked(sc);
} else {
@@ -2774,7 +2757,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
case SIOCADDMULTI:
case SIOCDELMULTI:
RL_LOCK(sc);
- re_setmulti(sc);
+ re_set_rxmode(sc);
RL_UNLOCK(sc);
break;
case SIOCGIFMEDIA:
diff --git a/sys/dev/safe/safe.c b/sys/dev/safe/safe.c
index f3f1243..736b329 100644
--- a/sys/dev/safe/safe.c
+++ b/sys/dev/safe/safe.c
@@ -84,7 +84,7 @@ static int safe_attach(device_t);
static int safe_detach(device_t);
static int safe_suspend(device_t);
static int safe_resume(device_t);
-static void safe_shutdown(device_t);
+static int safe_shutdown(device_t);
static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
static int safe_freesession(device_t, u_int64_t);
@@ -503,12 +503,13 @@ safe_detach(device_t dev)
* Stop all chip i/o so that the kernel's probe routines don't
* get confused by errant DMAs when rebooting.
*/
-static void
+static int
safe_shutdown(device_t dev)
{
#ifdef notyet
safe_stop(device_get_softc(dev));
#endif
+ return (0);
}
/*
diff --git a/sys/dev/scc/scc_if.m b/sys/dev/scc/scc_if.m
index c67e23f..f40f64a 100644
--- a/sys/dev/scc/scc_if.m
+++ b/sys/dev/scc/scc_if.m
@@ -66,7 +66,7 @@ METHOD int enabled {
} DEFAULT default_enabled;
# iclear()
-METHOD void iclear {
+METHOD int iclear {
struct scc_softc *this;
struct scc_chan *chan;
};
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c
index 86b6283..bf5fdac 100644
--- a/sys/dev/sdhci/sdhci.c
+++ b/sys/dev/sdhci/sdhci.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/resource.h>
#include <sys/rman.h>
+#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <dev/pci/pcireg.h>
@@ -151,6 +152,12 @@ struct sdhci_softc {
struct sdhci_slot slots[6];
};
+SYSCTL_NODE(_hw, OID_AUTO, sdhci, CTLFLAG_RD, 0, "sdhci driver");
+
+int sdhci_debug;
+TUNABLE_INT("hw.sdhci.debug", &sdhci_debug);
+SYSCTL_INT(_hw_sdhci, OID_AUTO, debug, CTLFLAG_RW, &sdhci_debug, 0, "Debug level");
+
static inline uint8_t
RD1(struct sdhci_slot *slot, bus_size_t off)
{
@@ -734,7 +741,7 @@ sdhci_attach(device_t dev)
if (sc->quirks & SDHCI_QUIRK_FORCE_DMA)
slot->opt |= SDHCI_HAVE_DMA;
- if (bootverbose) {
+ if (bootverbose || sdhci_debug) {
slot_printf(slot, "%uMHz%s 4bits%s%s%s %s\n",
slot->max_clk / 1000000,
(caps & SDHCI_CAN_DO_HISPD) ? " HS" : "",
@@ -1146,17 +1153,10 @@ sdhci_start(struct sdhci_slot *slot)
return;
}
*/
- if (req->cmd->error) {
- if (bootverbose) {
- slot_printf(slot,
- "Command error %d (opcode %u arg %u flags %u "
- "dlen %u dflags %u)\n",
- req->cmd->error, req->cmd->opcode, req->cmd->arg,
- req->cmd->flags,
- (req->cmd->data)?(u_int)req->cmd->data->len:0,
- (req->cmd->data)?(u_int)req->cmd->data->flags:0);
- }
- } else if (slot->sc->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST) {
+ if (sdhci_debug > 1)
+ slot_printf(slot, "result: %d\n", req->cmd->error);
+ if (!req->cmd->error &&
+ (slot->sc->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) {
sdhci_reset(slot, SDHCI_RESET_CMD);
sdhci_reset(slot, SDHCI_RESET_DATA);
}
@@ -1177,9 +1177,12 @@ sdhci_request(device_t brdev, device_t reqdev, struct mmc_request *req)
SDHCI_UNLOCK(slot);
return (EBUSY);
}
-/* printf("%s cmd op %u arg %u flags %u data %ju\n", __func__,
- req->cmd->opcode, req->cmd->arg, req->cmd->flags,
- (req->cmd->data)?req->cmd->data->len:0); */
+ if (sdhci_debug > 1) {
+ slot_printf(slot, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n",
+ req->cmd->opcode, req->cmd->arg, req->cmd->flags,
+ (req->cmd->data)?(u_int)req->cmd->data->len:0,
+ (req->cmd->data)?req->cmd->data->flags:0);
+ }
slot->req = req;
slot->flags = 0;
sdhci_start(slot);
@@ -1363,23 +1366,23 @@ sdhci_intr(void *arg)
SDHCI_UNLOCK(slot);
continue;
}
-/*
- slot_printf(slot, "got interrupt %x\n", intmask);
-*/
+ if (sdhci_debug > 2)
+ slot_printf(slot, "Interrupt %#x\n", intmask);
+
/* Handle card presence interrupts. */
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
WR4(slot, SDHCI_INT_STATUS, intmask &
(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE));
if (intmask & SDHCI_INT_CARD_REMOVE) {
- if (bootverbose)
+ if (bootverbose || sdhci_debug)
slot_printf(slot, "Card removed\n");
callout_stop(&slot->card_callout);
taskqueue_enqueue(taskqueue_swi_giant,
&slot->card_task);
}
if (intmask & SDHCI_INT_CARD_INSERT) {
- if (bootverbose)
+ if (bootverbose || sdhci_debug)
slot_printf(slot, "Card inserted\n");
callout_reset(&slot->card_callout, hz / 2,
sdhci_card_delay, slot);
diff --git a/sys/dev/si/si.c b/sys/dev/si/si.c
index d7789ee..ded079c 100644
--- a/sys/dev/si/si.c
+++ b/sys/dev/si/si.c
@@ -1549,7 +1549,7 @@ si_command(struct si_port *pp, int cmd, int waitflag)
/* This is very very bad. The card has crashed. */
/* XXX the driver breaks at this point */
if (err == ETIMEDOUT)
- printf("%s: tsleep1 timeout. hi_stat %s, sp_pend %s\n", pp->sp_name, si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend));
+ DPRINT(("%s: tsleep1 timeout. hi_stat %s, sp_pend %s\n", pp->sp_name, si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
splx(oldspl);
return;
}
@@ -1586,7 +1586,7 @@ si_command(struct si_port *pp, int cmd, int waitflag)
if (err) {
DPRINT((pp, DBG_PARAM, "sicmd2 tsleep error: hi_stat (%s) sp_pend (%s)\n", si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
if (err == ETIMEDOUT) {
- printf("%s: tsleep2 timeout. hi_stat %s, sp_pend %s\n", pp->sp_name, si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend));
+ DPRINT(("%s: tsleep2 timeout. hi_stat %s, sp_pend %s\n", pp->sp_name, si_cmdname(ccbp->hi_stat), si_cmdname(pp->sp_pend)));
}
break;
}
diff --git a/sys/dev/smbus/smb.c b/sys/dev/smbus/smb.c
index df3ebe9..579204d 100644
--- a/sys/dev/smbus/smb.c
+++ b/sys/dev/smbus/smb.c
@@ -180,6 +180,10 @@ smbioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
parent = device_get_parent(smbdev);
+ /* Make sure that LSB bit is cleared. */
+ if (s->slave & 0x1)
+ return (EINVAL);
+
/* Allocate the bus. */
if ((error = smbus_request_bus(parent, smbdev,
(flags & O_NONBLOCK) ? SMB_DONTWAIT : (SMB_WAIT | SMB_INTR))))
diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c
index 8d6485c..4a48037 100644
--- a/sys/dev/snp/snp.c
+++ b/sys/dev/snp/snp.c
@@ -127,7 +127,6 @@ snp_open(struct cdev *dev, int flag, int mode, struct thread *td)
/* Allocate per-snoop data. */
ss = malloc(sizeof(struct snp_softc), M_SNP, M_WAITOK|M_ZERO);
- ttyoutq_init(&ss->snp_outq);
cv_init(&ss->snp_outwait, "snp out");
devfs_set_cdevpriv(ss, snp_dtor);
diff --git a/sys/dev/sound/macio/aoa.c b/sys/dev/sound/macio/aoa.c
new file mode 100644
index 0000000..54efe4f
--- /dev/null
+++ b/sys/dev/sound/macio/aoa.c
@@ -0,0 +1,384 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+
+/*
+ * Apple Onboard Audio (AOA).
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/dbdma.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/macio/aoa.h>
+#include "mixer_if.h"
+
+struct aoa_dma {
+ struct mtx mutex;
+ struct resource *reg; /* DBDMA registers */
+ dbdma_channel_t *channel; /* DBDMA channel */
+ bus_dma_tag_t tag; /* bus_dma tag */
+ struct pcm_channel *pcm; /* PCM channel */
+ struct snd_dbuf *buf; /* PCM buffer */
+ u_int slots; /* # of slots */
+ u_int slot; /* current slot */
+ u_int bufsz; /* buffer size */
+ u_int blksz; /* block size */
+ int running;
+};
+
+static void
+aoa_dma_set_program(struct aoa_dma *dma)
+{
+ u_int32_t addr;
+ int i;
+
+ addr = (u_int32_t) sndbuf_getbufaddr(dma->buf);
+ KASSERT(dma->bufsz == sndbuf_getsize(dma->buf), ("bad size"));
+
+ dma->slots = dma->bufsz / dma->blksz;
+
+ for (i = 0; i < dma->slots; ++i) {
+ dbdma_insert_command(dma->channel,
+ i, /* slot */
+ DBDMA_OUTPUT_MORE, /* command */
+ 0, /* stream */
+ addr, /* data */
+ dma->blksz, /* count */
+ DBDMA_ALWAYS, /* interrupt */
+ DBDMA_COND_TRUE, /* branch */
+ DBDMA_NEVER, /* wait */
+ dma->slots + 1 /* branch_slot */
+ );
+
+ addr += dma->blksz;
+ }
+
+ /* Branch back to beginning. */
+ dbdma_insert_branch(dma->channel, dma->slots, 0);
+
+ /* STOP command to branch when S0 is asserted. */
+ dbdma_insert_stop(dma->channel, dma->slots + 1);
+
+ /* Set S0 as the condition to branch to STOP. */
+ dbdma_set_branch_selector(dma->channel, 1 << 0, 1 << 0);
+ dbdma_set_device_status(dma->channel, 1 << 0, 0);
+
+ dbdma_sync_commands(dma->channel, BUS_DMASYNC_PREWRITE);
+}
+
+#define AOA_BUFFER_SIZE 65536
+
+static struct aoa_dma *
+aoa_dma_create(struct aoa_softc *sc)
+{
+ struct aoa_dma *dma;
+ bus_dma_tag_t tag;
+ int err;
+ device_t self;
+
+ self = sc->sc_dev;
+ err = bus_dma_tag_create(bus_get_dma_tag(self),
+ 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ AOA_BUFFER_SIZE, 1, AOA_BUFFER_SIZE, 0, NULL, NULL, &tag);
+ if (err != 0)
+ return (NULL);
+
+ dma = malloc(sizeof(*dma), M_DEVBUF, M_WAITOK | M_ZERO);
+ dma->tag = tag;
+ dma->bufsz = AOA_BUFFER_SIZE;
+ dma->blksz = PAGE_SIZE; /* initial blocksize */
+
+ mtx_init(&dma->mutex, "AOA", NULL, MTX_DEF);
+
+ sc->sc_intrp = dma;
+
+ return (dma);
+}
+
+static void
+aoa_dma_delete(struct aoa_dma *dma)
+{
+ bus_dma_tag_destroy(dma->tag);
+ mtx_destroy(&dma->mutex);
+ free(dma, M_DEVBUF);
+}
+
+static int
+aoa_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksz)
+{
+ struct aoa_dma *dma = data;
+ int err, lz;
+
+ DPRINTF(("aoa_chan_setblocksize: blocksz = %u, dma->blksz = %u\n",
+ blocksz, dma->blksz));
+ KASSERT(!dma->running, ("dma is running"));
+ KASSERT(blocksz > 0, ("bad blocksz"));
+
+ /* Round blocksz down to a power of two... */
+ __asm volatile ("cntlzw %0,%1" : "=r"(lz) : "r"(blocksz));
+ blocksz = 1 << (31 - lz);
+ DPRINTF(("blocksz = %u\n", blocksz));
+
+ /* ...but no more than the buffer. */
+ if (blocksz > dma->bufsz)
+ blocksz = dma->bufsz;
+
+ err = sndbuf_resize(dma->buf, dma->bufsz / blocksz, blocksz);
+ if (err != 0) {
+ DPRINTF(("sndbuf_resize returned %d\n", err));
+ return (0);
+ }
+
+ if (blocksz == dma->blksz)
+ return (dma->blksz);
+
+ /* One slot per block plus branch to 0 plus STOP. */
+ err = dbdma_resize_channel(dma->channel, 2 + dma->bufsz / blocksz);
+ if (err != 0) {
+ DPRINTF(("dbdma_resize_channel returned %d\n", err));
+ return (0);
+ }
+
+ /* Set the new blocksize. */
+ dma->blksz = blocksz;
+ aoa_dma_set_program(dma);
+
+ return (dma->blksz);
+}
+
+static int
+aoa_chan_setformat(kobj_t obj, void *data, u_int32_t format)
+{
+ DPRINTF(("aoa_chan_setformat: format = %u\n", format));
+
+ if (format != (AFMT_STEREO | AFMT_S16_BE))
+ return (EINVAL);
+
+ return (0);
+}
+
+static int
+aoa_chan_setspeed(kobj_t obj, void *data, u_int32_t speed)
+{
+ DPRINTF(("aoa_chan_setspeed: speed = %u\n", speed));
+
+ return (44100);
+}
+
+static int
+aoa_chan_getptr(kobj_t obj, void *data)
+{
+ struct aoa_dma *dma = data;
+
+ if (!dma->running)
+ return (0);
+
+ return (dma->slot * dma->blksz);
+}
+
+static void *
+aoa_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
+ struct pcm_channel *c, int dir)
+{
+ struct aoa_softc *sc = devinfo;
+ struct aoa_dma *dma;
+ int max_slots, err;
+
+ KASSERT(dir == PCMDIR_PLAY, ("bad dir"));
+
+ dma = aoa_dma_create(sc);
+ if (!dma)
+ return (NULL);
+ dma->pcm = c;
+ dma->buf = b;
+ dma->reg = sc->sc_odma;
+
+ /* One slot per block, plus branch to 0 plus STOP. */
+ max_slots = 2 + dma->bufsz / dma->blksz;
+ err = dbdma_allocate_channel(dma->reg, 0, bus_get_dma_tag(sc->sc_dev),
+ max_slots, &dma->channel );
+ if (err != 0) {
+ aoa_dma_delete(dma);
+ return (NULL);
+ }
+
+ if (sndbuf_alloc(dma->buf, dma->tag, 0, dma->bufsz) != 0) {
+ dbdma_free_channel(dma->channel);
+ aoa_dma_delete(dma);
+ return (NULL);
+ }
+
+ aoa_dma_set_program(dma);
+
+ return (dma);
+}
+
+static int
+aoa_chan_trigger(kobj_t obj, void *data, int go)
+{
+ struct aoa_dma *dma = data;
+ int i;
+
+ switch (go) {
+ case PCMTRIG_START:
+
+ /* Start the DMA. */
+ dma->running = 1;
+
+ dma->slot = 0;
+ dbdma_set_current_cmd(dma->channel, dma->slot);
+
+ dbdma_run(dma->channel);
+
+ return (0);
+
+ case PCMTRIG_STOP:
+ case PCMTRIG_ABORT:
+
+ mtx_lock(&dma->mutex);
+
+ dma->running = 0;
+
+ /* Make it branch to the STOP command. */
+ dbdma_set_device_status(dma->channel, 1 << 0, 1 << 0);
+
+ /* XXX should wait for DBDMA_ACTIVE to clear. */
+ DELAY(40000);
+
+ /* Reset the DMA. */
+ dbdma_stop(dma->channel);
+ dbdma_set_device_status(dma->channel, 1 << 0, 0);
+
+ for (i = 0; i < dma->slots; ++i)
+ dbdma_clear_cmd_status(dma->channel, i);
+
+ mtx_unlock(&dma->mutex);
+
+ return (0);
+ }
+
+ return (0);
+}
+
+static int
+aoa_chan_free(kobj_t obj, void *data)
+{
+ struct aoa_dma *dma = data;
+
+ sndbuf_free(dma->buf);
+ dbdma_free_channel(dma->channel);
+ aoa_dma_delete(dma);
+
+ return (0);
+}
+
+void
+aoa_interrupt(void *xsc)
+{
+ struct aoa_softc *sc = xsc;
+ struct aoa_dma *dma;
+
+ if (!(dma = sc->sc_intrp) || !dma->running)
+ return;
+
+ mtx_lock(&dma->mutex);
+
+ while (dbdma_get_cmd_status(dma->channel, dma->slot)) {
+
+ dbdma_clear_cmd_status(dma->channel, dma->slot);
+ dma->slot = (dma->slot + 1) % dma->slots;
+
+ mtx_unlock(&dma->mutex);
+ chn_intr(dma->pcm);
+ mtx_lock(&dma->mutex);
+ }
+
+ mtx_unlock(&dma->mutex);
+}
+
+static u_int32_t sc_fmt[] = {
+ AFMT_S16_BE | AFMT_STEREO,
+ 0
+};
+static struct pcmchan_caps aoa_caps = {44100, 44100, sc_fmt, 0};
+
+static struct pcmchan_caps *
+aoa_chan_getcaps(kobj_t obj, void *data)
+{
+ return (&aoa_caps);
+}
+
+static kobj_method_t aoa_chan_methods[] = {
+ KOBJMETHOD(channel_init, aoa_chan_init),
+ KOBJMETHOD(channel_free, aoa_chan_free),
+ KOBJMETHOD(channel_setformat, aoa_chan_setformat),
+ KOBJMETHOD(channel_setspeed, aoa_chan_setspeed),
+ KOBJMETHOD(channel_setblocksize,aoa_chan_setblocksize),
+ KOBJMETHOD(channel_trigger, aoa_chan_trigger),
+ KOBJMETHOD(channel_getptr, aoa_chan_getptr),
+ KOBJMETHOD(channel_getcaps, aoa_chan_getcaps),
+ { 0, 0 }
+};
+CHANNEL_DECLARE(aoa_chan);
+
+int
+aoa_attach(void *xsc)
+{
+ char status[SND_STATUSLEN];
+ struct aoa_softc *sc;
+ device_t self;
+ int err;
+
+ sc = xsc;
+ self = sc->sc_dev;
+
+ if (pcm_register(self, sc, 1, 0))
+ return (ENXIO);
+
+ err = pcm_getbuffersize(self, AOA_BUFFER_SIZE, AOA_BUFFER_SIZE,
+ AOA_BUFFER_SIZE);
+ DPRINTF(("pcm_getbuffersize returned %d\n", err));
+
+ pcm_addchan(self, PCMDIR_PLAY, &aoa_chan_class, sc);
+
+ snprintf(status, sizeof(status), "at %s", ofw_bus_get_name(self));
+ pcm_setstatus(self, status);
+
+ return (0);
+}
+
diff --git a/sys/dev/sound/macio/aoa.h b/sys/dev/sound/macio/aoa.h
new file mode 100644
index 0000000..285ae51
--- /dev/null
+++ b/sys/dev/sound/macio/aoa.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+
+#ifndef SOUND_AOA_H
+#define SOUND_AOA_H
+
+#ifndef AOA_DEBUG
+#define DPRINTF(x) /* nothing */
+#else
+#define DPRINTF(x) printf x
+#endif
+
+struct aoa_softc {
+ device_t sc_dev;
+ void *sc_intrp;
+ struct resource *sc_odma;
+};
+
+void aoa_interrupt(void *);
+int aoa_attach(void *xsc);
+
+#endif /* SOUND_AOA_H */
+
diff --git a/sys/dev/sound/macio/davbus.c b/sys/dev/sound/macio/davbus.c
new file mode 100644
index 0000000..15909f8
--- /dev/null
+++ b/sys/dev/sound/macio/davbus.c
@@ -0,0 +1,595 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+
+/*
+ * Apple DAVbus audio controller.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/macio/aoa.h>
+#include <dev/sound/macio/davbusreg.h>
+
+#include <machine/intr_machdep.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+
+#include "mixer_if.h"
+
+struct davbus_softc {
+ struct aoa_softc aoa;
+ phandle_t node;
+ phandle_t soundnode;
+ struct resource *reg;
+ struct mtx mutex;
+ int device_id;
+ u_int output_mask;
+ u_int (*read_status)(struct davbus_softc *, u_int);
+ void (*set_outputs)(struct davbus_softc *, u_int);
+};
+
+static int davbus_probe(device_t);
+static int davbus_attach(device_t);
+static void davbus_cint(void *);
+
+static device_method_t pcm_davbus_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, davbus_probe),
+ DEVMETHOD(device_attach, davbus_attach),
+
+ { 0, 0 }
+};
+
+static driver_t pcm_davbus_driver = {
+ "pcm",
+ pcm_davbus_methods,
+ PCM_SOFTC_SIZE
+};
+
+DRIVER_MODULE(pcm_davbus, macio, pcm_davbus_driver, pcm_devclass, 0, 0);
+MODULE_DEPEND(pcm_davbus, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+
+/*****************************************************************************
+ Probe and attachment routines.
+ *****************************************************************************/
+static int
+davbus_probe(device_t self)
+{
+ const char *name;
+
+ name = ofw_bus_get_name(self);
+ if (!name)
+ return (ENXIO);
+
+ if (strcmp(name, "davbus") != 0)
+ return (ENXIO);
+
+ device_set_desc(self, "Apple DAVBus Audio Controller");
+
+ return (0);
+}
+
+/*
+ * Burgundy codec control
+ */
+
+static int burgundy_init(struct snd_mixer *m);
+static int burgundy_uninit(struct snd_mixer *m);
+static int burgundy_reinit(struct snd_mixer *m);
+static void burgundy_write_locked(struct davbus_softc *, u_int, u_int);
+static void burgundy_set_outputs(struct davbus_softc *d, u_int mask);
+static u_int burgundy_read_status(struct davbus_softc *d, u_int status);
+static int burgundy_set(struct snd_mixer *m, unsigned dev, unsigned left,
+ unsigned right);
+static int burgundy_setrecsrc(struct snd_mixer *m, u_int32_t src);
+
+static kobj_method_t burgundy_mixer_methods[] = {
+ KOBJMETHOD(mixer_init, burgundy_init),
+ KOBJMETHOD(mixer_uninit, burgundy_uninit),
+ KOBJMETHOD(mixer_reinit, burgundy_reinit),
+ KOBJMETHOD(mixer_set, burgundy_set),
+ KOBJMETHOD(mixer_setrecsrc, burgundy_setrecsrc),
+ { 0, 0 }
+};
+
+MIXER_DECLARE(burgundy_mixer);
+
+static int
+burgundy_init(struct snd_mixer *m)
+{
+ struct davbus_softc *d;
+
+ d = mix_getdevinfo(m);
+
+ d->read_status = burgundy_read_status;
+ d->set_outputs = burgundy_set_outputs;
+
+ /*
+ * We configure the Burgundy codec as follows:
+ *
+ * o Input subframe 0 is connected to input digital
+ * stream A (ISA).
+ * o Stream A (ISA) is mixed in mixer 2 (MIX2).
+ * o Output of mixer 2 (MIX2) is routed to output sources
+ * OS0 and OS1 which can be converted to analog.
+ *
+ */
+ mtx_lock(&d->mutex);
+
+ burgundy_write_locked(d, 0x16700, 0x40);
+
+ burgundy_write_locked(d, BURGUNDY_MIX0_REG, 0);
+ burgundy_write_locked(d, BURGUNDY_MIX1_REG, 0);
+ burgundy_write_locked(d, BURGUNDY_MIX2_REG, BURGUNDY_MIX_ISA);
+ burgundy_write_locked(d, BURGUNDY_MIX3_REG, 0);
+
+ burgundy_write_locked(d, BURGUNDY_OS_REG, BURGUNDY_OS0_MIX2 |
+ BURGUNDY_OS1_MIX2);
+
+ burgundy_write_locked(d, BURGUNDY_SDIN_REG, BURGUNDY_ISA_SF0);
+
+ /* Set several digital scalers to unity gain. */
+ burgundy_write_locked(d, BURGUNDY_MXS2L_REG, BURGUNDY_MXS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_MXS2R_REG, BURGUNDY_MXS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_OSS0L_REG, BURGUNDY_OSS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_OSS0R_REG, BURGUNDY_OSS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_OSS1L_REG, BURGUNDY_OSS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_OSS1R_REG, BURGUNDY_OSS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_ISSAL_REG, BURGUNDY_ISS_UNITY);
+ burgundy_write_locked(d, BURGUNDY_ISSAR_REG, BURGUNDY_ISS_UNITY);
+
+ burgundy_set_outputs(d, burgundy_read_status(d,
+ bus_read_4(d->reg, DAVBUS_CODEC_STATUS)));
+
+ mtx_unlock(&d->mutex);
+
+ mix_setdevs(m, SOUND_MASK_VOLUME);
+
+ return (0);
+}
+
+static int
+burgundy_uninit(struct snd_mixer *m)
+{
+ return (0);
+}
+
+static int
+burgundy_reinit(struct snd_mixer *m)
+{
+ return (0);
+}
+
+static void
+burgundy_write_locked(struct davbus_softc *d, u_int reg, u_int val)
+{
+ u_int size, addr, offset, data, i;
+
+ size = (reg & 0x00FF0000) >> 16;
+ addr = (reg & 0x0000FF00) >> 8;
+ offset = reg & 0xFF;
+
+ for (i = offset; i < offset + size; ++i) {
+ data = BURGUNDY_CTRL_WRITE | (addr << 12) |
+ ((size + offset - 1) << 10) | (i << 8) | (val & 0xFF);
+ if (i == offset)
+ data |= BURGUNDY_CTRL_RESET;
+
+ bus_write_4(d->reg, DAVBUS_CODEC_CTRL, data);
+
+ while (bus_read_4(d->reg, DAVBUS_CODEC_CTRL) &
+ DAVBUS_CODEC_BUSY)
+ DELAY(1);
+
+ val >>= 8; /* next byte. */
+ }
+}
+
+/* Must be called with d->mutex held. */
+static void
+burgundy_set_outputs(struct davbus_softc *d, u_int mask)
+{
+ u_int x = 0;
+
+ if (mask == d->output_mask)
+ return;
+
+ /*
+ * Bordeaux card wirings:
+ * Port 15: RCA out
+ * Port 16: Minijack out
+ * Port 17: Internal speaker
+ *
+ * B&W G3 wirings:
+ * Port 14: Minijack out
+ * Port 17: Internal speaker
+ */
+
+ DPRINTF(("Enabled outputs:"));
+ if (mask & (1 << 0)) {
+ DPRINTF((" SPEAKER"));
+ x |= BURGUNDY_P17M_EN;
+ }
+ if (mask & (1 << 1)) {
+ DPRINTF((" HEADPHONES"));
+ x |= BURGUNDY_P14L_EN | BURGUNDY_P14R_EN;
+ }
+ DPRINTF(("\n"));
+
+ burgundy_write_locked(d, BURGUNDY_MUTE_REG, x);
+ d->output_mask = mask;
+}
+
+static u_int
+burgundy_read_status(struct davbus_softc *d, u_int status)
+{
+ if (status & 0x4)
+ return (1 << 1);
+ else
+ return (1 << 0);
+}
+
+static int
+burgundy_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+{
+ struct davbus_softc *d;
+ int lval, rval;
+
+ lval = ((100 - left) * 15 / 100) & 0xf;
+ rval = ((100 - right) * 15 / 100) & 0xf;
+ DPRINTF(("volume %d %d\n", lval, rval));
+
+ d = mix_getdevinfo(m);
+
+ switch (dev) {
+ case SOUND_MIXER_VOLUME:
+ mtx_lock(&d->mutex);
+
+ burgundy_write_locked(d, BURGUNDY_OL13_REG, lval);
+ burgundy_write_locked(d, BURGUNDY_OL14_REG, (rval << 4) | lval);
+ burgundy_write_locked(d, BURGUNDY_OL15_REG, (rval << 4) | lval);
+ burgundy_write_locked(d, BURGUNDY_OL16_REG, (rval << 4) | lval);
+ burgundy_write_locked(d, BURGUNDY_OL17_REG, lval);
+
+ mtx_unlock(&d->mutex);
+
+ return (left | (right << 8));
+ }
+
+ return (0);
+}
+
+static int
+burgundy_setrecsrc(struct snd_mixer *m, u_int32_t src)
+{
+ return (0);
+}
+
+/*
+ * Screamer Codec Control
+ */
+
+static int screamer_init(struct snd_mixer *m);
+static int screamer_uninit(struct snd_mixer *m);
+static int screamer_reinit(struct snd_mixer *m);
+static void screamer_write_locked(struct davbus_softc *, u_int, u_int);
+static void screamer_set_outputs(struct davbus_softc *d, u_int mask);
+static u_int screamer_read_status(struct davbus_softc *d, u_int status);
+static int screamer_set(struct snd_mixer *m, unsigned dev, unsigned left,
+ unsigned right);
+static int screamer_setrecsrc(struct snd_mixer *m, u_int32_t src);
+
+static kobj_method_t screamer_mixer_methods[] = {
+ KOBJMETHOD(mixer_init, screamer_init),
+ KOBJMETHOD(mixer_uninit, screamer_uninit),
+ KOBJMETHOD(mixer_reinit, screamer_reinit),
+ KOBJMETHOD(mixer_set, screamer_set),
+ KOBJMETHOD(mixer_setrecsrc, screamer_setrecsrc),
+ { 0, 0 }
+};
+
+MIXER_DECLARE(screamer_mixer);
+
+static int
+screamer_init(struct snd_mixer *m)
+{
+ struct davbus_softc *d;
+
+ d = mix_getdevinfo(m);
+
+ d->read_status = screamer_read_status;
+ d->set_outputs = screamer_set_outputs;
+
+ mtx_lock(&d->mutex);
+
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR0, SCREAMER_INPUT_CD |
+ SCREAMER_DEFAULT_CD_GAIN);
+
+ screamer_set_outputs(d, screamer_read_status(d,
+ bus_read_4(d->reg, DAVBUS_CODEC_STATUS)));
+
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR2, 0);
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR4, 0);
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR5, 0);
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR6, 0);
+
+ mtx_unlock(&d->mutex);
+
+ mix_setdevs(m, SOUND_MASK_VOLUME);
+
+ return (0);
+}
+
+static int
+screamer_uninit(struct snd_mixer *m)
+{
+ return (0);
+}
+
+static int
+screamer_reinit(struct snd_mixer *m)
+{
+ return (0);
+}
+
+
+static void
+screamer_write_locked(struct davbus_softc *d, u_int reg, u_int val)
+{
+ u_int x;
+
+ KASSERT(val == (val & 0xfff), ("bad val"));
+
+ while (bus_read_4(d->reg, DAVBUS_CODEC_CTRL) & DAVBUS_CODEC_BUSY)
+ DELAY(100);
+
+ x = reg;
+ x |= SCREAMER_CODEC_EMSEL0;
+ x |= val;
+ bus_write_4(d->reg, DAVBUS_CODEC_CTRL, x);
+
+ while (bus_read_4(d->reg, DAVBUS_CODEC_CTRL) & DAVBUS_CODEC_BUSY)
+ DELAY(100);
+}
+
+/* Must be called with d->mutex held. */
+static void
+screamer_set_outputs(struct davbus_softc *d, u_int mask)
+{
+ u_int x;
+
+ if (mask == d->output_mask) {
+ return;
+ }
+
+ x = SCREAMER_MUTE_SPEAKER | SCREAMER_MUTE_HEADPHONES;
+
+ DPRINTF(("Enabled outputs: "));
+
+ if (mask & (1 << 0)) {
+ DPRINTF(("SPEAKER "));
+ x &= ~SCREAMER_MUTE_SPEAKER;
+ }
+ if (mask & (1 << 1)) {
+ DPRINTF(("HEADPHONES "));
+ x &= ~SCREAMER_MUTE_HEADPHONES;
+ }
+
+ DPRINTF(("\n"));
+
+ if (d->device_id == 5 || d->device_id == 11) {
+ DPRINTF(("Enabling programmable output.\n"));
+ x |= SCREAMER_PROG_OUTPUT0;
+ }
+ if (d->device_id == 8 || d->device_id == 11) {
+ x &= ~SCREAMER_MUTE_SPEAKER;
+
+ if (mask & (1 << 0))
+ x |= SCREAMER_PROG_OUTPUT1; /* enable speaker. */
+ }
+
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR1, x);
+ d->output_mask = mask;
+}
+
+static u_int
+screamer_read_status(struct davbus_softc *d, u_int status)
+{
+ int headphones;
+
+ switch (d->device_id) {
+ case 5: /* Sawtooth */
+ headphones = (status & 0x4);
+ break;
+
+ case 8:
+ case 11: /* iMac DV */
+ /* The iMac DV has 2 headphone outputs. */
+ headphones = (status & 0x7);
+ break;
+
+ default:
+ headphones = (status & 0x8);
+ }
+
+ if (headphones)
+ return (1 << 1);
+ else
+ return (1 << 0);
+}
+
+static int
+screamer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+{
+ struct davbus_softc *d;
+ int lval, rval;
+
+ lval = ((100 - left) * 15 / 100) & 0xf;
+ rval = ((100 - right) * 15 / 100) & 0xf;
+ DPRINTF(("volume %d %d\n", lval, rval));
+
+ d = mix_getdevinfo(m);
+
+ switch (dev) {
+ case SOUND_MIXER_VOLUME:
+ mtx_lock(&d->mutex);
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR2, (lval << 6) |
+ rval);
+ screamer_write_locked(d, SCREAMER_CODEC_ADDR4, (lval << 6) |
+ rval);
+ mtx_unlock(&d->mutex);
+
+ return (left | (right << 8));
+ }
+
+ return (0);
+}
+
+static int
+screamer_setrecsrc(struct snd_mixer *m, u_int32_t src)
+{
+ return (0);
+}
+
+static int
+davbus_attach(device_t self)
+{
+ struct davbus_softc *sc;
+ struct resource *dbdma_irq, *cintr;
+ void *cookie;
+ char compat[64];
+ int rid, oirq, err;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ sc->aoa.sc_dev = self;
+ sc->node = ofw_bus_get_node(self);
+ sc->soundnode = OF_child(sc->node);
+
+ /* Map the controller register space. */
+ rid = 0;
+ sc->reg = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (sc->reg == NULL)
+ return (ENXIO);
+
+ /* Map the DBDMA channel register space. */
+ rid = 1;
+ sc->aoa.sc_odma = bus_alloc_resource_any(self, SYS_RES_MEMORY,
+ &rid, RF_ACTIVE);
+ if (sc->aoa.sc_odma == NULL)
+ return (ENXIO);
+
+ /* Establish the DBDMA channel edge-triggered interrupt. */
+ rid = 1;
+ dbdma_irq = bus_alloc_resource_any(self, SYS_RES_IRQ,
+ &rid, RF_SHAREABLE | RF_ACTIVE);
+ if (dbdma_irq == NULL)
+ return (ENXIO);
+
+ oirq = rman_get_start(dbdma_irq);
+
+ DPRINTF(("interrupting at irq %d\n", oirq));
+
+ err = powerpc_config_intr(oirq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
+ if (err != 0)
+ return (err);
+
+ snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt,
+ sc, &cookie);
+
+ /* Now initialize the controller. */
+
+ bzero(compat, sizeof(compat));
+ OF_getprop(sc->soundnode, "compatible", compat, sizeof(compat));
+ OF_getprop(sc->soundnode, "device-id", &sc->device_id, sizeof(u_int));
+
+ mtx_init(&sc->mutex, "DAVbus", NULL, MTX_DEF);
+
+ device_printf(self, "codec: <%s>\n", compat);
+
+ /* Setup the control interrupt. */
+ rid = 0;
+ cintr = bus_alloc_resource_any(self, SYS_RES_IRQ,
+ &rid, RF_SHAREABLE | RF_ACTIVE);
+ if (cintr != NULL)
+ bus_setup_intr(self, cintr, INTR_TYPE_MISC | INTR_MPSAFE,
+ NULL, davbus_cint, sc, &cookie);
+
+ /* Initialize controller registers. */
+ bus_write_4(sc->reg, DAVBUS_SOUND_CTRL, DAVBUS_INPUT_SUBFRAME0 |
+ DAVBUS_OUTPUT_SUBFRAME0 | DAVBUS_RATE_44100 | DAVBUS_INTR_PORTCHG);
+
+ /* Attach DBDMA engine and PCM layer */
+ err = aoa_attach(sc);
+ if (err)
+ return (err);
+
+ /* Install codec module */
+ if (strcmp(compat, "screamer") == 0)
+ mixer_init(self, &screamer_mixer_class, sc);
+ else if (strcmp(compat, "burgundy") == 0)
+ mixer_init(self, &burgundy_mixer_class, sc);
+
+ return (0);
+}
+
+static void
+davbus_cint(void *ptr)
+{
+ struct davbus_softc *d = ptr;
+ u_int reg, status, mask;
+
+ mtx_lock(&d->mutex);
+
+ reg = bus_read_4(d->reg, DAVBUS_SOUND_CTRL);
+ if (reg & DAVBUS_PORTCHG) {
+
+ status = bus_read_4(d->reg, DAVBUS_CODEC_STATUS);
+
+ if (d->read_status && d->set_outputs) {
+
+ mask = (*d->read_status)(d, status);
+ (*d->set_outputs)(d, mask);
+ }
+
+ /* Clear the interrupt. */
+ bus_write_4(d->reg, DAVBUS_SOUND_CTRL, reg);
+ }
+
+ mtx_unlock(&d->mutex);
+}
+
diff --git a/sys/dev/sound/macio/davbusreg.h b/sys/dev/sound/macio/davbusreg.h
new file mode 100644
index 0000000..a7ccdf1
--- /dev/null
+++ b/sys/dev/sound/macio/davbusreg.h
@@ -0,0 +1,285 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+
+/*
+ * Apple DAVbus audio controller.
+ */
+
+#ifndef _SOUND_DAVBUS_H
+#define _SOUND_DAVBUS_H
+
+/* DAVbus controller registers. */
+#define DAVBUS_SOUND_CTRL 0x00
+#define DAVBUS_CODEC_CTRL 0x10
+#define DAVBUS_CODEC_STATUS 0x20
+#define DAVBUS_CLIP_COUNT 0x30
+#define DAVBUS_BYTE_SWAP 0x40
+
+/*
+ * The DAVbus uses a serial bus time multiplexed in four subframes,
+ * but the controller itself uses subframe 0 to communicate with the codec.
+ * In some machines, the other subframes may be used by external devices
+ * thorugh the DAV interface.
+ */
+/* DAVBUS_SOUND_CTRL bit definitions. */
+#define DAVBUS_INPUT_SUBFRAME0 0x00000001
+#define DAVBUS_INPUT_SUBFRAME1 0x00000002
+#define DAVBUS_INPUT_SUBFRAME2 0x00000004
+#define DAVBUS_INPUT_SUBFRAME3 0x00000008
+
+#define DAVBUS_OUTPUT_SUBFRAME0 0x00000010
+#define DAVBUS_OUTPUT_SUBFRAME1 0x00000020
+#define DAVBUS_OUTPUT_SUBFRAME2 0x00000040
+#define DAVBUS_OUTPUT_SUBFRAME3 0x00000080
+
+#define DAVBUS_RATE_44100 0x00000000
+#define DAVBUS_RATE_29400 0x00000100
+#define DAVBUS_RATE_22050 0x00000200
+#define DAVBUS_RATE_17640 0x00000300
+#define DAVBUS_RATE_14700 0x00000400
+#define DAVBUS_RATE_11025 0x00000500
+#define DAVBUS_RATE_8820 0x00000600
+#define DAVBUS_RATE_7350 0x00000700
+#define DAVBUS_RATE_MASK 0x00000700
+
+#define DAVBUS_ERROR 0x00000800
+#define DAVBUS_PORTCHG 0x00001000
+#define DAVBUS_INTR_ERROR 0x00002000 /* interrupt on error */
+#define DAVBUS_INTR_PORTCHG 0x00004000 /* interrupt on port change */
+
+#define DAVBUS_STATUS_SUBFRAME 0x00018000 /* mask */
+
+/* DAVBUS_CODEC_CTRL bit definitions. */
+#define DAVBUS_CODEC_BUSY 0x01000000
+
+
+/*
+ * Burgundy Codec Control Bits
+ */
+
+/* Burgundy transaction bits. */
+#define BURGUNDY_CTRL_RESET 0x00100000
+#define BURGUNDY_CTRL_WRITE 0x00200000
+
+/* Mute control for each analog output port. */
+#define BURGUNDY_MUTE_REG 0x16000
+#define BURGUNDY_P13M_EN 0x01
+#define BURGUNDY_P14L_EN 0x02
+#define BURGUNDY_P14R_EN 0x04
+#define BURGUNDY_P15L_EN 0x08
+#define BURGUNDY_P15R_EN 0x10
+#define BURGUNDY_P16L_EN 0x20
+#define BURGUNDY_P16R_EN 0x40
+#define BURGUNDY_P17M_EN 0x80
+
+/* Attenuation of each analog output port. */
+#define BURGUNDY_OL13_REG 0x16100
+#define BURGUNDY_OL14_REG 0x16200
+#define BURGUNDY_OL15_REG 0x16300
+#define BURGUNDY_OL16_REG 0x16400
+#define BURGUNDY_OL17_REG 0x16500
+
+/* Inputs of four digital mixers. */
+#define BURGUNDY_MIX0_REG 0x42900
+#define BURGUNDY_MIX1_REG 0x42A00
+#define BURGUNDY_MIX2_REG 0x42B00
+#define BURGUNDY_MIX3_REG 0x42C00
+#define BURGUNDY_MIX_IS0 0x00010001
+#define BURGUNDY_MIX_IS1 0x00020002
+#define BURGUNDY_MIX_IS2 0x00040004
+#define BURGUNDY_MIX_IS3 0x00080008
+#define BURGUNDY_MIX_IS4 0x00100010
+#define BURGUNDY_MIX_ISA 0x01000100 /* Digital stream ISA. */
+#define BURGUNDY_MIX_ISB 0x02000200 /* Digital stream ISB. */
+#define BURGUNDY_MIX_ISC 0x04000400 /* Digital stream ISC. */
+#define BURGUNDY_MIX_ISD 0x08000800 /* Digital stream ISD. */
+#define BURGUNDY_MIX_ISE 0x10001000 /* Digital stream ISE. */
+#define BURGUNDY_MIX_ISF 0x20002000 /* Digital stream ISF. */
+#define BURGUNDY_MIX_ISG 0x40004000 /* Digital stream ISG. */
+#define BURGUNDY_MIX_ISH 0x80008000 /* Digital stream ISH. */
+
+/* A digital scalar at the output of each mixer. */
+#define BURGUNDY_MXS0L_REG 0x12D00
+#define BURGUNDY_MXS0R_REG 0x12D01
+#define BURGUNDY_MXS1L_REG 0x12D02
+#define BURGUNDY_MXS1R_REG 0x12D03
+#define BURGUNDY_MXS2L_REG 0x12E00
+#define BURGUNDY_MXS2R_REG 0x12E01
+#define BURGUNDY_MXS3L_REG 0x12E02
+#define BURGUNDY_MXS3R_REG 0x12E03
+#define BURGUNDY_MXS_UNITY 0xDF
+
+/* Demultiplexer. Routes the mixer 0-3 (see above) to output sources.
+ Output sources 0-2 can be converted to analog. */
+#define BURGUNDY_OS_REG 0x42F00
+#define BURGUNDY_OS0_MIX0 0x00000000
+#define BURGUNDY_OS0_MIX1 0x00000001
+#define BURGUNDY_OS0_MIX2 0x00000002
+#define BURGUNDY_OS0_MIX3 0x00000003
+#define BURGUNDY_OS1_MIX0 0x00000000
+#define BURGUNDY_OS1_MIX1 0x00000004
+#define BURGUNDY_OS1_MIX2 0x00000008
+#define BURGUNDY_OS1_MIX3 0x0000000C
+#define BURGUNDY_OS2_MIX0 0x00000000
+#define BURGUNDY_OS2_MIX1 0x00000010
+#define BURGUNDY_OS2_MIX2 0x00000020
+#define BURGUNDY_OS2_MIX3 0x00000030
+#define BURGUNDY_OS3_MIX0 0x00000000
+#define BURGUNDY_OS3_MIX1 0x00000040
+#define BURGUNDY_OS3_MIX2 0x00000080
+#define BURGUNDY_OS3_MIX3 0x000000C0
+#define BURGUNDY_OSA_MIX0 0x00000000
+#define BURGUNDY_OSA_MIX1 0x00010000
+#define BURGUNDY_OSA_MIX2 0x00020000
+#define BURGUNDY_OSA_MIX3 0x00030000
+#define BURGUNDY_OSB_MIX0 0x00000000
+#define BURGUNDY_OSB_MIX1 0x00040000
+#define BURGUNDY_OSB_MIX2 0x00080000
+#define BURGUNDY_OSB_MIX3 0x000C0000
+#define BURGUNDY_OSC_MIX0 0x00000000
+#define BURGUNDY_OSC_MIX1 0x00100000
+#define BURGUNDY_OSC_MIX2 0x00200000
+#define BURGUNDY_OSC_MIX3 0x00300000
+#define BURGUNDY_OSD_MIX0 0x00000000
+#define BURGUNDY_OSD_MIX1 0x00400000
+#define BURGUNDY_OSD_MIX2 0x00800000
+#define BURGUNDY_OSD_MIX3 0x00C00000
+#define BURGUNDY_OSE_MIX0 0x00000000
+#define BURGUNDY_OSE_MIX1 0x01000000
+#define BURGUNDY_OSE_MIX2 0x02000000
+#define BURGUNDY_OSE_MIX3 0x03000000
+#define BURGUNDY_OSF_MIX0 0x00000000
+#define BURGUNDY_OSF_MIX1 0x04000000
+#define BURGUNDY_OSF_MIX2 0x08000000
+#define BURGUNDY_OSF_MIX3 0x0C000000
+#define BURGUNDY_OSG_MIX0 0x00000000
+#define BURGUNDY_OSG_MIX1 0x10000000
+#define BURGUNDY_OSG_MIX2 0x20000000
+#define BURGUNDY_OSG_MIX3 0x30000000
+#define BURGUNDY_OSH_MIX0 0x00000000
+#define BURGUNDY_OSH_MIX1 0x40000000
+#define BURGUNDY_OSH_MIX2 0x80000000
+#define BURGUNDY_OSH_MIX3 0xC0000000
+
+/* A digital scalar for output sources 0 to 3. */
+#define BURGUNDY_OSS0L_REG 0x13000
+#define BURGUNDY_OSS0R_REG 0x13001
+#define BURGUNDY_OSS1L_REG 0x13002
+#define BURGUNDY_OSS1R_REG 0x13003
+#define BURGUNDY_OSS2L_REG 0x13100
+#define BURGUNDY_OSS2R_REG 0x13101
+#define BURGUNDY_OSS3L_REG 0x13102
+#define BURGUNDY_OSS3R_REG 0x13103
+#define BURGUNDY_OSS_UNITY 0xDF
+
+/* Digital input streams ISA-ISC. A stream may be derived from data coming
+ from the controller in subframes 0 to 3 as well as from internal
+ output sources OSA-OSD. */
+#define BURGUNDY_SDIN_REG 0x17800
+#define BURGUNDY_ISA_SF0 0x00
+#define BURGUNDY_ISA_OSA 0x02
+#define BURGUNDY_ISB_SF1 0x00
+#define BURGUNDY_ISB_OSB 0x08
+#define BURGUNDY_ISC_SF2 0x00
+#define BURGUNDY_ISC_OSC 0x20
+#define BURGUNDY_ISD_SF3 0x00
+#define BURGUNDY_ISD_OSD 0x80
+
+/* A digital scaler for input streams 0-4 A-H. */
+#define BURGUNDY_ISSAL_REG 0x12500
+#define BURGUNDY_ISSAR_REG 0x12501
+#define BURGUNDY_ISS_UNITY 0xDF
+
+/*
+ * Screamer codec control bits
+ * This codec has the following 12-bit control registers:
+ * cc0 cc1 cc2 cc4 cc5 cc6 cc7
+ */
+
+/* screamer transaction bits. */
+#define SCREAMER_CODEC_ADDR0 0x00000000
+#define SCREAMER_CODEC_ADDR1 0x00001000
+#define SCREAMER_CODEC_ADDR2 0x00002000
+#define SCREAMER_CODEC_ADDR4 0x00004000
+#define SCREAMER_CODEC_ADDR5 0x00005000
+#define SCREAMER_CODEC_ADDR6 0x00006000
+#define SCREAMER_CODEC_ADDR7 0x00007000
+#define SCREAMER_CODEC_EMSEL0 0x00000000
+#define SCREAMER_CODEC_EMSEL1 0x00400000
+#define SCREAMER_CODEC_EMSEL2 0x00800000
+#define SCREAMER_CODEC_EMSEL4 0x00c00000
+
+
+/* cc0 */
+/*
+ * Bits 7-4 specify the left ADC input gain;
+ * bits 3-0 specify the right ADC input gain.
+ *
+ * The gain is a 4-bit value expressed in units of 1.5 dB,
+ * ranging from 0 dB (0) to +22.5 dB (15).
+ */
+#define SCREAMER_DEFAULT_CD_GAIN 0x000000bb /* +16.5 dB */
+#define SCREAMER_INPUT_CD 0x00000200
+#define SCREAMER_INPUT_LINE 0x00000400
+#define SCREAMER_INPUT_MICROPHONE 0x00000800
+#define SCREAMER_INPUT_MASK 0x00000e00
+
+/* cc1 */
+#define SCREAMER_LOOP_THROUGH 0x00000040
+#define SCREAMER_MUTE_SPEAKER 0x00000080
+#define SCREAMER_MUTE_HEADPHONES 0x00000200
+#define SCREAMER_PARALLEL_OUTPUT 0x00000c00
+#define SCREAMER_PROG_OUTPUT0 0x00000400
+#define SCREAMER_PROG_OUTPUT1 0x00000800
+
+/* cc2: headphones/external port attenuation */
+/* cc4: internal speaker attenuation */
+/*
+ * Bits 9-6 specify left DAC output attenuation.
+ * Bits 3-0 specify right DAC output attenuation.
+ *
+ * The attenuation is a 4-bit value expressed in units of -1.5 dB,
+ * ranging from 0 dB (0) to -22.5 dB (15).
+ */
+
+/* screamer codec status bits. */
+#define SCREAMER_STATUS_MASK 0x00FFFFFF
+#define SCREAMER_STATUS_SENSEMASK 0x0000000F
+#define SCREAMER_STATUS_SENSE0 0x00000008
+#define SCREAMER_STATUS_SENSE1 0x00000004
+#define SCREAMER_STATUS_SENSE2 0x00000002
+#define SCREAMER_STATUS_SENSE3 0x00000001
+#define SCREAMER_STATUS_PARTMASK 0x00000300
+#define SCREAMER_STATUS_PARTSHFT 8
+#define SCREAMER_PART_CRYSTAL 0x00000100
+#define SCREAMER_PART_NATIONAL 0x00000200
+#define SCREAMER_PART_TI 0x00000300
+#define SCREAMER_STATUS_REVMASK 0x0000F000
+#define SCREAMER_STATUS_REVSHFT 12
+
+#endif /* _SOUND_DAVBUS_H */
+
diff --git a/sys/dev/sound/macio/i2s.c b/sys/dev/sound/macio/i2s.c
new file mode 100644
index 0000000..11a0826
--- /dev/null
+++ b/sys/dev/sound/macio/i2s.c
@@ -0,0 +1,745 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+/*-
+ * Copyright (c) 2002, 2003 Tsubai Masanari. 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. 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.
+ *
+ * NetBSD: snapper.c,v 1.28 2008/05/16 03:49:54 macallan Exp
+ * Id: snapper.c,v 1.11 2002/10/31 17:42:13 tsubai Exp
+ */
+
+/*
+ * Apple I2S audio controller.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/dbdma.h>
+#include <machine/intr_machdep.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <machine/pio.h>
+#include <sys/rman.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/macio/aoa.h>
+#include <powerpc/powermac/macgpiovar.h>
+
+struct i2s_softc {
+ struct aoa_softc aoa;
+ phandle_t node;
+ phandle_t soundnode;
+ struct resource *reg;
+ u_int output_mask;
+ struct mtx port_mtx;
+};
+
+static int i2s_probe(device_t);
+static int i2s_attach(device_t);
+static void i2s_postattach(void *);
+static int i2s_setup(struct i2s_softc *, u_int, u_int, u_int);
+static void i2s_mute_headphone (struct i2s_softc *, int);
+static void i2s_mute_lineout (struct i2s_softc *, int);
+static void i2s_mute_speaker (struct i2s_softc *, int);
+static void i2s_set_outputs(void *, u_int);
+
+static struct intr_config_hook *i2s_delayed_attach = NULL;
+
+kobj_class_t i2s_mixer_class = NULL;
+device_t i2s_mixer = NULL;
+
+static device_method_t pcm_i2s_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, i2s_probe),
+ DEVMETHOD(device_attach, i2s_attach),
+
+ { 0, 0 }
+};
+
+static driver_t pcm_i2s_driver = {
+ "pcm",
+ pcm_i2s_methods,
+ PCM_SOFTC_SIZE
+};
+
+DRIVER_MODULE(pcm_i2s, macio, pcm_i2s_driver, pcm_devclass, 0, 0);
+MODULE_DEPEND(pcm_i2s, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+
+static int aoagpio_probe(device_t);
+static int aoagpio_attach(device_t);
+
+static device_method_t aoagpio_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, aoagpio_probe),
+ DEVMETHOD(device_attach, aoagpio_attach),
+
+ { 0, 0 }
+};
+
+struct aoagpio_softc {
+ device_t dev;
+ int ctrl;
+ int detect_active; /* for extint-gpio */
+ int level; /* for extint-gpio */
+ struct i2s_softc *i2s; /* for extint-gpio */
+};
+
+static driver_t aoagpio_driver = {
+ "aoagpio",
+ aoagpio_methods,
+ sizeof(struct aoagpio_softc)
+};
+static devclass_t aoagpio_devclass;
+
+DRIVER_MODULE(aoagpio, macgpio, aoagpio_driver, aoagpio_devclass, 0, 0);
+
+
+/*****************************************************************************
+ Probe and attachment routines.
+ *****************************************************************************/
+static int
+i2s_probe(device_t self)
+{
+ const char *name;
+
+ name = ofw_bus_get_name(self);
+ if (!name)
+ return (ENXIO);
+
+ if (strcmp(name, "i2s") != 0)
+ return (ENXIO);
+
+ device_set_desc(self, "Apple I2S Audio Controller");
+
+ return (0);
+}
+
+static phandle_t of_find_firstchild_byname(phandle_t, const char *);
+
+static int
+i2s_attach(device_t self)
+{
+ struct i2s_softc *sc;
+ struct resource *dbdma_irq;
+ void *dbdma_ih;
+ int rid, oirq, err;
+ phandle_t port;
+
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ sc->aoa.sc_dev = self;
+ sc->node = ofw_bus_get_node(self);
+
+ port = of_find_firstchild_byname(sc->node, "i2s-a");
+ if (port == -1)
+ return (ENXIO);
+ sc->soundnode = of_find_firstchild_byname(port, "sound");
+ if (sc->soundnode == -1)
+ return (ENXIO);
+
+ mtx_init(&sc->port_mtx, "port_mtx", NULL, MTX_DEF);
+
+ /* Map the controller register space. */
+ rid = 0;
+ sc->reg = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (sc->reg == NULL)
+ return ENXIO;
+
+ /* Map the DBDMA channel register space. */
+ rid = 1;
+ sc->aoa.sc_odma = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (sc->aoa.sc_odma == NULL)
+ return ENXIO;
+
+ /* Establish the DBDMA channel edge-triggered interrupt. */
+ rid = 1;
+ dbdma_irq = bus_alloc_resource_any(self, SYS_RES_IRQ,
+ &rid, RF_SHAREABLE | RF_ACTIVE);
+ if (dbdma_irq == NULL)
+ return (ENXIO);
+
+ /* Now initialize the controller. */
+ err = i2s_setup(sc, 44100, 16, 64);
+ if (err != 0)
+ return (err);
+
+ snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt,
+ sc, &dbdma_ih);
+
+ oirq = rman_get_start(dbdma_irq);
+ err = powerpc_config_intr(oirq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
+ if (err != 0)
+ return (err);
+
+ /*
+ * Register a hook for delayed attach in order to allow
+ * the I2C controller to attach.
+ */
+ if ((i2s_delayed_attach = malloc(sizeof(struct intr_config_hook),
+ M_TEMP, M_WAITOK | M_ZERO)) == NULL)
+ return (ENOMEM);
+
+ i2s_delayed_attach->ich_func = i2s_postattach;
+ i2s_delayed_attach->ich_arg = sc;
+
+ if (config_intrhook_establish(i2s_delayed_attach) != 0)
+ return (ENOMEM);
+
+ return (aoa_attach(sc));
+}
+
+/*****************************************************************************
+ GPIO routines.
+ *****************************************************************************/
+
+enum gpio_ctrl {
+ AMP_MUTE,
+ HEADPHONE_MUTE,
+ LINEOUT_MUTE,
+ AUDIO_HW_RESET,
+ HEADPHONE_DETECT,
+ LINEOUT_DETECT,
+ GPIO_CTRL_NUM
+};
+
+#define GPIO_CTRL_EXTINT_SET \
+ ((1 << HEADPHONE_DETECT) | \
+ (1 << LINEOUT_DETECT))
+
+static struct aoagpio_softc *gpio_ctrls[GPIO_CTRL_NUM] =
+ {NULL, NULL, NULL, NULL, NULL, NULL};
+
+static struct gpio_match {
+ const char *name;
+ enum gpio_ctrl ctrl;
+} gpio_controls[] = {
+ {"headphone-mute", HEADPHONE_MUTE},
+ {"lineout-mute", LINEOUT_MUTE},
+ {"amp-mute", AMP_MUTE},
+ {"headphone-detect", HEADPHONE_DETECT},
+ {"lineout-detect", LINEOUT_DETECT},
+ {"line-output-detect", LINEOUT_DETECT},
+ {"audio-hw-reset", AUDIO_HW_RESET},
+ {"hw-reset", AUDIO_HW_RESET},
+ {NULL, GPIO_CTRL_NUM}
+};
+
+static void i2s_cint(struct i2s_softc *);
+
+static void
+aoagpio_int(void *cookie)
+{
+ device_t self = cookie;
+ struct aoagpio_softc *sc;
+
+ sc = device_get_softc(self);
+
+ if (macgpio_read(self) & GPIO_LEVEL_RO)
+ sc->level = sc->detect_active;
+ else
+ sc->level = !(sc->detect_active);
+
+ if (sc->i2s)
+ i2s_cint(sc->i2s);
+}
+
+static int
+aoagpio_probe(device_t gpio)
+{
+ phandle_t node;
+ char bname[32];
+ const char *name;
+ struct gpio_match *m;
+ struct aoagpio_softc *sc;
+
+ node = ofw_bus_get_node(gpio);
+ if (node == 0 || node == -1)
+ return (EINVAL);
+
+ bzero(bname, sizeof(bname));
+ if (OF_getprop(node, "audio-gpio", bname, sizeof(bname)) > 2)
+ name = bname;
+ else
+ name = ofw_bus_get_name(gpio);
+
+ /* Try to find a match. */
+ for (m = gpio_controls; m->name != NULL; m++) {
+ if (strcmp(name, m->name) == 0) {
+ sc = device_get_softc(gpio);
+ gpio_ctrls[m->ctrl] = sc;
+ sc->dev = gpio;
+ sc->ctrl = m->ctrl;
+ sc->level = 0;
+ sc->detect_active = 0;
+ sc->i2s = NULL;
+
+ OF_getprop(node, "audio-gpio-active-state",
+ &sc->detect_active, sizeof(sc->detect_active));
+
+ if ((1 << m->ctrl) & GPIO_CTRL_EXTINT_SET)
+ aoagpio_int(gpio);
+
+ device_set_desc(gpio, m->name);
+ device_quiet(gpio);
+ return (0);
+ }
+ }
+
+ return (ENXIO);
+}
+
+static int
+aoagpio_attach(device_t gpio)
+{
+ struct aoagpio_softc *sc;
+ struct resource *r;
+ void *cookie;
+ int irq, rid = 0;
+
+ sc = device_get_softc(gpio);
+
+ if ((1 << sc->ctrl) & GPIO_CTRL_EXTINT_SET) {
+ r = bus_alloc_resource_any(gpio, SYS_RES_IRQ, &rid, RF_ACTIVE);
+ if (r == NULL)
+ return (ENXIO);
+
+ irq = rman_get_start(r);
+ DPRINTF(("interrupting at irq %d\n", irq));
+
+ if (powerpc_config_intr(irq, INTR_TRIGGER_EDGE,
+ INTR_POLARITY_LOW) != 0)
+ return (ENXIO);
+
+ bus_setup_intr(gpio, r, INTR_TYPE_MISC | INTR_MPSAFE |
+ INTR_ENTROPY, NULL, aoagpio_int, gpio, &cookie);
+ }
+
+ return (0);
+}
+
+/*
+ * I2S module registers
+ */
+#define I2S_INT 0x00
+#define I2S_FORMAT 0x10
+#define I2S_FRAMECOUNT 0x40
+#define I2S_FRAMEMATCH 0x50
+#define I2S_WORDSIZE 0x60
+
+/* I2S_INT register definitions */
+#define I2S_INT_CLKSTOPPEND 0x01000000 /* clock-stop interrupt pending */
+
+/* I2S_FORMAT register definitions */
+#define CLKSRC_49MHz 0x80000000 /* Use 49152000Hz Osc. */
+#define CLKSRC_45MHz 0x40000000 /* Use 45158400Hz Osc. */
+#define CLKSRC_18MHz 0x00000000 /* Use 18432000Hz Osc. */
+#define MCLK_DIV_MASK 0x1f000000 /* MCLK = SRC / DIV */
+#define SCLK_DIV_MASK 0x00f00000 /* SCLK = MCLK / DIV */
+#define SCLK_MASTER 0x00080000 /* Master mode */
+#define SCLK_SLAVE 0x00000000 /* Slave mode */
+#define SERIAL_FORMAT 0x00070000
+#define SERIAL_SONY 0x00000000
+#define SERIAL_64x 0x00010000
+#define SERIAL_32x 0x00020000
+#define SERIAL_DAV 0x00040000
+#define SERIAL_SILICON 0x00050000
+
+/* I2S_WORDSIZE register definitions */
+#define INPUT_STEREO (2 << 24)
+#define INPUT_MONO (1 << 24)
+#define INPUT_16BIT (0 << 16)
+#define INPUT_24BIT (3 << 16)
+#define OUTPUT_STEREO (2 << 8)
+#define OUTPUT_MONO (1 << 8)
+#define OUTPUT_16BIT (0 << 0)
+#define OUTPUT_24BIT (3 << 0)
+
+/* Master clock, needed by some codecs. We hardcode this
+ to 256 * fs as this is valid for most codecs. */
+#define MCLK_FS 256
+
+/* Number of clock sources we can use. */
+#define NCLKS 3
+static const struct i2s_clksrc {
+ u_int cs_clock;
+ u_int cs_reg;
+} clksrc[NCLKS] = {
+ {49152000, CLKSRC_49MHz},
+ {45158400, CLKSRC_45MHz},
+ {18432000, CLKSRC_18MHz}
+};
+
+/* Configure the I2S controller for the required settings.
+ 'rate' is the frame rate.
+ 'wordsize' is the sample size (usually 16 bits).
+ 'sclk_fs' is the SCLK/framerate ratio, which needs to be equal
+ or greater to the number of bits per frame. */
+
+static int
+i2s_setup(struct i2s_softc *sc, u_int rate, u_int wordsize, u_int sclk_fs)
+{
+ u_int mclk, mdiv, sdiv;
+ u_int reg = 0, x, wordformat;
+ u_int i;
+
+ /* Make sure the settings are consistent... */
+ if ((wordsize * 2) > sclk_fs)
+ return (EINVAL);
+
+ if (sclk_fs != 32 && sclk_fs != 64)
+ return (EINVAL);
+
+ /*
+ * Find a clock source to derive the master clock (MCLK)
+ * and the I2S bit block (SCLK) and set the divisors as
+ * appropriate.
+ */
+ mclk = rate * MCLK_FS;
+ sdiv = MCLK_FS / sclk_fs;
+
+ for (i = 0; i < NCLKS; ++i) {
+ if ((clksrc[i].cs_clock % mclk) == 0) {
+ reg = clksrc[i].cs_reg;
+ mdiv = clksrc[i].cs_clock / mclk;
+ break;
+ }
+ }
+ if (reg == 0)
+ return (EINVAL);
+
+ switch (mdiv) {
+ /* exception cases */
+ case 1:
+ x = 14;
+ break;
+ case 3:
+ x = 13;
+ break;
+ case 5:
+ x = 12;
+ break;
+ default:
+ x = (mdiv / 2) - 1;
+ break;
+ }
+ reg |= (x << 24) & MCLK_DIV_MASK;
+
+ switch (sdiv) {
+ case 1:
+ x = 8;
+ break;
+ case 3:
+ x = 9;
+ break;
+ default:
+ x = (sdiv / 2) - 1;
+ break;
+ }
+ reg |= (x << 20) & SCLK_DIV_MASK;
+
+ /*
+ * XXX use master mode for now. This needs to be
+ * revisited if we want to add recording from SPDIF some day.
+ */
+ reg |= SCLK_MASTER;
+
+ switch (sclk_fs) {
+ case 64:
+ reg |= SERIAL_64x;
+ break;
+ case 32:
+ reg |= SERIAL_32x;
+ break;
+ }
+
+ /* stereo input and output */
+ wordformat = INPUT_STEREO | OUTPUT_STEREO;
+
+ switch (wordsize) {
+ case 16:
+ wordformat |= INPUT_16BIT | OUTPUT_16BIT;
+ break;
+ case 24:
+ wordformat |= INPUT_24BIT | OUTPUT_24BIT;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ x = bus_read_4(sc->reg, I2S_WORDSIZE);
+ if (x != wordformat)
+ bus_write_4(sc->reg, I2S_WORDSIZE, wordformat);
+
+ x = bus_read_4(sc->reg, I2S_FORMAT);
+ if (x != reg) {
+ /*
+ * XXX to change the format we need to stop the clock
+ * via the FCR registers. For now, rely on the firmware
+ * to set sane defaults (44100).
+ */
+ printf("i2s_setup: changing format not supported yet.\n");
+ return (EOPNOTSUPP);
+
+#ifdef notyet
+ if (obio_fcr_isset(OBIO_FCR1, I2S0CLKEN)) {
+
+ bus_space_write_4(sc->sc_tag, sc->sc_bsh, I2S_INT,
+ I2S_INT_CLKSTOPPEND);
+
+ obio_fcr_clear(OBIO_FCR1, I2S0CLKEN);
+
+ for (timo = 1000; timo > 0; timo--) {
+ if (bus_space_read_4(sc->sc_tag, sc->sc_bsh,
+ I2S_INT) & I2S_INT_CLKSTOPPEND)
+ break;
+
+ DELAY(10);
+ }
+
+ if (timo == 0)
+ printf("%s: timeout waiting for clock to stop\n",
+ sc->sc_dev.dv_xname);
+ }
+
+ bus_space_write_4(sc->sc_tag, sc->sc_bsh, I2S_FORMAT, reg);
+
+ obio_fcr_set(OBIO_FCR1, I2S0CLKEN);
+#endif
+ }
+
+ return (0);
+}
+
+
+/* XXX this does not belong here. */
+static phandle_t
+of_find_firstchild_byname(phandle_t node, const char *req_name)
+{
+ char name[32]; /* max name len per OF spec. */
+ phandle_t n;
+
+ for (n = OF_child(node); n != -1; n = OF_peer(n)) {
+ bzero(name, sizeof(name));
+ OF_getprop(n, "name", name, sizeof(name));
+
+ if (strcmp(name, req_name) == 0)
+ return (n);
+ }
+
+ return (-1);
+}
+
+
+static u_int
+gpio_read(enum gpio_ctrl ctrl)
+{
+ struct aoagpio_softc *sc;
+
+ if ((sc = gpio_ctrls[ctrl]) == NULL)
+ return (0);
+
+ return (macgpio_read(sc->dev) & GPIO_DATA);
+}
+
+static void
+gpio_write(enum gpio_ctrl ctrl, u_int x)
+{
+ struct aoagpio_softc *sc;
+ u_int reg;
+
+ if ((sc = gpio_ctrls[ctrl]) == NULL)
+ return;
+
+ reg = GPIO_DDR_OUTPUT;
+ if (x)
+ reg |= GPIO_DATA;
+
+ macgpio_write(sc->dev, reg);
+}
+
+static void
+i2s_cint(struct i2s_softc *sc)
+{
+ u_int mask = 0;
+
+ if (gpio_ctrls[HEADPHONE_DETECT] &&
+ gpio_ctrls[HEADPHONE_DETECT]->level)
+ mask |= 1 << 1;
+
+ if (gpio_ctrls[LINEOUT_DETECT] &&
+ gpio_ctrls[LINEOUT_DETECT]->level)
+ mask |= 1 << 2;
+
+ if (mask == 0)
+ mask = 1 << 0; /* fall back to speakers. */
+
+ i2s_set_outputs(sc, mask);
+}
+
+#define reset_active 0
+
+/* these values are in microseconds */
+#define RESET_SETUP_TIME 5000
+#define RESET_HOLD_TIME 20000
+#define RESET_RELEASE_TIME 10000
+
+static void
+i2s_audio_hw_reset(struct i2s_softc *sc)
+{
+ if (gpio_ctrls[AUDIO_HW_RESET]) {
+ DPRINTF(("resetting codec\n"));
+
+ gpio_write(AUDIO_HW_RESET, !reset_active); /* Negate RESET */
+ DELAY(RESET_SETUP_TIME);
+
+ gpio_write(AUDIO_HW_RESET, reset_active); /* Assert RESET */
+ DELAY(RESET_HOLD_TIME);
+
+ gpio_write(AUDIO_HW_RESET, !reset_active); /* Negate RESET */
+ DELAY(RESET_RELEASE_TIME);
+
+ } else {
+ DPRINTF(("no audio_hw_reset\n"));
+ }
+}
+
+#define AMP_ACTIVE 0 /* XXX OF */
+#define HEADPHONE_ACTIVE 0 /* XXX OF */
+#define LINEOUT_ACTIVE 0 /* XXX OF */
+
+#define MUTE_CONTROL(xxx, yyy) \
+static void \
+i2s_mute_##xxx(struct i2s_softc *sc, int mute) \
+{ \
+ int x; \
+ \
+ if (gpio_ctrls[yyy##_MUTE] == NULL) \
+ return; \
+ if (mute) \
+ x = yyy##_ACTIVE; \
+ else \
+ x = ! yyy##_ACTIVE; \
+ \
+ if (x != gpio_read(yyy##_MUTE)) \
+ gpio_write(yyy##_MUTE, x); \
+}
+
+MUTE_CONTROL(speaker, AMP)
+MUTE_CONTROL(headphone, HEADPHONE)
+MUTE_CONTROL(lineout, LINEOUT)
+
+static void
+i2s_set_outputs(void *ptr, u_int mask)
+{
+ struct i2s_softc *sc = ptr;
+
+ if (mask == sc->output_mask)
+ return;
+
+ mtx_lock(&sc->port_mtx);
+
+ i2s_mute_speaker(sc, 1);
+ i2s_mute_headphone(sc, 1);
+ i2s_mute_lineout(sc, 1);
+
+ DPRINTF(("enabled outputs: "));
+
+ if (mask & (1 << 0)) {
+ DPRINTF(("SPEAKER "));
+ i2s_mute_speaker(sc, 0);
+ }
+ if (mask & (1 << 1)) {
+ DPRINTF(("HEADPHONE "));
+ i2s_mute_headphone(sc, 0);
+ }
+ if (mask & (1 << 2)) {
+ DPRINTF(("LINEOUT "));
+ i2s_mute_lineout(sc, 0);
+ }
+
+ DPRINTF(("\n"));
+ sc->output_mask = mask;
+
+ mtx_unlock(&sc->port_mtx);
+}
+
+static void
+i2s_postattach(void *xsc)
+{
+ struct i2s_softc *sc = xsc;
+ device_t self;
+ int i;
+
+ self = sc->aoa.sc_dev;
+
+ /* Reset the codec. */
+ i2s_audio_hw_reset(sc);
+
+ /* If we have a codec, initialize it. */
+ if (i2s_mixer)
+ mixer_init(self, i2s_mixer_class, i2s_mixer);
+
+ /* Read initial port status. */
+ i2s_cint(sc);
+
+ /* Enable GPIO interrupt callback. */
+ for (i = 0; i < GPIO_CTRL_NUM; i++)
+ if (gpio_ctrls[i])
+ gpio_ctrls[i]->i2s = sc;
+
+ config_intrhook_disestablish(i2s_delayed_attach);
+ free(i2s_delayed_attach, M_TEMP);
+}
+
diff --git a/sys/dev/sound/macio/snapper.c b/sys/dev/sound/macio/snapper.c
new file mode 100644
index 0000000..8acca10
--- /dev/null
+++ b/sys/dev/sound/macio/snapper.c
@@ -0,0 +1,486 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+/*-
+ * Copyright (c) 2002, 2003 Tsubai Masanari. 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. 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.
+ *
+ * NetBSD: snapper.c,v 1.28 2008/05/16 03:49:54 macallan Exp
+ * Id: snapper.c,v 1.11 2002/10/31 17:42:13 tsubai Exp
+ */
+
+/*
+ * Apple Snapper audio.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/dbdma.h>
+#include <machine/intr_machdep.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <machine/pio.h>
+#include <sys/rman.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/sound/pcm/sound.h>
+#include "mixer_if.h"
+
+extern kobj_class_t i2s_mixer_class;
+extern device_t i2s_mixer;
+
+struct snapper_softc
+{
+ device_t sc_dev;
+ uint32_t sc_addr;
+};
+
+static int snapper_probe(device_t);
+static int snapper_attach(device_t);
+static int snapper_init(struct snd_mixer *m);
+static void snapper_uninit(struct snd_mixer *m);
+static int snapper_reinit(struct snd_mixer *m);
+static int snapper_set(struct snd_mixer *m, unsigned dev, unsigned left,
+ unsigned right);
+static int snapper_setrecsrc(struct snd_mixer *m, u_int32_t src);
+
+static device_method_t snapper_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, snapper_probe),
+ DEVMETHOD(device_attach, snapper_attach),
+
+ { 0, 0 }
+};
+
+static driver_t snapper_driver = {
+ "snapper",
+ snapper_methods,
+ sizeof(struct snapper_softc)
+};
+static devclass_t snapper_devclass;
+
+DRIVER_MODULE(snapper, iicbus, snapper_driver, snapper_devclass, 0, 0);
+MODULE_VERSION(snapper, 1);
+MODULE_DEPEND(snapper, iicbus, 1, 1, 1);
+
+static kobj_method_t snapper_mixer_methods[] = {
+ KOBJMETHOD(mixer_init, snapper_init),
+ KOBJMETHOD(mixer_uninit, snapper_uninit),
+ KOBJMETHOD(mixer_reinit, snapper_reinit),
+ KOBJMETHOD(mixer_set, snapper_set),
+ KOBJMETHOD(mixer_setrecsrc, snapper_setrecsrc),
+ { 0, 0 }
+};
+
+MIXER_DECLARE(snapper_mixer);
+
+#define SNAPPER_IICADDR 0x6a /* Hard-coded I2C slave addr */
+
+/* Snapper (Texas Instruments TAS3004) registers. */
+#define SNAPPER_MCR1 0x01 /* Main control register 1 (1byte) */
+#define SNAPPER_DRC 0x02 /* Dynamic range compression (6bytes) */
+#define SNAPPER_VOLUME 0x04 /* Volume (6bytes) */
+#define SNAPPER_TREBLE 0x05 /* Treble control (1byte) */
+#define SNAPPER_BASS 0x06 /* Bass control (1byte) */
+#define SNAPPER_MIXER_L 0x07 /* Mixer left gain (9bytes) */
+#define SNAPPER_MIXER_R 0x08 /* Mixer right gain (9bytes) */
+#define SNAPPER_LB0 0x0a /* Left biquad 0 (15bytes) */
+#define SNAPPER_LB1 0x0b /* Left biquad 1 (15bytes) */
+#define SNAPPER_LB2 0x0c /* Left biquad 2 (15bytes) */
+#define SNAPPER_LB3 0x0d /* Left biquad 3 (15bytes) */
+#define SNAPPER_LB4 0x0e /* Left biquad 4 (15bytes) */
+#define SNAPPER_LB5 0x0f /* Left biquad 5 (15bytes) */
+#define SNAPPER_LB6 0x10 /* Left biquad 6 (15bytes) */
+#define SNAPPER_RB0 0x13 /* Right biquad 0 (15bytes) */
+#define SNAPPER_RB1 0x14 /* Right biquad 1 (15bytes) */
+#define SNAPPER_RB2 0x15 /* Right biquad 2 (15bytes) */
+#define SNAPPER_RB3 0x16 /* Right biquad 3 (15bytes) */
+#define SNAPPER_RB4 0x17 /* Right biquad 4 (15bytes) */
+#define SNAPPER_RB5 0x18 /* Right biquad 5 (15bytes) */
+#define SNAPPER_RB6 0x19 /* Right biquad 6 (15bytes) */
+#define SNAPPER_LLB 0x21 /* Left loudness biquad (15bytes) */
+#define SNAPPER_RLB 0x22 /* Right loudness biquad (15bytes) */
+#define SNAPPER_LLB_GAIN 0x23 /* Left loudness biquad gain (3bytes) */
+#define SNAPPER_RLB_GAIN 0x24 /* Right loudness biquad gain (3bytes) */
+#define SNAPPER_ACR 0x40 /* Analog control register (1byte) */
+#define SNAPPER_MCR2 0x43 /* Main control register 2 (1byte) */
+#define SNAPPER_MCR1_FL 0x80 /* Fast load */
+#define SNAPPER_MCR1_SC 0x40 /* SCLK frequency */
+#define SNAPPER_MCR1_SC_32 0x00 /* 32fs */
+#define SNAPPER_MCR1_SC_64 0x40 /* 64fs */
+#define SNAPPER_MCR1_SM 0x30 /* Output serial port mode */
+#define SNAPPER_MCR1_SM_L 0x00 /* Left justified */
+#define SNAPPER_MCR1_SM_R 0x10 /* Right justified */
+#define SNAPPER_MCR1_SM_I2S 0x20 /* I2S */
+#define SNAPPER_MCR1_W 0x03 /* Serial port word length */
+#define SNAPPER_MCR1_W_16 0x00 /* 16 bit */
+#define SNAPPER_MCR1_W_18 0x01 /* 18 bit */
+#define SNAPPER_MCR1_W_20 0x02 /* 20 bit */
+#define SNAPPER_MCR1_W_24 0x03 /* 20 bit */
+#define SNAPPER_MCR2_DL 0x80 /* Download */
+#define SNAPPER_MCR2_AP 0x02 /* All pass mode */
+#define SNAPPER_ACR_ADM 0x80 /* ADC output mode */
+#define SNAPPER_ACR_LRB 0x40 /* Select B input */
+#define SNAPPER_ACR_DM 0x0c /* De-emphasis control */
+#define SNAPPER_ACR_DM_OFF 0x00 /* off */
+#define SNAPPER_ACR_DM_48 0x04 /* fs = 48kHz */
+#define SNAPPER_ACR_DM_44 0x08 /* fs = 44.1kHz */
+#define SNAPPER_ACR_INP 0x02 /* Analog input select */
+#define SNAPPER_ACR_INP_A 0x00 /* A */
+#define SNAPPER_ACR_INP_B 0x02 /* B */
+#define SNAPPER_ACR_APD 0x01 /* Analog power down */
+
+
+struct snapper_reg {
+ u_char MCR1[1];
+ u_char DRC[6];
+ u_char VOLUME[6];
+ u_char TREBLE[1];
+ u_char BASS[1];
+ u_char MIXER_L[9];
+ u_char MIXER_R[9];
+ u_char LB0[15];
+ u_char LB1[15];
+ u_char LB2[15];
+ u_char LB3[15];
+ u_char LB4[15];
+ u_char LB5[15];
+ u_char LB6[15];
+ u_char RB0[15];
+ u_char RB1[15];
+ u_char RB2[15];
+ u_char RB3[15];
+ u_char RB4[15];
+ u_char RB5[15];
+ u_char RB6[15];
+ u_char LLB[15];
+ u_char RLB[15];
+ u_char LLB_GAIN[3];
+ u_char RLB_GAIN[3];
+ u_char ACR[1];
+ u_char MCR2[1];
+};
+
+static const struct snapper_reg snapper_initdata = {
+ { SNAPPER_MCR1_SC_64 | SNAPPER_MCR1_SM_I2S |
+ SNAPPER_MCR1_W_16 }, /* MCR1 */
+ { 1, 0, 0, 0, 0, 0 }, /* DRC */
+ { 0, 0, 0, 0, 0, 0 }, /* VOLUME */
+ { 0x72 }, /* TREBLE */
+ { 0x72 }, /* BASS */
+ { 0x10, 0x00, 0x00, 0, 0, 0, 0, 0, 0 }, /* MIXER_L */
+ { 0x10, 0x00, 0x00, 0, 0, 0, 0, 0, 0 }, /* MIXER_R */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0, 0, 0 }, /* LLB_GAIN */
+ { 0, 0, 0 }, /* RLB_GAIN */
+ { SNAPPER_ACR_ADM | SNAPPER_ACR_LRB | SNAPPER_ACR_INP_B },/* ACR */
+ { SNAPPER_MCR2_AP } /* MCR2 */
+};
+
+static const char snapper_regsize[] = {
+ 0, /* 0x00 */
+ sizeof snapper_initdata.MCR1, /* 0x01 */
+ sizeof snapper_initdata.DRC, /* 0x02 */
+ 0, /* 0x03 */
+ sizeof snapper_initdata.VOLUME, /* 0x04 */
+ sizeof snapper_initdata.TREBLE, /* 0x05 */
+ sizeof snapper_initdata.BASS, /* 0x06 */
+ sizeof snapper_initdata.MIXER_L, /* 0x07 */
+ sizeof snapper_initdata.MIXER_R, /* 0x08 */
+ 0, /* 0x09 */
+ sizeof snapper_initdata.LB0, /* 0x0a */
+ sizeof snapper_initdata.LB1, /* 0x0b */
+ sizeof snapper_initdata.LB2, /* 0x0c */
+ sizeof snapper_initdata.LB3, /* 0x0d */
+ sizeof snapper_initdata.LB4, /* 0x0e */
+ sizeof snapper_initdata.LB5, /* 0x0f */
+ sizeof snapper_initdata.LB6, /* 0x10 */
+ 0, /* 0x11 */
+ 0, /* 0x12 */
+ sizeof snapper_initdata.RB0, /* 0x13 */
+ sizeof snapper_initdata.RB1, /* 0x14 */
+ sizeof snapper_initdata.RB2, /* 0x15 */
+ sizeof snapper_initdata.RB3, /* 0x16 */
+ sizeof snapper_initdata.RB4, /* 0x17 */
+ sizeof snapper_initdata.RB5, /* 0x18 */
+ sizeof snapper_initdata.RB6, /* 0x19 */
+ 0,0,0,0, 0,0,
+ 0, /* 0x20 */
+ sizeof snapper_initdata.LLB, /* 0x21 */
+ sizeof snapper_initdata.RLB, /* 0x22 */
+ sizeof snapper_initdata.LLB_GAIN, /* 0x23 */
+ sizeof snapper_initdata.RLB_GAIN, /* 0x24 */
+ 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,
+ sizeof snapper_initdata.ACR, /* 0x40 */
+ 0, /* 0x41 */
+ 0, /* 0x42 */
+ sizeof snapper_initdata.MCR2 /* 0x43 */
+};
+
+/* dB = 20 * log (x) table. */
+static u_int snapper_volume_table[100] = {
+ 0x00000148, 0x0000015C, 0x00000171, 0x00000186, // -46.0, -45.5, -45.0, -44.5,
+ 0x0000019E, 0x000001B6, 0x000001D0, 0x000001EB, // -44.0, -43.5, -43.0, -42.5,
+ 0x00000209, 0x00000227, 0x00000248, 0x0000026B, // -42.0, -41.5, -41.0, -40.5,
+ 0x0000028F, 0x000002B6, 0x000002DF, 0x0000030B, // -40.0, -39.5, -39.0, -38.5,
+ 0x00000339, 0x0000036A, 0x0000039E, 0x000003D5, // -38.0, -37.5, -37.0, -36.5,
+ 0x0000040F, 0x0000044C, 0x0000048D, 0x000004D2, // -36.0, -35.5, -35.0, -34.5,
+ 0x0000051C, 0x00000569, 0x000005BB, 0x00000612, // -34.0, -33.5, -33.0, -32.5,
+ 0x0000066E, 0x000006D0, 0x00000737, 0x000007A5, // -32.0, -31.5, -31.0, -30.5,
+ 0x00000818, 0x00000893, 0x00000915, 0x0000099F, // -30.0, -29.5, -29.0, -28.5,
+ 0x00000A31, 0x00000ACC, 0x00000B6F, 0x00000C1D, // -28.0, -27.5, -27.0, -26.5,
+ 0x00000CD5, 0x00000D97, 0x00000E65, 0x00000F40, // -26.0, -25.5, -25.0, -24.5,
+ 0x00001027, 0x0000111C, 0x00001220, 0x00001333, // -24.0, -23.5, -23.0, -22.5,
+ 0x00001456, 0x0000158A, 0x000016D1, 0x0000182B, // -22.0, -21.5, -21.0, -20.5,
+ 0x0000199A, 0x00001B1E, 0x00001CB9, 0x00001E6D, // -20.0, -19.5, -19.0, -18.5,
+ 0x0000203A, 0x00002223, 0x00002429, 0x0000264E, // -18.0, -17.5, -17.0, -16.5,
+ 0x00002893, 0x00002AFA, 0x00002D86, 0x00003039, // -16.0, -15.5, -15.0, -14.5,
+ 0x00003314, 0x0000361B, 0x00003950, 0x00003CB5, // -14.0, -13.5, -13.0, -12.5,
+ 0x0000404E, 0x0000441D, 0x00004827, 0x00004C6D, // -12.0, -11.5, -11.0, -10.5,
+ 0x000050F4, 0x000055C0, 0x00005AD5, 0x00006037, // -10.0, -9.5, -9.0, -8.5,
+ 0x000065EA, 0x00006BF4, 0x0000725A, 0x00007920, // -8.0, -7.5, -7.0, -6.5,
+ 0x0000804E, 0x000087EF, 0x00008FF6, 0x0000987D, // -6.0, -5.5, -5.0, -4.5,
+ 0x0000A186, 0x0000AB19, 0x0000B53C, 0x0000BFF9, // -4.0, -3.5, -3.0, -2.5,
+ 0x0000CB59, 0x0000D766, 0x0000E429, 0x0000F1AE, // -2.0, -1.5, -1.0, -0.5,
+ 0x00010000, 0x00010F2B, 0x00011F3D, 0x00013042, // 0.0, +0.5, +1.0, +1.5,
+ 0x00014249, 0x00015562, 0x0001699C, 0x00017F09 // 2.0, +2.5, +3.0, +3.5,
+};
+
+static int
+snapper_write(struct snapper_softc *sc, uint8_t reg, const void *data)
+{
+ u_int size;
+ uint8_t buf[16];
+
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 0, buf }
+ };
+
+ KASSERT(reg < sizeof(snapper_regsize), ("bad reg"));
+ size = snapper_regsize[reg];
+ msg[0].len = size + 1;
+ buf[0] = reg;
+ memcpy(&buf[1], data, size);
+
+ iicbus_transfer(sc->sc_dev, msg, 1);
+
+ return (0);
+}
+
+static int
+snapper_probe(device_t dev)
+{
+ const char *name, *compat;
+
+ name = ofw_bus_get_name(dev);
+ if (name == NULL)
+ return (ENXIO);
+
+ if (strcmp(name, "deq") == 0) {
+ if (iicbus_get_addr(dev) != SNAPPER_IICADDR)
+ return (ENXIO);
+ } else if (strcmp(name, "codec") == 0) {
+ compat = ofw_bus_get_compat(dev);
+ if (compat == NULL || strcmp(compat, "tas3004") != 0)
+ return (ENXIO);
+ } else {
+ return (ENXIO);
+ }
+
+ device_set_desc(dev, "Texas Instruments TAS3004 Audio Codec");
+ return (0);
+}
+
+static int
+snapper_attach(device_t dev)
+{
+ struct snapper_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+ sc->sc_addr = iicbus_get_addr(dev);
+
+ i2s_mixer_class = &snapper_mixer_class;
+ i2s_mixer = dev;
+
+ return (0);
+}
+
+static int
+snapper_init(struct snd_mixer *m)
+{
+ struct snapper_softc *sc;
+ u_int x = 0;
+
+ sc = device_get_softc(mix_getdevinfo(m));
+
+ snapper_write(sc, SNAPPER_LB0, snapper_initdata.LB0);
+ snapper_write(sc, SNAPPER_LB1, snapper_initdata.LB1);
+ snapper_write(sc, SNAPPER_LB2, snapper_initdata.LB2);
+ snapper_write(sc, SNAPPER_LB3, snapper_initdata.LB3);
+ snapper_write(sc, SNAPPER_LB4, snapper_initdata.LB4);
+ snapper_write(sc, SNAPPER_LB5, snapper_initdata.LB5);
+ snapper_write(sc, SNAPPER_LB6, snapper_initdata.LB6);
+ snapper_write(sc, SNAPPER_RB0, snapper_initdata.RB0);
+ snapper_write(sc, SNAPPER_RB1, snapper_initdata.RB1);
+ snapper_write(sc, SNAPPER_RB1, snapper_initdata.RB1);
+ snapper_write(sc, SNAPPER_RB2, snapper_initdata.RB2);
+ snapper_write(sc, SNAPPER_RB3, snapper_initdata.RB3);
+ snapper_write(sc, SNAPPER_RB4, snapper_initdata.RB4);
+ snapper_write(sc, SNAPPER_RB5, snapper_initdata.RB5);
+ snapper_write(sc, SNAPPER_RB6, snapper_initdata.RB6);
+ snapper_write(sc, SNAPPER_MCR1, snapper_initdata.MCR1);
+ snapper_write(sc, SNAPPER_MCR2, snapper_initdata.MCR2);
+ snapper_write(sc, SNAPPER_DRC, snapper_initdata.DRC);
+ snapper_write(sc, SNAPPER_VOLUME, snapper_initdata.VOLUME);
+ snapper_write(sc, SNAPPER_TREBLE, snapper_initdata.TREBLE);
+ snapper_write(sc, SNAPPER_BASS, snapper_initdata.BASS);
+ snapper_write(sc, SNAPPER_MIXER_L, snapper_initdata.MIXER_L);
+ snapper_write(sc, SNAPPER_MIXER_R, snapper_initdata.MIXER_R);
+ snapper_write(sc, SNAPPER_LLB, snapper_initdata.LLB);
+ snapper_write(sc, SNAPPER_RLB, snapper_initdata.RLB);
+ snapper_write(sc, SNAPPER_LLB_GAIN, snapper_initdata.LLB_GAIN);
+ snapper_write(sc, SNAPPER_RLB_GAIN, snapper_initdata.RLB_GAIN);
+ snapper_write(sc, SNAPPER_ACR, snapper_initdata.ACR);
+
+ x |= SOUND_MASK_VOLUME;
+ mix_setdevs(m, x);
+
+ return (0);
+}
+
+static void
+snapper_uninit(struct snd_mixer *m)
+{
+ return;
+}
+
+static int
+snapper_reinit(struct snd_mixer *m)
+{
+ return (0);
+}
+
+static int
+snapper_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+{
+ struct snapper_softc *sc;
+ struct mtx *mixer_lock;
+ int locked;
+ u_int l, r;
+ u_char reg[6];
+
+ sc = device_get_softc(mix_getdevinfo(m));
+ mixer_lock = mixer_get_lock(m);
+ locked = mtx_owned(mixer_lock);
+
+ if (left > 100 || right > 100)
+ return (0);
+
+ l = (left == 0) ? 0 : snapper_volume_table[left - 1];
+ r = (right == 0) ? 0 : snapper_volume_table[right - 1];
+
+ switch (dev) {
+ case SOUND_MIXER_VOLUME:
+ reg[0] = (l & 0xff0000) >> 16;
+ reg[1] = (l & 0x00ff00) >> 8;
+ reg[2] = l & 0x0000ff;
+ reg[3] = (r & 0xff0000) >> 16;
+ reg[4] = (r & 0x00ff00) >> 8;
+ reg[5] = r & 0x0000ff;
+
+ /*
+ * We need to unlock the mixer lock because iicbus_transfer()
+ * may sleep. The mixer lock itself is unnecessary here
+ * because it is meant to serialize hardware access, which
+ * is taken care of by the I2C layer, so this is safe.
+ */
+
+ if (locked)
+ mtx_unlock(mixer_lock);
+
+ snapper_write(sc, SNAPPER_VOLUME, reg);
+
+ if (locked)
+ mtx_lock(mixer_lock);
+
+ return (left | (right << 8));
+ }
+
+ return (0);
+}
+
+static int
+snapper_setrecsrc(struct snd_mixer *m, u_int32_t src)
+{
+ return (0);
+}
+
diff --git a/sys/dev/sound/macio/tumbler.c b/sys/dev/sound/macio/tumbler.c
new file mode 100644
index 0000000..3007ece
--- /dev/null
+++ b/sys/dev/sound/macio/tumbler.c
@@ -0,0 +1,432 @@
+/*-
+ * Copyright 2008 by Marco Trillo. 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$
+ */
+/*-
+ * Copyright (c) 2002, 2003 Tsubai Masanari. 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. 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.
+ *
+ * NetBSD: tumbler.c,v 1.28 2008/05/16 03:49:54 macallan Exp
+ * Id: tumbler.c,v 1.11 2002/10/31 17:42:13 tsubai Exp
+ */
+
+/*
+ * Apple I2S audio controller.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/dbdma.h>
+#include <machine/intr_machdep.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <machine/pio.h>
+#include <sys/rman.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/sound/pcm/sound.h>
+#include "mixer_if.h"
+
+extern kobj_class_t i2s_mixer_class;
+extern device_t i2s_mixer;
+
+struct tumbler_softc
+{
+ device_t sc_dev;
+ uint32_t sc_addr;
+};
+
+static int tumbler_probe(device_t);
+static int tumbler_attach(device_t);
+static int tumbler_init(struct snd_mixer *m);
+static void tumbler_uninit(struct snd_mixer *m);
+static int tumbler_reinit(struct snd_mixer *m);
+static int tumbler_set(struct snd_mixer *m, unsigned dev, unsigned left,
+ unsigned right);
+static int tumbler_setrecsrc(struct snd_mixer *m, u_int32_t src);
+
+static device_method_t tumbler_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, tumbler_probe),
+ DEVMETHOD(device_attach, tumbler_attach),
+
+ { 0, 0 }
+};
+
+static driver_t tumbler_driver = {
+ "tumbler",
+ tumbler_methods,
+ sizeof(struct tumbler_softc)
+};
+static devclass_t tumbler_devclass;
+
+DRIVER_MODULE(tumbler, iicbus, tumbler_driver, tumbler_devclass, 0, 0);
+MODULE_VERSION(tumbler, 1);
+MODULE_DEPEND(tumbler, iicbus, 1, 1, 1);
+
+static kobj_method_t tumbler_mixer_methods[] = {
+ KOBJMETHOD(mixer_init, tumbler_init),
+ KOBJMETHOD(mixer_uninit, tumbler_uninit),
+ KOBJMETHOD(mixer_reinit, tumbler_reinit),
+ KOBJMETHOD(mixer_set, tumbler_set),
+ KOBJMETHOD(mixer_setrecsrc, tumbler_setrecsrc),
+ { 0, 0 }
+};
+
+MIXER_DECLARE(tumbler_mixer);
+
+#define TUMBLER_IICADDR 0x68 /* Tumbler I2C slave address */
+
+/* Tumbler (Texas Instruments TAS3001) registers. */
+#define TUMBLER_MCR 0x01 /* Main control register (1byte) */
+#define TUMBLER_DRC 0x02 /* Dynamic Range Compression (2bytes) */
+#define TUMBLER_VOLUME 0x04 /* Volume (6bytes) */
+#define TUMBLER_TREBLE 0x05 /* Treble control (1byte) */
+#define TUMBLER_BASS 0x06 /* Bass control (1byte) */
+#define TUMBLER_MIXER1 0x07 /* Mixer1 (3bytes) */
+#define TUMBLER_MIXER2 0x08 /* Mixer2 (3bytes) */
+#define TUMBLER_LB0 0x0a /* Left biquad 0 (15bytes) */
+#define TUMBLER_LB1 0x0b /* Left biquad 1 (15bytes) */
+#define TUMBLER_LB2 0x0c /* Left biquad 2 (15bytes) */
+#define TUMBLER_LB3 0x0d /* Left biquad 3 (15bytes) */
+#define TUMBLER_LB4 0x0e /* Left biquad 4 (15bytes) */
+#define TUMBLER_LB5 0x0f /* Left biquad 5 (15bytes) */
+#define TUMBLER_RB0 0x13 /* Right biquad 0 (15bytes) */
+#define TUMBLER_RB1 0x14 /* Right biquad 1 (15bytes) */
+#define TUMBLER_RB2 0x15 /* Right biquad 2 (15bytes) */
+#define TUMBLER_RB3 0x16 /* Right biquad 3 (15bytes) */
+#define TUMBLER_RB4 0x17 /* Right biquad 4 (15bytes) */
+#define TUMBLER_RB5 0x18 /* Right biquad 5 (15bytes) */
+#define TUMBLER_MCR_FL 0x80 /* Fast load */
+#define TUMBLER_MCR_SC 0x40 /* SCLK frequency */
+#define TUMBLER_MCR_SC_32 0x00 /* 32fs */
+#define TUMBLER_MCR_SC_64 0x40 /* 64fs */
+#define TUMBLER_MCR_SM 0x30 /* Output serial port mode */
+#define TUMBLER_MCR_SM_L 0x00 /* Left justified */
+#define TUMBLER_MCR_SM_R 0x10 /* Right justified */
+#define TUMBLER_MCR_SM_I2S 0x20 /* I2S */
+#define TUMBLER_MCR_ISM 0x0C /* Input serial mode */
+#define TUMBLER_MCR_ISM_L 0x00
+#define TUMBLER_MCR_ISM_R 0x04
+#define TUMBLER_MCR_ISM_I2S 0x08
+#define TUMBLER_MCR_W 0x03 /* Serial port word length */
+#define TUMBLER_MCR_W_16 0x00 /* 16 bit */
+#define TUMBLER_MCR_W_18 0x01 /* 18 bit */
+#define TUMBLER_MCR_W_20 0x02 /* 20 bit */
+#define TUMBLER_DRC_COMP_31 0xc0 /* 3:1 compression */
+#define TUMBLER_DRC_ENABLE 0x01 /* enable DRC */
+#define TUMBLER_DRC_DEFL_TH 0xa0 /* default compression threshold */
+
+/*
+ * Tumbler codec.
+ */
+
+struct tumbler_reg {
+ u_char MCR[1];
+ u_char DRC[2];
+ u_char VOLUME[6];
+ u_char TREBLE[1];
+ u_char BASS[1];
+ u_char MIXER1[3];
+ u_char MIXER2[3];
+ u_char LB0[15];
+ u_char LB1[15];
+ u_char LB2[15];
+ u_char LB3[15];
+ u_char LB4[15];
+ u_char LB5[15];
+ u_char RB0[15];
+ u_char RB1[15];
+ u_char RB2[15];
+ u_char RB3[15];
+ u_char RB4[15];
+ u_char RB5[15];
+};
+
+const struct tumbler_reg tumbler_initdata = {
+ { TUMBLER_MCR_SC_64 | TUMBLER_MCR_SM_I2S |
+ TUMBLER_MCR_ISM_I2S | TUMBLER_MCR_W_16 }, /* MCR */
+ { TUMBLER_DRC_COMP_31, TUMBLER_DRC_DEFL_TH }, /* DRC */
+ { 0, 0, 0, 0, 0, 0 }, /* VOLUME */
+ { 0x72 }, /* TREBLE */
+ { 0x3e }, /* BASS */
+ { 0x10, 0x00, 0x00 }, /* MIXER1 */
+ { 0x00, 0x00, 0x00 }, /* MIXER2 */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* BIQUAD */
+ { 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* BIQUAD */
+};
+
+const char tumbler_regsize[] = {
+ 0, /* 0x00 */
+ sizeof tumbler_initdata.MCR, /* 0x01 */
+ sizeof tumbler_initdata.DRC, /* 0x02 */
+ 0, /* 0x03 */
+ sizeof tumbler_initdata.VOLUME, /* 0x04 */
+ sizeof tumbler_initdata.TREBLE, /* 0x05 */
+ sizeof tumbler_initdata.BASS, /* 0x06 */
+ sizeof tumbler_initdata.MIXER1, /* 0x07 */
+ sizeof tumbler_initdata.MIXER2, /* 0x08 */
+ 0, /* 0x09 */
+ sizeof tumbler_initdata.LB0, /* 0x0a */
+ sizeof tumbler_initdata.LB1, /* 0x0b */
+ sizeof tumbler_initdata.LB2, /* 0x0c */
+ sizeof tumbler_initdata.LB3, /* 0x0d */
+ sizeof tumbler_initdata.LB4, /* 0x0e */
+ sizeof tumbler_initdata.LB5, /* 0x0f */
+ 0, /* 0x10 */
+ 0, /* 0x11 */
+ 0, /* 0x12 */
+ sizeof tumbler_initdata.RB0, /* 0x13 */
+ sizeof tumbler_initdata.RB1, /* 0x14 */
+ sizeof tumbler_initdata.RB2, /* 0x15 */
+ sizeof tumbler_initdata.RB3, /* 0x16 */
+ sizeof tumbler_initdata.RB4, /* 0x17 */
+ sizeof tumbler_initdata.RB5 /* 0x18 */
+};
+
+/* dB = 20 * log (x) table. */
+static u_int tumbler_volume_table[100] = {
+ 0x00000148, 0x0000015C, 0x00000171, 0x00000186, // -46.0, -45.5, -45.0, -44.5,
+ 0x0000019E, 0x000001B6, 0x000001D0, 0x000001EB, // -44.0, -43.5, -43.0, -42.5,
+ 0x00000209, 0x00000227, 0x00000248, 0x0000026B, // -42.0, -41.5, -41.0, -40.5,
+ 0x0000028F, 0x000002B6, 0x000002DF, 0x0000030B, // -40.0, -39.5, -39.0, -38.5,
+ 0x00000339, 0x0000036A, 0x0000039E, 0x000003D5, // -38.0, -37.5, -37.0, -36.5,
+ 0x0000040F, 0x0000044C, 0x0000048D, 0x000004D2, // -36.0, -35.5, -35.0, -34.5,
+ 0x0000051C, 0x00000569, 0x000005BB, 0x00000612, // -34.0, -33.5, -33.0, -32.5,
+ 0x0000066E, 0x000006D0, 0x00000737, 0x000007A5, // -32.0, -31.5, -31.0, -30.5,
+ 0x00000818, 0x00000893, 0x00000915, 0x0000099F, // -30.0, -29.5, -29.0, -28.5,
+ 0x00000A31, 0x00000ACC, 0x00000B6F, 0x00000C1D, // -28.0, -27.5, -27.0, -26.5,
+ 0x00000CD5, 0x00000D97, 0x00000E65, 0x00000F40, // -26.0, -25.5, -25.0, -24.5,
+ 0x00001027, 0x0000111C, 0x00001220, 0x00001333, // -24.0, -23.5, -23.0, -22.5,
+ 0x00001456, 0x0000158A, 0x000016D1, 0x0000182B, // -22.0, -21.5, -21.0, -20.5,
+ 0x0000199A, 0x00001B1E, 0x00001CB9, 0x00001E6D, // -20.0, -19.5, -19.0, -18.5,
+ 0x0000203A, 0x00002223, 0x00002429, 0x0000264E, // -18.0, -17.5, -17.0, -16.5,
+ 0x00002893, 0x00002AFA, 0x00002D86, 0x00003039, // -16.0, -15.5, -15.0, -14.5,
+ 0x00003314, 0x0000361B, 0x00003950, 0x00003CB5, // -14.0, -13.5, -13.0, -12.5,
+ 0x0000404E, 0x0000441D, 0x00004827, 0x00004C6D, // -12.0, -11.5, -11.0, -10.5,
+ 0x000050F4, 0x000055C0, 0x00005AD5, 0x00006037, // -10.0, -9.5, -9.0, -8.5,
+ 0x000065EA, 0x00006BF4, 0x0000725A, 0x00007920, // -8.0, -7.5, -7.0, -6.5,
+ 0x0000804E, 0x000087EF, 0x00008FF6, 0x0000987D, // -6.0, -5.5, -5.0, -4.5,
+ 0x0000A186, 0x0000AB19, 0x0000B53C, 0x0000BFF9, // -4.0, -3.5, -3.0, -2.5,
+ 0x0000CB59, 0x0000D766, 0x0000E429, 0x0000F1AE, // -2.0, -1.5, -1.0, -0.5,
+ 0x00010000, 0x00010F2B, 0x00011F3D, 0x00013042, // 0.0, +0.5, +1.0, +1.5,
+ 0x00014249, 0x00015562, 0x0001699C, 0x00017F09 // 2.0, +2.5, +3.0, +3.5,
+};
+
+static int
+tumbler_write(struct tumbler_softc *sc, uint8_t reg, const void *data)
+{
+ u_int size;
+ uint8_t buf[16];
+
+ struct iic_msg msg[] = {
+ { sc->sc_addr, IIC_M_WR, 0, buf }
+ };
+
+ KASSERT(reg < sizeof(tumbler_regsize), ("bad reg"));
+ size = tumbler_regsize[reg];
+ msg[0].len = size + 1;
+ buf[0] = reg;
+ memcpy(&buf[1], data, size);
+
+ iicbus_transfer(sc->sc_dev, msg, 1);
+
+ return (0);
+}
+
+static int
+tumbler_probe(device_t dev)
+{
+ const char *name;
+
+ name = ofw_bus_get_name(dev);
+ if (name == NULL)
+ return (ENXIO);
+
+ if (strcmp(name, "deq") == 0 && iicbus_get_addr(dev) ==
+ TUMBLER_IICADDR) {
+ device_set_desc(dev, "Texas Instruments TAS3001 Audio Codec");
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+static int
+tumbler_attach(device_t dev)
+{
+ struct tumbler_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+ sc->sc_addr = iicbus_get_addr(dev);
+
+ i2s_mixer_class = &tumbler_mixer_class;
+ i2s_mixer = dev;
+
+ return (0);
+}
+
+static int
+tumbler_init(struct snd_mixer *m)
+{
+ struct tumbler_softc *sc;
+ u_int x = 0;
+
+ sc = device_get_softc(mix_getdevinfo(m));
+
+ tumbler_write(sc, TUMBLER_LB0, tumbler_initdata.LB0);
+ tumbler_write(sc, TUMBLER_LB1, tumbler_initdata.LB1);
+ tumbler_write(sc, TUMBLER_LB2, tumbler_initdata.LB2);
+ tumbler_write(sc, TUMBLER_LB3, tumbler_initdata.LB3);
+ tumbler_write(sc, TUMBLER_LB4, tumbler_initdata.LB4);
+ tumbler_write(sc, TUMBLER_LB5, tumbler_initdata.LB5);
+ tumbler_write(sc, TUMBLER_RB0, tumbler_initdata.RB0);
+ tumbler_write(sc, TUMBLER_RB1, tumbler_initdata.RB1);
+ tumbler_write(sc, TUMBLER_RB1, tumbler_initdata.RB1);
+ tumbler_write(sc, TUMBLER_RB2, tumbler_initdata.RB2);
+ tumbler_write(sc, TUMBLER_RB3, tumbler_initdata.RB3);
+ tumbler_write(sc, TUMBLER_RB4, tumbler_initdata.RB4);
+ tumbler_write(sc, TUMBLER_RB5, tumbler_initdata.RB5);
+ tumbler_write(sc, TUMBLER_MCR, tumbler_initdata.MCR);
+ tumbler_write(sc, TUMBLER_DRC, tumbler_initdata.DRC);
+ tumbler_write(sc, TUMBLER_VOLUME, tumbler_initdata.VOLUME);
+ tumbler_write(sc, TUMBLER_TREBLE, tumbler_initdata.TREBLE);
+ tumbler_write(sc, TUMBLER_BASS, tumbler_initdata.BASS);
+ tumbler_write(sc, TUMBLER_MIXER1, tumbler_initdata.MIXER1);
+ tumbler_write(sc, TUMBLER_MIXER2, tumbler_initdata.MIXER2);
+
+ x |= SOUND_MASK_VOLUME;
+ mix_setdevs(m, x);
+
+ return (0);
+}
+
+static void
+tumbler_uninit(struct snd_mixer *m)
+{
+ return;
+}
+
+static int
+tumbler_reinit(struct snd_mixer *m)
+{
+ return (0);
+}
+
+static int
+tumbler_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+{
+ struct tumbler_softc *sc;
+ struct mtx *mixer_lock;
+ int locked;
+ u_int l, r;
+ u_char reg[6];
+
+ sc = device_get_softc(mix_getdevinfo(m));
+ mixer_lock = mixer_get_lock(m);
+ locked = mtx_owned(mixer_lock);
+
+ switch (dev) {
+ case SOUND_MIXER_VOLUME:
+ if (left > 100 || right > 100)
+ return (0);
+
+ l = (left == 0 ? 0 : tumbler_volume_table[left - 1]);
+ r = (right == 0 ? 0 : tumbler_volume_table[right - 1]);
+
+ reg[0] = (l & 0xff0000) >> 16;
+ reg[1] = (l & 0x00ff00) >> 8;
+ reg[2] = l & 0x0000ff;
+ reg[3] = (r & 0xff0000) >> 16;
+ reg[4] = (r & 0x00ff00) >> 8;
+ reg[5] = r & 0x0000ff;
+
+ /*
+ * We need to unlock the mixer lock because iicbus_transfer()
+ * may sleep. The mixer lock itself is unnecessary here
+ * because it is meant to serialize hardware access, which
+ * is taken care of by the I2C layer, so this is safe.
+ */
+
+ if (locked)
+ mtx_unlock(mixer_lock);
+
+ tumbler_write(sc, TUMBLER_VOLUME, reg);
+
+ if (locked)
+ mtx_lock(mixer_lock);
+
+ return (left | (right << 8));
+ }
+
+ return (0);
+}
+
+static int
+tumbler_setrecsrc(struct snd_mixer *m, u_int32_t src)
+{
+ return (0);
+}
+
diff --git a/sys/dev/sound/pci/au88x0.c b/sys/dev/sound/pci/au88x0.c
deleted file mode 100644
index 4050827..0000000
--- a/sys/dev/sound/pci/au88x0.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*-
- * Copyright (c) 2003 Dag-Erling Coïdan Smørgrav
- * 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
- * in this position and unchanged.
- * 2. Redistributions in binary form must 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 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$
- */
-
-#include <dev/sound/pcm/sound.h>
-#include <dev/sound/pcm/ac97.h>
-#include <dev/sound/pci/au88x0.h>
-
-#include <machine/bus.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-
-/***************************************************************************\
- * *
- * SUPPORTED CHIPSETS *
- * *
-\***************************************************************************/
-
-static struct au88x0_chipset au88x0_chipsets[] = {
- {
- .auc_name = "Aureal Vortex (8820)",
- .auc_pci_id = 0x000112eb,
-
- .auc_control = 0x1280c,
-
- .auc_irq_source = 0x12800,
- .auc_irq_mask = 0x12804,
- .auc_irq_control = 0x12808,
- .auc_irq_status = 0x1199c,
-
- .auc_dma_control = 0x1060c,
-
- .auc_fifo_size = 0x20,
- .auc_wt_fifos = 32,
- .auc_wt_fifo_base = 0x0e800,
- .auc_wt_fifo_ctl = 0x0f800,
- .auc_wt_dma_ctl = 0x10500,
- .auc_adb_fifos = 16,
- .auc_adb_fifo_base = 0x0e000,
- .auc_adb_fifo_ctl = 0x0f840,
- .auc_adb_dma_ctl = 0x10580,
-
- .auc_adb_route_base = 0x10800,
- .auc_adb_route_bits = 7,
- .auc_adb_codec_in = 0x48,
- .auc_adb_codec_out = 0x58,
- },
- {
- .auc_name = "Aureal Vortex 2 (8830)",
- .auc_pci_id = 0x000212eb,
-
- .auc_control = 0x2a00c,
-
- .auc_irq_source = 0x2a000,
- .auc_irq_mask = 0x2a004,
- .auc_irq_control = 0x2a008,
- .auc_irq_status = 0x2919c,
-
- .auc_dma_control = 0x27ae8,
-
- .auc_fifo_size = 0x40,
- .auc_wt_fifos = 64,
- .auc_wt_fifo_base = 0x10000,
- .auc_wt_fifo_ctl = 0x16000,
- .auc_wt_dma_ctl = 0x27900,
- .auc_adb_fifos = 32,
- .auc_adb_fifo_base = 0x14000,
- .auc_adb_fifo_ctl = 0x16100,
- .auc_adb_dma_ctl = 0x27a00,
-
- .auc_adb_route_base = 0x28000,
- .auc_adb_route_bits = 8,
- .auc_adb_codec_in = 0x70,
- .auc_adb_codec_out = 0x88,
- },
- {
- .auc_name = "Aureal Vortex Advantage (8810)",
- .auc_pci_id = 0x000312eb,
-
- .auc_control = 0x2a00c,
-
- .auc_irq_source = 0x2a000,
- .auc_irq_mask = 0x2a004,
- .auc_irq_control = 0x2a008,
- .auc_irq_status = 0x2919c,
-
- .auc_dma_control = 0x27ae8,
-
- .auc_fifo_size = 0x20,
- .auc_wt_fifos = 32,
- .auc_wt_fifo_base = 0x10000,
- .auc_wt_fifo_ctl = 0x16000,
- .auc_wt_dma_ctl = 0x27fd8,
- .auc_adb_fifos = 16,
- .auc_adb_fifo_base = 0x14000,
- .auc_adb_fifo_ctl = 0x16100,
- .auc_adb_dma_ctl = 0x27180,
-
- .auc_adb_route_base = 0x28000,
- .auc_adb_route_bits = 8,
- .auc_adb_codec_in = 0x70,
- .auc_adb_codec_out = 0x88,
- },
- {
- .auc_pci_id = 0,
- }
-};
-
-
-/***************************************************************************\
- * *
- * FORMATS AND CAPABILITIES *
- * *
-\***************************************************************************/
-
-static u_int32_t au88x0_formats[] = {
- AFMT_U8,
- AFMT_STEREO | AFMT_U8,
- AFMT_S16_LE,
- AFMT_STEREO | AFMT_S16_LE,
- 0
-};
-
-static struct pcmchan_caps au88x0_capabilities = {
- 4000, /* minimum sample rate */
- 48000, /* maximum sample rate */
- au88x0_formats, /* supported formats */
- 0 /* no particular capabilities */
-};
-
-
-/***************************************************************************\
- * *
- * CODEC INTERFACE *
- * *
-\***************************************************************************/
-
-/*
- * Read from the au88x0 register space
- */
-#if 1
-/* all our writes are 32-bit */
-#define au88x0_read(aui, reg, n) \
- bus_space_read_4((aui)->aui_spct, (aui)->aui_spch, (reg))
-#define au88x0_write(aui, reg, data, n) \
- bus_space_write_4((aui)->aui_spct, (aui)->aui_spch, (reg), (data))
-#else
-static uint32_t
-au88x0_read(struct au88x0_info *aui, int reg, int size)
-{
- uint32_t data;
-
- switch (size) {
- case 1:
- data = bus_space_read_1(aui->aui_spct, aui->aui_spch, reg);
- break;
- case 2:
- data = bus_space_read_2(aui->aui_spct, aui->aui_spch, reg);
- break;
- case 4:
- data = bus_space_read_4(aui->aui_spct, aui->aui_spch, reg);
- break;
- default:
- panic("unsupported read size %d", size);
- }
- return (data);
-}
-
-/*
- * Write to the au88x0 register space
- */
-static void
-au88x0_write(struct au88x0_info *aui, int reg, uint32_t data, int size)
-{
-
- switch (size) {
- case 1:
- bus_space_write_1(aui->aui_spct, aui->aui_spch, reg, data);
- break;
- case 2:
- bus_space_write_2(aui->aui_spct, aui->aui_spch, reg, data);
- break;
- case 4:
- bus_space_write_4(aui->aui_spct, aui->aui_spch, reg, data);
- break;
- default:
- panic("unsupported write size %d", size);
- }
-}
-#endif
-
-/*
- * Reset and initialize the codec
- */
-static void
-au88x0_codec_init(struct au88x0_info *aui)
-{
- uint32_t data;
- int i;
-
- /* wave that chicken */
- au88x0_write(aui, AU88X0_CODEC_CONTROL, 0x8068, 4);
- DELAY(AU88X0_SETTLE_DELAY);
- au88x0_write(aui, AU88X0_CODEC_CONTROL, 0x00e8, 4);
- DELAY(1000);
- for (i = 0; i < 32; ++i) {
- au88x0_write(aui, AU88X0_CODEC_CHANNEL + i * 4, 0, 4);
- DELAY(AU88X0_SETTLE_DELAY);
- }
- au88x0_write(aui, AU88X0_CODEC_CONTROL, 0x00e8, 4);
- DELAY(AU88X0_SETTLE_DELAY);
-
- /* enable both codec channels */
- data = au88x0_read(aui, AU88X0_CODEC_ENABLE, 4);
- data |= (1 << (8 + 0)) | (1 << (8 + 1));
- au88x0_write(aui, AU88X0_CODEC_ENABLE, data, 4);
- DELAY(AU88X0_SETTLE_DELAY);
-}
-
-/*
- * Wait for the codec to get ready to accept a register write
- * Should be called at spltty
- */
-static int
-au88x0_codec_wait(struct au88x0_info *aui)
-{
- uint32_t data;
- int i;
-
- for (i = 0; i < AU88X0_RETRY_COUNT; ++i) {
- data = au88x0_read(aui, AU88X0_CODEC_CONTROL, 4);
- if (data & AU88X0_CDCTL_WROK)
- return (0);
- DELAY(AU88X0_SETTLE_DELAY);
- }
- device_printf(aui->aui_dev, "timeout while waiting for codec\n");
- return (-1);
-}
-
-/*
- * Read from the ac97 codec
- */
-static int
-au88x0_codec_read(kobj_t obj, void *arg, int reg)
-{
- struct au88x0_info *aui = arg;
- uint32_t data;
- int sl;
-
- sl = spltty();
- au88x0_codec_wait(aui);
- au88x0_write(aui, AU88X0_CODEC_IO, AU88X0_CDIO_READ(reg), 4);
- DELAY(1000);
- data = au88x0_read(aui, AU88X0_CODEC_IO, 4);
- splx(sl);
- data &= AU88X0_CDIO_DATA_MASK;
- data >>= AU88X0_CDIO_DATA_SHIFT;
- return (data);
-}
-
-/*
- * Write to the ac97 codec
- */
-static int
-au88x0_codec_write(kobj_t obj, void *arg, int reg, uint32_t data)
-{
- struct au88x0_info *aui = arg;
- int sl;
-
- sl = spltty();
- au88x0_codec_wait(aui);
- au88x0_write(aui, AU88X0_CODEC_IO, AU88X0_CDIO_WRITE(reg, data), 4);
- splx(sl);
- return 0;
-}
-
-/*
- * Codec interface glue
- */
-static kobj_method_t au88x0_ac97_methods[] = {
- KOBJMETHOD(ac97_read, au88x0_codec_read),
- KOBJMETHOD(ac97_write, au88x0_codec_write),
- { 0, 0 }
-};
-AC97_DECLARE(au88x0_ac97);
-
-#define au88x0_channel(aui, dir) \
- &(aui)->aui_chan[((dir) == PCMDIR_PLAY) ? 0 : 1]
-
-
-/***************************************************************************\
- * *
- * CHANNEL INTERFACE *
- * *
-\***************************************************************************/
-
-/*
- * Initialize a PCM channel
- */
-static void *
-au88x0_chan_init(kobj_t obj, void *arg,
- struct snd_dbuf *buf, struct pcm_channel *chan, int dir)
-{
- struct au88x0_info *aui = arg;
- struct au88x0_chan_info *auci = au88x0_channel(aui, dir);
-
- if (sndbuf_alloc(buf, aui->aui_dmat, 0, aui->aui_bufsize) != 0)
- return (NULL);
- auci->auci_aui = aui;
- auci->auci_pcmchan = chan;
- auci->auci_buf = buf;
- auci->auci_dir = dir;
- return (auci);
-}
-
-/*
- * Set the data format for a PCM channel
- */
-static int
-au88x0_chan_setformat(kobj_t obj, void *arg, u_int32_t format)
-{
-
- /* XXX */
- return (ENXIO);
-}
-
-/*
- * Set the sample rate for a PCM channel
- */
-static int
-au88x0_chan_setspeed(kobj_t obj, void *arg, u_int32_t speed)
-{
-
- /* XXX */
- return (speed);
-}
-
-/*
- * Set the block size for a PCM channel
- */
-static int
-au88x0_chan_setblocksize(kobj_t obj, void *arg, u_int32_t blocksize)
-{
-
- /* XXX */
- return (blocksize);
-}
-
-/*
- * Initiate a data transfer
- */
-static int
-au88x0_chan_trigger(kobj_t obj, void *arg, int trigger)
-{
- struct au88x0_chan_info *auci = arg;
-
- (void)auci;
- switch (trigger) {
- case PCMTRIG_START:
- break;
- case PCMTRIG_STOP:
- case PCMTRIG_ABORT:
- break;
- }
- return (0);
-}
-
-/*
- *
- */
-static int
-au88x0_chan_getptr(kobj_t obj, void *arg)
-{
-
- /* XXX */
- return (0);
-}
-
-/*
- * Return the capabilities of a PCM channel
- */
-static struct pcmchan_caps *
-au88x0_chan_getcaps(kobj_t obj, void *arg)
-{
-
- return (&au88x0_capabilities);
-}
-
-/*
- * Channel interface glue
- */
-static kobj_method_t au88x0_chan_methods[] = {
- KOBJMETHOD(channel_init, au88x0_chan_init),
- KOBJMETHOD(channel_setformat, au88x0_chan_setformat),
- KOBJMETHOD(channel_setspeed, au88x0_chan_setspeed),
- KOBJMETHOD(channel_setblocksize, au88x0_chan_setblocksize),
- KOBJMETHOD(channel_trigger, au88x0_chan_trigger),
- KOBJMETHOD(channel_getptr, au88x0_chan_getptr),
- KOBJMETHOD(channel_getcaps, au88x0_chan_getcaps),
- { 0, 0 }
-};
-CHANNEL_DECLARE(au88x0_chan);
-
-
-/***************************************************************************\
- * *
- * INTERRUPT HANDLER *
- * *
-\***************************************************************************/
-
-static void
-au88x0_intr(void *arg)
-{
- struct au88x0_info *aui = arg;
- struct au88x0_chipset *auc = aui->aui_chipset;
- int pending, source;
-
- pending = au88x0_read(aui, auc->auc_irq_control, 4);
- if ((pending & AU88X0_IRQ_PENDING_BIT) == 0)
- return;
- source = au88x0_read(aui, auc->auc_irq_source, 4);
- if (source & AU88X0_IRQ_FATAL_ERR)
- device_printf(aui->aui_dev,
- "fatal error interrupt received\n");
- if (source & AU88X0_IRQ_PARITY_ERR)
- device_printf(aui->aui_dev,
- "parity error interrupt received\n");
- /* XXX handle the others... */
-
- /* acknowledge the interrupts we just handled */
- au88x0_write(aui, auc->auc_irq_source, source, 4);
- au88x0_read(aui, auc->auc_irq_source, 4);
-}
-
-
-/***************************************************************************\
- * *
- * INITIALIZATION *
- * *
-\***************************************************************************/
-
-/*
- * Reset and initialize the ADB and WT FIFOs
- *
- * - need to find out what the magic values 0x42000 and 0x2000 mean.
- */
-static void
-au88x0_fifo_init(struct au88x0_info *aui)
-{
- struct au88x0_chipset *auc = aui->aui_chipset;
- int i;
-
- /* reset, then clear the ADB FIFOs */
- for (i = 0; i < auc->auc_adb_fifos; ++i)
- au88x0_write(aui, auc->auc_adb_fifo_ctl + i * 4, 0x42000, 4);
- for (i = 0; i < auc->auc_adb_fifos * auc->auc_fifo_size; ++i)
- au88x0_write(aui, auc->auc_adb_fifo_base + i * 4, 0, 4);
-
- /* reset, then clear the WT FIFOs */
- for (i = 0; i < auc->auc_wt_fifos; ++i)
- au88x0_write(aui, auc->auc_wt_fifo_ctl + i * 4, 0x42000, 4);
- for (i = 0; i < auc->auc_wt_fifos * auc->auc_fifo_size; ++i)
- au88x0_write(aui, auc->auc_wt_fifo_base + i * 4, 0, 4);
-}
-
-/*
- * Hardware initialization
- */
-static void
-au88x0_init(struct au88x0_info *aui)
-{
- struct au88x0_chipset *auc = aui->aui_chipset;
-
- /* reset the chip */
- au88x0_write(aui, auc->auc_control, 0xffffffff, 4);
- DELAY(10000);
-
- /* clear all interrupts */
- au88x0_write(aui, auc->auc_irq_source, 0xffffffff, 4);
- au88x0_read(aui, auc->auc_irq_source, 4);
- au88x0_read(aui, auc->auc_irq_status, 4);
-
- /* initialize the codec */
- au88x0_codec_init(aui);
-
- /* initialize the fifos */
- au88x0_fifo_init(aui);
-
- /* initialize the DMA engine */
- /* XXX chicken-waving! */
- au88x0_write(aui, auc->auc_dma_control, 0x1380000, 4);
-}
-
-/*
- * Construct and set status string
- */
-static void
-au88x0_set_status(device_t dev)
-{
- char status[SND_STATUSLEN];
- struct au88x0_info *aui;
-
- aui = pcm_getdevinfo(dev);
- snprintf(status, sizeof status, "at %s 0x%lx irq %ld %s",
- (aui->aui_regtype == SYS_RES_IOPORT)? "io" : "memory",
- rman_get_start(aui->aui_reg), rman_get_start(aui->aui_irq),PCM_KLDSTRING(snd_au88x0));
- pcm_setstatus(dev, status);
-}
-
-
-/***************************************************************************\
- * *
- * PCI INTERFACE *
- * *
-\***************************************************************************/
-
-/*
- * Probe
- */
-static int
-au88x0_pci_probe(device_t dev)
-{
- struct au88x0_chipset *auc;
- uint32_t pci_id;
-
- pci_id = pci_get_devid(dev);
- for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc) {
- if (auc->auc_pci_id == pci_id) {
- device_set_desc(dev, auc->auc_name);
- return BUS_PROBE_DEFAULT;
- }
- }
- return (ENXIO);
-}
-
-/*
- * Attach
- */
-static int
-au88x0_pci_attach(device_t dev)
-{
- struct au88x0_chipset *auc;
- struct au88x0_info *aui = NULL;
- uint32_t config;
- int error;
-
- aui = malloc(sizeof(*aui), M_DEVBUF, M_WAITOK | M_ZERO);
- aui->aui_dev = dev;
-
- /* Model-specific parameters */
- aui->aui_model = pci_get_devid(dev);
- for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc)
- if (auc->auc_pci_id == aui->aui_model)
- aui->aui_chipset = auc;
- if (aui->aui_chipset == NULL)
- panic("%s() called for non-au88x0 device", __func__);
-
- /* enable pio, mmio, bus-mastering dma */
- config = pci_read_config(dev, PCIR_COMMAND, 2);
- config |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
- pci_write_config(dev, PCIR_COMMAND, config, 2);
-
- /* register mapping */
- config = pci_read_config(dev, PCIR_COMMAND, 2);
- if (config & PCIM_CMD_MEMEN) {
- /* try memory-mapped I/O */
- aui->aui_regid = PCIR_BAR(0);
- aui->aui_regtype = SYS_RES_MEMORY;
- aui->aui_reg = bus_alloc_resource_any(dev, aui->aui_regtype,
- &aui->aui_regid, RF_ACTIVE);
- }
- if (aui->aui_reg == NULL && (config & PCIM_CMD_PORTEN)) {
- /* fall back on port I/O */
- aui->aui_regid = PCIR_BAR(0);
- aui->aui_regtype = SYS_RES_IOPORT;
- aui->aui_reg = bus_alloc_resource_any(dev, aui->aui_regtype,
- &aui->aui_regid, RF_ACTIVE);
- }
- if (aui->aui_reg == NULL) {
- /* both mmio and pio failed... */
- device_printf(dev, "failed to map registers\n");
- goto failed;
- }
- aui->aui_spct = rman_get_bustag(aui->aui_reg);
- aui->aui_spch = rman_get_bushandle(aui->aui_reg);
-
- /* IRQ mapping */
- aui->aui_irqid = 0;
- aui->aui_irqtype = SYS_RES_IRQ;
- aui->aui_irq = bus_alloc_resource_any(dev, aui->aui_irqtype,
- &aui->aui_irqid, RF_ACTIVE | RF_SHAREABLE);
- if (aui->aui_irq == 0) {
- device_printf(dev, "failed to map IRQ\n");
- goto failed;
- }
-
- /* install interrupt handler */
- error = snd_setup_intr(dev, aui->aui_irq, 0, au88x0_intr,
- aui, &aui->aui_irqh);
- if (error != 0) {
- device_printf(dev, "failed to install interrupt handler\n");
- goto failed;
- }
-
- /* DMA mapping */
- aui->aui_bufsize = pcm_getbuffersize(dev, AU88X0_BUFSIZE_MIN,
- AU88X0_BUFSIZE_DFLT, AU88X0_BUFSIZE_MAX);
- error = bus_dma_tag_create(bus_get_dma_tag(dev),
- 2, 0, /* 16-bit alignment, no boundary */
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* restrict to 4GB */
- NULL, NULL, /* no filter */
- aui->aui_bufsize, 1, aui->aui_bufsize,
- 0, busdma_lock_mutex, &Giant, &aui->aui_dmat);
- if (error != 0) {
- device_printf(dev, "failed to create DMA tag\n");
- goto failed;
- }
-
- /* initialize the hardware */
- au88x0_init(aui);
-
- /* initialize the ac97 codec and mixer */
- if ((aui->aui_ac97i = AC97_CREATE(dev, aui, au88x0_ac97)) == NULL) {
- device_printf(dev, "failed to initialize ac97 codec\n");
- goto failed;
- }
- if (mixer_init(dev, ac97_getmixerclass(), aui->aui_ac97i) != 0) {
- device_printf(dev, "failed to initialize ac97 mixer\n");
- goto failed;
- }
-
- /* register with the pcm driver */
- if (pcm_register(dev, aui, 0, 0))
- goto failed;
- pcm_addchan(dev, PCMDIR_PLAY, &au88x0_chan_class, aui);
-#if 0
- pcm_addchan(dev, PCMDIR_REC, &au88x0_chan_class, aui);
-#endif
- au88x0_set_status(dev);
-
- return (0);
-failed:
- if (aui->aui_ac97i != NULL)
- ac97_destroy(aui->aui_ac97i);
- if (aui->aui_dmat)
- bus_dma_tag_destroy(aui->aui_dmat);
- if (aui->aui_irqh != NULL)
- bus_teardown_intr(dev, aui->aui_irq, aui->aui_irqh);
- if (aui->aui_irq)
- bus_release_resource(dev, aui->aui_irqtype,
- aui->aui_irqid, aui->aui_irq);
- if (aui->aui_reg)
- bus_release_resource(dev, aui->aui_regtype,
- aui->aui_regid, aui->aui_reg);
- free(aui, M_DEVBUF);
- return (ENXIO);
-}
-
-/*
- * Detach
- */
-static int
-au88x0_pci_detach(device_t dev)
-{
- struct au88x0_info *aui;
- int error;
-
- aui = pcm_getdevinfo(dev);
- if ((error = pcm_unregister(dev)) != 0)
- return (error);
-
- /* release resources in reverse order */
- bus_dma_tag_destroy(aui->aui_dmat);
- bus_teardown_intr(dev, aui->aui_irq, aui->aui_irqh);
- bus_release_resource(dev, aui->aui_irqtype,
- aui->aui_irqid, aui->aui_irq);
- bus_release_resource(dev, aui->aui_regtype,
- aui->aui_regid, aui->aui_reg);
- free(aui, M_DEVBUF);
-
- return (0);
-}
-
-/*
- * Driver glue
- */
-static device_method_t au88x0_methods[] = {
- DEVMETHOD(device_probe, au88x0_pci_probe),
- DEVMETHOD(device_attach, au88x0_pci_attach),
- DEVMETHOD(device_detach, au88x0_pci_detach),
- { 0, 0 }
-};
-
-static driver_t au88x0_driver = {
- "pcm",
- au88x0_methods,
- PCM_SOFTC_SIZE,
-};
-
-DRIVER_MODULE(snd_au88x0, pci, au88x0_driver, pcm_devclass, 0, 0);
-MODULE_DEPEND(snd_au88x0, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
-MODULE_VERSION(snd_au88x0, 1);
diff --git a/sys/dev/sound/pci/au88x0.h b/sys/dev/sound/pci/au88x0.h
deleted file mode 100644
index 15f7b76..0000000
--- a/sys/dev/sound/pci/au88x0.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*-
- * Copyright (c) 2003 Dag-Erling Coïdan Smørgrav
- * 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
- * in this position and unchanged.
- * 2. Redistributions in binary form must 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 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 _AU88X0_H_INCLUDED
-#define _AU88X0_H_INCLUDED
-
-/*
- * Chipset parameters
- */
-struct au88x0_chipset {
- const char *auc_name;
- uint32_t auc_pci_id;
-
- /* General control register */
- uint32_t auc_control;
-#define AU88X0_CTL_MIDI_ENABLE 0x0001
-#define AU88X0_CTL_GAME_ENABLE 0x0008
-#define AU88X0_CTL_IRQ_ENABLE 0x4000
-
- /* IRQ control register */
- uint32_t auc_irq_source;
-#define AU88X0_IRQ_FATAL_ERR 0x0001
-#define AU88X0_IRQ_PARITY_ERR 0x0002
-#define AU88X0_IRQ_REG_ERR 0x0004
-#define AU88X0_IRQ_FIFO_ERR 0x0008
-#define AU88X0_IRQ_DMA_ERR 0x0010
-#define AU88X0_IRQ_PCMOUT 0x0020
-#define AU88X0_IRQ_TIMER 0x1000
-#define AU88X0_IRQ_MIDI 0x2000
-#define AU88X0_IRQ_MODEM 0x4000
- uint32_t auc_irq_mask;
- uint32_t auc_irq_control;
-#define AU88X0_IRQ_PENDING_BIT 0x0001
- uint32_t auc_irq_status;
-
- /* DMA control registers */
- uint32_t auc_dma_control;
-
- /* FIFOs */
- int auc_fifo_size;
- int auc_wt_fifos;
- uint32_t auc_wt_fifo_base;
- uint32_t auc_wt_fifo_ctl;
- uint32_t auc_wt_dma_ctl;
- int auc_adb_fifos;
- uint32_t auc_adb_fifo_base;
- uint32_t auc_adb_fifo_ctl;
- uint32_t auc_adb_dma_ctl;
-
- /* Routing */
- uint32_t auc_adb_route_base;
- int auc_adb_route_bits;
- int auc_adb_codec_in;
- int auc_adb_codec_out;
-};
-
-/*
- * Channel information
- */
-struct au88x0_chan_info {
- struct au88x0_info *auci_aui;
- struct pcm_channel *auci_pcmchan;
- struct snd_dbuf *auci_buf;
- int auci_dir;
-};
-
-/*
- * Device information
- */
-struct au88x0_info {
- /* the device we're associated with */
- device_t aui_dev;
- uint32_t aui_model;
- struct au88x0_chipset *aui_chipset;
-
- /* parameters */
- bus_size_t aui_bufsize;
- int aui_wt_fifos;
- int aui_wt_fifo_ctl;
- int aui_adb_fifos;
- int aui_adb_fifo_ctl;
- int aui_fifo_size;
- uint32_t aui_chanbase;
-
- /* bus_space tag and handle */
- bus_space_tag_t aui_spct;
- bus_space_handle_t aui_spch;
-
- /* register space */
- int aui_regtype;
- int aui_regid;
- struct resource *aui_reg;
-
- /* irq */
- int aui_irqtype;
- int aui_irqid;
- struct resource *aui_irq;
- void *aui_irqh;
-
- /* dma */
- bus_dma_tag_t aui_dmat;
-
- /* codec */
- struct ac97_info *aui_ac97i;
-
- /* channels */
- struct au88x0_chan_info aui_chan[2];
-};
-
-/*
- * Common parameters
- */
-#define AU88X0_SETTLE_DELAY 1000
-#define AU88X0_RETRY_COUNT 10
-#define AU88X0_BUFSIZE_MIN 0x1000
-#define AU88X0_BUFSIZE_DFLT 0x4000
-#define AU88X0_BUFSIZE_MAX 0x4000
-
-/*
- * Codec control registers
- *
- * AU88X0_CODEC_CHANNEL array of 32 32-bit words
- *
- * AU88X0_CODEC_CONTROL control register
- *
- * bit 16 ready
- *
- * AU88X0_CODEC_IO I/O register
- *
- * bits 0-15 contents of codec register
- * bits 16-22 address of codec register
- * bit 23 0 for read, 1 for write
- */
-#define AU88X0_CODEC_CHANNEL 0x29080
-#define AU88X0_CODEC_CONTROL 0x29184
-#define AU88X0_CDCTL_WROK 0x00000100
-#define AU88X0_CODEC_IO 0x29188
-#define AU88X0_CDIO_DATA_SHIFT 0
-#define AU88X0_CDIO_DATA_MASK 0x0000ffff
-#define AU88X0_CDIO_ADDR_SHIFT 16
-#define AU88X0_CDIO_ADDR_MASK 0x007f0000
-#define AU88X0_CDIO_RDBIT 0x00000000
-#define AU88X0_CDIO_WRBIT 0x00800000
-#define AU88X0_CDIO_READ(a) (AU88X0_CDIO_RDBIT | \
- (((a) << AU88X0_CDIO_ADDR_SHIFT) & AU88X0_CDIO_ADDR_MASK))
-#define AU88X0_CDIO_WRITE(a, d) (AU88X0_CDIO_WRBIT | \
- (((a) << AU88X0_CDIO_ADDR_SHIFT) & AU88X0_CDIO_ADDR_MASK) | \
- (((d) << AU88X0_CDIO_DATA_SHIFT) & AU88X0_CDIO_DATA_MASK))
-#define AU88X0_CODEC_ENABLE 0x29190
-
-#endif
diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c
index 7e9d1bd..cda1e82 100644
--- a/sys/dev/sound/pci/cmi.c
+++ b/sys/dev/sound/pci/cmi.c
@@ -60,6 +60,7 @@ SND_DECLARE_FILE("$FreeBSD$");
#define CMI8338B_PCI_ID 0x010113f6
#define CMI8738_PCI_ID 0x011113f6
#define CMI8738B_PCI_ID 0x011213f6
+#define CMI120_USB_ID 0x01030d8c
/* Buffer size max is 64k for permitted DMA boundaries */
#define CMI_DEFAULT_BUFSZ 16384
@@ -916,6 +917,9 @@ cmi_probe(device_t dev)
case CMI8738B_PCI_ID:
device_set_desc(dev, "CMedia CMI8738B");
return BUS_PROBE_DEFAULT;
+ case CMI120_USB_ID:
+ device_set_desc(dev, "CMedia CMI120");
+ return BUS_PROBE_DEFAULT;
default:
return ENXIO;
}
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 8ee7106..afdd638 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -83,7 +83,7 @@
#include "mixer_if.h"
-#define HDA_DRV_TEST_REV "20081226_0122"
+#define HDA_DRV_TEST_REV "20090131_0127"
SND_DECLARE_FILE("$FreeBSD$");
@@ -149,6 +149,7 @@ SND_DECLARE_FILE("$FreeBSD$");
#define HDA_INTEL_82801H HDA_MODEL_CONSTRUCT(INTEL, 0x284b)
#define HDA_INTEL_82801I HDA_MODEL_CONSTRUCT(INTEL, 0x293e)
#define HDA_INTEL_82801J HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e)
+#define HDA_INTEL_PCH HDA_MODEL_CONSTRUCT(INTEL, 0x3b56)
#define HDA_INTEL_SCH HDA_MODEL_CONSTRUCT(INTEL, 0x811b)
#define HDA_INTEL_ALL HDA_MODEL_CONSTRUCT(INTEL, 0xffff)
@@ -178,6 +179,19 @@ SND_DECLARE_FILE("$FreeBSD$");
#define ATI_VENDORID 0x1002
#define HDA_ATI_SB450 HDA_MODEL_CONSTRUCT(ATI, 0x437b)
#define HDA_ATI_SB600 HDA_MODEL_CONSTRUCT(ATI, 0x4383)
+#define HDA_ATI_RS600 HDA_MODEL_CONSTRUCT(ATI, 0x793b)
+#define HDA_ATI_RS690 HDA_MODEL_CONSTRUCT(ATI, 0x7919)
+#define HDA_ATI_RS780 HDA_MODEL_CONSTRUCT(ATI, 0x960f)
+#define HDA_ATI_R600 HDA_MODEL_CONSTRUCT(ATI, 0xaa00)
+#define HDA_ATI_RV630 HDA_MODEL_CONSTRUCT(ATI, 0xaa08)
+#define HDA_ATI_RV610 HDA_MODEL_CONSTRUCT(ATI, 0xaa10)
+#define HDA_ATI_RV670 HDA_MODEL_CONSTRUCT(ATI, 0xaa18)
+#define HDA_ATI_RV635 HDA_MODEL_CONSTRUCT(ATI, 0xaa20)
+#define HDA_ATI_RV620 HDA_MODEL_CONSTRUCT(ATI, 0xaa28)
+#define HDA_ATI_RV770 HDA_MODEL_CONSTRUCT(ATI, 0xaa30)
+#define HDA_ATI_RV730 HDA_MODEL_CONSTRUCT(ATI, 0xaa38)
+#define HDA_ATI_RV710 HDA_MODEL_CONSTRUCT(ATI, 0xaa40)
+#define HDA_ATI_RV740 HDA_MODEL_CONSTRUCT(ATI, 0xaa48)
#define HDA_ATI_ALL HDA_MODEL_CONSTRUCT(ATI, 0xffff)
/* VIA */
@@ -469,6 +483,7 @@ static const struct {
{ HDA_INTEL_82801H, "Intel 82801H" },
{ HDA_INTEL_82801I, "Intel 82801I" },
{ HDA_INTEL_82801J, "Intel 82801J" },
+ { HDA_INTEL_PCH, "Intel PCH" },
{ HDA_INTEL_SCH, "Intel SCH" },
{ HDA_NVIDIA_MCP51, "NVidia MCP51" },
{ HDA_NVIDIA_MCP55, "NVidia MCP55" },
@@ -488,8 +503,20 @@ static const struct {
{ HDA_NVIDIA_MCP79_2, "NVidia MCP79" },
{ HDA_NVIDIA_MCP79_3, "NVidia MCP79" },
{ HDA_NVIDIA_MCP79_4, "NVidia MCP79" },
- { HDA_ATI_SB450, "ATI SB450" },
- { HDA_ATI_SB600, "ATI SB600" },
+ { HDA_ATI_SB450, "ATI SB450" },
+ { HDA_ATI_SB600, "ATI SB600" },
+ { HDA_ATI_RS600, "ATI RS600" },
+ { HDA_ATI_RS690, "ATI RS690" },
+ { HDA_ATI_RS780, "ATI RS780" },
+ { HDA_ATI_R600, "ATI R600" },
+ { HDA_ATI_RV610, "ATI RV610" },
+ { HDA_ATI_RV620, "ATI RV620" },
+ { HDA_ATI_RV630, "ATI RV630" },
+ { HDA_ATI_RV635, "ATI RV635" },
+ { HDA_ATI_RV710, "ATI RV710" },
+ { HDA_ATI_RV730, "ATI RV730" },
+ { HDA_ATI_RV740, "ATI RV740" },
+ { HDA_ATI_RV770, "ATI RV770" },
{ HDA_VIA_VT82XX, "VIA VT8251/8237A" },
{ HDA_SIS_966, "SiS 966" },
{ HDA_ULI_M5461, "ULI M5461" },
@@ -671,6 +698,7 @@ static const struct {
/* Silicon Image */
#define SII_VENDORID 0x1095
+#define HDA_CODEC_SII1390 HDA_CODEC_CONSTRUCT(SII, 0x1390)
#define HDA_CODEC_SII1392 HDA_CODEC_CONSTRUCT(SII, 0x1392)
#define HDA_CODEC_SIIXXXX HDA_CODEC_CONSTRUCT(SII, 0xffff)
@@ -706,6 +734,22 @@ static const struct {
#define HDA_CODEC_VT1708B_5 HDA_CODEC_CONSTRUCT(VIA, 0xe725)
#define HDA_CODEC_VT1708B_6 HDA_CODEC_CONSTRUCT(VIA, 0xe726)
#define HDA_CODEC_VT1708B_7 HDA_CODEC_CONSTRUCT(VIA, 0xe727)
+#define HDA_CODEC_VT1708S_0 HDA_CODEC_CONSTRUCT(VIA, 0x0397)
+#define HDA_CODEC_VT1708S_1 HDA_CODEC_CONSTRUCT(VIA, 0x1397)
+#define HDA_CODEC_VT1708S_2 HDA_CODEC_CONSTRUCT(VIA, 0x2397)
+#define HDA_CODEC_VT1708S_3 HDA_CODEC_CONSTRUCT(VIA, 0x3397)
+#define HDA_CODEC_VT1708S_4 HDA_CODEC_CONSTRUCT(VIA, 0x4397)
+#define HDA_CODEC_VT1708S_5 HDA_CODEC_CONSTRUCT(VIA, 0x5397)
+#define HDA_CODEC_VT1708S_6 HDA_CODEC_CONSTRUCT(VIA, 0x6397)
+#define HDA_CODEC_VT1708S_7 HDA_CODEC_CONSTRUCT(VIA, 0x7397)
+#define HDA_CODEC_VT1702_0 HDA_CODEC_CONSTRUCT(VIA, 0x0398)
+#define HDA_CODEC_VT1702_1 HDA_CODEC_CONSTRUCT(VIA, 0x1398)
+#define HDA_CODEC_VT1702_2 HDA_CODEC_CONSTRUCT(VIA, 0x2398)
+#define HDA_CODEC_VT1702_3 HDA_CODEC_CONSTRUCT(VIA, 0x3398)
+#define HDA_CODEC_VT1702_4 HDA_CODEC_CONSTRUCT(VIA, 0x4398)
+#define HDA_CODEC_VT1702_5 HDA_CODEC_CONSTRUCT(VIA, 0x5398)
+#define HDA_CODEC_VT1702_6 HDA_CODEC_CONSTRUCT(VIA, 0x6398)
+#define HDA_CODEC_VT1702_7 HDA_CODEC_CONSTRUCT(VIA, 0x7398)
#define HDA_CODEC_VTXXXX HDA_CODEC_CONSTRUCT(VIA, 0xffff)
/* ATI */
@@ -716,9 +760,18 @@ static const struct {
#define HDA_CODEC_ATIXXXX HDA_CODEC_CONSTRUCT(ATI, 0xffff)
/* NVIDIA */
+#define HDA_CODEC_NVIDIAMCP78 HDA_CODEC_CONSTRUCT(NVIDIA, 0x0002)
+#define HDA_CODEC_NVIDIAMCP78_2 HDA_CODEC_CONSTRUCT(NVIDIA, 0x0006)
+#define HDA_CODEC_NVIDIAMCP7A HDA_CODEC_CONSTRUCT(NVIDIA, 0x0007)
+#define HDA_CODEC_NVIDIAMCP67 HDA_CODEC_CONSTRUCT(NVIDIA, 0x0067)
+#define HDA_CODEC_NVIDIAMCP73 HDA_CODEC_CONSTRUCT(NVIDIA, 0x8001)
#define HDA_CODEC_NVIDIAXXXX HDA_CODEC_CONSTRUCT(NVIDIA, 0xffff)
/* INTEL */
+#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_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
/* Codecs */
@@ -833,10 +886,36 @@ static const struct {
{ HDA_CODEC_VT1708B_5, "VIA VT1708B_5" },
{ HDA_CODEC_VT1708B_6, "VIA VT1708B_6" },
{ HDA_CODEC_VT1708B_7, "VIA VT1708B_7" },
+ { HDA_CODEC_VT1708S_0, "VIA VT1708S_0" },
+ { HDA_CODEC_VT1708S_1, "VIA VT1708S_1" },
+ { HDA_CODEC_VT1708S_2, "VIA VT1708S_2" },
+ { HDA_CODEC_VT1708S_3, "VIA VT1708S_3" },
+ { HDA_CODEC_VT1708S_4, "VIA VT1708S_4" },
+ { HDA_CODEC_VT1708S_5, "VIA VT1708S_5" },
+ { HDA_CODEC_VT1708S_6, "VIA VT1708S_6" },
+ { HDA_CODEC_VT1708S_7, "VIA VT1708S_7" },
+ { HDA_CODEC_VT1702_0, "VIA VT1702_0" },
+ { HDA_CODEC_VT1702_1, "VIA VT1702_1" },
+ { HDA_CODEC_VT1702_2, "VIA VT1702_2" },
+ { HDA_CODEC_VT1702_3, "VIA VT1702_3" },
+ { HDA_CODEC_VT1702_4, "VIA VT1702_4" },
+ { HDA_CODEC_VT1702_5, "VIA VT1702_5" },
+ { HDA_CODEC_VT1702_6, "VIA VT1702_6" },
+ { HDA_CODEC_VT1702_7, "VIA VT1702_7" },
{ HDA_CODEC_ATIRS600_1,"ATI RS600 HDMI" },
{ HDA_CODEC_ATIRS600_2,"ATI RS600 HDMI" },
{ HDA_CODEC_ATIRS690, "ATI RS690/780 HDMI" },
{ HDA_CODEC_ATIR6XX, "ATI R6xx HDMI" },
+ { HDA_CODEC_NVIDIAMCP67, "NVidia MCP67 HDMI" },
+ { HDA_CODEC_NVIDIAMCP73, "NVidia MCP73 HDMI" },
+ { HDA_CODEC_NVIDIAMCP78, "NVidia MCP78 HDMI" },
+ { HDA_CODEC_NVIDIAMCP78_2, "NVidia MCP78 HDMI" },
+ { HDA_CODEC_NVIDIAMCP7A, "NVidia MCP7A HDMI" },
+ { HDA_CODEC_INTELG45_1, "Intel G45 HDMI" },
+ { HDA_CODEC_INTELG45_2, "Intel G45 HDMI" },
+ { HDA_CODEC_INTELG45_3, "Intel G45 HDMI" },
+ { HDA_CODEC_INTELG45_4, "Intel G45 HDMI" },
+ { HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" },
{ HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" },
/* Unknown codec */
{ HDA_CODEC_ALCXXXX, "Realtek (Unknown)" },
@@ -2443,9 +2522,10 @@ hdac_widget_pin_parse(struct hdac_widget *w)
{
struct hdac_softc *sc = w->devinfo->codec->sc;
uint32_t config, pincap;
- const char *devstr, *connstr;
+ const char *devstr;
nid_t cad = w->devinfo->codec->cad;
nid_t nid = w->nid;
+ int conn, color;
config = hdac_widget_pin_getconfig(w);
w->wclass.pin.config = config;
@@ -2467,13 +2547,19 @@ hdac_widget_pin_parse(struct hdac_widget *w)
devstr = HDA_DEVS[(config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) >>
HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT];
- connstr = HDA_CONNS[(config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >>
- HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT];
+ conn = (config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >>
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT;
+ color = (config & HDA_CONFIG_DEFAULTCONF_COLOR_MASK) >>
+ HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT;
strlcat(w->name, ": ", sizeof(w->name));
strlcat(w->name, devstr, sizeof(w->name));
strlcat(w->name, " (", sizeof(w->name));
- strlcat(w->name, connstr, sizeof(w->name));
+ if (conn == 0 && color != 0 && color != 15) {
+ strlcat(w->name, HDA_COLORS[color], sizeof(w->name));
+ strlcat(w->name, " ", sizeof(w->name));
+ }
+ strlcat(w->name, HDA_CONNS[conn], sizeof(w->name));
strlcat(w->name, ")", sizeof(w->name));
}
@@ -2499,8 +2585,15 @@ hdac_widget_getcaps(struct hdac_widget *w, int *waspin)
Change beeper pin node type to beeper to help parser. */
*waspin = 0;
switch (id) {
+ case HDA_CODEC_AD1882:
+ case HDA_CODEC_AD1883:
+ case HDA_CODEC_AD1984:
+ case HDA_CODEC_AD1984A:
+ case HDA_CODEC_AD1984B:
+ case HDA_CODEC_AD1987:
case HDA_CODEC_AD1988:
case HDA_CODEC_AD1988B:
+ case HDA_CODEC_AD1989B:
beeper = 26;
break;
case HDA_CODEC_ALC260:
@@ -4567,6 +4660,33 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo)
* nid: 26 = Line-in, leave it alone.
*/
break;
+ case HDA_CODEC_AD1983:
+ /*
+ * This codec has several possible usages, but none
+ * fit the parser best. Help parser to choose better.
+ */
+ /* Disable direct unmixed playback to get pcm volume. */
+ w = hdac_widget_get(devinfo, 5);
+ if (w != NULL)
+ w->connsenable[0] = 0;
+ w = hdac_widget_get(devinfo, 6);
+ if (w != NULL)
+ w->connsenable[0] = 0;
+ w = hdac_widget_get(devinfo, 11);
+ if (w != NULL)
+ w->connsenable[0] = 0;
+ /* Disable mic and line selectors. */
+ w = hdac_widget_get(devinfo, 12);
+ if (w != NULL)
+ w->connsenable[1] = 0;
+ w = hdac_widget_get(devinfo, 13);
+ if (w != NULL)
+ w->connsenable[1] = 0;
+ /* Disable recording from mono playback mix. */
+ w = hdac_widget_get(devinfo, 20);
+ if (w != NULL)
+ w->connsenable[3] = 0;
+ break;
case HDA_CODEC_AD1986A:
/*
* This codec has overcomplicated input mixing.
@@ -5472,7 +5592,7 @@ hdac_audio_disable_crossas(struct hdac_devinfo *devinfo)
struct hdac_audio_ctl *ctl;
int i, j;
- /* Disable crossassociatement connections. */
+ /* Disable crossassociatement and unwanted crosschannel connections. */
/* ... using selectors */
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdac_widget_get(devinfo, i);
@@ -5490,7 +5610,10 @@ hdac_audio_disable_crossas(struct hdac_devinfo *devinfo)
cw = hdac_widget_get(devinfo, w->conns[j]);
if (cw == NULL || w->enable == 0)
continue;
- if (w->bindas == cw->bindas || cw->bindas == -2)
+ if (cw->bindas == -2)
+ continue;
+ if (w->bindas == cw->bindas &&
+ (w->bindseqmask & cw->bindseqmask) != 0)
continue;
w->connsenable[j] = 0;
HDA_BOOTHVERBOSE(
@@ -5509,7 +5632,8 @@ hdac_audio_disable_crossas(struct hdac_devinfo *devinfo)
if (ctl->widget->bindas == -2 ||
ctl->childwidget->bindas == -2)
continue;
- if (ctl->widget->bindas != ctl->childwidget->bindas) {
+ if (ctl->widget->bindas != ctl->childwidget->bindas ||
+ (ctl->widget->bindseqmask & ctl->childwidget->bindseqmask) == 0) {
ctl->forcemute = 1;
ctl->muted = HDA_AMP_MUTE_ALL;
ctl->left = 0;
@@ -6025,6 +6149,29 @@ hdac_audio_prepare_pin_ctrl(struct hdac_devinfo *devinfo)
}
static void
+hdac_audio_ctl_commit(struct hdac_devinfo *devinfo)
+{
+ struct hdac_audio_ctl *ctl;
+ int i, z;
+
+ i = 0;
+ while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
+ if (ctl->enable == 0 || ctl->ossmask != 0) {
+ /* Mute disabled and mixer controllable controls.
+ * Last will be initialized by mixer_init().
+ * This expected to reduce click on startup. */
+ hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_ALL, 0, 0);
+ continue;
+ }
+ /* Init fixed controls to 0dB amplification. */
+ z = ctl->offset;
+ if (z > ctl->step)
+ z = ctl->step;
+ hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_NONE, z, z);
+ }
+}
+
+static void
hdac_audio_commit(struct hdac_devinfo *devinfo)
{
struct hdac_softc *sc = devinfo->codec->sc;
@@ -6040,11 +6187,41 @@ hdac_audio_commit(struct hdac_devinfo *devinfo)
hdac_command(sc, HDA_CMD_12BIT(cad, devinfo->nid,
0x7e7, 0), cad);
+ /* Commit controls. */
+ hdac_audio_ctl_commit(devinfo);
+
+ /* Commit selectors, pins and EAPD. */
+ for (i = 0; i < devinfo->nodecnt; i++) {
+ w = &devinfo->widget[i];
+ if (w == NULL)
+ continue;
+ if (w->selconn == -1)
+ w->selconn = 0;
+ if (w->nconns > 0)
+ hdac_widget_connection_select(w, w->selconn);
+ if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
+ hdac_command(sc,
+ HDA_CMD_SET_PIN_WIDGET_CTRL(cad, w->nid,
+ w->wclass.pin.ctrl), cad);
+ }
+ if (w->param.eapdbtl != HDAC_INVALID) {
+ uint32_t val;
+
+ val = w->param.eapdbtl;
+ if (devinfo->function.audio.quirks &
+ HDA_QUIRK_EAPDINV)
+ val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
+ hdac_command(sc,
+ HDA_CMD_SET_EAPD_BTL_ENABLE(cad, w->nid,
+ val), cad);
+ }
+ }
+
+ /* Commit GPIOs. */
gdata = 0;
gmask = 0;
gdir = 0;
commitgpio = 0;
-
numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(
devinfo->function.audio.gpio);
@@ -6099,54 +6276,6 @@ hdac_audio_commit(struct hdac_devinfo *devinfo)
HDA_CMD_SET_GPIO_DATA(cad, devinfo->nid,
gdata), cad);
}
-
- for (i = 0; i < devinfo->nodecnt; i++) {
- w = &devinfo->widget[i];
- if (w == NULL)
- continue;
- if (w->selconn == -1)
- w->selconn = 0;
- if (w->nconns > 0)
- hdac_widget_connection_select(w, w->selconn);
- if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
- hdac_command(sc,
- HDA_CMD_SET_PIN_WIDGET_CTRL(cad, w->nid,
- w->wclass.pin.ctrl), cad);
- }
- if (w->param.eapdbtl != HDAC_INVALID) {
- uint32_t val;
-
- val = w->param.eapdbtl;
- if (devinfo->function.audio.quirks &
- HDA_QUIRK_EAPDINV)
- val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
- hdac_command(sc,
- HDA_CMD_SET_EAPD_BTL_ENABLE(cad, w->nid,
- val), cad);
-
- }
- }
-}
-
-static void
-hdac_audio_ctl_commit(struct hdac_devinfo *devinfo)
-{
- struct hdac_audio_ctl *ctl;
- int i, z;
-
- i = 0;
- while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
- if (ctl->enable == 0) {
- /* Mute disabled controls. */
- hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_ALL, 0, 0);
- continue;
- }
- /* Init controls to 0dB amplification. */
- z = ctl->offset;
- if (z > ctl->step)
- z = ctl->step;
- hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_NONE, z, z);
- }
}
static void
@@ -6977,7 +7106,7 @@ hdac_config_fetch(struct hdac_softc *sc, uint32_t *on, uint32_t *off)
hdac_quirks_tab[k].key, len - inv) != 0)
continue;
if (len - inv != strlen(hdac_quirks_tab[k].key))
- break;
+ continue;
HDA_BOOTVERBOSE(
printf(" %s%s", (inv != 0) ? "no" : "",
hdac_quirks_tab[k].key);
@@ -7391,10 +7520,6 @@ hdac_attach2(void *arg)
);
hdac_audio_commit(devinfo);
HDA_BOOTHVERBOSE(
- device_printf(sc->dev, "Ctls commit...\n");
- );
- hdac_audio_ctl_commit(devinfo);
- HDA_BOOTHVERBOSE(
device_printf(sc->dev, "HP switch init...\n");
);
hdac_hp_switch_init(devinfo);
@@ -7644,10 +7769,6 @@ hdac_resume(device_t dev)
);
hdac_audio_commit(devinfo);
HDA_BOOTHVERBOSE(
- device_printf(dev, "Ctls commit...\n");
- );
- hdac_audio_ctl_commit(devinfo);
- HDA_BOOTHVERBOSE(
device_printf(dev, "HP switch init...\n");
);
hdac_hp_switch_init(devinfo);
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index f13ae31..56c1aaf 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -814,7 +814,12 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
case SNDCTL_SYSINFO:
sound_oss_sysinfo((oss_sysinfo *)arg);
break;
+ case SNDCTL_CARDINFO:
+ ret = sound_oss_card_info((oss_card_info *)arg);
+ break;
case SNDCTL_AUDIOINFO:
+ case SNDCTL_AUDIOINFO_EX:
+ case SNDCTL_ENGINEINFO:
ret = dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg);
break;
case SNDCTL_MIXERINFO:
@@ -1370,9 +1375,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
case SNDCTL_DSP_GETCAPS:
pcm_lock(d);
- *arg_i = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER;
+ *arg_i = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER;
if (rdch && wrch && !(dsp_get_flags(i_dev) & SD_F_SIMPLEX))
- *arg_i |= DSP_CAP_DUPLEX;
+ *arg_i |= PCM_CAP_DUPLEX;
pcm_unlock(d);
break;
@@ -1770,18 +1775,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
break;
#if 0
/**
- * @note The SNDCTL_CARDINFO ioctl was omitted per 4Front developer
- * documentation. "The usability of this call is very limited. It's
- * provided only for completeness of the API. OSS API doesn't have
- * any concept of card. Any information returned by this ioctl calld
- * is reserved exclusively for the utility programs included in the
- * OSS package. Applications should not try to use for this
- * information in any ways."
- */
- case SNDCTL_CARDINFO:
- ret = EINVAL;
- break;
- /**
* @note The S/PDIF interface ioctls, @c SNDCTL_DSP_READCTL and
* @c SNDCTL_DSP_WRITECTL have been omitted at the suggestion of
* 4Front Technologies.
@@ -2282,13 +2275,14 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
/*
* These flags stolen from SNDCTL_DSP_GETCAPS handler.
* Note, however, that a single channel operates in
- * only one direction, so DSP_CAP_DUPLEX is out.
+ * only one direction, so PCM_CAP_DUPLEX is out.
*/
/**
* @todo @c SNDCTL_AUDIOINFO::caps - Make drivers keep
* these in pcmchan::caps?
*/
- ai->caps = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER;
+ ai->caps = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER |
+ ((ch->direction == PCMDIR_PLAY) ? PCM_CAP_OUTPUT : PCM_CAP_INPUT);
/*
* Collect formats supported @b natively by the
@@ -2345,7 +2339,8 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
* @c real_device - OSSv4 docs: "Obsolete."
*/
ai->real_device = -1;
- strlcpy(ai->devnode, devname, sizeof(ai->devnode));
+ strlcpy(ai->devnode, "/dev/", sizeof(ai->devnode));
+ strlcat(ai->devnode, devname, sizeof(ai->devnode));
ai->enabled = device_is_attached(d->dev) ? 1 : 0;
/**
* @note
@@ -2369,6 +2364,9 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
for (i = 0; i < ai->nrates; i++)
ai->rates[i] = rates[i];
+
+ ai->next_play_engine = 0;
+ ai->next_rec_engine = 0;
CHN_UNLOCK(ch);
}
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index dd3b7bb..d25d745 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -1022,6 +1022,27 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
int ret, *arg_i = (int *)arg;
int v = -1, j = cmd & 0xff;
+ /*
+ * Certain ioctls may be made on any type of device (audio, mixer,
+ * and MIDI). Handle those special cases here.
+ */
+ if (IOCGROUP(cmd) == 'X') {
+ switch (cmd) {
+ case SNDCTL_SYSINFO:
+ sound_oss_sysinfo((oss_sysinfo *)arg);
+ return (0);
+ case SNDCTL_CARDINFO:
+ return (sound_oss_card_info((oss_card_info *)arg));
+ case SNDCTL_AUDIOINFO:
+ case SNDCTL_AUDIOINFO_EX:
+ case SNDCTL_ENGINEINFO:
+ return (dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg));
+ case SNDCTL_MIXERINFO:
+ return (mixer_oss_mixerinfo(i_dev, (oss_mixerinfo *)arg));
+ }
+ return (EINVAL);
+ }
+
m = i_dev->si_drv1;
if (m == NULL)
@@ -1033,11 +1054,6 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
return (EBADF);
}
- if (cmd == SNDCTL_MIXERINFO) {
- snd_mtxunlock(m->lock);
- return (mixer_oss_mixerinfo(i_dev, (oss_mixerinfo *)arg));
- }
-
if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) {
if (j == SOUND_MIXER_RECSRC)
ret = mixer_setrecsrc(m, *arg_i);
@@ -1074,16 +1090,6 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
ret = 0;
switch (cmd) {
- /** @todo Double check return values, error codes. */
- case SNDCTL_SYSINFO:
- snd_mtxunlock(m->lock);
- sound_oss_sysinfo((oss_sysinfo *)arg);
- return (ret);
- break;
- case SNDCTL_AUDIOINFO:
- snd_mtxunlock(m->lock);
- return (dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg));
- break;
case SNDCTL_DSP_GET_RECSRC_NAMES:
bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo));
break;
@@ -1097,7 +1103,7 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
*arg_i = SOUND_VERSION;
break;
default:
- ret = ENXIO;
+ ret = EINVAL;
break;
}
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index b842ae8..cdaf8ba 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -1405,6 +1405,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
{
static char si_product[] = "FreeBSD native OSS ABI";
static char si_version[] = __XSTRING(__FreeBSD_version);
+ static char si_license[] = "BSD";
static int intnbits = sizeof(int) * 8; /* Better suited as macro?
Must pester a C guru. */
@@ -1417,6 +1418,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
strlcpy(si->product, si_product, sizeof(si->product));
strlcpy(si->version, si_version, sizeof(si->version));
si->versionnum = SOUND_VERSION;
+ strlcpy(si->license, si_license, sizeof(si->license));
/*
* Iterate over PCM devices and their channels, gathering up data
@@ -1454,6 +1456,7 @@ sound_oss_sysinfo(oss_sysinfo *si)
pcm_unlock(d);
}
+ si->numaudioengines = si->numaudios;
si->numsynths = 0; /* OSSv4 docs: this field is obsolete */
/**
@@ -1490,6 +1493,38 @@ sound_oss_sysinfo(oss_sysinfo *si)
si->filler[i] = -1;
}
+int
+sound_oss_card_info(oss_card_info *si)
+{
+ struct snddev_info *d;
+ int i, ncards;
+
+ ncards = 0;
+
+ for (i = 0; pcm_devclass != NULL &&
+ i < devclass_get_maxunit(pcm_devclass); i++) {
+ d = devclass_get_softc(pcm_devclass, i);
+ if (!PCM_REGISTERED(d))
+ continue;
+
+ if (ncards++ != si->card)
+ continue;
+
+ mtx_assert(d->lock, MA_NOTOWNED);
+ pcm_lock(d);
+
+ strlcpy(si->shortname, device_get_nameunit(d->dev),
+ sizeof(si->shortname));
+ strlcpy(si->longname, device_get_desc(d->dev),
+ sizeof(si->longname));
+ strlcpy(si->hw_info, d->status, sizeof(si->hw_info));
+ si->intr_count = si->ack_count = 0;
+ pcm_unlock(d);
+ return (0);
+ }
+ return (ENXIO);
+}
+
/************************************************************************/
static int
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index b743ec0..391414c 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -601,6 +601,7 @@ struct snddev_info {
};
void sound_oss_sysinfo(oss_sysinfo *);
+int sound_oss_card_info(oss_card_info *);
#ifdef PCM_DEBUG_MTX
#define pcm_lock(d) mtx_lock(((struct snddev_info *)(d))->lock)
diff --git a/sys/dev/speaker/spkr.c b/sys/dev/speaker/spkr.c
index 8d2ceed..66fd302 100644
--- a/sys/dev/speaker/spkr.c
+++ b/sys/dev/speaker/spkr.c
@@ -419,9 +419,7 @@ spkropen(dev, flags, fmt, td)
(void) printf("spkropen: entering with dev = %s\n", devtoname(dev));
#endif /* DEBUG */
- if (dev2unit(dev) != 0)
- return(ENXIO);
- else if (spkr_active)
+ if (spkr_active)
return(EBUSY);
else {
#ifdef DEBUG
@@ -444,9 +442,8 @@ spkrwrite(dev, uio, ioflag)
printf("spkrwrite: entering with dev = %s, count = %d\n",
devtoname(dev), uio->uio_resid);
#endif /* DEBUG */
- if (dev2unit(dev) != 0)
- return(ENXIO);
- else if (uio->uio_resid > (DEV_BSIZE - 1)) /* prevent system crashes */
+
+ if (uio->uio_resid > (DEV_BSIZE - 1)) /* prevent system crashes */
return(E2BIG);
else {
unsigned n;
@@ -475,15 +472,11 @@ spkrclose(dev, flags, fmt, td)
(void) printf("spkrclose: entering with dev = %s\n", devtoname(dev));
#endif /* DEBUG */
- if (dev2unit(dev) != 0)
- return(ENXIO);
- else {
- wakeup(&endtone);
- wakeup(&endrest);
- free(spkr_inbuf, M_SPKR);
- spkr_active = FALSE;
- return(0);
- }
+ wakeup(&endtone);
+ wakeup(&endrest);
+ free(spkr_inbuf, M_SPKR);
+ spkr_active = FALSE;
+ return(0);
}
static int
@@ -499,9 +492,7 @@ spkrioctl(dev, cmd, cmdarg, flags, td)
devtoname(dev), cmd);
#endif /* DEBUG */
- if (dev2unit(dev) != 0)
- return(ENXIO);
- else if (cmd == SPKRTONE) {
+ if (cmd == SPKRTONE) {
tone_t *tp = (tone_t *)cmdarg;
if (tp->frequency == 0)
diff --git a/sys/dev/syscons/scterm-dumb.c b/sys/dev/syscons/scterm-dumb.c
deleted file mode 100644
index 1c130b6..0000000
--- a/sys/dev/syscons/scterm-dumb.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
- * 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 as
- * the first lines of this file unmodified.
- * 2. Redistributions in binary form must 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 ``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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_syscons.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/consio.h>
-
-#if defined(__sparc64__) || defined(__powerpc__)
-#include <machine/sc_machdep.h>
-#else
-#include <machine/pc/display.h>
-#endif
-
-#include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
-
-#ifdef SC_DUMB_TERMINAL
-
-/* dumb terminal emulator */
-
-static sc_term_init_t dumb_init;
-static sc_term_term_t dumb_term;
-static sc_term_puts_t dumb_puts;
-static sc_term_ioctl_t dumb_ioctl;
-static sc_term_clear_t dumb_clear;
-static sc_term_input_t dumb_input;
-static void dumb_nop(void);
-
-static sc_term_sw_t sc_term_dumb = {
- { NULL, NULL },
- "dumb", /* emulator name */
- "dumb terminal", /* description */
- "*", /* matching renderer */
- 0, /* softc size */
- 0,
- dumb_init,
- dumb_term,
- dumb_puts,
- dumb_ioctl,
- (sc_term_reset_t *)dumb_nop,
- (sc_term_default_attr_t *)dumb_nop,
- dumb_clear,
- (sc_term_notify_t *)dumb_nop,
- dumb_input,
-};
-
-SCTERM_MODULE(dumb, sc_term_dumb);
-
-static int
-dumb_init(scr_stat *scp, void **softc, int code)
-{
- switch (code) {
- case SC_TE_COLD_INIT:
- ++sc_term_dumb.te_refcount;
- break;
- case SC_TE_WARM_INIT:
- break;
- }
- return 0;
-}
-
-static int
-dumb_term(scr_stat *scp, void **softc)
-{
- --sc_term_dumb.te_refcount;
- return 0;
-}
-
-static void
-dumb_puts(scr_stat *scp, u_char *buf, int len)
-{
- while (len > 0) {
- ++scp->sc->write_in_progress;
- sc_term_gen_print(scp, &buf, &len, SC_NORM_ATTR << 8);
- sc_term_gen_scroll(scp, scp->sc->scr_map[0x20],
- SC_NORM_ATTR << 8);
- --scp->sc->write_in_progress;
- }
-}
-
-static int
-dumb_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
- int flag, struct proc *p)
-{
- vid_info_t *vi;
-
- switch (cmd) {
- case GIO_ATTR: /* get current attributes */
- *(int*)data = SC_NORM_ATTR;
- return 0;
- case CONS_GETINFO: /* get current (virtual) console info */
- vi = (vid_info_t *)data;
- if (vi->size != sizeof(struct vid_info))
- return EINVAL;
- vi->mv_norm.fore = SC_NORM_ATTR & 0x0f;
- vi->mv_norm.back = (SC_NORM_ATTR >> 4) & 0x0f;
- vi->mv_rev.fore = SC_NORM_ATTR & 0x0f;
- vi->mv_rev.back = (SC_NORM_ATTR >> 4) & 0x0f;
- /*
- * The other fields are filled by the upper routine. XXX
- */
- return ENOIOCTL;
- }
- return ENOIOCTL;
-}
-
-static void
-dumb_clear(scr_stat *scp)
-{
- sc_move_cursor(scp, 0, 0);
- sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8);
- mark_all(scp);
-}
-
-static int
-dumb_input(scr_stat *scp, int c, struct tty *tp)
-{
- return FALSE;
-}
-
-static void
-dumb_nop(void)
-{
- /* nothing */
-}
-
-#endif /* SC_DUMB_TERMINAL */
diff --git a/sys/dev/syscons/scterm-sc.c b/sys/dev/syscons/scterm-sc.c
deleted file mode 100644
index b52bea8..0000000
--- a/sys/dev/syscons/scterm-sc.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*-
- * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
- * Copyright (c) 1992-1998 Søren Schmidt
- * 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 as
- * the first lines of this file unmodified.
- * 2. Redistributions in binary form must 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 ``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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_syscons.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/consio.h>
-
-#if defined(__sparc64__) || defined(__powerpc__)
-#include <machine/sc_machdep.h>
-#else
-#include <machine/pc/display.h>
-#endif
-
-#include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
-
-#ifndef SC_DUMB_TERMINAL
-
-#define MAX_ESC_PAR 5
-
-/* attribute flags */
-typedef struct {
- u_short fg; /* foreground color */
- u_short bg; /* background color */
-} color_t;
-
-typedef struct {
- int flags;
-#define SCTERM_BUSY (1 << 0)
- int esc;
- int num_param;
- int last_param;
- int param[MAX_ESC_PAR];
- int saved_xpos;
- int saved_ypos;
- int attr_mask; /* current logical attr mask */
-#define NORMAL_ATTR 0x00
-#define BLINK_ATTR 0x01
-#define BOLD_ATTR 0x02
-#define UNDERLINE_ATTR 0x04
-#define REVERSE_ATTR 0x08
-#define FG_CHANGED 0x10
-#define BG_CHANGED 0x20
- int cur_attr; /* current hardware attr word */
- color_t cur_color; /* current hardware color */
- color_t std_color; /* normal hardware color */
- color_t rev_color; /* reverse hardware color */
- color_t dflt_std_color; /* default normal color */
- color_t dflt_rev_color; /* default reverse color */
-} term_stat;
-
-static sc_term_init_t scterm_init;
-static sc_term_term_t scterm_term;
-static sc_term_puts_t scterm_puts;
-static sc_term_ioctl_t scterm_ioctl;
-static sc_term_reset_t scterm_reset;
-static sc_term_default_attr_t scterm_default_attr;
-static sc_term_clear_t scterm_clear;
-static sc_term_notify_t scterm_notify;
-static sc_term_input_t scterm_input;
-
-static sc_term_sw_t sc_term_sc = {
- { NULL, NULL },
- "sc", /* emulator name */
- "syscons terminal", /* description */
- "*", /* matching renderer, any :-) */
- sizeof(term_stat), /* softc size */
- 0,
- scterm_init,
- scterm_term,
- scterm_puts,
- scterm_ioctl,
- scterm_reset,
- scterm_default_attr,
- scterm_clear,
- scterm_notify,
- scterm_input,
-};
-
-SCTERM_MODULE(sc, sc_term_sc);
-
-static term_stat reserved_term_stat;
-static void scterm_scan_esc(scr_stat *scp, term_stat *tcp,
- u_char c);
-static int mask2attr(term_stat *tcp);
-
-static int
-scterm_init(scr_stat *scp, void **softc, int code)
-{
- term_stat *tcp;
-
- if (*softc == NULL) {
- if (reserved_term_stat.flags & SCTERM_BUSY)
- return EINVAL;
- *softc = &reserved_term_stat;
- }
- tcp = *softc;
-
- switch (code) {
- case SC_TE_COLD_INIT:
- bzero(tcp, sizeof(*tcp));
- tcp->flags = SCTERM_BUSY;
- tcp->esc = 0;
- tcp->saved_xpos = -1;
- tcp->saved_ypos = -1;
- tcp->attr_mask = NORMAL_ATTR;
- /* XXX */
- tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f;
- tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f;
- tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f;
- tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f;
- tcp->std_color = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- ++sc_term_sc.te_refcount;
- break;
-
- case SC_TE_WARM_INIT:
- tcp->esc = 0;
- tcp->saved_xpos = -1;
- tcp->saved_ypos = -1;
-#if 0
- tcp->std_color = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
-#endif
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
-
- return 0;
-}
-
-static int
-scterm_term(scr_stat *scp, void **softc)
-{
- if (*softc == &reserved_term_stat) {
- *softc = NULL;
- bzero(&reserved_term_stat, sizeof(reserved_term_stat));
- }
- --sc_term_sc.te_refcount;
- return 0;
-}
-
-static void
-scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c)
-{
- static u_char ansi_col[16] = {
- FG_BLACK, FG_RED, FG_GREEN, FG_BROWN,
- FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY,
- FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW,
- FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE
- };
- static int cattrs[] = {
- 0, /* block */
- CONS_BLINK_CURSOR, /* blinking block */
- CONS_CHAR_CURSOR, /* underline */
- CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */
- CONS_RESET_CURSOR, /* reset to default */
- CONS_HIDDEN_CURSOR, /* hide cursor */
- };
- static int tcattrs[] = {
- CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */
- CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */
- CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */
- };
- sc_softc_t *sc;
- int v0, v1, v2;
- int i, n;
-
- i = n = 0;
- sc = scp->sc;
- if (tcp->esc == 1) { /* seen ESC */
- switch (c) {
-
- case '7': /* Save cursor position */
- tcp->saved_xpos = scp->xpos;
- tcp->saved_ypos = scp->ypos;
- break;
-
- case '8': /* Restore saved cursor position */
- if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
- sc_move_cursor(scp, tcp->saved_xpos,
- tcp->saved_ypos);
- break;
-
- case '[': /* Start ESC [ sequence */
- tcp->esc = 2;
- tcp->last_param = -1;
- for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
- tcp->param[i] = 1;
- tcp->num_param = 0;
- return;
-
- case 'M': /* Move cursor up 1 line, scroll if at top */
- sc_term_up_scroll(scp, 1, sc->scr_map[0x20],
- tcp->cur_attr, 0, 0);
- break;
-#ifdef notyet
- case 'Q':
- tcp->esc = 4;
- return;
-#endif
- case 'c': /* reset */
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color
- = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_attr = mask2attr(tcp);
- sc_change_cursor_shape(scp,
- CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1);
- sc_clear_screen(scp);
- break;
-
- case '(': /* iso-2022: designate 94 character set to G0 */
- tcp->esc = 5;
- return;
- }
- } else if (tcp->esc == 2) { /* seen ESC [ */
- if (c >= '0' && c <= '9') {
- if (tcp->num_param < MAX_ESC_PAR) {
- if (tcp->last_param != tcp->num_param) {
- tcp->last_param = tcp->num_param;
- tcp->param[tcp->num_param] = 0;
- } else {
- tcp->param[tcp->num_param] *= 10;
- }
- tcp->param[tcp->num_param] += c - '0';
- return;
- }
- }
- tcp->num_param = tcp->last_param + 1;
- switch (c) {
-
- case ';':
- if (tcp->num_param < MAX_ESC_PAR)
- return;
- break;
-
- case '=':
- tcp->esc = 3;
- tcp->last_param = -1;
- for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
- tcp->param[i] = 1;
- tcp->num_param = 0;
- return;
-
- case 'A': /* up n rows */
- sc_term_up(scp, tcp->param[0], 0);
- break;
-
- case 'B': /* down n rows */
- sc_term_down(scp, tcp->param[0], 0);
- break;
-
- case 'C': /* right n columns */
- sc_term_right(scp, tcp->param[0]);
- break;
-
- case 'D': /* left n columns */
- sc_term_left(scp, tcp->param[0]);
- break;
-
- case 'E': /* cursor to start of line n lines down */
- n = tcp->param[0];
- if (n < 1)
- n = 1;
- sc_move_cursor(scp, 0, scp->ypos + n);
- break;
-
- case 'F': /* cursor to start of line n lines up */
- n = tcp->param[0];
- if (n < 1)
- n = 1;
- sc_move_cursor(scp, 0, scp->ypos - n);
- break;
-
- case 'f': /* Cursor move */
- case 'H':
- if (tcp->num_param == 0)
- sc_move_cursor(scp, 0, 0);
- else if (tcp->num_param == 2)
- sc_move_cursor(scp, tcp->param[1] - 1,
- tcp->param[0] - 1);
- break;
-
- case 'J': /* Clear all or part of display */
- if (tcp->num_param == 0)
- n = 0;
- else
- n = tcp->param[0];
- sc_term_clr_eos(scp, n, sc->scr_map[0x20],
- tcp->cur_attr);
- break;
-
- case 'K': /* Clear all or part of line */
- if (tcp->num_param == 0)
- n = 0;
- else
- n = tcp->param[0];
- sc_term_clr_eol(scp, n, sc->scr_map[0x20],
- tcp->cur_attr);
- break;
-
- case 'L': /* Insert n lines */
- sc_term_ins_line(scp, scp->ypos, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'M': /* Delete n lines */
- sc_term_del_line(scp, scp->ypos, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'P': /* Delete n chars */
- sc_term_del_char(scp, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr);
- break;
-
- case '@': /* Insert n chars */
- sc_term_ins_char(scp, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr);
- break;
-
- case 'S': /* scroll up n lines */
- sc_term_del_line(scp, 0, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'T': /* scroll down n lines */
- sc_term_ins_line(scp, 0, tcp->param[0],
- sc->scr_map[0x20], tcp->cur_attr, 0);
- break;
-
- case 'X': /* erase n characters in line */
- n = tcp->param[0];
- if (n < 1)
- n = 1;
- if (n > scp->xsize - scp->xpos)
- n = scp->xsize - scp->xpos;
- sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
- sc->scr_map[0x20], tcp->cur_attr);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos + n - 1);
- break;
-
- case 'Z': /* move n tabs backwards */
- sc_term_backtab(scp, tcp->param[0]);
- break;
-
- case '`': /* move cursor to column n */
- sc_term_col(scp, tcp->param[0]);
- break;
-
- case 'a': /* move cursor n columns to the right */
- sc_term_right(scp, tcp->param[0]);
- break;
-
- case 'd': /* move cursor to row n */
- sc_term_row(scp, tcp->param[0]);
- break;
-
- case 'e': /* move cursor n rows down */
- sc_term_down(scp, tcp->param[0], 0);
- break;
-
- case 'm': /* change attribute */
- if (tcp->num_param == 0) {
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
- for (i = 0; i < tcp->num_param; i++) {
- switch (n = tcp->param[i]) {
- case 0: /* back to normal */
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 1: /* bold */
- tcp->attr_mask |= BOLD_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 4: /* underline */
- tcp->attr_mask |= UNDERLINE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 5: /* blink */
- tcp->attr_mask |= BLINK_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 7: /* reverse */
- tcp->attr_mask |= REVERSE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 22: /* remove bold (or dim) */
- tcp->attr_mask &= ~BOLD_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 24: /* remove underline */
- tcp->attr_mask &= ~UNDERLINE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 25: /* remove blink */
- tcp->attr_mask &= ~BLINK_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 27: /* remove reverse */
- tcp->attr_mask &= ~REVERSE_ATTR;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 30: case 31: /* set ansi fg color */
- case 32: case 33: case 34:
- case 35: case 36: case 37:
- tcp->attr_mask |= FG_CHANGED;
- tcp->cur_color.fg = ansi_col[n - 30];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 39: /* restore fg color back to normal */
- tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR);
- tcp->cur_color.fg = tcp->std_color.fg;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 40: case 41: /* set ansi bg color */
- case 42: case 43: case 44:
- case 45: case 46: case 47:
- tcp->attr_mask |= BG_CHANGED;
- tcp->cur_color.bg = ansi_col[n - 40];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 49: /* restore bg color back to normal */
- tcp->attr_mask &= ~BG_CHANGED;
- tcp->cur_color.bg = tcp->std_color.bg;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
- }
- break;
-
- case 's': /* Save cursor position */
- tcp->saved_xpos = scp->xpos;
- tcp->saved_ypos = scp->ypos;
- break;
-
- case 'u': /* Restore saved cursor position */
- if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
- sc_move_cursor(scp, tcp->saved_xpos,
- tcp->saved_ypos);
- break;
-
- case 'x':
- if (tcp->num_param == 0)
- n = 0;
- else
- n = tcp->param[0];
- switch (n) {
- case 0: /* reset colors and attributes back to normal */
- tcp->attr_mask = NORMAL_ATTR;
- tcp->cur_color = tcp->std_color
- = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 1: /* set ansi background */
- tcp->attr_mask &= ~BG_CHANGED;
- tcp->cur_color.bg = tcp->std_color.bg
- = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 2: /* set ansi foreground */
- tcp->attr_mask &= ~FG_CHANGED;
- tcp->cur_color.fg = tcp->std_color.fg
- = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 3: /* set adapter attribute directly */
- tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED);
- tcp->cur_color.fg = tcp->std_color.fg
- = tcp->param[1] & 0x0f;
- tcp->cur_color.bg = tcp->std_color.bg
- = (tcp->param[1] >> 4) & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 5: /* set ansi reverse background */
- tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 6: /* set ansi reverse foreground */
- tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f];
- tcp->cur_attr = mask2attr(tcp);
- break;
- case 7: /* set adapter reverse attribute directly */
- tcp->rev_color.fg = tcp->param[1] & 0x0f;
- tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- break;
- }
- break;
-
- case 'z': /* switch to (virtual) console n */
- if (tcp->num_param == 1)
- sc_switch_scr(sc, tcp->param[0]);
- break;
- }
- } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */
- if (c >= '0' && c <= '9') {
- if (tcp->num_param < MAX_ESC_PAR) {
- if (tcp->last_param != tcp->num_param) {
- tcp->last_param = tcp->num_param;
- tcp->param[tcp->num_param] = 0;
- } else {
- tcp->param[tcp->num_param] *= 10;
- }
- tcp->param[tcp->num_param] += c - '0';
- return;
- }
- }
- tcp->num_param = tcp->last_param + 1;
- switch (c) {
-
- case ';':
- if (tcp->num_param < MAX_ESC_PAR)
- return;
- break;
-
- case 'A': /* set display border color */
- if (tcp->num_param == 1) {
- scp->border=tcp->param[0] & 0xff;
- if (scp == sc->cur_scp)
- sc_set_border(scp, scp->border);
- }
- break;
-
- case 'B': /* set bell pitch and duration */
- if (tcp->num_param == 2) {
- scp->bell_pitch = tcp->param[0];
- scp->bell_duration =
- (tcp->param[1] * hz + 99) / 100;
- }
- break;
-
- case 'C': /* set global/parmanent cursor type & shape */
- i = spltty();
- n = tcp->num_param;
- v0 = tcp->param[0];
- v1 = tcp->param[1];
- v2 = tcp->param[2];
- switch (n) {
- case 1: /* flags only */
- if (v0 < sizeof(cattrs)/sizeof(cattrs[0]))
- v0 = cattrs[v0];
- else /* backward compatibility */
- v0 = cattrs[v0 & 0x3];
- sc_change_cursor_shape(scp, v0, -1, -1);
- break;
- case 2:
- v2 = 0;
- v0 &= 0x1f; /* backward compatibility */
- v1 &= 0x1f;
- /* FALL THROUGH */
- case 3: /* base and height */
- if (v2 == 0) /* count from top */
- sc_change_cursor_shape(scp, -1,
- scp->font_size - v1 - 1,
- v1 - v0 + 1);
- else if (v2 == 1) /* count from bottom */
- sc_change_cursor_shape(scp, -1,
- v0, v1 - v0 + 1);
- break;
- }
- splx(i);
- break;
-
- case 'F': /* set adapter foreground */
- if (tcp->num_param == 1) {
- tcp->attr_mask &= ~FG_CHANGED;
- tcp->cur_color.fg = tcp->std_color.fg
- = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'G': /* set adapter background */
- if (tcp->num_param == 1) {
- tcp->attr_mask &= ~BG_CHANGED;
- tcp->cur_color.bg = tcp->std_color.bg
- = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'H': /* set adapter reverse foreground */
- if (tcp->num_param == 1) {
- tcp->rev_color.fg = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'I': /* set adapter reverse background */
- if (tcp->num_param == 1) {
- tcp->rev_color.bg = tcp->param[0] & 0x0f;
- tcp->cur_attr = mask2attr(tcp);
- }
- break;
-
- case 'S': /* set local/temporary cursor type & shape */
- i = spltty();
- n = tcp->num_param;
- v0 = tcp->param[0];
- switch (n) {
- case 0:
- v0 = 0;
- /* FALL THROUGH */
- case 1:
- if (v0 < sizeof(tcattrs)/sizeof(tcattrs[0]))
- sc_change_cursor_shape(scp,
- tcattrs[v0], -1, -1);
- break;
- }
- splx(i);
- break;
- }
-#ifdef notyet
- } else if (tcp->esc == 4) { /* seen ESC Q */
- /* to be filled */
-#endif
- } else if (tcp->esc == 5) { /* seen ESC ( */
- switch (c) {
- case 'B': /* iso-2022: desginate ASCII into G0 */
- break;
- /* other items to be filled */
- default:
- break;
- }
- }
- tcp->esc = 0;
-}
-
-static void
-scterm_puts(scr_stat *scp, u_char *buf, int len)
-{
- term_stat *tcp;
-
- tcp = scp->ts;
-outloop:
- scp->sc->write_in_progress++;
-
- if (tcp->esc) {
- scterm_scan_esc(scp, tcp, *buf);
- buf++;
- len--;
- } else {
- switch (*buf) {
- case 0x1b:
- tcp->esc = 1;
- tcp->num_param = 0;
- buf++;
- len--;
- break;
- default:
- sc_term_gen_print(scp, &buf, &len, tcp->cur_attr);
- break;
- }
- }
-
- sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr);
-
- scp->sc->write_in_progress--;
- if (len)
- goto outloop;
-}
-
-static int
-scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
- struct thread *td)
-{
- term_stat *tcp = scp->ts;
- vid_info_t *vi;
-
- switch (cmd) {
- case GIO_ATTR: /* get current attributes */
- /* FIXME: */
- *(int*)data = (tcp->cur_attr >> 8) & 0xff;
- return 0;
- case CONS_GETINFO: /* get current (virtual) console info */
- vi = (vid_info_t *)data;
- if (vi->size != sizeof(struct vid_info))
- return EINVAL;
- vi->mv_norm.fore = tcp->std_color.fg;
- vi->mv_norm.back = tcp->std_color.bg;
- vi->mv_rev.fore = tcp->rev_color.fg;
- vi->mv_rev.back = tcp->rev_color.bg;
- /*
- * The other fields are filled by the upper routine. XXX
- */
- return ENOIOCTL;
- }
- return ENOIOCTL;
-}
-
-static int
-scterm_reset(scr_stat *scp, int code)
-{
- /* FIXME */
- return 0;
-}
-
-static void
-scterm_default_attr(scr_stat *scp, int color, int rev_color)
-{
- term_stat *tcp = scp->ts;
-
- tcp->dflt_std_color.fg = color & 0x0f;
- tcp->dflt_std_color.bg = (color >> 4) & 0x0f;
- tcp->dflt_rev_color.fg = rev_color & 0x0f;
- tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f;
- tcp->std_color = tcp->dflt_std_color;
- tcp->rev_color = tcp->dflt_rev_color;
- tcp->cur_color = tcp->std_color;
- tcp->cur_attr = mask2attr(tcp);
-}
-
-static void
-scterm_clear(scr_stat *scp)
-{
- term_stat *tcp = scp->ts;
-
- sc_move_cursor(scp, 0, 0);
- sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr);
- mark_all(scp);
-}
-
-static void
-scterm_notify(scr_stat *scp, int event)
-{
- switch (event) {
- case SC_TE_NOTIFY_VTSWITCH_IN:
- break;
- case SC_TE_NOTIFY_VTSWITCH_OUT:
- break;
- }
-}
-
-static int
-scterm_input(scr_stat *scp, int c, struct tty *tp)
-{
- return FALSE;
-}
-
-/*
- * Calculate hardware attributes word using logical attributes mask and
- * hardware colors
- */
-
-/* FIXME */
-static int
-mask2attr(term_stat *tcp)
-{
- int attr, mask = tcp->attr_mask;
-
- if (mask & REVERSE_ATTR) {
- attr = ((mask & FG_CHANGED) ?
- tcp->cur_color.bg : tcp->rev_color.fg) |
- (((mask & BG_CHANGED) ?
- tcp->cur_color.fg : tcp->rev_color.bg) << 4);
- } else
- attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4);
-
- /* XXX: underline mapping for Hercules adapter can be better */
- if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
- attr ^= 0x08;
- if (mask & BLINK_ATTR)
- attr ^= 0x80;
-
- return (attr << 8);
-}
-
-#endif /* SC_DUMB_TERMINAL */
diff --git a/sys/dev/syscons/scterm-teken.c b/sys/dev/syscons/scterm-teken.c
new file mode 100644
index 0000000..798a2cd
--- /dev/null
+++ b/sys/dev/syscons/scterm-teken.c
@@ -0,0 +1,504 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must 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 ``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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_syscons.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/consio.h>
+
+#if defined(__sparc64__) || defined(__powerpc__)
+#include <machine/sc_machdep.h>
+#else
+#include <machine/pc/display.h>
+#endif
+
+#include <dev/syscons/syscons.h>
+
+#include <dev/syscons/teken/teken.h>
+
+static void scteken_revattr(unsigned char, teken_attr_t *);
+
+static sc_term_init_t scteken_init;
+static sc_term_term_t scteken_term;
+static sc_term_puts_t scteken_puts;
+static sc_term_ioctl_t scteken_ioctl;
+static sc_term_default_attr_t scteken_default_attr;
+static sc_term_clear_t scteken_clear;
+static sc_term_input_t scteken_input;
+static void scteken_nop(void);
+
+typedef struct {
+ teken_t ts_teken;
+ int ts_busy;
+} teken_stat;
+
+static teken_stat reserved_teken_stat;
+
+static sc_term_sw_t sc_term_scteken = {
+ { NULL, NULL },
+ "scteken", /* emulator name */
+ "teken terminal", /* description */
+ "*", /* matching renderer */
+ sizeof(teken_stat), /* softc size */
+ 0,
+ scteken_init,
+ scteken_term,
+ scteken_puts,
+ scteken_ioctl,
+ (sc_term_reset_t *)scteken_nop,
+ scteken_default_attr,
+ scteken_clear,
+ (sc_term_notify_t *)scteken_nop,
+ scteken_input,
+};
+
+SCTERM_MODULE(scteken, sc_term_scteken);
+
+static tf_bell_t scteken_bell;
+static tf_cursor_t scteken_cursor;
+static tf_putchar_t scteken_putchar;
+static tf_fill_t scteken_fill;
+static tf_copy_t scteken_copy;
+static tf_param_t scteken_param;
+static tf_respond_t scteken_respond;
+
+static const teken_funcs_t scteken_funcs = {
+ .tf_bell = scteken_bell,
+ .tf_cursor = scteken_cursor,
+ .tf_putchar = scteken_putchar,
+ .tf_fill = scteken_fill,
+ .tf_copy = scteken_copy,
+ .tf_param = scteken_param,
+ .tf_respond = scteken_respond,
+};
+
+static int
+scteken_init(scr_stat *scp, void **softc, int code)
+{
+ teken_stat *ts = scp->ts;
+ teken_pos_t tp;
+
+ if (*softc == NULL) {
+ if (reserved_teken_stat.ts_busy)
+ return (EINVAL);
+ *softc = &reserved_teken_stat;
+ }
+ ts = *softc;
+
+ switch (code) {
+ case SC_TE_COLD_INIT:
+ ++sc_term_scteken.te_refcount;
+ ts->ts_busy = 1;
+ /* FALLTHROUGH */
+ case SC_TE_WARM_INIT:
+ teken_init(&ts->ts_teken, &scteken_funcs, scp);
+
+ tp.tp_row = scp->ysize;
+ tp.tp_col = scp->xsize;
+ teken_set_winsize(&ts->ts_teken, &tp);
+
+ tp.tp_row = scp->cursor_pos / scp->xsize;
+ tp.tp_col = scp->cursor_pos % scp->xsize;
+ teken_set_cursor(&ts->ts_teken, &tp);
+ break;
+ }
+
+ return (0);
+}
+
+static int
+scteken_term(scr_stat *scp, void **softc)
+{
+
+ if (*softc == &reserved_teken_stat) {
+ *softc = NULL;
+ reserved_teken_stat.ts_busy = 0;
+ }
+ --sc_term_scteken.te_refcount;
+
+ return (0);
+}
+
+static void
+scteken_puts(scr_stat *scp, u_char *buf, int len)
+{
+ teken_stat *ts = scp->ts;
+
+ scp->sc->write_in_progress++;
+ teken_input(&ts->ts_teken, buf, len);
+ scp->sc->write_in_progress--;
+}
+
+static int
+scteken_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
+ struct thread *td)
+{
+ vid_info_t *vi;
+
+ switch (cmd) {
+ case GIO_ATTR: /* get current attributes */
+ *(int*)data = SC_NORM_ATTR;
+ return (0);
+ case CONS_GETINFO: /* get current (virtual) console info */
+ /* XXX: INCORRECT! */
+ vi = (vid_info_t *)data;
+ if (vi->size != sizeof(struct vid_info))
+ return EINVAL;
+ vi->mv_norm.fore = SC_NORM_ATTR & 0x0f;
+ vi->mv_norm.back = (SC_NORM_ATTR >> 4) & 0x0f;
+ vi->mv_rev.fore = SC_NORM_ATTR & 0x0f;
+ vi->mv_rev.back = (SC_NORM_ATTR >> 4) & 0x0f;
+ /*
+ * The other fields are filled by the upper routine. XXX
+ */
+ return (ENOIOCTL);
+ }
+
+ return (ENOIOCTL);
+}
+
+static void
+scteken_default_attr(scr_stat *scp, int color, int rev_color)
+{
+ teken_stat *ts = scp->ts;
+ teken_attr_t ta;
+
+ scteken_revattr(color, &ta);
+ teken_set_defattr(&ts->ts_teken, &ta);
+}
+
+static void
+scteken_clear(scr_stat *scp)
+{
+
+ sc_move_cursor(scp, 0, 0);
+ sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8);
+ mark_all(scp);
+}
+
+static int
+scteken_input(scr_stat *scp, int c, struct tty *tp)
+{
+
+ return FALSE;
+}
+
+static void
+scteken_nop(void)
+{
+
+}
+
+/*
+ * libteken routines.
+ */
+
+static const unsigned char fgcolors_normal[TC_NCOLORS] = {
+ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN,
+ FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY,
+};
+
+static const unsigned char fgcolors_bold[TC_NCOLORS] = {
+ FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW,
+ FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE,
+};
+
+static const unsigned char bgcolors[TC_NCOLORS] = {
+ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN,
+ BG_BLUE, BG_MAGENTA, BG_CYAN, BG_LIGHTGREY,
+};
+
+static void
+scteken_revattr(unsigned char color, teken_attr_t *a)
+{
+ teken_color_t fg, bg;
+
+ /*
+ * XXX: Reverse conversion of syscons to teken attributes. Not
+ * realiable. Maybe we should turn it into a 1:1 mapping one of
+ * these days?
+ */
+
+ a->ta_format = 0;
+ a->ta_fgcolor = TC_WHITE;
+ a->ta_bgcolor = TC_BLACK;
+
+#ifdef FG_BLINK
+ if (color & FG_BLINK) {
+ a->ta_format |= TF_BLINK;
+ color &= ~FG_BLINK;
+ }
+#endif /* FG_BLINK */
+
+ for (fg = 0; fg < TC_NCOLORS; fg++) {
+ for (bg = 0; bg < TC_NCOLORS; bg++) {
+ if ((fgcolors_normal[fg] | bgcolors[bg]) == color) {
+ a->ta_fgcolor = fg;
+ a->ta_bgcolor = bg;
+ return;
+ }
+
+ if ((fgcolors_bold[fg] | bgcolors[bg]) == color) {
+ a->ta_fgcolor = fg;
+ a->ta_bgcolor = bg;
+ a->ta_format |= TF_BOLD;
+ return;
+ }
+ }
+ }
+}
+
+static inline unsigned int
+scteken_attr(const teken_attr_t *a)
+{
+ unsigned int attr = 0;
+
+ if (a->ta_format & TF_BOLD)
+ attr |= fgcolors_bold[a->ta_fgcolor];
+ else
+ attr |= fgcolors_normal[a->ta_fgcolor];
+ attr |= bgcolors[a->ta_bgcolor];
+
+#ifdef FG_UNDERLINE
+ if (a->ta_format & TF_UNDERLINE)
+ attr |= FG_UNDERLINE;
+#endif /* FG_UNDERLINE */
+#ifdef FG_BLINK
+ if (a->ta_format & TF_BLINK)
+ attr |= FG_BLINK;
+#endif /* FG_BLINK */
+
+ return (attr << 8);
+}
+
+static void
+scteken_bell(void *arg)
+{
+ scr_stat *scp = arg;
+
+ sc_bell(scp, scp->bell_pitch, scp->bell_duration);
+}
+
+static void
+scteken_cursor(void *arg, const teken_pos_t *p)
+{
+ scr_stat *scp = arg;
+
+ sc_move_cursor(scp, p->tp_col, p->tp_row);
+}
+
+static void
+scteken_putchar(void *arg, const teken_pos_t *tp, teken_char_t c,
+ const teken_attr_t *a)
+{
+ scr_stat *scp = arg;
+ u_char *map;
+ u_char ch;
+ vm_offset_t p;
+ int cursor, attr;
+
+#ifdef TEKEN_UTF8
+ if (c >= 0x80) {
+ /* XXX: Don't display UTF-8 yet. */
+ attr = (FG_YELLOW|BG_RED) << 8;
+ ch = '?';
+ } else
+#endif /* TEKEN_UTF8 */
+ {
+ attr = scteken_attr(a);
+ ch = c;
+ }
+
+ map = scp->sc->scr_map;
+
+ cursor = tp->tp_row * scp->xsize + tp->tp_col;
+ p = sc_vtb_pointer(&scp->vtb, cursor);
+ sc_vtb_putchar(&scp->vtb, p, map[ch], attr);
+
+ mark_for_update(scp, cursor);
+ /*
+ * XXX: Why do we need this? Only marking `cursor' should be
+ * enough. Without this line, we get artifacts.
+ */
+ mark_for_update(scp, imin(cursor + 1, scp->xsize * scp->ysize - 1));
+}
+
+static void
+scteken_fill(void *arg, const teken_rect_t *r, teken_char_t c,
+ const teken_attr_t *a)
+{
+ scr_stat *scp = arg;
+ u_char *map;
+ u_char ch;
+ unsigned int width;
+ int attr, row;
+
+#ifdef TEKEN_UTF8
+ if (c >= 0x80) {
+ /* XXX: Don't display UTF-8 yet. */
+ attr = (FG_YELLOW|BG_RED) << 8;
+ ch = '?';
+ } else
+#endif /* TEKEN_UTF8 */
+ {
+ attr = scteken_attr(a);
+ ch = c;
+ }
+
+ map = scp->sc->scr_map;
+
+ if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) {
+ /* Single contiguous region to fill. */
+ sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * scp->xsize,
+ (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize,
+ map[ch], attr);
+ } else {
+ /* Fill display line by line. */
+ width = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+ for (row = r->tr_begin.tp_row; row < r->tr_end.tp_row; row++) {
+ sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row *
+ scp->xsize + r->tr_begin.tp_col,
+ width, map[ch], attr);
+ }
+ }
+
+ /* Mark begin and end positions to be refreshed. */
+ mark_for_update(scp,
+ r->tr_begin.tp_row * scp->xsize + r->tr_begin.tp_col);
+ mark_for_update(scp,
+ (r->tr_end.tp_row - 1) * scp->xsize + (r->tr_end.tp_col - 1));
+ sc_remove_cutmarking(scp);
+}
+
+static void
+scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p)
+{
+ scr_stat *scp = arg;
+ unsigned int width;
+ int src, dst, end;
+
+#ifndef SC_NO_HISTORY
+ /*
+ * We count a line of input as history if we perform a copy of
+ * one whole line upward. In other words: if a line of text gets
+ * overwritten by a rectangle that's right below it.
+ */
+ if (scp->history != NULL &&
+ r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize &&
+ r->tr_begin.tp_row == p->tp_row + 1) {
+ sc_hist_save_one_line(scp, p->tp_row);
+ }
+#endif
+
+ if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) {
+ /* Single contiguous region to copy. */
+ sc_vtb_move(&scp->vtb, r->tr_begin.tp_row * scp->xsize,
+ p->tp_row * scp->xsize,
+ (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize);
+ } else {
+ /* Copy line by line. */
+ width = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+ if (p->tp_row < r->tr_begin.tp_row) {
+ /* Copy from top to bottom. */
+ src = r->tr_begin.tp_row * scp->xsize +
+ r->tr_begin.tp_col;
+ end = r->tr_end.tp_row * scp->xsize +
+ r->tr_end.tp_col;
+ dst = p->tp_row * scp->xsize + p->tp_col;
+
+ while (src < end) {
+ sc_vtb_move(&scp->vtb, src, dst, width);
+
+ src += scp->xsize;
+ dst += scp->xsize;
+ }
+ } else {
+ /* Copy from bottom to top. */
+ src = (r->tr_end.tp_row - 1) * scp->xsize +
+ r->tr_begin.tp_col;
+ end = r->tr_begin.tp_row * scp->xsize +
+ r->tr_begin.tp_col;
+ dst = (p->tp_row + r->tr_end.tp_row -
+ r->tr_begin.tp_row - 1) * scp->xsize + p->tp_col;
+
+ while (src >= end) {
+ sc_vtb_move(&scp->vtb, src, dst, width);
+
+ src -= scp->xsize;
+ dst -= scp->xsize;
+ }
+ }
+ }
+
+ /* Mark begin and end positions to be refreshed. */
+ mark_for_update(scp,
+ p->tp_row * scp->xsize + p->tp_col);
+ mark_for_update(scp,
+ (p->tp_row + r->tr_end.tp_row - r->tr_begin.tp_row - 1) *
+ scp->xsize +
+ (p->tp_col + r->tr_end.tp_col - r->tr_begin.tp_col - 1));
+ sc_remove_cutmarking(scp);
+}
+
+static void
+scteken_param(void *arg, int cmd, int value)
+{
+ scr_stat *scp = arg;
+
+ switch (cmd) {
+ case TP_SHOWCURSOR:
+ if (value) {
+ sc_change_cursor_shape(scp,
+ CONS_RESET_CURSOR|CONS_LOCAL_CURSOR, -1, -1);
+ } else {
+ sc_change_cursor_shape(scp,
+ CONS_HIDDEN_CURSOR|CONS_LOCAL_CURSOR, -1, -1);
+ }
+ break;
+ case TP_SWITCHVT:
+ sc_switch_scr(scp->sc, value);
+ break;
+ }
+}
+
+static void
+scteken_respond(void *arg, const void *buf, size_t len)
+{
+ scr_stat *scp = arg;
+
+ sc_respond(scp, buf, len);
+}
diff --git a/sys/dev/syscons/scterm.c b/sys/dev/syscons/scterm.c
index 0b9135a..f0f56b5 100644
--- a/sys/dev/syscons/scterm.c
+++ b/sys/dev/syscons/scterm.c
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
#include <sys/consio.h>
#include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
SET_DECLARE(scterm_set, sc_term_sw_t);
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 37b08b6..a9b8e40 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -2741,6 +2741,16 @@ scinit(int unit, int flags)
init_scp(sc, sc->first_vty, scp);
sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize,
(void *)sc_buffer, FALSE);
+
+ /* move cursors to the initial positions */
+ if (col >= scp->xsize)
+ col = 0;
+ if (row >= scp->ysize)
+ row = scp->ysize - 1;
+ scp->xpos = col;
+ scp->ypos = row;
+ scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
+
if (sc_init_emulator(scp, SC_DFLT_TERM))
sc_init_emulator(scp, "*");
(*scp->tsw->te_default_attr)(scp,
@@ -2764,15 +2774,6 @@ scinit(int unit, int flags)
sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0, scp->xsize*scp->ysize);
#endif
- /* move cursors to the initial positions */
- if (col >= scp->xsize)
- col = 0;
- if (row >= scp->ysize)
- row = scp->ysize - 1;
- scp->xpos = col;
- scp->ypos = row;
- scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
-
if (bios_value.cursor_end < scp->font_size)
sc->dflt_curs_attr.base = scp->font_size -
bios_value.cursor_end - 1;
@@ -3569,7 +3570,7 @@ sc_show_font(scr_stat *scp, int page)
#endif /* !SC_NO_FONT_LOADING */
void
-sc_paste(scr_stat *scp, u_char *p, int count)
+sc_paste(scr_stat *scp, const u_char *p, int count)
{
struct tty *tp;
u_char *rmap;
@@ -3584,6 +3585,22 @@ sc_paste(scr_stat *scp, u_char *p, int count)
}
void
+sc_respond(scr_stat *scp, const u_char *p, int count)
+{
+ struct tty *tp;
+
+ tp = SC_DEV(scp->sc, scp->sc->cur_scp->index);
+ if (!tty_opened(tp))
+ return;
+ for (; count > 0; --count)
+ ttydisc_rint(tp, *p++, 0);
+#if 0
+ /* XXX: we can't call ttydisc_rint_done() here! */
+ ttydisc_rint_done(tp);
+#endif
+}
+
+void
sc_bell(scr_stat *scp, int pitch, int duration)
{
if (cold || shutdown_in_progress || !enable_bell)
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index 548cec6..56b30d3 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -563,7 +563,8 @@ int sc_clean_up(scr_stat *scp);
int sc_switch_scr(sc_softc_t *sc, u_int next_scr);
void sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard);
int sc_init_emulator(scr_stat *scp, char *name);
-void sc_paste(scr_stat *scp, u_char *p, int count);
+void sc_paste(scr_stat *scp, const u_char *p, int count);
+void sc_respond(scr_stat *scp, const u_char *p, int count);
void sc_bell(scr_stat *scp, int pitch, int duration);
/* schistory.c */
diff --git a/sys/dev/syscons/teken/Makefile b/sys/dev/syscons/teken/Makefile
new file mode 100644
index 0000000..cbdd12b
--- /dev/null
+++ b/sys/dev/syscons/teken/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+PROG= teken_demo
+SRCS= teken_demo.c teken.c teken_state.h
+CLEANFILES= teken_state.h teken.log
+LDADD= -lncurses -lutil
+NO_MAN=
+WARNS?= 6
+
+teken_state.h: gensequences sequences
+ awk -f gensequences sequences > ${.TARGET}
+
+.include <bsd.prog.mk>
diff --git a/sys/dev/syscons/teken/gensequences b/sys/dev/syscons/teken/gensequences
new file mode 100644
index 0000000..86c7979
--- /dev/null
+++ b/sys/dev/syscons/teken/gensequences
@@ -0,0 +1,157 @@
+#!/usr/bin/awk -f
+
+#-
+# Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+function die(msg) {
+ print msg;
+ exit 1;
+}
+
+function cchar(str) {
+ if (str == "^[")
+ return "\\x1B";
+
+ return str;
+}
+
+BEGIN {
+FS = "\t+"
+
+while (getline > 0) {
+ if (NF == 0 || $1 ~ /^#/)
+ continue;
+
+ if (NF != 3 && NF != 4)
+ die("Invalid line layout: " NF " columns");
+
+ split($3, sequence, " +");
+ nsequences = 0;
+ for (s in sequence)
+ nsequences++;
+
+ prefix = "";
+ l_prefix_name[""] = "teken_state_init";
+ for (i = 1; i < nsequences; i++) {
+ n = prefix sequence[i];
+ l_prefix_parent[n] = prefix;
+ l_prefix_suffix[n] = sequence[i];
+ if (!l_prefix_name[n])
+ l_prefix_name[n] = "teken_state_" ++npr;
+ prefix = n;
+ }
+
+ suffix = sequence[nsequences];
+ cmd = prefix suffix;
+
+ # Fill lists
+ if (l_cmd_name[cmd] != "")
+ die(cmd " already exists");
+ l_cmd_prefix[cmd] = prefix;
+ l_cmd_suffix[cmd] = suffix;
+ l_cmd_args[cmd] = $4;
+ l_cmd_abbr[cmd] = $1;
+ l_cmd_name[cmd] = $2;
+ l_cmd_c_name[cmd] = "teken_subr_" tolower($2);
+ gsub(" ", "_", l_cmd_c_name[cmd]);
+
+ if ($4 != "")
+ l_prefix_numbercmds[prefix]++;
+}
+
+print "/* Generated file. Do not edit. */";
+print "";
+
+for (p in l_prefix_name) {
+ if (l_prefix_name[p] != "teken_state_init")
+ print "static teken_state_t " l_prefix_name[p] ";";
+}
+
+for (p in l_prefix_name) {
+ print "";
+ print "/* '" p "' */";
+ print "static void";
+ print l_prefix_name[p] "(teken_t *t, teken_char_t c)";
+ print "{";
+
+ if (l_prefix_numbercmds[p] > 0) {
+ print "";
+ print "\tif (teken_state_numbers(t, c))";
+ print "\t\treturn;";
+ }
+
+ print "";
+ print "\tswitch (c) {";
+ for (c in l_cmd_prefix) {
+ if (l_cmd_prefix[c] != p)
+ continue;
+
+ print "\tcase '" cchar(l_cmd_suffix[c]) "': /* " l_cmd_abbr[c] ": " l_cmd_name[c] " */";
+
+ if (l_cmd_args[c] == "v") {
+ print "\t\t" l_cmd_c_name[c] "(t, t->t_curnum, t->t_nums);";
+ } else {
+ printf "\t\t%s(t", l_cmd_c_name[c];
+ split(l_cmd_args[c], args, " ");
+ for (a = 1; args[a] != ""; a++) {
+ if (args[a] == "n")
+ printf ", (t->t_curnum < %d || t->t_nums[%d] == 0) ? 1 : t->t_nums[%d]", a, (a - 1), (a - 1);
+ else if (args[a] == "r")
+ printf ", t->t_curnum < %d ? 0 : t->t_nums[%d]", a, (a - 1);
+ else
+ die("Invalid argument type: " args[a]);
+ }
+ print ");";
+ }
+ print "\t\tbreak;";
+ }
+ for (pc in l_prefix_parent) {
+ if (l_prefix_parent[pc] != p)
+ continue;
+ print "\tcase '" cchar(l_prefix_suffix[pc]) "':";
+ print "\t\tteken_state_switch(t, " l_prefix_name[pc] ");";
+ print "\t\treturn;";
+ }
+
+ print "\tdefault:";
+ if (l_prefix_name[p] == "teken_state_init") {
+ print "\t\tteken_subr_regular_character(t, c);";
+ } else {
+ print "\t\tteken_printf(\"Unsupported sequence in " l_prefix_name[p] ": %u\\n\", (unsigned int)c);";
+ }
+ print "\t\tbreak;";
+
+ print "\t}";
+
+ if (l_prefix_name[p] != "teken_state_init") {
+ print "";
+ print "\tteken_state_switch(t, teken_state_init);";
+ }
+ print "}";
+}
+
+}
diff --git a/sys/dev/syscons/teken/sequences b/sys/dev/syscons/teken/sequences
new file mode 100644
index 0000000..59d3245
--- /dev/null
+++ b/sys/dev/syscons/teken/sequences
@@ -0,0 +1,109 @@
+#-
+# Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+# File format is as follows:
+# Abbr Abbreviation of sequence name
+# Name Sequence name (will be converted to C function name)
+# Sequence Bytes that form the sequence
+# Arguments Standard value of arguments passed to this sequence
+# - `n' non-zero number (0 gets converted to 1)
+# - `r' regular numeric argument
+# - `v' means a variable number of arguments
+
+# Abbr Name Sequence Arguments
+CBT Cursor Backward Tabulation ^[ [ Z n
+CHT Cursor Forward Tabulation ^[ [ I n
+CNL Cursor Next Line ^[ [ E n
+CPL Cursor Previous Line ^[ [ F n
+CPR Cursor Position Report ^[ [ n r
+CUB Cursor Backward ^[ [ D n
+CUD Cursor Down ^[ [ B n
+CUD Cursor Down ^[ [ e n
+CUF Cursor Forward ^[ [ C n
+CUF Cursor Forward ^[ [ a n
+CUP Cursor Position ^[ [ H n n
+CUP Cursor Position ^[ [ f n n
+CUU Cursor Up ^[ [ A n
+DA1 Primary Device Attributes ^[ [ c r
+DA2 Secondary Device Attributes ^[ [ > c r
+DC Delete character ^[ [ P n
+DCS Device Control String ^[ P
+DECALN Alignment test ^[ # 8
+DECDHL Double Height Double Width Line Top ^[ # 3
+DECDHL Double Height Double Width Line Bottom ^[ # 4
+DECDWL Single Height Double Width Line ^[ # 6
+DECKPAM Keypad application mode ^[ =
+DECKPNM Keypad numeric mode ^[ >
+DECRC Restore cursor ^[ 8
+DECRC Restore cursor ^[ [ u
+DECRM Reset DEC mode ^[ [ ? l r
+DECSC Save cursor ^[ 7
+DECSC Save cursor ^[ [ s
+DECSM Set DEC mode ^[ [ ? h r
+DECSTBM Set top and bottom margins ^[ [ r r r
+DECSWL Single Height Single Width Line ^[ # 5
+DL Delete line ^[ [ M n
+DSR Device Status Report ^[ [ ? n r
+ECH Erase character ^[ [ X n
+ED Erase display ^[ [ J r
+EL Erase line ^[ [ K r
+G0SCS0 G0 SCS Special Graphics ^[ ( 0
+G0SCS1 G0 SCS US ASCII ^[ ( 1
+G0SCS2 G0 SCS Special Graphics ^[ ( 2
+G0SCSA G0 SCS UK National ^[ ( A
+G0SCSB G0 SCS US ASCII ^[ ( B
+G1SCS0 G1 SCS Special Graphics ^[ ) 0
+G1SCS1 G1 SCS US ASCII ^[ ) 1
+G1SCS2 G1 SCS Special Graphics ^[ ) 2
+G1SCSA G1 SCS UK National ^[ ) A
+G1SCSB G1 SCS US ASCII ^[ ) B
+HPA Horizontal Position Absolute ^[ [ G n
+HPA Horizontal Position Absolute ^[ [ ` n
+HTS Horizontal Tab Set ^[ H
+ICH Insert character ^[ [ @ n
+IL Insert line ^[ [ L n
+IND Index ^[ D
+NEL Next line ^[ E
+RI Reverse index ^[ M
+RIS Reset to Initial State ^[ c
+RM Reset Mode ^[ [ l r
+SD Pan Up ^[ [ T n
+SGR Set Graphic Rendition ^[ [ m v
+SM Set Mode ^[ [ h r
+ST String Terminator ^[ \\
+SU Pan Down ^[ [ S n
+TBC Tab Clear ^[ [ g r
+VPA Vertical Position Absolute ^[ [ d n
+
+# Cons25 compatibility sequences
+C25ADBG Cons25 set adapter background ^[ [ = G r
+C25ADFG Cons25 set adapter foreground ^[ [ = F r
+C25CURS Cons25 set cursor type ^[ [ = S r
+C25VTSW Cons25 switch virtual terminal ^[ [ z r
+
+# VT52 compatibility
+#DECID VT52 DECID ^[ Z
diff --git a/sys/dev/syscons/teken/teken.c b/sys/dev/syscons/teken/teken.c
new file mode 100644
index 0000000..3a60255
--- /dev/null
+++ b/sys/dev/syscons/teken/teken.c
@@ -0,0 +1,411 @@
+/*-
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#if defined(__FreeBSD__) && defined(_KERNEL)
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/systm.h>
+#define teken_assert(x) MPASS(x)
+#define teken_printf(x,...)
+#else /* !(__FreeBSD__ && _KERNEL) */
+#include <sys/types.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#define teken_assert(x) assert(x)
+#define teken_printf(x,...) do { \
+ if (df != NULL) \
+ fprintf(df, x, ## __VA_ARGS__); \
+} while (0)
+/* debug messages */
+static FILE *df;
+#endif /* __FreeBSD__ && _KERNEL */
+
+#include "teken.h"
+
+#ifdef TEKEN_UTF8
+#include "teken_wcwidth.h"
+#else /* !TEKEN_UTF8 */
+#ifdef TEKEN_XTERM
+#define teken_wcwidth(c) ((c <= 0x1B) ? -1 : 1)
+#else /* !TEKEN_XTERM */
+#define teken_wcwidth(c) (1)
+#endif /* TEKEN_XTERM */
+#endif /* TEKEN_UTF8 */
+
+#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
+#include "teken_scs.h"
+#else /* !(TEKEN_XTERM && TEKEN_UTF8) */
+#define teken_scs_process(t, c) (c)
+#define teken_scs_restore(t)
+#define teken_scs_save(t)
+#define teken_scs_set(t, g, ts)
+#define teken_scs_switch(t, g)
+#endif /* TEKEN_XTERM && TEKEN_UTF8 */
+
+/* Private flags for teken_format_t. */
+#define TF_REVERSE 0x08
+
+/* Private flags for t_stateflags. */
+#define TS_FIRSTDIGIT 0x01 /* First numeric digit in escape sequence. */
+#define TS_INSERT 0x02 /* Insert mode. */
+#define TS_AUTOWRAP 0x04 /* Autowrap. */
+#define TS_ORIGIN 0x08 /* Origin mode. */
+#ifdef TEKEN_XTERM
+#define TS_WRAPPED 0x10 /* Next character should be printed on col 0. */
+#else /* !TEKEN_XTERM */
+#define TS_WRAPPED 0x00 /* Simple line wrapping. */
+#endif /* TEKEN_XTERM */
+
+/* Character that blanks a cell. */
+#define BLANK ' '
+
+static teken_state_t teken_state_init;
+
+/*
+ * Wrappers for hooks.
+ */
+
+static inline void
+teken_funcs_bell(teken_t *t)
+{
+
+ t->t_funcs->tf_bell(t->t_softc);
+}
+
+static inline void
+teken_funcs_cursor(teken_t *t)
+{
+
+ teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row);
+ teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col);
+
+ t->t_funcs->tf_cursor(t->t_softc, &t->t_cursor);
+}
+
+static inline void
+teken_funcs_putchar(teken_t *t, const teken_pos_t *p, teken_char_t c,
+ const teken_attr_t *a)
+{
+ teken_attr_t ta;
+
+ teken_assert(p->tp_row < t->t_winsize.tp_row);
+ teken_assert(p->tp_col < t->t_winsize.tp_col);
+
+ /* Apply inversion. */
+ if (a->ta_format & TF_REVERSE) {
+ ta.ta_format = a->ta_format;
+ ta.ta_fgcolor = a->ta_bgcolor;
+ ta.ta_bgcolor = a->ta_fgcolor;
+ a = &ta;
+ }
+
+ t->t_funcs->tf_putchar(t->t_softc, p, c, a);
+}
+
+static inline void
+teken_funcs_fill(teken_t *t, const teken_rect_t *r,
+ const teken_char_t c, const teken_attr_t *a)
+{
+ teken_attr_t ta;
+
+ teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row);
+ teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row);
+ teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col);
+ teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col);
+
+ /* Apply inversion. */
+ if (a->ta_format & TF_REVERSE) {
+ ta.ta_format = a->ta_format;
+ ta.ta_fgcolor = a->ta_bgcolor;
+ ta.ta_bgcolor = a->ta_fgcolor;
+ a = &ta;
+ }
+
+ t->t_funcs->tf_fill(t->t_softc, r, c, a);
+}
+
+static inline void
+teken_funcs_copy(teken_t *t, const teken_rect_t *r, const teken_pos_t *p)
+{
+
+ teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row);
+ teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row);
+ teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col);
+ teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col);
+ teken_assert(p->tp_row + (r->tr_end.tp_row - r->tr_begin.tp_row) <= t->t_winsize.tp_row);
+ teken_assert(p->tp_col + (r->tr_end.tp_col - r->tr_begin.tp_col) <= t->t_winsize.tp_col);
+
+ t->t_funcs->tf_copy(t->t_softc, r, p);
+}
+
+static inline void
+teken_funcs_param(teken_t *t, int cmd, int value)
+{
+
+ t->t_funcs->tf_param(t->t_softc, cmd, value);
+}
+
+static inline void
+teken_funcs_respond(teken_t *t, const void *buf, size_t len)
+{
+
+ t->t_funcs->tf_respond(t->t_softc, buf, len);
+}
+
+#include "teken_subr.h"
+#include "teken_subr_compat.h"
+
+/*
+ * Programming interface.
+ */
+
+void
+teken_init(teken_t *t, const teken_funcs_t *tf, void *softc)
+{
+ teken_pos_t tp = { .tp_row = 24, .tp_col = 80 };
+
+#if !(defined(__FreeBSD__) && defined(_KERNEL))
+ df = fopen("teken.log", "w");
+ if (df != NULL)
+ setvbuf(df, NULL, _IOLBF, BUFSIZ);
+#endif /* !(__FreeBSD__ && _KERNEL) */
+
+ t->t_funcs = tf;
+ t->t_softc = softc;
+
+ t->t_nextstate = teken_state_init;
+
+ t->t_defattr.ta_format = 0;
+ t->t_defattr.ta_fgcolor = TC_WHITE;
+ t->t_defattr.ta_bgcolor = TC_BLACK;
+ teken_subr_do_reset(t);
+
+#ifdef TEKEN_UTF8
+ t->t_utf8_left = 0;
+#endif /* TEKEN_UTF8 */
+
+ teken_set_winsize(t, &tp);
+}
+
+static void
+teken_input_char(teken_t *t, teken_char_t c)
+{
+
+ switch (c) {
+ case '\0':
+ break;
+ case '\a':
+ teken_subr_bell(t);
+ break;
+ case '\b':
+ teken_subr_backspace(t);
+ break;
+ case '\n':
+ case '\x0B':
+ teken_subr_newline(t);
+ break;
+ case '\x0C':
+ teken_subr_newpage(t);
+ break;
+#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
+ case '\x0E':
+ teken_scs_switch(t, 1);
+ break;
+ case '\x0F':
+ teken_scs_switch(t, 0);
+ break;
+#endif /* TEKEN_XTERM && TEKEN_UTF8 */
+ case '\r':
+ teken_subr_carriage_return(t);
+ break;
+ case '\t':
+ teken_subr_horizontal_tab(t);
+ break;
+ default:
+ t->t_nextstate(t, c);
+ break;
+ }
+
+ /* Post-processing assertions. */
+ teken_assert(t->t_cursor.tp_row >= t->t_originreg.ts_begin);
+ teken_assert(t->t_cursor.tp_row < t->t_originreg.ts_end);
+ teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row);
+ teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col);
+ teken_assert(t->t_saved_cursor.tp_row < t->t_winsize.tp_row);
+ teken_assert(t->t_saved_cursor.tp_col < t->t_winsize.tp_col);
+ teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
+ teken_assert(t->t_scrollreg.ts_begin < t->t_scrollreg.ts_end);
+ /* Origin region has to be window size or the same as scrollreg. */
+ teken_assert((t->t_originreg.ts_begin == t->t_scrollreg.ts_begin &&
+ t->t_originreg.ts_end == t->t_scrollreg.ts_end) ||
+ (t->t_originreg.ts_begin == 0 &&
+ t->t_originreg.ts_end == t->t_winsize.tp_row));
+}
+
+static void
+teken_input_byte(teken_t *t, unsigned char c)
+{
+
+#ifdef TEKEN_UTF8
+ /*
+ * UTF-8 handling.
+ */
+ if ((c & 0x80) == 0x00) {
+ /* One-byte sequence. */
+ t->t_utf8_left = 0;
+ teken_input_char(t, c);
+ } else if ((c & 0xe0) == 0xc0) {
+ /* Two-byte sequence. */
+ t->t_utf8_left = 1;
+ t->t_utf8_partial = c & 0x1f;
+ } else if ((c & 0xf0) == 0xe0) {
+ /* Three-byte sequence. */
+ t->t_utf8_left = 2;
+ t->t_utf8_partial = c & 0x0f;
+ } else if ((c & 0xf8) == 0xf0) {
+ /* Four-byte sequence. */
+ t->t_utf8_left = 3;
+ t->t_utf8_partial = c & 0x07;
+ } else if ((c & 0xc0) == 0x80) {
+ if (t->t_utf8_left == 0)
+ return;
+ t->t_utf8_left--;
+ t->t_utf8_partial = (t->t_utf8_partial << 6) | (c & 0x3f);
+ if (t->t_utf8_left == 0) {
+ teken_printf("Got UTF-8 char %u\n", t->t_utf8_partial);
+ teken_input_char(t, t->t_utf8_partial);
+ }
+ }
+#else /* !TEKEN_UTF8 */
+ teken_input_char(t, c);
+#endif /* TEKEN_UTF8 */
+}
+
+void
+teken_input(teken_t *t, const void *buf, size_t len)
+{
+ const char *c = buf;
+
+ while (len-- > 0)
+ teken_input_byte(t, *c++);
+}
+
+void
+teken_set_cursor(teken_t *t, const teken_pos_t *p)
+{
+
+ /* XXX: bounds checking with originreg! */
+ teken_assert(p->tp_row < t->t_winsize.tp_row);
+ teken_assert(p->tp_col < t->t_winsize.tp_col);
+
+ t->t_cursor = *p;
+}
+
+void
+teken_set_defattr(teken_t *t, const teken_attr_t *a)
+{
+
+ t->t_curattr = t->t_saved_curattr = t->t_defattr = *a;
+}
+
+void
+teken_set_winsize(teken_t *t, const teken_pos_t *p)
+{
+
+ teken_assert(p->tp_col <= T_NUMCOL);
+
+ t->t_winsize = *p;
+ /* XXX: bounds checking with cursor/etc! */
+ t->t_scrollreg.ts_begin = 0;
+ t->t_scrollreg.ts_end = t->t_winsize.tp_row;
+ t->t_originreg = t->t_scrollreg;
+}
+
+/*
+ * State machine.
+ */
+
+static void
+teken_state_switch(teken_t *t, teken_state_t *s)
+{
+
+ t->t_nextstate = s;
+ t->t_curnum = 0;
+ t->t_stateflags |= TS_FIRSTDIGIT;
+}
+
+static int
+teken_state_numbers(teken_t *t, teken_char_t c)
+{
+
+ teken_assert(t->t_curnum < T_NUMSIZE);
+
+ if (c >= '0' && c <= '9') {
+ /*
+ * Don't do math with the default value of 1 when a
+ * custom number is inserted.
+ */
+ if (t->t_stateflags & TS_FIRSTDIGIT) {
+ t->t_stateflags &= ~TS_FIRSTDIGIT;
+ t->t_nums[t->t_curnum] = 0;
+ } else {
+ t->t_nums[t->t_curnum] *= 10;
+ }
+
+ t->t_nums[t->t_curnum] += c - '0';
+ return (1);
+ } else if (c == ';') {
+ if (t->t_stateflags & TS_FIRSTDIGIT)
+ t->t_nums[t->t_curnum] = 0;
+
+ /* Only allow a limited set of arguments. */
+ if (++t->t_curnum == T_NUMSIZE) {
+ teken_state_switch(t, teken_state_init);
+ return (1);
+ }
+
+ t->t_stateflags |= TS_FIRSTDIGIT;
+ return (1);
+ } else {
+ if (t->t_stateflags & TS_FIRSTDIGIT && t->t_curnum > 0) {
+ /* Finish off the last empty argument. */
+ t->t_nums[t->t_curnum] = 0;
+ t->t_curnum++;
+ } else if ((t->t_stateflags & TS_FIRSTDIGIT) == 0) {
+ /* Also count the last argument. */
+ t->t_curnum++;
+ }
+ }
+
+ return (0);
+}
+
+#include "teken_state.h"
diff --git a/sys/dev/syscons/teken/teken.h b/sys/dev/syscons/teken/teken.h
new file mode 100644
index 0000000..ed965d9
--- /dev/null
+++ b/sys/dev/syscons/teken/teken.h
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _TEKEN_H_
+#define _TEKEN_H_
+
+/*
+ * libteken: terminal emulation library.
+ *
+ * This library converts an UTF-8 stream of bytes to terminal drawing
+ * commands.
+ *
+ * Configuration switches:
+ * - TEKEN_UTF8: Enable/disable UTF-8 handling.
+ * - TEKEN_XTERM: Enable xterm-style emulation, instead of cons25.
+ */
+
+#if defined(__FreeBSD__) && defined(_KERNEL)
+#include "opt_teken.h"
+#endif /* __FreeBSD__ && _KERNEL */
+
+#ifdef TEKEN_UTF8
+typedef uint32_t teken_char_t;
+#else /* !TEKEN_UTF8 */
+typedef unsigned char teken_char_t;
+#endif /* TEKEN_UTF8 */
+typedef unsigned short teken_unit_t;
+typedef unsigned char teken_format_t;
+#define TF_BOLD 0x01
+#define TF_UNDERLINE 0x02
+#define TF_BLINK 0x04
+typedef unsigned char teken_color_t;
+#define TC_BLACK 0
+#define TC_RED 1
+#define TC_GREEN 2
+#define TC_BROWN 3
+#define TC_BLUE 4
+#define TC_MAGENTA 5
+#define TC_CYAN 6
+#define TC_WHITE 7
+#define TC_NCOLORS 8
+
+typedef struct {
+ teken_unit_t tp_row;
+ teken_unit_t tp_col;
+} teken_pos_t;
+typedef struct {
+ teken_pos_t tr_begin;
+ teken_pos_t tr_end;
+} teken_rect_t;
+typedef struct {
+ teken_format_t ta_format;
+ teken_color_t ta_fgcolor;
+ teken_color_t ta_bgcolor;
+} teken_attr_t;
+typedef struct {
+ teken_unit_t ts_begin;
+ teken_unit_t ts_end;
+} teken_span_t;
+
+typedef struct __teken teken_t;
+
+typedef void teken_state_t(teken_t *, teken_char_t);
+
+/*
+ * Drawing routines supplied by the user.
+ */
+
+typedef void tf_bell_t(void *);
+typedef void tf_cursor_t(void *, const teken_pos_t *);
+typedef void tf_putchar_t(void *, const teken_pos_t *, teken_char_t,
+ const teken_attr_t *);
+typedef void tf_fill_t(void *, const teken_rect_t *, teken_char_t,
+ const teken_attr_t *);
+typedef void tf_copy_t(void *, const teken_rect_t *, const teken_pos_t *);
+typedef void tf_param_t(void *, int, int);
+#define TP_SHOWCURSOR 0
+#define TP_CURSORKEYS 1
+#define TP_KEYPADAPP 2
+#define TP_AUTOREPEAT 3
+#define TP_SWITCHVT 4
+#define TP_132COLS 5
+typedef void tf_respond_t(void *, const void *, size_t);
+
+typedef struct {
+ tf_bell_t *tf_bell;
+ tf_cursor_t *tf_cursor;
+ tf_putchar_t *tf_putchar;
+ tf_fill_t *tf_fill;
+ tf_copy_t *tf_copy;
+ tf_param_t *tf_param;
+ tf_respond_t *tf_respond;
+} teken_funcs_t;
+
+#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
+typedef teken_char_t teken_scs_t(teken_char_t);
+#endif /* TEKEN_XTERM && TEKEN_UTF8 */
+
+/*
+ * Terminal state.
+ */
+
+struct __teken {
+ const teken_funcs_t *t_funcs;
+ void *t_softc;
+
+ teken_state_t *t_nextstate;
+ unsigned int t_stateflags;
+
+#define T_NUMSIZE 8
+ unsigned int t_nums[T_NUMSIZE];
+ unsigned int t_curnum;
+
+ teken_pos_t t_cursor;
+ teken_attr_t t_curattr;
+ teken_pos_t t_saved_cursor;
+ teken_attr_t t_saved_curattr;
+
+ teken_attr_t t_defattr;
+ teken_pos_t t_winsize;
+
+ /* For DECSTBM. */
+ teken_span_t t_scrollreg;
+ /* For DECOM. */
+ teken_span_t t_originreg;
+
+#define T_NUMCOL 160
+ unsigned int t_tabstops[T_NUMCOL / (sizeof(unsigned int) * 8)];
+
+#ifdef TEKEN_UTF8
+ unsigned int t_utf8_left;
+ teken_char_t t_utf8_partial;
+#endif /* TEKEN_UTF8 */
+
+#if defined(TEKEN_XTERM) && defined(TEKEN_UTF8)
+ unsigned int t_curscs;
+ teken_scs_t *t_saved_curscs;
+ teken_scs_t *t_scs[2];
+#endif /* TEKEN_XTERM && TEKEN_UTF8 */
+};
+
+/* Initialize teken structure. */
+void teken_init(teken_t *, const teken_funcs_t *, void *);
+
+/* Deliver character input. */
+void teken_input(teken_t *, const void *, size_t);
+
+/* Set teken attributes. */
+void teken_set_cursor(teken_t *, const teken_pos_t *);
+void teken_set_defattr(teken_t *, const teken_attr_t *);
+void teken_set_winsize(teken_t *, const teken_pos_t *);
+
+#endif /* !_TEKEN_H_ */
diff --git a/sys/dev/syscons/teken/teken_demo.c b/sys/dev/syscons/teken/teken_demo.c
new file mode 100644
index 0000000..bacfd68
--- /dev/null
+++ b/sys/dev/syscons/teken/teken_demo.c
@@ -0,0 +1,367 @@
+/*-
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/ioctl.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <ncurses.h>
+#if defined(__FreeBSD__)
+#include <libutil.h>
+#elif defined(__linux__)
+#include <pty.h>
+#else
+#include <util.h>
+#endif
+
+#include "teken.h"
+
+static tf_bell_t test_bell;
+static tf_cursor_t test_cursor;
+static tf_putchar_t test_putchar;
+static tf_fill_t test_fill;
+static tf_copy_t test_copy;
+static tf_param_t test_param;
+static tf_respond_t test_respond;
+
+static teken_funcs_t tf = {
+ .tf_bell = test_bell,
+ .tf_cursor = test_cursor,
+ .tf_putchar = test_putchar,
+ .tf_fill = test_fill,
+ .tf_copy = test_copy,
+ .tf_param = test_param,
+ .tf_respond = test_respond,
+};
+
+struct pixel {
+ teken_char_t c;
+ teken_attr_t a;
+};
+
+#define NCOLS 80
+#ifdef TEKEN_XTERM
+#define NROWS 24
+#else /* !TEKEN_XTERM */
+#define NROWS 25
+#endif /* TEKEN_XTERM */
+struct pixel buffer[NCOLS][NROWS];
+
+static int ptfd;
+
+static void
+printchar(const teken_pos_t *p)
+{
+ int y, x, attr = 0;
+ struct pixel *px;
+ char str[5] = { 0 };
+
+ assert(p->tp_row < NROWS);
+ assert(p->tp_col < NCOLS);
+
+ getyx(stdscr, y, x);
+
+ px = &buffer[p->tp_col][p->tp_row];
+
+ /* Convert Unicode to UTF-8. */
+#ifdef TEKEN_UTF8
+ if (px->c < 0x80) {
+ str[0] = px->c;
+ } else if (px->c < 0x800) {
+ str[0] = 0xc0 | (px->c >> 6);
+ str[1] = 0x80 | (px->c & 0x3f);
+ } else if (px->c < 0x10000) {
+ str[0] = 0xe0 | (px->c >> 12);
+ str[1] = 0x80 | ((px->c >> 6) & 0x3f);
+ str[2] = 0x80 | (px->c & 0x3f);
+ } else {
+ str[0] = 0xf0 | (px->c >> 18);
+ str[1] = 0x80 | ((px->c >> 12) & 0x3f);
+ str[2] = 0x80 | ((px->c >> 6) & 0x3f);
+ str[3] = 0x80 | (px->c & 0x3f);
+ }
+#else /* !TEKEN_UTF8 */
+ str[0] = px->c;
+#endif /* TEKEN_UTF8 */
+
+ if (px->a.ta_format & TF_BOLD)
+ attr |= A_BOLD;
+ if (px->a.ta_format & TF_UNDERLINE)
+ attr |= A_UNDERLINE;
+ if (px->a.ta_format & TF_BLINK)
+ attr |= A_BLINK;
+
+ bkgdset(attr | COLOR_PAIR(px->a.ta_fgcolor + 8 * px->a.ta_bgcolor));
+ mvaddstr(p->tp_row, p->tp_col, str);
+
+ move(y, x);
+}
+
+static void
+test_bell(void *s __unused)
+{
+
+ beep();
+}
+
+static void
+test_cursor(void *s __unused, const teken_pos_t *p)
+{
+
+ move(p->tp_row, p->tp_col);
+}
+
+static void
+test_putchar(void *s __unused, const teken_pos_t *p, teken_char_t c,
+ const teken_attr_t *a)
+{
+
+ buffer[p->tp_col][p->tp_row].c = c;
+ buffer[p->tp_col][p->tp_row].a = *a;
+ printchar(p);
+}
+
+static void
+test_fill(void *s, const teken_rect_t *r, teken_char_t c,
+ const teken_attr_t *a)
+{
+ teken_pos_t p;
+
+ /* Braindead implementation of fill() - just call putchar(). */
+ for (p.tp_row = r->tr_begin.tp_row; p.tp_row < r->tr_end.tp_row; p.tp_row++)
+ for (p.tp_col = r->tr_begin.tp_col; p.tp_col < r->tr_end.tp_col; p.tp_col++)
+ test_putchar(s, &p, c, a);
+}
+
+static void
+test_copy(void *s __unused, const teken_rect_t *r, const teken_pos_t *p)
+{
+ int nrow, ncol, x, y; /* Has to be signed - >= 0 comparison */
+ teken_pos_t d;
+
+ /*
+ * Copying is a little tricky. We must make sure we do it in
+ * correct order, to make sure we don't overwrite our own data.
+ */
+
+ nrow = r->tr_end.tp_row - r->tr_begin.tp_row;
+ ncol = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+ if (p->tp_row < r->tr_begin.tp_row) {
+ /* Copy from top to bottom. */
+ if (p->tp_col < r->tr_begin.tp_col) {
+ /* Copy from left to right. */
+ for (y = 0; y < nrow; y++) {
+ d.tp_row = p->tp_row + y;
+ for (x = 0; x < ncol; x++) {
+ d.tp_col = p->tp_col + x;
+ buffer[d.tp_col][d.tp_row] =
+ buffer[r->tr_begin.tp_col + x][r->tr_begin.tp_row + y];
+ printchar(&d);
+ }
+ }
+ } else {
+ /* Copy from right to left. */
+ for (y = 0; y < nrow; y++) {
+ d.tp_row = p->tp_row + y;
+ for (x = ncol - 1; x >= 0; x--) {
+ d.tp_col = p->tp_col + x;
+ buffer[d.tp_col][d.tp_row] =
+ buffer[r->tr_begin.tp_col + x][r->tr_begin.tp_row + y];
+ printchar(&d);
+ }
+ }
+ }
+ } else {
+ /* Copy from bottom to top. */
+ if (p->tp_col < r->tr_begin.tp_col) {
+ /* Copy from left to right. */
+ for (y = nrow - 1; y >= 0; y--) {
+ d.tp_row = p->tp_row + y;
+ for (x = 0; x < ncol; x++) {
+ d.tp_col = p->tp_col + x;
+ buffer[d.tp_col][d.tp_row] =
+ buffer[r->tr_begin.tp_col + x][r->tr_begin.tp_row + y];
+ printchar(&d);
+ }
+ }
+ } else {
+ /* Copy from right to left. */
+ for (y = nrow - 1; y >= 0; y--) {
+ d.tp_row = p->tp_row + y;
+ for (x = ncol - 1; x >= 0; x--) {
+ d.tp_col = p->tp_col + x;
+ buffer[d.tp_col][d.tp_row] =
+ buffer[r->tr_begin.tp_col + x][r->tr_begin.tp_row + y];
+ printchar(&d);
+ }
+ }
+ }
+ }
+}
+
+static void
+test_param(void *s __unused, int cmd, int value)
+{
+
+ switch (cmd) {
+ case TP_SHOWCURSOR:
+ curs_set(value);
+ break;
+ case TP_KEYPADAPP:
+ keypad(stdscr, value ? TRUE : FALSE);
+ break;
+ }
+}
+
+static void
+test_respond(void *s __unused, const void *buf, size_t len)
+{
+
+ write(ptfd, buf, len);
+}
+
+static void
+redraw_border(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < NROWS; i++)
+ mvaddch(i, NCOLS, '|');
+ for (i = 0; i < NCOLS; i++)
+ mvaddch(NROWS, i, '-');
+
+ mvaddch(NROWS, NCOLS, '+');
+}
+
+static void
+redraw_all(void)
+{
+ teken_pos_t tp;
+
+ for (tp.tp_row = 0; tp.tp_row < NROWS; tp.tp_row++)
+ for (tp.tp_col = 0; tp.tp_col < NCOLS; tp.tp_col++)
+ printchar(&tp);
+
+ redraw_border();
+}
+
+int
+main(int argc __unused, char *argv[] __unused)
+{
+ struct winsize ws;
+ teken_t t;
+ teken_pos_t tp;
+ fd_set rfds;
+ char b[256];
+ ssize_t bl;
+ const int ccolors[8] = {
+ COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
+ COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
+ };
+ int i, j;
+
+#ifdef TEKEN_UTF8
+ setlocale(LC_CTYPE, "UTF-8");
+#endif /* TEKEN_UTF8 */
+
+ tp.tp_row = ws.ws_row = NROWS;
+ tp.tp_col = ws.ws_col = NCOLS;
+
+ switch (forkpty(&ptfd, NULL, NULL, &ws)) {
+ case -1:
+ perror("forkpty");
+ exit(1);
+ case 0:
+#ifdef TEKEN_XTERM
+ setenv("TERM", "xterm", 1);
+#else /* !TEKEN_XTERM */
+ setenv("TERM", "cons25", 1);
+#endif /* TEKEN_XTERM */
+#ifdef TEKEN_UTF8
+ setenv("LC_CTYPE", "UTF-8", 0);
+#endif /* TEKEN_UTF8 */
+ execlp("zsh", "-zsh", NULL);
+ execlp("bash", "-bash", NULL);
+ execlp("sh", "-sh", NULL);
+ _exit(1);
+ }
+
+ teken_init(&t, &tf, NULL);
+ teken_set_winsize(&t, &tp);
+
+ initscr();
+ raw();
+ start_color();
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
+ init_pair(i + 8 * j, ccolors[i], ccolors[j]);
+
+ redraw_border();
+
+ FD_ZERO(&rfds);
+
+ for (;;) {
+ FD_SET(STDIN_FILENO, &rfds);
+ FD_SET(ptfd, &rfds);
+
+ if (select(ptfd + 1, &rfds, NULL, NULL, NULL) < 0) {
+ if (errno == EINTR) {
+ redraw_all();
+ refresh();
+ continue;
+ }
+ break;
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &rfds)) {
+ bl = read(STDIN_FILENO, b, sizeof b);
+ if (bl <= 0)
+ break;
+ write(ptfd, b, bl);
+ }
+
+ if (FD_ISSET(ptfd, &rfds)) {
+ bl = read(ptfd, b, sizeof b);
+ if (bl <= 0)
+ break;
+ teken_input(&t, b, bl);
+ refresh();
+ }
+ }
+
+ endwin();
+
+ return (0);
+}
diff --git a/sys/dev/syscons/teken/teken_scs.h b/sys/dev/syscons/teken/teken_scs.h
new file mode 100644
index 0000000..baeb296
--- /dev/null
+++ b/sys/dev/syscons/teken/teken_scs.h
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+static void
+teken_scs_set(teken_t *t, unsigned int g, teken_scs_t *ts)
+{
+
+ t->t_scs[g] = ts;
+}
+
+static void
+teken_scs_switch(teken_t *t, unsigned int g)
+{
+
+ t->t_curscs = g;
+}
+
+static void
+teken_scs_restore(teken_t *t)
+{
+
+ t->t_scs[t->t_curscs] = t->t_saved_curscs;
+}
+
+static void
+teken_scs_save(teken_t *t)
+{
+
+ t->t_saved_curscs = t->t_scs[t->t_curscs];
+}
+
+static teken_char_t
+teken_scs_process(teken_t *t, teken_char_t c)
+{
+
+ return (t->t_scs[t->t_curscs](c));
+}
+
+/* Unicode points for VT100 box drawing. */
+static const uint16_t teken_boxdrawing[31] = {
+ 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
+ 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
+ 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
+ 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7
+};
+
+static teken_char_t
+teken_scs_special_graphics(teken_char_t c)
+{
+
+ /* Box drawing. */
+ if (c >= '`' && c <= '~')
+ return (teken_boxdrawing[c - '`']);
+ return (c);
+}
+
+static teken_char_t
+teken_scs_uk_national(teken_char_t c)
+{
+
+ /* Pound sign. */
+ if (c == '#')
+ return (0xa3);
+ return (c);
+}
+
+static teken_char_t
+teken_scs_us_ascii(teken_char_t c)
+{
+
+ /* No processing. */
+ return (c);
+}
diff --git a/sys/dev/syscons/teken/teken_stress.c b/sys/dev/syscons/teken/teken_stress.c
new file mode 100644
index 0000000..1b71647
--- /dev/null
+++ b/sys/dev/syscons/teken/teken_stress.c
@@ -0,0 +1,123 @@
+/*-
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "teken.h"
+
+static tf_bell_t stress_bell;
+static tf_cursor_t stress_cursor;
+static tf_putchar_t stress_putchar;
+static tf_fill_t stress_fill;
+static tf_copy_t stress_copy;
+static tf_param_t stress_param;
+static tf_respond_t stress_respond;
+
+static teken_funcs_t tf = {
+ .tf_bell = stress_bell,
+ .tf_cursor = stress_cursor,
+ .tf_putchar = stress_putchar,
+ .tf_fill = stress_fill,
+ .tf_copy = stress_copy,
+ .tf_param = stress_param,
+ .tf_respond = stress_respond,
+};
+
+static void
+stress_bell(void *s __unused)
+{
+}
+
+static void
+stress_cursor(void *s __unused, const teken_pos_t *p __unused)
+{
+}
+
+static void
+stress_putchar(void *s __unused, const teken_pos_t *p __unused,
+ teken_char_t c __unused, const teken_attr_t *a __unused)
+{
+}
+
+static void
+stress_fill(void *s __unused, const teken_rect_t *r __unused,
+ teken_char_t c __unused, const teken_attr_t *a __unused)
+{
+}
+
+static void
+stress_copy(void *s __unused, const teken_rect_t *r __unused,
+ const teken_pos_t *p __unused)
+{
+}
+
+static void
+stress_param(void *s __unused, int cmd __unused, int value __unused)
+{
+}
+
+static void
+stress_respond(void *s __unused, const void *buf __unused, size_t len __unused)
+{
+}
+
+int
+main(int argc __unused, char *argv[] __unused)
+{
+ teken_t t;
+ int rnd;
+ unsigned int iteration = 0;
+ char buf[2048];
+
+ rnd = open("/dev/urandom", O_RDONLY);
+ if (rnd < 0) {
+ perror("/dev/urandom");
+ exit(1);
+ }
+
+ teken_init(&t, &tf, NULL);
+
+ for (;;) {
+ if (read(rnd, buf, sizeof buf) != sizeof buf) {
+ perror("read");
+ exit(1);
+ }
+
+ teken_input(&t, buf, sizeof buf);
+
+ iteration++;
+ if ((iteration % 10000) == 0)
+ printf("Processed %u frames\n", iteration);
+ }
+}
diff --git a/sys/dev/syscons/teken/teken_subr.h b/sys/dev/syscons/teken/teken_subr.h
new file mode 100644
index 0000000..2ca2c30
--- /dev/null
+++ b/sys/dev/syscons/teken/teken_subr.h
@@ -0,0 +1,1206 @@
+/*-
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+static void teken_subr_cursor_up(teken_t *, unsigned int);
+static void teken_subr_erase_line(teken_t *, unsigned int);
+static void teken_subr_regular_character(teken_t *, teken_char_t);
+static void teken_subr_reset_to_initial_state(teken_t *);
+static void teken_subr_save_cursor(teken_t *);
+
+static inline int
+teken_tab_isset(teken_t *t, unsigned int col)
+{
+ unsigned int b, o;
+
+ teken_assert(col <= T_NUMCOL);
+
+ b = col / (sizeof(unsigned int) * 8);
+ o = col % (sizeof(unsigned int) * 8);
+
+ return (t->t_tabstops[b] & (1 << o));
+}
+
+static inline void
+teken_tab_clear(teken_t *t, unsigned int col)
+{
+ unsigned int b, o;
+
+ teken_assert(col <= T_NUMCOL);
+
+ b = col / (sizeof(unsigned int) * 8);
+ o = col % (sizeof(unsigned int) * 8);
+
+ t->t_tabstops[b] &= ~(1 << o);
+}
+
+static inline void
+teken_tab_set(teken_t *t, unsigned int col)
+{
+ unsigned int b, o;
+
+ teken_assert(col <= T_NUMCOL);
+
+ b = col / (sizeof(unsigned int) * 8);
+ o = col % (sizeof(unsigned int) * 8);
+
+ t->t_tabstops[b] |= 1 << o;
+}
+
+static void
+teken_tab_default(teken_t *t)
+{
+ unsigned int i;
+
+ memset(&t->t_tabstops, 0, T_NUMCOL / 8);
+
+ for (i = 8; i < T_NUMCOL; i += 8)
+ teken_tab_set(t, i);
+}
+
+static void
+teken_subr_do_scroll(teken_t *t, int amount)
+{
+ teken_rect_t tr;
+ teken_pos_t tp;
+
+ teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row);
+ teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
+ teken_assert(amount != 0);
+
+ /* Copy existing data 1 line up. */
+ if (amount > 0) {
+ /* Scroll down. */
+
+ /* Copy existing data up. */
+ if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
+ tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount;
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+ tp.tp_row = t->t_scrollreg.ts_begin;
+ tp.tp_col = 0;
+ teken_funcs_copy(t, &tr, &tp);
+
+ tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount;
+ } else {
+ tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
+ }
+
+ /* Clear the last lines. */
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+ } else {
+ /* Scroll up. */
+ amount = -amount;
+
+ /* Copy existing data down. */
+ if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
+ tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+ tp.tp_row = t->t_scrollreg.ts_begin + amount;
+ tp.tp_col = 0;
+ teken_funcs_copy(t, &tr, &tp);
+
+ tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount;
+ } else {
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end;
+ }
+
+ /* Clear the first lines. */
+ tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+ }
+}
+
+static ssize_t
+teken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16])
+{
+
+ switch (cmd) {
+ case 5: /* Operating status. */
+ strcpy(response, "0n");
+ return (2);
+ case 6: { /* Cursor position. */
+ int len;
+
+ len = snprintf(response, 16, "%u;%uR",
+ (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1,
+ t->t_cursor.tp_col + 1);
+
+ if (len >= 16)
+ return (-1);
+ return (len);
+ }
+ case 15: /* Printer status. */
+ strcpy(response, "13n");
+ return (3);
+ case 25: /* UDK status. */
+ strcpy(response, "20n");
+ return (3);
+ case 26: /* Keyboard status. */
+ strcpy(response, "27;1n");
+ return (5);
+ default:
+ teken_printf("Unknown DSR\n");
+ return (-1);
+ }
+}
+
+static void
+teken_subr_alignment_test(teken_t *t)
+{
+ teken_rect_t tr;
+
+ t->t_scrollreg.ts_begin = 0;
+ t->t_scrollreg.ts_end = t->t_winsize.tp_row;
+
+ t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+
+ tr.tr_begin.tp_row = 0;
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end = t->t_winsize;
+ teken_funcs_fill(t, &tr, 'E', &t->t_defattr);
+}
+
+static void
+teken_subr_backspace(teken_t *t)
+{
+
+#ifdef TEKEN_XTERM
+ if (t->t_cursor.tp_col == 0)
+ return;
+
+ t->t_cursor.tp_col--;
+ t->t_stateflags &= ~TS_WRAPPED;
+#else /* !TEKEN_XTERM */
+ if (t->t_cursor.tp_col == 0) {
+ if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
+ return;
+ t->t_cursor.tp_row--;
+ t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+ } else {
+ t->t_cursor.tp_col--;
+ }
+#endif /* TEKEN_XTERM */
+
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_bell(teken_t *t)
+{
+
+ teken_funcs_bell(t);
+}
+
+static void
+teken_subr_carriage_return(teken_t *t)
+{
+
+ t->t_cursor.tp_col = 0;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_backward(teken_t *t, unsigned int ncols)
+{
+
+ if (ncols > t->t_cursor.tp_col)
+ t->t_cursor.tp_col = 0;
+ else
+ t->t_cursor.tp_col -= ncols;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs)
+{
+
+ do {
+ /* Stop when we've reached the beginning of the line. */
+ if (t->t_cursor.tp_col == 0)
+ break;
+
+ t->t_cursor.tp_col--;
+
+ /* Tab marker set. */
+ if (teken_tab_isset(t, t->t_cursor.tp_col))
+ ntabs--;
+ } while (ntabs > 0);
+
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_down(teken_t *t, unsigned int nrows)
+{
+
+ if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end)
+ t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
+ else
+ t->t_cursor.tp_row += nrows;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_forward(teken_t *t, unsigned int ncols)
+{
+
+ if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
+ t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+ else
+ t->t_cursor.tp_col += ncols;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs)
+{
+
+ do {
+ /* Stop when we've reached the end of the line. */
+ if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1)
+ break;
+
+ t->t_cursor.tp_col++;
+
+ /* Tab marker set. */
+ if (teken_tab_isset(t, t->t_cursor.tp_col))
+ ntabs--;
+ } while (ntabs > 0);
+
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_next_line(teken_t *t, unsigned int ncols)
+{
+
+ t->t_cursor.tp_col = 0;
+ teken_subr_cursor_down(t, ncols);
+}
+
+static void
+teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col)
+{
+
+ t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
+ if (row >= t->t_originreg.ts_end)
+ t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
+
+ t->t_cursor.tp_col = col - 1;
+ if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
+ t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_cursor_position_report(teken_t *t, unsigned int cmd)
+{
+ char response[18] = "\x1B[";
+ ssize_t len;
+
+ len = teken_subr_do_cpr(t, cmd, response + 2);
+ if (len < 0)
+ return;
+
+ teken_funcs_respond(t, response, len + 2);
+}
+
+static void
+teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols)
+{
+
+ t->t_cursor.tp_col = 0;
+ teken_subr_cursor_up(t, ncols);
+}
+
+static void
+teken_subr_cursor_up(teken_t *t, unsigned int nrows)
+{
+
+ if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row)
+ t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
+ else
+ t->t_cursor.tp_row -= nrows;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_delete_character(teken_t *t, unsigned int ncols)
+{
+ teken_rect_t tr;
+
+ tr.tr_begin.tp_row = t->t_cursor.tp_row;
+ tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+
+ if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
+ tr.tr_begin.tp_col = t->t_cursor.tp_col;
+ } else {
+ /* Copy characters to the left. */
+ tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols;
+ teken_funcs_copy(t, &tr, &t->t_cursor);
+
+ tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols;
+ }
+
+ /* Blank trailing columns. */
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_delete_line(teken_t *t, unsigned int nrows)
+{
+ teken_rect_t tr;
+
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+
+ if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
+ tr.tr_begin.tp_row = t->t_cursor.tp_row;
+ } else {
+ teken_pos_t tp;
+
+ /* Copy rows up. */
+ tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows;
+ tp.tp_row = t->t_cursor.tp_row;
+ tp.tp_col = 0;
+ teken_funcs_copy(t, &tr, &tp);
+
+ tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows;
+ }
+
+ /* Blank trailing rows. */
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_device_control_string(teken_t *t __unused)
+{
+
+ teken_printf("device control string???\n");
+}
+
+static void
+teken_subr_device_status_report(teken_t *t, unsigned int cmd)
+{
+ char response[19] = "\x1B[?";
+ ssize_t len;
+
+ len = teken_subr_do_cpr(t, cmd, response + 3);
+ if (len < 0)
+ return;
+
+ teken_funcs_respond(t, response, len + 3);
+}
+
+static void
+teken_subr_double_height_double_width_line_top(teken_t *t __unused)
+{
+
+ teken_printf("double height double width top\n");
+}
+
+static void
+teken_subr_double_height_double_width_line_bottom(teken_t *t __unused)
+{
+
+ teken_printf("double height double width bottom\n");
+}
+
+static void
+teken_subr_erase_character(teken_t *t, unsigned int ncols)
+{
+ teken_rect_t tr;
+
+ tr.tr_begin = t->t_cursor;
+ tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
+
+ if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+ else
+ tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
+
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_erase_display(teken_t *t, unsigned int mode)
+{
+ teken_rect_t r;
+
+ r.tr_begin.tp_col = 0;
+ r.tr_end.tp_col = t->t_winsize.tp_col;
+
+ switch (mode) {
+ case 1: /* Erase from the top to the cursor. */
+ teken_subr_erase_line(t, 1);
+
+ /* Erase lines above. */
+ if (t->t_cursor.tp_row == 0)
+ return;
+ r.tr_begin.tp_row = 0;
+ r.tr_end.tp_row = t->t_cursor.tp_row;
+ break;
+ case 2: /* Erase entire display. */
+ r.tr_begin.tp_row = 0;
+ r.tr_end.tp_row = t->t_winsize.tp_row;
+ break;
+ default: /* Erase from cursor to the bottom. */
+ teken_subr_erase_line(t, 0);
+
+ /* Erase lines below. */
+ if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1)
+ return;
+ r.tr_begin.tp_row = t->t_cursor.tp_row + 1;
+ r.tr_end.tp_row = t->t_winsize.tp_row;
+ break;
+ }
+
+ teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_erase_line(teken_t *t, unsigned int mode)
+{
+ teken_rect_t r;
+
+ r.tr_begin.tp_row = t->t_cursor.tp_row;
+ r.tr_end.tp_row = t->t_cursor.tp_row + 1;
+
+ switch (mode) {
+ case 1: /* Erase from the beginning of the line to the cursor. */
+ r.tr_begin.tp_col = 0;
+ r.tr_end.tp_col = t->t_cursor.tp_col + 1;
+ break;
+ case 2: /* Erase entire line. */
+ r.tr_begin.tp_col = 0;
+ r.tr_end.tp_col = t->t_winsize.tp_col;
+ break;
+ default: /* Erase from cursor to the end of the line. */
+ r.tr_begin.tp_col = t->t_cursor.tp_col;
+ r.tr_end.tp_col = t->t_winsize.tp_col;
+ break;
+ }
+
+ teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_g0_scs_special_graphics(teken_t *t __unused)
+{
+
+ teken_scs_set(t, 0, teken_scs_special_graphics);
+}
+
+static void
+teken_subr_g0_scs_uk_national(teken_t *t __unused)
+{
+
+ teken_scs_set(t, 0, teken_scs_uk_national);
+}
+
+static void
+teken_subr_g0_scs_us_ascii(teken_t *t __unused)
+{
+
+ teken_scs_set(t, 0, teken_scs_us_ascii);
+}
+
+static void
+teken_subr_g1_scs_special_graphics(teken_t *t __unused)
+{
+
+ teken_scs_set(t, 1, teken_scs_special_graphics);
+}
+
+static void
+teken_subr_g1_scs_uk_national(teken_t *t __unused)
+{
+
+ teken_scs_set(t, 1, teken_scs_uk_national);
+}
+
+static void
+teken_subr_g1_scs_us_ascii(teken_t *t __unused)
+{
+
+ teken_scs_set(t, 1, teken_scs_us_ascii);
+}
+
+static void
+teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col)
+{
+
+ t->t_cursor.tp_col = col - 1;
+ if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
+ t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_horizontal_tab(teken_t *t)
+{
+#ifdef TEKEN_XTERM
+ teken_rect_t tr;
+
+ tr.tr_begin = t->t_cursor;
+ teken_subr_cursor_forward_tabulation(t, 1);
+ tr.tr_end.tp_row = tr.tr_begin.tp_row + 1;
+ tr.tr_end.tp_col = t->t_cursor.tp_col;
+
+ /* Blank region that we skipped. */
+ if (tr.tr_end.tp_col > tr.tr_begin.tp_col)
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+#else /* !TEKEN_XTERM */
+
+ teken_subr_cursor_forward_tabulation(t, 1);
+#endif /* TEKEN_XTERM */
+}
+
+static void
+teken_subr_horizontal_tab_set(teken_t *t)
+{
+
+ teken_tab_set(t, t->t_cursor.tp_col);
+}
+
+static void
+teken_subr_index(teken_t *t)
+{
+
+ if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) {
+ t->t_cursor.tp_row++;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+ } else {
+ teken_subr_do_scroll(t, 1);
+ }
+}
+
+static void
+teken_subr_insert_character(teken_t *t, unsigned int ncols)
+{
+ teken_rect_t tr;
+
+ tr.tr_begin = t->t_cursor;
+ tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
+
+ if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+ } else {
+ teken_pos_t tp;
+
+ /* Copy characters to the right. */
+ tr.tr_end.tp_col = t->t_winsize.tp_col - ncols;
+ tp.tp_row = t->t_cursor.tp_row;
+ tp.tp_col = t->t_cursor.tp_col + ncols;
+ teken_funcs_copy(t, &tr, &tp);
+
+ tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
+ }
+
+ /* Blank current location. */
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_insert_line(teken_t *t, unsigned int nrows)
+{
+ teken_rect_t tr;
+
+ tr.tr_begin.tp_row = t->t_cursor.tp_row;
+ tr.tr_begin.tp_col = 0;
+ tr.tr_end.tp_col = t->t_winsize.tp_col;
+
+ if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end;
+ } else {
+ teken_pos_t tp;
+
+ /* Copy lines down. */
+ tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows;
+ tp.tp_row = t->t_cursor.tp_row + nrows;
+ tp.tp_col = 0;
+ teken_funcs_copy(t, &tr, &tp);
+
+ tr.tr_end.tp_row = t->t_cursor.tp_row + nrows;
+ }
+
+ /* Blank current location. */
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+}
+
+static void
+teken_subr_keypad_application_mode(teken_t *t)
+{
+
+ teken_funcs_param(t, TP_KEYPADAPP, 1);
+}
+
+static void
+teken_subr_keypad_numeric_mode(teken_t *t)
+{
+
+ teken_funcs_param(t, TP_KEYPADAPP, 0);
+}
+
+static void
+teken_subr_newline(teken_t *t)
+{
+
+ t->t_cursor.tp_row++;
+
+ if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) {
+ teken_subr_do_scroll(t, 1);
+ t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
+ }
+
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_newpage(teken_t *t)
+{
+#ifdef TEKEN_XTERM
+
+ teken_subr_newline(t);
+#else /* !TEKEN_XTERM */
+ teken_rect_t tr;
+
+ tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0;
+ tr.tr_end = t->t_winsize;
+ teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
+
+ t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
+ teken_funcs_cursor(t);
+#endif /* TEKEN_XTERM */
+}
+
+static void
+teken_subr_next_line(teken_t *t)
+{
+
+ t->t_cursor.tp_col = 0;
+ teken_subr_newline(t);
+}
+
+static void
+teken_subr_pan_down(teken_t *t, unsigned int nrows)
+{
+
+ teken_subr_do_scroll(t, (int)nrows);
+}
+
+static void
+teken_subr_pan_up(teken_t *t, unsigned int nrows)
+{
+
+ teken_subr_do_scroll(t, -(int)nrows);
+}
+
+static void
+teken_subr_primary_device_attributes(teken_t *t, unsigned int request)
+{
+
+ if (request == 0) {
+ const char response[] = "\x1B[?1;2c";
+
+ teken_funcs_respond(t, response, sizeof response - 1);
+ } else {
+ teken_printf("Unknown DA1\n");
+ }
+}
+
+static void
+teken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c,
+ int width)
+{
+
+ if (t->t_stateflags & TS_INSERT &&
+ tp->tp_col < t->t_winsize.tp_col - width) {
+ teken_rect_t ctr;
+ teken_pos_t ctp;
+
+ /* Insert mode. Move existing characters to the right. */
+ ctr.tr_begin = *tp;
+ ctr.tr_end.tp_row = tp->tp_row + 1;
+ ctr.tr_end.tp_col = t->t_winsize.tp_col - width;
+ ctp.tp_row = tp->tp_row;
+ ctp.tp_col = tp->tp_col + width;
+ teken_funcs_copy(t, &ctr, &ctp);
+ }
+
+ teken_funcs_putchar(t, tp, c, &t->t_curattr);
+}
+
+static void
+teken_subr_regular_character(teken_t *t, teken_char_t c)
+{
+ int width;
+
+ c = teken_scs_process(t, c);
+
+ /* XXX: Don't process zero-width characters yet. */
+ width = teken_wcwidth(c);
+ if (width <= 0)
+ return;
+
+#ifdef TEKEN_XTERM
+ if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 &&
+ (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) ==
+ (TS_WRAPPED|TS_AUTOWRAP)) {
+ teken_pos_t tp;
+
+ /* Perform line wrapping. */
+
+ if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
+ /* Perform scrolling. */
+ teken_subr_do_scroll(t, 1);
+ tp.tp_row = t->t_scrollreg.ts_end - 1;
+ } else {
+ /* No scrolling needed. */
+ tp.tp_row = t->t_cursor.tp_row + 1;
+ if (tp.tp_row == t->t_winsize.tp_row) {
+ /*
+ * Corner case: regular character
+ * outside scrolling region, but at the
+ * bottom of the screen.
+ */
+ teken_subr_do_putchar(t, &t->t_cursor,
+ c, width);
+ return;
+ }
+ }
+
+ tp.tp_col = 0;
+ teken_subr_do_putchar(t, &tp, c, width);
+
+ t->t_cursor.tp_row = tp.tp_row;
+ t->t_cursor.tp_col = width;
+ t->t_stateflags &= ~TS_WRAPPED;
+ } else {
+ /* No line wrapping needed. */
+ teken_subr_do_putchar(t, &t->t_cursor, c, width);
+ t->t_cursor.tp_col += width;
+
+ if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
+ t->t_stateflags |= TS_WRAPPED;
+ t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
+ } else {
+ t->t_stateflags &= ~TS_WRAPPED;
+ }
+ }
+#else /* !TEKEN_XTERM */
+ teken_subr_do_putchar(t, &t->t_cursor, c, width);
+ t->t_cursor.tp_col += width;
+
+ if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
+ if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
+ /* Perform scrolling. */
+ teken_subr_do_scroll(t, 1);
+ } else {
+ /* No scrolling needed. */
+ if (t->t_cursor.tp_row < t->t_winsize.tp_row - 1)
+ t->t_cursor.tp_row++;
+ }
+ t->t_cursor.tp_col = 0;
+ }
+#endif /* TEKEN_XTERM */
+
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
+{
+
+ switch (cmd) {
+ case 1: /* Cursor keys mode. */
+ teken_funcs_param(t, TP_CURSORKEYS, 0);
+ break;
+ case 2: /* DECANM: ANSI/VT52 mode. */
+ teken_printf("DECRST VT52\n");
+ break;
+ case 3: /* 132 column mode. */
+ teken_funcs_param(t, TP_132COLS, 0);
+ teken_subr_reset_to_initial_state(t);
+ break;
+ case 5: /* Inverse video. */
+ teken_printf("DECRST inverse video\n");
+ break;
+ case 6: /* Origin mode. */
+ t->t_stateflags &= ~TS_ORIGIN;
+ t->t_originreg.ts_begin = 0;
+ t->t_originreg.ts_end = t->t_winsize.tp_row;
+ t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+ break;
+ case 7: /* Autowrap mode. */
+ t->t_stateflags &= ~TS_AUTOWRAP;
+ break;
+ case 8: /* Autorepeat mode. */
+ teken_funcs_param(t, TP_AUTOREPEAT, 0);
+ break;
+ case 25: /* Hide cursor. */
+ teken_funcs_param(t, TP_SHOWCURSOR, 0);
+ break;
+ case 40: /* Disallow 132 columns. */
+ teken_printf("DECRST allow 132\n");
+ break;
+ case 45: /* Disable reverse wraparound. */
+ teken_printf("DECRST reverse wraparound\n");
+ break;
+ case 47: /* Switch to alternate buffer. */
+ teken_printf("Switch to alternate buffer\n");
+ break;
+ default:
+ teken_printf("Unknown DECRST: %u\n", cmd);
+ }
+}
+
+static void
+teken_subr_reset_mode(teken_t *t, unsigned int cmd)
+{
+
+ switch (cmd) {
+ case 4:
+ t->t_stateflags &= ~TS_INSERT;
+ break;
+ default:
+ teken_printf("Unknown reset mode: %u\n", cmd);
+ }
+}
+
+static void
+teken_subr_do_reset(teken_t *t)
+{
+
+ t->t_curattr = t->t_defattr;
+ t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
+ t->t_stateflags = TS_AUTOWRAP;
+
+ teken_scs_set(t, 0, teken_scs_us_ascii);
+ teken_scs_set(t, 1, teken_scs_us_ascii);
+ teken_scs_switch(t, 0);
+
+ teken_subr_save_cursor(t);
+ teken_tab_default(t);
+}
+
+static void
+teken_subr_reset_to_initial_state(teken_t *t)
+{
+
+ teken_subr_do_reset(t);
+ teken_subr_erase_display(t, 2);
+ teken_funcs_param(t, TP_SHOWCURSOR, 1);
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_restore_cursor(teken_t *t)
+{
+
+ t->t_cursor = t->t_saved_cursor;
+ t->t_curattr = t->t_saved_curattr;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_scs_restore(t);
+ teken_funcs_cursor(t);
+}
+
+static void
+teken_subr_reverse_index(teken_t *t)
+{
+
+ if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) {
+ t->t_cursor.tp_row--;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+ } else {
+ teken_subr_do_scroll(t, -1);
+ }
+}
+
+static void
+teken_subr_save_cursor(teken_t *t)
+{
+
+ t->t_saved_cursor = t->t_cursor;
+ t->t_saved_curattr = t->t_curattr;
+ teken_scs_save(t);
+}
+
+static void
+teken_subr_secondary_device_attributes(teken_t *t, unsigned int request)
+{
+
+ if (request == 0) {
+ const char response[] = "\x1B[>0;10;0c";
+ teken_funcs_respond(t, response, sizeof response - 1);
+ } else {
+ teken_printf("Unknown DA2\n");
+ }
+}
+
+static void
+teken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
+{
+
+ switch (cmd) {
+ case 1: /* Cursor keys mode. */
+ teken_funcs_param(t, TP_CURSORKEYS, 1);
+ break;
+ case 2: /* DECANM: ANSI/VT52 mode. */
+ teken_printf("DECSET VT52\n");
+ break;
+ case 3: /* 132 column mode. */
+ teken_funcs_param(t, TP_132COLS, 1);
+ teken_subr_reset_to_initial_state(t);
+ break;
+ case 5: /* Inverse video. */
+ teken_printf("DECSET inverse video\n");
+ break;
+ case 6: /* Origin mode. */
+ t->t_stateflags |= TS_ORIGIN;
+ t->t_originreg = t->t_scrollreg;
+ t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
+ t->t_cursor.tp_col = 0;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+ break;
+ case 7: /* Autowrap mode. */
+ t->t_stateflags |= TS_AUTOWRAP;
+ break;
+ case 8: /* Autorepeat mode. */
+ teken_funcs_param(t, TP_AUTOREPEAT, 1);
+ break;
+ case 25: /* Display cursor. */
+ teken_funcs_param(t, TP_SHOWCURSOR, 1);
+ break;
+ case 40: /* Allow 132 columns. */
+ teken_printf("DECSET allow 132\n");
+ break;
+ case 45: /* Enable reverse wraparound. */
+ teken_printf("DECSET reverse wraparound\n");
+ break;
+ case 47: /* Switch to alternate buffer. */
+ teken_printf("Switch away from alternate buffer\n");
+ break;
+ default:
+ teken_printf("Unknown DECSET: %u\n", cmd);
+ }
+}
+
+static void
+teken_subr_set_mode(teken_t *t, unsigned int cmd)
+{
+
+ switch (cmd) {
+ case 4:
+ teken_printf("Insert mode\n");
+ t->t_stateflags |= TS_INSERT;
+ break;
+ default:
+ teken_printf("Unknown set mode: %u\n", cmd);
+ }
+}
+
+static void
+teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds,
+ unsigned int cmds[])
+{
+ unsigned int i, n;
+
+ /* No attributes means reset. */
+ if (ncmds == 0) {
+ t->t_curattr = t->t_defattr;
+ return;
+ }
+
+ for (i = 0; i < ncmds; i++) {
+ n = cmds[i];
+
+ switch (n) {
+ case 0: /* Reset. */
+ t->t_curattr = t->t_defattr;
+ break;
+ case 1: /* Bold. */
+ t->t_curattr.ta_format |= TF_BOLD;
+ break;
+ case 4: /* Underline. */
+ t->t_curattr.ta_format |= TF_UNDERLINE;
+ break;
+ case 5: /* Blink. */
+ t->t_curattr.ta_format |= TF_BLINK;
+ break;
+ case 7: /* Reverse. */
+ t->t_curattr.ta_format |= TF_REVERSE;
+ break;
+ case 22: /* Remove bold. */
+ t->t_curattr.ta_format &= ~TF_BOLD;
+ break;
+ case 24: /* Remove underline. */
+ t->t_curattr.ta_format &= ~TF_UNDERLINE;
+ break;
+ case 25: /* Remove blink. */
+ t->t_curattr.ta_format &= ~TF_BLINK;
+ break;
+ case 27: /* Remove reverse. */
+ t->t_curattr.ta_format &= ~TF_REVERSE;
+ break;
+ case 30: /* Set foreground color: black */
+ case 31: /* Set foreground color: red */
+ case 32: /* Set foreground color: green */
+ case 33: /* Set foreground color: brown */
+ case 34: /* Set foreground color: blue */
+ case 35: /* Set foreground color: magenta */
+ case 36: /* Set foreground color: cyan */
+ case 37: /* Set foreground color: white */
+ t->t_curattr.ta_fgcolor = n - 30;
+ break;
+ case 39: /* Set default foreground color. */
+ t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor;
+ break;
+ case 40: /* Set background color: black */
+ case 41: /* Set background color: red */
+ case 42: /* Set background color: green */
+ case 43: /* Set background color: brown */
+ case 44: /* Set background color: blue */
+ case 45: /* Set background color: magenta */
+ case 46: /* Set background color: cyan */
+ case 47: /* Set background color: white */
+ t->t_curattr.ta_bgcolor = n - 40;
+ break;
+ case 49: /* Set default background color. */
+ t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor;
+ break;
+ default:
+ teken_printf("unsupported attribute %u\n", n);
+ }
+ }
+}
+
+static void
+teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top,
+ unsigned int bottom)
+{
+
+ /* Adjust top row number. */
+ if (top > 0)
+ top--;
+ /* Adjust bottom row number. */
+ if (bottom == 0 || bottom > t->t_winsize.tp_row)
+ bottom = t->t_winsize.tp_row;
+
+ /* Invalid arguments. */
+ if (top >= bottom - 1) {
+ top = 0;
+ bottom = t->t_winsize.tp_row;
+ }
+
+ t->t_scrollreg.ts_begin = top;
+ t->t_scrollreg.ts_end = bottom;
+ if (t->t_stateflags & TS_ORIGIN) {
+ /* XXX: home cursor? */
+ t->t_originreg = t->t_scrollreg;
+ t->t_cursor.tp_row = t->t_originreg.ts_begin;
+ t->t_cursor.tp_col = 0;
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+ }
+}
+
+static void
+teken_subr_single_height_double_width_line(teken_t *t __unused)
+{
+
+ teken_printf("single height double width???\n");
+}
+
+static void
+teken_subr_single_height_single_width_line(teken_t *t __unused)
+{
+
+ teken_printf("single height single width???\n");
+}
+
+static void
+teken_subr_string_terminator(teken_t *t __unused)
+{
+
+ teken_printf("string terminator???\n");
+}
+
+static void
+teken_subr_tab_clear(teken_t *t, unsigned int cmd)
+{
+
+ switch (cmd) {
+ case 0:
+ teken_tab_clear(t, t->t_cursor.tp_col);
+ break;
+ case 3:
+ memset(&t->t_tabstops, 0, T_NUMCOL / 8);
+ break;
+ }
+}
+
+static void
+teken_subr_vertical_position_absolute(teken_t *t, unsigned int row)
+{
+
+ t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
+ if (row >= t->t_originreg.ts_end)
+ t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
+
+
+ t->t_stateflags &= ~TS_WRAPPED;
+ teken_funcs_cursor(t);
+}
diff --git a/sys/dev/syscons/teken/teken_subr_compat.h b/sys/dev/syscons/teken/teken_subr_compat.h
new file mode 100644
index 0000000..e49c1cd
--- /dev/null
+++ b/sys/dev/syscons/teken/teken_subr_compat.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+static void
+teken_subr_cons25_set_cursor_type(teken_t *t, unsigned int type)
+{
+
+ teken_funcs_param(t, TP_SHOWCURSOR, type != 1);
+}
+
+static const teken_color_t cons25_colors[8] = { TC_BLACK, TC_BLUE,
+ TC_GREEN, TC_CYAN, TC_RED, TC_MAGENTA, TC_BROWN, TC_WHITE };
+
+static void
+teken_subr_cons25_set_adapter_background(teken_t *t, unsigned int c)
+{
+
+ t->t_defattr.ta_bgcolor = cons25_colors[c % 8];
+ t->t_curattr.ta_bgcolor = cons25_colors[c % 8];
+}
+
+static void
+teken_subr_cons25_set_adapter_foreground(teken_t *t, unsigned int c)
+{
+
+ t->t_defattr.ta_fgcolor = cons25_colors[c % 8];
+ t->t_curattr.ta_fgcolor = cons25_colors[c % 8];
+ if (c >= 8) {
+ t->t_defattr.ta_format |= TF_BOLD;
+ t->t_curattr.ta_format |= TF_BOLD;
+ } else {
+ t->t_defattr.ta_format &= ~TF_BOLD;
+ t->t_curattr.ta_format &= ~TF_BOLD;
+ }
+}
+
+static void
+teken_subr_cons25_switch_virtual_terminal(teken_t *t, unsigned int vt)
+{
+
+ teken_funcs_param(t, TP_SWITCHVT, vt);
+}
+
+#if 0
+static void
+teken_subr_vt52_decid(teken_t *t)
+{
+ const char response[] = "\x1B/Z";
+
+ teken_funcs_respond(t, response, sizeof response - 1);
+}
+#endif
diff --git a/sys/dev/syscons/teken/teken_wcwidth.h b/sys/dev/syscons/teken/teken_wcwidth.h
new file mode 100644
index 0000000..838fb3d
--- /dev/null
+++ b/sys/dev/syscons/teken/teken_wcwidth.h
@@ -0,0 +1,120 @@
+/*
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to this software.
+ *
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ *
+ * $FreeBSD$
+ */
+
+struct interval {
+ teken_char_t first;
+ teken_char_t last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(teken_char_t ucs, const struct interval *table, int max) {
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+static int teken_wcwidth(teken_char_t ucs)
+{
+ /* sorted list of non-overlapping intervals of non-spacing characters */
+ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
+ static const struct interval combining[] = {
+ { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
+ { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+ { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
+ { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
+ { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+ { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+ { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
+ { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
+ { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
+ { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
+ { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
+ { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
+ { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
+ { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
+ { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
+ { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
+ { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
+ { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
+ { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
+ { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+ { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
+ { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
+ { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
+ { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
+ { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
+ { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
+ { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
+ { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
+ { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
+ { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
+ { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
+ { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
+ { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
+ { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
+ { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
+ { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
+ { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
+ { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
+ { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
+ { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
+ { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
+ { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
+ { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
+ { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
+ { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
+ { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
+ { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
+ { 0xE0100, 0xE01EF }
+ };
+
+ /* test for 8-bit control characters */
+ if (ucs == 0)
+ return 0;
+ if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+ return -1;
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, combining,
+ sizeof(combining) / sizeof(struct interval) - 1))
+ return 0;
+
+ /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+ return 1 +
+ (ucs >= 0x1100 &&
+ (ucs <= 0x115f || /* Hangul Jamo init. consonants */
+ ucs == 0x2329 || ucs == 0x232a ||
+ (ucs >= 0x2e80 && ucs <= 0xa4cf &&
+ ucs != 0x303f) || /* CJK ... Yi */
+ (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+ (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+ (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
+ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+ (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
+ (ucs >= 0xffe0 && ucs <= 0xffe6) ||
+ (ucs >= 0x20000 && ucs <= 0x2fffd) ||
+ (ucs >= 0x30000 && ucs <= 0x3fffd)));
+}
diff --git a/sys/dev/uart/uart_cpu_mv.c b/sys/dev/uart/uart_cpu_mv.c
index ec9adbe..067f5dc 100644
--- a/sys/dev/uart/uart_cpu_mv.c
+++ b/sys/dev/uart/uart_cpu_mv.c
@@ -53,6 +53,7 @@ bus_space_tag_t uart_bus_space_mem;
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
+
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
}
@@ -77,7 +78,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
0, &di->bas.bsh) != 0)
return (ENXIO);
- di->baudrate = 115200;
+ di->baudrate = 0;
di->bas.regshft = 2;
di->bas.rclk = get_tclk();
di->databits = 8;
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 11a5e83..c159600 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -2769,7 +2769,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
/* We will change them to point here */
snext = exfer->sqtdend->nextqtd;
- next = htohc32(sc, snext->physaddr);
+ next = (snext != NULL) ? htohc32(sc, snext->physaddr) : EHCI_NULL(sc);
/*
* Now loop through any qTDs before us and keep track of the pointer
diff --git a/sys/dev/usb/ehci_mbus.c b/sys/dev/usb/ehci_mbus.c
index afa2430..792c89d 100644
--- a/sys/dev/usb/ehci_mbus.c
+++ b/sys/dev/usb/ehci_mbus.c
@@ -73,6 +73,19 @@ static device_shutdown_t ehci_mbus_shutdown;
static device_suspend_t ehci_mbus_suspend;
static device_resume_t ehci_mbus_resume;
+static int err_intr(void *arg);
+
+struct resource *irq_err;
+void *ih_err;
+
+#define USB_BRIDGE_INTR_CAUSE 0x210
+#define USB_BRIDGE_INTR_MASK 0x214
+
+#define MV_USB_ADDR_DECODE_ERR (1 << 0)
+#define MV_USB_HOST_UNDERFLOW (1 << 1)
+#define MV_USB_HOST_OVERFLOW (1 << 2)
+#define MV_USB_DEVICE_UNDERFLOW (1 << 3)
+
static int
ehci_mbus_suspend(device_t self)
{
@@ -157,6 +170,15 @@ ehci_mbus_attach(device_t self)
device_get_name(self));
sc->sc_size = MV_USB_SIZE - MV_USB_HOST_OFST;
+ rid = 0;
+ irq_err = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (irq_err == NULL) {
+ device_printf(self, "Could not allocate error irq\n");
+ ehci_mbus_detach(self);
+ return (ENXIO);
+ }
+
/*
* Notice: Marvell EHCI controller has TWO interrupt lines, so make sure to
* use the correct rid for the main one (controller interrupt) --
@@ -181,6 +203,19 @@ ehci_mbus_attach(device_t self)
sprintf(sc->sc_vendor, "Marvell");
sc->sc_id_vendor = EHCI_VENDORID_MRVL;
+ err = bus_setup_intr(self, irq_err, INTR_FAST | INTR_TYPE_BIO,
+ err_intr, NULL, sc, &ih_err);
+ if (err) {
+ device_printf(self, "Could not setup error irq, %d\n", err);
+ ih_err = NULL;
+ ehci_mbus_detach(self);
+ return (ENXIO);
+ }
+
+ EWRITE4(sc, USB_BRIDGE_INTR_MASK, MV_USB_ADDR_DECODE_ERR |
+ MV_USB_HOST_UNDERFLOW | MV_USB_HOST_OVERFLOW |
+ MV_USB_DEVICE_UNDERFLOW);
+
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
NULL, (driver_intr_t*)ehci_intr, sc, &sc->ih);
if (err) {
@@ -277,6 +312,17 @@ ehci_mbus_detach(device_t self)
err);
sc->ih = NULL;
}
+ EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
+
+ if (irq_err && ih_err) {
+ err = bus_teardown_intr(self, irq_err, ih_err);
+
+ if (err)
+ device_printf(self, "Could not tear down irq, %d\n",
+ err);
+ ih_err = NULL;
+ }
+
if (sc->sc_bus.bdev) {
device_delete_child(self, sc->sc_bus.bdev);
sc->sc_bus.bdev = NULL;
@@ -285,6 +331,10 @@ ehci_mbus_detach(device_t self)
bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
sc->irq_res = NULL;
}
+ if (irq_err) {
+ bus_release_resource(self, SYS_RES_IRQ, 1, irq_err);
+ irq_err = NULL;
+ }
if (sc->io_res) {
bus_release_resource(self, SYS_RES_MEMORY, 0, sc->io_res);
sc->io_res = NULL;
@@ -294,6 +344,32 @@ ehci_mbus_detach(device_t self)
return (0);
}
+static int
+err_intr(void *arg)
+{
+ ehci_softc_t *sc = arg;
+ unsigned int cause;
+
+ cause = EREAD4(sc, USB_BRIDGE_INTR_CAUSE);
+ if (cause) {
+ printf("IRQ ERR: cause: 0x%08x\n", cause);
+ if (cause & MV_USB_ADDR_DECODE_ERR)
+ printf("IRQ ERR: Address decoding error\n");
+ if (cause & MV_USB_HOST_UNDERFLOW)
+ printf("IRQ ERR: USB Host Underflow\n");
+ if (cause & MV_USB_HOST_OVERFLOW)
+ printf("IRQ ERR: USB Host Overflow\n");
+ if (cause & MV_USB_DEVICE_UNDERFLOW)
+ printf("IRQ ERR: USB Device Underflow\n");
+ if (cause & ~(MV_USB_ADDR_DECODE_ERR | MV_USB_HOST_UNDERFLOW |
+ MV_USB_HOST_OVERFLOW | MV_USB_DEVICE_UNDERFLOW))
+ printf("IRQ ERR: Unknown error\n");
+
+ EWRITE4(sc, USB_BRIDGE_INTR_CAUSE, 0);
+ }
+ return (FILTER_HANDLED);
+}
+
static device_method_t ehci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ehci_mbus_probe),
diff --git a/sys/dev/usb/ehci_pci.c b/sys/dev/usb/ehci_pci.c
index 1ae2228..819bc25 100644
--- a/sys/dev/usb/ehci_pci.c
+++ b/sys/dev/usb/ehci_pci.c
@@ -315,6 +315,14 @@ ehci_pci_attach(device_t self)
device_printf(self, "Quirk for CS5536 USB 2.0 enabled\n");
break;
}
+
+ /*
+ * Quirk for Parallels Desktop 4.0.
+ */
+ if (pci_get_devid(self) == PCI_EHCI_DEVICEID_ICH6) {
+ sc->sc_bus.usbrev = USBREV_2_0;
+ break;
+ }
sc->sc_bus.usbrev = USBREV_UNKNOWN;
return ENXIO;
case PCI_USBREV_2_0:
diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c
index 35ae548..c0c7cb6 100644
--- a/sys/dev/usb/if_rum.c
+++ b/sys/dev/usb/if_rum.c
@@ -108,6 +108,7 @@ static const struct usb_devno rum_devs[] = {
{ USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G },
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP },
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP },
+ { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG },
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1 },
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2 },
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3 },
diff --git a/sys/dev/usb/if_urtw.c b/sys/dev/usb/if_urtw.c
new file mode 100644
index 0000000..d1a3a84
--- /dev/null
+++ b/sys/dev/usb/if_urtw.c
@@ -0,0 +1,3324 @@
+/*-
+ * Copyright (c) 2008 Weongyo Jeong <weongyo@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
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.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>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+#include "usbdevs.h"
+
+#include <dev/usb/if_urtwreg.h>
+#include <dev/usb/if_urtwvar.h>
+
+SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
+#ifdef URTW_DEBUG
+int urtw_debug = 0;
+SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
+ "control debugging printfs");
+TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
+enum {
+ URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
+ URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
+ URTW_DEBUG_RESET = 0x00000004, /* reset processing */
+ URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
+ URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
+ URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
+ URTW_DEBUG_STAT = 0x00000040, /* statistic */
+ URTW_DEBUG_ANY = 0xffffffff
+};
+#define DPRINTF(sc, m, fmt, ...) do { \
+ if (sc->sc_debug & (m)) \
+ printf(fmt, __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(sc, m, fmt, ...) do { \
+ (void) sc; \
+} while (0)
+#endif
+int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
+SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW,
+ &urtw_preamble_mode, 0, "set the preable mode (long or short)");
+TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
+
+/* recognized device vendors/products */
+static const struct usb_devno urtw_devs[] = {
+#define URTW_DEV(v,p) { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }
+ URTW_DEV(REALTEK, RTL8187),
+ URTW_DEV(NETGEAR, WG111V2)
+#undef URTW_DEV
+};
+
+#define urtw_read8_m(sc, val, data) do { \
+ error = urtw_read8_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_write8_m(sc, val, data) do { \
+ error = urtw_write8_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_read16_m(sc, val, data) do { \
+ error = urtw_read16_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_write16_m(sc, val, data) do { \
+ error = urtw_write16_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_read32_m(sc, val, data) do { \
+ error = urtw_read32_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_write32_m(sc, val, data) do { \
+ error = urtw_write32_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_8187_write_phy_ofdm(sc, val, data) do { \
+ error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_8187_write_phy_cck(sc, val, data) do { \
+ error = urtw_8187_write_phy_cck_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_8225_write(sc, val, data) do { \
+ error = urtw_8225_write_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+
+struct urtw_pair {
+ uint32_t reg;
+ uint32_t val;
+};
+
+static uint8_t urtw_8225_agc[] = {
+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
+ 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
+ 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
+ 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
+ 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
+ 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
+ 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
+ 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
+ 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+static uint32_t urtw_8225_channel[] = {
+ 0x0000, /* dummy channel 0 */
+ 0x085c, /* 1 */
+ 0x08dc, /* 2 */
+ 0x095c, /* 3 */
+ 0x09dc, /* 4 */
+ 0x0a5c, /* 5 */
+ 0x0adc, /* 6 */
+ 0x0b5c, /* 7 */
+ 0x0bdc, /* 8 */
+ 0x0c5c, /* 9 */
+ 0x0cdc, /* 10 */
+ 0x0d5c, /* 11 */
+ 0x0ddc, /* 12 */
+ 0x0e5c, /* 13 */
+ 0x0f72, /* 14 */
+};
+
+static uint8_t urtw_8225_gain[] = {
+ 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
+ 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
+ 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
+ 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
+ 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
+ 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
+ 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
+};
+
+static struct urtw_pair urtw_8225_rf_part1[] = {
+ { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
+ { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
+ { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
+ { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
+};
+
+static struct urtw_pair urtw_8225_rf_part2[] = {
+ { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
+ { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
+ { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
+ { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
+ { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
+ { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
+ { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
+ { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
+ { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
+ { 0x27, 0x88 }
+};
+
+static struct urtw_pair urtw_8225_rf_part3[] = {
+ { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
+ { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
+ { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
+ { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
+ { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
+ { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
+ { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
+};
+
+static uint16_t urtw_8225_rxgain[] = {
+ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+ 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+ 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+ 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+ 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+ 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+ 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+ 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+ 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+ 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
+ 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
+};
+
+static uint8_t urtw_8225_threshold[] = {
+ 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
+};
+
+static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
+ 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
+};
+
+static uint8_t urtw_8225_txpwr_cck[] = {
+ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
+ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
+ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
+ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
+ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
+ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
+};
+
+static uint8_t urtw_8225_txpwr_cck_ch14[] = {
+ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
+ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
+};
+
+static uint8_t urtw_8225_txpwr_ofdm[]={
+ 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
+};
+
+static uint8_t urtw_8225v2_gain_bg[]={
+ 0x23, 0x15, 0xa5, /* -82-1dbm */
+ 0x23, 0x15, 0xb5, /* -82-2dbm */
+ 0x23, 0x15, 0xc5, /* -82-3dbm */
+ 0x33, 0x15, 0xc5, /* -78dbm */
+ 0x43, 0x15, 0xc5, /* -74dbm */
+ 0x53, 0x15, 0xc5, /* -70dbm */
+ 0x63, 0x15, 0xc5, /* -66dbm */
+};
+
+static struct urtw_pair urtw_8225v2_rf_part1[] = {
+ { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
+ { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
+ { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
+ { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
+};
+
+static struct urtw_pair urtw_8225v2_rf_part2[] = {
+ { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
+ { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
+ { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
+ { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
+ { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
+ { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
+ { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
+ { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
+ { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
+ { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
+};
+
+static struct urtw_pair urtw_8225v2_rf_part3[] = {
+ { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
+ { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
+ { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
+ { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
+ { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
+ { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
+ { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
+ { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
+};
+
+static uint16_t urtw_8225v2_rxgain[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
+ 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
+ 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
+ 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
+ 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
+ 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
+ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
+ 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
+ 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
+ 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
+ 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
+ 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
+};
+
+static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+};
+
+static uint8_t urtw_8225v2_txpwr_cck[] = {
+ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+};
+
+static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
+ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+};
+
+static struct urtw_pair urtw_ratetable[] = {
+ { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
+ { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
+ { 96, 10 }, { 108, 11 }
+};
+
+static struct ieee80211vap *urtw_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 urtw_vap_delete(struct ieee80211vap *);
+static void urtw_init(void *);
+static void urtw_stop(struct ifnet *, int);
+static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
+static void urtw_start(struct ifnet *);
+static int urtw_alloc_rx_data_list(struct urtw_softc *);
+static int urtw_alloc_tx_data_list(struct urtw_softc *);
+static void urtw_free_data_list(struct urtw_softc *,
+ usbd_pipe_handle, usbd_pipe_handle,
+ struct urtw_data data[], int);
+static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_bpf_params *);
+static void urtw_scan_start(struct ieee80211com *);
+static void urtw_scan_end(struct ieee80211com *);
+static void urtw_set_channel(struct ieee80211com *);
+static void urtw_update_mcast(struct ifnet *);
+static void urtw_rxeof(usbd_xfer_handle, usbd_private_handle,
+ usbd_status);
+static int urtw_tx_start(struct urtw_softc *,
+ struct ieee80211_node *, struct mbuf *, int);
+static void urtw_txeof_low(usbd_xfer_handle, usbd_private_handle,
+ usbd_status);
+static void urtw_txeof_normal(usbd_xfer_handle,
+ usbd_private_handle, usbd_status);
+static int urtw_newstate(struct ieee80211vap *,
+ enum ieee80211_state, int);
+static void urtw_ledtask(void *);
+static void urtw_ledusbtask(void *);
+static void urtw_ctxtask(void *);
+static void urtw_task(void *);
+static void urtw_watchdog(void *);
+static void urtw_set_multi(void *);
+static int urtw_isbmode(uint16_t);
+static uint16_t urtw_rate2rtl(int);
+static uint16_t urtw_rtl2rate(int);
+static usbd_status urtw_set_rate(struct urtw_softc *);
+static usbd_status urtw_update_msr(struct urtw_softc *);
+static usbd_status urtw_read8_c(struct urtw_softc *, int, uint8_t *);
+static usbd_status urtw_read16_c(struct urtw_softc *, int, uint16_t *);
+static usbd_status urtw_read32_c(struct urtw_softc *, int, uint32_t *);
+static usbd_status urtw_write8_c(struct urtw_softc *, int, uint8_t);
+static usbd_status urtw_write16_c(struct urtw_softc *, int, uint16_t);
+static usbd_status urtw_write32_c(struct urtw_softc *, int, uint32_t);
+static usbd_status urtw_eprom_cs(struct urtw_softc *, int);
+static usbd_status urtw_eprom_ck(struct urtw_softc *);
+static usbd_status urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
+ int);
+static usbd_status urtw_eprom_read32(struct urtw_softc *, uint32_t,
+ uint32_t *);
+static usbd_status urtw_eprom_readbit(struct urtw_softc *, int16_t *);
+static usbd_status urtw_eprom_writebit(struct urtw_softc *, int16_t);
+static usbd_status urtw_get_macaddr(struct urtw_softc *);
+static usbd_status urtw_get_txpwr(struct urtw_softc *);
+static usbd_status urtw_get_rfchip(struct urtw_softc *);
+static usbd_status urtw_led_init(struct urtw_softc *);
+static usbd_status urtw_8185_rf_pins_enable(struct urtw_softc *);
+static usbd_status urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
+static usbd_status urtw_8187_write_phy(struct urtw_softc *, uint8_t,
+ uint32_t);
+static usbd_status urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
+ uint8_t, uint32_t);
+static usbd_status urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
+ uint32_t);
+static usbd_status urtw_8225_setgain(struct urtw_softc *, int16_t);
+static usbd_status urtw_8225_usb_init(struct urtw_softc *);
+static usbd_status urtw_8225_write_c(struct urtw_softc *, uint8_t,
+ uint16_t);
+static usbd_status urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
+ uint16_t *);
+static usbd_status urtw_8225_read(struct urtw_softc *, uint8_t,
+ uint32_t *);
+static usbd_status urtw_8225_rf_init(struct urtw_softc *);
+static usbd_status urtw_8225_rf_set_chan(struct urtw_softc *, int);
+static usbd_status urtw_8225_rf_set_sens(struct urtw_softc *, int);
+static usbd_status urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
+static usbd_status urtw_8225v2_rf_init(struct urtw_softc *);
+static usbd_status urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
+static usbd_status urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
+static usbd_status urtw_8225v2_setgain(struct urtw_softc *, int16_t);
+static usbd_status urtw_8225_isv2(struct urtw_softc *, int *);
+static usbd_status urtw_read8e(struct urtw_softc *, int, uint8_t *);
+static usbd_status urtw_write8e(struct urtw_softc *, int, uint8_t);
+static usbd_status urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
+static usbd_status urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
+static usbd_status urtw_open_pipes(struct urtw_softc *);
+static usbd_status urtw_close_pipes(struct urtw_softc *);
+static usbd_status urtw_intr_enable(struct urtw_softc *);
+static usbd_status urtw_intr_disable(struct urtw_softc *);
+static usbd_status urtw_reset(struct urtw_softc *);
+static usbd_status urtw_led_on(struct urtw_softc *, int);
+static usbd_status urtw_led_ctl(struct urtw_softc *, int);
+static usbd_status urtw_led_blink(struct urtw_softc *);
+static usbd_status urtw_led_mode0(struct urtw_softc *, int);
+static usbd_status urtw_led_mode1(struct urtw_softc *, int);
+static usbd_status urtw_led_mode2(struct urtw_softc *, int);
+static usbd_status urtw_led_mode3(struct urtw_softc *, int);
+static usbd_status urtw_rx_setconf(struct urtw_softc *);
+static usbd_status urtw_rx_enable(struct urtw_softc *);
+static usbd_status urtw_tx_enable(struct urtw_softc *sc);
+
+static int
+urtw_match(device_t dev)
+{
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ const struct usb_devno *ud;
+
+ if (uaa->iface != NULL)
+ return UMATCH_NONE;
+ ud = usb_lookup(urtw_devs, uaa->vendor, uaa->product);
+
+ return (ud != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+}
+
+static int
+urtw_attach(device_t dev)
+{
+ int ret = 0;
+ struct urtw_softc *sc = device_get_softc(dev);
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ struct ieee80211com *ic;
+ struct ifnet *ifp;
+ uint8_t bands;
+ uint32_t data;
+ usbd_status error;
+
+ sc->sc_dev = dev;
+ sc->sc_udev = uaa->device;
+#ifdef URTW_DEBUG
+ sc->sc_debug = urtw_debug;
+#endif
+
+ mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
+ MTX_DEF);
+ callout_init(&sc->sc_led_ch, 0);
+ callout_init(&sc->sc_watchdog_ch, 0);
+ usb_init_task(&sc->sc_ledtask, urtw_ledusbtask, sc);
+ usb_init_task(&sc->sc_ctxtask, urtw_ctxtask, sc);
+ usb_init_task(&sc->sc_task, urtw_task, sc);
+
+ urtw_read32_m(sc, URTW_RX, &data);
+ sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
+ URTW_EEPROM_93C46;
+
+ error = urtw_get_rfchip(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_get_macaddr(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_get_txpwr(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_led_init(sc);
+ if (error != 0)
+ goto fail;
+
+ sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
+ sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
+ sc->sc_currate = 3;
+ sc->sc_preamble_mode = urtw_preamble_mode;
+
+ ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
+ if (ifp == NULL) {
+ device_printf(sc->sc_dev, "can not allocate ifnet\n");
+ ret = ENXIO;
+ goto fail;
+ }
+
+ ifp->if_softc = sc;
+ if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+ IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
+ ifp->if_init = urtw_init;
+ ifp->if_ioctl = urtw_ioctl;
+ ifp->if_start = urtw_start;
+ /* XXX URTW_TX_DATA_LIST_COUNT */
+ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+ IFQ_SET_READY(&ifp->if_snd);
+
+ ic = ifp->if_l2com;
+ ic->ic_ifp = ifp;
+ ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+ ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
+
+ /* set device capabilities */
+ ic->ic_caps =
+ IEEE80211_C_STA | /* station mode */
+ IEEE80211_C_MONITOR | /* monitor mode supported */
+ IEEE80211_C_TXPMGT | /* tx power management */
+ IEEE80211_C_SHPREAMBLE | /* short preamble supported */
+ IEEE80211_C_SHSLOT | /* short slot time supported */
+ IEEE80211_C_BGSCAN | /* capable of bg scanning */
+ IEEE80211_C_WPA; /* 802.11i */
+
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
+
+ bands = 0;
+ setbit(&bands, IEEE80211_MODE_11B);
+ setbit(&bands, IEEE80211_MODE_11G);
+ ieee80211_init_channels(ic, NULL, &bands);
+
+ ieee80211_ifattach(ic);
+ ic->ic_raw_xmit = urtw_raw_xmit;
+ ic->ic_scan_start = urtw_scan_start;
+ ic->ic_scan_end = urtw_scan_end;
+ ic->ic_set_channel = urtw_set_channel;
+
+ ic->ic_vap_create = urtw_vap_create;
+ ic->ic_vap_delete = urtw_vap_delete;
+ ic->ic_update_mcast = urtw_update_mcast;
+
+ bpfattach(ifp, DLT_IEEE802_11_RADIO,
+ sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
+
+ sc->sc_rxtap_len = sizeof sc->sc_rxtap;
+ sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
+ sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT);
+
+ sc->sc_txtap_len = sizeof sc->sc_txtap;
+ sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
+ sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT);
+
+ if (bootverbose)
+ ieee80211_announce(ic);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
+fail:
+ return (ret);
+}
+
+static usbd_status
+urtw_open_pipes(struct urtw_softc *sc)
+{
+ usbd_status error;
+
+ /*
+ * NB: there is no way to distinguish each pipes so we need to hardcode
+ * pipe numbers
+ */
+
+ /* tx pipe - low priority packets */
+ error = usbd_open_pipe(sc->sc_iface, 0x2, USBD_EXCLUSIVE_USE,
+ &sc->sc_txpipe_low);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not open Tx low pipe: %s\n",
+ usbd_errstr(error));
+ goto fail;
+ }
+ /* tx pipe - normal priority packets */
+ error = usbd_open_pipe(sc->sc_iface, 0x3, USBD_EXCLUSIVE_USE,
+ &sc->sc_txpipe_normal);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not open Tx normal pipe: %s\n",
+ usbd_errstr(error));
+ goto fail;
+ }
+ /* rx pipe */
+ error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
+ &sc->sc_rxpipe);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not open Rx pipe: %s\n",
+ usbd_errstr(error));
+ goto fail;
+ }
+
+ return (0);
+fail:
+ (void)urtw_close_pipes(sc);
+ return (error);
+}
+
+static usbd_status
+urtw_close_pipes(struct urtw_softc *sc)
+{
+ usbd_status error = 0;
+
+ if (sc->sc_rxpipe != NULL) {
+ error = usbd_close_pipe(sc->sc_rxpipe);
+ if (error != 0)
+ goto fail;
+ sc->sc_rxpipe = NULL;
+ }
+ if (sc->sc_txpipe_low != NULL) {
+ error = usbd_close_pipe(sc->sc_txpipe_low);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpipe_low = NULL;
+ }
+ if (sc->sc_txpipe_normal != NULL) {
+ error = usbd_close_pipe(sc->sc_txpipe_normal);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpipe_normal = NULL;
+ }
+fail:
+ return (error);
+}
+
+static int
+urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
+ int ndata, int maxsz, int fillmbuf)
+{
+ int i, error;
+
+ for (i = 0; i < ndata; i++) {
+ struct urtw_data *dp = &data[i];
+
+ dp->sc = sc;
+ dp->xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (dp->xfer == NULL) {
+ device_printf(sc->sc_dev, "could not allocate xfer\n");
+ error = ENOMEM;
+ goto fail;
+ }
+ if (fillmbuf) {
+ dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (dp->m == NULL) {
+ device_printf(sc->sc_dev,
+ "could not allocate rx mbuf\n");
+ error = ENOMEM;
+ goto fail;
+ }
+ dp->buf = mtod(dp->m, uint8_t *);
+ } else {
+ dp->m = NULL;
+ dp->buf = usbd_alloc_buffer(dp->xfer, maxsz);
+ if (dp->buf == NULL) {
+ device_printf(sc->sc_dev,
+ "could not allocate buffer\n");
+ error = ENOMEM;
+ goto fail;
+ }
+ if (((unsigned long)dp->buf) % 4)
+ device_printf(sc->sc_dev,
+ "warn: unaligned buffer %p\n", dp->buf);
+ }
+ dp->ni = NULL;
+ }
+
+ return 0;
+
+fail: urtw_free_data_list(sc, NULL, NULL, data, ndata);
+ return error;
+}
+
+static void
+urtw_free_data_list(struct urtw_softc *sc, usbd_pipe_handle pipe1,
+ usbd_pipe_handle pipe2, struct urtw_data data[], int ndata)
+{
+ int i;
+
+ /* make sure no transfers are pending */
+ if (pipe1 != NULL)
+ usbd_abort_pipe(pipe1);
+ if (pipe2 != NULL)
+ usbd_abort_pipe(pipe2);
+
+ for (i = 0; i < ndata; i++) {
+ struct urtw_data *dp = &data[i];
+
+ if (dp->xfer != NULL) {
+ usbd_free_xfer(dp->xfer);
+ dp->xfer = NULL;
+ }
+ if (dp->m != NULL) {
+ m_freem(dp->m);
+ dp->m = NULL;
+ }
+ if (dp->ni != NULL) {
+ ieee80211_free_node(dp->ni);
+ dp->ni = NULL;
+ }
+ }
+}
+
+static int
+urtw_alloc_rx_data_list(struct urtw_softc *sc)
+{
+
+ return urtw_alloc_data_list(sc,
+ sc->sc_rxdata, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
+}
+
+static void
+urtw_free_rx_data_list(struct urtw_softc *sc)
+{
+
+ urtw_free_data_list(sc, sc->sc_rxpipe, NULL, sc->sc_rxdata,
+ URTW_RX_DATA_LIST_COUNT);
+}
+
+static int
+urtw_alloc_tx_data_list(struct urtw_softc *sc)
+{
+
+ return urtw_alloc_data_list(sc,
+ sc->sc_txdata, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
+ 0 /* no mbufs */);
+}
+
+static void
+urtw_free_tx_data_list(struct urtw_softc *sc)
+{
+
+ urtw_free_data_list(sc, sc->sc_txpipe_low, sc->sc_txpipe_normal,
+ sc->sc_txdata, URTW_TX_DATA_LIST_COUNT);
+}
+
+static usbd_status
+urtw_led_init(struct urtw_softc *sc)
+{
+ uint32_t rev;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
+ error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
+ if (error != 0)
+ goto fail;
+
+ switch (rev & URTW_EPROM_CID_MASK) {
+ case URTW_EPROM_CID_ALPHA0:
+ sc->sc_strategy = URTW_SW_LED_MODE1;
+ break;
+ case URTW_EPROM_CID_SERCOMM_PS:
+ sc->sc_strategy = URTW_SW_LED_MODE3;
+ break;
+ case URTW_EPROM_CID_HW_LED:
+ sc->sc_strategy = URTW_HW_LED;
+ break;
+ case URTW_EPROM_CID_RSVD0:
+ case URTW_EPROM_CID_RSVD1:
+ default:
+ sc->sc_strategy = URTW_SW_LED_MODE0;
+ break;
+ }
+
+ sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
+
+fail:
+ return (error);
+}
+
+/* XXX why we should allocalte memory buffer instead of using memory stack? */
+static usbd_status
+urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
+ uint16_t *data)
+{
+ uint8_t *buf;
+ uint16_t data16;
+ usb_device_request_t *req;
+ usbd_status error = 0;
+
+ data16 = *data;
+ req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (req == NULL) {
+ device_printf(sc->sc_dev, "could not allocate a memory\n");
+ goto fail0;
+ }
+ buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (req == NULL) {
+ device_printf(sc->sc_dev, "could not allocate a memory\n");
+ goto fail1;
+ }
+
+ req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req->bRequest = URTW_8187_SETREGS_REQ;
+ USETW(req->wValue, addr);
+ USETW(req->wIndex, index);
+ USETW(req->wLength, sizeof(uint16_t));
+ buf[0] = (data16 & 0x00ff);
+ buf[1] = (data16 & 0xff00) >> 8;
+
+ error = usbd_do_request(sc->sc_udev, req, buf);
+
+ free(buf, M_80211_VAP);
+fail1: free(req, M_80211_VAP);
+fail0: return (error);
+}
+
+static usbd_status
+urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
+{
+ int i;
+ int16_t bit;
+ uint8_t rlen = 12, wlen = 6;
+ uint16_t o1, o2, o3, tmp;
+ uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
+ uint32_t mask = 0x80000000, value = 0;
+ usbd_status error;
+
+ urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
+ urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
+ urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
+ o1 &= ~URTW_RF_PINS_MAGIC4;
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
+ DELAY(5);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
+ DELAY(5);
+
+ for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
+ bit = ((d2w & mask) != 0) ? 1 : 0;
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ mask = mask >> 1;
+ if (i == 2)
+ break;
+ bit = ((d2w & mask) != 0) ? 1 : 0;
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
+ DELAY(1);
+ }
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
+ DELAY(2);
+
+ mask = 0x800;
+ for (i = 0; i < rlen; i++, mask = mask >> 1) {
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
+ o1 | URTW_BB_HOST_BANG_RW);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
+ o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
+ o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
+ o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+
+ urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
+ value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
+ o1 | URTW_BB_HOST_BANG_RW);
+ DELAY(2);
+ }
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
+ URTW_BB_HOST_BANG_RW);
+ DELAY(2);
+
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
+
+ if (data != NULL)
+ *data = value;
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
+{
+ uint16_t d80, d82, d84;
+ usbd_status error;
+
+ urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
+ d80 &= URTW_RF_PINS_MAGIC1;
+ urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
+ urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
+ d84 &= URTW_RF_PINS_MAGIC2;
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
+ DELAY(10);
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
+ DELAY(10);
+
+ error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
+ if (error != 0)
+ goto fail;
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
+ DELAY(10);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
+ usbd_delay_ms(sc->sc_udev, 2);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225_isv2(struct urtw_softc *sc, int *ret)
+{
+ uint32_t data;
+ usbd_status error;
+
+ *ret = 1;
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
+ usbd_delay_ms(sc->sc_udev, 500);
+
+ urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
+ URTW_8225_ADDR_0_DATA_MAGIC1);
+
+ error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
+ if (error != 0)
+ goto fail;
+ if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
+ *ret = 0;
+ else {
+ error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
+ if (error != 0)
+ goto fail;
+ if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
+ *ret = 0;
+ }
+
+ urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
+ URTW_8225_ADDR_0_DATA_MAGIC2);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_get_rfchip(struct urtw_softc *sc)
+{
+ int ret;
+ uint32_t data;
+ usbd_status error;
+
+ error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
+ if (error != 0)
+ goto fail;
+ switch (data & 0xff) {
+ case URTW_EPROM_RFCHIPID_RTL8225U:
+ error = urtw_8225_isv2(sc, &ret);
+ if (error != 0)
+ goto fail;
+ if (ret == 0) {
+ sc->sc_rf_init = urtw_8225_rf_init;
+ sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
+ sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
+ } else {
+ sc->sc_rf_init = urtw_8225v2_rf_init;
+ sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
+ }
+ sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
+ sc->sc_sens = URTW_8225_RF_DEF_SENS;
+ break;
+ default:
+ panic("unsupported RF chip %d\n", data & 0xff);
+ /* never reach */
+ }
+
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_get_txpwr(struct urtw_softc *sc)
+{
+ int i, j;
+ uint32_t data;
+ usbd_status error;
+
+ error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpwr_cck_base = data & 0xf;
+ sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
+
+ for (i = 1, j = 0; i < 6; i += 2, j++) {
+ error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpwr_cck[i] = data & 0xf;
+ sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
+ sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
+ sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
+ }
+ for (i = 1, j = 0; i < 4; i += 2, j++) {
+ error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpwr_cck[i + 6] = data & 0xf;
+ sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
+ sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
+ sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
+ }
+ for (i = 1, j = 0; i < 4; i += 2, j++) {
+ error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
+ sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
+ sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
+ sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
+ }
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_get_macaddr(struct urtw_softc *sc)
+{
+ uint32_t data;
+ usbd_status error;
+
+ error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_bssid[0] = data & 0xff;
+ sc->sc_bssid[1] = (data & 0xff00) >> 8;
+ error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_bssid[2] = data & 0xff;
+ sc->sc_bssid[3] = (data & 0xff00) >> 8;
+ error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
+ if (error != 0)
+ goto fail;
+ sc->sc_bssid[4] = data & 0xff;
+ sc->sc_bssid[5] = (data & 0xff00) >> 8;
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
+{
+#define URTW_READCMD_LEN 3
+ int addrlen, i;
+ int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
+ usbd_status error;
+
+ /* NB: make sure the buffer is initialized */
+ *data = 0;
+
+ /* enable EPROM programming */
+ urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
+ DELAY(URTW_EPROM_DELAY);
+
+ error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
+ if (error != 0)
+ goto fail;
+ error = urtw_eprom_ck(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
+ if (error != 0)
+ goto fail;
+ if (sc->sc_epromtype == URTW_EEPROM_93C56) {
+ addrlen = 8;
+ addrstr[0] = addr & (1 << 7);
+ addrstr[1] = addr & (1 << 6);
+ addrstr[2] = addr & (1 << 5);
+ addrstr[3] = addr & (1 << 4);
+ addrstr[4] = addr & (1 << 3);
+ addrstr[5] = addr & (1 << 2);
+ addrstr[6] = addr & (1 << 1);
+ addrstr[7] = addr & (1 << 0);
+ } else {
+ addrlen=6;
+ addrstr[0] = addr & (1 << 5);
+ addrstr[1] = addr & (1 << 4);
+ addrstr[2] = addr & (1 << 3);
+ addrstr[3] = addr & (1 << 2);
+ addrstr[4] = addr & (1 << 1);
+ addrstr[5] = addr & (1 << 0);
+ }
+ error = urtw_eprom_sendbits(sc, addrstr, addrlen);
+ if (error != 0)
+ goto fail;
+
+ error = urtw_eprom_writebit(sc, 0);
+ if (error != 0)
+ goto fail;
+
+ for (i = 0; i < 16; i++) {
+ error = urtw_eprom_ck(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_eprom_readbit(sc, &data16);
+ if (error != 0)
+ goto fail;
+
+ (*data) |= (data16 << (15 - i));
+ }
+
+ error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
+ if (error != 0)
+ goto fail;
+ error = urtw_eprom_ck(sc);
+ if (error != 0)
+ goto fail;
+
+ /* now disable EPROM programming */
+ urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
+fail:
+ return (error);
+#undef URTW_READCMD_LEN
+}
+
+static usbd_status
+urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
+{
+ uint8_t data8;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
+ *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
+ DELAY(URTW_EPROM_DELAY);
+
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
+{
+ int i = 0;
+ usbd_status error = 0;
+
+ for (i = 0; i < buflen; i++) {
+ error = urtw_eprom_writebit(sc, buf[i]);
+ if (error != 0)
+ goto fail;
+ error = urtw_eprom_ck(sc);
+ if (error != 0)
+ goto fail;
+ }
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
+{
+ uint8_t data;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_EPROM_CMD, &data);
+ if (bit != 0)
+ urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
+ else
+ urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
+ DELAY(URTW_EPROM_DELAY);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_eprom_ck(struct urtw_softc *sc)
+{
+ uint8_t data;
+ usbd_status error;
+
+ /* masking */
+ urtw_read8_m(sc, URTW_EPROM_CMD, &data);
+ urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
+ DELAY(URTW_EPROM_DELAY);
+ /* unmasking */
+ urtw_read8_m(sc, URTW_EPROM_CMD, &data);
+ urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
+ DELAY(URTW_EPROM_DELAY);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_eprom_cs(struct urtw_softc *sc, int able)
+{
+ uint8_t data;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_EPROM_CMD, &data);
+ if (able == URTW_EPROM_ENABLE)
+ urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
+ else
+ urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
+ DELAY(URTW_EPROM_DELAY);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
+{
+ usb_device_request_t req;
+ usbd_status error;
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_GETREGS_REQ;
+ USETW(req.wValue, val | 0xff00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint8_t));
+
+ error = usbd_do_request(sc->sc_udev, &req, data);
+ return (error);
+}
+
+static usbd_status
+urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
+{
+ usb_device_request_t req;
+ usbd_status error;
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_GETREGS_REQ;
+ USETW(req.wValue, val | 0xfe00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint8_t));
+
+ error = usbd_do_request(sc->sc_udev, &req, data);
+ return (error);
+}
+
+static usbd_status
+urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
+{
+ usb_device_request_t req;
+ usbd_status error;
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_GETREGS_REQ;
+ USETW(req.wValue, val | 0xff00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint16_t));
+
+ error = usbd_do_request(sc->sc_udev, &req, data);
+ return (error);
+}
+
+static usbd_status
+urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
+{
+ usb_device_request_t req;
+ usbd_status error;
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_GETREGS_REQ;
+ USETW(req.wValue, val | 0xff00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint32_t));
+
+ error = usbd_do_request(sc->sc_udev, &req, data);
+ return (error);
+}
+
+static usbd_status
+urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_SETREGS_REQ;
+ USETW(req.wValue, val | 0xff00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint8_t));
+
+ return (usbd_do_request(sc->sc_udev, &req, &data));
+}
+
+static usbd_status
+urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_SETREGS_REQ;
+ USETW(req.wValue, val | 0xfe00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint8_t));
+
+ return (usbd_do_request(sc->sc_udev, &req, &data));
+}
+
+static usbd_status
+urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_SETREGS_REQ;
+ USETW(req.wValue, val | 0xff00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint16_t));
+
+ return (usbd_do_request(sc->sc_udev, &req, &data));
+}
+
+static usbd_status
+urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = URTW_8187_SETREGS_REQ;
+ USETW(req.wValue, val | 0xff00);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, sizeof(uint32_t));
+
+ return (usbd_do_request(sc->sc_udev, &req, &data));
+}
+
+static int
+urtw_detach(device_t dev)
+{
+ struct urtw_softc *sc = device_get_softc(dev);
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ if (!device_is_attached(dev))
+ return 0;
+
+ urtw_stop(ifp, 1);
+
+ callout_drain(&sc->sc_led_ch);
+ callout_drain(&sc->sc_watchdog_ch);
+ usb_rem_task(sc->sc_udev, &sc->sc_ledtask);
+ usb_rem_task(sc->sc_udev, &sc->sc_ctxtask);
+ usb_rem_task(sc->sc_udev, &sc->sc_task);
+
+ /* abort and free xfers */
+ urtw_free_tx_data_list(sc);
+ urtw_free_rx_data_list(sc);
+ urtw_close_pipes(sc);
+
+ bpfdetach(ifp);
+ ieee80211_ifdetach(ic);
+ if_free(ifp);
+ mtx_destroy(&sc->sc_mtx);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
+
+ return (0);
+}
+
+static struct ieee80211vap *
+urtw_vap_create(struct ieee80211com *ic,
+ const char name[IFNAMSIZ], int unit, int opmode, int flags,
+ const uint8_t bssid[IEEE80211_ADDR_LEN],
+ const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+ struct urtw_vap *uvp;
+ struct ieee80211vap *vap;
+
+ if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
+ return (NULL);
+ uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (uvp == NULL)
+ return (NULL);
+ vap = &uvp->vap;
+ /* enable s/w bmiss handling for sta mode */
+ ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ /* override state transition machine */
+ uvp->newstate = vap->iv_newstate;
+ vap->iv_newstate = urtw_newstate;
+
+ /* complete setup */
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status);
+ ic->ic_opmode = opmode;
+ return (vap);
+}
+
+static void
+urtw_vap_delete(struct ieee80211vap *vap)
+{
+ struct urtw_vap *uvp = URTW_VAP(vap);
+
+ ieee80211_vap_detach(vap);
+ free(uvp, M_80211_VAP);
+}
+
+static usbd_status
+urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
+{
+ uint8_t data;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_EPROM_CMD, &data);
+ data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
+ data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
+ urtw_write8_m(sc, URTW_EPROM_CMD, data);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
+{
+ uint8_t data;
+ usbd_status error;
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
+ if (error)
+ goto fail;
+
+ urtw_read8_m(sc, URTW_CONFIG3, &data);
+ urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
+ urtw_write32_m(sc, URTW_ANAPARAM, val);
+ urtw_read8_m(sc, URTW_CONFIG3, &data);
+ urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
+ if (error)
+ goto fail;
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
+{
+ uint8_t data;
+ usbd_status error;
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
+ if (error)
+ goto fail;
+
+ urtw_read8_m(sc, URTW_CONFIG3, &data);
+ urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
+ urtw_write32_m(sc, URTW_ANAPARAM2, val);
+ urtw_read8_m(sc, URTW_CONFIG3, &data);
+ urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
+ if (error)
+ goto fail;
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_intr_disable(struct urtw_softc *sc)
+{
+ usbd_status error;
+
+ urtw_write16_m(sc, URTW_INTR_MASK, 0);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_reset(struct urtw_softc *sc)
+{
+ uint8_t data;
+ usbd_status error;
+
+ error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
+ if (error)
+ goto fail;
+ error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
+ if (error)
+ goto fail;
+
+ error = urtw_intr_disable(sc);
+ if (error)
+ goto fail;
+ usbd_delay_ms(sc->sc_udev, 100);
+
+ error = urtw_write8e(sc, 0x18, 0x10);
+ if (error != 0)
+ goto fail;
+ error = urtw_write8e(sc, 0x18, 0x11);
+ if (error != 0)
+ goto fail;
+ error = urtw_write8e(sc, 0x18, 0x00);
+ if (error != 0)
+ goto fail;
+ usbd_delay_ms(sc->sc_udev, 100);
+
+ urtw_read8_m(sc, URTW_CMD, &data);
+ data = (data & 0x2) | URTW_CMD_RST;
+ urtw_write8_m(sc, URTW_CMD, data);
+ usbd_delay_ms(sc->sc_udev, 100);
+
+ urtw_read8_m(sc, URTW_CMD, &data);
+ if (data & URTW_CMD_RST) {
+ device_printf(sc->sc_dev, "reset timeout\n");
+ goto fail;
+ }
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
+ if (error)
+ goto fail;
+ usbd_delay_ms(sc->sc_udev, 100);
+
+ error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
+ if (error)
+ goto fail;
+ error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
+ if (error)
+ goto fail;
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_led_on(struct urtw_softc *sc, int type)
+{
+ usbd_status error;
+
+ if (type == URTW_LED_GPIO) {
+ switch (sc->sc_gpio_ledpin) {
+ case URTW_LED_PIN_GPIO0:
+ urtw_write8_m(sc, URTW_GPIO, 0x01);
+ urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
+ break;
+ default:
+ panic("unsupported LED PIN type 0x%x",
+ sc->sc_gpio_ledpin);
+ /* never reach */
+ }
+ } else {
+ panic("unsupported LED type 0x%x", type);
+ /* never reach */
+ }
+
+ sc->sc_gpio_ledon = 1;
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_led_off(struct urtw_softc *sc, int type)
+{
+ usbd_status error;
+
+ if (type == URTW_LED_GPIO) {
+ switch (sc->sc_gpio_ledpin) {
+ case URTW_LED_PIN_GPIO0:
+ urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
+ urtw_write8_m(sc,
+ URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
+ break;
+ default:
+ panic("unsupported LED PIN type 0x%x",
+ sc->sc_gpio_ledpin);
+ /* never reach */
+ }
+ } else {
+ panic("unsupported LED type 0x%x", type);
+ /* never reach */
+ }
+
+ sc->sc_gpio_ledon = 0;
+
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_led_mode0(struct urtw_softc *sc, int mode)
+{
+
+ switch (mode) {
+ case URTW_LED_CTL_POWER_ON:
+ sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
+ break;
+ case URTW_LED_CTL_TX:
+ if (sc->sc_gpio_ledinprogress == 1)
+ return (0);
+
+ sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
+ sc->sc_gpio_blinktime = 2;
+ break;
+ case URTW_LED_CTL_LINK:
+ sc->sc_gpio_ledstate = URTW_LED_ON;
+ break;
+ default:
+ panic("unsupported LED mode 0x%x", mode);
+ /* never reach */
+ }
+
+ switch (sc->sc_gpio_ledstate) {
+ case URTW_LED_ON:
+ if (sc->sc_gpio_ledinprogress != 0)
+ break;
+ urtw_led_on(sc, URTW_LED_GPIO);
+ break;
+ case URTW_LED_BLINK_NORMAL:
+ if (sc->sc_gpio_ledinprogress != 0)
+ break;
+ sc->sc_gpio_ledinprogress = 1;
+ sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
+ URTW_LED_OFF : URTW_LED_ON;
+ callout_reset(&sc->sc_led_ch, hz, urtw_ledtask, sc);
+ break;
+ case URTW_LED_POWER_ON_BLINK:
+ urtw_led_on(sc, URTW_LED_GPIO);
+ usbd_delay_ms(sc->sc_udev, 100);
+ urtw_led_off(sc, URTW_LED_GPIO);
+ break;
+ default:
+ panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
+ /* never reach */
+ }
+ return (0);
+}
+
+static usbd_status
+urtw_led_mode1(struct urtw_softc *sc, int mode)
+{
+
+ return (USBD_INVAL);
+}
+
+static usbd_status
+urtw_led_mode2(struct urtw_softc *sc, int mode)
+{
+
+ return (USBD_INVAL);
+}
+
+static usbd_status
+urtw_led_mode3(struct urtw_softc *sc, int mode)
+{
+
+ return (USBD_INVAL);
+}
+
+static usbd_status
+urtw_led_blink(struct urtw_softc *sc)
+{
+ uint8_t ing = 0;
+ usbd_status error;
+
+ if (sc->sc_gpio_blinkstate == URTW_LED_ON)
+ error = urtw_led_on(sc, URTW_LED_GPIO);
+ else
+ error = urtw_led_off(sc, URTW_LED_GPIO);
+ sc->sc_gpio_blinktime--;
+ if (sc->sc_gpio_blinktime == 0)
+ ing = 1;
+ else {
+ if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
+ sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
+ sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
+ ing = 1;
+ }
+ if (ing == 1) {
+ if (sc->sc_gpio_ledstate == URTW_LED_ON &&
+ sc->sc_gpio_ledon == 0)
+ error = urtw_led_on(sc, URTW_LED_GPIO);
+ else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
+ sc->sc_gpio_ledon == 1)
+ error = urtw_led_off(sc, URTW_LED_GPIO);
+
+ sc->sc_gpio_blinktime = 0;
+ sc->sc_gpio_ledinprogress = 0;
+ return (0);
+ }
+
+ sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
+ URTW_LED_ON : URTW_LED_OFF;
+
+ switch (sc->sc_gpio_ledstate) {
+ case URTW_LED_BLINK_NORMAL:
+ callout_reset(&sc->sc_led_ch, hz, urtw_ledtask, sc);
+ break;
+ default:
+ panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
+ /* never reach */
+ }
+ return (0);
+}
+
+static void
+urtw_ledusbtask(void *arg)
+{
+ struct urtw_softc *sc = arg;
+
+ if (sc->sc_strategy != URTW_SW_LED_MODE0)
+ panic("could not process a LED strategy 0x%x", sc->sc_strategy);
+
+ urtw_led_blink(sc);
+}
+
+static void
+urtw_ledtask(void *arg)
+{
+ struct urtw_softc *sc = arg;
+
+ /*
+ * NB: to change a status of the led we need at least a sleep so we
+ * can't do it here
+ */
+ usb_add_task(sc->sc_udev, &sc->sc_ledtask, USB_TASKQ_DRIVER);
+}
+
+static usbd_status
+urtw_led_ctl(struct urtw_softc *sc, int mode)
+{
+ usbd_status error = 0;
+
+ switch (sc->sc_strategy) {
+ case URTW_SW_LED_MODE0:
+ error = urtw_led_mode0(sc, mode);
+ break;
+ case URTW_SW_LED_MODE1:
+ error = urtw_led_mode1(sc, mode);
+ break;
+ case URTW_SW_LED_MODE2:
+ error = urtw_led_mode2(sc, mode);
+ break;
+ case URTW_SW_LED_MODE3:
+ error = urtw_led_mode3(sc, mode);
+ break;
+ default:
+ panic("unsupported LED mode %d\n", sc->sc_strategy);
+ /* never reach */
+ }
+
+ return (error);
+}
+
+static usbd_status
+urtw_update_msr(struct urtw_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ uint8_t data;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_MSR, &data);
+ data &= ~URTW_MSR_LINK_MASK;
+
+ if (sc->sc_state == IEEE80211_S_RUN) {
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_STA:
+ case IEEE80211_M_MONITOR:
+ data |= URTW_MSR_LINK_STA;
+ break;
+ case IEEE80211_M_IBSS:
+ data |= URTW_MSR_LINK_ADHOC;
+ break;
+ case IEEE80211_M_HOSTAP:
+ data |= URTW_MSR_LINK_HOSTAP;
+ break;
+ default:
+ panic("unsupported operation mode 0x%x\n",
+ ic->ic_opmode);
+ /* never reach */
+ }
+ } else
+ data |= URTW_MSR_LINK_NONE;
+
+ urtw_write8_m(sc, URTW_MSR, data);
+fail:
+ return (error);
+}
+
+static uint16_t
+urtw_rate2rtl(int rate)
+{
+#define N(a) (sizeof(a) / sizeof((a)[0]))
+ int i;
+
+ for (i = 0; i < N(urtw_ratetable); i++) {
+ if (rate == urtw_ratetable[i].reg)
+ return urtw_ratetable[i].val;
+ }
+
+ return (3);
+#undef N
+}
+
+static uint16_t
+urtw_rtl2rate(int rate)
+{
+#define N(a) (sizeof(a) / sizeof((a)[0]))
+ int i;
+
+ for (i = 0; i < N(urtw_ratetable); i++) {
+ if (rate == urtw_ratetable[i].val)
+ return urtw_ratetable[i].reg;
+ }
+
+ return (0);
+#undef N
+}
+
+static usbd_status
+urtw_set_rate(struct urtw_softc *sc)
+{
+ int i, basic_rate, min_rr_rate, max_rr_rate;
+ uint16_t data;
+ usbd_status error;
+
+ basic_rate = urtw_rate2rtl(48);
+ min_rr_rate = urtw_rate2rtl(12);
+ max_rr_rate = urtw_rate2rtl(48);
+
+ urtw_write8_m(sc, URTW_RESP_RATE,
+ max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
+ min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
+
+ urtw_read16_m(sc, URTW_BRSR, &data);
+ data &= ~URTW_BRSR_MBR_8185;
+
+ for (i = 0; i <= basic_rate; i++)
+ data |= (1 << i);
+
+ urtw_write16_m(sc, URTW_BRSR, data);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_intr_enable(struct urtw_softc *sc)
+{
+ usbd_status error;
+
+ urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_adapter_start(struct urtw_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ usbd_status error;
+
+ error = urtw_reset(sc);
+ if (error)
+ goto fail;
+
+ urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
+ urtw_write8_m(sc, URTW_GPIO, 0);
+
+ /* for led */
+ urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
+ error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
+ if (error != 0)
+ goto fail;
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
+ if (error)
+ goto fail;
+ /* applying MAC address again. */
+ urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_myaddr)[0]);
+ urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_myaddr)[1] & 0xffff);
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
+ if (error)
+ goto fail;
+
+ error = urtw_update_msr(sc);
+ if (error)
+ goto fail;
+
+ urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
+ urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
+ urtw_write8_m(sc, URTW_RATE_FALLBACK, 0x81);
+ error = urtw_set_rate(sc);
+ if (error != 0)
+ goto fail;
+
+ error = sc->sc_rf_init(sc);
+ if (error != 0)
+ goto fail;
+ if (sc->sc_rf_set_sens != NULL)
+ sc->sc_rf_set_sens(sc, sc->sc_sens);
+
+ /* XXX correct? to call write16 */
+ urtw_write16_m(sc, URTW_PSR, 1);
+ urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
+ urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
+ urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
+ /* XXX correct? to call write16 */
+ urtw_write16_m(sc, URTW_PSR, 0);
+ urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
+
+ error = urtw_intr_enable(sc);
+ if (error != 0)
+ goto fail;
+
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_rx_setconf(struct urtw_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ uint32_t data;
+ usbd_status error;
+
+ urtw_read32_m(sc, URTW_RX, &data);
+ data = data &~ URTW_RX_FILTER_MASK;
+#if 0
+ data = data | URTW_RX_FILTER_CTL;
+#endif
+ data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
+ data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
+
+ if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+ data = data | URTW_RX_FILTER_ICVERR;
+ data = data | URTW_RX_FILTER_PWR;
+ }
+ if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
+ data = data | URTW_RX_FILTER_CRCERR;
+
+ if (ic->ic_opmode == IEEE80211_M_MONITOR ||
+ (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
+ data = data | URTW_RX_FILTER_ALLMAC;
+ } else {
+ data = data | URTW_RX_FILTER_NICMAC;
+ data = data | URTW_RX_CHECK_BSSID;
+ }
+
+ data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
+ data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
+ data = data &~ URTW_MAX_RX_DMA_MASK;
+ data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
+
+ urtw_write32_m(sc, URTW_RX, data);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_rx_enable(struct urtw_softc *sc)
+{
+ int i;
+ struct urtw_data *rxdata;
+ uint8_t data;
+ usbd_status error;
+
+ /*
+ * Start up the receive pipe.
+ */
+ for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
+ rxdata = &sc->sc_rxdata[i];
+
+ usbd_setup_xfer(rxdata->xfer, sc->sc_rxpipe, rxdata,
+ rxdata->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
+ urtw_rxeof);
+ error = usbd_transfer(rxdata->xfer);
+ if (error != USBD_IN_PROGRESS && error != 0) {
+ device_printf(sc->sc_dev,
+ "could not queue Rx transfer\n");
+ goto fail;
+ }
+ }
+
+ error = urtw_rx_setconf(sc);
+ if (error != 0)
+ goto fail;
+
+ urtw_read8_m(sc, URTW_CMD, &data);
+ urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_tx_enable(struct urtw_softc *sc)
+{
+ uint8_t data8;
+ uint32_t data;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_CW_CONF, &data8);
+ data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
+ urtw_write8_m(sc, URTW_CW_CONF, data8);
+
+ urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
+ data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
+ data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
+ data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
+ urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
+
+ urtw_read32_m(sc, URTW_TX_CONF, &data);
+ data &= ~URTW_TX_LOOPBACK_MASK;
+ data |= URTW_TX_LOOPBACK_NONE;
+ data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
+ data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
+ data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
+ data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
+ data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
+ data &= ~URTW_TX_SWPLCPLEN;
+ data |= URTW_TX_NOICV;
+ urtw_write32_m(sc, URTW_TX_CONF, data);
+
+ urtw_read8_m(sc, URTW_CMD, &data8);
+ urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
+fail:
+ return (error);
+}
+
+static void
+urtw_init(void *arg)
+{
+ int ret;
+ struct urtw_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+ usbd_status error;
+
+ urtw_stop(ifp, 0);
+
+ error = urtw_adapter_start(sc);
+ if (error != 0)
+ goto fail;
+
+ /* reset softc variables */
+ sc->sc_txidx = sc->sc_tx_low_queued = sc->sc_tx_normal_queued = 0;
+ sc->sc_txtimer = 0;
+
+ if (!(sc->sc_flags & URTW_INIT_ONCE)) {
+ error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "could not set configuration no\n");
+ goto fail;
+ }
+ /* get the first interface handle */
+ error = usbd_device2interface_handle(sc->sc_udev,
+ URTW_IFACE_INDEX, &sc->sc_iface);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "could not get interface handle\n");
+ goto fail;
+ }
+ error = urtw_open_pipes(sc);
+ if (error != 0)
+ goto fail;
+ ret = urtw_alloc_rx_data_list(sc);
+ if (error != 0)
+ goto fail;
+ ret = urtw_alloc_tx_data_list(sc);
+ if (error != 0)
+ goto fail;
+ sc->sc_flags |= URTW_INIT_ONCE;
+ }
+
+ error = urtw_rx_enable(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_tx_enable(sc);
+ if (error != 0)
+ goto fail;
+
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
+ callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
+fail:
+ return;
+}
+
+static void
+urtw_set_multi(void *arg)
+{
+ struct urtw_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+
+ if (!(ifp->if_flags & IFF_UP))
+ return;
+
+ /*
+ * XXX don't know how to set a device. Lack of docs. Just try to set
+ * IFF_ALLMULTI flag here.
+ */
+ IF_ADDR_LOCK(ifp);
+ ifp->if_flags |= IFF_ALLMULTI;
+ IF_ADDR_UNLOCK(ifp);
+}
+
+static int
+urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ struct urtw_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ifreq *ifr = (struct ifreq *) data;
+ int error = 0, startall = 0;
+
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ mtx_lock(&Giant);
+ if (ifp->if_flags & IFF_UP) {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if ((ifp->if_flags ^ sc->sc_if_flags) &
+ (IFF_ALLMULTI | IFF_PROMISC))
+ urtw_set_multi(sc);
+ } else {
+ urtw_init(ifp->if_softc);
+ startall = 1;
+ }
+ } else {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ urtw_stop(ifp, 1);
+ }
+ sc->sc_if_flags = ifp->if_flags;
+ mtx_unlock(&Giant);
+ if (startall)
+ ieee80211_start_all(ic);
+ break;
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
+ break;
+ case SIOCGIFADDR:
+ error = ether_ioctl(ifp, cmd, data);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+static void
+urtw_start(struct ifnet *ifp)
+{
+ struct urtw_softc *sc = ifp->if_softc;
+ struct ieee80211_node *ni;
+ struct mbuf *m;
+
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ return;
+
+ URTW_LOCK(sc);
+ for (;;) {
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ break;
+ if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT ||
+ sc->sc_tx_normal_queued >= URTW_TX_DATA_LIST_COUNT) {
+ IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ m->m_pkthdr.rcvif = NULL;
+ m = ieee80211_encap(ni, m);
+ if (m == NULL) {
+ ieee80211_free_node(ni);
+ ifp->if_oerrors++;
+ continue;
+ }
+
+ if (urtw_tx_start(sc, ni, m, URTW_PRIORITY_NORMAL) != 0) {
+ ieee80211_free_node(ni);
+ ifp->if_oerrors++;
+ break;
+ }
+
+ sc->sc_txtimer = 5;
+ }
+ URTW_UNLOCK(sc);
+}
+
+static void
+urtw_txeof_low(usbd_xfer_handle xfer, usbd_private_handle priv,
+ usbd_status status)
+{
+ struct urtw_data *data = priv;
+ struct urtw_softc *sc = data->sc;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct mbuf *m;
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+ return;
+
+ device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
+ usbd_errstr(status));
+
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_txpipe_low);
+
+ ifp->if_oerrors++;
+ return;
+ }
+
+ /*
+ * Do any tx complete callback. Note this must be done before releasing
+ * the node reference.
+ */
+ m = data->m;
+ if (m != NULL && m->m_flags & M_TXCB) {
+ ieee80211_process_callback(data->ni, m, 0); /* XXX status? */
+ m_freem(m);
+ data->m = NULL;
+ }
+
+ ieee80211_free_node(data->ni);
+ data->ni = NULL;
+
+ sc->sc_txtimer = 0;
+ ifp->if_opackets++;
+
+ URTW_LOCK(sc);
+ sc->sc_tx_low_queued--;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ URTW_UNLOCK(sc);
+
+ urtw_start(ifp);
+}
+
+static void
+urtw_txeof_normal(usbd_xfer_handle xfer, usbd_private_handle priv,
+ usbd_status status)
+{
+ struct urtw_data *data = priv;
+ struct urtw_softc *sc = data->sc;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct mbuf *m;
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+ return;
+
+ device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
+ usbd_errstr(status));
+
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_txpipe_normal);
+
+ ifp->if_oerrors++;
+ return;
+ }
+
+ /*
+ * Do any tx complete callback. Note this must be done before releasing
+ * the node reference.
+ */
+ m = data->m;
+ if (m != NULL && m->m_flags & M_TXCB) {
+ ieee80211_process_callback(data->ni, m, 0); /* XXX status? */
+ m_freem(m);
+ data->m = NULL;
+ }
+
+ ieee80211_free_node(data->ni);
+ data->ni = NULL;
+
+ sc->sc_txtimer = 0;
+ ifp->if_opackets++;
+
+ URTW_LOCK(sc);
+ sc->sc_tx_normal_queued--;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ URTW_UNLOCK(sc);
+
+ urtw_start(ifp);
+}
+
+static int
+urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
+ int prior)
+{
+ int xferlen;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
+ struct ieee80211_key *k;
+ const struct ieee80211_txparam *tp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct urtw_data *data;
+ usbd_status error;
+
+ URTW_ASSERT_LOCKED(sc);
+
+ /*
+ * Software crypto.
+ */
+ if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+ k = ieee80211_crypto_encap(ni, m0);
+ if (k == NULL) {
+ device_printf(sc->sc_dev,
+ "ieee80211_crypto_encap returns NULL.\n");
+ /* XXX we don't expect the fragmented frames */
+ m_freem(m0);
+ return (ENOBUFS);
+ }
+
+ /* in case packet header moved, reset pointer */
+ wh = mtod(m0, struct ieee80211_frame *);
+ }
+
+ if (bpf_peers_present(ifp->if_bpf)) {
+ struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
+
+ /* XXX Are variables correct? */
+ tap->wt_flags = 0;
+ tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+
+ bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+ }
+
+ xferlen = m0->m_pkthdr.len + 4 * 3;
+ if((0 == xferlen % 64) || (0 == xferlen % 512))
+ xferlen += 1;
+
+ data = &sc->sc_txdata[sc->sc_txidx];
+ sc->sc_txidx = (sc->sc_txidx + 1) % URTW_TX_DATA_LIST_COUNT;
+
+ bzero(data->buf, URTW_TX_MAXSIZE);
+ data->buf[0] = m0->m_pkthdr.len & 0xff;
+ data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8;
+ data->buf[1] |= (1 << 7);
+
+ if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+ (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
+ (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
+ (sc->sc_currate != 0))
+ data->buf[2] |= 1;
+ if ((m0->m_pkthdr.len > vap->iv_rtsthreshold) &&
+ prior == URTW_PRIORITY_LOW)
+ panic("TODO tx.");
+ if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
+ data->buf[2] |= (1 << 1);
+ /* RTS rate - 10 means we use a basic rate. */
+ data->buf[2] |= (urtw_rate2rtl(2) << 3);
+ /*
+ * XXX currently TX rate control depends on the rate value of
+ * RX descriptor because I don't know how to we can control TX rate
+ * in more smart way. Please fix me you find a thing.
+ */
+ data->buf[3] = sc->sc_currate;
+ if (prior == URTW_PRIORITY_NORMAL) {
+ tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1))
+ data->buf[3] = urtw_rate2rtl(tp->mcastrate);
+ else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
+ data->buf[3] = urtw_rate2rtl(tp->ucastrate);
+ }
+ data->buf[8] = 3; /* CW minimum */
+ data->buf[8] |= (7 << 4); /* CW maximum */
+ data->buf[9] |= 11; /* retry limitation */
+
+ m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[12]);
+ data->ni = ni;
+ data->m = m0;
+
+ usbd_setup_xfer(data->xfer,
+ (prior == URTW_PRIORITY_LOW) ? sc->sc_txpipe_low :
+ sc->sc_txpipe_normal, data, data->buf, xferlen,
+ USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTW_DATA_TIMEOUT,
+ (prior == URTW_PRIORITY_LOW) ? urtw_txeof_low : urtw_txeof_normal);
+ error = usbd_transfer(data->xfer);
+ if (error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION) {
+ device_printf(sc->sc_dev, "could not send frame: %s\n",
+ usbd_errstr(error));
+ return EIO;
+ }
+
+ error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
+ if (error != 0)
+ device_printf(sc->sc_dev, "could not control LED (%d)\n", error);
+
+ if (prior == URTW_PRIORITY_LOW)
+ sc->sc_tx_low_queued++;
+ else
+ sc->sc_tx_normal_queued++;
+
+ return (0);
+}
+
+static int
+urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct urtw_softc *sc = ifp->if_softc;
+
+ /* prevent management frames from being sent if we're not ready */
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ m_freem(m);
+ ieee80211_free_node(ni);
+ return ENETDOWN;
+ }
+ URTW_LOCK(sc);
+ if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT ||
+ sc->sc_tx_normal_queued >= URTW_TX_DATA_LIST_COUNT) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ m_freem(m);
+ ieee80211_free_node(ni);
+ URTW_UNLOCK(sc);
+ return (ENOBUFS); /* XXX */
+ }
+
+ ifp->if_opackets++;
+ if (urtw_tx_start(sc, ni, m, URTW_PRIORITY_LOW) != 0) {
+ ieee80211_free_node(ni);
+ ifp->if_oerrors++;
+ URTW_UNLOCK(sc);
+ return (EIO);
+ }
+
+ sc->sc_txtimer = 5;
+ URTW_UNLOCK(sc);
+ return (0);
+}
+
+static void
+urtw_scan_start(struct ieee80211com *ic)
+{
+
+ /* XXX do nothing? */
+}
+
+static void
+urtw_scan_end(struct ieee80211com *ic)
+{
+
+ /* XXX do nothing? */
+}
+
+static void
+urtw_set_channel(struct ieee80211com *ic)
+{
+ struct urtw_softc *sc = ic->ic_ifp->if_softc;
+ struct ifnet *ifp = sc->sc_ifp;
+
+ /*
+ * if the user set a channel explicitly using ifconfig(8) this function
+ * can be called earlier than we're expected that in some cases the
+ * initialization would be failed if setting a channel is called before
+ * the init have done.
+ */
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ return;
+
+ sc->sc_ctxarg = URTW_SET_CHANNEL;
+ usb_add_task(sc->sc_udev, &sc->sc_ctxtask, USB_TASKQ_DRIVER);
+}
+
+static void
+urtw_update_mcast(struct ifnet *ifp)
+{
+
+ /* XXX do nothing? */
+}
+
+static usbd_status
+urtw_8225_usb_init(struct urtw_softc *sc)
+{
+ uint8_t data;
+ usbd_status error;
+
+ urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
+ urtw_write8_m(sc, URTW_GPIO, 0);
+ error = urtw_read8e(sc, 0x53, &data);
+ if (error)
+ goto fail;
+ error = urtw_write8e(sc, 0x53, data | (1 << 7));
+ if (error)
+ goto fail;
+ urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
+ urtw_write8_m(sc, URTW_GPIO, 0x20);
+ urtw_write8_m(sc, URTW_GP_ENABLE, 0);
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
+
+ usbd_delay_ms(sc->sc_udev, 500);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8185_rf_pins_enable(struct urtw_softc *sc)
+{
+ usbd_status error = 0;
+
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
+{
+ uint32_t phyw;
+ usbd_status error;
+
+ phyw = ((data << 8) | (addr | 0x80));
+ urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
+ urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
+ urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
+ urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
+ usbd_delay_ms(sc->sc_udev, 1);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
+{
+
+ data = data & 0xff;
+ return urtw_8187_write_phy(sc, addr, data);
+}
+
+static usbd_status
+urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
+{
+
+ data = data & 0xff;
+ return urtw_8187_write_phy(sc, addr, data | 0x10000);
+}
+
+static usbd_status
+urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
+{
+ usbd_status error;
+
+ urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
+ urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
+ urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
+ urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
+{
+ int i, idx, set;
+ uint8_t *cck_pwltable;
+ uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
+ uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
+ uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
+ usbd_status error;
+
+ cck_pwrlvl_max = 11;
+ ofdm_pwrlvl_max = 25; /* 12 -> 25 */
+ ofdm_pwrlvl_min = 10;
+
+ /* CCK power setting */
+ cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
+ idx = cck_pwrlvl % 6;
+ set = cck_pwrlvl / 6;
+ cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
+ urtw_8225_txpwr_cck;
+
+ urtw_write8_m(sc, URTW_TX_GAIN_CCK,
+ urtw_8225_tx_gain_cck_ofdm[set] >> 1);
+ for (i = 0; i < 8; i++) {
+ urtw_8187_write_phy_cck(sc, 0x44 + i,
+ cck_pwltable[idx * 8 + i]);
+ }
+ usbd_delay_ms(sc->sc_udev, 1);
+
+ /* OFDM power setting */
+ ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
+ ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
+ ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
+
+ idx = ofdm_pwrlvl % 6;
+ set = ofdm_pwrlvl / 6;
+
+ error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
+ if (error)
+ goto fail;
+ urtw_8187_write_phy_ofdm(sc, 2, 0x42);
+ urtw_8187_write_phy_ofdm(sc, 6, 0);
+ urtw_8187_write_phy_ofdm(sc, 8, 0);
+
+ urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
+ urtw_8225_tx_gain_cck_ofdm[set] >> 1);
+ urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
+ urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
+ usbd_delay_ms(sc->sc_udev, 1);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
+{
+ usbd_status error;
+
+ urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
+ usbd_delay_ms(sc->sc_udev, 1);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225_rf_init(struct urtw_softc *sc)
+{
+#define N(a) (sizeof(a) / sizeof((a)[0]))
+ int i;
+ uint16_t data;
+ usbd_status error;
+
+ error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
+ if (error)
+ goto fail;
+
+ error = urtw_8225_usb_init(sc);
+ if (error)
+ goto fail;
+
+ urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
+ urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
+ urtw_write16_m(sc, URTW_BRSR, 0xffff);
+ urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
+ if (error)
+ goto fail;
+ urtw_write8_m(sc, URTW_CONFIG3, 0x44);
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
+ if (error)
+ goto fail;
+
+ error = urtw_8185_rf_pins_enable(sc);
+ if (error)
+ goto fail;
+ usbd_delay_ms(sc->sc_udev, 1000);
+
+ for (i = 0; i < N(urtw_8225_rf_part1); i++) {
+ urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
+ urtw_8225_rf_part1[i].val);
+ usbd_delay_ms(sc->sc_udev, 1);
+ }
+ usbd_delay_ms(sc->sc_udev, 100);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
+ usbd_delay_ms(sc->sc_udev, 200);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
+ usbd_delay_ms(sc->sc_udev, 200);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
+
+ for (i = 0; i < 95; i++) {
+ urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
+ urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
+ }
+
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
+
+ for (i = 0; i < 128; i++) {
+ urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
+ usbd_delay_ms(sc->sc_udev, 1);
+ urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
+ usbd_delay_ms(sc->sc_udev, 1);
+ }
+
+ for (i = 0; i < N(urtw_8225_rf_part2); i++) {
+ urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
+ urtw_8225_rf_part2[i].val);
+ usbd_delay_ms(sc->sc_udev, 1);
+ }
+
+ error = urtw_8225_setgain(sc, 4);
+ if (error)
+ goto fail;
+
+ for (i = 0; i < N(urtw_8225_rf_part3); i++) {
+ urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
+ urtw_8225_rf_part3[i].val);
+ usbd_delay_ms(sc->sc_udev, 1);
+ }
+
+ urtw_write8_m(sc, URTW_ADDR_MAGIC4, 0x0d);
+
+ error = urtw_8225_set_txpwrlvl(sc, 1);
+ if (error)
+ goto fail;
+
+ urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
+ usbd_delay_ms(sc->sc_udev, 1);
+ urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
+ usbd_delay_ms(sc->sc_udev, 1);
+
+ /* TX ant A, 0x0 for B */
+ error = urtw_8185_tx_antenna(sc, 0x3);
+ if (error)
+ goto fail;
+ urtw_write32_m(sc, URTW_ADDR_MAGIC5, 0x3dc00002);
+
+ error = urtw_8225_rf_set_chan(sc, 1);
+fail:
+ return (error);
+#undef N
+}
+
+static usbd_status
+urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
+{
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211_channel *c = ic->ic_curchan;
+ usbd_status error;
+
+ error = urtw_8225_set_txpwrlvl(sc, chan);
+ if (error)
+ goto fail;
+ urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
+ usbd_delay_ms(sc->sc_udev, 10);
+
+ urtw_write8_m(sc, URTW_SIFS, 0x22);
+
+ if (sc->sc_state == IEEE80211_S_ASSOC &&
+ ic->ic_flags & IEEE80211_F_SHSLOT)
+ urtw_write8_m(sc, URTW_SLOT, 0x9);
+ else
+ urtw_write8_m(sc, URTW_SLOT, 0x14);
+
+ if (IEEE80211_IS_CHAN_G(c)) {
+ /* for G */
+ urtw_write8_m(sc, URTW_DIFS, 0x14);
+ urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
+ urtw_write8_m(sc, URTW_CW_VAL, 0x73);
+ } else {
+ /* for B */
+ urtw_write8_m(sc, URTW_DIFS, 0x24);
+ urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
+ urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
+ }
+
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
+{
+ usbd_status error;
+
+ if (sens < 0 || sens > 6)
+ return -1;
+
+ if (sens > 4)
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
+ else
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
+
+ sens = 6 - sens;
+ error = urtw_8225_setgain(sc, sens);
+ if (error)
+ goto fail;
+
+ urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
+
+fail:
+ return (error);
+}
+
+static void
+urtw_stop(struct ifnet *ifp, int disable)
+{
+ struct urtw_softc *sc = ifp->if_softc;
+
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+ callout_stop(&sc->sc_led_ch);
+ callout_stop(&sc->sc_watchdog_ch);
+
+ if (sc->sc_rxpipe != NULL)
+ usbd_abort_pipe(sc->sc_rxpipe);
+ if (sc->sc_txpipe_low != NULL)
+ usbd_abort_pipe(sc->sc_txpipe_low);
+ if (sc->sc_txpipe_normal != NULL)
+ usbd_abort_pipe(sc->sc_txpipe_normal);
+}
+
+static int
+urtw_isbmode(uint16_t rate)
+{
+
+ rate = urtw_rtl2rate(rate);
+
+ return ((rate <= 22 && rate != 12 && rate != 18) ||
+ rate == 44) ? (1) : (0);
+}
+
+static void
+urtw_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+{
+ int actlen, flen, len, nf, rssi;
+ struct ieee80211_frame *wh;
+ struct ieee80211_node *ni;
+ struct mbuf *m, *mnew;
+ struct urtw_data *data = priv;
+ struct urtw_softc *sc = data->sc;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ uint8_t *desc, quality, rate;
+ usbd_status error;
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+ return;
+
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_rxpipe);
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
+ if (actlen < URTW_MIN_RXBUFSZ) {
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ /* 4 dword and 4 byte CRC */
+ len = actlen - (4 * 4);
+ desc = data->buf + len;
+ flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
+ if (flen > actlen) {
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ rate = (desc[2] & 0xf0) >> 4;
+ quality = desc[4] & 0xff;
+ /* XXX correct? */
+ rssi = (desc[6] & 0xfe) >> 1;
+ if (!urtw_isbmode(rate)) {
+ rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
+ rssi = ((90 - rssi) * 100) / 65;
+ } else {
+ rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
+ rssi = ((95 - rssi) * 100) / 65;
+ }
+
+ mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (mnew == NULL) {
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ m = data->m;
+ data->m = mnew;
+ data->buf = mtod(mnew, uint8_t *);
+
+ /* finalize mbuf */
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = m->m_len = flen - 4;
+
+ if (bpf_peers_present(ifp->if_bpf)) {
+ struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
+
+ /* XXX Are variables correct? */
+ tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
+ tap->wr_dbm_antsignal = (int8_t)rssi;
+
+ bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+ }
+
+ wh = mtod(m, struct ieee80211_frame *);
+ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
+ sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
+ ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
+ /* XXX correct? */
+ nf = (quality > 64) ? 0 : ((64 - quality) * 100) / 64;
+ /* send the frame to the 802.11 layer */
+ if (ni != NULL) {
+ (void) ieee80211_input(ni, m, rssi, -nf, 0);
+ /* node is no longer needed */
+ ieee80211_free_node(ni);
+ } else
+ (void) ieee80211_input_all(ic, m, rssi, -nf, 0);
+
+skip: /* setup a new transfer */
+ usbd_setup_xfer(xfer, sc->sc_rxpipe, data, data->buf, MCLBYTES,
+ USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
+ error = usbd_transfer(xfer);
+ if (error != USBD_IN_PROGRESS && error != 0)
+ device_printf(sc->sc_dev, "could not queue Rx transfer\n");
+}
+
+static int
+urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+ struct urtw_vap *rvp = URTW_VAP(vap);
+ struct ieee80211com *ic = vap->iv_ic;
+ struct urtw_softc *sc = ic->ic_ifp->if_softc;
+
+ DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
+ ieee80211_state_name[vap->iv_state],
+ ieee80211_state_name[nstate]);
+
+ /* do it in a process context */
+ sc->sc_state = nstate;
+ sc->sc_arg = arg;
+
+ if (nstate == IEEE80211_S_INIT) {
+ rvp->newstate(vap, nstate, arg);
+ return (0);
+ } else {
+ usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
+ return (EINPROGRESS);
+ }
+}
+
+static usbd_status
+urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
+{
+ uint8_t *gainp;
+ usbd_status error;
+
+ /* XXX for A? */
+ gainp = urtw_8225v2_gain_bg;
+ urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
+ usbd_delay_ms(sc->sc_udev, 1);
+ urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
+ usbd_delay_ms(sc->sc_udev, 1);
+ urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
+ usbd_delay_ms(sc->sc_udev, 1);
+ urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
+ usbd_delay_ms(sc->sc_udev, 1);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
+{
+ int i;
+ uint8_t *cck_pwrtable;
+ uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
+ uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
+ uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
+ usbd_status error;
+
+ /* CCK power setting */
+ cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
+ cck_pwrlvl += sc->sc_txpwr_cck_base;
+ cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
+ cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
+ urtw_8225v2_txpwr_cck;
+
+ for (i = 0; i < 8; i++)
+ urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
+
+ urtw_write8_m(sc, URTW_TX_GAIN_CCK,
+ urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
+ usbd_delay_ms(sc->sc_udev, 1);
+
+ /* OFDM power setting */
+ ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
+ ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
+ ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
+ ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
+
+ error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
+ if (error)
+ goto fail;
+
+ urtw_8187_write_phy_ofdm(sc, 2, 0x42);
+ urtw_8187_write_phy_ofdm(sc, 5, 0x0);
+ urtw_8187_write_phy_ofdm(sc, 6, 0x40);
+ urtw_8187_write_phy_ofdm(sc, 7, 0x0);
+ urtw_8187_write_phy_ofdm(sc, 8, 0x40);
+
+ urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
+ urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
+ usbd_delay_ms(sc->sc_udev, 1);
+fail:
+ return (error);
+}
+
+static usbd_status
+urtw_8225v2_rf_init(struct urtw_softc *sc)
+{
+#define N(a) (sizeof(a) / sizeof((a)[0]))
+ int i;
+ uint16_t data;
+ uint32_t data32;
+ usbd_status error;
+
+ error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
+ if (error)
+ goto fail;
+
+ error = urtw_8225_usb_init(sc);
+ if (error)
+ goto fail;
+
+ urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
+ urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
+ urtw_write16_m(sc, URTW_BRSR, 0xffff);
+ urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
+
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
+ if (error)
+ goto fail;
+ urtw_write8_m(sc, URTW_CONFIG3, 0x44);
+ error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
+ if (error)
+ goto fail;
+
+ error = urtw_8185_rf_pins_enable(sc);
+ if (error)
+ goto fail;
+
+ usbd_delay_ms(sc->sc_udev, 500);
+
+ for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
+ urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
+ urtw_8225v2_rf_part1[i].val);
+ }
+ usbd_delay_ms(sc->sc_udev, 50);
+
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
+
+ for (i = 0; i < 95; i++) {
+ urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
+ urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
+ urtw_8225v2_rxgain[i]);
+ }
+
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
+ usbd_delay_ms(sc->sc_udev, 100);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
+ usbd_delay_ms(sc->sc_udev, 100);
+
+ error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
+ if (error != 0)
+ goto fail;
+ if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
+ device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
+ if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
+ usbd_delay_ms(sc->sc_udev, 100);
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
+ usbd_delay_ms(sc->sc_udev, 50);
+ error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
+ if (error != 0)
+ goto fail;
+ if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
+ device_printf(sc->sc_dev, "RF calibration failed\n");
+ }
+ usbd_delay_ms(sc->sc_udev, 100);
+
+ urtw_8225_write(sc,
+ URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
+ for (i = 0; i < 128; i++) {
+ urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
+ urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
+ }
+
+ for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
+ urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
+ urtw_8225v2_rf_part2[i].val);
+ }
+
+ error = urtw_8225v2_setgain(sc, 4);
+ if (error)
+ goto fail;
+
+ for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
+ urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
+ urtw_8225v2_rf_part3[i].val);
+ }
+
+ urtw_write8_m(sc, URTW_ADDR_MAGIC4, 0x0d);
+
+ error = urtw_8225v2_set_txpwrlvl(sc, 1);
+ if (error)
+ goto fail;
+
+ urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
+ urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
+
+ /* TX ant A, 0x0 for B */
+ error = urtw_8185_tx_antenna(sc, 0x3);
+ if (error)
+ goto fail;
+ urtw_write32_m(sc, URTW_ADDR_MAGIC5, 0x3dc00002);
+
+ error = urtw_8225_rf_set_chan(sc, 1);
+fail:
+ return (error);
+#undef N
+}
+
+static usbd_status
+urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
+{
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211_channel *c = ic->ic_curchan;
+ usbd_status error;
+
+ error = urtw_8225v2_set_txpwrlvl(sc, chan);
+ if (error)
+ goto fail;
+
+ urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
+ usbd_delay_ms(sc->sc_udev, 10);
+
+ urtw_write8_m(sc, URTW_SIFS, 0x22);
+
+ if(sc->sc_state == IEEE80211_S_ASSOC &&
+ ic->ic_flags & IEEE80211_F_SHSLOT)
+ urtw_write8_m(sc, URTW_SLOT, 0x9);
+ else
+ urtw_write8_m(sc, URTW_SLOT, 0x14);
+
+ if (IEEE80211_IS_CHAN_G(c)) {
+ /* for G */
+ urtw_write8_m(sc, URTW_DIFS, 0x14);
+ urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
+ urtw_write8_m(sc, URTW_CW_VAL, 0x73);
+ } else {
+ /* for B */
+ urtw_write8_m(sc, URTW_DIFS, 0x24);
+ urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
+ urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
+ }
+
+fail:
+ return (error);
+}
+
+static void
+urtw_ctxtask(void *arg)
+{
+ struct urtw_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ uint32_t data;
+ usbd_status error;
+
+ switch (sc->sc_ctxarg) {
+ case URTW_SET_CHANNEL:
+ /*
+ * during changing th channel we need to temporarily be disable
+ * TX.
+ */
+ urtw_read32_m(sc, URTW_TX_CONF, &data);
+ data &= ~URTW_TX_LOOPBACK_MASK;
+ urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
+ error = sc->sc_rf_set_chan(sc,
+ ieee80211_chan2ieee(ic, ic->ic_curchan));
+ if (error != 0)
+ goto fail;
+ usbd_delay_ms(sc->sc_udev, 10);
+ urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_NONE);
+ break;
+ default:
+ panic("unknown argument.\n");
+ }
+
+fail:
+ if (error != 0)
+ device_printf(sc->sc_dev, "could not change the channel\n");
+ return;
+}
+
+static void
+urtw_task(void *arg)
+{
+ struct urtw_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ struct ieee80211_node *ni = vap->iv_bss;
+ struct urtw_vap *uvp = URTW_VAP(vap);
+ usbd_status error = 0;
+
+ switch (sc->sc_state) {
+ case IEEE80211_S_RUN:
+ /* setting bssid. */
+ urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
+ urtw_write16_m(sc, URTW_BSSID + 4,
+ ((uint16_t *)ni->ni_bssid)[2]);
+ urtw_update_msr(sc);
+ /* XXX maybe the below would be incorrect. */
+ urtw_write16_m(sc, URTW_ATIM_WND, 2);
+ urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
+ urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
+ urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
+ error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
+ if (error != 0)
+ device_printf(sc->sc_dev,
+ "could not control LED (%d)\n", error);
+ break;
+ default:
+ break;
+ }
+
+fail:
+ if (error != 0)
+ printf("error duing processing RUN state.");
+
+ IEEE80211_LOCK(ic);
+ uvp->newstate(vap, sc->sc_state, sc->sc_arg);
+ if (vap->iv_newstate_cb != NULL)
+ vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
+ IEEE80211_UNLOCK(ic);
+}
+
+static void
+urtw_watchdog(void *arg)
+{
+ struct urtw_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+
+ if (sc->sc_txtimer > 0) {
+ if (--sc->sc_txtimer == 0) {
+ device_printf(sc->sc_dev, "device timeout\n");
+ ifp->if_oerrors++;
+ return;
+ }
+ callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
+ }
+}
+
+static device_method_t urtw_methods[] = {
+ DEVMETHOD(device_probe, urtw_match),
+ DEVMETHOD(device_attach, urtw_attach),
+ DEVMETHOD(device_detach, urtw_detach),
+ { 0, 0 }
+};
+static driver_t urtw_driver = {
+ "urtw",
+ urtw_methods,
+ sizeof(struct urtw_softc)
+};
+static devclass_t urtw_devclass;
+
+DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(urtw, wlan, 1, 1, 1);
+MODULE_DEPEND(urtw, usb, 1, 1, 1);
diff --git a/sys/dev/usb/if_urtwreg.h b/sys/dev/usb/if_urtwreg.h
new file mode 100644
index 0000000..7a9baa3
--- /dev/null
+++ b/sys/dev/usb/if_urtwreg.h
@@ -0,0 +1,256 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2008 Weongyo Jeong <weongyo@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
+ * 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.
+ */
+
+#define URTW_CONFIG_NO 1
+#define URTW_IFACE_INDEX 0
+
+/* for 8187 */
+#define URTW_MAC0 0x0000 /* 1 byte */
+#define URTW_MAC1 0x0001 /* 1 byte */
+#define URTW_MAC2 0x0002 /* 1 byte */
+#define URTW_MAC3 0x0003 /* 1 byte */
+#define URTW_MAC4 0x0004 /* 1 byte */
+#define URTW_MAC5 0x0005 /* 1 byte */
+#define URTW_BRSR 0x002c /* 2 byte */
+#define URTW_BRSR_MBR_8185 (0x0fff)
+#define URTW_BSSID 0x002e /* 6 byte */
+#define URTW_RESP_RATE 0x0034 /* 1 byte */
+#define URTW_RESP_MAX_RATE_SHIFT (4)
+#define URTW_RESP_MIN_RATE_SHIFT (0)
+#define URTW_EIFS 0x0035 /* 1 byte */
+#define URTW_INTR_MASK 0x003c /* 2 byte */
+#define URTW_CMD 0x0037 /* 1 byte */
+#define URTW_CMD_TX_ENABLE (0x4)
+#define URTW_CMD_RX_ENABLE (0x8)
+#define URTW_CMD_RST (0x10)
+#define URTW_TX_CONF 0x0040 /* 4 byte */
+#define URTW_TX_LOOPBACK_SHIFT (17)
+#define URTW_TX_LOOPBACK_NONE (0 << URTW_TX_LOOPBACK_SHIFT)
+#define URTW_TX_LOOPBACK_MAC (1 << URTW_TX_LOOPBACK_SHIFT)
+#define URTW_TX_LOOPBACK_BASEBAND (2 << URTW_TX_LOOPBACK_SHIFT)
+#define URTW_TX_LOOPBACK_CONTINUE (3 << URTW_TX_LOOPBACK_SHIFT)
+#define URTW_TX_LOOPBACK_MASK (0x60000)
+#define URTW_TX_DPRETRY_MASK (0xff00)
+#define URTW_TX_RTSRETRY_MASK (0xff)
+#define URTW_TX_DPRETRY_SHIFT (0)
+#define URTW_TX_RTSRETRY_SHIFT (8)
+#define URTW_TX_NOCRC (0x10000)
+#define URTW_TX_MXDMA_MASK (0xe00000)
+#define URTW_TX_MXDMA_1024 (6 << URTW_TX_MXDMA_SHIFT)
+#define URTW_TX_MXDMA_2048 (7 << URTW_TX_MXDMA_SHIFT)
+#define URTW_TX_MXDMA_SHIFT (21)
+#define URTW_TX_CWMIN (1 << 31)
+#define URTW_TX_DISCW (1 << 20)
+#define URTW_TX_SWPLCPLEN (1 << 24)
+#define URTW_TX_NOICV (0x80000)
+#define URTW_RX 0x0044 /* 4 byte */
+#define URTW_RX_9356SEL (1 << 6)
+#define URTW_RX_FILTER_MASK \
+ (URTW_RX_FILTER_ALLMAC | URTW_RX_FILTER_NICMAC | URTW_RX_FILTER_MCAST | \
+ URTW_RX_FILTER_BCAST | URTW_RX_FILTER_CRCERR | URTW_RX_FILTER_ICVERR | \
+ URTW_RX_FILTER_DATA | URTW_RX_FILTER_CTL | URTW_RX_FILTER_MNG | \
+ (1 << 21) | \
+ URTW_RX_FILTER_PWR | URTW_RX_CHECK_BSSID)
+#define URTW_RX_FILTER_ALLMAC (0x00000001)
+#define URTW_RX_FILTER_NICMAC (0x00000002)
+#define URTW_RX_FILTER_MCAST (0x00000004)
+#define URTW_RX_FILTER_BCAST (0x00000008)
+#define URTW_RX_FILTER_CRCERR (0x00000020)
+#define URTW_RX_FILTER_ICVERR (0x00001000)
+#define URTW_RX_FILTER_DATA (0x00040000)
+#define URTW_RX_FILTER_CTL (0x00080000)
+#define URTW_RX_FILTER_MNG (0x00100000)
+#define URTW_RX_FILTER_PWR (0x00400000)
+#define URTW_RX_CHECK_BSSID (0x00800000)
+#define URTW_RX_FIFO_THRESHOLD_MASK ((1 << 13) | (1 << 14) | (1 << 15))
+#define URTW_RX_FIFO_THRESHOLD_SHIFT (13)
+#define URTW_RX_FIFO_THRESHOLD_128 (3)
+#define URTW_RX_FIFO_THRESHOLD_256 (4)
+#define URTW_RX_FIFO_THRESHOLD_512 (5)
+#define URTW_RX_FIFO_THRESHOLD_1024 (6)
+#define URTW_RX_FIFO_THRESHOLD_NONE (7 << URTW_RX_FIFO_THRESHOLD_SHIFT)
+#define URTW_RX_AUTORESETPHY (1 << URTW_RX_AUTORESETPHY_SHIFT)
+#define URTW_RX_AUTORESETPHY_SHIFT (28)
+#define URTW_MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
+#define URTW_MAX_RX_DMA_2048 (7 << URTW_MAX_RX_DMA_SHIFT)
+#define URTW_MAX_RX_DMA_1024 (6)
+#define URTW_MAX_RX_DMA_SHIFT (10)
+#define URTW_RCR_ONLYERLPKT (1 << 31)
+#define URTW_INT_TIMEOUT 0x0048 /* 4 byte */
+#define URTW_EPROM_CMD 0x0050 /* 1 byte */
+#define URTW_EPROM_CMD_NORMAL (0x0)
+#define URTW_EPROM_CMD_NORMAL_MODE \
+ (URTW_EPROM_CMD_NORMAL << URTW_EPROM_CMD_SHIFT)
+#define URTW_EPROM_CMD_LOAD (0x1)
+#define URTW_EPROM_CMD_PROGRAM (0x2)
+#define URTW_EPROM_CMD_PROGRAM_MODE \
+ (URTW_EPROM_CMD_PROGRAM << URTW_EPROM_CMD_SHIFT)
+#define URTW_EPROM_CMD_CONFIG (0x3)
+#define URTW_EPROM_CMD_SHIFT (6)
+#define URTW_EPROM_CMD_MASK ((1 << 7) | (1 << 6))
+#define URTW_EPROM_READBIT (0x1)
+#define URTW_EPROM_WRITEBIT (0x2)
+#define URTW_EPROM_CK (0x4)
+#define URTW_EPROM_CS (0x8)
+#define URTW_CONFIG2 0x0053
+#define URTW_ANAPARAM 0x0054 /* 4 byte */
+#define URTW_8225_ANAPARAM_ON (0xa0000a59)
+#define URTW_MSR 0x0058 /* 1 byte */
+#define URTW_MSR_LINK_MASK ((1 << 2) | (1 << 3))
+#define URTW_MSR_LINK_SHIFT (2)
+#define URTW_MSR_LINK_NONE (0 << URTW_MSR_LINK_SHIFT)
+#define URTW_MSR_LINK_ADHOC (1 << URTW_MSR_LINK_SHIFT)
+#define URTW_MSR_LINK_STA (2 << URTW_MSR_LINK_SHIFT)
+#define URTW_MSR_LINK_HOSTAP (3 << URTW_MSR_LINK_SHIFT)
+#define URTW_CONFIG3 0x0059 /* 1 byte */
+#define URTW_CONFIG3_ANAPARAM_WRITE (0x40)
+#define URTW_CONFIG3_ANAPARAM_W_SHIFT (6)
+#define URTW_ADDR_MAGIC4 0x005b /* 1 byte */
+#define URTW_PSR 0x005e /* 1 byte */
+#define URTW_ANAPARAM2 0x0060 /* 4 byte */
+#define URTW_8225_ANAPARAM2_ON (0x860c7312)
+#define URTW_BEACON_INTERVAL 0x0070 /* 2 byte */
+#define URTW_ATIM_WND 0x0072 /* 2 byte */
+#define URTW_BEACON_INTERVAL_TIME 0x0074 /* 2 byte */
+#define URTW_ATIM_TR_ITV 0x0076 /* 2 byte */
+#define URTW_PHY_MAGIC1 0x007c /* 1 byte */
+#define URTW_PHY_MAGIC2 0x007d /* 1 byte */
+#define URTW_PHY_MAGIC3 0x007e /* 1 byte */
+#define URTW_PHY_MAGIC4 0x007f /* 1 byte */
+#define URTW_RF_PINS_OUTPUT 0x0080 /* 2 byte */
+#define URTW_RF_PINS_OUTPUT_MAGIC1 (0x3a0)
+#define URTW_BB_HOST_BANG_CLK (1 << 1)
+#define URTW_BB_HOST_BANG_EN (1 << 2)
+#define URTW_BB_HOST_BANG_RW (1 << 3)
+#define URTW_RF_PINS_ENABLE 0x0082 /* 2 byte */
+#define URTW_RF_PINS_SELECT 0x0084 /* 2 byte */
+#define URTW_ADDR_MAGIC1 0x0085 /* broken? */
+#define URTW_RF_PINS_INPUT 0x0086 /* 2 byte */
+#define URTW_RF_PINS_MAGIC1 (0xfff3)
+#define URTW_RF_PINS_MAGIC2 (0xfff0)
+#define URTW_RF_PINS_MAGIC3 (0x0007)
+#define URTW_RF_PINS_MAGIC4 (0xf)
+#define URTW_RF_PINS_MAGIC5 (0x0080)
+#define URTW_RF_PARA 0x0088 /* 4 byte */
+#define URTW_RF_TIMING 0x008c /* 4 byte */
+#define URTW_GP_ENABLE 0x0090 /* 1 byte */
+#define URTW_GP_ENABLE_DATA_MAGIC1 (0x1)
+#define URTW_GPIO 0x0091 /* 1 byte */
+#define URTW_GPIO_DATA_MAGIC1 (0x1)
+#define URTW_ADDR_MAGIC5 0x0094 /* 4 byte */
+#define URTW_TX_AGC_CTL 0x009c /* 1 byte */
+#define URTW_TX_AGC_CTL_PERPACKET_GAIN (0x1)
+#define URTW_TX_AGC_CTL_PERPACKET_ANTSEL (0x2)
+#define URTW_TX_AGC_CTL_FEEDBACK_ANT (0x4)
+#define URTW_TX_GAIN_CCK 0x009d /* 1 byte */
+#define URTW_TX_GAIN_OFDM 0x009e /* 1 byte */
+#define URTW_TX_ANTENNA 0x009f /* 1 byte */
+#define URTW_WPA_CONFIG 0x00b0 /* 1 byte */
+#define URTW_SIFS 0x00b4 /* 1 byte */
+#define URTW_DIFS 0x00b5 /* 1 byte */
+#define URTW_SLOT 0x00b6 /* 1 byte */
+#define URTW_CW_CONF 0x00bc /* 1 byte */
+#define URTW_CW_CONF_PERPACKET_RETRY (0x2)
+#define URTW_CW_CONF_PERPACKET_CW (0x1)
+#define URTW_CW_VAL 0x00bd /* 1 byte */
+#define URTW_RATE_FALLBACK 0x00be /* 1 byte */
+#define URTW_TALLY_SEL 0x00fc /* 1 byte */
+#define URTW_ADDR_MAGIC2 0x00fe /* 2 byte */
+#define URTW_ADDR_MAGIC3 0x00ff /* 1 byte */
+
+/* for 8225 */
+#define URTW_8225_ADDR_0_MAGIC 0x0
+#define URTW_8225_ADDR_0_DATA_MAGIC1 (0x1b7)
+#define URTW_8225_ADDR_0_DATA_MAGIC2 (0x0b7)
+#define URTW_8225_ADDR_0_DATA_MAGIC3 (0x127)
+#define URTW_8225_ADDR_0_DATA_MAGIC4 (0x027)
+#define URTW_8225_ADDR_0_DATA_MAGIC5 (0x22f)
+#define URTW_8225_ADDR_0_DATA_MAGIC6 (0x2bf)
+#define URTW_8225_ADDR_1_MAGIC 0x1
+#define URTW_8225_ADDR_2_MAGIC 0x2
+#define URTW_8225_ADDR_2_DATA_MAGIC1 (0xc4d)
+#define URTW_8225_ADDR_2_DATA_MAGIC2 (0x44d)
+#define URTW_8225_ADDR_3_MAGIC 0x3
+#define URTW_8225_ADDR_3_DATA_MAGIC1 (0x2)
+#define URTW_8225_ADDR_5_MAGIC 0x5
+#define URTW_8225_ADDR_5_DATA_MAGIC1 (0x4)
+#define URTW_8225_ADDR_6_MAGIC 0x6
+#define URTW_8225_ADDR_6_DATA_MAGIC1 (0xe6)
+#define URTW_8225_ADDR_6_DATA_MAGIC2 (0x80)
+#define URTW_8225_ADDR_7_MAGIC 0x7
+#define URTW_8225_ADDR_8_MAGIC 0x8
+#define URTW_8225_ADDR_8_DATA_MAGIC1 (0x588)
+#define URTW_8225_ADDR_9_MAGIC 0x9
+#define URTW_8225_ADDR_9_DATA_MAGIC1 (0x700)
+#define URTW_8225_ADDR_C_MAGIC 0xc
+#define URTW_8225_ADDR_C_DATA_MAGIC1 (0x850)
+#define URTW_8225_ADDR_C_DATA_MAGIC2 (0x050)
+
+/* for EEPROM */
+#define URTW_EPROM_TXPW_BASE 0x05
+#define URTW_EPROM_RFCHIPID 0x06
+#define URTW_EPROM_RFCHIPID_RTL8225U (5)
+#define URTW_EPROM_MACADDR 0x07
+#define URTW_EPROM_TXPW0 0x16
+#define URTW_EPROM_TXPW2 0x1b
+#define URTW_EPROM_TXPW1 0x3d
+#define URTW_EPROM_SWREV 0x3f
+#define URTW_EPROM_CID_MASK (0xff)
+#define URTW_EPROM_CID_RSVD0 (0x00)
+#define URTW_EPROM_CID_RSVD1 (0xff)
+#define URTW_EPROM_CID_ALPHA0 (0x01)
+#define URTW_EPROM_CID_SERCOMM_PS (0x02)
+#define URTW_EPROM_CID_HW_LED (0x03)
+
+/* LED */
+#define URTW_CID_DEFAULT 0
+#define URTW_CID_8187_ALPHA0 1
+#define URTW_CID_8187_SERCOMM_PS 2
+#define URTW_CID_8187_HW_LED 3
+#define URTW_SW_LED_MODE0 0
+#define URTW_SW_LED_MODE1 1
+#define URTW_SW_LED_MODE2 2
+#define URTW_SW_LED_MODE3 3
+#define URTW_HW_LED 4
+#define URTW_LED_CTL_POWER_ON 0
+#define URTW_LED_CTL_LINK 2
+#define URTW_LED_CTL_TX 4
+#define URTW_LED_PIN_GPIO0 0
+#define URTW_LED_PIN_LED0 1
+#define URTW_LED_PIN_LED1 2
+#define URTW_LED_UNKNOWN 0
+#define URTW_LED_ON 1
+#define URTW_LED_OFF 2
+#define URTW_LED_BLINK_NORMAL 3
+#define URTW_LED_BLINK_SLOWLY 4
+#define URTW_LED_POWER_ON_BLINK 5
+#define URTW_LED_SCAN_BLINK 6
+#define URTW_LED_NO_LINK_BLINK 7
+#define URTW_LED_BLINK_CM3 8
+
+/* for extra area */
+#define URTW_EPROM_DISABLE 0
+#define URTW_EPROM_ENABLE 1
+#define URTW_EPROM_DELAY 10
+#define URTW_8187_GETREGS_REQ 5
+#define URTW_8187_SETREGS_REQ 5
+#define URTW_8225_RF_MAX_SENS 6
+#define URTW_8225_RF_DEF_SENS 4
+#define URTW_DEFAULT_RTS_RETRY 7
+#define URTW_DEFAULT_TX_RETRY 7
+#define URTW_DEFAULT_RTS_THRESHOLD 2342U
diff --git a/sys/dev/usb/if_urtwvar.h b/sys/dev/usb/if_urtwvar.h
new file mode 100644
index 0000000..77c09ef
--- /dev/null
+++ b/sys/dev/usb/if_urtwvar.h
@@ -0,0 +1,151 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2008 Weongyo Jeong <weongyo@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
+ * 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.
+ */
+
+/* XXX no definition at net80211? */
+#define URTW_MAX_CHANNELS 15
+
+struct urtw_data {
+ struct urtw_softc *sc;
+ usbd_xfer_handle xfer;
+ uint8_t *buf;
+ struct mbuf *m;
+ struct ieee80211_node *ni; /* NB: tx only */
+};
+
+/* XXX not correct.. */
+#define URTW_MIN_RXBUFSZ \
+ (sizeof(struct ieee80211_frame_min))
+
+#define URTW_RX_DATA_LIST_COUNT 1
+#define URTW_TX_DATA_LIST_COUNT 16
+#define URTW_RX_MAXSIZE 0x9c4
+#define URTW_TX_MAXSIZE 0x9c4
+
+struct urtw_rx_radiotap_header {
+ struct ieee80211_radiotap_header wr_ihdr;
+ uint8_t wr_flags;
+ uint16_t wr_chan_freq;
+ uint16_t wr_chan_flags;
+ int8_t wr_dbm_antsignal;
+} __packed;
+
+#define URTW_RX_RADIOTAP_PRESENT \
+ ((1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
+
+struct urtw_tx_radiotap_header {
+ struct ieee80211_radiotap_header wt_ihdr;
+ uint8_t wt_flags;
+ uint16_t wt_chan_freq;
+ uint16_t wt_chan_flags;
+} __packed;
+
+#define URTW_TX_RADIOTAP_PRESENT \
+ ((1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL))
+
+struct urtw_vap {
+ struct ieee80211vap vap;
+ int (*newstate)(struct ieee80211vap *,
+ enum ieee80211_state, int);
+};
+#define URTW_VAP(vap) ((struct urtw_vap *)(vap))
+
+struct urtw_softc {
+ struct ifnet *sc_ifp;
+ device_t sc_dev;
+ usbd_device_handle sc_udev;
+ usbd_interface_handle sc_iface;
+ struct mtx sc_mtx;
+
+ int sc_debug;
+ int sc_if_flags;
+ int sc_flags;
+#define URTW_INIT_ONCE (1 << 1)
+ struct usb_task sc_task;
+ struct usb_task sc_ctxtask;
+ int sc_ctxarg;
+#define URTW_SET_CHANNEL 1
+ enum ieee80211_state sc_state;
+ int sc_arg;
+ int (*sc_newstate)(struct ieee80211com *,
+ enum ieee80211_state, int);
+
+ int sc_epromtype;
+#define URTW_EEPROM_93C46 0
+#define URTW_EEPROM_93C56 1
+ uint8_t sc_crcmon;
+ uint8_t sc_bssid[IEEE80211_ADDR_LEN];
+
+ /* for RF */
+ usbd_status (*sc_rf_init)(struct urtw_softc *);
+ usbd_status (*sc_rf_set_chan)(struct urtw_softc *,
+ int);
+ usbd_status (*sc_rf_set_sens)(struct urtw_softc *,
+ int);
+ uint8_t sc_rfchip;
+ uint32_t sc_max_sens;
+ uint32_t sc_sens;
+ /* for LED */
+ struct callout sc_led_ch;
+ struct usb_task sc_ledtask;
+ uint8_t sc_psr;
+ uint8_t sc_strategy;
+#define URTW_LED_GPIO 1
+ uint8_t sc_gpio_ledon;
+ uint8_t sc_gpio_ledinprogress;
+ uint8_t sc_gpio_ledstate;
+ uint8_t sc_gpio_ledpin;
+ uint8_t sc_gpio_blinktime;
+ uint8_t sc_gpio_blinkstate;
+ /* RX/TX */
+ usbd_pipe_handle sc_rxpipe;
+ usbd_pipe_handle sc_txpipe_low;
+ usbd_pipe_handle sc_txpipe_normal;
+#define URTW_PRIORITY_LOW 0
+#define URTW_PRIORITY_NORMAL 1
+#define URTW_DATA_TIMEOUT 10000 /* 10 sec */
+ struct urtw_data sc_rxdata[URTW_RX_DATA_LIST_COUNT];
+ struct urtw_data sc_txdata[URTW_TX_DATA_LIST_COUNT];
+ uint32_t sc_tx_low_queued;
+ uint32_t sc_tx_normal_queued;
+ uint32_t sc_txidx;
+ uint8_t sc_rts_retry;
+ uint8_t sc_tx_retry;
+ uint8_t sc_preamble_mode;
+#define URTW_PREAMBLE_MODE_SHORT 1
+#define URTW_PREAMBLE_MODE_LONG 2
+ struct callout sc_watchdog_ch;
+ int sc_txtimer;
+ int sc_currate;
+ /* TX power */
+ uint8_t sc_txpwr_cck[URTW_MAX_CHANNELS];
+ uint8_t sc_txpwr_cck_base;
+ uint8_t sc_txpwr_ofdm[URTW_MAX_CHANNELS];
+ uint8_t sc_txpwr_ofdm_base;
+
+ struct urtw_rx_radiotap_header sc_rxtap;
+ int sc_rxtap_len;
+ struct urtw_tx_radiotap_header sc_txtap;
+ int sc_txtap_len;
+};
+
+#define URTW_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
+#define URTW_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
+#define URTW_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
diff --git a/sys/dev/usb/u3g.c b/sys/dev/usb/u3g.c
index 67722a9..366337b 100644
--- a/sys/dev/usb/u3g.c
+++ b/sys/dev/usb/u3g.c
@@ -108,6 +108,9 @@ static const struct u3g_speeds_s u3g_speeds[] = {
{7200000, 384000},
};
+#define U3GIBUFSIZE 1024
+#define U3GOBUFSIZE 1024
+
/*
* Various supported device vendors/products.
*/
@@ -296,10 +299,9 @@ u3g_attach(device_t self)
ucom->sc_iface = uaa->ifaces[i];
ucom->sc_bulkin_no = bulkin_no;
ucom->sc_bulkout_no = bulkout_no;
- // Allocate a buffer enough for 10ms worth of data
- ucom->sc_ibufsize = u3g_speeds[sc->sc_speed].ispeed/10/USB_FRAMES_PER_SECOND*10;
- ucom->sc_ibufsizepad = ucom->sc_ibufsize;
- ucom->sc_obufsize = u3g_speeds[sc->sc_speed].ospeed/10/USB_FRAMES_PER_SECOND*10;
+ ucom->sc_ibufsize = U3GIBUFSIZE;
+ ucom->sc_ibufsizepad = U3GIBUFSIZE;
+ ucom->sc_obufsize = U3GOBUFSIZE;
ucom->sc_opkthdrlen = 0;
ucom->sc_callback = &u3g_callback;
@@ -362,7 +364,6 @@ u3g_open(void *addr, int portno)
* anyway.
* Note: We abuse the fact that ucom sets the speed through
* ispeed/ospeed, not through ispeedwat/ospeedwat.
- * XXX Are the speeds correct?
*/
if (portno == 0) {
struct u3g_softc *sc = addr;
diff --git a/sys/dev/usb/uftdi.c b/sys/dev/usb/uftdi.c
index d701eed..c652977 100644
--- a/sys/dev/usb/uftdi.c
+++ b/sys/dev/usb/uftdi.c
@@ -186,6 +186,9 @@ uftdi_match(device_t self)
if (uaa->vendor == USB_VENDOR_MELCO &&
(uaa->product == USB_PRODUCT_MELCO_PCOPRS1))
return (UMATCH_VENDOR_PRODUCT);
+ if (uaa->vendor == USB_VENDOR_DRESDENELEKTRONIK &&
+ (uaa->product == USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD))
+ return (UMATCH_VENDOR_PRODUCT);
return (UMATCH_NONE);
}
@@ -316,6 +319,18 @@ uftdi_attach(device_t self)
}
break;
+ case USB_VENDOR_DRESDENELEKTRONIK:
+ switch( uaa->product ){
+ case USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD:
+ sc->sc_type = UFTDI_TYPE_8U232AM;
+ sc->sc_hdrlen = 0;
+ break;
+
+ default: /* Can't happen */
+ goto bad;
+ }
+ break;
+
default: /* Can't happen */
goto bad;
}
diff --git a/sys/dev/usb/uhci_pci.c b/sys/dev/usb/uhci_pci.c
index 65a932a..4ee19d6 100644
--- a/sys/dev/usb/uhci_pci.c
+++ b/sys/dev/usb/uhci_pci.c
@@ -389,6 +389,12 @@ uhci_pci_attach(device_t self)
break;
}
+ /*
+ * Quirk for Parallels Desktop 4.0.
+ */
+ if (pci_get_devid(self) == PCI_UHCI_DEVICEID_ICH6_A)
+ sc->sc_bus.usbrev = USBREV_2_0;
+
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
NULL, (driver_intr_t *) uhci_intr, sc, &sc->ih);
if (err) {
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 607c0be..375907f 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -151,6 +151,7 @@ vendor PLANTRONICS 0x047f Plantronics
vendor KYOCERA 0x0482 Kyocera Wireless Corp.
vendor STMICRO 0x0483 STMicroelectronics
vendor FOXCONN 0x0489 Foxconn
+vendor MEIZU 0x0492 Meizu Electronics
vendor YAMAHA 0x0499 YAMAHA
vendor COMPAQ 0x049f Compaq
vendor HITACHI 0x04a4 Hitachi
@@ -622,6 +623,7 @@ vendor QCOM 0x18e8 Qcom
vendor LINKSYS3 0x1915 Linksys
vendor QUALCOMMINC 0x19d2 Qualcomm, Incorporated
vendor STELERA 0x1a8d Stelera Wireless
+vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik
vendor DLINK 0x2001 D-Link
vendor PLANEX2 0x2019 Planex Communications
vendor ERICSSON 0x2282 Ericsson
@@ -808,6 +810,7 @@ product AKS USBHASP 0x0001 USB-HASP 0.06
/* Alcor Micro, Inc. products */
product ALCOR2 KBD_HUB 0x2802 Kbd Hub
+product ALCOR TRANSCEND 0x6387 Transcend JetFlash Drive
product ALCOR MA_KBD_HUB 0x9213 MacAlly Kbd Hub
product ALCOR AU9814 0x9215 AU9814 Hub
product ALCOR UMCR_9361 0x9361 USB Multimedia Card Reader
@@ -1167,6 +1170,9 @@ product DMI CFSM_RW 0xa109 CF/SM Reader/Writer
/* DrayTek products */
product DRAYTEK VIGOR550 0x0550 Vigor550
+/* dresden elektronik products */
+product DRESDENELEKTRONIK SENSORTERMINALBOARD 0x0001 SensorTerminalBoard
+
/* Dynastream Innovations */
product DYNASTREAM ANTDEVBOARD 0x1003 ANT dev board
@@ -1239,12 +1245,18 @@ product EPSON STYLUS_895 0x0602 Stylus Photo 895 Card Reader
product EPSON CX5400 0x0808 CX5400 scanner
product EPSON 3500 0x080e CX-3500/3600/3650 MFP
product EPSON RX425 0x080f Stylus Photo RX425 scanner
-product EPSON 4800 0x0819 CX4800 MP scanner
-product EPSON 4200 0x0820 CX4200 MP scanner
-product EPSON 5000 0x082b DX-50x0 MFP scanner
-product EPSON 6000 0x082e DX-60x0 MFP scanner
-product EPSON DX7400 0x0838 DX7400/CX7300 scanner
-product EPSON DX8400 0x0839 DX8400 scanner
+product EPSON DX3800 0x0818 CX3700/CX3800/DX38x0 MFP scanner
+product EPSON 4800 0x0819 CX4700/CX4800/DX48x0 MFP scanner
+product EPSON 4200 0x0820 CX4100/CX4200/DX4200 MFP scanner
+product EPSON 5000 0x082b CX4900/CX5000/DX50x0 MFP scanner
+product EPSON 6000 0x082e CX5900/CX6000/DX60x0 MFP scanner
+product EPSON DX4000 0x082f DX4000 MFP scanner
+product EPSON DX7400 0x0838 CX7300/CX7400/DX7400 MFP scanner
+product EPSON DX8400 0x0839 CX8300/CX8400/DX8400 MFP scanner
+product EPSON SX100 0x0841 SX100/NX100 MFP scanner
+product EPSON NX300 0x0848 NX300 MFP scanner
+product EPSON SX200 0x0849 SX200/SX205 MFP scanner
+product EPSON SX400 0x084a SX400/NX400/TX400 MFP scanner
/* e-TEK Labs products */
product ETEK 1COM 0x8007 Serial
@@ -1496,6 +1508,7 @@ product IOMEGA ZIP250 0x0030 Zip 250
/* Ituner networks products */
product ITUNERNET USBLCD2X20 0x0002 USB-LCD 2x20
+product ITUNERNET USBLCD4X20 0xc001 USB-LCD 4x20
/* Jablotron products */
product JABLOTRON PC60B 0x0001 PC-60B
@@ -1650,6 +1663,9 @@ product MCT DU_H3SP_USB232 0x0200 D-Link DU-H3SP USB BAY Hub
product MCT USB232 0x0210 USB-232 Interface
product MCT SITECOM_USB232 0x0230 Sitecom USB-232 Products
+/* Meizu Electronics */
+product MEIZU M6_SL 0x0140 MiniPlayer M6 (SL)
+
/* Melco, Inc products */
product MELCO LUATX1 0x0001 LUA-TX Ethernet
product MELCO LUATX5 0x0005 LUA-TX Ethernet
@@ -1665,6 +1681,7 @@ product MELCO PCOPRS1 0x00b3 PC-OP-RS1 RemoteStation
product MELCO SG54HP 0x00d8 WLI-U2-SG54HP
product MELCO G54HP 0x00d9 WLI-U2-G54HP
product MELCO KG54L 0x00da WLI-U2-KG54L
+product MELCO SG54HG 0x00f4 WLI-U2-SG54HG
/* Merlin products */
product MERLIN V620 0x1110 Merlin V620
@@ -1785,6 +1802,7 @@ product MSYSTEMS DISKONKEY2 0x0011 DiskOnKey
/* Myson products */
product MYSON HEDEN 0x8818 USB-IDE
+product MYSON STARREADER 0x9920 USB flash card adapter
/* National Semiconductor */
product NATIONAL BEARPAW1200 0x1000 BearPaw 1200
@@ -1815,6 +1833,7 @@ product NETGEAR FA120 0x1040 USB 2.0 Ethernet
product NETGEAR WG111V2_2 0x4240 PrismGT USB 2.0 WLAN
product NETGEAR WG111U 0x4300 WG111U
product NETGEAR WG111U_NF 0x4301 WG111U (no firmware)
+product NETGEAR WG111V2 0x6a00 WG111V2
product NETGEAR2 MA101 0x4100 MA101
product NETGEAR2 MA101B 0x4102 MA101 Rev B
product NETGEAR3 WG111T 0x4250 WG111T
@@ -2029,6 +2048,7 @@ product RALINK RT2573_2 0x9021 RT2501USB Wireless Adapter
/* ReakTek products */
/* Green House and CompUSA OEM this part */
product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet
+product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter
/* Ricoh products */
product RICOH VGPVCC2 0x1830 VGP-VCC2 Camera
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 8f0ce0f..a733bbf 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -237,8 +237,8 @@ usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
USBD_NO_TIMEOUT, cb);
ipipe->intrxfer = xfer;
ipipe->repeat = 1;
- err = usbd_transfer(xfer);
*pipe = ipipe;
+ err = usbd_transfer(xfer);
if (err != USBD_IN_PROGRESS && err)
goto bad2;
return (USBD_NORMAL_COMPLETION);
diff --git a/sys/dev/usb/uscanner.c b/sys/dev/usb/uscanner.c
index 1589bfd..bff3a48 100644
--- a/sys/dev/usb/uscanner.c
+++ b/sys/dev/usb/uscanner.c
@@ -90,6 +90,15 @@ struct uscan_info {
/* Table of scanners that may work with this driver. */
static const struct uscan_info uscanner_devs[] = {
+
+ /*
+ * These first two entries are duplicates of known-working units,
+ * so one can patch them to test support for newer devices
+ * without rebuilding the module.
+ */
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 }, /* duplicate */
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 }, /* duplicate */
+
/* Acer Peripherals */
{{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U }, 0 },
{{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_4300U }, 0 },
@@ -217,6 +226,12 @@ static const struct uscan_info uscanner_devs[] = {
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400 }, 0 },
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX7400 }, 0 },
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX8400 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3800 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX4000 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_NX300 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX200 }, 0 },
+ {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX400 }, 0 },
/* UMAX */
{{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
diff --git a/sys/dev/usb2/bluetooth/ng_ubt2.c b/sys/dev/usb2/bluetooth/ng_ubt2.c
index 1751312..7ebe86b 100644
--- a/sys/dev/usb2/bluetooth/ng_ubt2.c
+++ b/sys/dev/usb2/bluetooth/ng_ubt2.c
@@ -3,7 +3,7 @@
*/
/*-
- * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
+ * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,67 @@
* $FreeBSD$
*/
+/*
+ * NOTE: ng_ubt2 driver has a split personality. On one side it is
+ * a USB device driver and on the other it is a Netgraph node. This
+ * driver will *NOT* create traditional /dev/ enties, only Netgraph
+ * node.
+ *
+ * NOTE ON LOCKS USED: ng_ubt2 drives uses 2 locks (mutexes)
+ *
+ * 1) sc_if_mtx - lock for device's interface #0 and #1. This lock is used
+ * by USB for any USB request going over device's interface #0 and #1,
+ * i.e. interrupt, control, bulk and isoc. transfers.
+ *
+ * 2) sc_ng_mtx - this lock is used to protect shared (between USB, Netgraph
+ * and Taskqueue) data, such as outgoing mbuf queues, task flags and hook
+ * pointer. This lock *SHOULD NOT* be grabbed for a long time. In fact,
+ * think of it as a spin lock.
+ *
+ * NOTE ON LOCKING STRATEGY: ng_ubt2 driver operates in 3 different contexts.
+ *
+ * 1) USB context. This is where all the USB related stuff happens. All
+ * callbacks run in this context. All callbacks are called (by USB) with
+ * appropriate interface lock held. It is (generally) allowed to grab
+ * any additional locks.
+ *
+ * 2) Netgraph context. This is where all the Netgraph related stuff happens.
+ * Since we mark node as WRITER, the Netgraph node will be "locked" (from
+ * Netgraph point of view). Any variable that is only modified from the
+ * Netgraph context does not require any additonal locking. It is generally
+ * *NOT* allowed to grab *ANY* additional locks. Whatever you do, *DO NOT*
+ * grab any lock in the Netgraph context that could cause de-scheduling of
+ * the Netgraph thread for significant amount of time. In fact, the only
+ * lock that is allowed in the Netgraph context is the sc_ng_mtx lock.
+ * Also make sure that any code that is called from the Netgraph context
+ * follows the rule above.
+ *
+ * 3) Taskqueue context. This is where ubt_task runs. Since we are generally
+ * NOT allowed to grab any lock that could cause de-scheduling in the
+ * Netgraph context, and, USB requires us to grab interface lock before
+ * doing things with transfers, it is safer to transition from the Netgraph
+ * context to the Taskqueue context before we can call into USB subsystem.
+ *
+ * So, to put everything together, the rules are as follows.
+ * It is OK to call from the USB context or the Taskqueue context into
+ * the Netgraph context (i.e. call NG_SEND_xxx functions). In other words
+ * it is allowed to call into the Netgraph context with locks held.
+ * Is it *NOT* OK to call from the Netgraph context into the USB context,
+ * because USB requires us to grab interface locks, and, it is safer to
+ * avoid it. So, to make things safer we set task flags to indicate which
+ * actions we want to perform and schedule ubt_task which would run in the
+ * Taskqueue context.
+ * Is is OK to call from the Taskqueue context into the USB context,
+ * and, ubt_task does just that (i.e. grabs appropriate interface locks
+ * before calling into USB).
+ * Access to the outgoing queues, task flags and hook pointer is
+ * controlled by the sc_ng_mtx lock. It is an unavoidable evil. Again,
+ * sc_ng_mtx should really be a spin lock (and it is very likely to an
+ * equivalent of spin lock due to adaptive nature of freebsd mutexes).
+ * All USB callbacks accept softc pointer as a private data. USB ensures
+ * that this pointer is valid.
+ */
+
#include <dev/usb2/include/usb2_devid.h>
#include <dev/usb2/include/usb2_standard.h>
#include <dev/usb2/include/usb2_mfunc.h>
@@ -44,8 +105,11 @@
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/core/usb2_busdma.h>
+#include <dev/usb2/core/usb2_process.h>
+#include <dev/usb2/core/usb2_transfer.h>
#include <sys/mbuf.h>
+#include <sys/taskqueue.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
@@ -57,71 +121,58 @@
#include <dev/usb2/bluetooth/usb2_bluetooth.h>
#include <dev/usb2/bluetooth/ng_ubt2_var.h>
-/*
- * USB methods
- */
-
-static device_probe_t ubt_probe;
-static device_attach_t ubt_attach;
-static device_detach_t ubt_detach;
+static int ubt_modevent(module_t, int, void *);
+static device_probe_t ubt_probe;
+static device_attach_t ubt_attach;
+static device_detach_t ubt_detach;
-static devclass_t ubt_devclass;
-
-static device_method_t ubt_methods[] = {
- DEVMETHOD(device_probe, ubt_probe),
- DEVMETHOD(device_attach, ubt_attach),
- DEVMETHOD(device_detach, ubt_detach),
- {0, 0}
-};
-
-static driver_t ubt_driver = {
- .name = "ubt",
- .methods = ubt_methods,
- .size = sizeof(struct ubt_softc),
-};
+static void ubt_task_schedule(ubt_softc_p, int);
+static task_fn_t ubt_task;
-/*
- * Netgraph methods
- */
+#define ubt_xfer_start(sc, i) usb2_transfer_start((sc)->sc_xfer[(i)])
-static ng_constructor_t ng_ubt_constructor;
-static ng_shutdown_t ng_ubt_shutdown;
-static ng_newhook_t ng_ubt_newhook;
-static ng_connect_t ng_ubt_connect;
-static ng_disconnect_t ng_ubt_disconnect;
-static ng_rcvmsg_t ng_ubt_rcvmsg;
-static ng_rcvdata_t ng_ubt_rcvdata;
+/* Netgraph methods */
+static ng_constructor_t ng_ubt_constructor;
+static ng_shutdown_t ng_ubt_shutdown;
+static ng_newhook_t ng_ubt_newhook;
+static ng_connect_t ng_ubt_connect;
+static ng_disconnect_t ng_ubt_disconnect;
+static ng_rcvmsg_t ng_ubt_rcvmsg;
+static ng_rcvdata_t ng_ubt_rcvdata;
/* Queue length */
-static const struct ng_parse_struct_field ng_ubt_node_qlen_type_fields[] =
+static const struct ng_parse_struct_field ng_ubt_node_qlen_type_fields[] =
{
- {"queue", &ng_parse_int32_type,},
- {"qlen", &ng_parse_int32_type,},
- {NULL,}
+ { "queue", &ng_parse_int32_type, },
+ { "qlen", &ng_parse_int32_type, },
+ { NULL, }
};
-static const struct ng_parse_type ng_ubt_node_qlen_type = {
+static const struct ng_parse_type ng_ubt_node_qlen_type =
+{
&ng_parse_struct_type,
&ng_ubt_node_qlen_type_fields
};
/* Stat info */
-static const struct ng_parse_struct_field ng_ubt_node_stat_type_fields[] =
+static const struct ng_parse_struct_field ng_ubt_node_stat_type_fields[] =
{
- {"pckts_recv", &ng_parse_uint32_type,},
- {"bytes_recv", &ng_parse_uint32_type,},
- {"pckts_sent", &ng_parse_uint32_type,},
- {"bytes_sent", &ng_parse_uint32_type,},
- {"oerrors", &ng_parse_uint32_type,},
- {"ierrors", &ng_parse_uint32_type,},
- {NULL,}
+ { "pckts_recv", &ng_parse_uint32_type, },
+ { "bytes_recv", &ng_parse_uint32_type, },
+ { "pckts_sent", &ng_parse_uint32_type, },
+ { "bytes_sent", &ng_parse_uint32_type, },
+ { "oerrors", &ng_parse_uint32_type, },
+ { "ierrors", &ng_parse_uint32_type, },
+ { NULL, }
};
-static const struct ng_parse_type ng_ubt_node_stat_type = {
+static const struct ng_parse_type ng_ubt_node_stat_type =
+{
&ng_parse_struct_type,
&ng_ubt_node_stat_type_fields
};
/* Netgraph node command list */
-static const struct ng_cmdlist ng_ubt_cmdlist[] = {
+static const struct ng_cmdlist ng_ubt_cmdlist[] =
+{
{
NGM_UBT_COOKIE,
NGM_UBT_NODE_SET_DEBUG,
@@ -164,346 +215,260 @@ static const struct ng_cmdlist ng_ubt_cmdlist[] = {
NULL,
NULL
},
- {0,}
+ { 0, }
};
/* Netgraph node type */
-static struct ng_type typestruct = {
- .version = NG_ABI_VERSION,
- .name = NG_UBT_NODE_TYPE,
- .constructor = ng_ubt_constructor,
- .rcvmsg = ng_ubt_rcvmsg,
- .shutdown = ng_ubt_shutdown,
- .newhook = ng_ubt_newhook,
- .connect = ng_ubt_connect,
- .rcvdata = ng_ubt_rcvdata,
- .disconnect = ng_ubt_disconnect,
- .cmdlist = ng_ubt_cmdlist
+static struct ng_type typestruct =
+{
+ .version = NG_ABI_VERSION,
+ .name = NG_UBT_NODE_TYPE,
+ .constructor = ng_ubt_constructor,
+ .rcvmsg = ng_ubt_rcvmsg,
+ .shutdown = ng_ubt_shutdown,
+ .newhook = ng_ubt_newhook,
+ .connect = ng_ubt_connect,
+ .rcvdata = ng_ubt_rcvdata,
+ .disconnect = ng_ubt_disconnect,
+ .cmdlist = ng_ubt_cmdlist
};
-/* USB methods */
-
-static usb2_callback_t ubt_ctrl_write_callback;
-static usb2_callback_t ubt_intr_read_callback;
-static usb2_callback_t ubt_intr_read_clear_stall_callback;
-static usb2_callback_t ubt_bulk_read_callback;
-static usb2_callback_t ubt_bulk_read_clear_stall_callback;
-static usb2_callback_t ubt_bulk_write_callback;
-static usb2_callback_t ubt_bulk_write_clear_stall_callback;
-static usb2_callback_t ubt_isoc_read_callback;
-static usb2_callback_t ubt_isoc_write_callback;
-
-static int ubt_modevent(module_t, int, void *);
-static void ubt_intr_read_complete(node_p, hook_p, void *, int);
-static void ubt_bulk_read_complete(node_p, hook_p, void *, int);
-static void ubt_isoc_read_complete(node_p, hook_p, void *, int);
-
-/* USB config */
-static const struct usb2_config ubt_config_if_0[UBT_IF_0_N_TRANSFER] = {
-
- [0] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UBT_BULK_WRITE_BUFFER_SIZE,
- .mh.flags = {.pipe_bof = 1,},
- .mh.callback = &ubt_bulk_write_callback,
- },
-
- [1] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UBT_BULK_READ_BUFFER_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &ubt_bulk_read_callback,
- },
-
- [2] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0x110, /* bytes */
- .mh.callback = &ubt_intr_read_callback,
- },
-
- [3] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) + UBT_CTRL_BUFFER_SIZE),
- .mh.callback = &ubt_ctrl_write_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
+/****************************************************************************
+ ****************************************************************************
+ ** USB specific
+ ****************************************************************************
+ ****************************************************************************/
- [4] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &ubt_bulk_write_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
+/* USB methods */
+static usb2_callback_t ubt_ctrl_write_callback;
+static usb2_callback_t ubt_intr_read_callback;
+static usb2_callback_t ubt_bulk_read_callback;
+static usb2_callback_t ubt_bulk_write_callback;
+static usb2_callback_t ubt_isoc_read_callback;
+static usb2_callback_t ubt_isoc_write_callback;
- [5] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &ubt_bulk_read_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
+static int ubt_fwd_mbuf_up(ubt_softc_p, struct mbuf **);
+static int ubt_isoc_read_one_frame(struct usb2_xfer *, int);
- [6] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &ubt_intr_read_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-};
+/*
+ * USB config
+ *
+ * The following desribes usb transfers that could be submitted on USB device.
+ *
+ * Interface 0 on the USB device must present the following endpoints
+ * 1) Interrupt endpoint to receive HCI events
+ * 2) Bulk IN endpoint to receive ACL data
+ * 3) Bulk OUT endpoint to send ACL data
+ *
+ * Interface 1 on the USB device must present the following endpoints
+ * 1) Isochronous IN endpoint to receive SCO data
+ * 2) Isochronous OUT endpoint to send SCO data
+ */
-/* USB config */
-static const struct usb2_config
- ubt_config_if_1_full_speed[UBT_IF_1_N_TRANSFER] = {
-
- [0] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_read_callback,
+static const struct usb2_config ubt_config[UBT_N_TRANSFER] =
+{
+ /*
+ * Interface #0
+ */
+
+ /* Outgoing bulk transfer - ACL packets */
+ [UBT_IF_0_BULK_DT_WR] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .if_index = 0,
+ .mh.bufsize = UBT_BULK_WRITE_BUFFER_SIZE,
+ .mh.flags = { .pipe_bof = 1, .force_short_xfer = 1, },
+ .mh.callback = &ubt_bulk_write_callback,
},
-
- [1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_read_callback,
+ /* Incoming bulk transfer - ACL packets */
+ [UBT_IF_0_BULK_DT_RD] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 0,
+ .mh.bufsize = UBT_BULK_READ_BUFFER_SIZE,
+ .mh.flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
+ .mh.callback = &ubt_bulk_read_callback,
},
-
- [2] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_write_callback,
+ /* Incoming interrupt transfer - HCI events */
+ [UBT_IF_0_INTR_DT_RD] = {
+ .type = UE_INTERRUPT,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 0,
+ .mh.flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
+ .mh.bufsize = UBT_INTR_BUFFER_SIZE,
+ .mh.callback = &ubt_intr_read_callback,
},
-
- [3] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_write_callback,
+ /* Outgoing control transfer - HCI commands */
+ [UBT_IF_0_CTRL_DT_WR] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* control pipe */
+ .direction = UE_DIR_ANY,
+ .if_index = 0,
+ .mh.bufsize = UBT_CTRL_BUFFER_SIZE,
+ .mh.callback = &ubt_ctrl_write_callback,
+ .mh.timeout = 5000, /* 5 seconds */
},
-};
-/* USB config */
-static const struct usb2_config
- ubt_config_if_1_high_speed[UBT_IF_1_N_TRANSFER] = {
-
- [0] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES * 8,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_read_callback,
+ /*
+ * Interface #1
+ */
+
+ /* Incoming isochronous transfer #1 - SCO packets */
+ [UBT_IF_1_ISOC_DT_RD1] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 1,
+ .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .mh.frames = UBT_ISOC_NFRAMES,
+ .mh.flags = { .short_xfer_ok = 1, },
+ .mh.callback = &ubt_isoc_read_callback,
},
-
- [1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES * 8,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_read_callback,
+ /* Incoming isochronous transfer #2 - SCO packets */
+ [UBT_IF_1_ISOC_DT_RD2] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .if_index = 1,
+ .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .mh.frames = UBT_ISOC_NFRAMES,
+ .mh.flags = { .short_xfer_ok = 1, },
+ .mh.callback = &ubt_isoc_read_callback,
},
-
- [2] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES * 8,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_write_callback,
+ /* Outgoing isochronous transfer #1 - SCO packets */
+ [UBT_IF_1_ISOC_DT_WR1] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .if_index = 1,
+ .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .mh.frames = UBT_ISOC_NFRAMES,
+ .mh.flags = { .short_xfer_ok = 1, },
+ .mh.callback = &ubt_isoc_write_callback,
},
-
- [3] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES * 8,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ubt_isoc_write_callback,
+ /* Outgoing isochronous transfer #2 - SCO packets */
+ [UBT_IF_1_ISOC_DT_WR2] = {
+ .type = UE_ISOCHRONOUS,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .if_index = 1,
+ .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
+ .mh.frames = UBT_ISOC_NFRAMES,
+ .mh.flags = { .short_xfer_ok = 1, },
+ .mh.callback = &ubt_isoc_write_callback,
},
};
/*
- * Module
- */
-
-DRIVER_MODULE(ng_ubt, ushub, ubt_driver, ubt_devclass, ubt_modevent, 0);
-MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
-MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
-MODULE_DEPEND(ng_ubt, usb2_bluetooth, 1, 1, 1);
-MODULE_DEPEND(ng_ubt, usb2_core, 1, 1, 1);
-
-/****************************************************************************
- ****************************************************************************
- ** USB specific
- ****************************************************************************
- ****************************************************************************/
-
-/*
- * Load/Unload the driver module
- */
-
-static int
-ubt_modevent(module_t mod, int event, void *data)
-{
- int error;
-
- switch (event) {
- case MOD_LOAD:
- error = ng_newtype(&typestruct);
- if (error != 0) {
- printf("%s: Could not register "
- "Netgraph node type, error=%d\n",
- NG_UBT_NODE_TYPE, error);
- }
- break;
-
- case MOD_UNLOAD:
- error = ng_rmtype(&typestruct);
- break;
-
- default:
- error = EOPNOTSUPP;
- break;
- }
- return (error);
-} /* ubt_modevent */
-
-/*
* If for some reason device should not be attached then put
* VendorID/ProductID pair into the list below. The format is
* as follows:
*
- * { VENDOR_ID, PRODUCT_ID },
+ * { USB_VPI(VENDOR_ID, PRODUCT_ID, 0) },
*
* where VENDOR_ID and PRODUCT_ID are hex numbers.
*/
-static const struct usb2_device_id ubt_ignore_devs[] = {
+
+static const struct usb2_device_id ubt_ignore_devs[] =
+{
/* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */
- {USB_VPI(USB_VENDOR_AVM, 0x2200, 0)},
+ { USB_VPI(USB_VENDOR_AVM, 0x2200, 0) },
};
/* List of supported bluetooth devices */
-static const struct usb2_device_id ubt_devs[] = {
- /* Generic Bluetooth class devices. */
- {USB_IFACE_CLASS(UDCLASS_WIRELESS),
- USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
- USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH)},
+static const struct usb2_device_id ubt_devs[] =
+{
+ /* Generic Bluetooth class devices */
+ { USB_IFACE_CLASS(UDCLASS_WIRELESS),
+ USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
+ USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
/* AVM USB Bluetooth-Adapter BlueFritz! v2.0 */
- {USB_VPI(USB_VENDOR_AVM, 0x3800, 0)},
+ { USB_VPI(USB_VENDOR_AVM, 0x3800, 0) },
};
/*
- * Probe for a USB Bluetooth device
+ * Probe for a USB Bluetooth device.
+ * USB context.
*/
static int
ubt_probe(device_t dev)
{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
+ struct usb2_attach_arg *uaa = device_get_ivars(dev);
- if (uaa->usb2_mode != USB_MODE_HOST) {
+ if (uaa->usb2_mode != USB_MODE_HOST)
return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != 0) {
+
+ if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
- }
+
+ if (uaa->use_generic == 0)
+ return (ENXIO);
+
if (usb2_lookup_id_by_uaa(ubt_ignore_devs,
- sizeof(ubt_ignore_devs), uaa) == 0) {
+ sizeof(ubt_ignore_devs), uaa) == 0)
return (ENXIO);
- }
+
return (usb2_lookup_id_by_uaa(ubt_devs, sizeof(ubt_devs), uaa));
-}
+} /* ubt_probe */
/*
- * Attach the device
+ * Attach the device.
+ * USB context.
*/
static int
ubt_attach(device_t dev)
{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ubt_softc *sc = device_get_softc(dev);
- const struct usb2_config *isoc_setup;
- struct usb2_endpoint_descriptor *ed;
- uint16_t wMaxPacketSize;
- uint8_t alt_index;
- uint8_t iface_index;
- uint8_t i;
- uint8_t j;
+ struct usb2_attach_arg *uaa = device_get_ivars(dev);
+ struct ubt_softc *sc = device_get_softc(dev);
+ struct usb2_endpoint_descriptor *ed;
+ uint16_t wMaxPacketSize;
+ uint8_t alt_index, i, j;
+ uint8_t iface_index[2] = { 0, 1 };
device_set_usb2_desc(dev);
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
+ sc->sc_dev = dev;
+ sc->sc_debug = NG_UBT_WARN_LEVEL;
+
+ /*
+ * Create Netgraph node
+ */
+
+ if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
+ UBT_ALERT(sc, "could not create Netgraph node\n");
+ return (ENXIO);
+ }
+
+ /* Name Netgraph node */
+ if (ng_name_node(sc->sc_node, device_get_nameunit(dev)) != 0) {
+ UBT_ALERT(sc, "could not name Netgraph node\n");
+ NG_NODE_UNREF(sc->sc_node);
+ return (ENXIO);
+ }
+ NG_NODE_SET_PRIVATE(sc->sc_node, sc);
+ NG_NODE_FORCE_WRITER(sc->sc_node);
/*
* Initialize device softc structure
*/
- /* state */
- sc->sc_debug = NG_UBT_WARN_LEVEL;
- sc->sc_flags = 0;
- NG_UBT_STAT_RESET(sc->sc_stat);
+ /* initialize locks */
+ mtx_init(&sc->sc_ng_mtx, "ubt ng", NULL, MTX_DEF);
+ mtx_init(&sc->sc_if_mtx, "ubt if", NULL, MTX_DEF | MTX_RECURSE);
- /* control pipe */
+ /* initialize packet queues */
NG_BT_MBUFQ_INIT(&sc->sc_cmdq, UBT_DEFAULT_QLEN);
-
- /* bulk-out pipe */
NG_BT_MBUFQ_INIT(&sc->sc_aclq, UBT_DEFAULT_QLEN);
+ NG_BT_MBUFQ_INIT(&sc->sc_scoq, UBT_DEFAULT_QLEN);
- /* isoc-out pipe */
- NG_BT_MBUFQ_INIT(&sc->sc_scoq,
- (usb2_get_speed(uaa->device) == USB_SPEED_HIGH) ?
- (2 * UBT_ISOC_NFRAMES * 8) :
- (2 * UBT_ISOC_NFRAMES));
-
- /* isoc-in pipe */
- NG_BT_MBUFQ_INIT(&sc->sc_sciq,
- (usb2_get_speed(uaa->device) == USB_SPEED_HIGH) ?
- (2 * UBT_ISOC_NFRAMES * 8) :
- (2 * UBT_ISOC_NFRAMES));
-
- /* netgraph part */
- sc->sc_node = NULL;
- sc->sc_hook = NULL;
+ /* initialize glue task */
+ TASK_INIT(&sc->sc_task, 0, ubt_task, sc);
/*
* Configure Bluetooth USB device. Discover all required USB
@@ -524,793 +489,795 @@ ubt_attach(device_t dev)
*/
/*
- * Interface 0
- */
-
- mtx_init(&sc->sc_mtx, "ubt lock", NULL, MTX_DEF | MTX_RECURSE);
-
- iface_index = 0;
- if (usb2_transfer_setup
- (uaa->device, &iface_index, sc->sc_xfer_if_0, ubt_config_if_0,
- UBT_IF_0_N_TRANSFER, sc, &sc->sc_mtx)) {
- device_printf(dev, "Could not allocate transfers "
- "for interface 0!\n");
- goto detach;
- }
- /*
- * Interface 1
- * (search alternate settings, and find
- * the descriptor with the largest
- * wMaxPacketSize)
+ * For interface #1 search alternate settings, and find
+ * the descriptor with the largest wMaxPacketSize
*/
- isoc_setup =
- ((usb2_get_speed(uaa->device) == USB_SPEED_HIGH) ?
- ubt_config_if_1_high_speed :
- ubt_config_if_1_full_speed);
wMaxPacketSize = 0;
-
- /* search through all the descriptors looking for bidir mode */
-
- alt_index = 0 - 1;
+ alt_index = 0;
i = 0;
j = 0;
+
+ /* Search through all the descriptors looking for bidir mode */
while (1) {
uint16_t temp;
- ed = usb2_find_edesc(
- usb2_get_config_descriptor(uaa->device), 1, i, j);
+ ed = usb2_find_edesc(usb2_get_config_descriptor(uaa->device),
+ 1, i, j);
if (ed == NULL) {
- if (j == 0) {
- /* end of interfaces */
- break;
- } else {
+ if (j != 0) {
/* next interface */
j = 0;
- i++;
+ i ++;
continue;
}
+
+ break; /* end of interfaces */
}
+
temp = UGETW(ed->wMaxPacketSize);
if (temp > wMaxPacketSize) {
wMaxPacketSize = temp;
alt_index = i;
}
- j++;
- }
- if (usb2_set_alt_interface_index(uaa->device, 1, alt_index)) {
- device_printf(dev, "Could not set alternate "
- "setting %d for interface 1!\n", alt_index);
- goto detach;
+ j ++;
}
- iface_index = 1;
- if (usb2_transfer_setup
- (uaa->device, &iface_index, sc->sc_xfer_if_1,
- isoc_setup, UBT_IF_1_N_TRANSFER, sc, &sc->sc_mtx)) {
- device_printf(dev, "Could not allocate transfers "
- "for interface 1!\n");
- goto detach;
- }
- /* create Netgraph node */
- if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
- printf("%s: Could not create Netgraph node\n",
- sc->sc_name);
- sc->sc_node = NULL;
+ /* Set alt configuration on interface #1 only if we found it */
+ if (wMaxPacketSize > 0 &&
+ usb2_set_alt_interface_index(uaa->device, 1, alt_index)) {
+ UBT_ALERT(sc, "could not set alternate setting %d " \
+ "for interface 1!\n", alt_index);
goto detach;
}
- /* name node */
- if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
- printf("%s: Could not name Netgraph node\n",
- sc->sc_name);
- NG_NODE_UNREF(sc->sc_node);
- sc->sc_node = NULL;
+ /* Setup transfers for both interfaces */
+ if (usb2_transfer_setup(uaa->device, iface_index, sc->sc_xfer,
+ ubt_config, UBT_N_TRANSFER, sc, &sc->sc_if_mtx)) {
+ UBT_ALERT(sc, "could not allocate transfers\n");
goto detach;
}
- NG_NODE_SET_PRIVATE(sc->sc_node, sc);
- NG_NODE_FORCE_WRITER(sc->sc_node);
-
- /* claim all interfaces on the device */
- for (i = 1;; i++) {
-
- if (usb2_get_iface(uaa->device, i) == NULL) {
- break;
- }
+ /* Claim all interfaces on the device */
+ for (i = 1; usb2_get_iface(uaa->device, i) != NULL; i ++)
usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
- }
- return (0); /* success */
+ return (0); /* success */
detach:
ubt_detach(dev);
return (ENXIO);
-}
+} /* ubt_attach */
/*
- * Detach the device
+ * Detach the device.
+ * USB context.
*/
int
ubt_detach(device_t dev)
{
- struct ubt_softc *sc = device_get_softc(dev);
+ struct ubt_softc *sc = device_get_softc(dev);
+ node_p node = sc->sc_node;
- /* destroy Netgraph node */
-
- if (sc->sc_node != NULL) {
- NG_NODE_SET_PRIVATE(sc->sc_node, NULL);
- ng_rmnode_self(sc->sc_node);
+ /* Destroy Netgraph node */
+ if (node != NULL) {
sc->sc_node = NULL;
+ NG_NODE_REALLY_DIE(node);
+ ng_rmnode_self(node);
}
- /* free USB transfers, if any */
-
- usb2_transfer_unsetup(sc->sc_xfer_if_0, UBT_IF_0_N_TRANSFER);
-
- usb2_transfer_unsetup(sc->sc_xfer_if_1, UBT_IF_1_N_TRANSFER);
- mtx_destroy(&sc->sc_mtx);
+ /* Make sure ubt_task in gone */
+ taskqueue_drain(taskqueue_swi, &sc->sc_task);
- /* destroy queues */
+ /* Free USB transfers, if any */
+ usb2_transfer_unsetup(sc->sc_xfer, UBT_N_TRANSFER);
+ /* Destroy queues */
+ UBT_NG_LOCK(sc);
NG_BT_MBUFQ_DESTROY(&sc->sc_cmdq);
NG_BT_MBUFQ_DESTROY(&sc->sc_aclq);
NG_BT_MBUFQ_DESTROY(&sc->sc_scoq);
- NG_BT_MBUFQ_DESTROY(&sc->sc_sciq);
+ UBT_NG_UNLOCK(sc);
+
+ mtx_destroy(&sc->sc_if_mtx);
+ mtx_destroy(&sc->sc_ng_mtx);
return (0);
-}
+} /* ubt_detach */
+
+/*
+ * Called when outgoing control request (HCI command) has completed, i.e.
+ * HCI command was sent to the device.
+ * USB context.
+ */
static void
ubt_ctrl_write_callback(struct usb2_xfer *xfer)
{
- struct ubt_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- struct mbuf *m;
+ struct ubt_softc *sc = xfer->priv_sc;
+ struct usb2_device_request req;
+ struct mbuf *m;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-tr_transferred:
-
- if (xfer->error) {
- NG_UBT_STAT_OERROR(sc->sc_stat);
- } else {
- NG_UBT_STAT_BYTES_SENT(sc->sc_stat, xfer->actlen);
- NG_UBT_STAT_PCKTS_SENT(sc->sc_stat);
- }
+ UBT_INFO(sc, "sent %d bytes to control pipe\n", xfer->actlen);
+ UBT_STAT_BYTES_SENT(sc, xfer->actlen);
+ UBT_STAT_PCKTS_SENT(sc);
+ /* FALLTHROUGH */
case USB_ST_SETUP:
-
- /* get next mbuf, if any */
-
+send_next:
+ /* Get next command mbuf, if any */
+ UBT_NG_LOCK(sc);
NG_BT_MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
+ UBT_NG_UNLOCK(sc);
if (m == NULL) {
- NG_UBT_INFO(sc, "HCI command queue is empty\n");
- return;
- }
- /*
- * check HCI command frame size and
- * copy it to USB transfer buffer:
- */
-
- if (m->m_pkthdr.len > UBT_CTRL_BUFFER_SIZE) {
- panic("HCI command frame too big, size=%zd, len=%d\n",
- UBT_CTRL_BUFFER_SIZE, m->m_pkthdr.len);
+ UBT_INFO(sc, "HCI command queue is empty\n");
+ break; /* transfer complete */
}
- /* initialize a USB control request and then schedule it */
+ /* Initialize a USB control request and then schedule it */
bzero(&req, sizeof(req));
-
req.bmRequestType = UBT_HCI_REQUEST;
USETW(req.wLength, m->m_pkthdr.len);
- NG_UBT_INFO(sc, "Sending control request, bmRequestType=0x%02x, "
- "wLength=%d\n", req.bmRequestType, UGETW(req.wLength));
+ UBT_INFO(sc, "Sending control request, " \
+ "bmRequestType=0x%02x, wLength=%d\n",
+ req.bmRequestType, UGETW(req.wLength));
usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
usb2_m_copy_in(xfer->frbuffers + 1, 0, m, 0, m->m_pkthdr.len);
xfer->frlengths[0] = sizeof(req);
xfer->frlengths[1] = m->m_pkthdr.len;
- xfer->nframes = xfer->frlengths[1] ? 2 : 1;
+ xfer->nframes = 2;
NG_FREE_M(m);
usb2_start_hardware(xfer);
- return;
+ break;
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- /* ignore */
- return;
+ default: /* Error */
+ if (xfer->error != USB_ERR_CANCELLED) {
+ UBT_WARN(sc, "control transfer failed: %s\n",
+ usb2_errstr(xfer->error));
+
+ UBT_STAT_OERROR(sc);
+ goto send_next;
}
- goto tr_transferred;
+
+ /* transfer cancelled */
+ break;
}
-}
+} /* ubt_ctrl_write_callback */
+
+/*
+ * Called when incoming interrupt transfer (HCI event) has completed, i.e.
+ * HCI event was received from the device.
+ * USB context.
+ */
static void
ubt_intr_read_callback(struct usb2_xfer *xfer)
{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- uint32_t max_len;
- uint8_t *ptr;
+ struct ubt_softc *sc = xfer->priv_sc;
+ struct mbuf *m;
+ ng_hci_event_pkt_t *hdr;
+
+ m = NULL;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-
- /* allocate a new mbuf */
-
+ /* Allocate a new mbuf */
MGETHDR(m, M_DONTWAIT, MT_DATA);
-
if (m == NULL) {
- goto tr_setup;
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- MCLGET(m, M_DONTWAIT);
+ MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
- NG_FREE_M(m);
- goto tr_setup;
- }
- if (!(sc->sc_flags & UBT_HAVE_FRAME_TYPE)) {
- *mtod(m, uint8_t *)= NG_HCI_EVENT_PKT;
- m->m_pkthdr.len = m->m_len = 1;
- } else {
- m->m_pkthdr.len = m->m_len = 0;
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- max_len = (MCLBYTES - m->m_len);
-
- if (xfer->actlen > max_len) {
- xfer->actlen = max_len;
- }
- ptr = ((uint8_t *)(m->m_data)) + m->m_len;
+ /* Add HCI packet type */
+ *mtod(m, uint8_t *)= NG_HCI_EVENT_PKT;
+ m->m_pkthdr.len = m->m_len = 1;
- usb2_copy_out(xfer->frbuffers, 0, ptr, xfer->actlen);
+ if (xfer->actlen > MCLBYTES - 1)
+ xfer->actlen = MCLBYTES - 1;
+ usb2_copy_out(xfer->frbuffers, 0, mtod(m, uint8_t *) + 1,
+ xfer->actlen);
m->m_pkthdr.len += xfer->actlen;
m->m_len += xfer->actlen;
- NG_UBT_INFO(sc, "got %d bytes from interrupt "
- "pipe\n", xfer->actlen);
-
- sc->sc_intr_buffer = m;
-
- case USB_ST_SETUP:
-tr_setup:
-
- if (sc->sc_intr_buffer) {
- ng_send_fn(sc->sc_node, NULL, ubt_intr_read_complete, NULL, 0);
- return;
- }
- if (sc->sc_flags & UBT_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer_if_0[6]);
- return;
- }
- xfer->frlengths[0] = xfer->max_data_length;
+ UBT_INFO(sc, "got %d bytes from interrupt pipe\n",
+ xfer->actlen);
- usb2_start_hardware(xfer);
- return;
+ /* Validate packet and send it up the stack */
+ if (m->m_pkthdr.len < sizeof(*hdr)) {
+ UBT_INFO(sc, "HCI event packet is too short\n");
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= UBT_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer_if_0[6]);
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- return;
-
- }
-}
-
-static void
-ubt_intr_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_if_0[2];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UBT_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-ubt_intr_read_complete(node_p node, hook_p hook, void *arg1, int arg2)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
- struct mbuf *m;
- ng_hci_event_pkt_t *hdr;
- int error;
-
- if (sc == NULL) {
- return;
- }
- mtx_lock(&sc->sc_mtx);
-
- m = sc->sc_intr_buffer;
-
- if (m) {
-
- sc->sc_intr_buffer = NULL;
hdr = mtod(m, ng_hci_event_pkt_t *);
+ if (hdr->length != (m->m_pkthdr.len - sizeof(*hdr))) {
+ UBT_ERR(sc, "Invalid HCI event packet size, " \
+ "length=%d, pktlen=%d\n",
+ hdr->length, m->m_pkthdr.len);
- if ((sc->sc_hook == NULL) || NG_HOOK_NOT_VALID(sc->sc_hook)) {
- NG_UBT_INFO(sc, "No upstream hook\n");
- goto done;
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- NG_UBT_STAT_BYTES_RECV(sc->sc_stat, m->m_pkthdr.len);
- if (m->m_pkthdr.len < sizeof(*hdr)) {
- NG_UBT_INFO(sc, "Packet too short\n");
- goto done;
- }
- if (hdr->length == (m->m_pkthdr.len - sizeof(*hdr))) {
- NG_UBT_INFO(sc, "Got complete HCI event frame, "
- "pktlen=%d, length=%d\n",
- m->m_pkthdr.len, hdr->length);
+ UBT_INFO(sc, "got complete HCI event frame, pktlen=%d, " \
+ "length=%d\n", m->m_pkthdr.len, hdr->length);
- NG_UBT_STAT_PCKTS_RECV(sc->sc_stat);
+ UBT_STAT_PCKTS_RECV(sc);
+ UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
- NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
+ ubt_fwd_mbuf_up(sc, &m);
+ /* m == NULL at this point */
+ /* FALLTHROUGH */
- m = NULL;
+ case USB_ST_SETUP:
+submit_next:
+ NG_FREE_M(m); /* checks for m != NULL */
- if (error != 0) {
- NG_UBT_STAT_IERROR(sc->sc_stat);
- }
- } else {
- NG_UBT_ERR(sc, "Invalid HCI event frame size, "
- "length=%d, pktlen=%d\n",
- hdr->length, m->m_pkthdr.len);
+ xfer->frlengths[0] = xfer->max_data_length;
+ usb2_start_hardware(xfer);
+ break;
+
+ default: /* Error */
+ if (xfer->error != USB_ERR_CANCELLED) {
+ UBT_WARN(sc, "interrupt transfer failed: %s\n",
+ usb2_errstr(xfer->error));
- NG_UBT_STAT_IERROR(sc->sc_stat);
+ /* Try to clear stall first */
+ xfer->flags.stall_pipe = 1;
+ goto submit_next;
}
+ /* transfer cancelled */
+ break;
}
-done:
- if (m) {
- NG_FREE_M(m);
- }
- /* start USB transfer if not already started */
+} /* ubt_intr_read_callback */
- usb2_transfer_start(sc->sc_xfer_if_0[2]);
-
- mtx_unlock(&sc->sc_mtx);
-}
+/*
+ * Called when incoming bulk transfer (ACL packet) has completed, i.e.
+ * ACL packet was received from the device.
+ * USB context.
+ */
static void
ubt_bulk_read_callback(struct usb2_xfer *xfer)
{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- uint32_t max_len;
- uint8_t *ptr;
+ struct ubt_softc *sc = xfer->priv_sc;
+ struct mbuf *m;
+ ng_hci_acldata_pkt_t *hdr;
+ uint16_t len;
+
+ m = NULL;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-
- /* allocate new mbuf */
-
+ /* Allocate new mbuf */
MGETHDR(m, M_DONTWAIT, MT_DATA);
-
if (m == NULL) {
- goto tr_setup;
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- MCLGET(m, M_DONTWAIT);
+ MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
- NG_FREE_M(m);
- goto tr_setup;
- }
- if (!(sc->sc_flags & UBT_HAVE_FRAME_TYPE)) {
- *mtod(m, uint8_t *)= NG_HCI_ACL_DATA_PKT;
- m->m_pkthdr.len = m->m_len = 1;
- } else {
- m->m_pkthdr.len = m->m_len = 0;
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- max_len = (MCLBYTES - m->m_len);
-
- if (xfer->actlen > max_len) {
- xfer->actlen = max_len;
- }
- ptr = ((uint8_t *)(m->m_data)) + m->m_len;
+ /* Add HCI packet type */
+ *mtod(m, uint8_t *)= NG_HCI_ACL_DATA_PKT;
+ m->m_pkthdr.len = m->m_len = 1;
- usb2_copy_out(xfer->frbuffers, 0, ptr, xfer->actlen);
+ if (xfer->actlen > MCLBYTES - 1)
+ xfer->actlen = MCLBYTES - 1;
+ usb2_copy_out(xfer->frbuffers, 0, mtod(m, uint8_t *) + 1,
+ xfer->actlen);
m->m_pkthdr.len += xfer->actlen;
m->m_len += xfer->actlen;
- NG_UBT_INFO(sc, "got %d bytes from bulk-in "
- "pipe\n", xfer->actlen);
+ UBT_INFO(sc, "got %d bytes from bulk-in pipe\n",
+ xfer->actlen);
- sc->sc_bulk_in_buffer = m;
-
- case USB_ST_SETUP:
-tr_setup:
- if (sc->sc_bulk_in_buffer) {
- ng_send_fn(sc->sc_node, NULL, ubt_bulk_read_complete, NULL, 0);
- return;
- }
- if (sc->sc_flags & UBT_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer_if_0[5]);
- return;
- }
- xfer->frlengths[0] = xfer->max_data_length;
-
- usb2_start_hardware(xfer);
- return;
+ /* Validate packet and send it up the stack */
+ if (m->m_pkthdr.len < sizeof(*hdr)) {
+ UBT_INFO(sc, "HCI ACL packet is too short\n");
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= UBT_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer_if_0[5]);
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- return;
-
- }
-}
-
-static void
-ubt_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_if_0[1];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UBT_FLAG_READ_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-ubt_bulk_read_complete(node_p node, hook_p hook, void *arg1, int arg2)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
- struct mbuf *m;
- ng_hci_acldata_pkt_t *hdr;
- uint16_t len;
- int error;
-
- if (sc == NULL) {
- return;
- }
- mtx_lock(&sc->sc_mtx);
-
- m = sc->sc_bulk_in_buffer;
-
- if (m) {
-
- sc->sc_bulk_in_buffer = NULL;
hdr = mtod(m, ng_hci_acldata_pkt_t *);
+ len = le16toh(hdr->length);
+ if (len != (m->m_pkthdr.len - sizeof(*hdr))) {
+ UBT_ERR(sc, "Invalid ACL packet size, length=%d, " \
+ "pktlen=%d\n", len, m->m_pkthdr.len);
- if (sc->sc_hook == NULL || NG_HOOK_NOT_VALID(sc->sc_hook)) {
- NG_UBT_INFO(sc, "No upstream hook\n");
- goto done;
+ UBT_STAT_IERROR(sc);
+ goto submit_next;
}
- NG_UBT_STAT_BYTES_RECV(sc->sc_stat, m->m_pkthdr.len);
- if (m->m_pkthdr.len < sizeof(*hdr)) {
- NG_UBT_INFO(sc, "Packet too short\n");
- goto done;
- }
- len = le16toh(hdr->length);
+ UBT_INFO(sc, "got complete ACL data packet, pktlen=%d, " \
+ "length=%d\n", m->m_pkthdr.len, len);
- if (len == (m->m_pkthdr.len - sizeof(*hdr))) {
- NG_UBT_INFO(sc, "Got complete ACL data frame, "
- "pktlen=%d, length=%d\n",
- m->m_pkthdr.len, len);
+ UBT_STAT_PCKTS_RECV(sc);
+ UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
- NG_UBT_STAT_PCKTS_RECV(sc->sc_stat);
+ ubt_fwd_mbuf_up(sc, &m);
+ /* m == NULL at this point */
+ /* FALLTHOUGH */
- NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
+ case USB_ST_SETUP:
+submit_next:
+ NG_FREE_M(m); /* checks for m != NULL */
- m = NULL;
+ xfer->frlengths[0] = xfer->max_data_length;
+ usb2_start_hardware(xfer);
+ break;
- if (error != 0) {
- NG_UBT_STAT_IERROR(sc->sc_stat);
- }
- } else {
- NG_UBT_ERR(sc, "Invalid ACL frame size, "
- "length=%d, pktlen=%d\n",
- len, m->m_pkthdr.len);
+ default: /* Error */
+ if (xfer->error != USB_ERR_CANCELLED) {
+ UBT_WARN(sc, "bulk-in transfer failed: %s\n",
+ usb2_errstr(xfer->error));
- NG_UBT_STAT_IERROR(sc->sc_stat);
+ /* Try to clear stall first */
+ xfer->flags.stall_pipe = 1;
+ goto submit_next;
}
+ /* transfer cancelled */
+ break;
}
-done:
- if (m) {
- NG_FREE_M(m);
- }
- /* start USB transfer if not already started */
-
- usb2_transfer_start(sc->sc_xfer_if_0[1]);
+} /* ubt_bulk_read_callback */
- mtx_unlock(&sc->sc_mtx);
-}
+/*
+ * Called when outgoing bulk transfer (ACL packet) has completed, i.e.
+ * ACL packet was sent to the device.
+ * USB context.
+ */
static void
ubt_bulk_write_callback(struct usb2_xfer *xfer)
{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
+ struct ubt_softc *sc = xfer->priv_sc;
+ struct mbuf *m;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
- NG_UBT_INFO(sc, "sent %d bytes to bulk-out "
- "pipe\n", xfer->actlen);
- NG_UBT_STAT_BYTES_SENT(sc->sc_stat, xfer->actlen);
- NG_UBT_STAT_PCKTS_SENT(sc->sc_stat);
+ UBT_INFO(sc, "sent %d bytes to bulk-out pipe\n", xfer->actlen);
+ UBT_STAT_BYTES_SENT(sc, xfer->actlen);
+ UBT_STAT_PCKTS_SENT(sc);
+ /* FALLTHROUGH */
case USB_ST_SETUP:
- if (sc->sc_flags & UBT_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer_if_0[4]);
- return;
- }
- /* get next mbuf, if any */
-
+send_next:
+ /* Get next mbuf, if any */
+ UBT_NG_LOCK(sc);
NG_BT_MBUFQ_DEQUEUE(&sc->sc_aclq, m);
+ UBT_NG_UNLOCK(sc);
if (m == NULL) {
- NG_UBT_INFO(sc, "ACL data queue is empty\n");
- return;
+ UBT_INFO(sc, "ACL data queue is empty\n");
+ break; /* transfer completed */
}
+
/*
- * check ACL data frame size and
- * copy it back to a linear USB
- * transfer buffer:
+ * Copy ACL data frame back to a linear USB transfer buffer
+ * and schedule transfer
*/
- if (m->m_pkthdr.len > UBT_BULK_WRITE_BUFFER_SIZE) {
- panic("ACL data frame too big, size=%d, len=%d\n",
- UBT_BULK_WRITE_BUFFER_SIZE,
- m->m_pkthdr.len);
- }
usb2_m_copy_in(xfer->frbuffers, 0, m, 0, m->m_pkthdr.len);
-
- NG_UBT_INFO(sc, "bulk-out transfer has been started, "
- "len=%d\n", m->m_pkthdr.len);
-
xfer->frlengths[0] = m->m_pkthdr.len;
+ UBT_INFO(sc, "bulk-out transfer has been started, len=%d\n",
+ m->m_pkthdr.len);
+
NG_FREE_M(m);
usb2_start_hardware(xfer);
- return;
+ break;
- default: /* Error */
+ default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
+ UBT_WARN(sc, "bulk-out transfer failed: %s\n",
+ usb2_errstr(xfer->error));
- NG_UBT_WARN(sc, "bulk-out transfer failed: %s\n",
- usb2_errstr(xfer->error));
-
- NG_UBT_STAT_OERROR(sc->sc_stat);
+ UBT_STAT_OERROR(sc);
/* try to clear stall first */
- sc->sc_flags |= UBT_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer_if_0[4]);
+ xfer->flags.stall_pipe = 1;
+ goto send_next;
}
- return;
-
+ /* transfer cancelled */
+ break;
}
-}
+} /* ubt_bulk_write_callback */
-static void
-ubt_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_if_0[0];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UBT_FLAG_WRITE_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
+/*
+ * Called when incoming isoc transfer (SCO packet) has completed, i.e.
+ * SCO packet was received from the device.
+ * USB context.
+ */
static void
ubt_isoc_read_callback(struct usb2_xfer *xfer)
{
- struct ubt_softc *sc = xfer->priv_sc;
- ng_hci_scodata_pkt_t hdr;
- struct mbuf *m;
- uint8_t *ptr;
- uint32_t max_len;
- uint32_t n;
- uint32_t offset;
+ struct ubt_softc *sc = xfer->priv_sc;
+ int n;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-tr_transferred:
- offset = 0;
+ for (n = 0; n < xfer->nframes; n ++)
+ if (ubt_isoc_read_one_frame(xfer, n) < 0)
+ break;
+ /* FALLTHROUGH */
- for (n = 0; n < xfer->nframes; n++) {
+ case USB_ST_SETUP:
+read_next:
+ for (n = 0; n < xfer->nframes; n ++)
+ xfer->frlengths[n] = xfer->max_frame_size;
- if (xfer->frlengths[n] >= sizeof(hdr)) {
+ usb2_start_hardware(xfer);
+ break;
- usb2_copy_out(xfer->frbuffers, offset,
- &hdr, sizeof(hdr));
+ default: /* Error */
+ if (xfer->error != USB_ERR_CANCELLED) {
+ UBT_STAT_IERROR(sc);
+ goto read_next;
+ }
- if (hdr.length == (xfer->frlengths[n] - sizeof(hdr))) {
+ /* transfer cancelled */
+ break;
+ }
+} /* ubt_isoc_read_callback */
- NG_UBT_INFO(sc, "got complete SCO data "
- "frame, length=%d\n", hdr.length);
+/*
+ * Helper function. Called from ubt_isoc_read_callback() to read
+ * SCO data from one frame.
+ * USB context.
+ */
- if (!NG_BT_MBUFQ_FULL(&sc->sc_sciq)) {
+static int
+ubt_isoc_read_one_frame(struct usb2_xfer *xfer, int frame_no)
+{
+ struct ubt_softc *sc = xfer->priv_sc;
+ struct mbuf *m;
+ int len, want, got;
- /* allocate a new mbuf */
+ /* Get existing SCO reassembly buffer */
+ m = sc->sc_isoc_in_buffer;
+ sc->sc_isoc_in_buffer = NULL;
- MGETHDR(m, M_DONTWAIT, MT_DATA);
+ /* While we have data in the frame */
+ while ((len = xfer->frlengths[frame_no]) > 0) {
+ if (m == NULL) {
+ /* Start new reassembly buffer */
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ UBT_STAT_IERROR(sc);
+ return (-1); /* XXX out of sync! */
+ }
- if (m == NULL) {
- goto tr_setup;
- }
- MCLGET(m, M_DONTWAIT);
+ MCLGET(m, M_DONTWAIT);
+ if (!(m->m_flags & M_EXT)) {
+ UBT_STAT_IERROR(sc);
+ NG_FREE_M(m);
+ return (-1); /* XXX out of sync! */
+ }
- if (!(m->m_flags & M_EXT)) {
- NG_FREE_M(m);
- goto tr_setup;
- }
- /*
- * fix SCO data frame header
- * if required
- */
+ /* Expect SCO header */
+ *mtod(m, uint8_t *) = NG_HCI_SCO_DATA_PKT;
+ m->m_pkthdr.len = m->m_len = got = 1;
+ want = sizeof(ng_hci_scodata_pkt_t);
+ } else {
+ /*
+ * Check if we have SCO header and if so
+ * adjust amount of data we want
+ */
+ got = m->m_pkthdr.len;
+ want = sizeof(ng_hci_scodata_pkt_t);
+
+ if (got >= want)
+ want += mtod(m, ng_hci_scodata_pkt_t *)->length;
+ }
- if (!(sc->sc_flags & UBT_HAVE_FRAME_TYPE)) {
- *mtod(m, uint8_t *)= NG_HCI_SCO_DATA_PKT;
- m->m_pkthdr.len = m->m_len = 1;
- } else {
- m->m_pkthdr.len = m->m_len = 0;
- }
+ /* Append frame data to the SCO reassembly buffer */
+ if (got + len > want)
+ len = want - got;
- max_len = (MCLBYTES - m->m_len);
+ usb2_copy_out(xfer->frbuffers, frame_no * xfer->max_frame_size,
+ mtod(m, uint8_t *) + m->m_pkthdr.len, len);
- if (xfer->frlengths[n] > max_len) {
- xfer->frlengths[n] = max_len;
- }
- ptr = ((uint8_t *)(m->m_data)) + m->m_len;
+ m->m_pkthdr.len += len;
+ m->m_len += len;
+ xfer->frlengths[frame_no] -= len;
- usb2_copy_out
- (xfer->frbuffers, offset,
- ptr, xfer->frlengths[n]);
+ /* Check if we got everything we wanted, if not - continue */
+ if (got != want)
+ continue;
- m->m_pkthdr.len += xfer->frlengths[n];
- m->m_len += xfer->frlengths[n];
+ /* If we got here then we got complete SCO frame */
+ UBT_INFO(sc, "got complete SCO data frame, pktlen=%d, " \
+ "length=%d\n", m->m_pkthdr.len,
+ mtod(m, ng_hci_scodata_pkt_t *)->length);
- NG_BT_MBUFQ_ENQUEUE(&sc->sc_sciq, m);
- }
- }
- }
- offset += xfer->max_frame_size;
- }
+ UBT_STAT_PCKTS_RECV(sc);
+ UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
+
+ ubt_fwd_mbuf_up(sc, &m);
+ /* m == NULL at this point */
+ }
+
+ /* Put SCO reassembly buffer back */
+ sc->sc_isoc_in_buffer = m;
+
+ return (0);
+} /* ubt_isoc_read_one_frame */
+
+/*
+ * Called when outgoing isoc transfer (SCO packet) has completed, i.e.
+ * SCO packet was sent to the device.
+ * USB context.
+ */
+
+static void
+ubt_isoc_write_callback(struct usb2_xfer *xfer)
+{
+ struct ubt_softc *sc = xfer->priv_sc;
+ struct mbuf *m;
+ int n, space, offset;
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ UBT_INFO(sc, "sent %d bytes to isoc-out pipe\n", xfer->actlen);
+ UBT_STAT_BYTES_SENT(sc, xfer->actlen);
+ UBT_STAT_PCKTS_SENT(sc);
+ /* FALLTHROUGH */
case USB_ST_SETUP:
-tr_setup:
+send_next:
+ offset = 0;
+ space = xfer->max_frame_size * xfer->nframes;
+ m = NULL;
+
+ while (space > 0) {
+ if (m == NULL) {
+ UBT_NG_LOCK(sc);
+ NG_BT_MBUFQ_DEQUEUE(&sc->sc_scoq, m);
+ UBT_NG_UNLOCK(sc);
+
+ if (m == NULL)
+ break;
+ }
+
+ n = min(space, m->m_pkthdr.len);
+ if (n > 0) {
+ usb2_m_copy_in(xfer->frbuffers, offset, m,0, n);
+ m_adj(m, n);
+
+ offset += n;
+ space -= n;
+ }
- if (NG_BT_MBUFQ_LEN(&sc->sc_sciq) > 0) {
- ng_send_fn(sc->sc_node, NULL, ubt_isoc_read_complete, NULL, 0);
+ if (m->m_pkthdr.len == 0)
+ NG_FREE_M(m); /* sets m = NULL */
}
- for (n = 0; n < xfer->nframes; n++) {
- xfer->frlengths[n] = xfer->max_frame_size;
+
+ /* Put whatever is left from mbuf back on queue */
+ if (m != NULL) {
+ UBT_NG_LOCK(sc);
+ NG_BT_MBUFQ_PREPEND(&sc->sc_scoq, m);
+ UBT_NG_UNLOCK(sc);
+ }
+
+ /*
+ * Calculate sizes for isoc frames.
+ * Note that offset could be 0 at this point (i.e. we have
+ * nothing to send). That is fine, as we have isoc. transfers
+ * going in both directions all the time. In this case it
+ * would be just empty isoc. transfer.
+ */
+
+ for (n = 0; n < xfer->nframes; n ++) {
+ xfer->frlengths[n] = min(offset, xfer->max_frame_size);
+ offset -= xfer->frlengths[n];
}
usb2_start_hardware(xfer);
- return;
+ break;
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- /* ignore */
- return;
+ default: /* Error */
+ if (xfer->error != USB_ERR_CANCELLED) {
+ UBT_STAT_OERROR(sc);
+ goto send_next;
}
- goto tr_transferred;
+
+ /* transfer cancelled */
+ break;
}
}
-static void
-ubt_isoc_read_complete(node_p node, hook_p hook, void *arg1, int arg2)
+/*
+ * Utility function to forward provided mbuf upstream (i.e. up the stack).
+ * Modifies value of the mbuf pointer (sets it to NULL).
+ * Save to call from any context.
+ */
+
+static int
+ubt_fwd_mbuf_up(ubt_softc_p sc, struct mbuf **m)
{
- ubt_softc_p sc = NG_NODE_PRIVATE(node);
- struct mbuf *m;
- int error;
+ hook_p hook;
+ int error;
- if (sc == NULL) {
- return;
+ /*
+ * Close the race with Netgraph hook newhook/disconnect methods.
+ * Save the hook pointer atomically. Two cases are possible:
+ *
+ * 1) The hook pointer is NULL. It means disconnect method got
+ * there first. In this case we are done.
+ *
+ * 2) The hook pointer is not NULL. It means that hook pointer
+ * could be either in valid or invalid (i.e. in the process
+ * of disconnect) state. In any case grab an extra reference
+ * to protect the hook pointer.
+ *
+ * It is ok to pass hook in invalid state to NG_SEND_DATA_ONLY() as
+ * it checks for it. Drop extra reference after NG_SEND_DATA_ONLY().
+ */
+
+ UBT_NG_LOCK(sc);
+ if ((hook = sc->sc_hook) != NULL)
+ NG_HOOK_REF(hook);
+ UBT_NG_UNLOCK(sc);
+
+ if (hook == NULL) {
+ NG_FREE_M(*m);
+ return (ENETDOWN);
}
- mtx_lock(&sc->sc_mtx);
- while (1) {
+ NG_SEND_DATA_ONLY(error, hook, *m);
+ NG_HOOK_UNREF(hook);
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_sciq, m);
+ if (error != 0)
+ UBT_STAT_IERROR(sc);
- if (m == NULL) {
- break;
- }
- if (sc->sc_hook == NULL || NG_HOOK_NOT_VALID(sc->sc_hook)) {
- NG_UBT_INFO(sc, "No upstream hook\n");
- goto done;
- }
- NG_UBT_INFO(sc, "Got complete SCO data frame, "
- "pktlen=%d bytes\n", m->m_pkthdr.len);
+ return (error);
+} /* ubt_fwd_mbuf_up */
+
+/****************************************************************************
+ ****************************************************************************
+ ** Glue
+ ****************************************************************************
+ ****************************************************************************/
- NG_UBT_STAT_PCKTS_RECV(sc->sc_stat);
- NG_UBT_STAT_BYTES_RECV(sc->sc_stat, m->m_pkthdr.len);
+/*
+ * Schedule glue task. Should be called with sc_ng_mtx held.
+ * Netgraph context.
+ */
- NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
+static void
+ubt_task_schedule(ubt_softc_p sc, int action)
+{
+ mtx_assert(&sc->sc_ng_mtx, MA_OWNED);
- m = NULL;
+ /*
+ * Try to handle corner case when "start all" and "stop all"
+ * actions can both be set before task is executed.
+ *
+ * The rules are
+ *
+ * sc_task_flags action new sc_task_flags
+ * ------------------------------------------------------
+ * 0 start start
+ * 0 stop stop
+ * start start start
+ * start stop stop
+ * stop start stop|start
+ * stop stop stop
+ * stop|start start stop|start
+ * stop|start stop stop
+ */
- if (error) {
- NG_UBT_STAT_IERROR(sc->sc_stat);
- }
-done:
- if (m) {
- NG_FREE_M(m);
- }
+ if (action != 0) {
+ if ((action & UBT_FLAG_T_STOP_ALL) != 0)
+ sc->sc_task_flags &= ~UBT_FLAG_T_START_ALL;
+
+ sc->sc_task_flags |= action;
}
- mtx_unlock(&sc->sc_mtx);
-}
+ if (sc->sc_task_flags & UBT_FLAG_T_PENDING)
+ return;
+
+ if (taskqueue_enqueue(taskqueue_swi, &sc->sc_task) == 0) {
+ sc->sc_task_flags |= UBT_FLAG_T_PENDING;
+ return;
+ }
+
+ /* XXX: i think this should never happen */
+} /* ubt_task_schedule */
+
+/*
+ * Glue task. Examines sc_task_flags and does things depending on it.
+ * Taskqueue context.
+ */
static void
-ubt_isoc_write_callback(struct usb2_xfer *xfer)
+ubt_task(void *context, int pending)
{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- uint32_t n;
- uint32_t len;
- uint32_t offset;
+ ubt_softc_p sc = context;
+ int task_flags, i;
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- if (xfer->error) {
- NG_UBT_STAT_OERROR(sc->sc_stat);
- } else {
- NG_UBT_STAT_BYTES_SENT(sc->sc_stat, xfer->actlen);
- NG_UBT_STAT_PCKTS_SENT(sc->sc_stat);
- }
+ UBT_NG_LOCK(sc);
+ task_flags = sc->sc_task_flags;
+ sc->sc_task_flags = 0;
+ UBT_NG_UNLOCK(sc);
- case USB_ST_SETUP:
- offset = 0;
+ /*
+ * Stop all USB transfers synchronously.
+ * Stop interface #0 and #1 transfers at the same time and in the
+ * same loop. usb2_transfer_drain() will do appropriate locking.
+ */
- for (n = 0; n < xfer->nframes; n++) {
+ if (task_flags & UBT_FLAG_T_STOP_ALL)
+ for (i = 0; i < UBT_N_TRANSFER; i ++)
+ usb2_transfer_drain(sc->sc_xfer[i]);
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_scoq, m);
+ /* Start incoming interrupt and bulk, and all isoc. USB transfers */
+ if (task_flags & UBT_FLAG_T_START_ALL) {
+ /*
+ * Interface #0
+ */
- if (m) {
- len = min(xfer->max_frame_size, m->m_pkthdr.len);
+ mtx_lock(&sc->sc_if_mtx);
- usb2_m_copy_in(xfer->frbuffers, offset, m, 0, len);
+ ubt_xfer_start(sc, UBT_IF_0_INTR_DT_RD);
+ ubt_xfer_start(sc, UBT_IF_0_BULK_DT_RD);
- NG_FREE_M(m);
+ /*
+ * Interface #1
+ * Start both read and write isoc. transfers by default.
+ * Get them going all the time even if we have nothing
+ * to send to avoid any delays.
+ */
- xfer->frlengths[n] = len;
- offset += len;
- } else {
- xfer->frlengths[n] = 0;
- }
- }
+ ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_RD1);
+ ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_RD2);
+ ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_WR1);
+ ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_WR2);
- usb2_start_hardware(xfer);
- return;
+ mtx_unlock(&sc->sc_if_mtx);
+ }
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- /* ignore */
- return;
- }
- goto tr_transferred;
+ /* Start outgoing control transfer */
+ if (task_flags & UBT_FLAG_T_START_CTRL) {
+ mtx_lock(&sc->sc_if_mtx);
+ ubt_xfer_start(sc, UBT_IF_0_CTRL_DT_WR);
+ mtx_unlock(&sc->sc_if_mtx);
}
-}
+
+ /* Start outgoing bulk transfer */
+ if (task_flags & UBT_FLAG_T_START_BULK) {
+ mtx_lock(&sc->sc_if_mtx);
+ ubt_xfer_start(sc, UBT_IF_0_BULK_DT_WR);
+ mtx_unlock(&sc->sc_if_mtx);
+ }
+} /* ubt_task */
/****************************************************************************
****************************************************************************
@@ -1319,206 +1286,127 @@ tr_transferred:
****************************************************************************/
/*
- * Netgraph node constructor.
- * Do not allow to create node of this type:
+ * Netgraph node constructor. Do not allow to create node of this type.
+ * Netgraph context.
*/
static int
ng_ubt_constructor(node_p node)
{
return (EINVAL);
-}
+} /* ng_ubt_constructor */
/*
- * Netgraph node destructor.
- * Destroy node only when device has been detached:
+ * Netgraph node destructor. Destroy node only when device has been detached.
+ * Netgraph context.
*/
static int
ng_ubt_shutdown(node_p node)
{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
-
- /* Let old node go */
- NG_NODE_SET_PRIVATE(node, NULL);
- NG_NODE_UNREF(node);
-
- if (sc == NULL) {
- goto done;
- }
- mtx_lock(&sc->sc_mtx);
-
- /* Create Netgraph node */
- if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
- printf("%s: Could not create Netgraph node\n",
- sc->sc_name);
- sc->sc_node = NULL;
- goto done;
- }
- /* Name node */
- if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
- printf("%s: Could not name Netgraph node\n",
- sc->sc_name);
- NG_NODE_UNREF(sc->sc_node);
- sc->sc_node = NULL;
- goto done;
- }
- NG_NODE_SET_PRIVATE(sc->sc_node, sc);
- NG_NODE_FORCE_WRITER(sc->sc_node);
+ if (node->nd_flags & NGF_REALLY_DIE) {
+ /*
+ * We came here because the USB device is being
+ * detached, so stop being persistant.
+ */
+ NG_NODE_SET_PRIVATE(node, NULL);
+ NG_NODE_UNREF(node);
+ } else
+ NG_NODE_REVIVE(node); /* tell ng_rmnode we are persisant */
-done:
- if (sc) {
- mtx_unlock(&sc->sc_mtx);
- }
return (0);
-}
+} /* ng_ubt_shutdown */
/*
- * Create new hook.
- * There can only be one.
+ * Create new hook. There can only be one.
+ * Netgraph context.
*/
static int
ng_ubt_newhook(node_p node, hook_p hook, char const *name)
{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
- int error = 0;
+ struct ubt_softc *sc = NG_NODE_PRIVATE(node);
- if (strcmp(name, NG_UBT_HOOK) != 0) {
+ if (strcmp(name, NG_UBT_HOOK) != 0)
return (EINVAL);
- }
- mtx_lock(&sc->sc_mtx);
+ UBT_NG_LOCK(sc);
if (sc->sc_hook != NULL) {
- error = EISCONN;
- } else {
- sc->sc_hook = hook;
+ UBT_NG_UNLOCK(sc);
+
+ return (EISCONN);
}
- mtx_unlock(&sc->sc_mtx);
+ sc->sc_hook = hook;
+ UBT_NG_UNLOCK(sc);
- return (error);
-}
+ return (0);
+} /* ng_ubt_newhook */
/*
- * Connect hook.
- * Start incoming USB transfers
+ * Connect hook. Start incoming USB transfers.
+ * Netgraph context.
*/
static int
ng_ubt_connect(hook_p hook)
{
- struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+ struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
- mtx_lock(&sc->sc_mtx);
-
- sc->sc_flags |= (UBT_FLAG_READ_STALL |
- UBT_FLAG_WRITE_STALL |
- UBT_FLAG_INTR_STALL);
-
- /* start intr transfer */
- usb2_transfer_start(sc->sc_xfer_if_0[2]);
-
- /* start bulk-in transfer */
- usb2_transfer_start(sc->sc_xfer_if_0[1]);
-
- /* start bulk-out transfer */
- usb2_transfer_start(sc->sc_xfer_if_0[0]);
-
- /* start control-out transfer */
- usb2_transfer_start(sc->sc_xfer_if_0[3]);
-#if 0
- XXX can enable this XXX
-
- /* start isoc-in transfer */
- usb2_transfer_start(sc->sc_xfer_if_1[0]);
-
- usb2_transfer_start(sc->sc_xfer_if_1[1]);
-
- /* start isoc-out transfer */
- usb2_transfer_start(sc->sc_xfer_if_1[2]);
- usb2_transfer_start(sc->sc_xfer_if_1[3]);
-#endif
-
- mtx_unlock(&sc->sc_mtx);
+ UBT_NG_LOCK(sc);
+ ubt_task_schedule(sc, UBT_FLAG_T_START_ALL);
+ UBT_NG_UNLOCK(sc);
return (0);
-}
+} /* ng_ubt_connect */
/*
- * Disconnect hook
+ * Disconnect hook.
+ * Netgraph context.
*/
static int
ng_ubt_disconnect(hook_p hook)
{
- struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- int error = 0;
+ struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- if (sc != NULL) {
+ UBT_NG_LOCK(sc);
- mtx_lock(&sc->sc_mtx);
-
- if (hook != sc->sc_hook) {
- error = EINVAL;
- } else {
-
- /* stop intr transfer */
- usb2_transfer_stop(sc->sc_xfer_if_0[2]);
- usb2_transfer_stop(sc->sc_xfer_if_0[6]);
-
- /* stop bulk-in transfer */
- usb2_transfer_stop(sc->sc_xfer_if_0[1]);
- usb2_transfer_stop(sc->sc_xfer_if_0[5]);
-
- /* stop bulk-out transfer */
- usb2_transfer_stop(sc->sc_xfer_if_0[0]);
- usb2_transfer_stop(sc->sc_xfer_if_0[4]);
-
- /* stop control transfer */
- usb2_transfer_stop(sc->sc_xfer_if_0[3]);
+ if (hook != sc->sc_hook) {
+ UBT_NG_UNLOCK(sc);
- /* stop isoc-in transfer */
- usb2_transfer_stop(sc->sc_xfer_if_1[0]);
- usb2_transfer_stop(sc->sc_xfer_if_1[1]);
+ return (EINVAL);
+ }
- /* stop isoc-out transfer */
- usb2_transfer_stop(sc->sc_xfer_if_1[2]);
- usb2_transfer_stop(sc->sc_xfer_if_1[3]);
+ sc->sc_hook = NULL;
- /* cleanup queues */
- NG_BT_MBUFQ_DRAIN(&sc->sc_cmdq);
- NG_BT_MBUFQ_DRAIN(&sc->sc_aclq);
- NG_BT_MBUFQ_DRAIN(&sc->sc_scoq);
- NG_BT_MBUFQ_DRAIN(&sc->sc_sciq);
+ /* Kick off task to stop all USB xfers */
+ ubt_task_schedule(sc, UBT_FLAG_T_STOP_ALL);
- sc->sc_hook = NULL;
- }
+ /* Drain queues */
+ NG_BT_MBUFQ_DRAIN(&sc->sc_cmdq);
+ NG_BT_MBUFQ_DRAIN(&sc->sc_aclq);
+ NG_BT_MBUFQ_DRAIN(&sc->sc_scoq);
- mtx_unlock(&sc->sc_mtx);
- }
- return (error);
-}
+ UBT_NG_UNLOCK(sc);
+ return (0);
+} /* ng_ubt_disconnect */
+
/*
- * Process control message
+ * Process control message.
+ * Netgraph context.
*/
static int
ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
- struct ng_mesg *msg = NULL, *rsp = NULL;
- struct ng_bt_mbufq *q = NULL;
- int error = 0, queue, qlen;
-
- if (sc == NULL) {
- NG_FREE_ITEM(item);
- return (EHOSTDOWN);
- }
- mtx_lock(&sc->sc_mtx);
+ struct ubt_softc *sc = NG_NODE_PRIVATE(node);
+ struct ng_mesg *msg, *rsp = NULL;
+ struct ng_bt_mbufq *q;
+ int error = 0, queue, qlen;
NGI_GET_MSG(item, msg);
@@ -1527,25 +1415,27 @@ ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
switch (msg->header.cmd) {
case NGM_TEXT_STATUS:
NG_MKRESPONSE(rsp, msg, NG_TEXTRESPONSE, M_NOWAIT);
- if (rsp == NULL)
+ if (rsp == NULL) {
error = ENOMEM;
- else
- snprintf(rsp->data, NG_TEXTRESPONSE,
- "Hook: %s\n" \
- "Flags: %#x\n" \
- "Debug: %d\n" \
- "CMD queue: [have:%d,max:%d]\n" \
- "ACL queue: [have:%d,max:%d]\n" \
- "SCO queue: [have:%d,max:%d]",
- (sc->sc_hook != NULL) ? NG_UBT_HOOK : "",
- sc->sc_flags,
- sc->sc_debug,
- NG_BT_MBUFQ_LEN(&sc->sc_cmdq),
- sc->sc_cmdq.maxlen,
- NG_BT_MBUFQ_LEN(&sc->sc_aclq),
- sc->sc_aclq.maxlen,
- NG_BT_MBUFQ_LEN(&sc->sc_scoq),
- sc->sc_scoq.maxlen);
+ break;
+ }
+
+ snprintf(rsp->data, NG_TEXTRESPONSE,
+ "Hook: %s\n" \
+ "Task flags: %#x\n" \
+ "Debug: %d\n" \
+ "CMD queue: [have:%d,max:%d]\n" \
+ "ACL queue: [have:%d,max:%d]\n" \
+ "SCO queue: [have:%d,max:%d]",
+ (sc->sc_hook != NULL) ? NG_UBT_HOOK : "",
+ sc->sc_task_flags,
+ sc->sc_debug,
+ sc->sc_cmdq.len,
+ sc->sc_cmdq.maxlen,
+ sc->sc_aclq.len,
+ sc->sc_aclq.maxlen,
+ sc->sc_scoq.len,
+ sc->sc_scoq.maxlen);
break;
default:
@@ -1557,59 +1447,54 @@ ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
case NGM_UBT_COOKIE:
switch (msg->header.cmd) {
case NGM_UBT_NODE_SET_DEBUG:
- if (msg->header.arglen != sizeof(ng_ubt_node_debug_ep))
+ if (msg->header.arglen != sizeof(ng_ubt_node_debug_ep)){
error = EMSGSIZE;
- else
- sc->sc_debug =
- *((ng_ubt_node_debug_ep *) (msg->data));
+ break;
+ }
+
+ sc->sc_debug = *((ng_ubt_node_debug_ep *) (msg->data));
break;
case NGM_UBT_NODE_GET_DEBUG:
NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_debug_ep),
M_NOWAIT);
- if (rsp == NULL)
+ if (rsp == NULL) {
error = ENOMEM;
- else
- *((ng_ubt_node_debug_ep *) (rsp->data)) =
- sc->sc_debug;
+ break;
+ }
+
+ *((ng_ubt_node_debug_ep *) (rsp->data)) = sc->sc_debug;
break;
case NGM_UBT_NODE_SET_QLEN:
- if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep))
+ if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep)) {
error = EMSGSIZE;
- else {
- queue = ((ng_ubt_node_qlen_ep *)
- (msg->data))->queue;
- qlen = ((ng_ubt_node_qlen_ep *)
- (msg->data))->qlen;
-
- if (qlen <= 0) {
- error = EINVAL;
- break;
- }
- switch (queue) {
- case NGM_UBT_NODE_QUEUE_CMD:
- q = &sc->sc_cmdq;
- break;
+ break;
+ }
- case NGM_UBT_NODE_QUEUE_ACL:
- q = &sc->sc_aclq;
- break;
+ queue = ((ng_ubt_node_qlen_ep *) (msg->data))->queue;
+ qlen = ((ng_ubt_node_qlen_ep *) (msg->data))->qlen;
- case NGM_UBT_NODE_QUEUE_SCO:
- q = &sc->sc_scoq;
- break;
+ switch (queue) {
+ case NGM_UBT_NODE_QUEUE_CMD:
+ q = &sc->sc_cmdq;
+ break;
- default:
- q = NULL;
- error = EINVAL;
- break;
- }
+ case NGM_UBT_NODE_QUEUE_ACL:
+ q = &sc->sc_aclq;
+ break;
- if (q != NULL) {
- q->maxlen = qlen;
- }
+ case NGM_UBT_NODE_QUEUE_SCO:
+ q = &sc->sc_scoq;
+ break;
+
+ default:
+ error = EINVAL;
+ goto done;
+ /* NOT REACHED */
}
+
+ q->maxlen = qlen;
break;
case NGM_UBT_NODE_GET_QLEN:
@@ -1617,7 +1502,9 @@ ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
error = EMSGSIZE;
break;
}
+
queue = ((ng_ubt_node_qlen_ep *) (msg->data))->queue;
+
switch (queue) {
case NGM_UBT_NODE_QUEUE_CMD:
q = &sc->sc_cmdq;
@@ -1632,39 +1519,36 @@ ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
break;
default:
- q = NULL;
error = EINVAL;
- break;
+ goto done;
+ /* NOT REACHED */
}
- if (q != NULL) {
- NG_MKRESPONSE(rsp, msg,
- sizeof(ng_ubt_node_qlen_ep), M_NOWAIT);
- if (rsp == NULL) {
- error = ENOMEM;
- break;
- }
- ((ng_ubt_node_qlen_ep *) (rsp->data))->queue =
- queue;
- ((ng_ubt_node_qlen_ep *) (rsp->data))->qlen =
- q->maxlen;
+ NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_qlen_ep),
+ M_NOWAIT);
+ if (rsp == NULL) {
+ error = ENOMEM;
+ break;
}
+
+ ((ng_ubt_node_qlen_ep *) (rsp->data))->queue = queue;
+ ((ng_ubt_node_qlen_ep *) (rsp->data))->qlen = q->maxlen;
break;
case NGM_UBT_NODE_GET_STAT:
NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_stat_ep),
M_NOWAIT);
- if (rsp == NULL)
+ if (rsp == NULL) {
error = ENOMEM;
- else {
- bcopy(&sc->sc_stat, rsp->data,
- sizeof(ng_ubt_node_stat_ep));
+ break;
}
+
+ bcopy(&sc->sc_stat, rsp->data,
+ sizeof(ng_ubt_node_stat_ep));
break;
case NGM_UBT_NODE_RESET_STAT:
-
- NG_UBT_STAT_RESET(sc->sc_stat);
+ UBT_STAT_RESET(sc);
break;
default:
@@ -1677,90 +1561,160 @@ ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
error = EINVAL;
break;
}
-
+done:
NG_RESPOND_MSG(error, node, item, rsp);
NG_FREE_MSG(msg);
- mtx_unlock(&sc->sc_mtx);
-
return (error);
-}
+} /* ng_ubt_rcvmsg */
/*
- * Process data
+ * Process data.
+ * Netgraph context.
*/
static int
ng_ubt_rcvdata(hook_p hook, item_p item)
{
- struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- struct mbuf *m;
- struct ng_bt_mbufq *q;
- struct usb2_xfer *xfer;
- int error = 0;
-
- if (sc == NULL) {
- error = EHOSTDOWN;
- goto done;
- }
- mtx_lock(&sc->sc_mtx);
+ struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+ struct mbuf *m;
+ struct ng_bt_mbufq *q;
+ int action, error = 0;
if (hook != sc->sc_hook) {
error = EINVAL;
goto done;
}
- /* deatch mbuf and get HCI frame type */
+
+ /* Deatch mbuf and get HCI frame type */
NGI_GET_M(item, m);
- /* process HCI frame */
+ /*
+ * Minimal size of the HCI frame is 4 bytes: 1 byte frame type,
+ * 2 bytes connection handle and at least 1 byte of length.
+ * Panic on data frame that has size smaller than 4 bytes (it
+ * should not happen)
+ */
+
+ if (m->m_pkthdr.len < 4)
+ panic("HCI frame size is too small! pktlen=%d\n",
+ m->m_pkthdr.len);
+
+ /* Process HCI frame */
switch (*mtod(m, uint8_t *)) { /* XXX call m_pullup ? */
case NG_HCI_CMD_PKT:
- xfer = sc->sc_xfer_if_0[3];
+ if (m->m_pkthdr.len - 1 > UBT_CTRL_BUFFER_SIZE)
+ panic("HCI command frame size is too big! " \
+ "buffer size=%zd, packet len=%d\n",
+ UBT_CTRL_BUFFER_SIZE, m->m_pkthdr.len);
+
q = &sc->sc_cmdq;
+ action = UBT_FLAG_T_START_CTRL;
break;
case NG_HCI_ACL_DATA_PKT:
- xfer = sc->sc_xfer_if_0[0];
+ if (m->m_pkthdr.len - 1 > UBT_BULK_WRITE_BUFFER_SIZE)
+ panic("ACL data frame size is too big! " \
+ "buffer size=%d, packet len=%d\n",
+ UBT_BULK_WRITE_BUFFER_SIZE, m->m_pkthdr.len);
+
q = &sc->sc_aclq;
+ action = UBT_FLAG_T_START_BULK;
break;
case NG_HCI_SCO_DATA_PKT:
- xfer = NULL;
q = &sc->sc_scoq;
+ action = 0;
break;
default:
- NG_UBT_ERR(sc, "Dropping unsupported HCI frame, "
- "type=0x%02x, pktlen=%d\n",
- *mtod(m, uint8_t *),
- m->m_pkthdr.len);
+ UBT_ERR(sc, "Dropping unsupported HCI frame, type=0x%02x, " \
+ "pktlen=%d\n", *mtod(m, uint8_t *), m->m_pkthdr.len);
NG_FREE_M(m);
error = EINVAL;
goto done;
+ /* NOT REACHED */
}
- /* loose frame type, if required */
- if (!(sc->sc_flags & UBT_NEED_FRAME_TYPE)) {
- m_adj(m, sizeof(uint8_t));
- }
+ UBT_NG_LOCK(sc);
if (NG_BT_MBUFQ_FULL(q)) {
- NG_UBT_ERR(sc, "Dropping HCI frame 0x%02x, len=%d. "
- "Queue full\n", *mtod(m, uint8_t *),
- m->m_pkthdr.len);
+ NG_BT_MBUFQ_DROP(q);
+ UBT_NG_UNLOCK(sc);
+
+ UBT_ERR(sc, "Dropping HCI frame 0x%02x, len=%d. Queue full\n",
+ *mtod(m, uint8_t *), m->m_pkthdr.len);
+
NG_FREE_M(m);
} else {
+ /* Loose HCI packet type, enqueue mbuf and kick off task */
+ m_adj(m, sizeof(uint8_t));
NG_BT_MBUFQ_ENQUEUE(q, m);
- }
-
- if (xfer) {
- usb2_transfer_start(xfer);
+ ubt_task_schedule(sc, action);
+ UBT_NG_UNLOCK(sc);
}
done:
NG_FREE_ITEM(item);
- if (sc) {
- mtx_unlock(&sc->sc_mtx);
+ return (error);
+} /* ng_ubt_rcvdata */
+
+/****************************************************************************
+ ****************************************************************************
+ ** Module
+ ****************************************************************************
+ ****************************************************************************/
+
+/*
+ * Load/Unload the driver module
+ */
+
+static int
+ubt_modevent(module_t mod, int event, void *data)
+{
+ int error;
+
+ switch (event) {
+ case MOD_LOAD:
+ error = ng_newtype(&typestruct);
+ if (error != 0)
+ printf("%s: Could not register Netgraph node type, " \
+ "error=%d\n", NG_UBT_NODE_TYPE, error);
+ break;
+
+ case MOD_UNLOAD:
+ error = ng_rmtype(&typestruct);
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
}
+
return (error);
-}
+} /* ubt_modevent */
+
+static devclass_t ubt_devclass;
+
+static device_method_t ubt_methods[] =
+{
+ DEVMETHOD(device_probe, ubt_probe),
+ DEVMETHOD(device_attach, ubt_attach),
+ DEVMETHOD(device_detach, ubt_detach),
+ { 0, 0 }
+};
+
+static driver_t ubt_driver =
+{
+ .name = "ubt",
+ .methods = ubt_methods,
+ .size = sizeof(struct ubt_softc),
+};
+
+DRIVER_MODULE(ng_ubt, ushub, ubt_driver, ubt_devclass, ubt_modevent, 0);
+MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
+MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
+MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
+MODULE_DEPEND(ng_ubt, usb2_bluetooth, 1, 1, 1);
+MODULE_DEPEND(ng_ubt, usb2_core, 1, 1, 1);
+
diff --git a/sys/dev/usb2/bluetooth/ng_ubt2_var.h b/sys/dev/usb2/bluetooth/ng_ubt2_var.h
index 8fecc41..721e2f1 100644
--- a/sys/dev/usb2/bluetooth/ng_ubt2_var.h
+++ b/sys/dev/usb2/bluetooth/ng_ubt2_var.h
@@ -3,7 +3,7 @@
*/
/*-
- * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
+ * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,95 +32,100 @@
*/
#ifndef _NG_UBT_VAR_H_
-#define _NG_UBT_VAR_H_
-
-/* pullup wrapper */
-#define NG_UBT_M_PULLUP(m, s) \
- do { \
- if ((m)->m_len < (s)) \
- (m) = m_pullup((m), (s)); \
- if ((m) == NULL) { \
- NG_UBT_ALERT("%s: %s - m_pullup(%d) failed\n", \
- __func__, sc->sc_name, (s)); \
- } \
- } while (0)
+#define _NG_UBT_VAR_H_ 1
/* Debug printf's */
-#define NG_UBT_DEBUG(level, sc, fmt, ...) do { \
- if ((sc)->sc_debug >= (level)) { \
- printf("%s:%s:%d: " fmt, (sc)->sc_name, \
- __FUNCTION__, __LINE__,## __VA_ARGS__); \
- } \
+#define UBT_DEBUG(level, sc, fmt, ...) \
+do { \
+ if ((sc)->sc_debug >= (level)) \
+ device_printf((sc)->sc_dev, "%s:%d: " fmt, \
+ __FUNCTION__, __LINE__,## __VA_ARGS__); \
} while (0)
-#define NG_UBT_ALERT(...) NG_UBT_DEBUG(NG_UBT_ALERT_LEVEL, __VA_ARGS__)
-#define NG_UBT_ERR(...) NG_UBT_DEBUG(NG_UBT_ERR_LEVEL, __VA_ARGS__)
-#define NG_UBT_WARN(...) NG_UBT_DEBUG(NG_UBT_WARN_LEVEL, __VA_ARGS__)
-#define NG_UBT_INFO(...) NG_UBT_DEBUG(NG_UBT_INFO_LEVEL, __VA_ARGS__)
+#define UBT_ALERT(...) UBT_DEBUG(NG_UBT_ALERT_LEVEL, __VA_ARGS__)
+#define UBT_ERR(...) UBT_DEBUG(NG_UBT_ERR_LEVEL, __VA_ARGS__)
+#define UBT_WARN(...) UBT_DEBUG(NG_UBT_WARN_LEVEL, __VA_ARGS__)
+#define UBT_INFO(...) UBT_DEBUG(NG_UBT_INFO_LEVEL, __VA_ARGS__)
+
+#define UBT_NG_LOCK(sc) mtx_lock(&(sc)->sc_ng_mtx)
+#define UBT_NG_UNLOCK(sc) mtx_unlock(&(sc)->sc_ng_mtx)
/* Bluetooth USB control request type */
#define UBT_HCI_REQUEST 0x20
-#define UBT_DEFAULT_QLEN 12
+#define UBT_DEFAULT_QLEN 64
+#define UBT_ISOC_NFRAMES 32 /* should be factor of 8 */
/* Bluetooth USB defines */
-#define UBT_IF_0_N_TRANSFER 7 /* units */
-#define UBT_IF_1_N_TRANSFER 4 /* units */
-#define UBT_ISOC_NFRAMES 25 /* units */
+enum {
+ /* Interface #0 transfers */
+ UBT_IF_0_BULK_DT_WR = 0,
+ UBT_IF_0_BULK_DT_RD,
+ UBT_IF_0_INTR_DT_RD,
+ UBT_IF_0_CTRL_DT_WR,
+
+ /* Interface #1 transfers */
+ UBT_IF_1_ISOC_DT_RD1,
+ UBT_IF_1_ISOC_DT_RD2,
+ UBT_IF_1_ISOC_DT_WR1,
+ UBT_IF_1_ISOC_DT_WR2,
+
+ UBT_N_TRANSFER, /* total number of transfers */
+};
/* USB device softc structure */
struct ubt_softc {
+ device_t sc_dev; /* for debug printf */
+
/* State */
- ng_ubt_node_debug_ep sc_debug; /* debug level */
- uint32_t sc_flags; /* device flags */
-#define UBT_NEED_FRAME_TYPE (1 << 0)/* device required frame type */
-#define UBT_HAVE_FRAME_TYPE UBT_NEED_FRAME_TYPE
-#define UBT_FLAG_READ_STALL (1 << 1)/* read transfer has stalled */
-#define UBT_FLAG_WRITE_STALL (1 << 2)/* write transfer has stalled */
-#define UBT_FLAG_INTR_STALL (1 << 3)/* interrupt transfer has stalled */
-
- ng_ubt_node_stat_ep sc_stat; /* statistic */
-#define NG_UBT_STAT_PCKTS_SENT(s) (s).pckts_sent ++
-#define NG_UBT_STAT_BYTES_SENT(s, n) (s).bytes_sent += (n)
-#define NG_UBT_STAT_PCKTS_RECV(s) (s).pckts_recv ++
-#define NG_UBT_STAT_BYTES_RECV(s, n) (s).bytes_recv += (n)
-#define NG_UBT_STAT_OERROR(s) (s).oerrors ++
-#define NG_UBT_STAT_IERROR(s) (s).ierrors ++
-#define NG_UBT_STAT_RESET(s) bzero(&(s), sizeof((s)))
-
- uint8_t sc_name[16];
-
- struct mtx sc_mtx;
+ ng_ubt_node_debug_ep sc_debug; /* debug level */
- /* USB device specific */
- struct usb2_xfer *sc_xfer_if_0[UBT_IF_0_N_TRANSFER];
- struct usb2_xfer *sc_xfer_if_1[UBT_IF_1_N_TRANSFER];
+ ng_ubt_node_stat_ep sc_stat; /* statistic */
+#define UBT_STAT_PCKTS_SENT(sc) (sc)->sc_stat.pckts_sent ++
+#define UBT_STAT_BYTES_SENT(sc, n) (sc)->sc_stat.bytes_sent += (n)
+#define UBT_STAT_PCKTS_RECV(sc) (sc)->sc_stat.pckts_recv ++
+#define UBT_STAT_BYTES_RECV(sc, n) (sc)->sc_stat.bytes_recv += (n)
+#define UBT_STAT_OERROR(sc) (sc)->sc_stat.oerrors ++
+#define UBT_STAT_IERROR(sc) (sc)->sc_stat.ierrors ++
+#define UBT_STAT_RESET(sc) bzero(&(sc)->sc_stat, sizeof((sc)->sc_stat))
- /* Interrupt pipe (HCI events) */
- struct mbuf *sc_intr_buffer; /* interrupt buffer */
+ /* USB device specific */
+ struct mtx sc_if_mtx; /* interfaces lock */
+ struct usb2_xfer *sc_xfer[UBT_N_TRANSFER];
- /* Control pipe (HCI commands) */
- struct ng_bt_mbufq sc_cmdq; /* HCI command queue */
-#define UBT_CTRL_BUFFER_SIZE (sizeof(ng_hci_cmd_pkt_t) + NG_HCI_CMD_PKT_SIZE)
+ struct mtx sc_ng_mtx; /* lock for shared NG data */
- /* Bulk in pipe (ACL data) */
- struct mbuf *sc_bulk_in_buffer; /* bulk-in buffer */
+ /* HCI commands */
+ struct ng_bt_mbufq sc_cmdq; /* HCI command queue */
+#define UBT_CTRL_BUFFER_SIZE (sizeof(struct usb2_device_request) + \
+ sizeof(ng_hci_cmd_pkt_t) + NG_HCI_CMD_PKT_SIZE)
+#define UBT_INTR_BUFFER_SIZE (MCLBYTES-1) /* reserve 1 byte for ID-tag */
- /* Bulk out pipe (ACL data) */
- struct ng_bt_mbufq sc_aclq; /* ACL data queue */
-#define UBT_BULK_READ_BUFFER_SIZE (MCLBYTES-1) /* reserve one byte for ID-tag */
+ /* ACL data */
+ struct ng_bt_mbufq sc_aclq; /* ACL data queue */
+#define UBT_BULK_READ_BUFFER_SIZE (MCLBYTES-1) /* reserve 1 byte for ID-tag */
#define UBT_BULK_WRITE_BUFFER_SIZE (MCLBYTES)
- /* Isoc. out pipe (ACL data) */
- struct ng_bt_mbufq sc_scoq; /* SCO data queue */
-
- /* Isoc. in pipe (ACL data) */
- struct ng_bt_mbufq sc_sciq; /* SCO data queue */
+ /* SCO data */
+ struct ng_bt_mbufq sc_scoq; /* SCO data queue */
+ struct mbuf *sc_isoc_in_buffer; /* SCO reassembly buffer */
/* Netgraph specific */
- node_p sc_node; /* pointer back to node */
- hook_p sc_hook; /* upstream hook */
+ node_p sc_node; /* pointer back to node */
+ hook_p sc_hook; /* upstream hook */
+
+ /* Glue */
+ int sc_task_flags; /* task flags */
+#define UBT_FLAG_T_PENDING (1 << 0) /* task pending */
+#define UBT_FLAG_T_STOP_ALL (1 << 1) /* stop all xfers */
+#define UBT_FLAG_T_START_ALL (1 << 2) /* start all read and isoc
+ write xfers */
+#define UBT_FLAG_T_START_CTRL (1 << 3) /* start control xfer (write) */
+#define UBT_FLAG_T_START_BULK (1 << 4) /* start bulk xfer (write) */
+
+ struct task sc_task;
};
-typedef struct ubt_softc ubt_softc_t;
-typedef struct ubt_softc *ubt_softc_p;
+typedef struct ubt_softc ubt_softc_t;
+typedef struct ubt_softc * ubt_softc_p;
+
+#endif /* ndef _NG_UBT_VAR_H_ */
-#endif /* ndef _NG_UBT_VAR_H_ */
diff --git a/sys/dev/usb2/bluetooth/ubtbcmfw2.c b/sys/dev/usb2/bluetooth/ubtbcmfw2.c
index c270aaf..34ccf9f 100644
--- a/sys/dev/usb2/bluetooth/ubtbcmfw2.c
+++ b/sys/dev/usb2/bluetooth/ubtbcmfw2.c
@@ -3,7 +3,7 @@
*/
/*-
- * Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
+ * Copyright (c) 2003-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,99 +54,85 @@
#define UBTBCMFW_CONFIG_NO 1 /* Config number */
#define UBTBCMFW_IFACE_IDX 0 /* Control interface */
-#define UBTBCMFW_T_MAX 4 /* units */
-struct ubtbcmfw_softc {
- struct usb2_fifo_sc sc_fifo;
- struct mtx sc_mtx;
+#define UBTBCMFW_BSIZE 1024
+#define UBTBCMFW_IFQ_MAXLEN 2
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UBTBCMFW_T_MAX];
+enum {
+ UBTBCMFW_BULK_DT_WR = 0,
+ UBTBCMFW_INTR_DT_RD,
+ UBTBCMFW_N_TRANSFER,
+};
- uint8_t sc_flags;
-#define UBTBCMFW_FLAG_WRITE_STALL 0x01
-#define UBTBCMFW_FLAG_READ_STALL 0x02
+struct ubtbcmfw_softc {
+ struct usb2_device *sc_udev;
+ struct mtx sc_mtx;
+ struct usb2_xfer *sc_xfer[UBTBCMFW_N_TRANSFER];
+ struct usb2_fifo_sc sc_fifo;
};
-#define UBTBCMFW_BSIZE 1024
-#define UBTBCMFW_IFQ_MAXLEN 2
+/*
+ * Prototypes
+ */
-/* prototypes */
-
-static device_probe_t ubtbcmfw_probe;
-static device_attach_t ubtbcmfw_attach;
-static device_detach_t ubtbcmfw_detach;
-
-static usb2_callback_t ubtbcmfw_write_callback;
-static usb2_callback_t ubtbcmfw_write_clear_stall_callback;
-static usb2_callback_t ubtbcmfw_read_callback;
-static usb2_callback_t ubtbcmfw_read_clear_stall_callback;
-
-static usb2_fifo_close_t ubtbcmfw_close;
-static usb2_fifo_cmd_t ubtbcmfw_start_read;
-static usb2_fifo_cmd_t ubtbcmfw_start_write;
-static usb2_fifo_cmd_t ubtbcmfw_stop_read;
-static usb2_fifo_cmd_t ubtbcmfw_stop_write;
-static usb2_fifo_ioctl_t ubtbcmfw_ioctl;
-static usb2_fifo_open_t ubtbcmfw_open;
-
-static struct usb2_fifo_methods ubtbcmfw_fifo_methods = {
- .f_close = &ubtbcmfw_close,
- .f_ioctl = &ubtbcmfw_ioctl,
- .f_open = &ubtbcmfw_open,
- .f_start_read = &ubtbcmfw_start_read,
- .f_start_write = &ubtbcmfw_start_write,
- .f_stop_read = &ubtbcmfw_stop_read,
- .f_stop_write = &ubtbcmfw_stop_write,
- .basename[0] = "ubtbcmfw",
- .basename[1] = "ubtbcmfw",
- .basename[2] = "ubtbcmfw",
- .postfix[0] = "",
- .postfix[1] = ".1",
- .postfix[2] = ".2",
-};
+static device_probe_t ubtbcmfw_probe;
+static device_attach_t ubtbcmfw_attach;
+static device_detach_t ubtbcmfw_detach;
-static const struct usb2_config ubtbcmfw_config[UBTBCMFW_T_MAX] = {
+static usb2_callback_t ubtbcmfw_write_callback;
+static usb2_callback_t ubtbcmfw_read_callback;
- [0] = {
- .type = UE_BULK,
- .endpoint = 0x02, /* fixed */
- .direction = UE_DIR_OUT,
- .mh.bufsize = UBTBCMFW_BSIZE,
- .mh.flags = {.pipe_bof = 1,.proxy_buffer = 1,},
- .mh.callback = &ubtbcmfw_write_callback,
- },
+static usb2_fifo_close_t ubtbcmfw_close;
+static usb2_fifo_cmd_t ubtbcmfw_start_read;
+static usb2_fifo_cmd_t ubtbcmfw_start_write;
+static usb2_fifo_cmd_t ubtbcmfw_stop_read;
+static usb2_fifo_cmd_t ubtbcmfw_stop_write;
+static usb2_fifo_ioctl_t ubtbcmfw_ioctl;
+static usb2_fifo_open_t ubtbcmfw_open;
- [1] = {
- .type = UE_INTERRUPT,
- .endpoint = 0x01, /* fixed */
- .direction = UE_DIR_IN,
- .mh.bufsize = UBTBCMFW_BSIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1,},
- .mh.callback = &ubtbcmfw_read_callback,
- },
+static struct usb2_fifo_methods ubtbcmfw_fifo_methods =
+{
+ .f_close = &ubtbcmfw_close,
+ .f_ioctl = &ubtbcmfw_ioctl,
+ .f_open = &ubtbcmfw_open,
+ .f_start_read = &ubtbcmfw_start_read,
+ .f_start_write = &ubtbcmfw_start_write,
+ .f_stop_read = &ubtbcmfw_stop_read,
+ .f_stop_write = &ubtbcmfw_stop_write,
+ .basename[0] = "ubtbcmfw",
+ .basename[1] = "ubtbcmfw",
+ .basename[2] = "ubtbcmfw",
+ .postfix[0] = "",
+ .postfix[1] = ".1",
+ .postfix[2] = ".2",
+};
+
+/*
+ * Device's config structure
+ */
- [2] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &ubtbcmfw_write_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
+static const struct usb2_config ubtbcmfw_config[UBTBCMFW_N_TRANSFER] =
+{
+ [UBTBCMFW_BULK_DT_WR] = {
+ .type = UE_BULK,
+ .endpoint = 0x02, /* fixed */
+ .direction = UE_DIR_OUT,
+ .if_index = UBTBCMFW_IFACE_IDX,
+ .mh.bufsize = UBTBCMFW_BSIZE,
+ .mh.flags = { .pipe_bof = 1, .force_short_xfer = 1,
+ .proxy_buffer = 1, },
+ .mh.callback = &ubtbcmfw_write_callback,
},
- [3] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &ubtbcmfw_read_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
+ [UBTBCMFW_INTR_DT_RD] = {
+ .type = UE_INTERRUPT,
+ .endpoint = 0x01, /* fixed */
+ .direction = UE_DIR_IN,
+ .if_index = UBTBCMFW_IFACE_IDX,
+ .mh.bufsize = UBTBCMFW_BSIZE,
+ .mh.flags = { .pipe_bof = 1, .short_xfer_ok = 1,
+ .proxy_buffer = 1, },
+ .mh.callback = &ubtbcmfw_read_callback,
},
};
@@ -154,19 +140,21 @@ static const struct usb2_config ubtbcmfw_config[UBTBCMFW_T_MAX] = {
* Module
*/
-static devclass_t ubtbcmfw_devclass;
+static devclass_t ubtbcmfw_devclass;
-static device_method_t ubtbcmfw_methods[] = {
+static device_method_t ubtbcmfw_methods[] =
+{
DEVMETHOD(device_probe, ubtbcmfw_probe),
DEVMETHOD(device_attach, ubtbcmfw_attach),
DEVMETHOD(device_detach, ubtbcmfw_detach),
{0, 0}
};
-static driver_t ubtbcmfw_driver = {
- .name = "ubtbcmfw",
- .methods = ubtbcmfw_methods,
- .size = sizeof(struct ubtbcmfw_softc),
+static driver_t ubtbcmfw_driver =
+{
+ .name = "ubtbcmfw",
+ .methods = ubtbcmfw_methods,
+ .size = sizeof(struct ubtbcmfw_softc),
};
DRIVER_MODULE(ubtbcmfw, ushub, ubtbcmfw_driver, ubtbcmfw_devclass, NULL, 0);
@@ -180,21 +168,21 @@ MODULE_DEPEND(ubtbcmfw, usb2_core, 1, 1, 1);
static int
ubtbcmfw_probe(device_t dev)
{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
+ const struct usb2_device_id devs[] = {
+ /* Broadcom BCM2033 devices only */
+ { USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) },
+ };
- if (uaa->usb2_mode != USB_MODE_HOST) {
+ struct usb2_attach_arg *uaa = device_get_ivars(dev);
+
+ if (uaa->usb2_mode != USB_MODE_HOST)
return (ENXIO);
- }
+
if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
- /* Match the boot device. */
- if (uaa->info.idVendor == USB_VENDOR_BROADCOM &&
- uaa->info.idProduct == USB_PRODUCT_BROADCOM_BCM2033)
- return (0);
-
- return (ENXIO);
-}
+ return (usb2_lookup_id_by_uaa(devs, sizeof(devs), uaa));
+} /* ubtbcmfw_probe */
/*
* Attach the device
@@ -203,15 +191,11 @@ ubtbcmfw_probe(device_t dev)
static int
ubtbcmfw_attach(device_t dev)
{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ubtbcmfw_softc *sc = device_get_softc(dev);
- int32_t err;
- uint8_t iface_index;
+ struct usb2_attach_arg *uaa = device_get_ivars(dev);
+ struct ubtbcmfw_softc *sc = device_get_softc(dev);
+ uint8_t iface_index;
+ int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
- sc->sc_dev = dev;
sc->sc_udev = uaa->device;
device_set_usb2_desc(dev);
@@ -219,30 +203,35 @@ ubtbcmfw_attach(device_t dev)
mtx_init(&sc->sc_mtx, "ubtbcmfw lock", NULL, MTX_DEF | MTX_RECURSE);
iface_index = UBTBCMFW_IFACE_IDX;
- err = usb2_transfer_setup(uaa->device,
- &iface_index, sc->sc_xfer, ubtbcmfw_config,
- UBTBCMFW_T_MAX, sc, &sc->sc_mtx);
- if (err) {
- device_printf(dev, "allocating USB transfers "
- "failed, err=%s\n", usb2_errstr(err));
+ error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
+ ubtbcmfw_config, UBTBCMFW_N_TRANSFER,
+ sc, &sc->sc_mtx);
+ if (error != 0) {
+ device_printf(dev, "allocating USB transfers failed. %s\n",
+ usb2_errstr(error));
goto detach;
}
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
- err = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &ubtbcmfw_fifo_methods, &sc->sc_fifo,
- device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex);
- if (err) {
+ /* Set interface permissions */
+ usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
+ UID_ROOT, GID_OPERATOR, 0644);
+
+ error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
+ &ubtbcmfw_fifo_methods, &sc->sc_fifo,
+ device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex);
+ if (error != 0) {
+ device_printf(dev, "could not attach fifo. %s\n",
+ usb2_errstr(error));
goto detach;
}
- return (0); /* success */
+
+ return (0); /* success */
detach:
ubtbcmfw_detach(dev);
- return (ENOMEM); /* failure */
-}
+
+ return (ENXIO); /* failure */
+} /* ubtbcmfw_attach */
/*
* Detach the device
@@ -251,191 +240,192 @@ detach:
static int
ubtbcmfw_detach(device_t dev)
{
- struct ubtbcmfw_softc *sc = device_get_softc(dev);
+ struct ubtbcmfw_softc *sc = device_get_softc(dev);
usb2_fifo_detach(&sc->sc_fifo);
- usb2_transfer_unsetup(sc->sc_xfer, UBTBCMFW_T_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, UBTBCMFW_N_TRANSFER);
mtx_destroy(&sc->sc_mtx);
return (0);
-}
+} /* ubtbcmfw_detach */
+
+/*
+ * USB write callback
+ */
static void
ubtbcmfw_write_callback(struct usb2_xfer *xfer)
{
- struct ubtbcmfw_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo.fp[USB_FIFO_RX];
- uint32_t actlen;
+ struct ubtbcmfw_softc *sc = xfer->priv_sc;
+ struct usb2_fifo *f = sc->sc_fifo.fp[USB_FIFO_TX];
+ uint32_t actlen;
switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
case USB_ST_SETUP:
- if (sc->sc_flags & UBTBCMFW_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
- return;
- }
+ case USB_ST_TRANSFERRED:
+setup_next:
if (usb2_fifo_get_data(f, xfer->frbuffers, 0,
- UBTBCMFW_BSIZE, &actlen, 0)) {
-
+ xfer->max_data_length, &actlen, 0)) {
xfer->frlengths[0] = actlen;
usb2_start_hardware(xfer);
}
- return;
+ break;
- default: /* Error */
+ default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
- sc->sc_flags |= UBTBCMFW_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ xfer->flags.stall_pipe = 1;
+ goto setup_next;
}
- return;
+ break;
}
-}
+} /* ubtbcmfw_write_callback */
-static void
-ubtbcmfw_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ubtbcmfw_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UBTBCMFW_FLAG_WRITE_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
+/*
+ * USB read callback
+ */
static void
ubtbcmfw_read_callback(struct usb2_xfer *xfer)
{
- struct ubtbcmfw_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo.fp[USB_FIFO_RX];
+ struct ubtbcmfw_softc *sc = xfer->priv_sc;
+ struct usb2_fifo *fifo = sc->sc_fifo.fp[USB_FIFO_RX];
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
- usb2_fifo_put_data(f, xfer->frbuffers,
- 0, xfer->actlen, 1);
+ usb2_fifo_put_data(fifo, xfer->frbuffers, 0, xfer->actlen, 1);
+ /* FALLTHROUGH */
case USB_ST_SETUP:
- if (sc->sc_flags & UBTBCMFW_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
- return;
- }
- if (usb2_fifo_put_bytes_max(f) != 0) {
+setup_next:
+ if (usb2_fifo_put_bytes_max(fifo) > 0) {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
}
- return;
+ break;
- default: /* Error */
+ default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
- sc->sc_flags |= UBTBCMFW_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ xfer->flags.stall_pipe = 1;
+ goto setup_next;
}
- return;
+ break;
}
-}
-
-static void
-ubtbcmfw_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ubtbcmfw_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+} /* ubtbcmfw_read_callback */
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UBTBCMFW_FLAG_READ_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
+/*
+ * Called when we about to start read()ing from the device
+ */
static void
ubtbcmfw_start_read(struct usb2_fifo *fifo)
{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ struct ubtbcmfw_softc *sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[1]);
-}
+ usb2_transfer_start(sc->sc_xfer[UBTBCMFW_INTR_DT_RD]);
+} /* ubtbcmfw_start_read */
+
+/*
+ * Called when we about to stop reading (i.e. closing fifo)
+ */
static void
ubtbcmfw_stop_read(struct usb2_fifo *fifo)
{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ struct ubtbcmfw_softc *sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
-}
+ usb2_transfer_stop(sc->sc_xfer[UBTBCMFW_INTR_DT_RD]);
+} /* ubtbcmfw_stop_read */
+
+/*
+ * Called when we about to start write()ing to the device, poll()ing
+ * for write or flushing fifo
+ */
static void
ubtbcmfw_start_write(struct usb2_fifo *fifo)
{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ struct ubtbcmfw_softc *sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[0]);
-}
+ usb2_transfer_start(sc->sc_xfer[UBTBCMFW_BULK_DT_WR]);
+} /* ubtbcmfw_start_write */
+
+/*
+ * Called when we about to stop writing (i.e. closing fifo)
+ */
static void
ubtbcmfw_stop_write(struct usb2_fifo *fifo)
{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+
+ usb2_transfer_stop(sc->sc_xfer[UBTBCMFW_BULK_DT_WR]);
+} /* ubtbcmfw_stop_write */
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
-}
+/*
+ * Called when fifo is open
+ */
static int
ubtbcmfw_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ struct usb2_xfer *xfer;
+
+ /*
+ * f_open fifo method can only be called with either FREAD
+ * or FWRITE flag set at one time.
+ */
+
+ if (fflags & FREAD)
+ xfer = sc->sc_xfer[UBTBCMFW_INTR_DT_RD];
+ else if (fflags & FWRITE)
+ xfer = sc->sc_xfer[UBTBCMFW_BULK_DT_WR];
+ else
+ return (EINVAL); /* should not happen */
+
+ if (usb2_fifo_alloc_buffer(fifo, xfer->max_data_length,
+ UBTBCMFW_IFQ_MAXLEN) != 0)
+ return (ENOMEM);
- if (fflags & FREAD) {
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[1]->max_data_length,
- UBTBCMFW_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
- if (fflags & FWRITE) {
- /* clear stall first */
- mtx_lock(&sc->sc_mtx);
- sc->sc_flags |= UBTBCMFW_FLAG_WRITE_STALL;
- mtx_unlock(&sc->sc_mtx);
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[0]->max_data_length,
- UBTBCMFW_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
return (0);
-}
+} /* ubtbcmfw_open */
+
+/*
+ * Called when fifo is closed
+ */
static void
ubtbcmfw_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
{
- if (fflags & (FREAD | FWRITE)) {
+ if (fflags & (FREAD | FWRITE))
usb2_fifo_free_buffer(fifo);
- }
-}
+} /* ubtbcmfw_close */
+
+/*
+ * Process ioctl() on USB device
+ */
static int
ubtbcmfw_ioctl(struct usb2_fifo *fifo, u_long cmd, void *data,
int fflags, struct thread *td)
{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
- int error = 0;
+ struct ubtbcmfw_softc *sc = fifo->priv_sc0;
+ int error = 0;
switch (cmd) {
case USB_GET_DEVICE_DESC:
- *(struct usb2_device_descriptor *)data =
- *usb2_get_device_descriptor(sc->sc_udev);
+ memcpy(data, usb2_get_device_descriptor(sc->sc_udev),
+ sizeof(struct usb2_device_descriptor));
break;
default:
error = EINVAL;
break;
}
+
return (error);
-}
+} /* ubtbcmfw_ioctl */
diff --git a/sys/dev/usb2/controller/at91dci.c b/sys/dev/usb2/controller/at91dci.c
index a4e43df..3c4b430 100644
--- a/sys/dev/usb2/controller/at91dci.c
+++ b/sys/dev/usb2/controller/at91dci.c
@@ -50,14 +50,11 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR at91dcidebug
-#define usb2_config_td_cc at91dci_config_copy
-#define usb2_config_td_softc at91dci_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
@@ -106,7 +103,6 @@ static void at91dci_standard_done(struct usb2_xfer *);
static usb2_sw_transfer_func_t at91dci_root_intr_done;
static usb2_sw_transfer_func_t at91dci_root_ctrl_done;
-static usb2_config_td_command_t at91dci_root_ctrl_task;
/*
* NOTE: Some of the bits in the CSR register have inverse meaning so
@@ -261,42 +257,28 @@ at91dci_pull_down(struct at91dci_softc *sc)
}
static void
-at91dci_wakeup_peer(struct at91dci_softc *sc)
+at91dci_wakeup_peer(struct usb2_xfer *xfer)
{
- uint32_t temp;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
+ uint8_t use_polling;
if (!(sc->sc_flags.status_suspend)) {
return;
}
- temp = AT91_UDP_READ_4(sc, AT91_UDP_GSTATE);
-
- if (!(temp & AT91_UDP_GSTATE_ESR)) {
- return;
- }
- AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, temp);
-}
-
-static void
-at91dci_rem_wakeup_set(struct usb2_device *udev, uint8_t is_on)
-{
- struct at91dci_softc *sc;
- uint32_t temp;
-
- DPRINTFN(5, "is_on=%u\n", is_on);
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- sc = AT9100_DCI_BUS2SC(udev->bus);
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
- temp = AT91_UDP_READ_4(sc, AT91_UDP_GSTATE);
+ AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, AT91_UDP_GSTATE_ESR);
- if (is_on) {
- temp |= AT91_UDP_GSTATE_ESR;
+ /* wait 8 milliseconds */
+ if (use_polling) {
+ /* polling */
+ DELAY(8000);
} else {
- temp &= ~AT91_UDP_GSTATE_ESR;
+ /* Wait for reset to complete. */
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 8);
}
- AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, temp);
+ AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, 0);
}
static void
@@ -716,7 +698,7 @@ at91dci_xfer_do_fifo(struct usb2_xfer *xfer)
return (1); /* not complete */
done:
- sc = xfer->usb2_sc;
+ sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
temp = (xfer->endpoint & UE_ADDR);
/* update FIFO bank flag and multi buffer */
@@ -747,11 +729,9 @@ repeat:
}
}
-static void
-at91dci_vbus_interrupt(struct usb2_bus *bus, uint8_t is_on)
+void
+at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on)
{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus);
-
DPRINTFN(5, "vbus = %u\n", is_on);
USB_BUS_LOCK(&sc->sc_bus);
@@ -778,7 +758,6 @@ at91dci_vbus_interrupt(struct usb2_bus *bus, uint8_t is_on)
&at91dci_root_intr_done);
}
}
-
USB_BUS_UNLOCK(&sc->sc_bus);
}
@@ -904,7 +883,7 @@ at91dci_setup_standard_chain(struct usb2_xfer *xfer)
DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->udev));
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
temp.max_frame_size = xfer->max_frame_size;
@@ -919,7 +898,7 @@ at91dci_setup_standard_chain(struct usb2_xfer *xfer)
temp.setup_alt_next = xfer->flags_int.short_frames_ok;
temp.offset = 0;
- sc = xfer->usb2_sc;
+ sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
ep_no = (xfer->endpoint & UE_ADDR);
/* check if we should prepend a setup message */
@@ -1046,7 +1025,7 @@ at91dci_timeout(void *arg)
DPRINTF("xfer=%p\n", xfer);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* transfer is transferred */
at91dci_device_done(xfer, USB_ERR_TIMEOUT);
@@ -1060,7 +1039,7 @@ at91dci_start_standard_chain(struct usb2_xfer *xfer)
/* poll one time */
if (at91dci_xfer_do_fifo(xfer)) {
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
uint8_t ep_no = xfer->endpoint & UE_ADDR;
/*
@@ -1073,7 +1052,7 @@ at91dci_start_standard_chain(struct usb2_xfer *xfer)
DPRINTFN(15, "enable interrupts on endpoint %d\n", ep_no);
/* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
/* start timeout, if any */
if (xfer->timeout != 0) {
@@ -1087,7 +1066,7 @@ static void
at91dci_root_intr_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
DPRINTFN(9, "\n");
@@ -1227,7 +1206,7 @@ done:
static void
at91dci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
uint8_t ep_no;
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -1641,7 +1620,7 @@ at91dci_device_isoc_fs_close(struct usb2_xfer *xfer)
static void
at91dci_device_isoc_fs_enter(struct usb2_xfer *xfer)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
uint32_t temp;
uint32_t nframes;
@@ -1723,7 +1702,7 @@ at91dci_root_ctrl_open(struct usb2_xfer *xfer)
static void
at91dci_root_ctrl_close(struct usb2_xfer *xfer)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_ctrl.xfer == xfer) {
sc->sc_root_ctrl.xfer = NULL;
@@ -1797,7 +1776,7 @@ static const struct usb2_hub_descriptor_min at91dci_hubd = {
.wHubCharacteristics[0] =
(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
.wHubCharacteristics[1] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
+ (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
.bPwrOn2PwrGood = 50,
.bHubContrCurrent = 0,
.DeviceRemovable = {0}, /* port is removable */
@@ -1827,26 +1806,24 @@ at91dci_root_ctrl_enter(struct usb2_xfer *xfer)
static void
at91dci_root_ctrl_start(struct usb2_xfer *xfer)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_ctrl.xfer = xfer;
- usb2_config_td_queue_command(
- &sc->sc_config_td, NULL, &at91dci_root_ctrl_task, 0, 0);
+ usb2_bus_roothub_exec(xfer->xroot->bus);
}
static void
-at91dci_root_ctrl_task(struct at91dci_softc *sc,
- struct at91dci_config_copy *cc, uint16_t refcount)
+at91dci_root_ctrl_task(struct usb2_bus *bus)
{
- at91dci_root_ctrl_poll(sc);
+ at91dci_root_ctrl_poll(AT9100_DCI_BUS2SC(bus));
}
static void
at91dci_root_ctrl_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
uint16_t value;
uint16_t index;
uint8_t use_polling;
@@ -1867,7 +1844,7 @@ at91dci_root_ctrl_done(struct usb2_xfer *xfer,
value = UGETW(std->req.wValue);
index = UGETW(std->req.wIndex);
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
/* demultiplex the control request */
@@ -2120,7 +2097,7 @@ tr_handle_clear_port_feature:
switch (value) {
case UHF_PORT_SUSPEND:
- at91dci_wakeup_peer(sc);
+ at91dci_wakeup_peer(xfer);
break;
case UHF_PORT_ENABLE:
@@ -2272,7 +2249,7 @@ at91dci_root_intr_open(struct usb2_xfer *xfer)
static void
at91dci_root_intr_close(struct usb2_xfer *xfer)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_intr.xfer == xfer) {
sc->sc_root_intr.xfer = NULL;
@@ -2289,7 +2266,7 @@ at91dci_root_intr_enter(struct usb2_xfer *xfer)
static void
at91dci_root_intr_start(struct usb2_xfer *xfer)
{
- struct at91dci_softc *sc = xfer->usb2_sc;
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_intr.xfer = xfer;
}
@@ -2319,11 +2296,6 @@ at91dci_xfer_setup(struct usb2_setup_params *parm)
xfer = parm->curr_xfer;
/*
- * setup xfer
- */
- xfer->usb2_sc = sc;
-
- /*
* NOTE: This driver does not use any of the parameters that
* are computed from the following values. Just set some
* reasonable dummies:
@@ -2491,6 +2463,5 @@ struct usb2_bus_methods at91dci_bus_methods =
.get_hw_ep_profile = &at91dci_get_hw_ep_profile,
.set_stall = &at91dci_set_stall,
.clear_stall = &at91dci_clear_stall,
- .vbus_interrupt = &at91dci_vbus_interrupt,
- .rem_wakeup_set = &at91dci_rem_wakeup_set,
+ .roothub_exec = &at91dci_root_ctrl_task,
};
diff --git a/sys/dev/usb2/controller/at91dci.h b/sys/dev/usb2/controller/at91dci.h
index bade80a..d386307 100644
--- a/sys/dev/usb2/controller/at91dci.h
+++ b/sys/dev/usb2/controller/at91dci.h
@@ -34,6 +34,8 @@
#ifndef _AT9100_DCI_H_
#define _AT9100_DCI_H_
+#define AT91_MAX_DEVICES (USB_MIN_DEVICES + 1)
+
#define AT91_UDP_FRM 0x00 /* Frame number register */
#define AT91_UDP_FRM_MASK (0x7FF << 0) /* Frame Number as Defined in
* the Packet Field Formats */
@@ -204,8 +206,8 @@ struct at91dci_softc {
LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
- struct usb2_config_td sc_config_td;
+ struct usb2_device *sc_devices[AT91_MAX_DEVICES];
struct resource *sc_io_res;
struct resource *sc_irq_res;
void *sc_intr_hdl;
@@ -238,5 +240,6 @@ void at91dci_uninit(struct at91dci_softc *sc);
void at91dci_suspend(struct at91dci_softc *sc);
void at91dci_resume(struct at91dci_softc *sc);
void at91dci_interrupt(struct at91dci_softc *sc);
+void at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on);
#endif /* _AT9100_DCI_H_ */
diff --git a/sys/dev/usb2/controller/at91dci_atmelarm.c b/sys/dev/usb2/controller/at91dci_atmelarm.c
index 23de204..496eade 100644
--- a/sys/dev/usb2/controller/at91dci_atmelarm.c
+++ b/sys/dev/usb2/controller/at91dci_atmelarm.c
@@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
@@ -73,7 +72,7 @@ struct at91_udp_softc {
};
static void
-at91_vbus_interrupt(struct at91_udp_softc *sc)
+at91_vbus_poll(struct at91_udp_softc *sc)
{
uint32_t temp;
uint8_t vbus_val;
@@ -85,8 +84,7 @@ at91_vbus_interrupt(struct at91_udp_softc *sc)
/* just forward it */
vbus_val = at91_pio_gpio_get(VBUS_BASE, VBUS_MASK);
- (sc->sc_dci.sc_bus.methods->vbus_interrupt)
- (&sc->sc_dci.sc_bus, vbus_val);
+ at91dci_vbus_interrupt(&sc->sc_dci, vbus_val);
}
static void
@@ -133,9 +131,6 @@ at91_udp_attach(device_t dev)
int err;
int rid;
- if (sc == NULL) {
- return (ENXIO);
- }
/* setup AT9100 USB device controller interface softc */
sc->sc_dci.sc_clocks_on = &at91_udp_clocks_on;
@@ -145,9 +140,12 @@ at91_udp_attach(device_t dev)
sc->sc_dci.sc_pull_down = &at91_udp_pull_down;
sc->sc_dci.sc_pull_arg = sc;
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_dci.sc_bus.parent = dev;
+ sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
+ sc->sc_dci.sc_bus.devices_max = AT91_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
return (ENOMEM);
@@ -205,12 +203,6 @@ at91_udp_attach(device_t dev)
}
device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);
- err = usb2_config_td_setup(&sc->sc_dci.sc_config_td, sc,
- &sc->sc_dci.sc_bus.bus_mtx, NULL, 0, 4);
- if (err) {
- device_printf(dev, "could not setup config thread!\n");
- goto error;
- }
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (void *)at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
@@ -224,10 +216,10 @@ at91_udp_attach(device_t dev)
}
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_vbus_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)at91_vbus_interrupt, sc, &sc->sc_vbus_intr_hdl);
+ NULL, (void *)at91_vbus_poll, sc, &sc->sc_vbus_intr_hdl);
#else
err = bus_setup_intr(dev, sc->sc_vbus_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)at91_vbus_interrupt, sc, &sc->sc_vbus_intr_hdl);
+ (void *)at91_vbus_poll, sc, &sc->sc_vbus_intr_hdl);
#endif
if (err) {
sc->sc_vbus_intr_hdl = NULL;
@@ -241,7 +233,7 @@ at91_udp_attach(device_t dev)
goto error;
} else {
/* poll VBUS one time */
- at91_vbus_interrupt(sc);
+ at91_vbus_poll(sc);
}
return (0);
@@ -305,8 +297,6 @@ at91_udp_detach(device_t dev)
sc->sc_dci.sc_io_res);
sc->sc_dci.sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_dci.sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL);
/* disable clocks */
diff --git a/sys/dev/usb2/controller/atmegadci.c b/sys/dev/usb2/controller/atmegadci.c
new file mode 100644
index 0000000..073a99d
--- /dev/null
+++ b/sys/dev/usb2/controller/atmegadci.c
@@ -0,0 +1,2327 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This file contains the driver for the ATMEGA series USB Device
+ * Controller
+ */
+
+/*
+ * NOTE: When the chip detects BUS-reset it will also reset the
+ * endpoints, Function-address and more.
+ */
+
+#include <dev/usb2/include/usb2_standard.h>
+#include <dev/usb2/include/usb2_mfunc.h>
+#include <dev/usb2/include/usb2_error.h>
+#include <dev/usb2/include/usb2_defs.h>
+
+#define USB_DEBUG_VAR atmegadci_debug
+
+#include <dev/usb2/core/usb2_core.h>
+#include <dev/usb2/core/usb2_debug.h>
+#include <dev/usb2/core/usb2_busdma.h>
+#include <dev/usb2/core/usb2_process.h>
+#include <dev/usb2/core/usb2_sw_transfer.h>
+#include <dev/usb2/core/usb2_transfer.h>
+#include <dev/usb2/core/usb2_device.h>
+#include <dev/usb2/core/usb2_hub.h>
+#include <dev/usb2/core/usb2_util.h>
+
+#include <dev/usb2/controller/usb2_controller.h>
+#include <dev/usb2/controller/usb2_bus.h>
+#include <dev/usb2/controller/atmegadci.h>
+
+#define ATMEGA_BUS2SC(bus) \
+ ((struct atmegadci_softc *)(((uint8_t *)(bus)) - \
+ USB_P2U(&(((struct atmegadci_softc *)0)->sc_bus))))
+
+#define ATMEGA_PC2SC(pc) \
+ ATMEGA_BUS2SC((pc)->tag_parent->info->bus)
+
+#if USB_DEBUG
+static int atmegadci_debug = 0;
+
+SYSCTL_NODE(_hw_usb2, OID_AUTO, atmegadci, CTLFLAG_RW, 0, "USB ATMEGA DCI");
+SYSCTL_INT(_hw_usb2_atmegadci, OID_AUTO, debug, CTLFLAG_RW,
+ &atmegadci_debug, 0, "ATMEGA DCI debug level");
+#endif
+
+#define ATMEGA_INTR_ENDPT 1
+
+/* prototypes */
+
+struct usb2_bus_methods atmegadci_bus_methods;
+struct usb2_pipe_methods atmegadci_device_bulk_methods;
+struct usb2_pipe_methods atmegadci_device_ctrl_methods;
+struct usb2_pipe_methods atmegadci_device_intr_methods;
+struct usb2_pipe_methods atmegadci_device_isoc_fs_methods;
+struct usb2_pipe_methods atmegadci_root_ctrl_methods;
+struct usb2_pipe_methods atmegadci_root_intr_methods;
+
+static atmegadci_cmd_t atmegadci_setup_rx;
+static atmegadci_cmd_t atmegadci_data_rx;
+static atmegadci_cmd_t atmegadci_data_tx;
+static atmegadci_cmd_t atmegadci_data_tx_sync;
+static void atmegadci_device_done(struct usb2_xfer *, usb2_error_t);
+static void atmegadci_do_poll(struct usb2_bus *);
+static void atmegadci_root_ctrl_poll(struct atmegadci_softc *);
+static void atmegadci_standard_done(struct usb2_xfer *);
+
+static usb2_sw_transfer_func_t atmegadci_root_intr_done;
+static usb2_sw_transfer_func_t atmegadci_root_ctrl_done;
+
+/*
+ * Here is a list of what the chip supports:
+ */
+static const struct usb2_hw_ep_profile
+ atmegadci_ep_profile[2] = {
+
+ [0] = {
+ .max_in_frame_size = 64,
+ .max_out_frame_size = 64,
+ .is_simplex = 1,
+ .support_control = 1,
+ },
+ [1] = {
+ .max_in_frame_size = 64,
+ .max_out_frame_size = 64,
+ .is_simplex = 1,
+ .support_multi_buffer = 1,
+ .support_bulk = 1,
+ .support_interrupt = 1,
+ .support_isochronous = 1,
+ .support_in = 1,
+ .support_out = 1,
+ },
+};
+
+static void
+atmegadci_get_hw_ep_profile(struct usb2_device *udev,
+ const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
+{
+ if (ep_addr == 0)
+ *ppf = atmegadci_ep_profile;
+ else if (ep_addr < ATMEGA_EP_MAX)
+ *ppf = atmegadci_ep_profile + 1;
+ else
+ *ppf = NULL;
+}
+
+static void
+atmegadci_clocks_on(struct atmegadci_softc *sc)
+{
+ if (sc->sc_flags.clocks_off &&
+ sc->sc_flags.port_powered) {
+
+ DPRINTFN(5, "\n");
+
+ /* turn on clocks */
+ (sc->sc_clocks_on) (&sc->sc_bus);
+
+ ATMEGA_WRITE_1(sc, ATMEGA_USBCON,
+ ATMEGA_USBCON_USBE |
+ ATMEGA_USBCON_OTGPADE |
+ ATMEGA_USBCON_VBUSTE);
+
+ sc->sc_flags.clocks_off = 0;
+
+ /* enable transceiver ? */
+ }
+}
+
+static void
+atmegadci_clocks_off(struct atmegadci_softc *sc)
+{
+ if (!sc->sc_flags.clocks_off) {
+
+ DPRINTFN(5, "\n");
+
+ /* disable Transceiver ? */
+
+ ATMEGA_WRITE_1(sc, ATMEGA_USBCON,
+ ATMEGA_USBCON_USBE |
+ ATMEGA_USBCON_OTGPADE |
+ ATMEGA_USBCON_FRZCLK |
+ ATMEGA_USBCON_VBUSTE);
+
+ /* turn clocks off */
+ (sc->sc_clocks_off) (&sc->sc_bus);
+
+ sc->sc_flags.clocks_off = 1;
+ }
+}
+
+static void
+atmegadci_pull_up(struct atmegadci_softc *sc)
+{
+ /* pullup D+, if possible */
+
+ if (!sc->sc_flags.d_pulled_up &&
+ sc->sc_flags.port_powered) {
+ sc->sc_flags.d_pulled_up = 1;
+ ATMEGA_WRITE_1(sc, ATMEGA_UDCON, 0);
+ }
+}
+
+static void
+atmegadci_pull_down(struct atmegadci_softc *sc)
+{
+ /* pulldown D+, if possible */
+
+ if (sc->sc_flags.d_pulled_up) {
+ sc->sc_flags.d_pulled_up = 0;
+ ATMEGA_WRITE_1(sc, ATMEGA_UDCON, ATMEGA_UDCON_DETACH);
+ }
+}
+
+static void
+atmegadci_wakeup_peer(struct usb2_xfer *xfer)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+ uint8_t use_polling;
+ uint8_t temp;
+
+ if (!sc->sc_flags.status_suspend) {
+ return;
+ }
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
+
+ temp = ATMEGA_READ_1(sc, ATMEGA_UDCON);
+ ATMEGA_WRITE_1(sc, ATMEGA_UDCON, temp | ATMEGA_UDCON_RMWKUP);
+
+ /* wait 8 milliseconds */
+ if (use_polling) {
+ /* polling */
+ DELAY(8000);
+ } else {
+ /* Wait for reset to complete. */
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 8);
+ }
+
+ /* hardware should have cleared RMWKUP bit */
+}
+
+static void
+atmegadci_set_address(struct atmegadci_softc *sc, uint8_t addr)
+{
+ DPRINTFN(5, "addr=%d\n", addr);
+
+ ATMEGA_WRITE_1(sc, ATMEGA_UDADDR, addr);
+
+ addr |= ATMEGA_UDADDR_ADDEN;
+
+ ATMEGA_WRITE_1(sc, ATMEGA_UDADDR, addr);
+}
+
+static uint8_t
+atmegadci_setup_rx(struct atmegadci_td *td)
+{
+ struct atmegadci_softc *sc;
+ struct usb2_device_request req;
+ uint16_t count;
+ uint8_t temp;
+
+ /* get pointer to softc */
+ sc = ATMEGA_PC2SC(td->pc);
+
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
+
+ /* check endpoint status */
+ temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
+
+ DPRINTFN(5, "UEINTX=0x%02x\n", temp);
+
+ if (!(temp & ATMEGA_UEINTX_RXSTPI)) {
+ /* abort any ongoing transfer */
+ if (!td->did_stall) {
+ DPRINTFN(5, "stalling\n");
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
+ ATMEGA_UECONX_EPEN |
+ ATMEGA_UECONX_STALLRQ);
+ td->did_stall = 1;
+ }
+ goto not_complete;
+ }
+ /* get the packet byte count */
+ count =
+ (ATMEGA_READ_1(sc, ATMEGA_UEBCHX) << 8) |
+ (ATMEGA_READ_1(sc, ATMEGA_UEBCLX));
+
+ /* mask away undefined bits */
+ count &= 0x7FF;
+
+ /* verify data length */
+ if (count != td->remainder) {
+ DPRINTFN(0, "Invalid SETUP packet "
+ "length, %d bytes\n", count);
+ goto not_complete;
+ }
+ if (count != sizeof(req)) {
+ DPRINTFN(0, "Unsupported SETUP packet "
+ "length, %d bytes\n", count);
+ goto not_complete;
+ }
+ /* receive data */
+ ATMEGA_READ_MULTI_1(sc, ATMEGA_UEDATX,
+ (void *)&req, sizeof(req));
+
+ /* copy data into real buffer */
+ usb2_copy_in(td->pc, 0, &req, sizeof(req));
+
+ td->offset = sizeof(req);
+ td->remainder = 0;
+
+ /* sneak peek the set address */
+ if ((req.bmRequestType == UT_WRITE_DEVICE) &&
+ (req.bRequest == UR_SET_ADDRESS)) {
+ sc->sc_dv_addr = req.wValue[0] & 0x7F;
+ } else {
+ sc->sc_dv_addr = 0xFF;
+ }
+
+ /* clear SETUP packet interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ~ATMEGA_UEINTX_RXSTPI);
+ return (0); /* complete */
+
+not_complete:
+ /* we only want to know if there is a SETUP packet */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, ATMEGA_UEIENX_RXSTPE);
+ return (1); /* not complete */
+}
+
+static uint8_t
+atmegadci_data_rx(struct atmegadci_td *td)
+{
+ struct atmegadci_softc *sc;
+ struct usb2_page_search buf_res;
+ uint16_t count;
+ uint8_t temp;
+ uint8_t to;
+ uint8_t got_short;
+
+ to = 3; /* don't loop forever! */
+ got_short = 0;
+
+ /* get pointer to softc */
+ sc = ATMEGA_PC2SC(td->pc);
+
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
+
+repeat:
+ /* check if any of the FIFO banks have data */
+ /* check endpoint status */
+ temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
+
+ DPRINTFN(5, "temp=0x%02x rem=%u\n", temp, td->remainder);
+
+ if (temp & ATMEGA_UEINTX_RXSTPI) {
+ if (td->remainder == 0) {
+ /*
+ * We are actually complete and have
+ * received the next SETUP
+ */
+ DPRINTFN(5, "faking complete\n");
+ return (0); /* complete */
+ }
+ /*
+ * USB Host Aborted the transfer.
+ */
+ td->error = 1;
+ return (0); /* complete */
+ }
+ /* check status */
+ if (!(temp & (ATMEGA_UEINTX_FIFOCON |
+ ATMEGA_UEINTX_RXOUTI))) {
+ /* no data */
+ goto not_complete;
+ }
+ /* get the packet byte count */
+ count =
+ (ATMEGA_READ_1(sc, ATMEGA_UEBCHX) << 8) |
+ (ATMEGA_READ_1(sc, ATMEGA_UEBCLX));
+
+ /* mask away undefined bits */
+ count &= 0x7FF;
+
+ /* verify the packet byte count */
+ if (count != td->max_packet_size) {
+ if (count < td->max_packet_size) {
+ /* we have a short packet */
+ td->short_pkt = 1;
+ got_short = 1;
+ } else {
+ /* invalid USB packet */
+ td->error = 1;
+ return (0); /* we are complete */
+ }
+ }
+ /* verify the packet byte count */
+ if (count > td->remainder) {
+ /* invalid USB packet */
+ td->error = 1;
+ return (0); /* we are complete */
+ }
+ while (count > 0) {
+ usb2_get_page(td->pc, td->offset, &buf_res);
+
+ /* get correct length */
+ if (buf_res.length > count) {
+ buf_res.length = count;
+ }
+ /* receive data */
+ ATMEGA_READ_MULTI_1(sc, ATMEGA_UEDATX,
+ buf_res.buffer, buf_res.length);
+
+ /* update counters */
+ count -= buf_res.length;
+ td->offset += buf_res.length;
+ td->remainder -= buf_res.length;
+ }
+
+ /* clear OUT packet interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ATMEGA_UEINTX_RXOUTI ^ 0xFF);
+
+ /* release FIFO bank */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ATMEGA_UEINTX_FIFOCON ^ 0xFF);
+
+ /* check if we are complete */
+ if ((td->remainder == 0) || got_short) {
+ if (td->short_pkt) {
+ /* we are complete */
+ return (0);
+ }
+ /* else need to receive a zero length packet */
+ }
+ if (--to) {
+ goto repeat;
+ }
+not_complete:
+ /* we only want to know if there is a SETUP packet or OUT packet */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEIENX,
+ ATMEGA_UEIENX_RXSTPE | ATMEGA_UEIENX_RXOUTE);
+ return (1); /* not complete */
+}
+
+static uint8_t
+atmegadci_data_tx(struct atmegadci_td *td)
+{
+ struct atmegadci_softc *sc;
+ struct usb2_page_search buf_res;
+ uint16_t count;
+ uint8_t to;
+ uint8_t temp;
+
+ to = 3; /* don't loop forever! */
+
+ /* get pointer to softc */
+ sc = ATMEGA_PC2SC(td->pc);
+
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
+
+repeat:
+
+ /* check endpoint status */
+ temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
+
+ DPRINTFN(5, "temp=0x%02x rem=%u\n", temp, td->remainder);
+
+ if (temp & ATMEGA_UEINTX_RXSTPI) {
+ /*
+ * The current transfer was aborted
+ * by the USB Host
+ */
+ td->error = 1;
+ return (0); /* complete */
+ }
+ if (!(temp & (ATMEGA_UEINTX_FIFOCON |
+ ATMEGA_UEINTX_TXINI))) {
+ /* cannot write any data */
+ goto not_complete;
+ }
+ count = td->max_packet_size;
+ if (td->remainder < count) {
+ /* we have a short packet */
+ td->short_pkt = 1;
+ count = td->remainder;
+ }
+ while (count > 0) {
+
+ usb2_get_page(td->pc, td->offset, &buf_res);
+
+ /* get correct length */
+ if (buf_res.length > count) {
+ buf_res.length = count;
+ }
+ /* transmit data */
+ ATMEGA_WRITE_MULTI_1(sc, ATMEGA_UEDATX,
+ buf_res.buffer, buf_res.length);
+
+ /* update counters */
+ count -= buf_res.length;
+ td->offset += buf_res.length;
+ td->remainder -= buf_res.length;
+ }
+
+ /* clear IN packet interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, 0xFF ^ ATMEGA_UEINTX_TXINI);
+
+ /* allocate FIFO bank */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, 0xFF ^ ATMEGA_UEINTX_FIFOCON);
+
+ /* check remainder */
+ if (td->remainder == 0) {
+ if (td->short_pkt) {
+ return (0); /* complete */
+ }
+ /* else we need to transmit a short packet */
+ }
+ if (--to) {
+ goto repeat;
+ }
+not_complete:
+ /* we only want to know if there is a SETUP packet or free IN packet */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEIENX,
+ ATMEGA_UEIENX_RXSTPE | ATMEGA_UEIENX_TXINE);
+ return (1); /* not complete */
+}
+
+static uint8_t
+atmegadci_data_tx_sync(struct atmegadci_td *td)
+{
+ struct atmegadci_softc *sc;
+ uint8_t temp;
+
+ /* get pointer to softc */
+ sc = ATMEGA_PC2SC(td->pc);
+
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
+
+ /* check endpoint status */
+ temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
+
+ DPRINTFN(5, "temp=0x%02x\n", temp);
+
+ if (temp & ATMEGA_UEINTX_RXSTPI) {
+ DPRINTFN(5, "faking complete\n");
+ /* Race condition */
+ return (0); /* complete */
+ }
+ /*
+ * The control endpoint has only got one bank, so if that bank
+ * is free the packet has been transferred!
+ */
+ if (!(temp & (ATMEGA_UEINTX_FIFOCON |
+ ATMEGA_UEINTX_TXINI))) {
+ /* cannot write any data */
+ goto not_complete;
+ }
+ if (sc->sc_dv_addr != 0xFF) {
+ /* set new address */
+ atmegadci_set_address(sc, sc->sc_dv_addr);
+ }
+ return (0); /* complete */
+
+not_complete:
+ /* we only want to know if there is a SETUP packet or free IN packet */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEIENX,
+ ATMEGA_UEIENX_RXSTPE | ATMEGA_UEIENX_TXINE);
+ return (1); /* not complete */
+}
+
+static uint8_t
+atmegadci_xfer_do_fifo(struct usb2_xfer *xfer)
+{
+ struct atmegadci_td *td;
+
+ DPRINTFN(9, "\n");
+
+ td = xfer->td_transfer_cache;
+ while (1) {
+ if ((td->func) (td)) {
+ /* operation in progress */
+ break;
+ }
+ if (((void *)td) == xfer->td_transfer_last) {
+ goto done;
+ }
+ if (td->error) {
+ goto done;
+ } else if (td->remainder > 0) {
+ /*
+ * We had a short transfer. If there is no alternate
+ * next, stop processing !
+ */
+ if (!td->alt_next) {
+ goto done;
+ }
+ }
+ /*
+ * Fetch the next transfer descriptor and transfer
+ * some flags to the next transfer descriptor
+ */
+ td = td->obj_next;
+ xfer->td_transfer_cache = td;
+ }
+ return (1); /* not complete */
+
+done:
+ /* compute all actual lengths */
+
+ atmegadci_standard_done(xfer);
+ return (0); /* complete */
+}
+
+static void
+atmegadci_interrupt_poll(struct atmegadci_softc *sc)
+{
+ struct usb2_xfer *xfer;
+
+repeat:
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+ if (!atmegadci_xfer_do_fifo(xfer)) {
+ /* queue has been modified */
+ goto repeat;
+ }
+ }
+}
+
+static void
+atmegadci_vbus_interrupt(struct atmegadci_softc *sc, uint8_t is_on)
+{
+ DPRINTFN(5, "vbus = %u\n", is_on);
+
+ if (is_on) {
+ if (!sc->sc_flags.status_vbus) {
+ sc->sc_flags.status_vbus = 1;
+
+ /* complete root HUB interrupt endpoint */
+
+ usb2_sw_transfer(&sc->sc_root_intr,
+ &atmegadci_root_intr_done);
+ }
+ } else {
+ if (sc->sc_flags.status_vbus) {
+ sc->sc_flags.status_vbus = 0;
+ sc->sc_flags.status_bus_reset = 0;
+ sc->sc_flags.status_suspend = 0;
+ sc->sc_flags.change_suspend = 0;
+ sc->sc_flags.change_connect = 1;
+
+ /* complete root HUB interrupt endpoint */
+
+ usb2_sw_transfer(&sc->sc_root_intr,
+ &atmegadci_root_intr_done);
+ }
+ }
+}
+
+void
+atmegadci_interrupt(struct atmegadci_softc *sc)
+{
+ uint8_t status;
+
+ USB_BUS_LOCK(&sc->sc_bus);
+
+ /* read interrupt status */
+ status = ATMEGA_READ_1(sc, ATMEGA_UDINT);
+
+ /* clear all set interrupts */
+ ATMEGA_WRITE_1(sc, ATMEGA_UDINT, ~status);
+
+ /* check for any bus state change interrupts */
+ if (status & ATMEGA_UDINT_EORSTI) {
+
+ DPRINTFN(5, "end of reset\n");
+
+ /* set correct state */
+ sc->sc_flags.status_bus_reset = 1;
+ sc->sc_flags.status_suspend = 0;
+ sc->sc_flags.change_suspend = 0;
+ sc->sc_flags.change_connect = 1;
+
+ /* disable resume interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
+ ATMEGA_UDINT_SUSPE |
+ ATMEGA_UDINT_EORSTE);
+
+ /* complete root HUB interrupt endpoint */
+ usb2_sw_transfer(&sc->sc_root_intr,
+ &atmegadci_root_intr_done);
+ }
+ /*
+ * If resume and suspend is set at the same time we interpret
+ * that like RESUME. Resume is set when there is at least 3
+ * milliseconds of inactivity on the USB BUS.
+ */
+ if (status & ATMEGA_UDINT_EORSMI) {
+
+ DPRINTFN(5, "resume interrupt\n");
+
+ if (sc->sc_flags.status_suspend) {
+ /* update status bits */
+ sc->sc_flags.status_suspend = 0;
+ sc->sc_flags.change_suspend = 1;
+
+ /* disable resume interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
+ ATMEGA_UDINT_SUSPE |
+ ATMEGA_UDINT_EORSTE);
+
+ /* complete root HUB interrupt endpoint */
+ usb2_sw_transfer(&sc->sc_root_intr,
+ &atmegadci_root_intr_done);
+ }
+ } else if (status & ATMEGA_UDINT_SUSPI) {
+
+ DPRINTFN(5, "suspend interrupt\n");
+
+ if (!sc->sc_flags.status_suspend) {
+ /* update status bits */
+ sc->sc_flags.status_suspend = 1;
+ sc->sc_flags.change_suspend = 1;
+
+ /* disable suspend interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
+ ATMEGA_UDINT_EORSMI |
+ ATMEGA_UDINT_EORSTE);
+
+ /* complete root HUB interrupt endpoint */
+ usb2_sw_transfer(&sc->sc_root_intr,
+ &atmegadci_root_intr_done);
+ }
+ }
+ /* check VBUS */
+ status = ATMEGA_READ_1(sc, ATMEGA_USBINT);
+
+ /* clear all set interrupts */
+ ATMEGA_WRITE_1(sc, ATMEGA_USBINT, ~status);
+
+ if (status & ATMEGA_USBINT_VBUSTI) {
+ uint8_t temp;
+
+ temp = ATMEGA_READ_1(sc, ATMEGA_USBSTA);
+ atmegadci_vbus_interrupt(sc, temp & ATMEGA_USBSTA_VBUS);
+ }
+ /* check for any endpoint interrupts */
+ status = ATMEGA_READ_1(sc, ATMEGA_UEINT);
+
+ /* clear all set interrupts */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEINT, ~status);
+
+ if (status) {
+
+ DPRINTFN(5, "real endpoint interrupt 0x%02x\n", status);
+
+ atmegadci_interrupt_poll(sc);
+ }
+ USB_BUS_UNLOCK(&sc->sc_bus);
+}
+
+static void
+atmegadci_setup_standard_chain_sub(struct atmegadci_std_temp *temp)
+{
+ struct atmegadci_td *td;
+
+ /* get current Transfer Descriptor */
+ td = temp->td_next;
+ temp->td = td;
+
+ /* prepare for next TD */
+ temp->td_next = td->obj_next;
+
+ /* fill out the Transfer Descriptor */
+ td->func = temp->func;
+ td->pc = temp->pc;
+ td->offset = temp->offset;
+ td->remainder = temp->len;
+ td->error = 0;
+ td->did_stall = 0;
+ td->short_pkt = temp->short_pkt;
+ td->alt_next = temp->setup_alt_next;
+}
+
+static void
+atmegadci_setup_standard_chain(struct usb2_xfer *xfer)
+{
+ struct atmegadci_std_temp temp;
+ struct atmegadci_softc *sc;
+ struct atmegadci_td *td;
+ uint32_t x;
+ uint8_t ep_no;
+ uint8_t need_sync;
+
+ DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
+ xfer->address, UE_GET_ADDR(xfer->endpoint),
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
+
+ temp.max_frame_size = xfer->max_frame_size;
+
+ td = xfer->td_start[0];
+ xfer->td_transfer_first = td;
+ xfer->td_transfer_cache = td;
+
+ /* setup temp */
+
+ temp.td = NULL;
+ temp.td_next = xfer->td_start[0];
+ temp.setup_alt_next = xfer->flags_int.short_frames_ok;
+ temp.offset = 0;
+
+ sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+ ep_no = (xfer->endpoint & UE_ADDR);
+
+ /* check if we should prepend a setup message */
+
+ if (xfer->flags_int.control_xfr) {
+ if (xfer->flags_int.control_hdr) {
+
+ temp.func = &atmegadci_setup_rx;
+ temp.len = xfer->frlengths[0];
+ temp.pc = xfer->frbuffers + 0;
+ temp.short_pkt = temp.len ? 1 : 0;
+
+ atmegadci_setup_standard_chain_sub(&temp);
+ }
+ x = 1;
+ } else {
+ x = 0;
+ }
+
+ if (x != xfer->nframes) {
+ if (xfer->endpoint & UE_DIR_IN) {
+ temp.func = &atmegadci_data_tx;
+ need_sync = 1;
+ } else {
+ temp.func = &atmegadci_data_rx;
+ need_sync = 0;
+ }
+
+ /* setup "pc" pointer */
+ temp.pc = xfer->frbuffers + x;
+ } else {
+ need_sync = 0;
+ }
+ while (x != xfer->nframes) {
+
+ /* DATA0 / DATA1 message */
+
+ temp.len = xfer->frlengths[x];
+
+ x++;
+
+ if (x == xfer->nframes) {
+ temp.setup_alt_next = 0;
+ }
+ if (temp.len == 0) {
+
+ /* make sure that we send an USB packet */
+
+ temp.short_pkt = 0;
+
+ } else {
+
+ /* regular data transfer */
+
+ temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
+ }
+
+ atmegadci_setup_standard_chain_sub(&temp);
+
+ if (xfer->flags_int.isochronous_xfr) {
+ temp.offset += temp.len;
+ } else {
+ /* get next Page Cache pointer */
+ temp.pc = xfer->frbuffers + x;
+ }
+ }
+
+ /* always setup a valid "pc" pointer for status and sync */
+ temp.pc = xfer->frbuffers + 0;
+
+ /* check if we need to sync */
+ if (need_sync && xfer->flags_int.control_xfr) {
+
+ /* we need a SYNC point after TX */
+ temp.func = &atmegadci_data_tx_sync;
+ temp.len = 0;
+ temp.short_pkt = 0;
+
+ atmegadci_setup_standard_chain_sub(&temp);
+ }
+ /* check if we should append a status stage */
+ if (xfer->flags_int.control_xfr &&
+ !xfer->flags_int.control_act) {
+
+ /*
+ * Send a DATA1 message and invert the current
+ * endpoint direction.
+ */
+ if (xfer->endpoint & UE_DIR_IN) {
+ temp.func = &atmegadci_data_rx;
+ need_sync = 0;
+ } else {
+ temp.func = &atmegadci_data_tx;
+ need_sync = 1;
+ }
+ temp.len = 0;
+ temp.short_pkt = 0;
+
+ atmegadci_setup_standard_chain_sub(&temp);
+ if (need_sync) {
+ /* we need a SYNC point after TX */
+ temp.func = &atmegadci_data_tx_sync;
+ temp.len = 0;
+ temp.short_pkt = 0;
+
+ atmegadci_setup_standard_chain_sub(&temp);
+ }
+ }
+ /* must have at least one frame! */
+ td = temp.td;
+ xfer->td_transfer_last = td;
+}
+
+static void
+atmegadci_timeout(void *arg)
+{
+ struct usb2_xfer *xfer = arg;
+
+ DPRINTF("xfer=%p\n", xfer);
+
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
+
+ /* transfer is transferred */
+ atmegadci_device_done(xfer, USB_ERR_TIMEOUT);
+}
+
+static void
+atmegadci_start_standard_chain(struct usb2_xfer *xfer)
+{
+ DPRINTFN(9, "\n");
+
+ /* poll one time - will turn on interrupts */
+ if (atmegadci_xfer_do_fifo(xfer)) {
+
+ /* put transfer on interrupt queue */
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
+
+ /* start timeout, if any */
+ if (xfer->timeout != 0) {
+ usb2_transfer_timeout_ms(xfer,
+ &atmegadci_timeout, xfer->timeout);
+ }
+ }
+}
+
+static void
+atmegadci_root_intr_done(struct usb2_xfer *xfer,
+ struct usb2_sw_transfer *std)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+
+ DPRINTFN(9, "\n");
+
+ USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
+
+ if (std->state != USB_SW_TR_PRE_DATA) {
+ if (std->state == USB_SW_TR_PRE_CALLBACK) {
+ /* transfer transferred */
+ atmegadci_device_done(xfer, std->err);
+ }
+ goto done;
+ }
+ /* setup buffer */
+ std->ptr = sc->sc_hub_idata;
+ std->len = sizeof(sc->sc_hub_idata);
+
+ /* set port bit */
+ sc->sc_hub_idata[0] = 0x02; /* we only have one port */
+
+done:
+ return;
+}
+
+static usb2_error_t
+atmegadci_standard_done_sub(struct usb2_xfer *xfer)
+{
+ struct atmegadci_td *td;
+ uint32_t len;
+ uint8_t error;
+
+ DPRINTFN(9, "\n");
+
+ td = xfer->td_transfer_cache;
+
+ do {
+ len = td->remainder;
+
+ if (xfer->aframes != xfer->nframes) {
+ /*
+ * Verify the length and subtract
+ * the remainder from "frlengths[]":
+ */
+ if (len > xfer->frlengths[xfer->aframes]) {
+ td->error = 1;
+ } else {
+ xfer->frlengths[xfer->aframes] -= len;
+ }
+ }
+ /* Check for transfer error */
+ if (td->error) {
+ /* the transfer is finished */
+ error = 1;
+ td = NULL;
+ break;
+ }
+ /* Check for short transfer */
+ if (len > 0) {
+ if (xfer->flags_int.short_frames_ok) {
+ /* follow alt next */
+ if (td->alt_next) {
+ td = td->obj_next;
+ } else {
+ td = NULL;
+ }
+ } else {
+ /* the transfer is finished */
+ td = NULL;
+ }
+ error = 0;
+ break;
+ }
+ td = td->obj_next;
+
+ /* this USB frame is complete */
+ error = 0;
+ break;
+
+ } while (0);
+
+ /* update transfer cache */
+
+ xfer->td_transfer_cache = td;
+
+ return (error ?
+ USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
+}
+
+static void
+atmegadci_standard_done(struct usb2_xfer *xfer)
+{
+ usb2_error_t err = 0;
+
+ DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
+ xfer, xfer->pipe);
+
+ /* reset scanner */
+
+ xfer->td_transfer_cache = xfer->td_transfer_first;
+
+ if (xfer->flags_int.control_xfr) {
+
+ if (xfer->flags_int.control_hdr) {
+
+ err = atmegadci_standard_done_sub(xfer);
+ }
+ xfer->aframes = 1;
+
+ if (xfer->td_transfer_cache == NULL) {
+ goto done;
+ }
+ }
+ while (xfer->aframes != xfer->nframes) {
+
+ err = atmegadci_standard_done_sub(xfer);
+ xfer->aframes++;
+
+ if (xfer->td_transfer_cache == NULL) {
+ goto done;
+ }
+ }
+
+ if (xfer->flags_int.control_xfr &&
+ !xfer->flags_int.control_act) {
+
+ err = atmegadci_standard_done_sub(xfer);
+ }
+done:
+ atmegadci_device_done(xfer, err);
+}
+
+/*------------------------------------------------------------------------*
+ * atmegadci_device_done
+ *
+ * NOTE: this function can be called more than one time on the
+ * same USB transfer!
+ *------------------------------------------------------------------------*/
+static void
+atmegadci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+ uint8_t ep_no;
+
+ USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
+
+ DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
+ xfer, xfer->pipe, error);
+
+ if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
+ ep_no = (xfer->endpoint & UE_ADDR);
+
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, ep_no);
+
+ /* disable endpoint interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, 0);
+
+ DPRINTFN(15, "disabled interrupts!\n");
+ }
+ /* dequeue transfer and start next transfer */
+ usb2_transfer_done(xfer, error);
+}
+
+static void
+atmegadci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
+ struct usb2_pipe *pipe)
+{
+ struct atmegadci_softc *sc;
+ uint8_t ep_no;
+
+ USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
+
+ DPRINTFN(5, "pipe=%p\n", pipe);
+
+ if (xfer) {
+ /* cancel any ongoing transfers */
+ atmegadci_device_done(xfer, USB_ERR_STALLED);
+ }
+ sc = ATMEGA_BUS2SC(udev->bus);
+ /* get endpoint number */
+ ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, ep_no);
+ /* set stall */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
+ ATMEGA_UECONX_EPEN |
+ ATMEGA_UECONX_STALLRQ);
+}
+
+static void
+atmegadci_clear_stall_sub(struct atmegadci_softc *sc, uint8_t ep_no,
+ uint8_t ep_type, uint8_t ep_dir)
+{
+ uint8_t temp;
+
+ if (ep_type == UE_CONTROL) {
+ /* clearing stall is not needed */
+ return;
+ }
+ /* select endpoint number */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, ep_no);
+
+ /* set endpoint reset */
+ ATMEGA_WRITE_1(sc, ATMEGA_UERST, ATMEGA_UERST_MASK(ep_no));
+
+ /* clear endpoint reset */
+ ATMEGA_WRITE_1(sc, ATMEGA_UERST, 0);
+
+ /* set stall */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
+ ATMEGA_UECONX_EPEN |
+ ATMEGA_UECONX_STALLRQ);
+
+ /* reset data toggle */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
+ ATMEGA_UECONX_EPEN |
+ ATMEGA_UECONX_RSTDT);
+
+ /* clear stall */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
+ ATMEGA_UECONX_EPEN |
+ ATMEGA_UECONX_STALLRQC);
+
+ if (ep_type == UE_CONTROL) {
+ /* one bank, 64-bytes wMaxPacket */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECFG0X,
+ ATMEGA_UECFG0X_EPTYPE0);
+ ATMEGA_WRITE_1(sc, ATMEGA_UECFG1X,
+ ATMEGA_UECFG1X_ALLOC |
+ ATMEGA_UECFG1X_EPBK0 |
+ ATMEGA_UECFG1X_EPSIZE(7));
+ } else {
+ temp = 0;
+ if (ep_type == UE_BULK) {
+ temp |= ATMEGA_UECFG0X_EPTYPE2;
+ } else if (ep_type == UE_INTERRUPT) {
+ temp |= ATMEGA_UECFG0X_EPTYPE3;
+ } else {
+ temp |= ATMEGA_UECFG0X_EPTYPE1;
+ }
+ if (ep_dir & UE_DIR_IN) {
+ temp |= ATMEGA_UECFG0X_EPDIR;
+ }
+ /* two banks, 64-bytes wMaxPacket */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECFG0X, temp);
+ ATMEGA_WRITE_1(sc, ATMEGA_UECFG1X,
+ ATMEGA_UECFG1X_ALLOC |
+ ATMEGA_UECFG1X_EPBK1 |
+ ATMEGA_UECFG1X_EPSIZE(7));
+
+ temp = ATMEGA_READ_1(sc, ATMEGA_UESTA0X);
+ if (!(temp & ATMEGA_UESTA0X_CFGOK)) {
+ DPRINTFN(0, "Chip rejected configuration\n");
+ }
+ }
+}
+
+static void
+atmegadci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
+{
+ struct atmegadci_softc *sc;
+ struct usb2_endpoint_descriptor *ed;
+
+ DPRINTFN(5, "pipe=%p\n", pipe);
+
+ USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
+
+ /* check mode */
+ if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
+ /* not supported */
+ return;
+ }
+ /* get softc */
+ sc = ATMEGA_BUS2SC(udev->bus);
+
+ /* get endpoint descriptor */
+ ed = pipe->edesc;
+
+ /* reset endpoint */
+ atmegadci_clear_stall_sub(sc,
+ (ed->bEndpointAddress & UE_ADDR),
+ (ed->bmAttributes & UE_XFERTYPE),
+ (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
+}
+
+usb2_error_t
+atmegadci_init(struct atmegadci_softc *sc)
+{
+ uint8_t n;
+
+ DPRINTF("start\n");
+
+ /* set up the bus structure */
+ sc->sc_bus.usbrev = USB_REV_1_1;
+ sc->sc_bus.methods = &atmegadci_bus_methods;
+
+ USB_BUS_LOCK(&sc->sc_bus);
+
+ /* enable USB PAD regulator */
+ ATMEGA_WRITE_1(sc, ATMEGA_UHWCON,
+ ATMEGA_UHWCON_UVREGE);
+
+ /* turn on clocks */
+ (sc->sc_clocks_on) (&sc->sc_bus);
+
+ /* wait a little for things to stabilise */
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
+
+ /* enable interrupts */
+ ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
+ ATMEGA_UDINT_SUSPE |
+ ATMEGA_UDINT_EORSTE);
+
+ /* reset all endpoints */
+ ATMEGA_WRITE_1(sc, ATMEGA_UERST,
+ (1 << ATMEGA_EP_MAX) - 1);
+
+ /* disable reset */
+ ATMEGA_WRITE_1(sc, ATMEGA_UERST, 0);
+
+ /* disable all endpoints */
+ for (n = 1; n != ATMEGA_EP_MAX; n++) {
+
+ /* select endpoint */
+ ATMEGA_WRITE_1(sc, ATMEGA_UENUM, n);
+
+ /* disable endpoint interrupt */
+ ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, 0);
+
+ /* disable endpoint */
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX, 0);
+ }
+
+ /* turn off clocks */
+
+ atmegadci_clocks_off(sc);
+
+ USB_BUS_UNLOCK(&sc->sc_bus);
+
+ /* catch any lost interrupts */
+
+ atmegadci_do_poll(&sc->sc_bus);
+
+ return (0); /* success */
+}
+
+void
+atmegadci_uninit(struct atmegadci_softc *sc)
+{
+ USB_BUS_LOCK(&sc->sc_bus);
+
+ /* turn on clocks */
+ (sc->sc_clocks_on) (&sc->sc_bus);
+
+ /* disable interrupts */
+ ATMEGA_WRITE_1(sc, ATMEGA_UDIEN, 0);
+
+ /* reset all endpoints */
+ ATMEGA_WRITE_1(sc, ATMEGA_UERST,
+ (1 << ATMEGA_EP_MAX) - 1);
+
+ /* disable reset */
+ ATMEGA_WRITE_1(sc, ATMEGA_UERST, 0);
+
+ sc->sc_flags.port_powered = 0;
+ sc->sc_flags.status_vbus = 0;
+ sc->sc_flags.status_bus_reset = 0;
+ sc->sc_flags.status_suspend = 0;
+ sc->sc_flags.change_suspend = 0;
+ sc->sc_flags.change_connect = 1;
+
+ atmegadci_pull_down(sc);
+ atmegadci_clocks_off(sc);
+
+ /* disable USB PAD regulator */
+ ATMEGA_WRITE_1(sc, ATMEGA_UHWCON, 0);
+
+ USB_BUS_UNLOCK(&sc->sc_bus);
+}
+
+void
+atmegadci_suspend(struct atmegadci_softc *sc)
+{
+ return;
+}
+
+void
+atmegadci_resume(struct atmegadci_softc *sc)
+{
+ return;
+}
+
+static void
+atmegadci_do_poll(struct usb2_bus *bus)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(bus);
+
+ USB_BUS_LOCK(&sc->sc_bus);
+ atmegadci_interrupt_poll(sc);
+ atmegadci_root_ctrl_poll(sc);
+ USB_BUS_UNLOCK(&sc->sc_bus);
+}
+
+/*------------------------------------------------------------------------*
+ * at91dci bulk support
+ *------------------------------------------------------------------------*/
+static void
+atmegadci_device_bulk_open(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_bulk_close(struct usb2_xfer *xfer)
+{
+ atmegadci_device_done(xfer, USB_ERR_CANCELLED);
+}
+
+static void
+atmegadci_device_bulk_enter(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_bulk_start(struct usb2_xfer *xfer)
+{
+ /* setup TDs */
+ atmegadci_setup_standard_chain(xfer);
+ atmegadci_start_standard_chain(xfer);
+}
+
+struct usb2_pipe_methods atmegadci_device_bulk_methods =
+{
+ .open = atmegadci_device_bulk_open,
+ .close = atmegadci_device_bulk_close,
+ .enter = atmegadci_device_bulk_enter,
+ .start = atmegadci_device_bulk_start,
+ .enter_is_cancelable = 1,
+ .start_is_cancelable = 1,
+};
+
+/*------------------------------------------------------------------------*
+ * at91dci control support
+ *------------------------------------------------------------------------*/
+static void
+atmegadci_device_ctrl_open(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_ctrl_close(struct usb2_xfer *xfer)
+{
+ atmegadci_device_done(xfer, USB_ERR_CANCELLED);
+}
+
+static void
+atmegadci_device_ctrl_enter(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_ctrl_start(struct usb2_xfer *xfer)
+{
+ /* setup TDs */
+ atmegadci_setup_standard_chain(xfer);
+ atmegadci_start_standard_chain(xfer);
+}
+
+struct usb2_pipe_methods atmegadci_device_ctrl_methods =
+{
+ .open = atmegadci_device_ctrl_open,
+ .close = atmegadci_device_ctrl_close,
+ .enter = atmegadci_device_ctrl_enter,
+ .start = atmegadci_device_ctrl_start,
+ .enter_is_cancelable = 1,
+ .start_is_cancelable = 1,
+};
+
+/*------------------------------------------------------------------------*
+ * at91dci interrupt support
+ *------------------------------------------------------------------------*/
+static void
+atmegadci_device_intr_open(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_intr_close(struct usb2_xfer *xfer)
+{
+ atmegadci_device_done(xfer, USB_ERR_CANCELLED);
+}
+
+static void
+atmegadci_device_intr_enter(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_intr_start(struct usb2_xfer *xfer)
+{
+ /* setup TDs */
+ atmegadci_setup_standard_chain(xfer);
+ atmegadci_start_standard_chain(xfer);
+}
+
+struct usb2_pipe_methods atmegadci_device_intr_methods =
+{
+ .open = atmegadci_device_intr_open,
+ .close = atmegadci_device_intr_close,
+ .enter = atmegadci_device_intr_enter,
+ .start = atmegadci_device_intr_start,
+ .enter_is_cancelable = 1,
+ .start_is_cancelable = 1,
+};
+
+/*------------------------------------------------------------------------*
+ * at91dci full speed isochronous support
+ *------------------------------------------------------------------------*/
+static void
+atmegadci_device_isoc_fs_open(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_device_isoc_fs_close(struct usb2_xfer *xfer)
+{
+ atmegadci_device_done(xfer, USB_ERR_CANCELLED);
+}
+
+static void
+atmegadci_device_isoc_fs_enter(struct usb2_xfer *xfer)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+ uint32_t temp;
+ uint32_t nframes;
+
+ DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
+ xfer, xfer->pipe->isoc_next, xfer->nframes);
+
+ /* get the current frame index */
+
+ nframes =
+ (ATMEGA_READ_1(sc, ATMEGA_UDFNUMH) << 8) |
+ (ATMEGA_READ_1(sc, ATMEGA_UDFNUML));
+
+ nframes &= ATMEGA_FRAME_MASK;
+
+ /*
+ * check if the frame index is within the window where the frames
+ * will be inserted
+ */
+ temp = (nframes - xfer->pipe->isoc_next) & ATMEGA_FRAME_MASK;
+
+ if ((xfer->pipe->is_synced == 0) ||
+ (temp < xfer->nframes)) {
+ /*
+ * If there is data underflow or the pipe queue is
+ * empty we schedule the transfer a few frames ahead
+ * of the current frame position. Else two isochronous
+ * transfers might overlap.
+ */
+ xfer->pipe->isoc_next = (nframes + 3) & ATMEGA_FRAME_MASK;
+ xfer->pipe->is_synced = 1;
+ DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
+ }
+ /*
+ * compute how many milliseconds the insertion is ahead of the
+ * current frame position:
+ */
+ temp = (xfer->pipe->isoc_next - nframes) & ATMEGA_FRAME_MASK;
+
+ /*
+ * pre-compute when the isochronous transfer will be finished:
+ */
+ xfer->isoc_time_complete =
+ usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
+ xfer->nframes;
+
+ /* compute frame number for next insertion */
+ xfer->pipe->isoc_next += xfer->nframes;
+
+ /* setup TDs */
+ atmegadci_setup_standard_chain(xfer);
+}
+
+static void
+atmegadci_device_isoc_fs_start(struct usb2_xfer *xfer)
+{
+ /* start TD chain */
+ atmegadci_start_standard_chain(xfer);
+}
+
+struct usb2_pipe_methods atmegadci_device_isoc_fs_methods =
+{
+ .open = atmegadci_device_isoc_fs_open,
+ .close = atmegadci_device_isoc_fs_close,
+ .enter = atmegadci_device_isoc_fs_enter,
+ .start = atmegadci_device_isoc_fs_start,
+ .enter_is_cancelable = 1,
+ .start_is_cancelable = 1,
+};
+
+/*------------------------------------------------------------------------*
+ * at91dci root control support
+ *------------------------------------------------------------------------*
+ * simulate a hardware HUB by handling
+ * all the necessary requests
+ *------------------------------------------------------------------------*/
+
+static void
+atmegadci_root_ctrl_open(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_root_ctrl_close(struct usb2_xfer *xfer)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+
+ if (sc->sc_root_ctrl.xfer == xfer) {
+ sc->sc_root_ctrl.xfer = NULL;
+ }
+ atmegadci_device_done(xfer, USB_ERR_CANCELLED);
+}
+
+/*
+ * USB descriptors for the virtual Root HUB:
+ */
+
+static const struct usb2_device_descriptor atmegadci_devd = {
+ .bLength = sizeof(struct usb2_device_descriptor),
+ .bDescriptorType = UDESC_DEVICE,
+ .bcdUSB = {0x00, 0x02},
+ .bDeviceClass = UDCLASS_HUB,
+ .bDeviceSubClass = UDSUBCLASS_HUB,
+ .bDeviceProtocol = UDPROTO_HSHUBSTT,
+ .bMaxPacketSize = 64,
+ .bcdDevice = {0x00, 0x01},
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .bNumConfigurations = 1,
+};
+
+static const struct usb2_device_qualifier atmegadci_odevd = {
+ .bLength = sizeof(struct usb2_device_qualifier),
+ .bDescriptorType = UDESC_DEVICE_QUALIFIER,
+ .bcdUSB = {0x00, 0x02},
+ .bDeviceClass = UDCLASS_HUB,
+ .bDeviceSubClass = UDSUBCLASS_HUB,
+ .bDeviceProtocol = UDPROTO_FSHUB,
+ .bMaxPacketSize0 = 0,
+ .bNumConfigurations = 0,
+};
+
+static const struct atmegadci_config_desc atmegadci_confd = {
+ .confd = {
+ .bLength = sizeof(struct usb2_config_descriptor),
+ .bDescriptorType = UDESC_CONFIG,
+ .wTotalLength[0] = sizeof(atmegadci_confd),
+ .bNumInterface = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = UC_SELF_POWERED,
+ .bMaxPower = 0,
+ },
+ .ifcd = {
+ .bLength = sizeof(struct usb2_interface_descriptor),
+ .bDescriptorType = UDESC_INTERFACE,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = UICLASS_HUB,
+ .bInterfaceSubClass = UISUBCLASS_HUB,
+ .bInterfaceProtocol = UIPROTO_HSHUBSTT,
+ },
+
+ .endpd = {
+ .bLength = sizeof(struct usb2_endpoint_descriptor),
+ .bDescriptorType = UDESC_ENDPOINT,
+ .bEndpointAddress = (UE_DIR_IN | ATMEGA_INTR_ENDPT),
+ .bmAttributes = UE_INTERRUPT,
+ .wMaxPacketSize[0] = 8,
+ .bInterval = 255,
+ },
+};
+
+static const struct usb2_hub_descriptor_min atmegadci_hubd = {
+ .bDescLength = sizeof(atmegadci_hubd),
+ .bDescriptorType = UDESC_HUB,
+ .bNbrPorts = 1,
+ .wHubCharacteristics[0] =
+ (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
+ .wHubCharacteristics[1] =
+ (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
+ .bPwrOn2PwrGood = 50,
+ .bHubContrCurrent = 0,
+ .DeviceRemovable = {0}, /* port is removable */
+};
+
+#define STRING_LANG \
+ 0x09, 0x04, /* American English */
+
+#define STRING_VENDOR \
+ 'A', 0, 'T', 0, 'M', 0, 'E', 0, 'G', 0, 'A', 0
+
+#define STRING_PRODUCT \
+ 'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \
+ 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
+ 'U', 0, 'B', 0,
+
+USB_MAKE_STRING_DESC(STRING_LANG, atmegadci_langtab);
+USB_MAKE_STRING_DESC(STRING_VENDOR, atmegadci_vendor);
+USB_MAKE_STRING_DESC(STRING_PRODUCT, atmegadci_product);
+
+static void
+atmegadci_root_ctrl_enter(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_root_ctrl_start(struct usb2_xfer *xfer)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+
+ sc->sc_root_ctrl.xfer = xfer;
+
+ usb2_bus_roothub_exec(xfer->xroot->bus);
+}
+
+static void
+atmegadci_root_ctrl_task(struct usb2_bus *bus)
+{
+ atmegadci_root_ctrl_poll(ATMEGA_BUS2SC(bus));
+}
+
+static void
+atmegadci_root_ctrl_done(struct usb2_xfer *xfer,
+ struct usb2_sw_transfer *std)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+ uint16_t value;
+ uint16_t index;
+ uint8_t use_polling;
+
+ USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
+
+ if (std->state != USB_SW_TR_SETUP) {
+ if (std->state == USB_SW_TR_PRE_CALLBACK) {
+ /* transfer transferred */
+ atmegadci_device_done(xfer, std->err);
+ }
+ goto done;
+ }
+ /* buffer reset */
+ std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
+ std->len = 0;
+
+ value = UGETW(std->req.wValue);
+ index = UGETW(std->req.wIndex);
+
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
+
+ /* demultiplex the control request */
+
+ switch (std->req.bmRequestType) {
+ case UT_READ_DEVICE:
+ switch (std->req.bRequest) {
+ case UR_GET_DESCRIPTOR:
+ goto tr_handle_get_descriptor;
+ case UR_GET_CONFIG:
+ goto tr_handle_get_config;
+ case UR_GET_STATUS:
+ goto tr_handle_get_status;
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_WRITE_DEVICE:
+ switch (std->req.bRequest) {
+ case UR_SET_ADDRESS:
+ goto tr_handle_set_address;
+ case UR_SET_CONFIG:
+ goto tr_handle_set_config;
+ case UR_CLEAR_FEATURE:
+ goto tr_valid; /* nop */
+ case UR_SET_DESCRIPTOR:
+ goto tr_valid; /* nop */
+ case UR_SET_FEATURE:
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_WRITE_ENDPOINT:
+ switch (std->req.bRequest) {
+ case UR_CLEAR_FEATURE:
+ switch (UGETW(std->req.wValue)) {
+ case UF_ENDPOINT_HALT:
+ goto tr_handle_clear_halt;
+ case UF_DEVICE_REMOTE_WAKEUP:
+ goto tr_handle_clear_wakeup;
+ default:
+ goto tr_stalled;
+ }
+ break;
+ case UR_SET_FEATURE:
+ switch (UGETW(std->req.wValue)) {
+ case UF_ENDPOINT_HALT:
+ goto tr_handle_set_halt;
+ case UF_DEVICE_REMOTE_WAKEUP:
+ goto tr_handle_set_wakeup;
+ default:
+ goto tr_stalled;
+ }
+ break;
+ case UR_SYNCH_FRAME:
+ goto tr_valid; /* nop */
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_READ_ENDPOINT:
+ switch (std->req.bRequest) {
+ case UR_GET_STATUS:
+ goto tr_handle_get_ep_status;
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_WRITE_INTERFACE:
+ switch (std->req.bRequest) {
+ case UR_SET_INTERFACE:
+ goto tr_handle_set_interface;
+ case UR_CLEAR_FEATURE:
+ goto tr_valid; /* nop */
+ case UR_SET_FEATURE:
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_READ_INTERFACE:
+ switch (std->req.bRequest) {
+ case UR_GET_INTERFACE:
+ goto tr_handle_get_interface;
+ case UR_GET_STATUS:
+ goto tr_handle_get_iface_status;
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_WRITE_CLASS_INTERFACE:
+ case UT_WRITE_VENDOR_INTERFACE:
+ /* XXX forward */
+ break;
+
+ case UT_READ_CLASS_INTERFACE:
+ case UT_READ_VENDOR_INTERFACE:
+ /* XXX forward */
+ break;
+
+ case UT_WRITE_CLASS_DEVICE:
+ switch (std->req.bRequest) {
+ case UR_CLEAR_FEATURE:
+ goto tr_valid;
+ case UR_SET_DESCRIPTOR:
+ case UR_SET_FEATURE:
+ break;
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_WRITE_CLASS_OTHER:
+ switch (std->req.bRequest) {
+ case UR_CLEAR_FEATURE:
+ goto tr_handle_clear_port_feature;
+ case UR_SET_FEATURE:
+ goto tr_handle_set_port_feature;
+ case UR_CLEAR_TT_BUFFER:
+ case UR_RESET_TT:
+ case UR_STOP_TT:
+ goto tr_valid;
+
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_READ_CLASS_OTHER:
+ switch (std->req.bRequest) {
+ case UR_GET_TT_STATE:
+ goto tr_handle_get_tt_state;
+ case UR_GET_STATUS:
+ goto tr_handle_get_port_status;
+ default:
+ goto tr_stalled;
+ }
+ break;
+
+ case UT_READ_CLASS_DEVICE:
+ switch (std->req.bRequest) {
+ case UR_GET_DESCRIPTOR:
+ goto tr_handle_get_class_descriptor;
+ case UR_GET_STATUS:
+ goto tr_handle_get_class_status;
+
+ default:
+ goto tr_stalled;
+ }
+ break;
+ default:
+ goto tr_stalled;
+ }
+ goto tr_valid;
+
+tr_handle_get_descriptor:
+ switch (value >> 8) {
+ case UDESC_DEVICE:
+ if (value & 0xff) {
+ goto tr_stalled;
+ }
+ std->len = sizeof(atmegadci_devd);
+ std->ptr = USB_ADD_BYTES(&atmegadci_devd, 0);
+ goto tr_valid;
+ case UDESC_CONFIG:
+ if (value & 0xff) {
+ goto tr_stalled;
+ }
+ std->len = sizeof(atmegadci_confd);
+ std->ptr = USB_ADD_BYTES(&atmegadci_confd, 0);
+ goto tr_valid;
+ case UDESC_STRING:
+ switch (value & 0xff) {
+ case 0: /* Language table */
+ std->len = sizeof(atmegadci_langtab);
+ std->ptr = USB_ADD_BYTES(&atmegadci_langtab, 0);
+ goto tr_valid;
+
+ case 1: /* Vendor */
+ std->len = sizeof(atmegadci_vendor);
+ std->ptr = USB_ADD_BYTES(&atmegadci_vendor, 0);
+ goto tr_valid;
+
+ case 2: /* Product */
+ std->len = sizeof(atmegadci_product);
+ std->ptr = USB_ADD_BYTES(&atmegadci_product, 0);
+ goto tr_valid;
+ default:
+ break;
+ }
+ break;
+ default:
+ goto tr_stalled;
+ }
+ goto tr_stalled;
+
+tr_handle_get_config:
+ std->len = 1;
+ sc->sc_hub_temp.wValue[0] = sc->sc_conf;
+ goto tr_valid;
+
+tr_handle_get_status:
+ std->len = 2;
+ USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
+ goto tr_valid;
+
+tr_handle_set_address:
+ if (value & 0xFF00) {
+ goto tr_stalled;
+ }
+ sc->sc_rt_addr = value;
+ goto tr_valid;
+
+tr_handle_set_config:
+ if (value >= 2) {
+ goto tr_stalled;
+ }
+ sc->sc_conf = value;
+ goto tr_valid;
+
+tr_handle_get_interface:
+ std->len = 1;
+ sc->sc_hub_temp.wValue[0] = 0;
+ goto tr_valid;
+
+tr_handle_get_tt_state:
+tr_handle_get_class_status:
+tr_handle_get_iface_status:
+tr_handle_get_ep_status:
+ std->len = 2;
+ USETW(sc->sc_hub_temp.wValue, 0);
+ goto tr_valid;
+
+tr_handle_set_halt:
+tr_handle_set_interface:
+tr_handle_set_wakeup:
+tr_handle_clear_wakeup:
+tr_handle_clear_halt:
+ goto tr_valid;
+
+tr_handle_clear_port_feature:
+ if (index != 1) {
+ goto tr_stalled;
+ }
+ DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
+
+ switch (value) {
+ case UHF_PORT_SUSPEND:
+ atmegadci_wakeup_peer(xfer);
+ break;
+
+ case UHF_PORT_ENABLE:
+ sc->sc_flags.port_enabled = 0;
+ break;
+
+ case UHF_PORT_TEST:
+ case UHF_PORT_INDICATOR:
+ case UHF_C_PORT_ENABLE:
+ case UHF_C_PORT_OVER_CURRENT:
+ case UHF_C_PORT_RESET:
+ /* nops */
+ break;
+ case UHF_PORT_POWER:
+ sc->sc_flags.port_powered = 0;
+ atmegadci_pull_down(sc);
+ atmegadci_clocks_off(sc);
+ break;
+ case UHF_C_PORT_CONNECTION:
+ sc->sc_flags.change_connect = 0;
+ break;
+ case UHF_C_PORT_SUSPEND:
+ sc->sc_flags.change_suspend = 0;
+ break;
+ default:
+ std->err = USB_ERR_IOERROR;
+ goto done;
+ }
+ goto tr_valid;
+
+tr_handle_set_port_feature:
+ if (index != 1) {
+ goto tr_stalled;
+ }
+ DPRINTFN(9, "UR_SET_PORT_FEATURE\n");
+
+ switch (value) {
+ case UHF_PORT_ENABLE:
+ sc->sc_flags.port_enabled = 1;
+ break;
+ case UHF_PORT_SUSPEND:
+ case UHF_PORT_RESET:
+ case UHF_PORT_TEST:
+ case UHF_PORT_INDICATOR:
+ /* nops */
+ break;
+ case UHF_PORT_POWER:
+ sc->sc_flags.port_powered = 1;
+ break;
+ default:
+ std->err = USB_ERR_IOERROR;
+ goto done;
+ }
+ goto tr_valid;
+
+tr_handle_get_port_status:
+
+ DPRINTFN(9, "UR_GET_PORT_STATUS\n");
+
+ if (index != 1) {
+ goto tr_stalled;
+ }
+ if (sc->sc_flags.status_vbus) {
+ atmegadci_clocks_on(sc);
+ atmegadci_pull_up(sc);
+ } else {
+ atmegadci_pull_down(sc);
+ atmegadci_clocks_off(sc);
+ }
+
+ /* Select FULL-speed and Device Side Mode */
+
+ value = UPS_PORT_MODE_DEVICE;
+
+ if (sc->sc_flags.port_powered) {
+ value |= UPS_PORT_POWER;
+ }
+ if (sc->sc_flags.port_enabled) {
+ value |= UPS_PORT_ENABLED;
+ }
+ if (sc->sc_flags.status_vbus &&
+ sc->sc_flags.status_bus_reset) {
+ value |= UPS_CURRENT_CONNECT_STATUS;
+ }
+ if (sc->sc_flags.status_suspend) {
+ value |= UPS_SUSPEND;
+ }
+ USETW(sc->sc_hub_temp.ps.wPortStatus, value);
+
+ value = 0;
+
+ if (sc->sc_flags.change_connect) {
+ value |= UPS_C_CONNECT_STATUS;
+ }
+ if (sc->sc_flags.change_suspend) {
+ value |= UPS_C_SUSPEND;
+ }
+ USETW(sc->sc_hub_temp.ps.wPortChange, value);
+ std->len = sizeof(sc->sc_hub_temp.ps);
+ goto tr_valid;
+
+tr_handle_get_class_descriptor:
+ if (value & 0xFF) {
+ goto tr_stalled;
+ }
+ std->ptr = USB_ADD_BYTES(&atmegadci_hubd, 0);
+ std->len = sizeof(atmegadci_hubd);
+ goto tr_valid;
+
+tr_stalled:
+ std->err = USB_ERR_STALLED;
+tr_valid:
+done:
+ return;
+}
+
+static void
+atmegadci_root_ctrl_poll(struct atmegadci_softc *sc)
+{
+ usb2_sw_transfer(&sc->sc_root_ctrl,
+ &atmegadci_root_ctrl_done);
+}
+
+struct usb2_pipe_methods atmegadci_root_ctrl_methods =
+{
+ .open = atmegadci_root_ctrl_open,
+ .close = atmegadci_root_ctrl_close,
+ .enter = atmegadci_root_ctrl_enter,
+ .start = atmegadci_root_ctrl_start,
+ .enter_is_cancelable = 1,
+ .start_is_cancelable = 0,
+};
+
+/*------------------------------------------------------------------------*
+ * at91dci root interrupt support
+ *------------------------------------------------------------------------*/
+static void
+atmegadci_root_intr_open(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_root_intr_close(struct usb2_xfer *xfer)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+
+ if (sc->sc_root_intr.xfer == xfer) {
+ sc->sc_root_intr.xfer = NULL;
+ }
+ atmegadci_device_done(xfer, USB_ERR_CANCELLED);
+}
+
+static void
+atmegadci_root_intr_enter(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_root_intr_start(struct usb2_xfer *xfer)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
+
+ sc->sc_root_intr.xfer = xfer;
+}
+
+struct usb2_pipe_methods atmegadci_root_intr_methods =
+{
+ .open = atmegadci_root_intr_open,
+ .close = atmegadci_root_intr_close,
+ .enter = atmegadci_root_intr_enter,
+ .start = atmegadci_root_intr_start,
+ .enter_is_cancelable = 1,
+ .start_is_cancelable = 1,
+};
+
+static void
+atmegadci_xfer_setup(struct usb2_setup_params *parm)
+{
+ const struct usb2_hw_ep_profile *pf;
+ struct atmegadci_softc *sc;
+ struct usb2_xfer *xfer;
+ void *last_obj;
+ uint32_t ntd;
+ uint32_t n;
+ uint8_t ep_no;
+
+ sc = ATMEGA_BUS2SC(parm->udev->bus);
+ xfer = parm->curr_xfer;
+
+ /*
+ * NOTE: This driver does not use any of the parameters that
+ * are computed from the following values. Just set some
+ * reasonable dummies:
+ */
+ parm->hc_max_packet_size = 0x500;
+ parm->hc_max_packet_count = 1;
+ parm->hc_max_frame_size = 0x500;
+
+ usb2_transfer_setup_sub(parm);
+
+ /*
+ * compute maximum number of TDs
+ */
+ if (parm->methods == &atmegadci_device_ctrl_methods) {
+
+ ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */
+ + 1 /* SYNC 2 */ ;
+
+ } else if (parm->methods == &atmegadci_device_bulk_methods) {
+
+ ntd = xfer->nframes + 1 /* SYNC */ ;
+
+ } else if (parm->methods == &atmegadci_device_intr_methods) {
+
+ ntd = xfer->nframes + 1 /* SYNC */ ;
+
+ } else if (parm->methods == &atmegadci_device_isoc_fs_methods) {
+
+ ntd = xfer->nframes + 1 /* SYNC */ ;
+
+ } else {
+
+ ntd = 0;
+ }
+
+ /*
+ * check if "usb2_transfer_setup_sub" set an error
+ */
+ if (parm->err) {
+ return;
+ }
+ /*
+ * allocate transfer descriptors
+ */
+ last_obj = NULL;
+
+ /*
+ * get profile stuff
+ */
+ if (ntd) {
+
+ ep_no = xfer->endpoint & UE_ADDR;
+ atmegadci_get_hw_ep_profile(parm->udev, &pf, ep_no);
+
+ if (pf == NULL) {
+ /* should not happen */
+ parm->err = USB_ERR_INVAL;
+ return;
+ }
+ } else {
+ ep_no = 0;
+ pf = NULL;
+ }
+
+ /* align data */
+ parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
+
+ for (n = 0; n != ntd; n++) {
+
+ struct atmegadci_td *td;
+
+ if (parm->buf) {
+
+ td = USB_ADD_BYTES(parm->buf, parm->size[0]);
+
+ /* init TD */
+ td->max_packet_size = xfer->max_packet_size;
+ td->ep_no = ep_no;
+ if (pf->support_multi_buffer) {
+ td->support_multi_buffer = 1;
+ }
+ td->obj_next = last_obj;
+
+ last_obj = td;
+ }
+ parm->size[0] += sizeof(*td);
+ }
+
+ xfer->td_start[0] = last_obj;
+}
+
+static void
+atmegadci_xfer_unsetup(struct usb2_xfer *xfer)
+{
+ return;
+}
+
+static void
+atmegadci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
+ struct usb2_pipe *pipe)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(udev->bus);
+
+ DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
+ pipe, udev->address,
+ edesc->bEndpointAddress, udev->flags.usb2_mode,
+ sc->sc_rt_addr);
+
+ if (udev->device_index == sc->sc_rt_addr) {
+
+ if (udev->flags.usb2_mode != USB_MODE_HOST) {
+ /* not supported */
+ return;
+ }
+ switch (edesc->bEndpointAddress) {
+ case USB_CONTROL_ENDPOINT:
+ pipe->methods = &atmegadci_root_ctrl_methods;
+ break;
+ case UE_DIR_IN | ATMEGA_INTR_ENDPT:
+ pipe->methods = &atmegadci_root_intr_methods;
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ } else {
+
+ if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
+ /* not supported */
+ return;
+ }
+ if (udev->speed != USB_SPEED_FULL) {
+ /* not supported */
+ return;
+ }
+ switch (edesc->bmAttributes & UE_XFERTYPE) {
+ case UE_CONTROL:
+ pipe->methods = &atmegadci_device_ctrl_methods;
+ break;
+ case UE_INTERRUPT:
+ pipe->methods = &atmegadci_device_intr_methods;
+ break;
+ case UE_ISOCHRONOUS:
+ pipe->methods = &atmegadci_device_isoc_fs_methods;
+ break;
+ case UE_BULK:
+ pipe->methods = &atmegadci_device_bulk_methods;
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+}
+
+struct usb2_bus_methods atmegadci_bus_methods =
+{
+ .pipe_init = &atmegadci_pipe_init,
+ .xfer_setup = &atmegadci_xfer_setup,
+ .xfer_unsetup = &atmegadci_xfer_unsetup,
+ .do_poll = &atmegadci_do_poll,
+ .get_hw_ep_profile = &atmegadci_get_hw_ep_profile,
+ .set_stall = &atmegadci_set_stall,
+ .clear_stall = &atmegadci_clear_stall,
+ .roothub_exec = &atmegadci_root_ctrl_task,
+};
diff --git a/sys/dev/usb2/controller/atmegadci.h b/sys/dev/usb2/controller/atmegadci.h
new file mode 100644
index 0000000..90b3334
--- /dev/null
+++ b/sys/dev/usb2/controller/atmegadci.h
@@ -0,0 +1,273 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * USB Device Port register definitions, copied from ATMEGA
+ * documentation provided by ATMEL.
+ */
+
+#ifndef _ATMEGADCI_H_
+#define _ATMEGADCI_H_
+
+#define ATMEGA_MAX_DEVICES (USB_MIN_DEVICES + 1)
+
+#ifndef ATMEGA_HAVE_BUS_SPACE
+#define ATMEGA_HAVE_BUS_SPACE 1
+#endif
+
+#define ATMEGA_UEINT 0xF4
+#define ATMEGA_UEINT_MASK(n) (1 << (n)) /* endpoint interrupt mask */
+
+#define ATMEGA_UEBCHX 0xF3 /* FIFO byte count high */
+#define ATMEGA_UEBCLX 0xF2 /* FIFO byte count low */
+#define ATMEGA_UEDATX 0xF1 /* FIFO data */
+
+#define ATMEGA_UEIENX 0xF0 /* interrupt enable register */
+#define ATMEGA_UEIENX_TXINE (1 << 0)
+#define ATMEGA_UEIENX_STALLEDE (1 << 1)
+#define ATMEGA_UEIENX_RXOUTE (1 << 2)
+#define ATMEGA_UEIENX_RXSTPE (1 << 3) /* received SETUP packet */
+#define ATMEGA_UEIENX_NAKOUTE (1 << 4)
+#define ATMEGA_UEIENX_NAKINE (1 << 6)
+#define ATMEGA_UEIENX_FLERRE (1 << 7)
+
+#define ATMEGA_UESTA1X 0xEF
+#define ATMEGA_UESTA1X_CURRBK (3 << 0) /* current bank */
+#define ATMEGA_UESTA1X_CTRLDIR (1 << 2) /* control endpoint direction */
+
+#define ATMEGA_UESTA0X 0xEE
+#define ATMEGA_UESTA0X_NBUSYBK (3 << 0)
+#define ATMEGA_UESTA0X_DTSEQ (3 << 2)
+#define ATMEGA_UESTA0X_UNDERFI (1 << 5) /* underflow */
+#define ATMEGA_UESTA0X_OVERFI (1 << 6) /* overflow */
+#define ATMEGA_UESTA0X_CFGOK (1 << 7)
+
+#define ATMEGA_UECFG1X 0xED /* endpoint config register */
+#define ATMEGA_UECFG1X_ALLOC (1 << 1)
+#define ATMEGA_UECFG1X_EPBK0 (0 << 2)
+#define ATMEGA_UECFG1X_EPBK1 (1 << 2)
+#define ATMEGA_UECFG1X_EPBK2 (2 << 2)
+#define ATMEGA_UECFG1X_EPBK3 (3 << 2)
+#define ATMEGA_UECFG1X_EPSIZE(n) ((n) << 4)
+
+#define ATMEGA_UECFG0X 0xEC
+#define ATMEGA_UECFG0X_EPDIR (1 << 0) /* endpoint direction */
+#define ATMEGA_UECFG0X_EPTYPE0 (0 << 6)
+#define ATMEGA_UECFG0X_EPTYPE1 (1 << 6)
+#define ATMEGA_UECFG0X_EPTYPE2 (2 << 6)
+#define ATMEGA_UECFG0X_EPTYPE3 (3 << 6)
+
+#define ATMEGA_UECONX 0xEB
+#define ATMEGA_UECONX_EPEN (1 << 0)
+#define ATMEGA_UECONX_RSTDT (1 << 3)
+#define ATMEGA_UECONX_STALLRQC (1 << 4) /* stall request clear */
+#define ATMEGA_UECONX_STALLRQ (1 << 5) /* stall request set */
+
+#define ATMEGA_UERST 0xEA /* endpoint reset register */
+#define ATMEGA_UERST_MASK(n) (1 << (n))
+
+#define ATMEGA_UENUM 0xE9 /* endpoint number */
+
+#define ATMEGA_UEINTX 0xE8 /* interrupt register */
+#define ATMEGA_UEINTX_TXINI (1 << 0)
+#define ATMEGA_UEINTX_STALLEDI (1 << 1)
+#define ATMEGA_UEINTX_RXOUTI (1 << 2)
+#define ATMEGA_UEINTX_RXSTPI (1 << 3) /* received setup packet */
+#define ATMEGA_UEINTX_NAKOUTI (1 << 4)
+#define ATMEGA_UEINTX_RWAL (1 << 5)
+#define ATMEGA_UEINTX_NAKINI (1 << 6)
+#define ATMEGA_UEINTX_FIFOCON (1 << 7)
+
+#define ATMEGA_UDMFN 0xE6
+#define ATMEGA_UDMFN_FNCERR (1 << 4)
+
+#define ATMEGA_UDFNUMH 0xE5 /* frame number high */
+#define ATMEGA_UDFNUMH_MASK 7
+
+#define ATMEGA_UDFNUML 0xE4 /* frame number low */
+#define ATMEGA_UDFNUML_MASK 0xFF
+
+#define ATMEGA_FRAME_MASK 0x7FF
+
+#define ATMEGA_UDADDR 0xE3 /* USB address */
+#define ATMEGA_UDADDR_MASK 0x7F
+#define ATMEGA_UDADDR_ADDEN (1 << 7)
+
+#define ATMEGA_UDIEN 0xE2 /* USB device interrupt enable */
+#define ATMEGA_UDINT_SUSPE (1 << 0)
+#define ATMEGA_UDINT_MSOFE (1 << 1)
+#define ATMEGA_UDINT_SOFE (1 << 2)
+#define ATMEGA_UDINT_EORSTE (1 << 3)
+#define ATMEGA_UDINT_WAKEUPE (1 << 4)
+#define ATMEGA_UDINT_EORSME (1 << 5)
+#define ATMEGA_UDINT_UPRSME (1 << 6)
+
+#define ATMEGA_UDINT 0xE1 /* USB device interrupt status */
+#define ATMEGA_UDINT_SUSPI (1 << 0)
+#define ATMEGA_UDINT_MSOFI (1 << 1)
+#define ATMEGA_UDINT_SOFI (1 << 2)
+#define ATMEGA_UDINT_EORSTI (1 << 3)
+#define ATMEGA_UDINT_WAKEUPI (1 << 4)
+#define ATMEGA_UDINT_EORSMI (1 << 5)
+#define ATMEGA_UDINT_UPRSMI (1 << 6)
+
+#define ATMEGA_UDCON 0xE0 /* USB device connection register */
+#define ATMEGA_UDCON_DETACH (1 << 0)
+#define ATMEGA_UDCON_RMWKUP (1 << 1)
+#define ATMEGA_UDCON_LSM (1 << 2)
+#define ATMEGA_UDCON_RSTCPU (1 << 3)
+
+#define ATMEGA_USBINT 0xDA
+#define ATMEGA_USBINT_VBUSTI (1 << 0) /* USB VBUS interrupt */
+
+#define ATMEGA_USBSTA 0xD9
+#define ATMEGA_USBSTA_VBUS (1 << 0)
+#define ATMEGA_USBSTA_ID (1 << 1)
+
+#define ATMEGA_USBCON 0xD8
+#define ATMEGA_USBCON_VBUSTE (1 << 0)
+#define ATMEGA_USBCON_OTGPADE (1 << 4)
+#define ATMEGA_USBCON_FRZCLK (1 << 5)
+#define ATMEGA_USBCON_USBE (1 << 7)
+
+#define ATMEGA_UHWCON 0xD7
+#define ATMEGA_UHWCON_UVREGE (1 << 0)
+
+#define ATMEGA_READ_1(sc, reg) \
+ bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
+
+#define ATMEGA_WRITE_1(sc, reg, data) \
+ bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
+
+#define ATMEGA_WRITE_MULTI_1(sc, reg, ptr, len) \
+ bus_space_write_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, ptr, len)
+
+#define ATMEGA_READ_MULTI_1(sc, reg, ptr, len) \
+ bus_space_read_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, ptr, len)
+
+/*
+ * Maximum number of endpoints supported:
+ */
+#define ATMEGA_EP_MAX 7
+
+struct atmegadci_td;
+
+typedef uint8_t (atmegadci_cmd_t)(struct atmegadci_td *td);
+typedef void (atmegadci_clocks_t)(struct usb2_bus *);
+
+struct atmegadci_td {
+ struct atmegadci_td *obj_next;
+ atmegadci_cmd_t *func;
+ struct usb2_page_cache *pc;
+ uint32_t offset;
+ uint32_t remainder;
+ uint16_t max_packet_size;
+ uint8_t error:1;
+ uint8_t alt_next:1;
+ uint8_t short_pkt:1;
+ uint8_t support_multi_buffer:1;
+ uint8_t did_stall:1;
+ uint8_t ep_no:3;
+};
+
+struct atmegadci_std_temp {
+ atmegadci_cmd_t *func;
+ struct usb2_page_cache *pc;
+ struct atmegadci_td *td;
+ struct atmegadci_td *td_next;
+ uint32_t len;
+ uint32_t offset;
+ uint16_t max_frame_size;
+ uint8_t short_pkt;
+ /*
+ * short_pkt = 0: transfer should be short terminated
+ * short_pkt = 1: transfer should not be short terminated
+ */
+ uint8_t setup_alt_next;
+};
+
+struct atmegadci_config_desc {
+ struct usb2_config_descriptor confd;
+ struct usb2_interface_descriptor ifcd;
+ struct usb2_endpoint_descriptor endpd;
+} __packed;
+
+union atmegadci_hub_temp {
+ uWord wValue;
+ struct usb2_port_status ps;
+};
+
+struct atmegadci_flags {
+ uint8_t change_connect:1;
+ uint8_t change_suspend:1;
+ uint8_t status_suspend:1; /* set if suspended */
+ uint8_t status_vbus:1; /* set if present */
+ uint8_t status_bus_reset:1; /* set if reset complete */
+ uint8_t remote_wakeup:1;
+ uint8_t self_powered:1;
+ uint8_t clocks_off:1;
+ uint8_t port_powered:1;
+ uint8_t port_enabled:1;
+ uint8_t d_pulled_up:1;
+};
+
+struct atmegadci_softc {
+ struct usb2_bus sc_bus;
+ union atmegadci_hub_temp sc_hub_temp;
+ LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
+ struct usb2_sw_transfer sc_root_ctrl;
+ struct usb2_sw_transfer sc_root_intr;
+
+ /* must be set by by the bus interface layer */
+ atmegadci_clocks_t *sc_clocks_on;
+ atmegadci_clocks_t *sc_clocks_off;
+
+ struct usb2_device *sc_devices[ATMEGA_MAX_DEVICES];
+ struct resource *sc_irq_res;
+ void *sc_intr_hdl;
+#if (ATMEGA_HAVE_BUS_SPACE != 0)
+ struct resource *sc_io_res;
+ bus_space_tag_t sc_io_tag;
+ bus_space_handle_t sc_io_hdl;
+#endif
+ uint8_t sc_rt_addr; /* root hub address */
+ uint8_t sc_dv_addr; /* device address */
+ uint8_t sc_conf; /* root hub config */
+
+ uint8_t sc_hub_idata[1];
+
+ struct atmegadci_flags sc_flags;
+};
+
+/* prototypes */
+
+usb2_error_t atmegadci_init(struct atmegadci_softc *sc);
+void atmegadci_uninit(struct atmegadci_softc *sc);
+void atmegadci_suspend(struct atmegadci_softc *sc);
+void atmegadci_resume(struct atmegadci_softc *sc);
+void atmegadci_interrupt(struct atmegadci_softc *sc);
+
+#endif /* _ATMEGADCI_H_ */
diff --git a/sys/dev/usb2/controller/atmegadci_atmelarm.c b/sys/dev/usb2/controller/atmegadci_atmelarm.c
new file mode 100644
index 0000000..e63f5cc
--- /dev/null
+++ b/sys/dev/usb2/controller/atmegadci_atmelarm.c
@@ -0,0 +1,27 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
diff --git a/sys/dev/usb2/controller/ehci2.c b/sys/dev/usb2/controller/ehci2.c
index fdecd7c..f55e834 100644
--- a/sys/dev/usb2/controller/ehci2.c
+++ b/sys/dev/usb2/controller/ehci2.c
@@ -52,14 +52,11 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR ehcidebug
-#define usb2_config_td_cc ehci_config_copy
-#define usb2_config_td_softc ehci_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
@@ -84,7 +81,7 @@ SYSCTL_INT(_hw_usb2_ehci, OID_AUTO, no_hs, CTLFLAG_RW,
&ehcinohighspeed, 0, "Disable High Speed USB");
static void ehci_dump_regs(ehci_softc_t *sc);
-static void ehci_dump_sqh(ehci_qh_t *sqh);
+static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh);
#endif
@@ -99,9 +96,8 @@ extern struct usb2_pipe_methods ehci_device_isoc_hs_methods;
extern struct usb2_pipe_methods ehci_root_ctrl_methods;
extern struct usb2_pipe_methods ehci_root_intr_methods;
-static usb2_config_td_command_t ehci_root_ctrl_task;
static void ehci_do_poll(struct usb2_bus *bus);
-static void ehci_root_ctrl_poll(struct ehci_softc *sc);
+static void ehci_root_ctrl_poll(ehci_softc_t *sc);
static void ehci_device_done(struct usb2_xfer *xfer, usb2_error_t error);
static uint8_t ehci_check_transfer(struct usb2_xfer *xfer);
static void ehci_timeout(void *arg);
@@ -110,6 +106,7 @@ static usb2_sw_transfer_func_t ehci_root_intr_done;
static usb2_sw_transfer_func_t ehci_root_ctrl_done;
struct ehci_std_temp {
+ ehci_softc_t *sc;
struct usb2_page_cache *pc;
ehci_qtd_t *td;
ehci_qtd_t *td_next;
@@ -123,10 +120,27 @@ struct ehci_std_temp {
uint8_t short_frames_ok;
};
+/*
+ * Byte-order conversion functions.
+ */
+static uint32_t
+htoehci32(ehci_softc_t *sc, const uint32_t v)
+{
+ return ((sc->sc_flags & EHCI_SCFLG_BIGEDESC) ?
+ htobe32(v) : htole32(v));
+}
+
+static uint32_t
+ehci32toh(ehci_softc_t *sc, const uint32_t v)
+{
+ return ((sc->sc_flags & EHCI_SCFLG_BIGEDESC) ?
+ be32toh(v) : le32toh(v));
+}
+
void
ehci_iterate_hw_softc(struct usb2_bus *bus, usb2_bus_mem_sub_cb_t *cb)
{
- struct ehci_softc *sc = EHCI_BUS2SC(bus);
+ ehci_softc_t *sc = EHCI_BUS2SC(bus);
uint32_t i;
cb(bus, &sc->sc_hw.pframes_pc, &sc->sc_hw.pframes_pg,
@@ -209,8 +223,6 @@ ehci_init(ehci_softc_t *sc)
uint16_t bit;
usb2_error_t err = 0;
- USB_BUS_LOCK(&sc->sc_bus);
-
DPRINTF("start\n");
usb2_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0);
@@ -245,10 +257,12 @@ ehci_init(ehci_softc_t *sc)
/* Reset the controller */
DPRINTF("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev));
+ USB_BUS_LOCK(&sc->sc_bus);
err = ehci_hc_reset(sc);
+ USB_BUS_UNLOCK(&sc->sc_bus);
if (err) {
device_printf(sc->sc_bus.bdev, "reset timeout\n");
- goto done;
+ return (err);
}
/*
* use current frame-list-size selection 0: 1024*4 bytes 1: 512*4
@@ -256,8 +270,7 @@ ehci_init(ehci_softc_t *sc)
*/
if (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD)) == 3) {
device_printf(sc->sc_bus.bdev, "invalid frame-list-size\n");
- err = USB_ERR_IOERROR;
- goto done;
+ return (USB_ERR_IOERROR);
}
/* set up the bus struct */
sc->sc_bus.methods = &ehci_bus_methods;
@@ -280,21 +293,21 @@ ehci_init(ehci_softc_t *sc)
sc->sc_intr_p_last[i] = qh;
qh->qh_self =
- htole32(buf_res.physaddr) |
- htole32(EHCI_LINK_QH);
+ htoehci32(sc, buf_res.physaddr) |
+ htoehci32(sc, EHCI_LINK_QH);
qh->qh_endp =
- htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
+ htoehci32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
qh->qh_endphub =
- htole32(EHCI_QH_SET_MULT(1));
+ htoehci32(sc, EHCI_QH_SET_MULT(1));
qh->qh_curqtd = 0;
qh->qh_qtd.qtd_next =
- htole32(EHCI_LINK_TERMINATE);
+ htoehci32(sc, EHCI_LINK_TERMINATE);
qh->qh_qtd.qtd_altnext =
- htole32(EHCI_LINK_TERMINATE);
+ htoehci32(sc, EHCI_LINK_TERMINATE);
qh->qh_qtd.qtd_status =
- htole32(EHCI_QTD_HALTED);
+ htoehci32(sc, EHCI_QTD_HALTED);
}
/*
@@ -329,7 +342,7 @@ ehci_init(ehci_softc_t *sc)
qh = sc->sc_intr_p_last[0];
/* the last (1ms) QH terminates */
- qh->qh_link = htole32(EHCI_LINK_TERMINATE);
+ qh->qh_link = htoehci32(sc, EHCI_LINK_TERMINATE);
}
for (i = 0; i < EHCI_VIRTUAL_FRAMELIST_COUNT; i++) {
ehci_sitd_t *sitd;
@@ -350,11 +363,11 @@ ehci_init(ehci_softc_t *sc)
/* initialize full speed isochronous */
sitd->sitd_self =
- htole32(buf_res.physaddr) |
- htole32(EHCI_LINK_SITD);
+ htoehci32(sc, buf_res.physaddr) |
+ htoehci32(sc, EHCI_LINK_SITD);
sitd->sitd_back =
- htole32(EHCI_LINK_TERMINATE);
+ htoehci32(sc, EHCI_LINK_TERMINATE);
sitd->sitd_next =
sc->sc_intr_p_last[i | (EHCI_VIRTUAL_FRAMELIST_COUNT / 2)]->qh_self;
@@ -375,8 +388,8 @@ ehci_init(ehci_softc_t *sc)
/* initialize high speed isochronous */
itd->itd_self =
- htole32(buf_res.physaddr) |
- htole32(EHCI_LINK_ITD);
+ htoehci32(sc, buf_res.physaddr) |
+ htoehci32(sc, EHCI_LINK_ITD);
itd->itd_next =
sitd->sitd_self;
@@ -421,20 +434,20 @@ ehci_init(ehci_softc_t *sc)
/* init dummy QH that starts the async list */
qh->qh_self =
- htole32(buf_res.physaddr) |
- htole32(EHCI_LINK_QH);
+ htoehci32(sc, buf_res.physaddr) |
+ htoehci32(sc, EHCI_LINK_QH);
/* fill the QH */
qh->qh_endp =
- htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
- qh->qh_endphub = htole32(EHCI_QH_SET_MULT(1));
+ htoehci32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
+ qh->qh_endphub = htoehci32(sc, EHCI_QH_SET_MULT(1));
qh->qh_link = qh->qh_self;
qh->qh_curqtd = 0;
/* fill the overlay qTD */
- qh->qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE);
- qh->qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
- qh->qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
+ qh->qh_qtd.qtd_next = htoehci32(sc, EHCI_LINK_TERMINATE);
+ qh->qh_qtd.qtd_altnext = htoehci32(sc, EHCI_LINK_TERMINATE);
+ qh->qh_qtd.qtd_status = htoehci32(sc, EHCI_QTD_HALTED);
}
/* flush all cache into memory */
@@ -442,7 +455,7 @@ ehci_init(ehci_softc_t *sc)
#if USB_DEBUG
if (ehcidebug) {
- ehci_dump_sqh(sc->sc_async_p_last);
+ ehci_dump_sqh(sc, sc->sc_async_p_last);
}
#endif
@@ -465,7 +478,7 @@ ehci_init(ehci_softc_t *sc)
EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
for (i = 0; i < 100; i++) {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
+ usb2_pause_mtx(NULL, 1);
hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
if (!hcr) {
break;
@@ -473,11 +486,8 @@ ehci_init(ehci_softc_t *sc)
}
if (hcr) {
device_printf(sc->sc_bus.bdev, "run timeout\n");
- err = USB_ERR_IOERROR;
- goto done;
+ return (USB_ERR_IOERROR);
}
-done:
- USB_BUS_UNLOCK(&sc->sc_bus);
if (!err) {
/* catch any lost interrupts */
@@ -490,7 +500,7 @@ done:
* shut down the controller when the system is going down
*/
void
-ehci_detach(struct ehci_softc *sc)
+ehci_detach(ehci_softc_t *sc)
{
USB_BUS_LOCK(&sc->sc_bus);
@@ -510,7 +520,7 @@ ehci_detach(struct ehci_softc *sc)
}
void
-ehci_suspend(struct ehci_softc *sc)
+ehci_suspend(ehci_softc_t *sc)
{
uint32_t cmd;
uint32_t hcr;
@@ -564,7 +574,7 @@ ehci_suspend(struct ehci_softc *sc)
}
void
-ehci_resume(struct ehci_softc *sc)
+ehci_resume(ehci_softc_t *sc)
{
struct usb2_page_search buf_res;
uint32_t cmd;
@@ -723,9 +733,9 @@ ehci_dump_regs(ehci_softc_t *sc)
}
static void
-ehci_dump_link(uint32_t link, int type)
+ehci_dump_link(ehci_softc_t *sc, uint32_t link, int type)
{
- link = le32toh(link);
+ link = ehci32toh(sc, link);
printf("0x%08x", link);
if (link & EHCI_LINK_TERMINATE)
printf("<T>");
@@ -752,16 +762,16 @@ ehci_dump_link(uint32_t link, int type)
}
static void
-ehci_dump_qtd(ehci_qtd_t *qtd)
+ehci_dump_qtd(ehci_softc_t *sc, ehci_qtd_t *qtd)
{
uint32_t s;
printf(" next=");
- ehci_dump_link(qtd->qtd_next, 0);
+ ehci_dump_link(sc, qtd->qtd_next, 0);
printf(" altnext=");
- ehci_dump_link(qtd->qtd_altnext, 0);
+ ehci_dump_link(sc, qtd->qtd_altnext, 0);
printf("\n");
- s = le32toh(qtd->qtd_status);
+ s = ehci32toh(sc, qtd->qtd_status);
printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
@@ -778,35 +788,35 @@ ehci_dump_qtd(ehci_qtd_t *qtd)
for (s = 0; s < 5; s++) {
printf(" buffer[%d]=0x%08x\n", s,
- le32toh(qtd->qtd_buffer[s]));
+ ehci32toh(sc, qtd->qtd_buffer[s]));
}
for (s = 0; s < 5; s++) {
printf(" buffer_hi[%d]=0x%08x\n", s,
- le32toh(qtd->qtd_buffer_hi[s]));
+ ehci32toh(sc, qtd->qtd_buffer_hi[s]));
}
}
static uint8_t
-ehci_dump_sqtd(ehci_qtd_t *sqtd)
+ehci_dump_sqtd(ehci_softc_t *sc, ehci_qtd_t *sqtd)
{
uint8_t temp;
usb2_pc_cpu_invalidate(sqtd->page_cache);
- printf("QTD(%p) at 0x%08x:\n", sqtd, le32toh(sqtd->qtd_self));
- ehci_dump_qtd(sqtd);
- temp = (sqtd->qtd_next & htole32(EHCI_LINK_TERMINATE)) ? 1 : 0;
+ printf("QTD(%p) at 0x%08x:\n", sqtd, ehci32toh(sc, sqtd->qtd_self));
+ ehci_dump_qtd(sc, sqtd);
+ temp = (sqtd->qtd_next & htoehci32(sc, EHCI_LINK_TERMINATE)) ? 1 : 0;
return (temp);
}
static void
-ehci_dump_sqtds(ehci_qtd_t *sqtd)
+ehci_dump_sqtds(ehci_softc_t *sc, ehci_qtd_t *sqtd)
{
uint16_t i;
uint8_t stop;
stop = 0;
for (i = 0; sqtd && (i < 20) && !stop; sqtd = sqtd->obj_next, i++) {
- stop = ehci_dump_sqtd(sqtd);
+ stop = ehci_dump_sqtd(sc, sqtd);
}
if (sqtd) {
printf("dump aborted, too many TDs\n");
@@ -814,16 +824,17 @@ ehci_dump_sqtds(ehci_qtd_t *sqtd)
}
static void
-ehci_dump_sqh(ehci_qh_t *qh)
+ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *qh)
{
- uint32_t endp, endphub;
+ uint32_t endp;
+ uint32_t endphub;
usb2_pc_cpu_invalidate(qh->page_cache);
- printf("QH(%p) at 0x%08x:\n", qh, le32toh(qh->qh_self) & ~0x1F);
+ printf("QH(%p) at 0x%08x:\n", qh, ehci32toh(sc, qh->qh_self) & ~0x1F);
printf(" link=");
- ehci_dump_link(qh->qh_link, 1);
+ ehci_dump_link(sc, qh->qh_link, 1);
printf("\n");
- endp = le32toh(qh->qh_endp);
+ endp = ehci32toh(sc, qh->qh_endp);
printf(" endp=0x%08x\n", endp);
printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
@@ -832,90 +843,90 @@ ehci_dump_sqh(ehci_qh_t *qh)
printf(" mpl=0x%x ctl=%d nrl=%d\n",
EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
EHCI_QH_GET_NRL(endp));
- endphub = le32toh(qh->qh_endphub);
+ endphub = ehci32toh(sc, qh->qh_endphub);
printf(" endphub=0x%08x\n", endphub);
printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
EHCI_QH_GET_MULT(endphub));
printf(" curqtd=");
- ehci_dump_link(qh->qh_curqtd, 0);
+ ehci_dump_link(sc, qh->qh_curqtd, 0);
printf("\n");
printf("Overlay qTD:\n");
- ehci_dump_qtd((void *)&qh->qh_qtd);
+ ehci_dump_qtd(sc, (void *)&qh->qh_qtd);
}
static void
-ehci_dump_sitd(ehci_sitd_t *sitd)
+ehci_dump_sitd(ehci_softc_t *sc, ehci_sitd_t *sitd)
{
usb2_pc_cpu_invalidate(sitd->page_cache);
- printf("SITD(%p) at 0x%08x\n", sitd, le32toh(sitd->sitd_self) & ~0x1F);
- printf(" next=0x%08x\n", le32toh(sitd->sitd_next));
+ printf("SITD(%p) at 0x%08x\n", sitd, ehci32toh(sc, sitd->sitd_self) & ~0x1F);
+ printf(" next=0x%08x\n", ehci32toh(sc, sitd->sitd_next));
printf(" portaddr=0x%08x dir=%s addr=%d endpt=0x%x port=0x%x huba=0x%x\n",
- le32toh(sitd->sitd_portaddr),
- (sitd->sitd_portaddr & htole32(EHCI_SITD_SET_DIR_IN))
+ ehci32toh(sc, sitd->sitd_portaddr),
+ (sitd->sitd_portaddr & htoehci32(sc, EHCI_SITD_SET_DIR_IN))
? "in" : "out",
- EHCI_SITD_GET_ADDR(le32toh(sitd->sitd_portaddr)),
- EHCI_SITD_GET_ENDPT(le32toh(sitd->sitd_portaddr)),
- EHCI_SITD_GET_PORT(le32toh(sitd->sitd_portaddr)),
- EHCI_SITD_GET_HUBA(le32toh(sitd->sitd_portaddr)));
- printf(" mask=0x%08x\n", le32toh(sitd->sitd_mask));
- printf(" status=0x%08x <%s> len=0x%x\n", le32toh(sitd->sitd_status),
- (sitd->sitd_status & htole32(EHCI_SITD_ACTIVE)) ? "ACTIVE" : "",
- EHCI_SITD_GET_LEN(le32toh(sitd->sitd_status)));
+ EHCI_SITD_GET_ADDR(ehci32toh(sc, sitd->sitd_portaddr)),
+ EHCI_SITD_GET_ENDPT(ehci32toh(sc, sitd->sitd_portaddr)),
+ EHCI_SITD_GET_PORT(ehci32toh(sc, sitd->sitd_portaddr)),
+ EHCI_SITD_GET_HUBA(ehci32toh(sc, sitd->sitd_portaddr)));
+ printf(" mask=0x%08x\n", ehci32toh(sc, sitd->sitd_mask));
+ printf(" status=0x%08x <%s> len=0x%x\n", ehci32toh(sc, sitd->sitd_status),
+ (sitd->sitd_status & htoehci32(sc, EHCI_SITD_ACTIVE)) ? "ACTIVE" : "",
+ EHCI_SITD_GET_LEN(ehci32toh(sc, sitd->sitd_status)));
printf(" back=0x%08x, bp=0x%08x,0x%08x,0x%08x,0x%08x\n",
- le32toh(sitd->sitd_back),
- le32toh(sitd->sitd_bp[0]),
- le32toh(sitd->sitd_bp[1]),
- le32toh(sitd->sitd_bp_hi[0]),
- le32toh(sitd->sitd_bp_hi[1]));
+ ehci32toh(sc, sitd->sitd_back),
+ ehci32toh(sc, sitd->sitd_bp[0]),
+ ehci32toh(sc, sitd->sitd_bp[1]),
+ ehci32toh(sc, sitd->sitd_bp_hi[0]),
+ ehci32toh(sc, sitd->sitd_bp_hi[1]));
}
static void
-ehci_dump_itd(ehci_itd_t *itd)
+ehci_dump_itd(ehci_softc_t *sc, ehci_itd_t *itd)
{
usb2_pc_cpu_invalidate(itd->page_cache);
- printf("ITD(%p) at 0x%08x\n", itd, le32toh(itd->itd_self) & ~0x1F);
- printf(" next=0x%08x\n", le32toh(itd->itd_next));
- printf(" status[0]=0x%08x; <%s>\n", le32toh(itd->itd_status[0]),
- (itd->itd_status[0] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[1]=0x%08x; <%s>\n", le32toh(itd->itd_status[1]),
- (itd->itd_status[1] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[2]=0x%08x; <%s>\n", le32toh(itd->itd_status[2]),
- (itd->itd_status[2] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[3]=0x%08x; <%s>\n", le32toh(itd->itd_status[3]),
- (itd->itd_status[3] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[4]=0x%08x; <%s>\n", le32toh(itd->itd_status[4]),
- (itd->itd_status[4] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[5]=0x%08x; <%s>\n", le32toh(itd->itd_status[5]),
- (itd->itd_status[5] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[6]=0x%08x; <%s>\n", le32toh(itd->itd_status[6]),
- (itd->itd_status[6] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[7]=0x%08x; <%s>\n", le32toh(itd->itd_status[7]),
- (itd->itd_status[7] & htole32(EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" bp[0]=0x%08x\n", le32toh(itd->itd_bp[0]));
+ printf("ITD(%p) at 0x%08x\n", itd, ehci32toh(sc, itd->itd_self) & ~0x1F);
+ printf(" next=0x%08x\n", ehci32toh(sc, itd->itd_next));
+ printf(" status[0]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[0]),
+ (itd->itd_status[0] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[1]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[1]),
+ (itd->itd_status[1] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[2]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[2]),
+ (itd->itd_status[2] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[3]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[3]),
+ (itd->itd_status[3] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[4]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[4]),
+ (itd->itd_status[4] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[5]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[5]),
+ (itd->itd_status[5] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[6]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[6]),
+ (itd->itd_status[6] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" status[7]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[7]),
+ (itd->itd_status[7] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
+ printf(" bp[0]=0x%08x\n", ehci32toh(sc, itd->itd_bp[0]));
printf(" addr=0x%02x; endpt=0x%01x\n",
- EHCI_ITD_GET_ADDR(le32toh(itd->itd_bp[0])),
- EHCI_ITD_GET_ENDPT(le32toh(itd->itd_bp[0])));
- printf(" bp[1]=0x%08x\n", le32toh(itd->itd_bp[1]));
+ EHCI_ITD_GET_ADDR(ehci32toh(sc, itd->itd_bp[0])),
+ EHCI_ITD_GET_ENDPT(ehci32toh(sc, itd->itd_bp[0])));
+ printf(" bp[1]=0x%08x\n", ehci32toh(sc, itd->itd_bp[1]));
printf(" dir=%s; mpl=0x%02x\n",
- (le32toh(itd->itd_bp[1]) & EHCI_ITD_SET_DIR_IN) ? "in" : "out",
- EHCI_ITD_GET_MPL(le32toh(itd->itd_bp[1])));
+ (ehci32toh(sc, itd->itd_bp[1]) & EHCI_ITD_SET_DIR_IN) ? "in" : "out",
+ EHCI_ITD_GET_MPL(ehci32toh(sc, itd->itd_bp[1])));
printf(" bp[2..6]=0x%08x,0x%08x,0x%08x,0x%08x,0x%08x\n",
- le32toh(itd->itd_bp[2]),
- le32toh(itd->itd_bp[3]),
- le32toh(itd->itd_bp[4]),
- le32toh(itd->itd_bp[5]),
- le32toh(itd->itd_bp[6]));
+ ehci32toh(sc, itd->itd_bp[2]),
+ ehci32toh(sc, itd->itd_bp[3]),
+ ehci32toh(sc, itd->itd_bp[4]),
+ ehci32toh(sc, itd->itd_bp[5]),
+ ehci32toh(sc, itd->itd_bp[6]));
printf(" bp_hi=0x%08x,0x%08x,0x%08x,0x%08x,\n"
" 0x%08x,0x%08x,0x%08x\n",
- le32toh(itd->itd_bp_hi[0]),
- le32toh(itd->itd_bp_hi[1]),
- le32toh(itd->itd_bp_hi[2]),
- le32toh(itd->itd_bp_hi[3]),
- le32toh(itd->itd_bp_hi[4]),
- le32toh(itd->itd_bp_hi[5]),
- le32toh(itd->itd_bp_hi[6]));
+ ehci32toh(sc, itd->itd_bp_hi[0]),
+ ehci32toh(sc, itd->itd_bp_hi[1]),
+ ehci32toh(sc, itd->itd_bp_hi[2]),
+ ehci32toh(sc, itd->itd_bp_hi[3]),
+ ehci32toh(sc, itd->itd_bp_hi[4]),
+ ehci32toh(sc, itd->itd_bp_hi[5]),
+ ehci32toh(sc, itd->itd_bp_hi[6]));
}
static void
@@ -936,12 +947,12 @@ ehci_dump_isoc(ehci_softc_t *sc)
sitd = sc->sc_isoc_fs_p_last[pos];
while (itd && max && max--) {
- ehci_dump_itd(itd);
+ ehci_dump_itd(sc, itd);
itd = itd->prev;
}
while (sitd && max && max--) {
- ehci_dump_sitd(sitd);
+ ehci_dump_sitd(sc, sitd);
sitd = sitd->prev;
}
}
@@ -956,7 +967,7 @@ ehci_transfer_intr_enqueue(struct usb2_xfer *xfer)
return;
}
/* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
/* start timeout, if any */
if (xfer->timeout != 0) {
@@ -1022,6 +1033,11 @@ _ehci_append_qh(ehci_qh_t *sqh, ehci_qh_t *last)
{
DPRINTFN(11, "%p to %p\n", sqh, last);
+ if (sqh->prev != NULL) {
+ /* should not happen */
+ DPRINTFN(0, "QH already linked!\n");
+ return (last);
+ }
/* (sc->sc_bus.mtx) must be locked */
sqh->next = last->next;
@@ -1040,12 +1056,6 @@ _ehci_append_qh(ehci_qh_t *sqh, ehci_qh_t *last)
usb2_pc_cpu_flush(last->page_cache);
-#if USB_DEBUG
- if (ehcidebug > 5) {
- printf("%s:\n", __FUNCTION__);
- ehci_dump_sqh(sqh);
- }
-#endif
return (sqh);
}
@@ -1109,14 +1119,6 @@ _ehci_remove_qh(ehci_qh_t *sqh, ehci_qh_t *last)
sqh->next->prev = sqh->prev;
usb2_pc_cpu_flush(sqh->next->page_cache);
}
- /*
- * set the Terminate-bit in the e_next of the QH, in case
- * the transferred packet was short so that the QH still
- * points at the last used TD
- */
-
- sqh->qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE);
-
last = ((last == sqh) ? sqh->prev : last);
sqh->prev = 0;
@@ -1129,6 +1131,7 @@ _ehci_remove_qh(ehci_qh_t *sqh, ehci_qh_t *last)
static usb2_error_t
ehci_non_isoc_done_sub(struct usb2_xfer *xfer)
{
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
ehci_qtd_t *td;
ehci_qtd_t *td_alt_next;
uint32_t status;
@@ -1140,7 +1143,7 @@ ehci_non_isoc_done_sub(struct usb2_xfer *xfer)
while (1) {
usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->qtd_status);
+ status = ehci32toh(sc, td->qtd_status);
len = EHCI_QTD_GET_BYTES(status);
@@ -1232,7 +1235,9 @@ ehci_non_isoc_done(struct usb2_xfer *xfer)
#if USB_DEBUG
if (ehcidebug > 10) {
- ehci_dump_sqtds(xfer->td_transfer_first);
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
+
+ ehci_dump_sqtds(sc, xfer->td_transfer_first);
}
#endif
@@ -1282,6 +1287,7 @@ static uint8_t
ehci_check_transfer(struct usb2_xfer *xfer)
{
struct usb2_pipe_methods *methods = xfer->pipe->methods;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
uint32_t status;
@@ -1294,13 +1300,13 @@ ehci_check_transfer(struct usb2_xfer *xfer)
td = xfer->td_transfer_last;
usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->sitd_status);
+ status = ehci32toh(sc, td->sitd_status);
/* also check if first is complete */
td = xfer->td_transfer_first;
usb2_pc_cpu_invalidate(td->page_cache);
- status |= le32toh(td->sitd_status);
+ status |= ehci32toh(sc, td->sitd_status);
if (!(status & EHCI_SITD_ACTIVE)) {
ehci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
@@ -1329,7 +1335,7 @@ ehci_check_transfer(struct usb2_xfer *xfer)
td->itd_status[6] | td->itd_status[7];
/* if no transactions are active we continue */
- if (!(status & htole32(EHCI_ITD_ACTIVE))) {
+ if (!(status & htoehci32(sc, EHCI_ITD_ACTIVE))) {
ehci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
goto transferred;
}
@@ -1346,7 +1352,7 @@ ehci_check_transfer(struct usb2_xfer *xfer)
while (1) {
usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->qtd_status);
+ status = ehci32toh(sc, td->qtd_status);
/*
* if there is an active TD the transfer isn't done
@@ -1511,7 +1517,7 @@ ehci_timeout(void *arg)
DPRINTF("xfer=%p\n", xfer);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* transfer is transferred */
ehci_device_done(xfer, USB_ERR_TIMEOUT);
@@ -1520,7 +1526,7 @@ ehci_timeout(void *arg)
static void
ehci_do_poll(struct usb2_bus *bus)
{
- struct ehci_softc *sc = EHCI_BUS2SC(bus);
+ ehci_softc_t *sc = EHCI_BUS2SC(bus);
USB_BUS_LOCK(&sc->sc_bus);
ehci_interrupt_poll(sc);
@@ -1542,7 +1548,7 @@ ehci_setup_standard_chain_sub(struct ehci_std_temp *temp)
uint8_t shortpkt_old;
uint8_t precompute;
- qtd_altnext = htole32(EHCI_LINK_TERMINATE);
+ qtd_altnext = htoehci32(temp->sc, EHCI_LINK_TERMINATE);
td_alt_next = NULL;
buf_offset = 0;
shortpkt_old = temp->shortpkt;
@@ -1599,7 +1605,8 @@ restart:
/* fill out current TD */
td->qtd_status =
- temp->qtd_status | htole32(EHCI_QTD_SET_BYTES(average));
+ temp->qtd_status |
+ htoehci32(temp->sc, EHCI_QTD_SET_BYTES(average));
if (average == 0) {
@@ -1607,7 +1614,8 @@ restart:
/* update data toggle, ZLP case */
- temp->qtd_status ^= htole32(EHCI_QTD_TOGGLE_MASK);
+ temp->qtd_status ^=
+ htoehci32(temp->sc, EHCI_QTD_TOGGLE_MASK);
}
td->len = 0;
@@ -1627,7 +1635,8 @@ restart:
if (((average + temp->max_frame_size - 1) /
temp->max_frame_size) & 1) {
- temp->qtd_status ^= htole32(EHCI_QTD_TOGGLE_MASK);
+ temp->qtd_status ^=
+ htoehci32(temp->sc, EHCI_QTD_TOGGLE_MASK);
}
}
td->len = average;
@@ -1639,7 +1648,8 @@ restart:
/* fill out buffer pointers */
usb2_get_page(temp->pc, buf_offset, &buf_res);
- td->qtd_buffer[0] = htole32(buf_res.physaddr);
+ td->qtd_buffer[0] =
+ htoehci32(temp->sc, buf_res.physaddr);
td->qtd_buffer_hi[0] = 0;
x = 1;
@@ -1648,7 +1658,9 @@ restart:
average -= EHCI_PAGE_SIZE;
buf_offset += EHCI_PAGE_SIZE;
usb2_get_page(temp->pc, buf_offset, &buf_res);
- td->qtd_buffer[x] = htole32(buf_res.physaddr & (~0xFFF));
+ td->qtd_buffer[x] =
+ htoehci32(temp->sc,
+ buf_res.physaddr & (~0xFFF));
td->qtd_buffer_hi[x] = 0;
x++;
}
@@ -1663,7 +1675,9 @@ restart:
*/
buf_offset += average;
usb2_get_page(temp->pc, buf_offset - 1, &buf_res);
- td->qtd_buffer[x] = htole32(buf_res.physaddr & (~0xFFF));
+ td->qtd_buffer[x] =
+ htoehci32(temp->sc,
+ buf_res.physaddr & (~0xFFF));
td->qtd_buffer_hi[x] = 0;
}
@@ -1713,10 +1727,11 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->udev));
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
temp.average = xfer->max_usb2_frame_size;
temp.max_frame_size = xfer->max_frame_size;
+ temp.sc = EHCI_BUS2SC(xfer->xroot->bus);
/* toggle the DMA set we are using */
xfer->flags_int.curr_dma_set ^= 1;
@@ -1736,23 +1751,26 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
if (xfer->flags_int.control_xfr) {
if (xfer->pipe->toggle_next) {
/* DATA1 is next */
- temp.qtd_status |= htole32(EHCI_QTD_SET_TOGGLE(1));
+ temp.qtd_status |=
+ htoehci32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
}
temp.auto_data_toggle = 0;
} else {
temp.auto_data_toggle = 1;
}
- if (usb2_get_speed(xfer->udev) != USB_SPEED_HIGH) {
+ if (usb2_get_speed(xfer->xroot->udev) != USB_SPEED_HIGH) {
/* max 3 retries */
- temp.qtd_status |= htole32(EHCI_QTD_SET_CERR(3));
+ temp.qtd_status |=
+ htoehci32(temp.sc, EHCI_QTD_SET_CERR(3));
}
/* check if we should prepend a setup message */
if (xfer->flags_int.control_xfr) {
if (xfer->flags_int.control_hdr) {
- temp.qtd_status &= htole32(EHCI_QTD_SET_CERR(3));
+ temp.qtd_status &=
+ htoehci32(temp.sc, EHCI_QTD_SET_CERR(3));
temp.qtd_status |= htole32
(EHCI_QTD_ACTIVE |
EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
@@ -1783,7 +1801,8 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
}
/* keep previous data toggle and error count */
- temp.qtd_status &= htole32(EHCI_QTD_SET_CERR(3) |
+ temp.qtd_status &=
+ htoehci32(temp.sc, EHCI_QTD_SET_CERR(3) |
EHCI_QTD_SET_TOGGLE(1));
if (temp.len == 0) {
@@ -1803,9 +1822,9 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
temp.qtd_status |=
(UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) ?
- htole32(EHCI_QTD_ACTIVE |
+ htoehci32(temp.sc, EHCI_QTD_ACTIVE |
EHCI_QTD_SET_PID(EHCI_QTD_PID_IN)) :
- htole32(EHCI_QTD_ACTIVE |
+ htoehci32(temp.sc, EHCI_QTD_ACTIVE |
EHCI_QTD_SET_PID(EHCI_QTD_PID_OUT));
ehci_setup_standard_chain_sub(&temp);
@@ -1821,14 +1840,14 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
* direction.
*/
- temp.qtd_status &= htole32(EHCI_QTD_SET_CERR(3) |
+ temp.qtd_status &= htoehci32(temp.sc, EHCI_QTD_SET_CERR(3) |
EHCI_QTD_SET_TOGGLE(1));
temp.qtd_status |=
(UE_GET_DIR(xfer->endpoint) == UE_DIR_OUT) ?
- htole32(EHCI_QTD_ACTIVE |
+ htoehci32(temp.sc, EHCI_QTD_ACTIVE |
EHCI_QTD_SET_PID(EHCI_QTD_PID_IN) |
EHCI_QTD_SET_TOGGLE(1)) :
- htole32(EHCI_QTD_ACTIVE |
+ htoehci32(temp.sc, EHCI_QTD_ACTIVE |
EHCI_QTD_SET_PID(EHCI_QTD_PID_OUT) |
EHCI_QTD_SET_TOGGLE(1));
@@ -1841,9 +1860,9 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
td = temp.td;
/* the last TD terminates the transfer: */
- td->qtd_next = htole32(EHCI_LINK_TERMINATE);
- td->qtd_altnext = htole32(EHCI_LINK_TERMINATE);
- td->qtd_status |= htole32(EHCI_QTD_IOC);
+ td->qtd_next = htoehci32(temp.sc, EHCI_LINK_TERMINATE);
+ td->qtd_altnext = htoehci32(temp.sc, EHCI_LINK_TERMINATE);
+ td->qtd_status |= htoehci32(temp.sc, EHCI_QTD_IOC);
usb2_pc_cpu_flush(td->page_cache);
@@ -1855,7 +1874,8 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
if (ehcidebug > 8) {
DPRINTF("nexttog=%d; data before transfer:\n",
xfer->pipe->toggle_next);
- ehci_dump_sqtds(xfer->td_transfer_first);
+ ehci_dump_sqtds(temp.sc,
+ xfer->td_transfer_first);
}
#endif
@@ -1870,12 +1890,12 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
EHCI_QH_SET_ENDPT(UE_GET_ADDR(xfer->endpoint)) |
EHCI_QH_SET_MPL(xfer->max_packet_size));
- if (usb2_get_speed(xfer->udev) == USB_SPEED_HIGH) {
+ if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) |
EHCI_QH_DTC | EHCI_QH_SET_NRL(8));
} else {
- if (usb2_get_speed(xfer->udev) == USB_SPEED_FULL) {
+ if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_FULL) {
qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_FULL) |
EHCI_QH_DTC);
} else {
@@ -1892,47 +1912,51 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
}
}
- qh->qh_endp = htole32(qh_endp);
+ qh->qh_endp = htoehci32(temp.sc, qh_endp);
qh_endphub =
(EHCI_QH_SET_MULT(xfer->max_packet_count & 3) |
EHCI_QH_SET_CMASK(xfer->usb2_cmask) |
EHCI_QH_SET_SMASK(xfer->usb2_smask) |
- EHCI_QH_SET_HUBA(xfer->udev->hs_hub_addr) |
- EHCI_QH_SET_PORT(xfer->udev->hs_port_no));
+ EHCI_QH_SET_HUBA(xfer->xroot->udev->hs_hub_addr) |
+ EHCI_QH_SET_PORT(xfer->xroot->udev->hs_port_no));
- qh->qh_endphub = htole32(qh_endphub);
- qh->qh_curqtd = htole32(0);
+ qh->qh_endphub = htoehci32(temp.sc, qh_endphub);
+ qh->qh_curqtd = htoehci32(temp.sc, 0);
/* fill the overlay qTD */
- qh->qh_qtd.qtd_status = htole32(0);
+ qh->qh_qtd.qtd_status = htoehci32(temp.sc, 0);
if (temp.auto_data_toggle) {
/* let the hardware compute the data toggle */
- qh->qh_endp &= ~htole32(EHCI_QH_DTC);
+ qh->qh_endp &= htoehci32(temp.sc, ~EHCI_QH_DTC);
if (xfer->pipe->toggle_next) {
/* DATA1 is next */
- qh->qh_qtd.qtd_status |= htole32(EHCI_QTD_SET_TOGGLE(1));
+ qh->qh_qtd.qtd_status |=
+ htoehci32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
}
}
td = xfer->td_transfer_first;
qh->qh_qtd.qtd_next = td->qtd_self;
- qh->qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE);
+ qh->qh_qtd.qtd_altnext =
+ htoehci32(temp.sc, EHCI_LINK_TERMINATE);
usb2_pc_cpu_flush(qh->page_cache);
- EHCI_APPEND_QH(qh, *qh_last);
+ if (xfer->xroot->udev->pwr_save.suspended == 0) {
+ EHCI_APPEND_QH(qh, *qh_last);
+ }
}
static void
ehci_root_intr_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct ehci_softc *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
uint16_t i;
uint16_t m;
@@ -1992,11 +2016,11 @@ ehci_isoc_fs_done(ehci_softc_t *sc, struct usb2_xfer *xfer)
#if USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("isoc FS-TD\n");
- ehci_dump_sitd(td);
+ ehci_dump_sitd(sc, td);
}
#endif
usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->sitd_status);
+ status = ehci32toh(sc, td->sitd_status);
len = EHCI_SITD_GET_LEN(status);
@@ -2044,12 +2068,12 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb2_xfer *xfer)
#if USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("isoc HS-TD\n");
- ehci_dump_itd(td);
+ ehci_dump_itd(sc, td);
}
#endif
usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->itd_status[td_no]);
+ status = ehci32toh(sc, td->itd_status[td_no]);
len = EHCI_ITD_GET_LEN(status);
@@ -2089,7 +2113,7 @@ static void
ehci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
{
struct usb2_pipe_methods *methods = xfer->pipe->methods;
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -2102,7 +2126,8 @@ ehci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
if (ehcidebug > 8) {
DPRINTF("nexttog=%d; data after transfer:\n",
xfer->pipe->toggle_next);
- ehci_dump_sqtds(xfer->td_transfer_first);
+ ehci_dump_sqtds(sc,
+ xfer->td_transfer_first);
}
#endif
@@ -2156,7 +2181,7 @@ ehci_device_bulk_enter(struct usb2_xfer *xfer)
static void
ehci_device_bulk_start(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
/* setup TD's and QH */
ehci_setup_standard_chain(xfer, &sc->sc_async_p_last);
@@ -2199,7 +2224,7 @@ ehci_device_ctrl_enter(struct usb2_xfer *xfer)
static void
ehci_device_ctrl_start(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
/* setup TD's and QH */
ehci_setup_standard_chain(xfer, &sc->sc_async_p_last);
@@ -2224,7 +2249,7 @@ struct usb2_pipe_methods ehci_device_ctrl_methods =
static void
ehci_device_intr_open(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
uint16_t best;
uint16_t bit;
uint16_t x;
@@ -2233,9 +2258,9 @@ ehci_device_intr_open(struct usb2_xfer *xfer)
/* Allocate a microframe slot first: */
slot = usb2_intr_schedule_adjust
- (xfer->udev, xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX);
+ (xfer->xroot->udev, xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX);
- if (usb2_get_speed(xfer->udev) == USB_SPEED_HIGH) {
+ if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
xfer->usb2_uframe = slot;
xfer->usb2_smask = (1 << slot) & 0xFF;
xfer->usb2_cmask = 0;
@@ -2277,11 +2302,11 @@ ehci_device_intr_open(struct usb2_xfer *xfer)
static void
ehci_device_intr_close(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
uint8_t slot;
slot = usb2_intr_schedule_adjust
- (xfer->udev, -(xfer->max_frame_size), xfer->usb2_uframe);
+ (xfer->xroot->udev, -(xfer->max_frame_size), xfer->usb2_uframe);
sc->sc_intr_stat[xfer->qh_pos]--;
@@ -2297,7 +2322,7 @@ ehci_device_intr_enter(struct usb2_xfer *xfer)
static void
ehci_device_intr_start(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
/* setup TD's and QH */
ehci_setup_standard_chain(xfer, &sc->sc_intr_p_last[xfer->qh_pos]);
@@ -2322,6 +2347,7 @@ struct usb2_pipe_methods ehci_device_intr_methods =
static void
ehci_device_isoc_fs_open(struct usb2_xfer *xfer)
{
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
ehci_sitd_t *td;
uint32_t sitd_portaddr;
uint8_t ds;
@@ -2329,13 +2355,13 @@ ehci_device_isoc_fs_open(struct usb2_xfer *xfer)
sitd_portaddr =
EHCI_SITD_SET_ADDR(xfer->address) |
EHCI_SITD_SET_ENDPT(UE_GET_ADDR(xfer->endpoint)) |
- EHCI_SITD_SET_HUBA(xfer->udev->hs_hub_addr) |
- EHCI_SITD_SET_PORT(xfer->udev->hs_port_no);
+ EHCI_SITD_SET_HUBA(xfer->xroot->udev->hs_hub_addr) |
+ EHCI_SITD_SET_PORT(xfer->xroot->udev->hs_port_no);
if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) {
sitd_portaddr |= EHCI_SITD_SET_DIR_IN;
}
- sitd_portaddr = htole32(sitd_portaddr);
+ sitd_portaddr = htoehci32(sc, sitd_portaddr);
/* initialize all TD's */
@@ -2352,7 +2378,7 @@ ehci_device_isoc_fs_open(struct usb2_xfer *xfer)
*
* micro-frame usage (8 microframes per 1ms)
*/
- td->sitd_back = htole32(EHCI_LINK_TERMINATE);
+ td->sitd_back = htoehci32(sc, EHCI_LINK_TERMINATE);
usb2_pc_cpu_flush(td->page_cache);
}
@@ -2369,7 +2395,7 @@ static void
ehci_device_isoc_fs_enter(struct usb2_xfer *xfer)
{
struct usb2_page_search buf_res;
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
struct usb2_fs_isoc_schedule *fss_start;
struct usb2_fs_isoc_schedule *fss_end;
struct usb2_fs_isoc_schedule *fss;
@@ -2430,7 +2456,7 @@ ehci_device_isoc_fs_enter(struct usb2_xfer *xfer)
*/
xfer->isoc_time_complete =
usb2_fs_isoc_schedule_isoc_time_expand
- (xfer->udev, &fss_start, &fss_end, nframes) + buf_offset +
+ (xfer->xroot->udev, &fss_start, &fss_end, nframes) + buf_offset +
xfer->nframes;
/* get the real number of frames */
@@ -2499,7 +2525,7 @@ ehci_device_isoc_fs_enter(struct usb2_xfer *xfer)
* non-zero length
*/
usb2_get_page(xfer->frbuffers, buf_offset, &buf_res);
- td->sitd_bp[0] = htole32(buf_res.physaddr);
+ td->sitd_bp[0] = htoehci32(sc, buf_res.physaddr);
buf_offset += *plen;
/*
* NOTE: We need to subtract one from the offset so
@@ -2544,9 +2570,9 @@ ehci_device_isoc_fs_enter(struct usb2_xfer *xfer)
sitd_mask = (EHCI_SITD_SET_SMASK(sa) |
EHCI_SITD_SET_CMASK(sb));
- td->sitd_bp[1] = htole32(temp);
+ td->sitd_bp[1] = htoehci32(sc, temp);
- td->sitd_mask = htole32(sitd_mask);
+ td->sitd_mask = htoehci32(sc, sitd_mask);
if (nframes == 0) {
td->sitd_status = htole32
@@ -2563,7 +2589,7 @@ ehci_device_isoc_fs_enter(struct usb2_xfer *xfer)
#if USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("FS-TD %d\n", nframes);
- ehci_dump_sitd(td);
+ ehci_dump_sitd(sc, td);
}
#endif
/* insert TD into schedule */
@@ -2606,6 +2632,7 @@ struct usb2_pipe_methods ehci_device_isoc_fs_methods =
static void
ehci_device_isoc_hs_open(struct usb2_xfer *xfer)
{
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
ehci_itd_t *td;
uint32_t temp;
uint8_t ds;
@@ -2639,10 +2666,10 @@ ehci_device_isoc_hs_open(struct usb2_xfer *xfer)
temp |= EHCI_ITD_SET_DIR_IN;
}
/* set maximum packet size */
- td->itd_bp[1] = htole32(temp);
+ td->itd_bp[1] = htoehci32(sc, temp);
/* set transfer multiplier */
- td->itd_bp[2] = htole32(xfer->max_packet_count & 3);
+ td->itd_bp[2] = htoehci32(sc, xfer->max_packet_count & 3);
usb2_pc_cpu_flush(td->page_cache);
}
@@ -2659,7 +2686,7 @@ static void
ehci_device_isoc_hs_enter(struct usb2_xfer *xfer)
{
struct usb2_page_search buf_res;
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
ehci_itd_t *td;
ehci_itd_t *td_last = NULL;
ehci_itd_t **pp_last;
@@ -2764,7 +2791,7 @@ ehci_device_isoc_hs_enter(struct usb2_xfer *xfer)
status = (EHCI_ITD_SET_LEN(*plen) |
EHCI_ITD_ACTIVE |
EHCI_ITD_SET_PG(0));
- td->itd_status[td_no] = htole32(status);
+ td->itd_status[td_no] = htoehci32(sc, status);
itd_offset[td_no] = buf_offset;
buf_offset += *plen;
plen++;
@@ -2787,14 +2814,14 @@ ehci_device_isoc_hs_enter(struct usb2_xfer *xfer)
/* get page address */
page_addr = buf_res.physaddr & ~0xFFF;
/* update page address */
- td->itd_bp[0] &= htole32(0xFFF);
- td->itd_bp[0] |= htole32(page_addr);
+ td->itd_bp[0] &= htoehci32(sc, 0xFFF);
+ td->itd_bp[0] |= htoehci32(sc, page_addr);
for (x = 0; x != td_no; x++) {
/* set page number and page offset */
status = (EHCI_ITD_SET_PG(page_no) |
(buf_res.physaddr & 0xFFF));
- td->itd_status[x] |= htole32(status);
+ td->itd_status[x] |= htoehci32(sc, status);
/* get next page offset */
if (itd_offset[x + 1] == buf_offset) {
@@ -2817,20 +2844,20 @@ ehci_device_isoc_hs_enter(struct usb2_xfer *xfer)
}
page_no++;
/* update page address */
- td->itd_bp[page_no] &= htole32(0xFFF);
- td->itd_bp[page_no] |= htole32(page_addr);
+ td->itd_bp[page_no] &= htoehci32(sc, 0xFFF);
+ td->itd_bp[page_no] |= htoehci32(sc, page_addr);
}
}
}
/* set IOC bit if we are complete */
if (nframes == 0) {
- td->itd_status[7] |= htole32(EHCI_ITD_IOC);
+ td->itd_status[7] |= htoehci32(sc, EHCI_ITD_IOC);
}
usb2_pc_cpu_flush(td->page_cache);
#if USB_DEBUG
if (ehcidebug > 15) {
DPRINTF("HS-TD %d\n", nframes);
- ehci_dump_itd(td);
+ ehci_dump_itd(sc, td);
}
#endif
/* insert TD into schedule */
@@ -2883,7 +2910,7 @@ ehci_root_ctrl_open(struct usb2_xfer *xfer)
static void
ehci_root_ctrl_close(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_ctrl.xfer == xfer) {
sc->sc_root_ctrl.xfer = NULL;
@@ -2990,28 +3017,26 @@ ehci_root_ctrl_enter(struct usb2_xfer *xfer)
static void
ehci_root_ctrl_start(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
DPRINTF("\n");
sc->sc_root_ctrl.xfer = xfer;
- usb2_config_td_queue_command
- (&sc->sc_config_td, NULL, &ehci_root_ctrl_task, 0, 0);
+ usb2_bus_roothub_exec(xfer->xroot->bus);
}
static void
-ehci_root_ctrl_task(struct ehci_softc *sc,
- struct usb2_config_td_cc *cc, uint16_t refcount)
+ehci_root_ctrl_task(struct usb2_bus *bus)
{
- ehci_root_ctrl_poll(sc);
+ ehci_root_ctrl_poll(EHCI_BUS2SC(bus));
}
static void
ehci_root_ctrl_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct ehci_softc *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
char *ptr;
uint32_t port;
uint32_t v;
@@ -3037,7 +3062,7 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
value = UGETW(std->req.wValue);
index = UGETW(std->req.wIndex);
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
"wValue=0x%04x wIndex=0x%04x\n",
@@ -3176,7 +3201,32 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
EOWRITE4(sc, port, v & ~EHCI_PS_PE);
break;
case UHF_PORT_SUSPEND:
- EOWRITE4(sc, port, v & ~EHCI_PS_SUSP);
+ if ((v & EHCI_PS_SUSP) && (!(v & EHCI_PS_FPR))) {
+
+ /*
+ * waking up a High Speed device is rather
+ * complicated if
+ */
+ EOWRITE4(sc, port, v | EHCI_PS_FPR);
+ }
+ /* wait 20ms for resume sequence to complete */
+ if (use_polling) {
+ /* polling */
+ DELAY(20 * 1000);
+ } else {
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 20);
+ }
+
+ EOWRITE4(sc, port, v & ~(EHCI_PS_SUSP |
+ EHCI_PS_FPR | (3 << 10) /* High Speed */ ));
+
+ /* settle time */
+ if (use_polling) {
+ /* polling */
+ DELAY(4 * 1000);
+ } else {
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 4);
+ }
break;
case UHF_PORT_POWER:
EOWRITE4(sc, port, v & ~EHCI_PS_PP);
@@ -3223,7 +3273,8 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
(EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH) |
(EHCI_HCS_P_INDICATOR(EREAD4(sc, EHCI_HCSPARAMS)) ?
UHD_PORT_IND : 0));
- sc->sc_hub_desc.hubd.bPwrOn2PwrGood = 200; /* XXX can't find out? */
+ /* XXX can't find out? */
+ sc->sc_hub_desc.hubd.bPwrOn2PwrGood = 200;
for (l = 0; l < sc->sc_noport; l++) {
/* XXX can't find out? */
sc->sc_hub_desc.hubd.DeviceRemovable[l / 8] &= ~(1 << (l % 8));
@@ -3260,7 +3311,7 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
i |= UPS_CURRENT_CONNECT_STATUS;
if (v & EHCI_PS_PE)
i |= UPS_PORT_ENABLED;
- if (v & EHCI_PS_SUSP)
+ if ((v & EHCI_PS_SUSP) && !(v & EHCI_PS_FPR))
i |= UPS_SUSPEND;
if (v & EHCI_PS_OCA)
i |= UPS_OVERCURRENT_INDICATOR;
@@ -3276,6 +3327,8 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
i |= UPS_C_PORT_ENABLED;
if (v & EHCI_PS_OCC)
i |= UPS_C_OVERCURRENT_INDICATOR;
+ if (v & EHCI_PS_FPR)
+ i |= UPS_C_SUSPEND;
if (sc->sc_isreset)
i |= UPS_C_PORT_RESET;
USETW(sc->sc_hub_desc.ps.wPortChange, i);
@@ -3398,7 +3451,7 @@ done:
}
static void
-ehci_root_ctrl_poll(struct ehci_softc *sc)
+ehci_root_ctrl_poll(ehci_softc_t *sc)
{
usb2_sw_transfer(&sc->sc_root_ctrl,
&ehci_root_ctrl_done);
@@ -3426,7 +3479,7 @@ ehci_root_intr_open(struct usb2_xfer *xfer)
static void
ehci_root_intr_close(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_intr.xfer == xfer) {
sc->sc_root_intr.xfer = NULL;
@@ -3443,7 +3496,7 @@ ehci_root_intr_enter(struct usb2_xfer *xfer)
static void
ehci_root_intr_start(struct usb2_xfer *xfer)
{
- ehci_softc_t *sc = xfer->usb2_sc;
+ ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_intr.xfer = xfer;
}
@@ -3481,11 +3534,6 @@ ehci_xfer_setup(struct usb2_setup_params *parm)
nitd = 0;
/*
- * setup xfer
- */
- xfer->usb2_sc = sc;
-
- /*
* compute maximum number of some structures
*/
if (parm->methods == &ehci_device_ctrl_methods) {
@@ -3621,7 +3669,7 @@ alloc_dma_set:
td = page_info.buffer;
/* init TD */
- td->itd_self = htole32(page_info.physaddr | EHCI_LINK_ITD);
+ td->itd_self = htoehci32(sc, page_info.physaddr | EHCI_LINK_ITD);
td->obj_next = last_obj;
td->page_cache = pc + n;
@@ -3645,7 +3693,7 @@ alloc_dma_set:
td = page_info.buffer;
/* init TD */
- td->sitd_self = htole32(page_info.physaddr | EHCI_LINK_SITD);
+ td->sitd_self = htoehci32(sc, page_info.physaddr | EHCI_LINK_SITD);
td->obj_next = last_obj;
td->page_cache = pc + n;
@@ -3669,7 +3717,7 @@ alloc_dma_set:
qtd = page_info.buffer;
/* init TD */
- qtd->qtd_self = htole32(page_info.physaddr);
+ qtd->qtd_self = htoehci32(sc, page_info.physaddr);
qtd->obj_next = last_obj;
qtd->page_cache = pc + n;
@@ -3697,7 +3745,7 @@ alloc_dma_set:
qh = page_info.buffer;
/* init QH */
- qh->qh_self = htole32(page_info.physaddr | EHCI_LINK_QH);
+ qh->qh_self = htoehci32(sc, page_info.physaddr | EHCI_LINK_QH);
qh->obj_next = last_obj;
qh->page_cache = pc + n;
@@ -3794,6 +3842,108 @@ ehci_get_dma_delay(struct usb2_bus *bus, uint32_t *pus)
*pus = (188); /* microseconds */
}
+static void
+ehci_device_resume(struct usb2_device *udev)
+{
+ ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
+ struct usb2_xfer *xfer;
+ struct usb2_pipe_methods *methods;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(udev->bus);
+
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+ if (xfer->xroot->udev == udev) {
+
+ methods = xfer->pipe->methods;
+
+ if ((methods == &ehci_device_bulk_methods) ||
+ (methods == &ehci_device_ctrl_methods)) {
+ EHCI_APPEND_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
+ sc->sc_async_p_last);
+ }
+ if (methods == &ehci_device_intr_methods) {
+ EHCI_APPEND_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
+ sc->sc_intr_p_last[xfer->qh_pos]);
+ }
+ }
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ return;
+}
+
+static void
+ehci_device_suspend(struct usb2_device *udev)
+{
+ ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
+ struct usb2_xfer *xfer;
+ struct usb2_pipe_methods *methods;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(udev->bus);
+
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+ if (xfer->xroot->udev == udev) {
+
+ methods = xfer->pipe->methods;
+
+ if ((methods == &ehci_device_bulk_methods) ||
+ (methods == &ehci_device_ctrl_methods)) {
+ EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
+ sc->sc_async_p_last);
+ }
+ if (methods == &ehci_device_intr_methods) {
+ EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
+ sc->sc_intr_p_last[xfer->qh_pos]);
+ }
+ }
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ return;
+}
+
+static void
+ehci_set_hw_power(struct usb2_bus *bus)
+{
+ ehci_softc_t *sc = EHCI_BUS2SC(bus);
+ uint32_t temp;
+ uint32_t flags;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(bus);
+
+ flags = bus->hw_power_state;
+
+ temp = EOREAD4(sc, EHCI_USBCMD);
+
+ temp &= ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
+
+ if (flags & (USB_HW_POWER_CONTROL |
+ USB_HW_POWER_BULK)) {
+ DPRINTF("Async is active\n");
+ temp |= EHCI_CMD_ASE;
+ }
+ if (flags & (USB_HW_POWER_INTERRUPT |
+ USB_HW_POWER_ISOC)) {
+ DPRINTF("Periodic is active\n");
+ temp |= EHCI_CMD_PSE;
+ }
+ EOWRITE4(sc, EHCI_USBCMD, temp);
+
+ USB_BUS_UNLOCK(bus);
+
+ return;
+}
+
struct usb2_bus_methods ehci_bus_methods =
{
.pipe_init = ehci_pipe_init,
@@ -3801,4 +3951,8 @@ struct usb2_bus_methods ehci_bus_methods =
.xfer_unsetup = ehci_xfer_unsetup,
.do_poll = ehci_do_poll,
.get_dma_delay = ehci_get_dma_delay,
+ .device_resume = ehci_device_resume,
+ .device_suspend = ehci_device_suspend,
+ .set_hw_power = ehci_set_hw_power,
+ .roothub_exec = ehci_root_ctrl_task,
};
diff --git a/sys/dev/usb2/controller/ehci2.h b/sys/dev/usb2/controller/ehci2.h
index 6765ace..ca2a1b8 100644
--- a/sys/dev/usb2/controller/ehci2.h
+++ b/sys/dev/usb2/controller/ehci2.h
@@ -38,6 +38,8 @@
#ifndef _EHCI_H_
#define _EHCI_H_
+#define EHCI_MAX_DEVICES USB_MAX_DEVICES
+
/* PCI config registers */
#define PCI_CBMEM 0x10 /* configuration base MEM */
#define PCI_INTERFACE_EHCI 0x20
@@ -160,6 +162,15 @@
#define EHCI_PS_CS 0x00000001 /* RO connect status */
#define EHCI_PS_CLEAR (EHCI_PS_OCC | EHCI_PS_PEC | EHCI_PS_CSC)
+#define EHCI_USBMODE 0x68 /* RW USB Device mode register */
+#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */
+#define EHCI_UM_CM_IDLE 0x0 /* Idle */
+#define EHCI_UM_CM_HOST 0x3 /* Host Controller */
+#define EHCI_UM_ES 0x00000004 /* R/WO Endian Select */
+#define EHCI_UM_ES_LE 0x0 /* Little-endian byte alignment */
+#define EHCI_UM_ES_BE 0x4 /* Big-endian byte alignment */
+#define EHCI_UM_SDIS 0x00000010 /* R/WO Stream Disable Mode */
+
#define EHCI_PORT_RESET_COMPLETE 2 /* ms */
/*
@@ -444,12 +455,12 @@ union ehci_hub_desc {
typedef struct ehci_softc {
struct ehci_hw_softc sc_hw;
struct usb2_bus sc_bus; /* base device */
- struct usb2_config_td sc_config_td;
struct usb2_callout sc_tmo_pcd;
union ehci_hub_desc sc_hub_desc;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
+ struct usb2_device *sc_devices[EHCI_MAX_DEVICES];
struct resource *sc_io_res;
struct resource *sc_irq_res;
struct ehci_qh *sc_async_p_last;
@@ -469,11 +480,12 @@ typedef struct ehci_softc {
uint16_t sc_intr_stat[EHCI_VIRTUAL_FRAMELIST_COUNT];
uint16_t sc_id_vendor; /* vendor ID for root hub */
uint16_t sc_flags; /* chip specific flags */
-#define EHCI_SCFLG_SETMODE 0x0001 /* set bridge mode again after init
- * (Marvell) */
-#define EHCI_SCFLG_FORCESPEED 0x0002 /* force speed (Marvell) */
-#define EHCI_SCFLG_NORESTERM 0x0004 /* don't terminate reset sequence
- * (Marvell) */
+#define EHCI_SCFLG_SETMODE 0x0001 /* set bridge mode again after init */
+#define EHCI_SCFLG_FORCESPEED 0x0002 /* force speed */
+#define EHCI_SCFLG_NORESTERM 0x0004 /* don't terminate reset sequence */
+#define EHCI_SCFLG_BIGEDESC 0x0008 /* big-endian byte order descriptors */
+#define EHCI_SCFLG_BIGEMMIO 0x0010 /* big-endian byte order MMIO */
+#define EHCI_SCFLG_TT 0x0020 /* transaction translator present */
uint8_t sc_offs; /* offset to operational registers */
uint8_t sc_doorbell_disable; /* set on doorbell failure */
diff --git a/sys/dev/usb2/controller/ehci2_pci.c b/sys/dev/usb2/controller/ehci2_pci.c
index 65e4fce..038211d 100644
--- a/sys/dev/usb2/controller/ehci2_pci.c
+++ b/sys/dev/usb2/controller/ehci2_pci.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
@@ -228,16 +227,15 @@ ehci_pci_attach(device_t self)
int err;
int rid;
- if (sc == NULL) {
- device_printf(self, "Could not allocate sc\n");
- return (ENXIO);
- }
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_bus.parent = self;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
- return ENOMEM;
+ return (ENOMEM);
}
sc->sc_dev = self;
@@ -259,8 +257,10 @@ ehci_pci_attach(device_t self)
sc->sc_bus.usbrev = USB_REV_2_0;
break;
default:
- sc->sc_bus.usbrev = USB_REV_UNKNOWN;
- break;
+ /* Quirk for Parallels Desktop 4.0 */
+ device_printf(self, "USB revision is unknown. Assuming v2.0.\n");
+ sc->sc_bus.usbrev = USB_REV_2_0;
+ break;
}
rid = PCI_CBMEM;
@@ -338,12 +338,6 @@ ehci_pci_attach(device_t self)
sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
}
- err = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_bus.bus_mtx,
- NULL, 0, 4);
- if (err) {
- device_printf(self, "could not setup config thread!\n");
- goto error;
- }
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (void *)(void *)ehci_interrupt, sc, &sc->sc_intr_hdl);
@@ -378,8 +372,6 @@ ehci_pci_detach(device_t self)
ehci_softc_t *sc = device_get_softc(self);
device_t bdev;
- usb2_config_td_drain(&sc->sc_config_td);
-
if (sc->sc_bus.bdev) {
bdev = sc->sc_bus.bdev;
device_detach(bdev);
@@ -419,8 +411,6 @@ ehci_pci_detach(device_t self)
sc->sc_io_res);
sc->sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
return (0);
diff --git a/sys/dev/usb2/controller/musb2_otg.c b/sys/dev/usb2/controller/musb2_otg.c
index e7119bf..79a1fba 100644
--- a/sys/dev/usb2/controller/musb2_otg.c
+++ b/sys/dev/usb2/controller/musb2_otg.c
@@ -42,14 +42,11 @@
#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR musbotgdebug
-#define usb2_config_td_cc musbotg_config_copy
-#define usb2_config_td_softc musbotg_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
@@ -101,7 +98,6 @@ static void musbotg_interrupt_poll(struct musbotg_softc *);
static usb2_sw_transfer_func_t musbotg_root_intr_done;
static usb2_sw_transfer_func_t musbotg_root_ctrl_done;
-static usb2_config_td_command_t musbotg_root_ctrl_task;
/*
* Here is a configuration that the chip supports.
@@ -208,14 +204,14 @@ musbotg_pull_down(struct musbotg_softc *sc)
static void
musbotg_wakeup_peer(struct usb2_xfer *xfer)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
uint8_t temp;
uint8_t use_polling;
if (!(sc->sc_flags.status_suspend)) {
return;
}
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
temp |= MUSB2_MASK_RESUME;
@@ -236,12 +232,6 @@ musbotg_wakeup_peer(struct usb2_xfer *xfer)
}
static void
-musbotg_rem_wakeup_set(struct usb2_device *udev, uint8_t is_on)
-{
- DPRINTFN(4, "is_on=%u\n", is_on);
-}
-
-static void
musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
{
DPRINTFN(4, "addr=%d\n", addr);
@@ -941,7 +931,7 @@ musbotg_xfer_do_fifo(struct usb2_xfer *xfer)
return (1); /* not complete */
done:
- sc = xfer->usb2_sc;
+ sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
/* compute all actual lengths */
@@ -964,11 +954,9 @@ repeat:
}
}
-static void
-musbotg_vbus_interrupt(struct usb2_bus *bus, uint8_t is_on)
+void
+musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on)
{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
-
DPRINTFN(4, "vbus = %u\n", is_on);
USB_BUS_LOCK(&sc->sc_bus);
@@ -1140,7 +1128,7 @@ musbotg_setup_standard_chain(struct usb2_xfer *xfer)
DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->udev));
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
temp.max_frame_size = xfer->max_frame_size;
@@ -1155,7 +1143,7 @@ musbotg_setup_standard_chain(struct usb2_xfer *xfer)
temp.setup_alt_next = xfer->flags_int.short_frames_ok;
temp.offset = 0;
- sc = xfer->usb2_sc;
+ sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
ep_no = (xfer->endpoint & UE_ADDR);
/* check if we should prepend a setup message */
@@ -1255,7 +1243,7 @@ musbotg_timeout(void *arg)
DPRINTFN(1, "xfer=%p\n", xfer);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* transfer is transferred */
musbotg_device_done(xfer, USB_ERR_TIMEOUT);
@@ -1264,7 +1252,7 @@ musbotg_timeout(void *arg)
static void
musbotg_ep_int_set(struct usb2_xfer *xfer, uint8_t on)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
uint16_t temp;
uint8_t ep_no = xfer->endpoint & UE_ADDR;
@@ -1314,7 +1302,7 @@ musbotg_start_standard_chain(struct usb2_xfer *xfer)
DPRINTFN(14, "enabled interrupts on endpoint\n");
/* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
/* start timeout, if any */
if (xfer->timeout != 0) {
@@ -1328,7 +1316,7 @@ static void
musbotg_root_intr_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
DPRINTFN(8, "\n");
@@ -1468,7 +1456,7 @@ done:
static void
musbotg_device_done(struct usb2_xfer *xfer, usb2_error_t error)
{
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
xfer, xfer->pipe, error);
@@ -2031,7 +2019,7 @@ musbotg_device_isoc_close(struct usb2_xfer *xfer)
static void
musbotg_device_isoc_enter(struct usb2_xfer *xfer)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
uint32_t temp;
uint32_t nframes;
uint32_t fs_frames;
@@ -2049,7 +2037,7 @@ musbotg_device_isoc_enter(struct usb2_xfer *xfer)
*/
temp = (nframes - xfer->pipe->isoc_next) & MUSB2_MASK_FRAME;
- if (usb2_get_speed(xfer->udev) == USB_SPEED_HIGH) {
+ if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
fs_frames = (xfer->nframes + 7) / 8;
} else {
fs_frames = xfer->nframes;
@@ -2119,7 +2107,7 @@ musbotg_root_ctrl_open(struct usb2_xfer *xfer)
static void
musbotg_root_ctrl_close(struct usb2_xfer *xfer)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_ctrl.xfer == xfer) {
sc->sc_root_ctrl.xfer = NULL;
@@ -2224,26 +2212,24 @@ musbotg_root_ctrl_enter(struct usb2_xfer *xfer)
static void
musbotg_root_ctrl_start(struct usb2_xfer *xfer)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
sc->sc_root_ctrl.xfer = xfer;
- usb2_config_td_queue_command(
- &sc->sc_config_td, NULL, &musbotg_root_ctrl_task, 0, 0);
+ usb2_bus_roothub_exec(xfer->xroot->bus);
}
static void
-musbotg_root_ctrl_task(struct musbotg_softc *sc,
- struct musbotg_config_copy *cc, uint16_t refcount)
+musbotg_root_ctrl_task(struct usb2_bus *bus)
{
- musbotg_root_ctrl_poll(sc);
+ musbotg_root_ctrl_poll(MUSBOTG_BUS2SC(bus));
}
static void
musbotg_root_ctrl_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
uint16_t value;
uint16_t index;
uint8_t use_polling;
@@ -2264,7 +2250,7 @@ musbotg_root_ctrl_done(struct usb2_xfer *xfer,
value = UGETW(std->req.wValue);
index = UGETW(std->req.wIndex);
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
/* demultiplex the control request */
@@ -2672,7 +2658,7 @@ musbotg_root_intr_open(struct usb2_xfer *xfer)
static void
musbotg_root_intr_close(struct usb2_xfer *xfer)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_intr.xfer == xfer) {
sc->sc_root_intr.xfer = NULL;
@@ -2689,7 +2675,7 @@ musbotg_root_intr_enter(struct usb2_xfer *xfer)
static void
musbotg_root_intr_start(struct usb2_xfer *xfer)
{
- struct musbotg_softc *sc = xfer->usb2_sc;
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
sc->sc_root_intr.xfer = xfer;
}
@@ -2719,11 +2705,6 @@ musbotg_xfer_setup(struct usb2_setup_params *parm)
xfer = parm->curr_xfer;
/*
- * setup xfer
- */
- xfer->usb2_sc = sc;
-
- /*
* NOTE: This driver does not use any of the parameters that
* are computed from the following values. Just set some
* reasonable dummies:
@@ -2890,6 +2871,5 @@ struct usb2_bus_methods musbotg_bus_methods =
.get_hw_ep_profile = &musbotg_get_hw_ep_profile,
.set_stall = &musbotg_set_stall,
.clear_stall = &musbotg_clear_stall,
- .vbus_interrupt = &musbotg_vbus_interrupt,
- .rem_wakeup_set = &musbotg_rem_wakeup_set,
+ .roothub_exec = &musbotg_root_ctrl_task,
};
diff --git a/sys/dev/usb2/controller/musb2_otg.h b/sys/dev/usb2/controller/musb2_otg.h
index 68193e2..0d880e1 100644
--- a/sys/dev/usb2/controller/musb2_otg.h
+++ b/sys/dev/usb2/controller/musb2_otg.h
@@ -32,6 +32,8 @@
#ifndef _MUSB2_OTG_H_
#define _MUSB2_OTG_H_
+#define MUSB2_MAX_DEVICES (USB_MIN_DEVICES + 1)
+
/* Common registers */
#define MUSB2_REG_FADDR 0x0000 /* function address register */
@@ -363,8 +365,9 @@ struct musbotg_softc {
union musbotg_hub_temp sc_hub_temp;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
- struct usb2_config_td sc_config_td;
struct usb2_hw_ep_profile sc_hw_ep_profile[16];
+
+ struct usb2_device *sc_devices[MUSB2_MAX_DEVICES];
struct resource *sc_io_res;
struct resource *sc_irq_res;
void *sc_intr_hdl;
@@ -399,5 +402,6 @@ void musbotg_uninit(struct musbotg_softc *sc);
void musbotg_suspend(struct musbotg_softc *sc);
void musbotg_resume(struct musbotg_softc *sc);
void musbotg_interrupt(struct musbotg_softc *sc);
+void musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on);
#endif /* _MUSB2_OTG_H_ */
diff --git a/sys/dev/usb2/controller/musb2_otg_atmelarm.c b/sys/dev/usb2/controller/musb2_otg_atmelarm.c
index de4b58b..6477c97 100644
--- a/sys/dev/usb2/controller/musb2_otg_atmelarm.c
+++ b/sys/dev/usb2/controller/musb2_otg_atmelarm.c
@@ -31,7 +31,6 @@
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
@@ -51,14 +50,12 @@ struct musbotg_super_softc {
};
static void
-musbotg_vbus_interrupt(struct musbotg_super_softc *sc)
+musbotg_vbus_poll(struct musbotg_super_softc *sc)
{
uint8_t vbus_val = 1; /* fake VBUS on - TODO */
/* just forward it */
-
- (sc->sc_otg.sc_bus.methods->vbus_interrupt)
- (&sc->sc_otg.sc_bus, vbus_val);
+ musbotg_vbus_interrupt(&sc->sc_otg, vbus_val);
}
static void
@@ -93,18 +90,17 @@ musbotg_attach(device_t dev)
int err;
int rid;
- if (sc == NULL) {
- return (ENXIO);
- }
/* setup MUSB OTG USB controller interface softc */
-
sc->sc_otg.sc_clocks_on = &musbotg_clocks_on;
sc->sc_otg.sc_clocks_off = &musbotg_clocks_off;
sc->sc_otg.sc_clocks_arg = sc;
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_otg.sc_bus.parent = dev;
+ sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
+ sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
return (ENOMEM);
@@ -133,12 +129,6 @@ musbotg_attach(device_t dev)
}
device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);
- err = usb2_config_td_setup(&sc->sc_otg.sc_config_td, sc,
- &sc->sc_otg.sc_bus.bus_mtx, NULL, 0, 4);
- if (err) {
- device_printf(dev, "could not setup config thread!\n");
- goto error;
- }
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (void *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
@@ -158,7 +148,7 @@ musbotg_attach(device_t dev)
goto error;
} else {
/* poll VBUS one time */
- musbotg_vbus_interrupt(sc);
+ musbotg_vbus_poll(sc);
}
return (0);
@@ -204,8 +194,6 @@ musbotg_detach(device_t dev)
sc->sc_otg.sc_io_res);
sc->sc_otg.sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_otg.sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL);
return (0);
diff --git a/sys/dev/usb2/controller/ohci2.c b/sys/dev/usb2/controller/ohci2.c
index b3f2f0e..a55940f 100644
--- a/sys/dev/usb2/controller/ohci2.c
+++ b/sys/dev/usb2/controller/ohci2.c
@@ -41,14 +41,11 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR ohcidebug
-#define usb2_config_td_cc ohci_config_copy
-#define usb2_config_td_softc ohci_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
@@ -99,7 +96,6 @@ extern struct usb2_pipe_methods ohci_device_isoc_methods;
extern struct usb2_pipe_methods ohci_root_ctrl_methods;
extern struct usb2_pipe_methods ohci_root_intr_methods;
-static usb2_config_td_command_t ohci_root_ctrl_task;
static void ohci_root_ctrl_poll(struct ohci_softc *sc);
static void ohci_do_poll(struct usb2_bus *bus);
static void ohci_device_done(struct usb2_xfer *xfer, usb2_error_t error);
@@ -172,7 +168,7 @@ ohci_controller_init(ohci_softc_t *sc)
DPRINTF("SMM active, request owner change\n");
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
for (i = 0; (i < 100) && (ctl & OHCI_IR); i++) {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
+ usb2_pause_mtx(NULL, 1);
ctl = OREAD4(sc, OHCI_CONTROL);
}
if (ctl & OHCI_IR) {
@@ -185,8 +181,7 @@ ohci_controller_init(ohci_softc_t *sc)
DPRINTF("cold started\n");
reset:
/* controller was cold started */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_BUS_RESET_DELAY);
+ usb2_pause_mtx(NULL, USB_BUS_RESET_DELAY);
}
/*
@@ -196,8 +191,7 @@ reset:
DPRINTF("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev));
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_BUS_RESET_DELAY);
+ usb2_pause_mtx(NULL, USB_BUS_RESET_DELAY);
/* we now own the host controller and the bus has been reset */
ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL));
@@ -259,8 +253,7 @@ reset:
desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP);
OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- OHCI_ENABLE_POWER_DELAY);
+ usb2_pause_mtx(NULL, OHCI_ENABLE_POWER_DELAY);
OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca);
/*
@@ -269,8 +262,7 @@ reset:
*/
sc->sc_noport = 0;
for (i = 0; (i < 10) && (sc->sc_noport == 0); i++) {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- OHCI_READ_DESC_DELAY);
+ usb2_pause_mtx(NULL, OHCI_READ_DESC_DELAY);
sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
}
@@ -308,8 +300,6 @@ ohci_init(ohci_softc_t *sc)
uint16_t x;
uint16_t y;
- USB_BUS_LOCK(&sc->sc_bus);
-
DPRINTF("start\n");
sc->sc_eintrs = OHCI_NORMAL_INTRS;
@@ -406,10 +396,8 @@ ohci_init(ohci_softc_t *sc)
sc->sc_bus.usbrev = USB_REV_1_0;
if (ohci_controller_init(sc)) {
- USB_BUS_UNLOCK(&sc->sc_bus);
return (USB_ERR_INVAL);
} else {
- USB_BUS_UNLOCK(&sc->sc_bus);
/* catch any lost interrupts */
ohci_do_poll(&sc->sc_bus);
return (USB_ERR_NORMAL_COMPLETION);
@@ -477,8 +465,6 @@ ohci_resume(ohci_softc_t *sc)
{
uint32_t ctl;
- USB_BUS_LOCK(&sc->sc_bus);
-
#if USB_DEBUG
DPRINTF("\n");
if (ohcidebug > 2) {
@@ -488,6 +474,7 @@ ohci_resume(ohci_softc_t *sc)
/* some broken BIOSes never initialize the Controller chip */
ohci_controller_init(sc);
+ USB_BUS_LOCK(&sc->sc_bus);
if (sc->sc_intre) {
OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
@@ -673,7 +660,7 @@ ohci_transfer_intr_enqueue(struct usb2_xfer *xfer)
return;
}
/* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
/* start timeout, if any */
if (xfer->timeout != 0) {
@@ -681,18 +668,22 @@ ohci_transfer_intr_enqueue(struct usb2_xfer *xfer)
}
}
-#define OHCI_APPEND_QH(sed,td_self,last) (last) = _ohci_append_qh(sed,td_self,last)
+#define OHCI_APPEND_QH(sed,last) (last) = _ohci_append_qh(sed,last)
static ohci_ed_t *
-_ohci_append_qh(ohci_ed_t *sed, uint32_t td_self, ohci_ed_t *last)
+_ohci_append_qh(ohci_ed_t *sed, ohci_ed_t *last)
{
DPRINTFN(11, "%p to %p\n", sed, last);
+ if (sed->prev != NULL) {
+ /* should not happen */
+ DPRINTFN(0, "ED already linked!\n");
+ return (last);
+ }
/* (sc->sc_bus.bus_mtx) must be locked */
sed->next = last->next;
sed->ed_next = last->ed_next;
sed->ed_tailp = 0;
- sed->ed_headp = td_self;
sed->prev = last;
@@ -730,13 +721,6 @@ _ohci_remove_qh(ohci_ed_t *sed, ohci_ed_t *last)
sed->next->prev = sed->prev;
usb2_pc_cpu_flush(sed->next->page_cache);
}
- /*
- * terminate transfer in case the transferred packet was
- * short so that the ED still points at the last used TD
- */
- sed->ed_flags |= htole32(OHCI_ED_SKIP);
- sed->ed_headp = sed->ed_tailp;
-
last = ((last == sed) ? sed->prev : last);
sed->prev = 0;
@@ -1240,7 +1224,7 @@ ohci_timeout(void *arg)
DPRINTF("xfer=%p\n", xfer);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* transfer is transferred */
ohci_device_done(xfer, USB_ERR_TIMEOUT);
@@ -1411,7 +1395,7 @@ ohci_setup_standard_chain(struct usb2_xfer *xfer, ohci_ed_t **ed_last)
DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->udev));
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
temp.average = xfer->max_usb2_frame_size;
temp.max_frame_size = xfer->max_frame_size;
@@ -1556,26 +1540,31 @@ ohci_setup_standard_chain(struct usb2_xfer *xfer, ohci_ed_t **ed_last)
ed_flags |= (OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD);
- if (xfer->udev->speed == USB_SPEED_LOW) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
ed_flags |= OHCI_ED_SPEED;
}
ed->ed_flags = htole32(ed_flags);
- usb2_pc_cpu_flush(ed->page_cache);
-
td = xfer->td_transfer_first;
- OHCI_APPEND_QH(ed, td->td_self, *ed_last);
+ ed->ed_headp = td->td_self;
- if (methods == &ohci_device_bulk_methods) {
- ohci_softc_t *sc = xfer->usb2_sc;
+ if (xfer->xroot->udev->pwr_save.suspended == 0) {
+ /* the append function will flush the endpoint descriptor */
+ OHCI_APPEND_QH(ed, *ed_last);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
- }
- if (methods == &ohci_device_ctrl_methods) {
- ohci_softc_t *sc = xfer->usb2_sc;
+ if (methods == &ohci_device_bulk_methods) {
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
+ OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
+ }
+ if (methods == &ohci_device_ctrl_methods) {
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
+
+ OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
+ }
+ } else {
+ usb2_pc_cpu_flush(ed->page_cache);
}
}
@@ -1583,7 +1572,7 @@ static void
ohci_root_intr_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
uint32_t hstatus;
uint16_t i;
uint16_t m;
@@ -1631,7 +1620,7 @@ static void
ohci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
{
struct usb2_pipe_methods *methods = xfer->pipe->methods;
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
ohci_ed_t *ed;
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -1687,7 +1676,7 @@ ohci_device_bulk_enter(struct usb2_xfer *xfer)
static void
ohci_device_bulk_start(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
/* setup TD's and QH */
ohci_setup_standard_chain(xfer, &sc->sc_bulk_p_last);
@@ -1730,7 +1719,7 @@ ohci_device_ctrl_enter(struct usb2_xfer *xfer)
static void
ohci_device_ctrl_start(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
/* setup TD's and QH */
ohci_setup_standard_chain(xfer, &sc->sc_ctrl_p_last);
@@ -1755,7 +1744,7 @@ struct usb2_pipe_methods ohci_device_ctrl_methods =
static void
ohci_device_intr_open(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
uint16_t best;
uint16_t bit;
uint16_t x;
@@ -1788,7 +1777,7 @@ ohci_device_intr_open(struct usb2_xfer *xfer)
static void
ohci_device_intr_close(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
sc->sc_intr_stat[xfer->qh_pos]--;
@@ -1804,7 +1793,7 @@ ohci_device_intr_enter(struct usb2_xfer *xfer)
static void
ohci_device_intr_start(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
/* setup TD's and QH */
ohci_setup_standard_chain(xfer, &sc->sc_intr_p_last[xfer->qh_pos]);
@@ -1843,7 +1832,7 @@ static void
ohci_device_isoc_enter(struct usb2_xfer *xfer)
{
struct usb2_page_search buf_res;
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
struct ohci_hcca *hcca;
uint32_t buf_offset;
uint32_t nframes;
@@ -2001,16 +1990,19 @@ ohci_device_isoc_enter(struct usb2_xfer *xfer)
OHCI_ED_SET_EN(UE_GET_ADDR(xfer->endpoint)) |
OHCI_ED_SET_MAXP(xfer->max_frame_size));
- if (xfer->udev->speed == USB_SPEED_LOW) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
ed_flags |= OHCI_ED_SPEED;
}
ed->ed_flags = htole32(ed_flags);
- usb2_pc_cpu_flush(ed->page_cache);
-
td = xfer->td_transfer_first;
- OHCI_APPEND_QH(ed, td->itd_self, sc->sc_isoc_p_last);
+ ed->ed_headp = td->itd_self;
+
+ /* isochronous transfers are not affected by suspend / resume */
+ /* the append function will flush the endpoint descriptor */
+
+ OHCI_APPEND_QH(ed, sc->sc_isoc_p_last);
}
static void
@@ -2046,7 +2038,7 @@ ohci_root_ctrl_open(struct usb2_xfer *xfer)
static void
ohci_root_ctrl_close(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_ctrl.xfer == xfer) {
sc->sc_root_ctrl.xfer = NULL;
@@ -2126,26 +2118,24 @@ ohci_root_ctrl_enter(struct usb2_xfer *xfer)
static void
ohci_root_ctrl_start(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_ctrl.xfer = xfer;
- usb2_config_td_queue_command
- (&sc->sc_config_td, NULL, &ohci_root_ctrl_task, 0, 0);
+ usb2_bus_roothub_exec(xfer->xroot->bus);
}
static void
-ohci_root_ctrl_task(struct ohci_softc *sc,
- struct ohci_config_copy *cc, uint16_t refcount)
+ohci_root_ctrl_task(struct usb2_bus *bus)
{
- ohci_root_ctrl_poll(sc);
+ ohci_root_ctrl_poll(OHCI_BUS2SC(bus));
}
static void
ohci_root_ctrl_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
char *ptr;
uint32_t port;
uint32_t v;
@@ -2170,7 +2160,7 @@ ohci_root_ctrl_done(struct usb2_xfer *xfer,
value = UGETW(std->req.wValue);
index = UGETW(std->req.wIndex);
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
"wValue=0x%04x wIndex=0x%04x\n",
@@ -2471,7 +2461,7 @@ ohci_root_intr_open(struct usb2_xfer *xfer)
static void
ohci_root_intr_close(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_intr.xfer == xfer) {
sc->sc_root_intr.xfer = NULL;
@@ -2488,7 +2478,7 @@ ohci_root_intr_enter(struct usb2_xfer *xfer)
static void
ohci_root_intr_start(struct usb2_xfer *xfer)
{
- ohci_softc_t *sc = xfer->usb2_sc;
+ ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_intr.xfer = xfer;
}
@@ -2519,11 +2509,6 @@ ohci_xfer_setup(struct usb2_setup_params *parm)
sc = OHCI_BUS2SC(parm->udev->bus);
xfer = parm->curr_xfer;
- /*
- * setup xfer
- */
- xfer->usb2_sc = sc;
-
parm->hc_max_packet_size = 0x500;
parm->hc_max_packet_count = 1;
parm->hc_max_frame_size = OHCI_PAGE_SIZE;
@@ -2740,6 +2725,115 @@ ohci_get_dma_delay(struct usb2_bus *bus, uint32_t *pus)
*pus = (1125); /* microseconds */
}
+static void
+ohci_device_resume(struct usb2_device *udev)
+{
+ struct ohci_softc *sc = OHCI_BUS2SC(udev->bus);
+ struct usb2_xfer *xfer;
+ struct usb2_pipe_methods *methods;
+ ohci_ed_t *ed;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(udev->bus);
+
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+ if (xfer->xroot->udev == udev) {
+
+ methods = xfer->pipe->methods;
+ ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
+
+ if (methods == &ohci_device_bulk_methods) {
+ OHCI_APPEND_QH(ed, sc->sc_bulk_p_last);
+ OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
+ }
+ if (methods == &ohci_device_ctrl_methods) {
+ OHCI_APPEND_QH(ed, sc->sc_ctrl_p_last);
+ OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
+ }
+ if (methods == &ohci_device_intr_methods) {
+ OHCI_APPEND_QH(ed, sc->sc_intr_p_last[xfer->qh_pos]);
+ }
+ }
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ return;
+}
+
+static void
+ohci_device_suspend(struct usb2_device *udev)
+{
+ struct ohci_softc *sc = OHCI_BUS2SC(udev->bus);
+ struct usb2_xfer *xfer;
+ struct usb2_pipe_methods *methods;
+ ohci_ed_t *ed;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(udev->bus);
+
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+ if (xfer->xroot->udev == udev) {
+
+ methods = xfer->pipe->methods;
+ ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
+
+ if (methods == &ohci_device_bulk_methods) {
+ OHCI_REMOVE_QH(ed, sc->sc_bulk_p_last);
+ }
+ if (methods == &ohci_device_ctrl_methods) {
+ OHCI_REMOVE_QH(ed, sc->sc_ctrl_p_last);
+ }
+ if (methods == &ohci_device_intr_methods) {
+ OHCI_REMOVE_QH(ed, sc->sc_intr_p_last[xfer->qh_pos]);
+ }
+ }
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ return;
+}
+
+static void
+ohci_set_hw_power(struct usb2_bus *bus)
+{
+ struct ohci_softc *sc = OHCI_BUS2SC(bus);
+ uint32_t temp;
+ uint32_t flags;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(bus);
+
+ flags = bus->hw_power_state;
+
+ temp = OREAD4(sc, OHCI_CONTROL);
+ temp &= ~(OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE);
+
+ if (flags & USB_HW_POWER_CONTROL)
+ temp |= OHCI_CLE;
+
+ if (flags & USB_HW_POWER_BULK)
+ temp |= OHCI_BLE;
+
+ if (flags & USB_HW_POWER_INTERRUPT)
+ temp |= OHCI_PLE;
+
+ if (flags & USB_HW_POWER_ISOC)
+ temp |= OHCI_IE | OHCI_PLE;
+
+ OWRITE4(sc, OHCI_CONTROL, temp);
+
+ USB_BUS_UNLOCK(bus);
+
+ return;
+}
+
struct usb2_bus_methods ohci_bus_methods =
{
.pipe_init = ohci_pipe_init,
@@ -2747,4 +2841,8 @@ struct usb2_bus_methods ohci_bus_methods =
.xfer_unsetup = ohci_xfer_unsetup,
.do_poll = ohci_do_poll,
.get_dma_delay = ohci_get_dma_delay,
+ .device_resume = ohci_device_resume,
+ .device_suspend = ohci_device_suspend,
+ .set_hw_power = ohci_set_hw_power,
+ .roothub_exec = ohci_root_ctrl_task,
};
diff --git a/sys/dev/usb2/controller/ohci2.h b/sys/dev/usb2/controller/ohci2.h
index fefde6c..84a6afd 100644
--- a/sys/dev/usb2/controller/ohci2.h
+++ b/sys/dev/usb2/controller/ohci2.h
@@ -39,6 +39,8 @@
#ifndef _OHCI_H_
#define _OHCI_H_
+#define OHCI_MAX_DEVICES USB_MAX_DEVICES
+
/* PCI config registers */
#define PCI_CBMEM 0x10 /* configuration base memory */
#define PCI_INTERFACE_OHCI 0x10
@@ -318,12 +320,12 @@ union ohci_hub_desc {
typedef struct ohci_softc {
struct ohci_hw_softc sc_hw;
struct usb2_bus sc_bus; /* base device */
- struct usb2_config_td sc_config_td;
struct usb2_callout sc_tmo_rhsc;
union ohci_hub_desc sc_hub_desc;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
+ struct usb2_device *sc_devices[OHCI_MAX_DEVICES];
struct resource *sc_io_res;
struct resource *sc_irq_res;
struct ohci_hcca *sc_hcca_p;
diff --git a/sys/dev/usb2/controller/ohci2_atmelarm.c b/sys/dev/usb2/controller/ohci2_atmelarm.c
index b440f14..a7f086c 100644
--- a/sys/dev/usb2/controller/ohci2_atmelarm.c
+++ b/sys/dev/usb2/controller/ohci2_atmelarm.c
@@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
@@ -70,15 +69,15 @@ ohci_atmelarm_attach(device_t dev)
int err;
int rid;
- if (sc == NULL) {
- return (ENXIO);
- }
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_ohci.sc_bus.parent = dev;
+ sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
+ sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
- return ENOMEM;
+ return (ENOMEM);
}
sc->iclk = at91_pmc_clock_ref("ohci_clk");
sc->fclk = at91_pmc_clock_ref("uhpck");
@@ -111,12 +110,6 @@ ohci_atmelarm_attach(device_t dev)
strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));
- err = usb2_config_td_setup(&sc->sc_ohci.sc_config_td, sc,
- &sc->sc_ohci.sc_bus.bus_mtx, NULL, 0, 4);
- if (err) {
- device_printf(dev, "could not setup config thread!\n");
- goto error;
- }
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (void *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
@@ -200,8 +193,6 @@ ohci_atmelarm_detach(device_t dev)
sc->sc_ohci.sc_io_res);
sc->sc_ohci.sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_ohci.sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc);
return (0);
diff --git a/sys/dev/usb2/controller/ohci2_pci.c b/sys/dev/usb2/controller/ohci2_pci.c
index 990c849..7d3506e 100644
--- a/sys/dev/usb2/controller/ohci2_pci.c
+++ b/sys/dev/usb2/controller/ohci2_pci.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
@@ -196,21 +195,27 @@ ohci_pci_attach(device_t self)
int rid;
int err;
- if (sc == NULL) {
- device_printf(self, "Could not allocate sc\n");
- return (ENXIO);
- }
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_bus.parent = self;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
&ohci_iterate_hw_softc)) {
- return ENOMEM;
+ return (ENOMEM);
}
sc->sc_dev = self;
pci_enable_busmaster(self);
+ /*
+ * Some Sun PCIO-2 USB controllers have their intpin register
+ * bogusly set to 0, although it should be 4. Correct that.
+ */
+ if (pci_get_devid(self) == 0x1103108e && pci_get_intpin(self) == 0)
+ pci_set_intpin(self, 4);
+
rid = PCI_CBMEM;
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
@@ -281,12 +286,6 @@ ohci_pci_attach(device_t self)
sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
}
- err = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_bus.bus_mtx,
- NULL, 0, 4);
- if (err) {
- device_printf(self, "could not setup config thread!\n");
- goto error;
- }
/* sc->sc_bus.usbrev; set by ohci_init() */
#if (__FreeBSD_version >= 700031)
@@ -322,8 +321,6 @@ ohci_pci_detach(device_t self)
ohci_softc_t *sc = device_get_softc(self);
device_t bdev;
- usb2_config_td_drain(&sc->sc_config_td);
-
if (sc->sc_bus.bdev) {
bdev = sc->sc_bus.bdev;
device_detach(bdev);
@@ -358,8 +355,6 @@ ohci_pci_detach(device_t self)
sc->sc_io_res);
sc->sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_bus, &ohci_iterate_hw_softc);
return (0);
diff --git a/sys/dev/usb2/controller/uhci2.c b/sys/dev/usb2/controller/uhci2.c
index 478e54f..107aef4 100644
--- a/sys/dev/usb2/controller/uhci2.c
+++ b/sys/dev/usb2/controller/uhci2.c
@@ -44,14 +44,11 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR uhcidebug
-#define usb2_config_td_cc uhci_config_copy
-#define usb2_config_td_softc uhci_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
@@ -138,7 +135,6 @@ extern struct usb2_pipe_methods uhci_device_isoc_methods;
extern struct usb2_pipe_methods uhci_root_ctrl_methods;
extern struct usb2_pipe_methods uhci_root_intr_methods;
-static usb2_config_td_command_t uhci_root_ctrl_task;
static void uhci_root_ctrl_poll(struct uhci_softc *);
static void uhci_do_poll(struct usb2_bus *);
static void uhci_device_done(struct usb2_xfer *, usb2_error_t);
@@ -410,8 +406,6 @@ uhci_init(uhci_softc_t *sc)
uint16_t x;
uint16_t y;
- USB_BUS_LOCK(&sc->sc_bus);
-
DPRINTF("start\n");
#if USB_DEBUG
@@ -601,12 +595,12 @@ uhci_init(uhci_softc_t *sc)
/* set up the bus struct */
sc->sc_bus.methods = &uhci_bus_methods;
+ USB_BUS_LOCK(&sc->sc_bus);
/* reset the controller */
uhci_reset(sc);
/* start the controller */
uhci_start(sc);
-
USB_BUS_UNLOCK(&sc->sc_bus);
/* catch lost interrupts */
@@ -882,7 +876,7 @@ uhci_transfer_intr_enqueue(struct usb2_xfer *xfer)
return;
}
/* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
/* start timeout, if any */
if (xfer->timeout != 0) {
@@ -916,17 +910,19 @@ _uhci_append_td(uhci_td_t *std, uhci_td_t *last)
return (std);
}
-#define UHCI_APPEND_QH(sqh,td,last) (last) = _uhci_append_qh(sqh,td,last)
+#define UHCI_APPEND_QH(sqh,last) (last) = _uhci_append_qh(sqh,last)
static uhci_qh_t *
-_uhci_append_qh(uhci_qh_t *sqh, uhci_td_t *td, uhci_qh_t *last)
+_uhci_append_qh(uhci_qh_t *sqh, uhci_qh_t *last)
{
DPRINTFN(11, "%p to %p\n", sqh, last);
+ if (sqh->h_prev != NULL) {
+ /* should not happen */
+ DPRINTFN(0, "QH already linked!\n");
+ return (last);
+ }
/* (sc->sc_bus.mtx) must be locked */
- sqh->e_next = td;
- sqh->qh_e_next = td->td_self;
-
sqh->h_next = last->h_next;
sqh->qh_h_next = last->qh_h_next;
@@ -990,13 +986,6 @@ _uhci_remove_qh(uhci_qh_t *sqh, uhci_qh_t *last)
sqh->h_next->h_prev = sqh->h_prev;
usb2_pc_cpu_flush(sqh->h_next->page_cache);
}
- /*
- * set the Terminate-bit in the e_next of the QH, in case
- * the transferred packet was short so that the QH still
- * points at the last used TD
- */
- sqh->qh_e_next = htole32(UHCI_PTR_T);
-
last = ((last == sqh) ? sqh->h_prev : last);
sqh->h_prev = 0;
@@ -1459,10 +1448,12 @@ uhci_interrupt(uhci_softc_t *sc)
}
if (status & UHCI_STS_HCH) {
/* no acknowledge needed */
- printf("%s: host controller halted\n",
+ DPRINTF("%s: host controller halted\n",
__FUNCTION__);
#if USB_DEBUG
- uhci_dump_all(sc);
+ if (uhcidebug > 0) {
+ uhci_dump_all(sc);
+ }
#endif
}
}
@@ -1497,7 +1488,7 @@ uhci_timeout(void *arg)
DPRINTF("xfer=%p\n", xfer);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* transfer is transferred */
uhci_device_done(xfer, USB_ERR_TIMEOUT);
@@ -1666,7 +1657,7 @@ uhci_setup_standard_chain(struct usb2_xfer *xfer)
DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->udev));
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
temp.average = xfer->max_frame_size;
temp.max_frame_size = xfer->max_frame_size;
@@ -1690,7 +1681,7 @@ uhci_setup_standard_chain(struct usb2_xfer *xfer)
htole32(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) |
UHCI_TD_ACTIVE));
- if (xfer->udev->speed == USB_SPEED_LOW) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
temp.td_status |= htole32(UHCI_TD_LS);
}
temp.td_token =
@@ -1823,7 +1814,7 @@ static void
uhci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
{
struct usb2_pipe_methods *methods = xfer->pipe->methods;
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
uhci_qh_t *qh;
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -1834,11 +1825,6 @@ uhci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
if (qh) {
usb2_pc_cpu_invalidate(qh->page_cache);
-
- qh->e_next = 0;
- qh->qh_e_next = htole32(UHCI_PTR_T);
-
- usb2_pc_cpu_flush(qh->page_cache);
}
if (xfer->flags_int.bandwidth_reclaimed) {
xfer->flags_int.bandwidth_reclaimed = 0;
@@ -1848,7 +1834,7 @@ uhci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
UHCI_REMOVE_QH(qh, sc->sc_bulk_p_last);
}
if (methods == &uhci_device_ctrl_methods) {
- if (xfer->udev->speed == USB_SPEED_LOW) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
UHCI_REMOVE_QH(qh, sc->sc_ls_ctl_p_last);
} else {
UHCI_REMOVE_QH(qh, sc->sc_fs_ctl_p_last);
@@ -1897,7 +1883,7 @@ uhci_device_bulk_enter(struct usb2_xfer *xfer)
static void
uhci_device_bulk_start(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
uhci_td_t *td;
uhci_qh_t *qh;
@@ -1907,9 +1893,16 @@ uhci_device_bulk_start(struct usb2_xfer *xfer)
/* setup QH */
qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
- UHCI_APPEND_QH(qh, td, sc->sc_bulk_p_last);
- uhci_add_loop(sc);
- xfer->flags_int.bandwidth_reclaimed = 1;
+ qh->e_next = td;
+ qh->qh_e_next = td->td_self;
+
+ if (xfer->xroot->udev->pwr_save.suspended == 0) {
+ UHCI_APPEND_QH(qh, sc->sc_bulk_p_last);
+ uhci_add_loop(sc);
+ xfer->flags_int.bandwidth_reclaimed = 1;
+ } else {
+ usb2_pc_cpu_flush(qh->page_cache);
+ }
/* put transfer on interrupt queue */
uhci_transfer_intr_enqueue(xfer);
@@ -1949,7 +1942,7 @@ uhci_device_ctrl_enter(struct usb2_xfer *xfer)
static void
uhci_device_ctrl_start(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
uhci_qh_t *qh;
uhci_td_t *td;
@@ -1959,14 +1952,21 @@ uhci_device_ctrl_start(struct usb2_xfer *xfer)
/* setup QH */
qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
+ qh->e_next = td;
+ qh->qh_e_next = td->td_self;
+
/*
* NOTE: some devices choke on bandwidth- reclamation for control
* transfers
*/
- if (xfer->udev->speed == USB_SPEED_LOW) {
- UHCI_APPEND_QH(qh, td, sc->sc_ls_ctl_p_last);
+ if (xfer->xroot->udev->pwr_save.suspended == 0) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
+ UHCI_APPEND_QH(qh, sc->sc_ls_ctl_p_last);
+ } else {
+ UHCI_APPEND_QH(qh, sc->sc_fs_ctl_p_last);
+ }
} else {
- UHCI_APPEND_QH(qh, td, sc->sc_fs_ctl_p_last);
+ usb2_pc_cpu_flush(qh->page_cache);
}
/* put transfer on interrupt queue */
uhci_transfer_intr_enqueue(xfer);
@@ -1988,7 +1988,7 @@ struct usb2_pipe_methods uhci_device_ctrl_methods =
static void
uhci_device_intr_open(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
uint16_t best;
uint16_t bit;
uint16_t x;
@@ -2021,7 +2021,7 @@ uhci_device_intr_open(struct usb2_xfer *xfer)
static void
uhci_device_intr_close(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
sc->sc_intr_stat[xfer->qh_pos]--;
@@ -2037,7 +2037,7 @@ uhci_device_intr_enter(struct usb2_xfer *xfer)
static void
uhci_device_intr_start(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
uhci_qh_t *qh;
uhci_td_t *td;
@@ -2047,8 +2047,17 @@ uhci_device_intr_start(struct usb2_xfer *xfer)
/* setup QH */
qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
- /* enter QHs into the controller data structures */
- UHCI_APPEND_QH(qh, td, sc->sc_intr_p_last[xfer->qh_pos]);
+ qh->e_next = td;
+ qh->qh_e_next = td->td_self;
+
+ if (xfer->xroot->udev->pwr_save.suspended == 0) {
+
+ /* enter QHs into the controller data structures */
+ UHCI_APPEND_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
+
+ } else {
+ usb2_pc_cpu_flush(qh->page_cache);
+ }
/* put transfer on interrupt queue */
uhci_transfer_intr_enqueue(xfer);
@@ -2106,7 +2115,7 @@ static void
uhci_device_isoc_enter(struct usb2_xfer *xfer)
{
struct uhci_mem_layout ml;
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
uint32_t nframes;
uint32_t temp;
uint32_t *plen;
@@ -2290,7 +2299,7 @@ uhci_root_ctrl_open(struct usb2_xfer *xfer)
static void
uhci_root_ctrl_close(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_ctrl.xfer == xfer) {
sc->sc_root_ctrl.xfer = NULL;
@@ -2385,6 +2394,24 @@ uhci_portreset(uhci_softc_t *sc, uint16_t index, uint8_t use_polling)
else
return (USB_ERR_IOERROR);
+ /*
+ * Before we do anything, turn on SOF messages on the USB
+ * BUS. Some USB devices do not cope without them!
+ */
+ if (!(UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS)) {
+
+ DPRINTF("Activating SOFs!\n");
+
+ UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS));
+
+ /* wait a little bit */
+ if (use_polling) {
+ DELAY(10000);
+ } else {
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 10);
+ }
+ }
+
x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_PR);
@@ -2402,12 +2429,16 @@ uhci_portreset(uhci_softc_t *sc, uint16_t index, uint8_t use_polling)
x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
- if (use_polling) {
- /* polling */
- DELAY(1000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
- }
+
+ mtx_unlock(&sc->sc_bus.bus_mtx);
+
+ /*
+ * This delay needs to be exactly 100us, else some USB devices
+ * fail to attach!
+ */
+ DELAY(100);
+
+ mtx_lock(&sc->sc_bus.bus_mtx);
DPRINTFN(4, "uhci port %d reset, status1 = 0x%04x\n",
index, UREAD2(sc, port));
@@ -2481,28 +2512,26 @@ uhci_root_ctrl_enter(struct usb2_xfer *xfer)
static void
uhci_root_ctrl_start(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
DPRINTF("\n");
sc->sc_root_ctrl.xfer = xfer;
- usb2_config_td_queue_command
- (&sc->sc_config_td, NULL, &uhci_root_ctrl_task, 0, 0);
+ usb2_bus_roothub_exec(xfer->xroot->bus);
}
static void
-uhci_root_ctrl_task(struct uhci_softc *sc,
- struct uhci_config_copy *cc, uint16_t refcount)
+uhci_root_ctrl_task(struct usb2_bus *bus)
{
- uhci_root_ctrl_poll(sc);
+ uhci_root_ctrl_poll(UHCI_BUS2SC(bus));
}
static void
uhci_root_ctrl_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
char *ptr;
uint16_t x;
uint16_t port;
@@ -2528,7 +2557,7 @@ uhci_root_ctrl_done(struct usb2_xfer *xfer,
value = UGETW(std->req.wValue);
index = UGETW(std->req.wIndex);
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
"wValue=0x%04x wIndex=0x%04x\n",
@@ -2659,7 +2688,7 @@ uhci_root_ctrl_done(struct usb2_xfer *xfer,
break;
case UHF_PORT_SUSPEND:
x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
+ UWRITE2(sc, port, x & ~(UHCI_PORTSC_SUSP));
break;
case UHF_PORT_RESET:
x = URWMASK(UREAD2(sc, port));
@@ -2681,11 +2710,13 @@ uhci_root_ctrl_done(struct usb2_xfer *xfer,
sc->sc_isreset = 0;
std->err = USB_ERR_NORMAL_COMPLETION;
goto done;
+ case UHF_C_PORT_SUSPEND:
+ sc->sc_isresumed &= ~(1 << index);
+ break;
case UHF_PORT_CONNECTION:
case UHF_PORT_OVER_CURRENT:
case UHF_PORT_POWER:
case UHF_PORT_LOW_SPEED:
- case UHF_C_PORT_SUSPEND:
default:
std->err = USB_ERR_IOERROR;
goto done;
@@ -2740,11 +2771,35 @@ uhci_root_ctrl_done(struct usb2_xfer *xfer,
status |= UPS_OVERCURRENT_INDICATOR;
if (x & UHCI_PORTSC_OCIC)
change |= UPS_C_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_SUSP)
- status |= UPS_SUSPEND;
if (x & UHCI_PORTSC_LSDA)
status |= UPS_LOW_SPEED;
+ if ((x & UHCI_PORTSC_PE) && (x & UHCI_PORTSC_RD)) {
+ /* need to do a write back */
+ UWRITE2(sc, port, URWMASK(x));
+
+ /* wait 20ms for resume sequence to complete */
+ if (use_polling) {
+ /* polling */
+ DELAY(20 * 1000);
+ } else {
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 20);
+ }
+
+ /* clear suspend and resume detect */
+ UWRITE2(sc, port, URWMASK(x) & ~(UHCI_PORTSC_RD |
+ UHCI_PORTSC_SUSP));
+
+ /* wait a little bit */
+ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 2);
+
+ sc->sc_isresumed |= (1 << index);
+
+ } else if (x & UHCI_PORTSC_SUSP) {
+ status |= UPS_SUSPEND;
+ }
status |= UPS_PORT_POWER;
+ if (sc->sc_isresumed & (1 << index))
+ change |= UPS_C_SUSPEND;
if (sc->sc_isreset)
change |= UPS_C_PORT_RESET;
USETW(sc->sc_hub_desc.ps.wPortStatus, status);
@@ -2831,7 +2886,7 @@ uhci_root_intr_open(struct usb2_xfer *xfer)
static void
uhci_root_intr_close(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_intr.xfer == xfer) {
sc->sc_root_intr.xfer = NULL;
@@ -2848,7 +2903,7 @@ uhci_root_intr_enter(struct usb2_xfer *xfer)
static void
uhci_root_intr_start(struct usb2_xfer *xfer)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_intr.xfer = xfer;
@@ -2860,7 +2915,7 @@ static void
uhci_root_intr_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
@@ -2886,7 +2941,7 @@ static void
uhci_root_intr_check(void *arg)
{
struct usb2_xfer *xfer = arg;
- uhci_softc_t *sc = xfer->usb2_sc;
+ uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
DPRINTFN(21, "\n");
@@ -2894,13 +2949,15 @@ uhci_root_intr_check(void *arg)
sc->sc_hub_idata[0] = 0;
- if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC | UHCI_PORTSC_OCIC)) {
+ if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC |
+ UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) {
sc->sc_hub_idata[0] |= 1 << 1;
}
- if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC | UHCI_PORTSC_OCIC)) {
+ if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC |
+ UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) {
sc->sc_hub_idata[0] |= 1 << 2;
}
- if ((sc->sc_hub_idata[0] == 0) || !(UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS)) {
+ if (sc->sc_hub_idata[0] == 0) {
/*
* no change or controller not running, try again in a while
*/
@@ -2938,11 +2995,6 @@ uhci_xfer_setup(struct usb2_setup_params *parm)
sc = UHCI_BUS2SC(parm->udev->bus);
xfer = parm->curr_xfer;
- /*
- * setup xfer
- */
- xfer->usb2_sc = sc;
-
parm->hc_max_packet_size = 0x500;
parm->hc_max_packet_count = 1;
parm->hc_max_frame_size = 0x500;
@@ -3190,6 +3242,130 @@ uhci_get_dma_delay(struct usb2_bus *bus, uint32_t *pus)
*pus = (1125); /* microseconds */
}
+static void
+uhci_device_resume(struct usb2_device *udev)
+{
+ struct uhci_softc *sc = UHCI_BUS2SC(udev->bus);
+ struct usb2_xfer *xfer;
+ struct usb2_pipe_methods *methods;
+ uhci_qh_t *qh;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(udev->bus);
+
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+ if (xfer->xroot->udev == udev) {
+
+ methods = xfer->pipe->methods;
+ qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
+
+ if (methods == &uhci_device_bulk_methods) {
+ UHCI_APPEND_QH(qh, sc->sc_bulk_p_last);
+ uhci_add_loop(sc);
+ xfer->flags_int.bandwidth_reclaimed = 1;
+ }
+ if (methods == &uhci_device_ctrl_methods) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
+ UHCI_APPEND_QH(qh, sc->sc_ls_ctl_p_last);
+ } else {
+ UHCI_APPEND_QH(qh, sc->sc_fs_ctl_p_last);
+ }
+ }
+ if (methods == &uhci_device_intr_methods) {
+ UHCI_APPEND_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
+ }
+ }
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ return;
+}
+
+static void
+uhci_device_suspend(struct usb2_device *udev)
+{
+ struct uhci_softc *sc = UHCI_BUS2SC(udev->bus);
+ struct usb2_xfer *xfer;
+ struct usb2_pipe_methods *methods;
+ uhci_qh_t *qh;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(udev->bus);
+
+ TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+ if (xfer->xroot->udev == udev) {
+
+ methods = xfer->pipe->methods;
+ qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
+
+ if (xfer->flags_int.bandwidth_reclaimed) {
+ xfer->flags_int.bandwidth_reclaimed = 0;
+ uhci_rem_loop(sc);
+ }
+ if (methods == &uhci_device_bulk_methods) {
+ UHCI_REMOVE_QH(qh, sc->sc_bulk_p_last);
+ }
+ if (methods == &uhci_device_ctrl_methods) {
+ if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
+ UHCI_REMOVE_QH(qh, sc->sc_ls_ctl_p_last);
+ } else {
+ UHCI_REMOVE_QH(qh, sc->sc_fs_ctl_p_last);
+ }
+ }
+ if (methods == &uhci_device_intr_methods) {
+ UHCI_REMOVE_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
+ }
+ }
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ return;
+}
+
+static void
+uhci_set_hw_power(struct usb2_bus *bus)
+{
+ struct uhci_softc *sc = UHCI_BUS2SC(bus);
+ uint32_t flags;
+
+ DPRINTF("\n");
+
+ USB_BUS_LOCK(bus);
+
+ flags = bus->hw_power_state;
+
+ /*
+ * WARNING: Some FULL speed USB devices require periodic SOF
+ * messages! If any USB devices are connected through the
+ * UHCI, power save will be disabled!
+ */
+ if (flags & (USB_HW_POWER_CONTROL |
+ USB_HW_POWER_NON_ROOT_HUB |
+ USB_HW_POWER_BULK |
+ USB_HW_POWER_INTERRUPT |
+ USB_HW_POWER_ISOC)) {
+ DPRINTF("Some USB transfer is "
+ "active on %u.\n",
+ device_get_unit(sc->sc_bus.bdev));
+ UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS));
+ } else {
+ DPRINTF("Power save on %u.\n",
+ device_get_unit(sc->sc_bus.bdev));
+ UHCICMD(sc, UHCI_CMD_MAXP);
+ }
+
+ USB_BUS_UNLOCK(bus);
+
+ return;
+}
+
+
struct usb2_bus_methods uhci_bus_methods =
{
.pipe_init = uhci_pipe_init,
@@ -3197,4 +3373,8 @@ struct usb2_bus_methods uhci_bus_methods =
.xfer_unsetup = uhci_xfer_unsetup,
.do_poll = uhci_do_poll,
.get_dma_delay = uhci_get_dma_delay,
+ .device_resume = uhci_device_resume,
+ .device_suspend = uhci_device_suspend,
+ .set_hw_power = uhci_set_hw_power,
+ .roothub_exec = uhci_root_ctrl_task,
};
diff --git a/sys/dev/usb2/controller/uhci2.h b/sys/dev/usb2/controller/uhci2.h
index 9be89ed..9365a4c 100644
--- a/sys/dev/usb2/controller/uhci2.h
+++ b/sys/dev/usb2/controller/uhci2.h
@@ -39,6 +39,8 @@
#ifndef _UHCI_H_
#define _UHCI_H_
+#define UHCI_MAX_DEVICES USB_MAX_DEVICES
+
/* PCI config registers */
#define PCI_USBREV 0x60 /* USB protocol revision */
#define PCI_USB_REV_MASK 0xff
@@ -268,11 +270,11 @@ struct uhci_hw_softc {
typedef struct uhci_softc {
struct uhci_hw_softc sc_hw;
struct usb2_bus sc_bus; /* base device */
- struct usb2_config_td sc_config_td;
union uhci_hub_desc sc_hub_desc;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
+ struct usb2_device *sc_devices[UHCI_MAX_DEVICES];
struct uhci_td *sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]; /* pointer to last TD
* for isochronous */
struct uhci_qh *sc_intr_p_last[UHCI_IFRAMELIST_COUNT]; /* pointer to last QH
@@ -300,7 +302,8 @@ typedef struct uhci_softc {
uint8_t sc_addr; /* device address */
uint8_t sc_conf; /* device configuration */
- uint8_t sc_isreset;
+ uint8_t sc_isreset; /* bits set if a root hub is reset */
+ uint8_t sc_isresumed; /* bits set if a port was resumed */
uint8_t sc_saved_sof;
uint8_t sc_hub_idata[1];
diff --git a/sys/dev/usb2/controller/uhci2_pci.c b/sys/dev/usb2/controller/uhci2_pci.c
index 9baf42b..725cd84 100644
--- a/sys/dev/usb2/controller/uhci2_pci.c
+++ b/sys/dev/usb2/controller/uhci2_pci.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/core/usb2_debug.h>
@@ -247,13 +246,12 @@ uhci_pci_attach(device_t self)
int rid;
int err;
- if (sc == NULL) {
- device_printf(self, "Could not allocate sc\n");
- return (ENXIO);
- }
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_bus.parent = self;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = UHCI_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
&uhci_iterate_hw_softc)) {
return ENOMEM;
@@ -318,16 +316,12 @@ uhci_pci_attach(device_t self)
sc->sc_bus.usbrev = USB_REV_1_0;
break;
default:
- sc->sc_bus.usbrev = USB_REV_UNKNOWN;
+ /* Quirk for Parallels Desktop 4.0 */
+ device_printf(self, "USB revision is unknown. Assuming v1.1.\n");
+ sc->sc_bus.usbrev = USB_REV_1_1;
break;
}
- err = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_bus.bus_mtx,
- NULL, 0, 4);
- if (err) {
- device_printf(self, "could not setup config thread!\n");
- goto error;
- }
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (void *)(void *)uhci_interrupt, sc, &sc->sc_intr_hdl);
@@ -376,8 +370,6 @@ uhci_pci_detach(device_t self)
uhci_softc_t *sc = device_get_softc(self);
device_t bdev;
- usb2_config_td_drain(&sc->sc_config_td);
-
if (sc->sc_bus.bdev) {
bdev = sc->sc_bus.bdev;
device_detach(bdev);
@@ -419,8 +411,6 @@ uhci_pci_detach(device_t self)
sc->sc_io_res);
sc->sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_bus, &uhci_iterate_hw_softc);
return (0);
diff --git a/sys/dev/usb2/controller/usb2_bus.h b/sys/dev/usb2/controller/usb2_bus.h
index d9dc74e..c81a7a5 100644
--- a/sys/dev/usb2/controller/usb2_bus.h
+++ b/sys/dev/usb2/controller/usb2_bus.h
@@ -52,12 +52,25 @@ struct usb2_bus {
struct usb2_bus_stat stats_err;
struct usb2_bus_stat stats_ok;
struct usb2_process explore_proc;
+ struct usb2_process roothub_proc;
+ /*
+ * There are two callback processes. One for Giant locked
+ * callbacks. One for non-Giant locked callbacks. This should
+ * avoid congestion and reduce response time in most cases.
+ */
+ struct usb2_process giant_callback_proc;
+ struct usb2_process non_giant_callback_proc;
struct usb2_bus_msg explore_msg[2];
struct usb2_bus_msg detach_msg[2];
- struct mtx bus_mtx; /* This mutex protects the USB
- * hardware */
+ struct usb2_bus_msg attach_msg[2];
+ struct usb2_bus_msg roothub_msg[2];
+ /*
+ * This mutex protects the USB hardware:
+ */
+ struct mtx bus_mtx;
struct usb2_perm perm;
struct usb2_xfer_queue intr_q;
+ struct usb2_callout power_wdog; /* power management */
device_t parent;
device_t bdev; /* filled by HC driver */
@@ -66,8 +79,9 @@ struct usb2_bus {
struct usb2_dma_tag dma_tags[USB_BUS_DMA_TAG_MAX];
struct usb2_bus_methods *methods; /* filled by HC driver */
- struct usb2_device *devices[USB_MAX_DEVICES];
+ struct usb2_device **devices;
+ uint32_t hw_power_state; /* see USB_HW_POWER_XXX */
uint32_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
uint32_t transfer_count[4];
uint16_t isoc_time_last; /* in milliseconds */
diff --git a/sys/dev/usb2/controller/usb2_controller.c b/sys/dev/usb2/controller/usb2_controller.c
index 5dd517d..a9596c7 100644
--- a/sys/dev/usb2/controller/usb2_controller.c
+++ b/sys/dev/usb2/controller/usb2_controller.c
@@ -59,6 +59,7 @@ static void usb2_bus_mem_alloc_all_cb(struct usb2_bus *,
static void usb2_bus_mem_free_all_cb(struct usb2_bus *,
struct usb2_page_cache *, struct usb2_page *, uint32_t,
uint32_t);
+static void usb2_bus_roothub(struct usb2_proc_msg *pm);
/* static variables */
@@ -148,6 +149,9 @@ usb2_detach(device_t dev)
/* was never setup properly */
return (0);
}
+ /* Stop power watchdog */
+ usb2_callout_drain(&bus->power_wdog);
+
/* Let the USB explore process detach all devices. */
USB_BUS_LOCK(bus);
@@ -162,6 +166,15 @@ usb2_detach(device_t dev)
USB_BUS_UNLOCK(bus);
+ /* Get rid of USB callback processes */
+
+ usb2_proc_unsetup(&bus->giant_callback_proc);
+ usb2_proc_unsetup(&bus->non_giant_callback_proc);
+
+ /* Get rid of USB roothub process */
+
+ usb2_proc_unsetup(&bus->roothub_proc);
+
/* Get rid of USB explore process */
usb2_proc_unsetup(&bus->explore_proc);
@@ -198,6 +211,11 @@ usb2_bus_explore(struct usb2_proc_msg *pm)
mtx_lock(&Giant);
/*
+ * First update the USB power state!
+ */
+ usb2_bus_powerd(bus);
+
+ /*
* Explore the Root USB HUB. This call can sleep,
* exiting Giant, which is actually Giant.
*/
@@ -246,24 +264,41 @@ usb2_bus_detach(struct usb2_proc_msg *pm)
bus->bdev = NULL;
}
+static void
+usb2_power_wdog(void *arg)
+{
+ struct usb2_bus *bus = arg;
+
+ USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
+
+ usb2_callout_reset(&bus->power_wdog,
+ 4 * hz, usb2_power_wdog, arg);
+
+ USB_BUS_UNLOCK(bus);
+
+ usb2_bus_power_update(bus);
+
+ return;
+}
+
/*------------------------------------------------------------------------*
- * usb2_attach_sub
+ * usb2_bus_attach
*
- * This function is the real USB bus attach code. It is factored out,
- * hence it can be called at two different places in time. During
- * bootup this function is called from "usb2_post_init". During
- * hot-plug it is called directly from the "usb2_attach()" method.
+ * This function attaches USB in context of the explore thread.
*------------------------------------------------------------------------*/
static void
-usb2_attach_sub(device_t dev, struct usb2_bus *bus)
+usb2_bus_attach(struct usb2_proc_msg *pm)
{
+ struct usb2_bus *bus;
struct usb2_device *child;
+ device_t dev;
usb2_error_t err;
uint8_t speed;
- DPRINTF("\n");
+ bus = ((struct usb2_bus_msg *)pm)->bus;
+ dev = bus->bdev;
- mtx_assert(&Giant, MA_OWNED);
+ DPRINTF("\n");
switch (bus->usbrev) {
case USB_REV_1_0:
@@ -291,6 +326,9 @@ usb2_attach_sub(device_t dev, struct usb2_bus *bus)
return;
}
+ USB_BUS_UNLOCK(bus);
+ mtx_lock(&Giant); /* XXX not required by USB */
+
/* Allocate the Root USB device */
child = usb2_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
@@ -307,10 +345,36 @@ usb2_attach_sub(device_t dev, struct usb2_bus *bus)
err = USB_ERR_NOMEM;
}
+ mtx_unlock(&Giant);
+ USB_BUS_LOCK(bus);
+
if (err) {
device_printf(bus->bdev, "Root HUB problem, error=%s\n",
usb2_errstr(err));
}
+
+ /* set softc - we are ready */
+ device_set_softc(dev, bus);
+
+ /* start watchdog - this function will unlock the BUS lock ! */
+ usb2_power_wdog(bus);
+
+ /* need to return locked */
+ USB_BUS_LOCK(bus);
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_attach_sub
+ *
+ * This function creates a thread which runs the USB attach code. It
+ * is factored out, hence it can be called at two different places in
+ * time. During bootup this function is called from
+ * "usb2_post_init". During hot-plug it is called directly from the
+ * "usb2_attach()" method.
+ *------------------------------------------------------------------------*/
+static void
+usb2_attach_sub(device_t dev, struct usb2_bus *bus)
+{
/* Initialise USB process messages */
bus->explore_msg[0].hdr.pm_callback = &usb2_bus_explore;
bus->explore_msg[0].bus = bus;
@@ -322,13 +386,43 @@ usb2_attach_sub(device_t dev, struct usb2_bus *bus)
bus->detach_msg[1].hdr.pm_callback = &usb2_bus_detach;
bus->detach_msg[1].bus = bus;
- /* Create a new USB process */
- if (usb2_proc_setup(&bus->explore_proc,
+ bus->attach_msg[0].hdr.pm_callback = &usb2_bus_attach;
+ bus->attach_msg[0].bus = bus;
+ bus->attach_msg[1].hdr.pm_callback = &usb2_bus_attach;
+ bus->attach_msg[1].bus = bus;
+
+ bus->roothub_msg[0].hdr.pm_callback = &usb2_bus_roothub;
+ bus->roothub_msg[0].bus = bus;
+ bus->roothub_msg[1].hdr.pm_callback = &usb2_bus_roothub;
+ bus->roothub_msg[1].bus = bus;
+
+ /* Create USB explore, roothub and callback processes */
+
+ if (usb2_proc_setup(&bus->giant_callback_proc,
&bus->bus_mtx, USB_PRI_MED)) {
- printf("WARNING: Creation of USB explore process failed.\n");
+ printf("WARNING: Creation of USB Giant "
+ "callback process failed.\n");
+ } else if (usb2_proc_setup(&bus->non_giant_callback_proc,
+ &bus->bus_mtx, USB_PRI_HIGH)) {
+ printf("WARNING: Creation of USB non-Giant "
+ "callback process failed.\n");
+ } else if (usb2_proc_setup(&bus->roothub_proc,
+ &bus->bus_mtx, USB_PRI_HIGH)) {
+ printf("WARNING: Creation of USB roothub "
+ "process failed.\n");
+ } else if (usb2_proc_setup(&bus->explore_proc,
+ &bus->bus_mtx, USB_PRI_MED)) {
+ printf("WARNING: Creation of USB explore "
+ "process failed.\n");
+ } else {
+ /* Get final attach going */
+ USB_BUS_LOCK(bus);
+ if (usb2_proc_msignal(&bus->explore_proc,
+ &bus->attach_msg[0], &bus->attach_msg[1])) {
+ /* ignore */
+ }
+ USB_BUS_UNLOCK(bus);
}
- /* set softc - we are ready */
- device_set_softc(dev, bus);
}
/*------------------------------------------------------------------------*
@@ -428,16 +522,24 @@ usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat,
{
bus->alloc_failed = 0;
- bus->devices_max = USB_MAX_DEVICES;
-
mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
NULL, MTX_DEF | MTX_RECURSE);
+ usb2_callout_init_mtx(&bus->power_wdog,
+ &bus->bus_mtx, CALLOUT_RETURNUNLOCKED);
+
TAILQ_INIT(&bus->intr_q.head);
usb2_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
dmat, &bus->bus_mtx, NULL, NULL, 32, USB_BUS_DMA_TAG_MAX);
+ if ((bus->devices_max > USB_MAX_DEVICES) ||
+ (bus->devices_max < USB_MIN_DEVICES) ||
+ (bus->devices == NULL)) {
+ DPRINTFN(0, "Devices field has not been "
+ "initialised properly!\n");
+ bus->alloc_failed = 1; /* failure */
+ }
if (cb) {
cb(bus, &usb2_bus_mem_alloc_all_cb);
}
@@ -470,3 +572,38 @@ usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
mtx_destroy(&bus->bus_mtx);
}
+
+/*------------------------------------------------------------------------*
+ * usb2_bus_roothub
+ *
+ * This function is used to execute roothub control requests on the
+ * roothub and is called from the roothub process.
+ *------------------------------------------------------------------------*/
+static void
+usb2_bus_roothub(struct usb2_proc_msg *pm)
+{
+ struct usb2_bus *bus;
+
+ bus = ((struct usb2_bus_msg *)pm)->bus;
+
+ USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
+
+ (bus->methods->roothub_exec) (bus);
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_bus_roothub_exec
+ *
+ * This function is used to schedule the "roothub_done" bus callback
+ * method. The bus lock must be locked when calling this function.
+ *------------------------------------------------------------------------*/
+void
+usb2_bus_roothub_exec(struct usb2_bus *bus)
+{
+ USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
+
+ if (usb2_proc_msignal(&bus->roothub_proc,
+ &bus->roothub_msg[0], &bus->roothub_msg[1])) {
+ /* ignore */
+ }
+}
diff --git a/sys/dev/usb2/controller/usb2_controller.h b/sys/dev/usb2/controller/usb2_controller.h
index 496e8c2..80633d9 100644
--- a/sys/dev/usb2/controller/usb2_controller.h
+++ b/sys/dev/usb2/controller/usb2_controller.h
@@ -61,17 +61,44 @@ struct usb2_bus_methods {
void (*xfer_setup) (struct usb2_setup_params *parm);
void (*xfer_unsetup) (struct usb2_xfer *xfer);
void (*get_dma_delay) (struct usb2_bus *, uint32_t *pdelay);
+ void (*device_suspend) (struct usb2_device *udev);
+ void (*device_resume) (struct usb2_device *udev);
+ void (*set_hw_power) (struct usb2_bus *bus);
+ /*
+ * The following flag is set if one or more control transfers are
+ * active:
+ */
+#define USB_HW_POWER_CONTROL 0x01
+ /*
+ * The following flag is set if one or more bulk transfers are
+ * active:
+ */
+#define USB_HW_POWER_BULK 0x02
+ /*
+ * The following flag is set if one or more interrupt transfers are
+ * active:
+ */
+#define USB_HW_POWER_INTERRUPT 0x04
+ /*
+ * The following flag is set if one or more isochronous transfers
+ * are active:
+ */
+#define USB_HW_POWER_ISOC 0x08
+ /*
+ * The following flag is set if one or more non-root-HUB devices
+ * are present on the given USB bus:
+ */
+#define USB_HW_POWER_NON_ROOT_HUB 0x10
/* USB Device mode only - Mandatory */
void (*get_hw_ep_profile) (struct usb2_device *udev, const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr);
void (*set_stall) (struct usb2_device *udev, struct usb2_xfer *xfer, struct usb2_pipe *pipe);
void (*clear_stall) (struct usb2_device *udev, struct usb2_pipe *pipe);
- void (*rem_wakeup_set) (struct usb2_device *udev, uint8_t is_on);
- /* USB Device mode only - Optional */
+ /* USB Device and Host mode - Optional */
- void (*vbus_interrupt) (struct usb2_bus *, uint8_t is_on);
+ void (*roothub_exec) (struct usb2_bus *);
};
/*
@@ -90,7 +117,6 @@ struct usb2_pipe_methods {
/* Optional */
- uint8_t (*isdone) (struct usb2_xfer *xfer);
void *info;
/* Flags */
@@ -165,6 +191,7 @@ struct usb2_temp_setup {
void usb2_bus_mem_flush_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb);
uint8_t usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat, usb2_bus_mem_cb_t *cb);
void usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb);
+void usb2_bus_roothub_exec(struct usb2_bus *bus);
uint16_t usb2_isoc_time_expand(struct usb2_bus *bus, uint16_t isoc_time_curr);
uint16_t usb2_fs_isoc_schedule_isoc_time_expand(struct usb2_device *udev, struct usb2_fs_isoc_schedule **pp_start, struct usb2_fs_isoc_schedule **pp_end, uint16_t isoc_time);
uint8_t usb2_fs_isoc_schedule_alloc(struct usb2_fs_isoc_schedule *fss, uint8_t *pstart, uint16_t len);
diff --git a/sys/dev/usb2/controller/uss820dci.c b/sys/dev/usb2/controller/uss820dci.c
index d010a53..58208d2 100644
--- a/sys/dev/usb2/controller/uss820dci.c
+++ b/sys/dev/usb2/controller/uss820dci.c
@@ -39,14 +39,11 @@
#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR uss820dcidebug
-#define usb2_config_td_cc uss820dci_config_copy
-#define usb2_config_td_softc uss820dci_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
@@ -98,7 +95,6 @@ static void uss820dci_update_shared_1(struct uss820dci_softc *, uint8_t,
static usb2_sw_transfer_func_t uss820dci_root_intr_done;
static usb2_sw_transfer_func_t uss820dci_root_ctrl_done;
-static usb2_config_td_command_t uss820dci_root_ctrl_task;
/*
* Here is a list of what the USS820D chip can support. The main
@@ -223,29 +219,6 @@ uss820dci_wakeup_peer(struct uss820dci_softc *sc)
}
static void
-uss820dci_rem_wakeup_set(struct usb2_device *udev, uint8_t is_on)
-{
- struct uss820dci_softc *sc;
- uint8_t temp;
-
- DPRINTFN(5, "is_on=%u\n", is_on);
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- sc = USS820_DCI_BUS2SC(udev->bus);
-
- temp = USS820_READ_1(sc, USS820_SCR);
-
- if (is_on) {
- temp |= USS820_SCR_RWUPE;
- } else {
- temp &= ~USS820_SCR_RWUPE;
- }
-
- USS820_WRITE_1(sc, USS820_SCR, temp);
-}
-
-static void
uss820dci_set_address(struct uss820dci_softc *sc, uint8_t addr)
{
DPRINTFN(5, "addr=%d\n", addr);
@@ -852,7 +825,7 @@ uss820dci_setup_standard_chain(struct usb2_xfer *xfer)
DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->udev));
+ xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
temp.max_frame_size = xfer->max_frame_size;
@@ -867,7 +840,7 @@ uss820dci_setup_standard_chain(struct usb2_xfer *xfer)
temp.setup_alt_next = xfer->flags_int.short_frames_ok;
temp.offset = 0;
- sc = xfer->usb2_sc;
+ sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
ep_no = (xfer->endpoint & UE_ADDR);
/* check if we should prepend a setup message */
@@ -976,7 +949,7 @@ uss820dci_timeout(void *arg)
DPRINTF("xfer=%p\n", xfer);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* transfer is transferred */
uss820dci_device_done(xfer, USB_ERR_TIMEOUT);
@@ -985,7 +958,7 @@ uss820dci_timeout(void *arg)
static void
uss820dci_intr_set(struct usb2_xfer *xfer, uint8_t set)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
uint8_t ep_no = (xfer->endpoint & UE_ADDR);
uint8_t ep_reg;
uint8_t temp;
@@ -1037,7 +1010,7 @@ uss820dci_start_standard_chain(struct usb2_xfer *xfer)
uss820dci_intr_set(xfer, 1);
/* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
+ usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
/* start timeout, if any */
if (xfer->timeout != 0) {
@@ -1051,7 +1024,7 @@ static void
uss820dci_root_intr_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
DPRINTFN(9, "\n");
@@ -1191,7 +1164,7 @@ done:
static void
uss820dci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
{
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
xfer, xfer->pipe, error);
@@ -1375,6 +1348,7 @@ uss820dci_init(struct uss820dci_softc *sc)
USS820_WRITE_1(sc, USS820_SCR,
USS820_SCR_T_IRQ |
USS820_SCR_IE_RESET |
+ /* USS820_SCR_RWUPE | */
USS820_SCR_IE_SUSP |
USS820_SCR_IRQPOL);
@@ -1664,7 +1638,7 @@ uss820dci_device_isoc_fs_close(struct usb2_xfer *xfer)
static void
uss820dci_device_isoc_fs_enter(struct usb2_xfer *xfer)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
uint32_t temp;
uint32_t nframes;
@@ -1746,7 +1720,7 @@ uss820dci_root_ctrl_open(struct usb2_xfer *xfer)
static void
uss820dci_root_ctrl_close(struct usb2_xfer *xfer)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_ctrl.xfer == xfer) {
sc->sc_root_ctrl.xfer = NULL;
@@ -1820,7 +1794,7 @@ static const struct usb2_hub_descriptor_min uss820dci_hubd = {
.wHubCharacteristics[0] =
(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
.wHubCharacteristics[1] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
+ (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
.bPwrOn2PwrGood = 50,
.bHubContrCurrent = 0,
.DeviceRemovable = {0}, /* port is removable */
@@ -1850,26 +1824,24 @@ uss820dci_root_ctrl_enter(struct usb2_xfer *xfer)
static void
uss820dci_root_ctrl_start(struct usb2_xfer *xfer)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_ctrl.xfer = xfer;
- usb2_config_td_queue_command(
- &sc->sc_config_td, NULL, &uss820dci_root_ctrl_task, 0, 0);
+ usb2_bus_roothub_exec(xfer->xroot->bus);
}
static void
-uss820dci_root_ctrl_task(struct uss820dci_softc *sc,
- struct uss820dci_config_copy *cc, uint16_t refcount)
+uss820dci_root_ctrl_task(struct usb2_bus *bus)
{
- uss820dci_root_ctrl_poll(sc);
+ uss820dci_root_ctrl_poll(USS820_DCI_BUS2SC(bus));
}
static void
uss820dci_root_ctrl_done(struct usb2_xfer *xfer,
struct usb2_sw_transfer *std)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
uint16_t value;
uint16_t index;
uint8_t use_polling;
@@ -1890,7 +1862,7 @@ uss820dci_root_ctrl_done(struct usb2_xfer *xfer,
value = UGETW(std->req.wValue);
index = UGETW(std->req.wIndex);
- use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
+ use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
/* demultiplex the control request */
@@ -2286,7 +2258,7 @@ uss820dci_root_intr_open(struct usb2_xfer *xfer)
static void
uss820dci_root_intr_close(struct usb2_xfer *xfer)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
if (sc->sc_root_intr.xfer == xfer) {
sc->sc_root_intr.xfer = NULL;
@@ -2303,7 +2275,7 @@ uss820dci_root_intr_enter(struct usb2_xfer *xfer)
static void
uss820dci_root_intr_start(struct usb2_xfer *xfer)
{
- struct uss820dci_softc *sc = xfer->usb2_sc;
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
sc->sc_root_intr.xfer = xfer;
}
@@ -2333,11 +2305,6 @@ uss820dci_xfer_setup(struct usb2_setup_params *parm)
xfer = parm->curr_xfer;
/*
- * setup xfer
- */
- xfer->usb2_sc = sc;
-
- /*
* NOTE: This driver does not use any of the parameters that
* are computed from the following values. Just set some
* reasonable dummies:
@@ -2518,5 +2485,5 @@ struct usb2_bus_methods uss820dci_bus_methods =
.get_hw_ep_profile = &uss820dci_get_hw_ep_profile,
.set_stall = &uss820dci_set_stall,
.clear_stall = &uss820dci_clear_stall,
- .rem_wakeup_set = &uss820dci_rem_wakeup_set,
+ .roothub_exec = &uss820dci_root_ctrl_task,
};
diff --git a/sys/dev/usb2/controller/uss820dci.h b/sys/dev/usb2/controller/uss820dci.h
index aa8b535..f99e2d5 100644
--- a/sys/dev/usb2/controller/uss820dci.h
+++ b/sys/dev/usb2/controller/uss820dci.h
@@ -28,6 +28,8 @@
#ifndef _USS820_DCI_H_
#define _USS820_DCI_H_
+#define USS820_MAX_DEVICES (USB_MIN_DEVICES + 1)
+
#define USS820_EP_MAX 8 /* maximum number of endpoints */
#define USS820_TXDAT 0x00 /* Transmit FIFO data */
@@ -345,8 +347,8 @@ struct uss820dci_softc {
LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
- struct usb2_config_td sc_config_td;
+ struct usb2_device *sc_devices[USS820_MAX_DEVICES];
struct resource *sc_io_res;
struct resource *sc_irq_res;
void *sc_intr_hdl;
diff --git a/sys/dev/usb2/controller/uss820dci_atmelarm.c b/sys/dev/usb2/controller/uss820dci_atmelarm.c
index 8e92ffb..387c167 100644
--- a/sys/dev/usb2/controller/uss820dci_atmelarm.c
+++ b/sys/dev/usb2/controller/uss820dci_atmelarm.c
@@ -34,7 +34,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_sw_transfer.h>
#include <dev/usb2/core/usb2_util.h>
@@ -135,12 +134,12 @@ uss820_atmelarm_attach(device_t dev)
int err;
int rid;
- if (sc == NULL) {
- return (ENXIO);
- }
- /* get all DMA memory */
-
+ /* initialise some bus fields */
sc->sc_bus.parent = dev;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = USS820_MAX_DEVICES;
+
+ /* get all DMA memory */
if (usb2_bus_mem_alloc_all(&sc->sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
return (ENOMEM);
@@ -171,12 +170,6 @@ uss820_atmelarm_attach(device_t dev)
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
- err = usb2_config_td_setup(&sc->sc_config_td, sc,
- &sc->sc_bus.bus_mtx, NULL, 0, 4);
- if (err) {
- device_printf(dev, "could not setup config thread!\n");
- goto error;
- }
#if (__FreeBSD_version >= 700031)
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
@@ -240,8 +233,6 @@ uss820_atmelarm_detach(device_t dev)
sc->sc_io_res);
sc->sc_io_res = NULL;
}
- usb2_config_td_unsetup(&sc->sc_config_td);
-
usb2_bus_mem_free_all(&sc->sc_bus, NULL);
return (0);
diff --git a/sys/dev/usb2/core/usb2_busdma.c b/sys/dev/usb2/core/usb2_busdma.c
index 33851f0..6c1f182e3 100644
--- a/sys/dev/usb2/core/usb2_busdma.c
+++ b/sys/dev/usb2/core/usb2_busdma.c
@@ -29,12 +29,15 @@
#include <dev/usb2/include/usb2_standard.h>
#include <dev/usb2/include/usb2_defs.h>
+#define USB_DEBUG_VAR usb2_debug
+
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
#include <dev/usb2/core/usb2_transfer.h>
#include <dev/usb2/core/usb2_device.h>
#include <dev/usb2/core/usb2_util.h>
+#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/controller/usb2_controller.h>
#include <dev/usb2/controller/usb2_bus.h>
@@ -418,7 +421,16 @@ usb2_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
pc->page_offset_buf = rem;
pc->page_offset_end += rem;
nseg--;
-
+#if (USB_DEBUG != 0)
+ if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
+ /*
+ * This check verifies that the physical address is correct:
+ */
+ DPRINTFN(0, "Page offset was not preserved!\n");
+ error = 1;
+ goto done;
+ }
+#endif
while (nseg > 0) {
nseg--;
segs++;
@@ -788,7 +800,16 @@ usb2_pc_common_mem_cb(struct usb2_page_cache *pc, bus_dma_segment_t *segs,
ext_seg = 0;
}
nseg--;
-
+#if (USB_DEBUG != 0)
+ if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
+ /*
+ * This check verifies that the physical address is correct:
+ */
+ DPRINTFN(0, "Page offset was not preserved!\n");
+ error = 1;
+ goto done;
+ }
+#endif
while (nseg > 0) {
nseg--;
segs++;
@@ -1205,15 +1226,15 @@ usb2_bdma_work_loop(struct usb2_xfer_queue *pq)
uint32_t nframes;
xfer = pq->curr;
- info = xfer->usb2_root;
+ info = xfer->xroot;
- mtx_assert(info->priv_mtx, MA_OWNED);
+ mtx_assert(info->xfer_mtx, MA_OWNED);
if (xfer->error) {
/* some error happened */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(info->bus);
usb2_transfer_done(xfer, 0);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(info->bus);
return;
}
if (!xfer->flags_int.bdma_setup) {
@@ -1285,9 +1306,9 @@ usb2_bdma_work_loop(struct usb2_xfer_queue *pq)
}
if (info->dma_error) {
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(info->bus);
usb2_transfer_done(xfer, USB_ERR_DMA_LOAD_FAILED);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(info->bus);
return;
}
if (info->dma_currframe != info->dma_nframes) {
@@ -1331,7 +1352,7 @@ usb2_bdma_done_event(struct usb2_dma_parent_tag *udpt)
info = udpt->info;
- mtx_assert(info->priv_mtx, MA_OWNED);
+ mtx_assert(info->xfer_mtx, MA_OWNED);
/* copy error */
info->dma_error = udpt->dma_error;
diff --git a/sys/dev/usb2/core/usb2_compat_linux.c b/sys/dev/usb2/core/usb2_compat_linux.c
index b094a42..4f52ea3 100644
--- a/sys/dev/usb2/core/usb2_compat_linux.c
+++ b/sys/dev/usb2/core/usb2_compat_linux.c
@@ -246,9 +246,6 @@ usb_linux_attach(device_t dev)
struct usb_device *p_dev;
const struct usb_device_id *id = NULL;
- if (sc == NULL) {
- return (ENOMEM);
- }
mtx_lock(&Giant);
LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) {
id = usb_linux_lookup_id(udrv->id_table, uaa);
@@ -393,8 +390,14 @@ usb_linux_shutdown(device_t dev)
static uint16_t
usb_max_isoc_frames(struct usb_device *dev)
{
- return ((usb2_get_speed(dev->bsd_udev) == USB_SPEED_HIGH) ?
- USB_MAX_HIGH_SPEED_ISOC_FRAMES : USB_MAX_FULL_SPEED_ISOC_FRAMES);
+ ; /* indent fix */
+ switch (usb2_get_speed(dev->bsd_udev)) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
+ return (USB_MAX_FULL_SPEED_ISOC_FRAMES);
+ default:
+ return (USB_MAX_HIGH_SPEED_ISOC_FRAMES);
+ }
}
/*------------------------------------------------------------------------*
diff --git a/sys/dev/usb2/core/usb2_core.h b/sys/dev/usb2/core/usb2_core.h
index acc30a8..156ec5d 100644
--- a/sys/dev/usb2/core/usb2_core.h
+++ b/sys/dev/usb2/core/usb2_core.h
@@ -101,8 +101,6 @@
#define USB_HOST_ALIGN 8 /* bytes, must be power of two */
-#define USB_ROOT_HUB_ADDR 1 /* value */
-
#define USB_ISOC_TIME_MAX 128 /* ms */
#define USB_FS_ISOC_UFRAME_MAX 4 /* exclusive unit */
@@ -162,9 +160,9 @@
#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx)
#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx)
#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t)
-#define USB_XFER_LOCK(_x) mtx_lock((_x)->xfer_mtx)
-#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xfer_mtx)
-#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xfer_mtx, _t)
+#define USB_XFER_LOCK(_x) mtx_lock((_x)->xroot->xfer_mtx)
+#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xroot->xfer_mtx)
+#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xroot->xfer_mtx, _t)
/* structure prototypes */
struct file;
@@ -309,10 +307,7 @@ struct usb2_xfer {
* are waiting on */
struct usb2_page *dma_page_ptr;
struct usb2_pipe *pipe; /* our USB pipe */
- struct usb2_device *udev;
- struct mtx *xfer_mtx; /* cannot be changed during operation */
- struct usb2_xfer_root *usb2_root; /* used by HC driver */
- void *usb2_sc; /* used by HC driver */
+ struct usb2_xfer_root *xroot; /* used by HC driver */
void *qh_start[2]; /* used by HC driver */
void *td_start[2]; /* used by HC driver */
void *td_transfer_first; /* used by HC driver */
@@ -440,6 +435,7 @@ uint8_t usb2_get_interface_altindex(struct usb2_interface *iface);
usb2_error_t usb2_set_alt_interface_index(struct usb2_device *udev,
uint8_t iface_index, uint8_t alt_index);
uint8_t usb2_get_speed(struct usb2_device *udev);
+uint32_t usb2_get_isoc_fps(struct usb2_device *udev);
usb2_error_t usb2_transfer_setup(struct usb2_device *udev,
const uint8_t *ifaces, struct usb2_xfer **pxfer,
const struct usb2_config *setup_start, uint16_t n_setup,
@@ -464,5 +460,6 @@ void usb2_set_iface_perm(struct usb2_device *udev, uint8_t iface_index,
uint32_t uid, uint32_t gid, uint16_t mode);
uint8_t usb2_get_bus_index(struct usb2_device *udev);
uint8_t usb2_get_device_index(struct usb2_device *udev);
+void usb2_set_power_mode(struct usb2_device *udev, uint8_t power_mode);
#endif /* _USB2_CORE_H_ */
diff --git a/sys/dev/usb2/core/usb2_debug.c b/sys/dev/usb2/core/usb2_debug.c
index dc9067d..46d27b4 100644
--- a/sys/dev/usb2/core/usb2_debug.c
+++ b/sys/dev/usb2/core/usb2_debug.c
@@ -31,6 +31,8 @@
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
#include <dev/usb2/core/usb2_device.h>
+#include <dev/usb2/core/usb2_busdma.h>
+#include <dev/usb2/core/usb2_transfer.h>
/*
* Define this unconditionally in case a kernel module is loaded that
@@ -128,6 +130,7 @@ usb2_dump_pipe(struct usb2_pipe *pipe)
void
usb2_dump_xfer(struct usb2_xfer *xfer)
{
+ struct usb2_device *udev;
printf("usb2_dump_xfer: xfer=%p\n", xfer);
if (xfer == NULL) {
return;
@@ -137,12 +140,13 @@ usb2_dump_xfer(struct usb2_xfer *xfer)
xfer);
return;
}
+ udev = xfer->xroot->udev;
printf("xfer %p: udev=%p vid=0x%04x pid=0x%04x addr=%d "
"pipe=%p ep=0x%02x attr=0x%02x\n",
- xfer, xfer->udev,
- UGETW(xfer->udev->ddesc.idVendor),
- UGETW(xfer->udev->ddesc.idProduct),
- xfer->udev->address, xfer->pipe,
+ xfer, udev,
+ UGETW(udev->ddesc.idVendor),
+ UGETW(udev->ddesc.idProduct),
+ udev->address, xfer->pipe,
xfer->pipe->edesc->bEndpointAddress,
xfer->pipe->edesc->bmAttributes);
}
diff --git a/sys/dev/usb2/core/usb2_device.c b/sys/dev/usb2/core/usb2_device.c
index 2356cc5..6f398bc 100644
--- a/sys/dev/usb2/core/usb2_device.c
+++ b/sys/dev/usb2/core/usb2_device.c
@@ -75,18 +75,6 @@ static usb2_error_t usb2_fill_iface_data(struct usb2_device *, uint8_t,
static void usb2_notify_addq(const char *type, struct usb2_device *);
static void usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t);
-/* static structures */
-
-static const uint8_t usb2_hub_speed_combs[USB_SPEED_MAX][USB_SPEED_MAX] = {
- /* HUB *//* subdevice */
- [USB_SPEED_HIGH][USB_SPEED_HIGH] = 1,
- [USB_SPEED_HIGH][USB_SPEED_FULL] = 1,
- [USB_SPEED_HIGH][USB_SPEED_LOW] = 1,
- [USB_SPEED_FULL][USB_SPEED_FULL] = 1,
- [USB_SPEED_FULL][USB_SPEED_LOW] = 1,
- [USB_SPEED_LOW][USB_SPEED_LOW] = 1,
-};
-
/* This variable is global to allow easy access to it: */
int usb2_template = 0;
@@ -1186,7 +1174,7 @@ usb2_suspend_resume_sub(struct usb2_device *udev, device_t dev, uint8_t do_suspe
}
/*------------------------------------------------------------------------*
- * usb2_suspend_resume_device
+ * usb2_suspend_resume
*
* The following function will suspend or resume the USB device.
*
@@ -1290,19 +1278,20 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
* Find an unused device index. In USB Host mode this is the
* same as the device address.
*
- * NOTE: Index 1 is reserved for the Root HUB.
+ * Device index zero is not used and device index 1 should
+ * always be the root hub.
*/
- for (device_index = USB_ROOT_HUB_ADDR; device_index !=
- USB_MAX_DEVICES; device_index++) {
- if (bus->devices[device_index] == NULL)
- break;
- }
+ for (device_index = USB_ROOT_HUB_ADDR;
+ (device_index != bus->devices_max) &&
+ (bus->devices[device_index] != NULL);
+ device_index++) /* nop */;
- if (device_index == USB_MAX_DEVICES) {
+ if (device_index == bus->devices_max) {
device_printf(bus->bdev,
"No free USB device index for new device!\n");
return (NULL);
}
+
if (depth > 0x10) {
device_printf(bus->bdev,
"Invalid device depth!\n");
@@ -1339,7 +1328,13 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
udev->bus = bus;
udev->address = USB_START_ADDR; /* default value */
udev->plugtime = (uint32_t)ticks;
+ /*
+ * We need to force the power mode to "on" because there are plenty
+ * of USB devices out there that do not work very well with
+ * automatic suspend and resume!
+ */
udev->power_mode = USB_POWER_MODE_ON;
+ udev->pwr_save.last_xfer_time = ticks;
/* we are not ready yet */
udev->refcount = 1;
@@ -1357,21 +1352,10 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
udev->speed = speed;
udev->flags.usb2_mode = usb2_mode;
- /* check speed combination */
+ /* speed combination should be checked by the parent HUB */
hub = udev->parent_hub;
- if (hub) {
- if (usb2_hub_speed_combs[hub->speed][speed] == 0) {
-#if USB_DEBUG
- printf("%s: the selected subdevice and HUB speed "
- "combination is not supported %d/%d.\n",
- __FUNCTION__, speed, hub->speed);
-#endif
- /* reject this combination */
- err = USB_ERR_INVAL;
- goto done;
- }
- }
+
/* search for our High Speed USB HUB, if any */
adev = udev;
@@ -1450,7 +1434,11 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
if (err) {
DPRINTFN(0, "getting device descriptor "
"at addr %d failed!\n", udev->address);
- goto done;
+ /* XXX try to re-enumerate the device */
+ err = usb2_req_re_enumerate(udev, &Giant);
+ if (err) {
+ goto done;
+ }
}
DPRINTF("adding unit addr=%d, rev=%02x, class=%d, "
"subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
@@ -1546,6 +1534,7 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
if (udev->flags.usb2_mode == USB_MODE_HOST) {
uint8_t config_index;
uint8_t config_quirk;
+ uint8_t set_config_failed = 0;
/*
* Most USB devices should attach to config index 0 by
@@ -1580,11 +1569,27 @@ repeat_set_config:
err = usb2_set_config_index(udev, config_index);
sx_unlock(udev->default_sx + 1);
if (err) {
- DPRINTFN(0, "Failure selecting "
- "configuration index %u: %s, port %u, addr %u\n",
- config_index, usb2_errstr(err), udev->port_no,
- udev->address);
-
+ if (udev->ddesc.bNumConfigurations != 0) {
+ if (!set_config_failed) {
+ set_config_failed = 1;
+ /* XXX try to re-enumerate the device */
+ err = usb2_req_re_enumerate(
+ udev, &Giant);
+ if (err == 0)
+ goto repeat_set_config;
+ }
+ DPRINTFN(0, "Failure selecting "
+ "configuration index %u: %s, port %u, "
+ "addr %u (ignored)\n",
+ config_index, usb2_errstr(err), udev->port_no,
+ udev->address);
+ }
+ /*
+ * Some USB devices do not have any
+ * configurations. Ignore any set config
+ * failures!
+ */
+ err = 0;
} else if (config_quirk) {
/* user quirk selects configuration index */
} else if ((config_index + 1) < udev->ddesc.bNumConfigurations) {
@@ -1608,7 +1613,7 @@ repeat_set_config:
goto repeat_set_config;
}
}
- } else if (usb2_test_huawei(udev, &uaa) == 0) {
+ } else if (usb2_test_huawei_autoinst_p(udev, &uaa) == 0) {
DPRINTFN(0, "Found Huawei auto-install disk!\n");
err = USB_ERR_STALLED; /* fake an error */
}
@@ -1670,6 +1675,11 @@ usb2_free_device(struct usb2_device *udev)
bus = udev->bus;
+ printf("ugen%u.%u: <%s> at %s (disconnected)\n",
+ device_get_unit(bus->bdev),
+ udev->device_index, udev->manufacturer,
+ device_get_nameunit(bus->bdev));
+
/*
* Destroy UGEN symlink, if any
*/
@@ -1709,8 +1719,18 @@ usb2_free_device(struct usb2_device *udev)
/* unsetup any leftover default USB transfers */
usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
+ /* template unsetup, if any */
(usb2_temp_unsetup_p) (udev);
+ /*
+ * Make sure that our clear-stall messages are not queued
+ * anywhere:
+ */
+ USB_BUS_LOCK(udev->bus);
+ usb2_proc_mwait(&udev->bus->non_giant_callback_proc,
+ &udev->cs_msg[0], &udev->cs_msg[1]);
+ USB_BUS_UNLOCK(udev->bus);
+
sx_destroy(udev->default_sx);
sx_destroy(udev->default_sx + 1);
@@ -1937,6 +1957,19 @@ usb2_get_speed(struct usb2_device *udev)
return (udev->speed);
}
+uint32_t
+usb2_get_isoc_fps(struct usb2_device *udev)
+{
+ ; /* indent fix */
+ switch (udev->speed) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
+ return (1000);
+ default:
+ return (8000);
+ }
+}
+
struct usb2_device_descriptor *
usb2_get_device_descriptor(struct usb2_device *udev)
{
@@ -2123,3 +2156,22 @@ usb2_fifo_free_wrap(struct usb2_device *udev,
usb2_fifo_free(f);
}
}
+
+/*------------------------------------------------------------------------*
+ * usb2_peer_can_wakeup
+ *
+ * Return values:
+ * 0: Peer cannot do resume signalling.
+ * Else: Peer can do resume signalling.
+ *------------------------------------------------------------------------*/
+uint8_t
+usb2_peer_can_wakeup(struct usb2_device *udev)
+{
+ const struct usb2_config_descriptor *cdp;
+
+ cdp = udev->cdesc;
+ if ((cdp != NULL) && (udev->flags.usb2_mode == USB_MODE_HOST)) {
+ return (cdp->bmAttributes & UC_REMOTE_WAKEUP);
+ }
+ return (0); /* not supported */
+}
diff --git a/sys/dev/usb2/core/usb2_device.h b/sys/dev/usb2/core/usb2_device.h
index 96dcb50..11686e2 100644
--- a/sys/dev/usb2/core/usb2_device.h
+++ b/sys/dev/usb2/core/usb2_device.h
@@ -83,6 +83,18 @@ struct usb2_device_flags {
};
/*
+ * The following structure is used for power-save purposes. The data
+ * in this structure is protected by the USB BUS lock.
+ */
+struct usb2_power_save {
+ int last_xfer_time; /* copy of "ticks" */
+ uint32_t type_refs[4]; /* transfer reference count */
+ uint32_t read_refs; /* data read references */
+ uint32_t write_refs; /* data write references */
+ uint8_t suspended; /* set if USB device is suspended */
+};
+
+/*
* The following structure defines an USB device. There exists one of
* these structures for every USB device.
*/
@@ -96,6 +108,7 @@ struct usb2_device {
struct usb2_interface ifaces[USB_IFACE_MAX];
struct usb2_pipe default_pipe; /* Control Endpoint 0 */
struct usb2_pipe pipes[USB_EP_MAX];
+ struct usb2_power_save pwr_save;/* power save data */
struct usb2_bus *bus; /* our USB BUS */
device_t parent_dev; /* parent device */
@@ -169,5 +182,6 @@ void *usb2_find_descriptor(struct usb2_device *udev, void *id,
uint8_t iface_index, uint8_t type, uint8_t type_mask,
uint8_t subtype, uint8_t subtype_mask);
void usb_linux_free_device(struct usb_device *dev);
+uint8_t usb2_peer_can_wakeup(struct usb2_device *udev);
#endif /* _USB2_DEVICE_H_ */
diff --git a/sys/dev/usb2/core/usb2_dynamic.c b/sys/dev/usb2/core/usb2_dynamic.c
index bf7ce59..3e0bdf1 100644
--- a/sys/dev/usb2/core/usb2_dynamic.c
+++ b/sys/dev/usb2/core/usb2_dynamic.c
@@ -39,6 +39,7 @@ static usb2_temp_get_desc_t usb2_temp_get_desc_w;
static usb2_temp_setup_by_index_t usb2_temp_setup_by_index_w;
static usb2_temp_unsetup_t usb2_temp_unsetup_w;
static usb2_test_quirk_t usb2_test_quirk_w;
+static usb2_test_huawei_autoinst_t usb2_test_huawei_autoinst_w;
static usb2_quirk_ioctl_t usb2_quirk_ioctl_w;
/* global variables */
@@ -46,6 +47,7 @@ usb2_temp_get_desc_t *usb2_temp_get_desc_p = &usb2_temp_get_desc_w;
usb2_temp_setup_by_index_t *usb2_temp_setup_by_index_p = &usb2_temp_setup_by_index_w;
usb2_temp_unsetup_t *usb2_temp_unsetup_p = &usb2_temp_unsetup_w;
usb2_test_quirk_t *usb2_test_quirk_p = &usb2_test_quirk_w;
+usb2_test_huawei_autoinst_t *usb2_test_huawei_autoinst_p = &usb2_test_huawei_autoinst_w;
usb2_quirk_ioctl_t *usb2_quirk_ioctl_p = &usb2_quirk_ioctl_w;
devclass_t usb2_devclass_ptr = NULL;
@@ -86,6 +88,13 @@ usb2_temp_unsetup_w(struct usb2_device *udev)
}
}
+static uint8_t
+usb2_test_huawei_autoinst_w(struct usb2_device *udev,
+ struct usb2_attach_arg *uaa)
+{
+ return (USB_ERR_INVAL);
+}
+
void
usb2_quirk_unload(void *arg)
{
@@ -130,3 +139,17 @@ usb2_bus_unload(void *arg)
pause("WAIT", hz);
}
+
+void
+usb2_test_huawei_unload(void *arg)
+{
+ /* reset function pointers */
+
+ usb2_test_huawei_autoinst_p = &usb2_test_huawei_autoinst_w;
+
+ /* wait for CPU to exit the loaded functions, if any */
+
+ /* XXX this is a tradeoff */
+
+ pause("WAIT", 16*hz);
+}
diff --git a/sys/dev/usb2/core/usb2_dynamic.h b/sys/dev/usb2/core/usb2_dynamic.h
index 7496929..2c45d09 100644
--- a/sys/dev/usb2/core/usb2_dynamic.h
+++ b/sys/dev/usb2/core/usb2_dynamic.h
@@ -37,6 +37,8 @@ struct usb2_device_request;
typedef usb2_error_t (usb2_temp_setup_by_index_t)(struct usb2_device *udev,
uint16_t index);
+typedef usb2_error_t (usb2_test_huawei_autoinst_t)(struct usb2_device *udev,
+ struct usb2_attach_arg *uaa);
typedef uint8_t (usb2_test_quirk_t)(const struct usb2_lookup_info *info,
uint16_t quirk);
typedef int (usb2_quirk_ioctl_t)(unsigned long cmd, caddr_t data,
@@ -52,11 +54,13 @@ extern usb2_temp_get_desc_t *usb2_temp_get_desc_p;
extern usb2_temp_setup_by_index_t *usb2_temp_setup_by_index_p;
extern usb2_temp_unsetup_t *usb2_temp_unsetup_p;
extern usb2_test_quirk_t *usb2_test_quirk_p;
+extern usb2_test_huawei_autoinst_t *usb2_test_huawei_autoinst_p;
extern usb2_quirk_ioctl_t *usb2_quirk_ioctl_p;
extern devclass_t usb2_devclass_ptr;
/* function prototypes */
+void usb2_test_huawei_unload(void *);
void usb2_temp_unload(void *);
void usb2_quirk_unload(void *);
void usb2_bus_unload(void *);
diff --git a/sys/dev/usb2/core/usb2_error.c b/sys/dev/usb2/core/usb2_error.c
index 417f111..8ee57b4 100644
--- a/sys/dev/usb2/core/usb2_error.c
+++ b/sys/dev/usb2/core/usb2_error.c
@@ -29,7 +29,37 @@
#include <dev/usb2/core/usb2_core.h>
-USB_MAKE_DEBUG_TABLE(USB_ERR);
+static const char* usb_errstr_table[USB_ERR_MAX] = {
+ [USB_ERR_NORMAL_COMPLETION] = "USB_ERR_NORMAL_COMPLETION",
+ [USB_ERR_PENDING_REQUESTS] = "USB_ERR_PENDING_REQUESTS",
+ [USB_ERR_NOT_STARTED] = "USB_ERR_NOT_STARTED",
+ [USB_ERR_INVAL] = "USB_ERR_INVAL",
+ [USB_ERR_NOMEM] = "USB_ERR_NOMEM",
+ [USB_ERR_CANCELLED] = "USB_ERR_CANCELLED",
+ [USB_ERR_BAD_ADDRESS] = "USB_ERR_BAD_ADDRESS",
+ [USB_ERR_BAD_BUFSIZE] = "USB_ERR_BAD_BUFSIZE",
+ [USB_ERR_BAD_FLAG] = "USB_ERR_BAD_FLAG",
+ [USB_ERR_NO_CALLBACK] = "USB_ERR_NO_CALLBACK",
+ [USB_ERR_IN_USE] = "USB_ERR_IN_USE",
+ [USB_ERR_NO_ADDR] = "USB_ERR_NO_ADDR",
+ [USB_ERR_NO_PIPE] = "USB_ERR_NO_PIPE",
+ [USB_ERR_ZERO_NFRAMES] = "USB_ERR_ZERO_NFRAMES",
+ [USB_ERR_ZERO_MAXP] = "USB_ERR_ZERO_MAXP",
+ [USB_ERR_SET_ADDR_FAILED] = "USB_ERR_SET_ADDR_FAILED",
+ [USB_ERR_NO_POWER] = "USB_ERR_NO_POWER",
+ [USB_ERR_TOO_DEEP] = "USB_ERR_TOO_DEEP",
+ [USB_ERR_IOERROR] = "USB_ERR_IOERROR",
+ [USB_ERR_NOT_CONFIGURED] = "USB_ERR_NOT_CONFIGURED",
+ [USB_ERR_TIMEOUT] = "USB_ERR_TIMEOUT",
+ [USB_ERR_SHORT_XFER] = "USB_ERR_SHORT_XFER",
+ [USB_ERR_STALLED] = "USB_ERR_STALLED",
+ [USB_ERR_INTERRUPTED] = "USB_ERR_INTERRUPTED",
+ [USB_ERR_DMA_LOAD_FAILED] = "USB_ERR_DMA_LOAD_FAILED",
+ [USB_ERR_BAD_CONTEXT] = "USB_ERR_BAD_CONTEXT",
+ [USB_ERR_NO_ROOT_HUB] = "USB_ERR_NO_ROOT_HUB",
+ [USB_ERR_NO_INTR_THREAD] = "USB_ERR_NO_INTR_THREAD",
+ [USB_ERR_NOT_LOCKED] = "USB_ERR_NOT_LOCKED",
+};
/*------------------------------------------------------------------------*
* usb2_errstr
@@ -39,5 +69,5 @@ USB_MAKE_DEBUG_TABLE(USB_ERR);
const char *
usb2_errstr(usb2_error_t err)
{
- return ((err < USB_ERR_MAX) ? USB_ERR[err] : "USB_ERR_UNKNOWN");
+ return (err < USB_ERR_MAX ? usb_errstr_table[err] : "USB_ERR_UNKNOWN");
}
diff --git a/sys/dev/usb2/core/usb2_generic.c b/sys/dev/usb2/core/usb2_generic.c
index fa09eef..79bfc2f 100644
--- a/sys/dev/usb2/core/usb2_generic.c
+++ b/sys/dev/usb2/core/usb2_generic.c
@@ -157,12 +157,16 @@ ugen_open(struct usb2_fifo *f, int fflags, struct thread *td)
DPRINTFN(6, "flag=0x%x\n", fflags);
mtx_lock(f->priv_mtx);
- if (usb2_get_speed(f->udev) == USB_SPEED_HIGH) {
- f->nframes = UGEN_HW_FRAMES * 8;
- f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
- } else {
+ switch (usb2_get_speed(f->udev)) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
f->nframes = UGEN_HW_FRAMES;
f->bufsize = UGEN_BULK_FS_BUFFER_SIZE;
+ break;
+ default:
+ f->nframes = UGEN_HW_FRAMES * 8;
+ f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
+ break;
}
type = ed->bmAttributes & UE_XFERTYPE;
@@ -1688,22 +1692,31 @@ ugen_set_power_mode(struct usb2_fifo *f, int mode)
{
struct usb2_device *udev = f->udev;
int err;
+ uint8_t old_mode;
if ((udev == NULL) ||
(udev->parent_hub == NULL)) {
return (EINVAL);
}
err = priv_check(curthread, PRIV_ROOT);
- if (err) {
+ if (err)
return (err);
- }
+
+ /* get old power mode */
+ old_mode = udev->power_mode;
+
+ /* if no change, then just return */
+ if (old_mode == mode)
+ return (0);
+
switch (mode) {
case USB_POWER_MODE_OFF:
- /* clear suspend */
- err = usb2_req_clear_port_feature(udev->parent_hub,
- NULL, udev->port_no, UHF_PORT_SUSPEND);
- if (err)
- break;
+ /* get the device unconfigured */
+ err = ugen_set_config(f, USB_UNCONFIG_INDEX);
+ if (err) {
+ DPRINTFN(0, "Could not unconfigure "
+ "device (ignored)\n");
+ }
/* clear port enable */
err = usb2_req_clear_port_feature(udev->parent_hub,
@@ -1711,24 +1724,21 @@ ugen_set_power_mode(struct usb2_fifo *f, int mode)
break;
case USB_POWER_MODE_ON:
- /* enable port */
- err = usb2_req_set_port_feature(udev->parent_hub,
- NULL, udev->port_no, UHF_PORT_ENABLE);
-
- /* FALLTHROUGH */
-
case USB_POWER_MODE_SAVE:
+ break;
+
case USB_POWER_MODE_RESUME:
- /* TODO: implement USB power save */
err = usb2_req_clear_port_feature(udev->parent_hub,
NULL, udev->port_no, UHF_PORT_SUSPEND);
+ mode = USB_POWER_MODE_SAVE;
break;
case USB_POWER_MODE_SUSPEND:
- /* TODO: implement USB power save */
err = usb2_req_set_port_feature(udev->parent_hub,
NULL, udev->port_no, UHF_PORT_SUSPEND);
+ mode = USB_POWER_MODE_SAVE;
break;
+
default:
return (EINVAL);
}
@@ -1736,7 +1746,15 @@ ugen_set_power_mode(struct usb2_fifo *f, int mode)
if (err)
return (ENXIO); /* I/O failure */
- udev->power_mode = mode; /* update copy of power mode */
+ /* if we are powered off we need to re-enumerate first */
+ if (old_mode == USB_POWER_MODE_OFF) {
+ err = ugen_re_enumerate(f);
+ if (err)
+ return (err);
+ }
+
+ /* set new power mode */
+ usb2_set_power_mode(udev, mode);
return (0); /* success */
}
diff --git a/sys/dev/usb2/core/usb2_handle_request.c b/sys/dev/usb2/core/usb2_handle_request.c
index d5714b4..65f0f01 100644
--- a/sys/dev/usb2/core/usb2_handle_request.c
+++ b/sys/dev/usb2/core/usb2_handle_request.c
@@ -86,7 +86,7 @@ usb2_handle_request_callback(struct usb2_xfer *xfer)
if (err == USB_ERR_BAD_CONTEXT) {
/* we need to re-setup the control transfer */
- usb2_needs_explore(xfer->udev->bus, 0);
+ usb2_needs_explore(xfer->xroot->bus, 0);
break;
}
/*
@@ -126,6 +126,7 @@ tr_restart:
static usb2_error_t
usb2_handle_set_config(struct usb2_xfer *xfer, uint8_t conf_no)
{
+ struct usb2_device *udev = xfer->xroot->udev;
usb2_error_t err = 0;
/*
@@ -134,7 +135,7 @@ usb2_handle_set_config(struct usb2_xfer *xfer, uint8_t conf_no)
*/
USB_XFER_UNLOCK(xfer);
mtx_lock(&Giant); /* XXX */
- sx_xlock(xfer->udev->default_sx + 1);
+ sx_xlock(udev->default_sx + 1);
if (conf_no == USB_UNCONFIG_NO) {
conf_no = USB_UNCONFIG_INDEX;
@@ -146,19 +147,19 @@ usb2_handle_set_config(struct usb2_xfer *xfer, uint8_t conf_no)
conf_no--;
}
- if (usb2_set_config_index(xfer->udev, conf_no)) {
+ if (usb2_set_config_index(udev, conf_no)) {
DPRINTF("set config %d failed\n", conf_no);
err = USB_ERR_STALLED;
goto done;
}
- if (usb2_probe_and_attach(xfer->udev, USB_IFACE_INDEX_ANY)) {
+ if (usb2_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
DPRINTF("probe and attach failed\n");
err = USB_ERR_STALLED;
goto done;
}
done:
mtx_unlock(&Giant); /* XXX */
- sx_unlock(xfer->udev->default_sx + 1);
+ sx_unlock(udev->default_sx + 1);
USB_XFER_LOCK(xfer);
return (err);
}
@@ -177,7 +178,7 @@ usb2_handle_iface_request(struct usb2_xfer *xfer,
{
struct usb2_interface *iface;
struct usb2_interface *iface_parent; /* parent interface */
- struct usb2_device *udev = xfer->udev;
+ struct usb2_device *udev = xfer->xroot->udev;
int error;
uint8_t iface_index;
@@ -332,11 +333,12 @@ tr_stalled:
static usb2_error_t
usb2_handle_set_stall(struct usb2_xfer *xfer, uint8_t ep, uint8_t do_stall)
{
+ struct usb2_device *udev = xfer->xroot->udev;
usb2_error_t err;
USB_XFER_UNLOCK(xfer);
- err = usb2_set_endpoint_stall(xfer->udev,
- usb2_get_pipe_by_addr(xfer->udev, ep), do_stall);
+ err = usb2_set_endpoint_stall(udev,
+ usb2_get_pipe_by_addr(udev, ep), do_stall);
USB_XFER_LOCK(xfer);
return (err);
}
@@ -379,7 +381,7 @@ usb2_handle_remote_wakeup(struct usb2_xfer *xfer, uint8_t is_on)
struct usb2_device *udev;
struct usb2_bus *bus;
- udev = xfer->udev;
+ udev = xfer->xroot->udev;
bus = udev->bus;
USB_BUS_LOCK(bus);
@@ -390,10 +392,12 @@ usb2_handle_remote_wakeup(struct usb2_xfer *xfer, uint8_t is_on)
udev->flags.remote_wakeup = 0;
}
- (bus->methods->rem_wakeup_set) (xfer->udev, is_on);
-
USB_BUS_UNLOCK(bus);
+ /* In case we are out of sync, update the power state. */
+
+ usb2_bus_power_update(udev->bus);
+
return (0); /* success */
}
@@ -477,7 +481,7 @@ usb2_handle_request(struct usb2_xfer *xfer)
max_len = 0;
src_zcopy = NULL;
src_mcopy = NULL;
- udev = xfer->udev;
+ udev = xfer->xroot->udev;
/* get some request fields decoded */
diff --git a/sys/dev/usb2/core/usb2_hub.c b/sys/dev/usb2/core/usb2_hub.c
index 34b275a..47db119 100644
--- a/sys/dev/usb2/core/usb2_hub.c
+++ b/sys/dev/usb2/core/usb2_hub.c
@@ -34,6 +34,7 @@
#include <dev/usb2/include/usb2_mfunc.h>
#include <dev/usb2/include/usb2_error.h>
#include <dev/usb2/include/usb2_standard.h>
+#include <dev/usb2/include/usb2_ioctl.h>
#define USB_DEBUG_VAR uhub_debug
@@ -52,6 +53,7 @@
#include <dev/usb2/controller/usb2_bus.h>
#define UHUB_INTR_INTERVAL 250 /* ms */
+#define UHUB_N_TRANSFER 1
#if USB_DEBUG
static int uhub_debug = 0;
@@ -61,6 +63,11 @@ SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0,
"Debug level");
#endif
+static int usb2_power_timeout = 30; /* seconds */
+
+SYSCTL_INT(_hw_usb2, OID_AUTO, power_timeout, CTLFLAG_RW,
+ &usb2_power_timeout, 0, "USB power timeout");
+
struct uhub_current_state {
uint16_t port_change;
uint16_t port_status;
@@ -70,10 +77,9 @@ struct uhub_softc {
struct uhub_current_state sc_st;/* current state */
device_t sc_dev; /* base device */
struct usb2_device *sc_udev; /* USB device */
- struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */
+ struct usb2_xfer *sc_xfer[UHUB_N_TRANSFER]; /* interrupt xfer */
uint8_t sc_flags;
#define UHUB_FLAG_DID_EXPLORE 0x01
-#define UHUB_FLAG_INTR_STALL 0x02
char sc_name[32];
};
@@ -86,15 +92,19 @@ struct uhub_softc {
static device_probe_t uhub_probe;
static device_attach_t uhub_attach;
static device_detach_t uhub_detach;
+static device_suspend_t uhub_suspend;
+static device_resume_t uhub_resume;
static bus_driver_added_t uhub_driver_added;
static bus_child_location_str_t uhub_child_location_string;
static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
static usb2_callback_t uhub_intr_callback;
-static usb2_callback_t uhub_intr_clear_stall_callback;
-static const struct usb2_config uhub_config[2] = {
+static void usb2_dev_resume_peer(struct usb2_device *udev);
+static void usb2_dev_suspend_peer(struct usb2_device *udev);
+
+static const struct usb2_config uhub_config[UHUB_N_TRANSFER] = {
[0] = {
.type = UE_INTERRUPT,
@@ -106,17 +116,6 @@ static const struct usb2_config uhub_config[2] = {
.mh.callback = &uhub_intr_callback,
.mh.interval = UHUB_INTR_INTERVAL,
},
-
- [1] = {
- .type = UE_CONTROL,
- .endpoint = 0,
- .direction = UE_DIR_ANY,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- .mh.flags = {},
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &uhub_intr_clear_stall_callback,
- },
};
/*
@@ -133,8 +132,8 @@ static driver_t uhub_driver =
DEVMETHOD(device_attach, uhub_attach),
DEVMETHOD(device_detach, uhub_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_suspend, uhub_suspend),
+ DEVMETHOD(device_resume, uhub_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(bus_child_location_str, uhub_child_location_string),
@@ -149,19 +148,6 @@ DRIVER_MODULE(ushub, usbus, uhub_driver, uhub_devclass, 0, 0);
DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0);
static void
-uhub_intr_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct uhub_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
uhub_intr_callback(struct usb2_xfer *xfer)
{
struct uhub_softc *sc = xfer->priv_sc;
@@ -178,21 +164,22 @@ uhub_intr_callback(struct usb2_xfer *xfer)
usb2_needs_explore(sc->sc_udev->bus, 0);
case USB_ST_SETUP:
- if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[1]);
- } else {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- return;
+ xfer->frlengths[0] = xfer->max_data_length;
+ usb2_start_hardware(xfer);
+ break;
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
- /* start clear stall */
- sc->sc_flags |= UHUB_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[1]);
+ /*
+ * Do a clear-stall. The "stall_pipe" flag
+ * will get cleared before next callback by
+ * the USB stack.
+ */
+ xfer->flags.stall_pipe = 1;
+ xfer->frlengths[0] = xfer->max_data_length;
+ usb2_start_hardware(xfer);
}
- return;
+ break;
}
}
@@ -302,8 +289,8 @@ repeat:
/* first clear the port connection change bit */
- err = usb2_req_clear_port_feature
- (udev, &Giant, portno, UHF_C_PORT_CONNECTION);
+ err = usb2_req_clear_port_feature(udev, &Giant,
+ portno, UHF_C_PORT_CONNECTION);
if (err) {
goto error;
@@ -338,6 +325,12 @@ repeat:
DPRINTF("Port %d is in Host Mode\n", portno);
+ if (sc->sc_st.port_status & UPS_SUSPEND) {
+ DPRINTF("Port %d was still "
+ "suspended, clearing.\n", portno);
+ err = usb2_req_clear_port_feature(sc->sc_udev,
+ &Giant, portno, UHF_PORT_SUSPEND);
+ }
/* USB Host Mode */
/* wait for maximum device power up time */
@@ -346,8 +339,7 @@ repeat:
/* reset port, which implies enabling it */
- err = usb2_req_reset_port
- (udev, &Giant, portno);
+ err = usb2_req_reset_port(udev, &Giant, portno);
if (err) {
DPRINTFN(0, "port %d reset "
@@ -380,18 +372,38 @@ repeat:
/*
* Figure out the device speed
*/
- speed =
- (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
- (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
-
+ switch (udev->speed) {
+ case USB_SPEED_HIGH:
+ if (sc->sc_st.port_status & UPS_HIGH_SPEED)
+ speed = USB_SPEED_HIGH;
+ else if (sc->sc_st.port_status & UPS_LOW_SPEED)
+ speed = USB_SPEED_LOW;
+ else
+ speed = USB_SPEED_FULL;
+ break;
+ case USB_SPEED_FULL:
+ if (sc->sc_st.port_status & UPS_LOW_SPEED)
+ speed = USB_SPEED_LOW;
+ else
+ speed = USB_SPEED_FULL;
+ break;
+ case USB_SPEED_LOW:
+ speed = USB_SPEED_LOW;
+ break;
+ default:
+ /* same speed like parent */
+ speed = udev->speed;
+ break;
+ }
/*
* Figure out the device mode
*
* NOTE: This part is currently FreeBSD specific.
*/
- usb2_mode =
- (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
- USB_MODE_DEVICE : USB_MODE_HOST;
+ if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
+ usb2_mode = USB_MODE_DEVICE;
+ else
+ usb2_mode = USB_MODE_HOST;
/* need to create a new child */
@@ -411,8 +423,8 @@ error:
}
if (err == 0) {
if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
- err = usb2_req_clear_port_feature
- (sc->sc_udev, &Giant,
+ err = usb2_req_clear_port_feature(
+ sc->sc_udev, &Giant,
portno, UHF_PORT_ENABLE);
}
}
@@ -446,16 +458,17 @@ uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
/* first clear the port suspend change bit */
- err = usb2_req_clear_port_feature
- (udev, &Giant, portno, UHF_C_PORT_SUSPEND);
-
+ err = usb2_req_clear_port_feature(udev, &Giant,
+ portno, UHF_C_PORT_SUSPEND);
if (err) {
+ DPRINTF("clearing suspend failed.\n");
goto done;
}
/* get fresh status */
err = uhub_read_port_status(sc, portno);
if (err) {
+ DPRINTF("reading port status failed.\n");
goto done;
}
/* get current state */
@@ -465,12 +478,21 @@ uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
} else {
is_suspend = 0;
}
+
+ DPRINTF("suspended=%u\n", is_suspend);
+
/* do the suspend or resume */
if (child) {
- sx_xlock(child->default_sx + 1);
- err = usb2_suspend_resume(child, is_suspend);
- sx_unlock(child->default_sx + 1);
+ /*
+ * This code handle two cases: 1) Host Mode - we can only
+ * receive resume here 2) Device Mode - we can receive
+ * suspend and resume here
+ */
+ if (is_suspend == 0)
+ usb2_dev_resume_peer(child);
+ else if (child->flags.usb2_mode == USB_MODE_DEVICE)
+ usb2_dev_suspend_peer(child);
}
done:
return (err);
@@ -502,6 +524,11 @@ uhub_explore(struct usb2_device *udev)
if (udev->depth > USB_HUB_MAX_DEPTH) {
return (USB_ERR_TOO_DEEP);
}
+ if (udev->pwr_save.suspended) {
+ /* need to wait until the child signals resume */
+ DPRINTF("Device is suspended!\n");
+ return (0);
+ }
for (x = 0; x != hub->nports; x++) {
up = hub->ports + x;
portno = x + 1;
@@ -511,6 +538,15 @@ uhub_explore(struct usb2_device *udev)
/* most likely the HUB is gone */
break;
}
+ if (sc->sc_st.port_change & UPS_C_OVERCURRENT_INDICATOR) {
+ DPRINTF("Overcurrent on port %u.\n", portno);
+ err = usb2_req_clear_port_feature(
+ udev, &Giant, portno, UHF_C_PORT_OVER_CURRENT);
+ if (err) {
+ /* most likely the HUB is gone */
+ break;
+ }
+ }
if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) {
/*
* Fake a connect status change so that the
@@ -613,9 +649,6 @@ uhub_attach(device_t dev)
uint8_t iface_index;
usb2_error_t err;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = udev;
sc->sc_dev = dev;
@@ -696,7 +729,7 @@ uhub_attach(device_t dev)
/* set up interrupt pipe */
iface_index = 0;
err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer,
- uhub_config, 2, sc, &Giant);
+ uhub_config, UHUB_N_TRANSFER, sc, &Giant);
if (err) {
DPRINTFN(0, "cannot setup interrupt transfer, "
"errstr=%s!\n", usb2_errstr(err));
@@ -750,8 +783,8 @@ uhub_attach(device_t dev)
}
if (!err) {
/* turn the power on */
- err = usb2_req_set_port_feature
- (udev, &Giant, portno, UHF_PORT_POWER);
+ err = usb2_req_set_port_feature(udev, &Giant,
+ portno, UHF_PORT_POWER);
}
if (err) {
DPRINTFN(0, "port %d power on failed, %s\n",
@@ -774,10 +807,14 @@ uhub_attach(device_t dev)
usb2_transfer_start(sc->sc_xfer[0]);
USB_XFER_UNLOCK(sc->sc_xfer[0]);
+ /* Enable automatic power save on all USB HUBs */
+
+ usb2_set_power_mode(udev, USB_POWER_MODE_SAVE);
+
return (0);
error:
- usb2_transfer_unsetup(sc->sc_xfer, 2);
+ usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
if (udev->hub) {
free(udev->hub, M_USBDEV);
@@ -820,13 +857,29 @@ uhub_detach(device_t dev)
child = NULL;
}
- usb2_transfer_unsetup(sc->sc_xfer, 2);
+ usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
free(hub, M_USBDEV);
sc->sc_udev->hub = NULL;
return (0);
}
+static int
+uhub_suspend(device_t dev)
+{
+ DPRINTF("\n");
+ /* Sub-devices are not suspended here! */
+ return (0);
+}
+
+static int
+uhub_resume(device_t dev)
+{
+ DPRINTF("\n");
+ /* Sub-devices are not resumed here! */
+ return (0);
+}
+
static void
uhub_driver_added(device_t dev, driver_t *driver)
{
@@ -1013,17 +1066,16 @@ usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
{
struct usb2_bus *bus = udev->bus;
struct usb2_hub *hub;
+ uint8_t speed;
USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
- if (usb2_get_speed(udev) == USB_SPEED_HIGH) {
- if (slot >= USB_HS_MICRO_FRAMES_MAX) {
- slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
- USB_HS_MICRO_FRAMES_MAX);
- }
- bus->uframe_usage[slot] += len;
- } else {
- if (usb2_get_speed(udev) == USB_SPEED_LOW) {
+ speed = usb2_get_speed(udev);
+
+ switch (speed) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
+ if (speed == USB_SPEED_LOW) {
len *= 8;
}
/*
@@ -1040,6 +1092,14 @@ usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
}
hub->uframe_usage[slot] += len;
bus->uframe_usage[slot] += len;
+ break;
+ default:
+ if (slot >= USB_HS_MICRO_FRAMES_MAX) {
+ slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
+ USB_HS_MICRO_FRAMES_MAX);
+ }
+ bus->uframe_usage[slot] += len;
+ break;
}
return (slot);
}
@@ -1334,3 +1394,448 @@ usb2_needs_explore_all(void)
max--;
}
}
+
+/*------------------------------------------------------------------------*
+ * usb2_bus_power_update
+ *
+ * This function will ensure that all USB devices on the given bus are
+ * properly suspended or resumed according to the device transfer
+ * state.
+ *------------------------------------------------------------------------*/
+void
+usb2_bus_power_update(struct usb2_bus *bus)
+{
+ usb2_needs_explore(bus, 0 /* no probe */ );
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_transfer_power_ref
+ *
+ * This function will modify the power save reference counts and
+ * wakeup the USB device associated with the given USB transfer, if
+ * needed.
+ *------------------------------------------------------------------------*/
+void
+usb2_transfer_power_ref(struct usb2_xfer *xfer, int val)
+{
+ static const uint32_t power_mask[4] = {
+ [UE_CONTROL] = USB_HW_POWER_CONTROL,
+ [UE_BULK] = USB_HW_POWER_BULK,
+ [UE_INTERRUPT] = USB_HW_POWER_INTERRUPT,
+ [UE_ISOCHRONOUS] = USB_HW_POWER_ISOC,
+ };
+ struct usb2_device *udev;
+ uint8_t needs_explore;
+ uint8_t needs_hw_power;
+ uint8_t xfer_type;
+
+ udev = xfer->xroot->udev;
+
+ if (udev->device_index == USB_ROOT_HUB_ADDR) {
+ /* no power save for root HUB */
+ return;
+ }
+ USB_BUS_LOCK(udev->bus);
+
+ xfer_type = xfer->pipe->edesc->bmAttributes & UE_XFERTYPE;
+
+ udev->pwr_save.last_xfer_time = ticks;
+ udev->pwr_save.type_refs[xfer_type] += val;
+
+ if (xfer->flags_int.control_xfr) {
+ udev->pwr_save.read_refs += val;
+ if (xfer->flags_int.usb2_mode == USB_MODE_HOST) {
+ /*
+ * it is not allowed to suspend during a control
+ * transfer
+ */
+ udev->pwr_save.write_refs += val;
+ }
+ } else if (USB_GET_DATA_ISREAD(xfer)) {
+ udev->pwr_save.read_refs += val;
+ } else {
+ udev->pwr_save.write_refs += val;
+ }
+
+ if (udev->pwr_save.suspended)
+ needs_explore =
+ (udev->pwr_save.write_refs != 0) ||
+ ((udev->pwr_save.read_refs != 0) &&
+ (usb2_peer_can_wakeup(udev) == 0));
+ else
+ needs_explore = 0;
+
+ if (!(udev->bus->hw_power_state & power_mask[xfer_type])) {
+ DPRINTF("Adding type %u to power state\n", xfer_type);
+ udev->bus->hw_power_state |= power_mask[xfer_type];
+ needs_hw_power = 1;
+ } else {
+ needs_hw_power = 0;
+ }
+
+ USB_BUS_UNLOCK(udev->bus);
+
+ if (needs_explore) {
+ DPRINTF("update\n");
+ usb2_bus_power_update(udev->bus);
+ } else if (needs_hw_power) {
+ DPRINTF("needs power\n");
+ if (udev->bus->methods->set_hw_power != NULL) {
+ (udev->bus->methods->set_hw_power) (udev->bus);
+ }
+ }
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_bus_powerd
+ *
+ * This function implements the USB power daemon and is called
+ * regularly from the USB explore thread.
+ *------------------------------------------------------------------------*/
+void
+usb2_bus_powerd(struct usb2_bus *bus)
+{
+ struct usb2_device *udev;
+ unsigned int temp;
+ unsigned int limit;
+ unsigned int mintime;
+ uint32_t type_refs[5];
+ uint8_t x;
+ uint8_t rem_wakeup;
+
+ limit = usb2_power_timeout;
+ if (limit == 0)
+ limit = hz;
+ else if (limit > 255)
+ limit = 255 * hz;
+ else
+ limit = limit * hz;
+
+ DPRINTF("bus=%p\n", bus);
+
+ USB_BUS_LOCK(bus);
+
+ /*
+ * The root HUB device is never suspended
+ * and we simply skip it.
+ */
+ for (x = USB_ROOT_HUB_ADDR + 1;
+ x != bus->devices_max; x++) {
+
+ udev = bus->devices[x];
+ if (udev == NULL)
+ continue;
+
+ rem_wakeup = usb2_peer_can_wakeup(udev);
+
+ temp = ticks - udev->pwr_save.last_xfer_time;
+
+ if ((udev->power_mode == USB_POWER_MODE_ON) ||
+ (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) ||
+ (udev->pwr_save.write_refs != 0) ||
+ ((udev->pwr_save.read_refs != 0) &&
+ (rem_wakeup == 0))) {
+
+ /* check if we are suspended */
+ if (udev->pwr_save.suspended != 0) {
+ USB_BUS_UNLOCK(bus);
+ usb2_dev_resume_peer(udev);
+ USB_BUS_LOCK(bus);
+ }
+ } else if (temp >= limit) {
+
+ /* check if we are not suspended */
+ if (udev->pwr_save.suspended == 0) {
+ USB_BUS_UNLOCK(bus);
+ usb2_dev_suspend_peer(udev);
+ USB_BUS_LOCK(bus);
+ }
+ }
+ }
+
+ /* reset counters */
+
+ mintime = 0 - 1;
+ type_refs[0] = 0;
+ type_refs[1] = 0;
+ type_refs[2] = 0;
+ type_refs[3] = 0;
+ type_refs[4] = 0;
+
+ /* Re-loop all the devices to get the actual state */
+
+ for (x = USB_ROOT_HUB_ADDR + 1;
+ x != bus->devices_max; x++) {
+
+ udev = bus->devices[x];
+ if (udev == NULL)
+ continue;
+
+ /* we found a non-Root-Hub USB device */
+ type_refs[4] += 1;
+
+ /* "last_xfer_time" can be updated by a resume */
+ temp = ticks - udev->pwr_save.last_xfer_time;
+
+ /*
+ * Compute minimum time since last transfer for the complete
+ * bus:
+ */
+ if (temp < mintime)
+ mintime = temp;
+
+ if (udev->pwr_save.suspended == 0) {
+ type_refs[0] += udev->pwr_save.type_refs[0];
+ type_refs[1] += udev->pwr_save.type_refs[1];
+ type_refs[2] += udev->pwr_save.type_refs[2];
+ type_refs[3] += udev->pwr_save.type_refs[3];
+ }
+ }
+
+ if (mintime >= (1 * hz)) {
+ /* recompute power masks */
+ DPRINTF("Recomputing power masks\n");
+ bus->hw_power_state = 0;
+ if (type_refs[UE_CONTROL] != 0)
+ bus->hw_power_state |= USB_HW_POWER_CONTROL;
+ if (type_refs[UE_BULK] != 0)
+ bus->hw_power_state |= USB_HW_POWER_BULK;
+ if (type_refs[UE_INTERRUPT] != 0)
+ bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
+ if (type_refs[UE_ISOCHRONOUS] != 0)
+ bus->hw_power_state |= USB_HW_POWER_ISOC;
+ if (type_refs[4] != 0)
+ bus->hw_power_state |= USB_HW_POWER_NON_ROOT_HUB;
+ }
+ USB_BUS_UNLOCK(bus);
+
+ if (bus->methods->set_hw_power != NULL) {
+ /* always update hardware power! */
+ (bus->methods->set_hw_power) (bus);
+ }
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_dev_resume_peer
+ *
+ * This function will resume an USB peer and do the required USB
+ * signalling to get an USB device out of the suspended state.
+ *------------------------------------------------------------------------*/
+static void
+usb2_dev_resume_peer(struct usb2_device *udev)
+{
+ struct usb2_bus *bus;
+ int err;
+
+ /* be NULL safe */
+ if (udev == NULL)
+ return;
+
+ /* check if already resumed */
+ if (udev->pwr_save.suspended == 0)
+ return;
+
+ /* we need a parent HUB to do resume */
+ if (udev->parent_hub == NULL)
+ return;
+
+ DPRINTF("udev=%p\n", udev);
+
+ if ((udev->flags.usb2_mode == USB_MODE_DEVICE) &&
+ (udev->flags.remote_wakeup == 0)) {
+ /*
+ * If the host did not set the remote wakeup feature, we can
+ * not wake it up either!
+ */
+ DPRINTF("remote wakeup is not set!\n");
+ return;
+ }
+ /* get bus pointer */
+ bus = udev->bus;
+
+ /* resume parent hub first */
+ usb2_dev_resume_peer(udev->parent_hub);
+
+ /* resume current port (Valid in Host and Device Mode) */
+ err = usb2_req_clear_port_feature(udev->parent_hub,
+ &Giant, udev->port_no, UHF_PORT_SUSPEND);
+ if (err) {
+ DPRINTFN(0, "Resuming port failed!\n");
+ return;
+ }
+ /* resume settle time */
+ usb2_pause_mtx(&Giant, USB_PORT_RESUME_DELAY);
+
+ if (bus->methods->device_resume != NULL) {
+ /* resume USB device on the USB controller */
+ (bus->methods->device_resume) (udev);
+ }
+ USB_BUS_LOCK(bus);
+ /* set that this device is now resumed */
+ udev->pwr_save.suspended = 0;
+ /* make sure that we don't go into suspend right away */
+ udev->pwr_save.last_xfer_time = ticks;
+
+ /* make sure the needed power masks are on */
+ if (udev->pwr_save.type_refs[UE_CONTROL] != 0)
+ bus->hw_power_state |= USB_HW_POWER_CONTROL;
+ if (udev->pwr_save.type_refs[UE_BULK] != 0)
+ bus->hw_power_state |= USB_HW_POWER_BULK;
+ if (udev->pwr_save.type_refs[UE_INTERRUPT] != 0)
+ bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
+ if (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0)
+ bus->hw_power_state |= USB_HW_POWER_ISOC;
+ USB_BUS_UNLOCK(bus);
+
+ if (bus->methods->set_hw_power != NULL) {
+ /* always update hardware power! */
+ (bus->methods->set_hw_power) (bus);
+ }
+ sx_xlock(udev->default_sx + 1);
+ /* notify all sub-devices about resume */
+ err = usb2_suspend_resume(udev, 0);
+ sx_unlock(udev->default_sx + 1);
+
+ /* check if peer has wakeup capability */
+ if (usb2_peer_can_wakeup(udev)) {
+ /* clear remote wakeup */
+ err = usb2_req_clear_device_feature(udev,
+ &Giant, UF_DEVICE_REMOTE_WAKEUP);
+ if (err) {
+ DPRINTFN(0, "Clearing device "
+ "remote wakeup failed: %s!\n",
+ usb2_errstr(err));
+ }
+ }
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_dev_suspend_peer
+ *
+ * This function will suspend an USB peer and do the required USB
+ * signalling to get an USB device into the suspended state.
+ *------------------------------------------------------------------------*/
+static void
+usb2_dev_suspend_peer(struct usb2_device *udev)
+{
+ struct usb2_device *hub;
+ struct usb2_device *child;
+ uint32_t temp;
+ int err;
+ uint8_t x;
+ uint8_t nports;
+ uint8_t suspend_parent;
+
+repeat:
+ /* be NULL safe */
+ if (udev == NULL)
+ return;
+
+ /* check if already suspended */
+ if (udev->pwr_save.suspended)
+ return;
+
+ /* we need a parent HUB to do suspend */
+ if (udev->parent_hub == NULL)
+ return;
+
+ DPRINTF("udev=%p\n", udev);
+
+ /* check if all devices on the parent hub are suspended */
+ hub = udev->parent_hub;
+ if (hub != NULL) {
+ nports = hub->hub->nports;
+ suspend_parent = 1;
+
+ for (x = 0; x != nports; x++) {
+
+ child = usb2_bus_port_get_device(hub->bus,
+ hub->hub->ports + x);
+
+ if (child == NULL)
+ continue;
+
+ if (child->pwr_save.suspended)
+ continue;
+
+ if (child == udev)
+ continue;
+
+ /* another device on the HUB is not suspended */
+ suspend_parent = 0;
+
+ break;
+ }
+ } else {
+ suspend_parent = 0;
+ }
+
+ sx_xlock(udev->default_sx + 1);
+ /* notify all sub-devices about suspend */
+ err = usb2_suspend_resume(udev, 1);
+ sx_unlock(udev->default_sx + 1);
+
+ if (usb2_peer_can_wakeup(udev)) {
+ /* allow device to do remote wakeup */
+ err = usb2_req_set_device_feature(udev,
+ &Giant, UF_DEVICE_REMOTE_WAKEUP);
+ if (err) {
+ DPRINTFN(0, "Setting device "
+ "remote wakeup failed!\n");
+ }
+ }
+ USB_BUS_LOCK(udev->bus);
+ /*
+ * Set that this device is suspended. This variable must be set
+ * before calling USB controller suspend callbacks.
+ */
+ udev->pwr_save.suspended = 1;
+ USB_BUS_UNLOCK(udev->bus);
+
+ if (udev->bus->methods->device_suspend != NULL) {
+
+ /* suspend device on the USB controller */
+ (udev->bus->methods->device_suspend) (udev);
+
+ /* do DMA delay */
+ temp = usb2_get_dma_delay(udev->bus);
+ usb2_pause_mtx(&Giant, temp);
+
+ }
+ /* suspend current port */
+ err = usb2_req_set_port_feature(udev->parent_hub,
+ &Giant, udev->port_no, UHF_PORT_SUSPEND);
+ if (err) {
+ DPRINTFN(0, "Suspending port failed\n");
+ return;
+ }
+ if (suspend_parent) {
+ udev = udev->parent_hub;
+ goto repeat;
+ }
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_set_power_mode
+ *
+ * This function will set the power mode, see USB_POWER_MODE_XXX for a
+ * USB device.
+ *------------------------------------------------------------------------*/
+void
+usb2_set_power_mode(struct usb2_device *udev, uint8_t power_mode)
+{
+ /* filter input argument */
+ if ((power_mode != USB_POWER_MODE_ON) &&
+ (power_mode != USB_POWER_MODE_OFF)) {
+ power_mode = USB_POWER_MODE_SAVE;
+ }
+ udev->power_mode = power_mode; /* update copy of power mode */
+
+ usb2_bus_power_update(udev->bus);
+
+ return;
+}
diff --git a/sys/dev/usb2/core/usb2_hub.h b/sys/dev/usb2/core/usb2_hub.h
index 8ef618e..87d85b3 100644
--- a/sys/dev/usb2/core/usb2_hub.h
+++ b/sys/dev/usb2/core/usb2_hub.h
@@ -74,5 +74,7 @@ struct usb2_device *usb2_bus_port_get_device(struct usb2_bus *bus,
struct usb2_port *up);
void usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe);
void usb2_needs_explore_all(void);
+void usb2_bus_power_update(struct usb2_bus *bus);
+void usb2_bus_powerd(struct usb2_bus *bus);
#endif /* _USB2_HUB_H_ */
diff --git a/sys/dev/usb2/core/usb2_mbuf.h b/sys/dev/usb2/core/usb2_mbuf.h
index 91f6a0c..109340c 100644
--- a/sys/dev/usb2/core/usb2_mbuf.h
+++ b/sys/dev/usb2/core/usb2_mbuf.h
@@ -38,8 +38,9 @@ struct usb2_mbuf {
struct usb2_mbuf *usb2_next;
uint32_t cur_data_len;
- uint32_t max_data_len:31;
- uint32_t last_packet:1;
+ uint32_t max_data_len;
+ uint8_t last_packet:1;
+ uint8_t unused:7;
};
/*
diff --git a/sys/dev/usb2/core/usb2_msctest.c b/sys/dev/usb2/core/usb2_msctest.c
index ef616ce..452f389 100644
--- a/sys/dev/usb2/core/usb2_msctest.c
+++ b/sys/dev/usb2/core/usb2_msctest.c
@@ -36,7 +36,6 @@
#include <dev/usb2/include/usb2_mfunc.h>
#include <dev/usb2/include/usb2_error.h>
#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_devid.h>
#define USB_DEBUG_VAR usb2_debug
@@ -577,163 +576,3 @@ done:
free(sc, M_USB);
return (err);
}
-
-/*
- * NOTE: The entries marked with XXX should be checked for the correct
- * speed indication to set the buffer sizes.
- */
-static const struct usb2_device_id u3g_devs[] = {
- /* OEM: Option */
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- /* OEM: Qualcomm, Inc. */
- {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
- /* OEM: Huawei */
- {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, U3GINFO(U3GSP_HSDPA, U3GFL_HUAWEI_INIT))},
- {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, U3GINFO(U3GSP_HSPA, U3GFL_HUAWEI_INIT))},
- /* OEM: Novatel */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- /* OEM: Merlin */
- {USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- /* OEM: Sierra Wireless: */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- /* Sierra TruInstaller device ID */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, U3GINFO(U3GSP_UMTS, U3GFL_SIERRA_INIT))},
-};
-
-static void
-u3g_sierra_init(struct usb2_device *udev)
-{
- struct usb2_device_request req;
-
- DPRINTFN(0, "\n");
-
- req.bmRequestType = UT_VENDOR;
- req.bRequest = UR_SET_INTERFACE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, UHF_PORT_CONNECTION);
- USETW(req.wLength, 0);
-
- if (usb2_do_request_flags(udev, NULL, &req,
- NULL, 0, NULL, USB_MS_HZ)) {
- /* ignore any errors */
- }
- return;
-}
-
-static void
-u3g_huawei_init(struct usb2_device *udev)
-{
- struct usb2_device_request req;
-
- DPRINTFN(0, "\n");
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, UHF_PORT_SUSPEND);
- USETW(req.wLength, 0);
-
- if (usb2_do_request_flags(udev, NULL, &req,
- NULL, 0, NULL, USB_MS_HZ)) {
- /* ignore any errors */
- }
- return;
-}
-
-int
-usb2_lookup_huawei(struct usb2_attach_arg *uaa)
-{
- /* Calling the lookup function will also set the driver info! */
- return (usb2_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
-}
-
-/*
- * The following function handles 3G modem devices (E220, Mobile,
- * etc.) with auto-install flash disks for Windows/MacOSX on the first
- * interface. After some command or some delay they change appearance
- * to a modem.
- */
-usb2_error_t
-usb2_test_huawei(struct usb2_device *udev, struct usb2_attach_arg *uaa)
-{
- struct usb2_interface *iface;
- struct usb2_interface_descriptor *id;
- uint32_t flags;
-
- if (udev == NULL) {
- return (USB_ERR_INVAL);
- }
- iface = usb2_get_iface(udev, 0);
- if (iface == NULL) {
- return (USB_ERR_INVAL);
- }
- id = iface->idesc;
- if (id == NULL) {
- return (USB_ERR_INVAL);
- }
- if (id->bInterfaceClass != UICLASS_MASS) {
- return (USB_ERR_INVAL);
- }
- if (usb2_lookup_huawei(uaa)) {
- /* no device match */
- return (USB_ERR_INVAL);
- }
- flags = USB_GET_DRIVER_INFO(uaa);
-
- if (flags & U3GFL_HUAWEI_INIT) {
- u3g_huawei_init(udev);
- } else if (flags & U3GFL_SCSI_EJECT) {
- return (usb2_test_autoinstall(udev, 0, 1));
- } else if (flags & U3GFL_SIERRA_INIT) {
- u3g_sierra_init(udev);
- } else {
- /* no quirks */
- return (USB_ERR_INVAL);
- }
- return (0); /* success */
-}
diff --git a/sys/dev/usb2/core/usb2_msctest.h b/sys/dev/usb2/core/usb2_msctest.h
index cdd335f..5bf64d0 100644
--- a/sys/dev/usb2/core/usb2_msctest.h
+++ b/sys/dev/usb2/core/usb2_msctest.h
@@ -29,30 +29,5 @@
usb2_error_t usb2_test_autoinstall(struct usb2_device *udev,
uint8_t iface_index, uint8_t do_eject);
-usb2_error_t usb2_test_huawei(struct usb2_device *udev,
- struct usb2_attach_arg *uaa);
-int usb2_lookup_huawei(struct usb2_attach_arg *uaa);
-
-/* Huawei specific defines */
-
-#define U3GINFO(flag,speed) ((flag)|((speed) * 256))
-#define U3G_GET_SPEED(uaa) (USB_GET_DRIVER_INFO(uaa) / 256)
-
-#define U3GFL_NONE 0x00
-#define U3GFL_HUAWEI_INIT 0x01 /* Requires init command (Huawei
- * cards) */
-#define U3GFL_SCSI_EJECT 0x02 /* Requires SCSI eject command
- * (Novatel) */
-#define U3GFL_SIERRA_INIT 0x04 /* Requires init command (Sierra
- * cards) */
-
-#define U3GSP_GPRS 0
-#define U3GSP_EDGE 1
-#define U3GSP_CDMA 2
-#define U3GSP_UMTS 3
-#define U3GSP_HSDPA 4
-#define U3GSP_HSUPA 5
-#define U3GSP_HSPA 6
-#define U3GSP_MAX 7
#endif /* _USB2_MSCTEST_H_ */
diff --git a/sys/dev/usb2/core/usb2_parse.c b/sys/dev/usb2/core/usb2_parse.c
index 223b3c2..1f722b5 100644
--- a/sys/dev/usb2/core/usb2_parse.c
+++ b/sys/dev/usb2/core/usb2_parse.c
@@ -43,25 +43,44 @@
* Else: Next descriptor after "desc"
*------------------------------------------------------------------------*/
struct usb2_descriptor *
-usb2_desc_foreach(struct usb2_config_descriptor *cd, struct usb2_descriptor *desc)
+usb2_desc_foreach(struct usb2_config_descriptor *cd,
+ struct usb2_descriptor *_desc)
{
- void *end;
+ uint8_t *desc_next;
+ uint8_t *start;
+ uint8_t *end;
+ uint8_t *desc;
- if (cd == NULL) {
+ /* be NULL safe */
+ if (cd == NULL)
return (NULL);
- }
- end = USB_ADD_BYTES(cd, UGETW(cd->wTotalLength));
- if (desc == NULL) {
- desc = USB_ADD_BYTES(cd, 0);
- } else {
- desc = USB_ADD_BYTES(desc, desc->bLength);
- }
- return (((((void *)desc) >= ((void *)cd)) &&
- (((void *)desc) < end) &&
- (USB_ADD_BYTES(desc, desc->bLength) >= ((void *)cd)) &&
- (USB_ADD_BYTES(desc, desc->bLength) <= end) &&
- (desc->bLength >= sizeof(*desc))) ? desc : NULL);
+ /* We assume that the "wTotalLength" has been checked. */
+ start = (uint8_t *)cd;
+ end = start + UGETW(cd->wTotalLength);
+ desc = (uint8_t *)_desc;
+
+ /* Get start of next USB descriptor. */
+ if (desc == NULL)
+ desc = start;
+ else
+ desc = desc + desc[0];
+
+ /* Check that the next USB descriptor is within the range. */
+ if ((desc < start) || (desc >= end))
+ return (NULL); /* out of range, or EOD */
+
+ /* Check that the second next USB descriptor is within range. */
+ desc_next = desc + desc[0];
+ if ((desc_next < start) || (desc_next > end))
+ return (NULL); /* out of range */
+
+ /* Check minimum descriptor length. */
+ if (desc[0] < 3)
+ return (NULL); /* too short descriptor */
+
+ /* Return start of next descriptor. */
+ return ((struct usb2_descriptor *)desc);
}
/*------------------------------------------------------------------------*
@@ -140,7 +159,6 @@ usb2_find_edesc(struct usb2_config_descriptor *cd,
desc = ((void *)d);
while ((desc = usb2_desc_foreach(cd, desc))) {
-
if (desc->bDescriptorType == UDESC_INTERFACE) {
break;
}
@@ -195,7 +213,6 @@ usb2_get_no_alts(struct usb2_config_descriptor *cd, uint8_t ifaceno)
uint16_t n = 0;
while ((desc = usb2_desc_foreach(cd, desc))) {
-
if ((desc->bDescriptorType == UDESC_INTERFACE) &&
(desc->bLength >= sizeof(*id))) {
id = (void *)desc;
diff --git a/sys/dev/usb2/core/usb2_process.c b/sys/dev/usb2/core/usb2_process.c
index 468bb30..facd84e 100644
--- a/sys/dev/usb2/core/usb2_process.c
+++ b/sys/dev/usb2/core/usb2_process.c
@@ -184,11 +184,11 @@ usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx, uint8_t prio)
TAILQ_INIT(&up->up_qhead);
- usb2_cv_init(&up->up_cv, "WMSG");
- usb2_cv_init(&up->up_drain, "DMSG");
+ usb2_cv_init(&up->up_cv, "wmsg");
+ usb2_cv_init(&up->up_drain, "dmsg");
if (USB_THREAD_CREATE(&usb2_process, up,
- &up->up_ptr, "USBPROC")) {
+ &up->up_ptr, "usbproc")) {
DPRINTFN(0, "Unable to create USB process.");
up->up_ptr = NULL;
goto error;
diff --git a/sys/dev/usb2/core/usb2_request.c b/sys/dev/usb2/core/usb2_request.c
index 030a022..3e48dc1 100644
--- a/sys/dev/usb2/core/usb2_request.c
+++ b/sys/dev/usb2/core/usb2_request.c
@@ -80,7 +80,7 @@ usb2_do_request_callback(struct usb2_xfer *xfer)
usb2_start_hardware(xfer);
break;
default:
- usb2_cv_signal(xfer->udev->default_cv);
+ usb2_cv_signal(xfer->xroot->udev->default_cv);
break;
}
}
@@ -94,18 +94,21 @@ void
usb2_do_clear_stall_callback(struct usb2_xfer *xfer)
{
struct usb2_device_request req;
+ struct usb2_device *udev;
struct usb2_pipe *pipe;
struct usb2_pipe *pipe_end;
struct usb2_pipe *pipe_first;
uint8_t to = USB_EP_MAX;
- USB_BUS_LOCK(xfer->udev->bus);
+ udev = xfer->xroot->udev;
+
+ USB_BUS_LOCK(udev->bus);
/* round robin pipe clear stall */
- pipe = xfer->udev->pipe_curr;
- pipe_end = xfer->udev->pipes + USB_EP_MAX;
- pipe_first = xfer->udev->pipes;
+ pipe = udev->pipe_curr;
+ pipe_end = udev->pipes + USB_EP_MAX;
+ pipe_first = udev->pipes;
if (pipe == NULL) {
pipe = pipe_first;
}
@@ -145,11 +148,11 @@ tr_setup:
/* set length */
xfer->frlengths[0] = sizeof(req);
xfer->nframes = 1;
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(udev->bus);
usb2_start_hardware(xfer);
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(udev->bus);
break;
}
pipe++;
@@ -165,8 +168,8 @@ tr_setup:
}
/* store current pipe */
- xfer->udev->pipe_curr = pipe;
- USB_BUS_UNLOCK(xfer->udev->bus);
+ udev->pipe_curr = pipe;
+ USB_BUS_UNLOCK(udev->bus);
}
/*------------------------------------------------------------------------*
@@ -367,7 +370,8 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
}
if (temp > 0) {
usb2_pause_mtx(
- xfer->xfer_mtx, temp);
+ xfer->xroot->xfer_mtx,
+ temp);
}
#endif
xfer->flags.manual_status = 0;
@@ -384,8 +388,8 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
if ((flags & USB_USE_POLLING) || cold) {
usb2_do_poll(udev->default_xfer, USB_DEFAULT_XFER_MAX);
} else {
- usb2_cv_wait(xfer->udev->default_cv,
- xfer->xfer_mtx);
+ usb2_cv_wait(udev->default_cv,
+ xfer->xroot->xfer_mtx);
}
}
@@ -611,7 +615,8 @@ usb2_req_get_desc(struct usb2_device *udev, struct mtx *mtx, void *desc,
}
USETW(req.wLength, min_len);
- err = usb2_do_request(udev, mtx, &req, desc);
+ err = usb2_do_request_flags(udev, mtx, &req,
+ desc, 0, NULL, 1000);
if (err) {
if (!retries) {
@@ -1326,6 +1331,7 @@ usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx)
struct usb2_device *parent_hub;
usb2_error_t err;
uint8_t old_addr;
+ uint8_t do_retry = 1;
if (udev->flags.usb2_mode != USB_MODE_HOST) {
return (USB_ERR_INVAL);
@@ -1335,6 +1341,7 @@ usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx)
if (parent_hub == NULL) {
return (USB_ERR_INVAL);
}
+retry:
err = usb2_req_reset_port(parent_hub, mtx, udev->port_no);
if (err) {
DPRINTFN(0, "addr=%d, port reset failed\n", old_addr);
@@ -1355,9 +1362,8 @@ usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx)
err = usb2_req_set_address(udev, mtx, old_addr);
if (err) {
/* XXX ignore any errors! */
- DPRINTFN(0, "addr=%d, set address failed\n",
+ DPRINTFN(0, "addr=%d, set address failed! (ignored)\n",
old_addr);
- err = 0;
}
/* restore device address */
udev->address = old_addr;
@@ -1381,7 +1387,57 @@ usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx)
goto done;
}
done:
+ if (err && do_retry) {
+ /* give the USB firmware some time to load */
+ usb2_pause_mtx(mtx, 500);
+ /* no more retries after this retry */
+ do_retry = 0;
+ /* try again */
+ goto retry;
+ }
/* restore address */
udev->address = old_addr;
return (err);
}
+
+/*------------------------------------------------------------------------*
+ * usb2_req_clear_device_feature
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb2_error_t
+usb2_req_clear_device_feature(struct usb2_device *udev, struct mtx *mtx,
+ uint16_t sel)
+{
+ struct usb2_device_request req;
+
+ req.bmRequestType = UT_WRITE_DEVICE;
+ req.bRequest = UR_CLEAR_FEATURE;
+ USETW(req.wValue, sel);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, 0);
+ return (usb2_do_request(udev, mtx, &req, 0));
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_req_set_device_feature
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb2_error_t
+usb2_req_set_device_feature(struct usb2_device *udev, struct mtx *mtx,
+ uint16_t sel)
+{
+ struct usb2_device_request req;
+
+ req.bmRequestType = UT_WRITE_DEVICE;
+ req.bRequest = UR_SET_FEATURE;
+ USETW(req.wValue, sel);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, 0);
+ return (usb2_do_request(udev, mtx, &req, 0));
+}
diff --git a/sys/dev/usb2/core/usb2_request.h b/sys/dev/usb2/core/usb2_request.h
index 3869968..b33e0a1 100644
--- a/sys/dev/usb2/core/usb2_request.h
+++ b/sys/dev/usb2/core/usb2_request.h
@@ -89,6 +89,8 @@ usb2_error_t usb2_req_set_report(struct usb2_device *udev, struct mtx *mtx,
void *data, uint16_t len, uint8_t iface_index,
uint8_t type, uint8_t id);
usb2_error_t usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx);
+usb2_error_t usb2_req_clear_device_feature(struct usb2_device *udev, struct mtx *mtx, uint16_t sel);
+usb2_error_t usb2_req_set_device_feature(struct usb2_device *udev, struct mtx *mtx, uint16_t sel);
#define usb2_do_request(u,m,r,d) \
usb2_do_request_flags(u,m,r,d,0,NULL,USB_DEFAULT_TIMEOUT)
diff --git a/sys/dev/usb2/core/usb2_sw_transfer.c b/sys/dev/usb2/core/usb2_sw_transfer.c
index e88ffc8..23f89ba 100644
--- a/sys/dev/usb2/core/usb2_sw_transfer.c
+++ b/sys/dev/usb2/core/usb2_sw_transfer.c
@@ -72,7 +72,7 @@ usb2_sw_transfer(struct usb2_sw_transfer *std,
DPRINTF("xfer gone\n");
return;
}
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
std->xfer = NULL;
diff --git a/sys/dev/usb2/core/usb2_transfer.c b/sys/dev/usb2/core/usb2_transfer.c
index 1cf6956..d47845e 100644
--- a/sys/dev/usb2/core/usb2_transfer.c
+++ b/sys/dev/usb2/core/usb2_transfer.c
@@ -63,6 +63,7 @@ static const struct usb2_std_packet_size
[USB_SPEED_FULL] = {.range = {0, 64}},
[USB_SPEED_HIGH] = {.range = {0, 1024}},
[USB_SPEED_VARIABLE] = {.range = {0, 1024}},
+ [USB_SPEED_SUPER] = {.range = {0, 1024}},
},
[UE_CONTROL] = {
@@ -70,6 +71,7 @@ static const struct usb2_std_packet_size
[USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
[USB_SPEED_HIGH] = {.fixed = {64, 64, 64, 64}},
[USB_SPEED_VARIABLE] = {.fixed = {512, 512, 512, 512}},
+ [USB_SPEED_SUPER] = {.fixed = {512, 512, 512, 512}},
},
[UE_BULK] = {
@@ -77,6 +79,7 @@ static const struct usb2_std_packet_size
[USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
[USB_SPEED_HIGH] = {.fixed = {512, 512, 512, 512}},
[USB_SPEED_VARIABLE] = {.fixed = {512, 512, 1024, 1536}},
+ [USB_SPEED_SUPER] = {.fixed = {1024, 1024, 1024, 1024}},
},
[UE_ISOCHRONOUS] = {
@@ -84,6 +87,7 @@ static const struct usb2_std_packet_size
[USB_SPEED_FULL] = {.range = {0, 1023}},
[USB_SPEED_HIGH] = {.range = {0, 1024}},
[USB_SPEED_VARIABLE] = {.range = {0, 3584}},
+ [USB_SPEED_SUPER] = {.range = {0, 1024}},
},
};
@@ -120,7 +124,6 @@ static const struct usb2_config usb2_control_ep_cfg[USB_DEFAULT_XFER_MAX] = {
/* function prototypes */
static void usb2_update_max_frame_size(struct usb2_xfer *);
-static uint32_t usb2_get_dma_delay(struct usb2_bus *);
static void usb2_transfer_unsetup_sub(struct usb2_xfer_root *, uint8_t);
static void usb2_control_transfer_init(struct usb2_xfer *);
static uint8_t usb2_start_hardware_sub(struct usb2_xfer *);
@@ -161,7 +164,7 @@ usb2_update_max_frame_size(struct usb2_xfer *xfer)
* 0: no DMA delay required
* Else: milliseconds of DMA delay
*------------------------------------------------------------------------*/
-static uint32_t
+uint32_t
usb2_get_dma_delay(struct usb2_bus *bus)
{
uint32_t temp = 0;
@@ -244,12 +247,12 @@ usb2_transfer_setup_sub_malloc(struct usb2_setup_params *parm,
for (x = 0; x != n_dma_pc; x++) {
/* need to initialize the page cache */
parm->dma_page_cache_ptr[x].tag_parent =
- &parm->curr_xfer->usb2_root->dma_parent_tag;
+ &parm->curr_xfer->xroot->dma_parent_tag;
}
for (x = 0; x != count; x++) {
/* need to initialize the page cache */
parm->xfer_page_cache_ptr[x].tag_parent =
- &parm->curr_xfer->usb2_root->dma_parent_tag;
+ &parm->curr_xfer->xroot->dma_parent_tag;
}
if (ppc) {
@@ -414,10 +417,14 @@ usb2_transfer_setup_sub(struct usb2_setup_params *parm)
*/
xfer->timeout = 1000 / 4;
}
- if (parm->speed == USB_SPEED_HIGH) {
- frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
- } else {
+ switch (parm->speed) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER;
+ break;
+ default:
+ frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
+ break;
}
if (xfer->nframes > frame_limit) {
@@ -447,13 +454,29 @@ usb2_transfer_setup_sub(struct usb2_setup_params *parm)
xfer->interval = edesc->bInterval;
- if (parm->speed == USB_SPEED_HIGH) {
- xfer->interval /= 8; /* 125us -> 1ms */
+ switch (parm->speed) {
+ case USB_SPEED_SUPER:
+ case USB_SPEED_VARIABLE:
+ /* 125us -> 1ms */
+ if (xfer->interval < 4)
+ xfer->interval = 1;
+ else if (xfer->interval > 16)
+ xfer->interval = (1<<(16-4));
+ else
+ xfer->interval =
+ (1 << (xfer->interval-4));
+ break;
+ case USB_SPEED_HIGH:
+ /* 125us -> 1ms */
+ xfer->interval /= 8;
+ break;
+ default:
+ break;
}
if (xfer->interval == 0) {
/*
- * one millisecond is the smallest
- * interval
+ * One millisecond is the smallest
+ * interval we support:
*/
xfer->interval = 1;
}
@@ -671,7 +694,7 @@ usb2_transfer_setup_sub(struct usb2_setup_params *parm)
if (parm->buf) {
for (x = 0; x != n_frbuffers; x++) {
xfer->frbuffers[x].tag_parent =
- &xfer->usb2_root->dma_parent_tag;
+ &xfer->xroot->dma_parent_tag;
if (xfer->flags_int.bdma_enable &&
(parm->bufsize_max > 0)) {
@@ -716,7 +739,7 @@ usb2_error_t
usb2_transfer_setup(struct usb2_device *udev,
const uint8_t *ifaces, struct usb2_xfer **ppxfer,
const struct usb2_config *setup_start, uint16_t n_setup,
- void *priv_sc, struct mtx *priv_mtx)
+ void *priv_sc, struct mtx *xfer_mtx)
{
struct usb2_xfer dummy;
struct usb2_setup_params parm;
@@ -746,9 +769,9 @@ usb2_transfer_setup(struct usb2_device *udev,
DPRINTFN(6, "ifaces array is NULL!\n");
return (USB_ERR_INVAL);
}
- if (priv_mtx == NULL) {
+ if (xfer_mtx == NULL) {
DPRINTFN(6, "using global lock\n");
- priv_mtx = &Giant;
+ xfer_mtx = &Giant;
}
/* sanity checks */
for (setup = setup_start, n = 0;
@@ -800,13 +823,14 @@ usb2_transfer_setup(struct usb2_device *udev,
usb2_cv_init(&info->cv_drain, "WDRAIN");
- info->priv_mtx = priv_mtx;
+ info->xfer_mtx = xfer_mtx;
usb2_dma_tag_setup(&info->dma_parent_tag,
parm.dma_tag_p, udev->bus->dma_parent_tag[0].tag,
- priv_mtx, &usb2_bdma_done_event, info, 32, parm.dma_tag_max);
+ xfer_mtx, &usb2_bdma_done_event, info, 32, parm.dma_tag_max);
info->bus = udev->bus;
+ info->udev = udev;
TAILQ_INIT(&info->done_q.head);
info->done_q.command = &usb2_callback_wrapper;
@@ -815,17 +839,16 @@ usb2_transfer_setup(struct usb2_device *udev,
info->dma_q.command = &usb2_bdma_work_loop;
info->done_m[0].hdr.pm_callback = &usb2_callback_proc;
- info->done_m[0].usb2_root = info;
+ info->done_m[0].xroot = info;
info->done_m[1].hdr.pm_callback = &usb2_callback_proc;
- info->done_m[1].usb2_root = info;
-
- /* create a callback thread */
-
- if (usb2_proc_setup(&info->done_p,
- &udev->bus->bus_mtx, USB_PRI_HIGH)) {
- parm.err = USB_ERR_NO_INTR_THREAD;
- goto done;
- }
+ info->done_m[1].xroot = info;
+
+ if (xfer_mtx == &Giant)
+ info->done_p =
+ &udev->bus->giant_callback_proc;
+ else
+ info->done_p =
+ &udev->bus->non_giant_callback_proc;
}
/* reset sizes */
@@ -872,11 +895,9 @@ usb2_transfer_setup(struct usb2_device *udev,
xfer = USB_ADD_BYTES(buf, parm.size[0]);
ppxfer[n] = xfer;
- xfer->udev = udev;
xfer->address = udev->address;
xfer->priv_sc = priv_sc;
- xfer->xfer_mtx = priv_mtx;
- xfer->usb2_root = info;
+ xfer->xroot = info;
info->setup_refcount++;
usb2_callout_init_mtx(&xfer->timeout_handle,
@@ -1047,10 +1068,11 @@ usb2_transfer_unsetup_sub(struct usb2_xfer_root *info, uint8_t needs_delay)
temp = usb2_get_dma_delay(info->bus);
usb2_pause_mtx(&info->bus->bus_mtx, temp);
}
- USB_BUS_UNLOCK(info->bus);
- /* wait for interrupt thread to exit */
- usb2_proc_unsetup(&info->done_p);
+ /* make sure that our done messages are not queued anywhere */
+ usb2_proc_mwait(info->done_p, &info->done_m[0], &info->done_m[1]);
+
+ USB_BUS_UNLOCK(info->bus);
/* free DMA'able memory, if any */
pc = info->dma_page_cache_start;
@@ -1101,7 +1123,7 @@ usb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup)
if (xfer) {
if (xfer->pipe) {
USB_XFER_LOCK(xfer);
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
/*
* HINT: when you start/stop a transfer, it
@@ -1113,7 +1135,7 @@ usb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup)
*
* That way, if your code has many parts that
* will not stop running under the same
- * lock, in other words "priv_mtx", the
+ * lock, in other words "xfer_mtx", the
* usb2_transfer_start and
* usb2_transfer_stop functions will simply
* return when they detect a NULL pointer
@@ -1125,7 +1147,7 @@ usb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup)
*/
pxfer[n_setup] = NULL;
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
USB_XFER_UNLOCK(xfer);
usb2_transfer_drain(xfer);
@@ -1146,8 +1168,8 @@ usb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup)
usb2_callout_drain(&xfer->timeout_handle);
- if (xfer->usb2_root) {
- info = xfer->usb2_root;
+ if (xfer->xroot) {
+ info = xfer->xroot;
USB_BUS_LOCK(info->bus);
@@ -1350,16 +1372,16 @@ usb2_start_hardware(struct usb2_xfer *xfer)
#if USB_DEBUG
if (USB_DEBUG_VAR > 0) {
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
usb2_dump_pipe(xfer->pipe);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
#endif
USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_NOTOWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_NOTOWNED);
/* Only open the USB transfer once! */
if (!xfer->flags_int.open) {
@@ -1367,21 +1389,24 @@ usb2_start_hardware(struct usb2_xfer *xfer)
DPRINTF("open\n");
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
(xfer->pipe->methods->open) (xfer);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/* set "transferring" flag */
xfer->flags_int.transferring = 1;
+ /* increment power reference */
+ usb2_transfer_power_ref(xfer, 1);
+
/*
* Check if the transfer is waiting on a queue, most
* frequently the "done_q":
*/
if (xfer->wait_queue) {
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
usb2_transfer_dequeue(xfer);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/* clear "did_dma_delay" flag */
xfer->flags_int.did_dma_delay = 0;
@@ -1413,16 +1438,16 @@ usb2_start_hardware(struct usb2_xfer *xfer)
*/
DPRINTF("xfer=%p nframes=0: stall "
"or clear stall!\n", xfer);
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
xfer->flags_int.can_cancel_immed = 1;
/* start the transfer */
usb2_command_wrapper(&xfer->pipe->pipe_q, xfer);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return;
}
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
usb2_transfer_done(xfer, USB_ERR_INVAL);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return;
}
/* compute total transfer length */
@@ -1431,9 +1456,9 @@ usb2_start_hardware(struct usb2_xfer *xfer)
xfer->sumlen += xfer->frlengths[x];
if (xfer->sumlen < xfer->frlengths[x]) {
/* length wrapped around */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
usb2_transfer_done(xfer, USB_ERR_INVAL);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return;
}
}
@@ -1448,9 +1473,9 @@ usb2_start_hardware(struct usb2_xfer *xfer)
if (xfer->flags_int.control_xfr) {
if (usb2_start_hardware_sub(xfer)) {
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
usb2_transfer_done(xfer, USB_ERR_STALLED);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return;
}
}
@@ -1486,7 +1511,7 @@ usb2_start_hardware(struct usb2_xfer *xfer)
*/
if (xfer->flags_int.bdma_enable) {
/* insert the USB transfer last in the BUS-DMA queue */
- usb2_command_wrapper(&xfer->usb2_root->dma_q, xfer);
+ usb2_command_wrapper(&xfer->xroot->dma_q, xfer);
return;
}
/*
@@ -1506,7 +1531,7 @@ usb2_pipe_enter(struct usb2_xfer *xfer)
USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
pipe = xfer->pipe;
@@ -1522,7 +1547,7 @@ usb2_pipe_enter(struct usb2_xfer *xfer)
if (xfer->error) {
/* some error has happened */
usb2_transfer_done(xfer, 0);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return;
}
} else {
@@ -1531,7 +1556,7 @@ usb2_pipe_enter(struct usb2_xfer *xfer)
/* start the transfer */
usb2_command_wrapper(&pipe->pipe_q, xfer);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/*------------------------------------------------------------------------*
@@ -1560,10 +1585,10 @@ usb2_transfer_start(struct usb2_xfer *xfer)
if (xfer->flags_int.transferring) {
return;
}
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
/* call the USB transfer callback */
usb2_callback_ss_done_defer(xfer);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/*------------------------------------------------------------------------*
@@ -1594,7 +1619,7 @@ usb2_transfer_stop(struct usb2_xfer *xfer)
}
/* try to stop the current USB transfer */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
xfer->error = USB_ERR_CANCELLED;/* override any previous error */
/*
* Clear "open" and "started" when both private and USB lock
@@ -1646,7 +1671,7 @@ usb2_transfer_stop(struct usb2_xfer *xfer)
}
}
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/*------------------------------------------------------------------------*
@@ -1670,22 +1695,22 @@ usb2_transfer_pending(struct usb2_xfer *xfer)
/* trivial case */
return (1);
}
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
if (xfer->wait_queue) {
/* we are waiting on a queue somewhere */
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return (1);
}
- info = xfer->usb2_root;
+ info = xfer->xroot;
pq = &info->done_q;
if (pq->curr == xfer) {
/* we are currently scheduled for callback */
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return (1);
}
/* we are not pending */
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return (0);
}
@@ -1707,7 +1732,7 @@ usb2_transfer_drain(struct usb2_xfer *xfer)
/* transfer is gone */
return;
}
- if (xfer->xfer_mtx != &Giant) {
+ if (xfer->xroot->xfer_mtx != &Giant) {
USB_XFER_LOCK_ASSERT(xfer, MA_NOTOWNED);
}
USB_XFER_LOCK(xfer);
@@ -1720,7 +1745,7 @@ usb2_transfer_drain(struct usb2_xfer *xfer)
* Wait until the current outstanding USB
* transfer is complete !
*/
- usb2_cv_wait(&xfer->usb2_root->cv_drain, xfer->xfer_mtx);
+ usb2_cv_wait(&xfer->xroot->cv_drain, xfer->xroot->xfer_mtx);
}
USB_XFER_UNLOCK(xfer);
}
@@ -1767,7 +1792,7 @@ static void
usb2_callback_proc(struct usb2_proc_msg *_pm)
{
struct usb2_done_msg *pm = (void *)_pm;
- struct usb2_xfer_root *info = pm->usb2_root;
+ struct usb2_xfer_root *info = pm->xroot;
/* Change locking order */
USB_BUS_UNLOCK(info->bus);
@@ -1776,14 +1801,14 @@ usb2_callback_proc(struct usb2_proc_msg *_pm)
* We exploit the fact that the mutex is the same for all
* callbacks that will be called from this thread:
*/
- mtx_lock(info->priv_mtx);
+ mtx_lock(info->xfer_mtx);
USB_BUS_LOCK(info->bus);
/* Continue where we lost track */
usb2_command_wrapper(&info->done_q,
info->done_q.curr);
- mtx_unlock(info->priv_mtx);
+ mtx_unlock(info->xfer_mtx);
}
/*------------------------------------------------------------------------*
@@ -1795,10 +1820,10 @@ usb2_callback_proc(struct usb2_proc_msg *_pm)
static void
usb2_callback_ss_done_defer(struct usb2_xfer *xfer)
{
- struct usb2_xfer_root *info = xfer->usb2_root;
+ struct usb2_xfer_root *info = xfer->xroot;
struct usb2_xfer_queue *pq = &info->done_q;
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
if (pq->curr != xfer) {
usb2_transfer_enqueue(pq, xfer);
@@ -1810,7 +1835,7 @@ usb2_callback_ss_done_defer(struct usb2_xfer *xfer)
* will have a Lock Order Reversal, LOR, if we try to
* proceed !
*/
- if (usb2_proc_msignal(&info->done_p,
+ if (usb2_proc_msignal(info->done_p,
&info->done_m[0], &info->done_m[1])) {
/* ignore */
}
@@ -1834,10 +1859,10 @@ static void
usb2_callback_wrapper(struct usb2_xfer_queue *pq)
{
struct usb2_xfer *xfer = pq->curr;
- struct usb2_xfer_root *info = xfer->usb2_root;
+ struct usb2_xfer_root *info = xfer->xroot;
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
- if (!mtx_owned(xfer->xfer_mtx)) {
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
+ if (!mtx_owned(xfer->xroot->xfer_mtx)) {
/*
* Cases that end up here:
*
@@ -1850,7 +1875,7 @@ usb2_callback_wrapper(struct usb2_xfer_queue *pq)
* will have a Lock Order Reversal, LOR, if we try to
* proceed !
*/
- if (usb2_proc_msignal(&info->done_p,
+ if (usb2_proc_msignal(info->done_p,
&info->done_m[0], &info->done_m[1])) {
/* ignore */
}
@@ -1868,24 +1893,27 @@ usb2_callback_wrapper(struct usb2_xfer_queue *pq)
/* get next USB transfer in the queue */
info->done_q.curr = NULL;
- USB_BUS_UNLOCK(xfer->udev->bus);
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_NOTOWNED);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_NOTOWNED);
/* set correct USB state for callback */
if (!xfer->flags_int.transferring) {
xfer->usb2_state = USB_ST_SETUP;
if (!xfer->flags_int.started) {
/* we got stopped before we even got started */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
goto done;
}
} else {
if (usb2_callback_wrapper_sub(xfer)) {
/* the callback has been deferred */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
goto done;
}
+ /* decrement power reference */
+ usb2_transfer_power_ref(xfer, -1);
+
xfer->flags_int.transferring = 0;
if (xfer->error) {
@@ -1906,12 +1934,11 @@ usb2_callback_wrapper(struct usb2_xfer_queue *pq)
(xfer->callback) (xfer);
/* pickup the USB mutex again */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
/*
* Check if we got started after that we got cancelled, but
- * before we managed to do the callback. Check if we are
- * draining.
+ * before we managed to do the callback.
*/
if ((!xfer->flags_int.open) &&
(xfer->flags_int.started) &&
@@ -1919,13 +1946,19 @@ usb2_callback_wrapper(struct usb2_xfer_queue *pq)
/* try to loop, but not recursivly */
usb2_command_wrapper(&info->done_q, xfer);
return;
- } else if (xfer->flags_int.draining &&
+ }
+
+done:
+ /*
+ * Check if we are draining.
+ */
+ if (xfer->flags_int.draining &&
(!xfer->flags_int.transferring)) {
/* "usb2_transfer_drain()" is waiting for end of transfer */
xfer->flags_int.draining = 0;
- usb2_cv_broadcast(&xfer->usb2_root->cv_drain);
+ usb2_cv_broadcast(&xfer->xroot->cv_drain);
}
-done:
+
/* do the next callback, if any */
usb2_command_wrapper(&info->done_q,
info->done_q.curr);
@@ -1944,7 +1977,7 @@ usb2_dma_delay_done_cb(void *arg)
{
struct usb2_xfer *xfer = arg;
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
DPRINTFN(3, "Completed %p\n", xfer);
@@ -2009,7 +2042,7 @@ usb2_transfer_done(struct usb2_xfer *xfer, usb2_error_t error)
{
struct usb2_xfer_queue *pq;
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
DPRINTF("err=%s\n", usb2_errstr(error));
@@ -2035,12 +2068,12 @@ usb2_transfer_done(struct usb2_xfer *xfer, usb2_error_t error)
*/
usb2_transfer_dequeue(xfer);
- if (mtx_owned(xfer->xfer_mtx)) {
+ if (mtx_owned(xfer->xroot->xfer_mtx)) {
/*
* If the private USB lock is not locked, then we assume
* that the BUS-DMA load stage has been passed:
*/
- pq = &xfer->usb2_root->dma_q;
+ pq = &xfer->xroot->dma_q;
if (pq->curr == xfer) {
/* start the next BUS-DMA load, if any */
@@ -2049,10 +2082,10 @@ usb2_transfer_done(struct usb2_xfer *xfer, usb2_error_t error)
}
/* keep some statistics */
if (xfer->error) {
- xfer->udev->bus->stats_err.uds_requests
+ xfer->xroot->bus->stats_err.uds_requests
[xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
} else {
- xfer->udev->bus->stats_ok.uds_requests
+ xfer->xroot->bus->stats_ok.uds_requests
[xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
}
@@ -2073,7 +2106,7 @@ usb2_transfer_start_cb(void *arg)
struct usb2_xfer *xfer = arg;
struct usb2_pipe *pipe = xfer->pipe;
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
DPRINTF("start\n");
@@ -2108,11 +2141,11 @@ usb2_transfer_set_stall(struct usb2_xfer *xfer)
USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
/* avoid any races by locking the USB mutex */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
xfer->flags.stall_pipe = 1;
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/*------------------------------------------------------------------------*
@@ -2131,11 +2164,11 @@ usb2_transfer_clear_stall(struct usb2_xfer *xfer)
USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
/* avoid any races by locking the USB mutex */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
xfer->flags.stall_pipe = 0;
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/*------------------------------------------------------------------------*
@@ -2153,7 +2186,7 @@ usb2_pipe_start(struct usb2_xfer_queue *pq)
xfer = pq->curr;
pipe = xfer->pipe;
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/*
* If the pipe is already stalled we do nothing !
@@ -2177,15 +2210,17 @@ usb2_pipe_start(struct usb2_xfer_queue *pq)
struct usb2_device *udev;
struct usb2_xfer_root *info;
- udev = xfer->udev;
+ info = xfer->xroot;
+ udev = info->udev;
pipe->is_stalled = 1;
if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
(udev->bus->methods->set_stall) (
udev, NULL, pipe);
} else if (udev->default_xfer[1]) {
- info = udev->default_xfer[1]->usb2_root;
- if (usb2_proc_msignal(&info->done_p,
+ info = udev->default_xfer[1]->xroot;
+ if (usb2_proc_msignal(
+ &info->bus->non_giant_callback_proc,
&udev->cs_msg[0], &udev->cs_msg[1])) {
/* ignore */
}
@@ -2255,7 +2290,7 @@ void
usb2_transfer_timeout_ms(struct usb2_xfer *xfer,
void (*cb) (void *arg), uint32_t ms)
{
- USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
+ USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
/* defer delay */
usb2_callout_reset(&xfer->timeout_handle,
@@ -2288,9 +2323,9 @@ usb2_callback_wrapper_sub(struct usb2_xfer *xfer)
if ((!xfer->flags_int.open) &&
(!xfer->flags_int.did_close)) {
DPRINTF("close\n");
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
(xfer->pipe->methods->close) (xfer);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
/* only close once */
xfer->flags_int.did_close = 1;
return (1); /* wait for new callback */
@@ -2311,16 +2346,16 @@ usb2_callback_wrapper_sub(struct usb2_xfer *xfer)
/* we can not cancel this delay */
xfer->flags_int.can_cancel_immed = 0;
- temp = usb2_get_dma_delay(xfer->udev->bus);
+ temp = usb2_get_dma_delay(xfer->xroot->bus);
DPRINTFN(3, "DMA delay, %u ms, "
"on %p\n", temp, xfer);
if (temp != 0) {
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
usb2_transfer_timeout_ms(xfer,
&usb2_dma_delay_done_cb, temp);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
return (1); /* wait for new callback */
}
}
@@ -2412,7 +2447,7 @@ usb2_callback_wrapper_sub(struct usb2_xfer *xfer)
* If the current USB transfer is completing we need to start the
* next one:
*/
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
if (pipe->pipe_q.curr == xfer) {
usb2_command_wrapper(&pipe->pipe_q, NULL);
@@ -2424,7 +2459,7 @@ usb2_callback_wrapper_sub(struct usb2_xfer *xfer)
xfer->pipe->is_synced = 0;
}
}
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
done:
return (0);
}
@@ -2627,7 +2662,7 @@ usb2_clear_stall_callback(struct usb2_xfer *xfer1,
* "ata-usb.c" depends on this)
*/
- usb2_clear_data_toggle(xfer2->udev, xfer2->pipe);
+ usb2_clear_data_toggle(xfer2->xroot->udev, xfer2->pipe);
/* setup a clear-stall packet */
@@ -2720,7 +2755,7 @@ void
usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
{
struct usb2_xfer *xfer;
- struct usb2_xfer_root *usb2_root;
+ struct usb2_xfer_root *xroot;
struct usb2_device *udev;
struct usb2_proc_msg *pm;
uint32_t to;
@@ -2734,8 +2769,8 @@ usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
for (n = 0; n != max; n++) {
xfer = ppxfer[n];
if (xfer) {
- usb2_root = xfer->usb2_root;
- udev = xfer->udev;
+ xroot = xfer->xroot;
+ udev = xroot->udev;
/*
* Poll hardware - signal that we are polling by
@@ -2746,10 +2781,10 @@ usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
USB_XFER_UNLOCK(xfer);
/* poll clear stall start */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
pm = &udev->cs_msg[0].hdr;
(pm->pm_callback) (pm);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
if (udev->default_xfer[1]) {
@@ -2757,20 +2792,20 @@ usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
usb2_callout_poll(udev->default_xfer[1]);
/* poll clear stall done thread */
- USB_BUS_LOCK(xfer->udev->bus);
+ USB_BUS_LOCK(xfer->xroot->bus);
pm = &udev->default_xfer[1]->
- usb2_root->done_m[0].hdr;
+ xroot->done_m[0].hdr;
(pm->pm_callback) (pm);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
/* poll timeout */
usb2_callout_poll(xfer);
/* poll done thread */
- USB_BUS_LOCK(xfer->udev->bus);
- pm = &usb2_root->done_m[0].hdr;
+ USB_BUS_LOCK(xfer->xroot->bus);
+ pm = &xroot->done_m[0].hdr;
(pm->pm_callback) (pm);
- USB_BUS_UNLOCK(xfer->udev->bus);
+ USB_BUS_UNLOCK(xfer->xroot->bus);
}
}
}
diff --git a/sys/dev/usb2/core/usb2_transfer.h b/sys/dev/usb2/core/usb2_transfer.h
index 1351046..4149499 100644
--- a/sys/dev/usb2/core/usb2_transfer.h
+++ b/sys/dev/usb2/core/usb2_transfer.h
@@ -33,7 +33,7 @@
*/
struct usb2_done_msg {
struct usb2_proc_msg hdr;
- struct usb2_xfer_root *usb2_root;
+ struct usb2_xfer_root *xroot;
};
/*
@@ -46,17 +46,17 @@ struct usb2_xfer_root {
struct usb2_xfer_queue done_q;
struct usb2_done_msg done_m[2];
struct cv cv_drain;
-
struct usb2_dma_parent_tag dma_parent_tag;
- struct usb2_process done_p;
+ struct usb2_process *done_p; /* pointer to callback process */
void *memory_base;
- struct mtx *priv_mtx;
+ struct mtx *xfer_mtx; /* cannot be changed during operation */
struct usb2_page_cache *dma_page_cache_start;
struct usb2_page_cache *dma_page_cache_end;
struct usb2_page_cache *xfer_page_cache_start;
struct usb2_page_cache *xfer_page_cache_end;
- struct usb2_bus *bus;
+ struct usb2_bus *bus; /* pointer to USB bus (cached) */
+ struct usb2_device *udev; /* pointer to USB device */
uint32_t memory_size;
uint32_t setup_refcount;
@@ -124,5 +124,7 @@ usb2_callback_t usb2_handle_request_callback;
usb2_callback_t usb2_do_clear_stall_callback;
void usb2_transfer_timeout_ms(struct usb2_xfer *xfer,
void (*cb) (void *arg), uint32_t ms);
+uint32_t usb2_get_dma_delay(struct usb2_bus *bus);
+void usb2_transfer_power_ref(struct usb2_xfer *xfer, int val);
#endif /* _USB2_TRANSFER_H_ */
diff --git a/sys/dev/usb2/ethernet/if_aue2.c b/sys/dev/usb2/ethernet/if_aue2.c
index f0bcc04..f30a712 100644
--- a/sys/dev/usb2/ethernet/if_aue2.c
+++ b/sys/dev/usb2/ethernet/if_aue2.c
@@ -87,7 +87,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_aue2_reg.h>
+#include <dev/usb2/ethernet/if_auereg.h>
MODULE_DEPEND(aue, usb2_ethernet, 1, 1, 1);
MODULE_DEPEND(aue, usb2_core, 1, 1, 1);
@@ -225,9 +225,9 @@ static void aue_ifmedia_sts_cb(struct ifnet *, struct ifmediareq *);
static int aue_ioctl_cb(struct ifnet *, u_long, caddr_t);
static void aue_watchdog(void *);
-static const struct usb2_config aue_config[AUE_ENDPT_MAX] = {
+static const struct usb2_config aue_config[AUE_N_TRANSFER] = {
- [0] = {
+ [AUE_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -237,7 +237,7 @@ static const struct usb2_config aue_config[AUE_ENDPT_MAX] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [1] = {
+ [AUE_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -246,7 +246,7 @@ static const struct usb2_config aue_config[AUE_ENDPT_MAX] = {
.mh.callback = &aue_bulk_read_callback,
},
- [2] = {
+ [AUE_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -257,7 +257,7 @@ static const struct usb2_config aue_config[AUE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [AUE_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -268,7 +268,7 @@ static const struct usb2_config aue_config[AUE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [AUE_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -277,7 +277,7 @@ static const struct usb2_config aue_config[AUE_ENDPT_MAX] = {
.mh.callback = &aue_intr_callback,
},
- [5] = {
+ [AUE_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -752,9 +752,6 @@ aue_attach(device_t dev)
int32_t error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -774,7 +771,7 @@ aue_attach(device_t dev)
iface_index = AUE_IFACE_IDX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, aue_config, AUE_ENDPT_MAX,
+ sc->sc_xfer, aue_config, AUE_N_TRANSFER,
sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB "
@@ -834,7 +831,6 @@ aue_cfg_first_time_setup(struct aue_softc *sc,
sc->sc_name);
goto done;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "aue", sc->sc_unit);
@@ -917,7 +913,7 @@ aue_detach(device_t dev)
mtx_unlock(&sc->sc_mtx);
/* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, AUE_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, AUE_N_TRANSFER);
/* get rid of any late children */
bus_generic_detach(dev);
@@ -939,7 +935,7 @@ static void
aue_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct aue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[AUE_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -973,7 +969,7 @@ aue_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
if (sc->sc_flags & AUE_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[AUE_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -984,7 +980,7 @@ aue_intr_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= AUE_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[AUE_INTR_CS_RD]);
}
return;
}
@@ -994,7 +990,7 @@ static void
aue_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct aue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[AUE_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1061,7 +1057,7 @@ aue_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & AUE_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[AUE_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -1083,7 +1079,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= AUE_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[AUE_BULK_CS_RD]);
}
DPRINTF("bulk read error, %s\n",
usb2_errstr(xfer->error));
@@ -1096,7 +1092,7 @@ static void
aue_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct aue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[AUE_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1122,7 +1118,7 @@ aue_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & AUE_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[AUE_BULK_CS_WR]);
goto done;
}
if (sc->sc_flags & AUE_FLAG_WAIT_LINK) {
@@ -1185,7 +1181,7 @@ done:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= AUE_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[AUE_BULK_CS_WR]);
}
ifp->if_oerrors++;
return;
@@ -1274,9 +1270,9 @@ aue_start_transfers(struct aue_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[4]);
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[AUE_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[AUE_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[AUE_BULK_DT_WR]);
}
}
@@ -1504,12 +1500,12 @@ aue_cfg_pre_stop(struct aue_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[4]);
- usb2_transfer_stop(sc->sc_xfer[5]);
+ usb2_transfer_stop(sc->sc_xfer[AUE_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[AUE_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[AUE_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[AUE_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[AUE_INTR_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[AUE_INTR_CS_RD]);
}
static void
diff --git a/sys/dev/usb2/ethernet/if_aue2_reg.h b/sys/dev/usb2/ethernet/if_auereg.h
index 8111b7a..7d41927 100644
--- a/sys/dev/usb2/ethernet/if_aue2_reg.h
+++ b/sys/dev/usb2/ethernet/if_auereg.h
@@ -60,7 +60,15 @@
* don't match those in the ADMtek Pegasus manual: we consider the RX data
* endpoint to be index 0 and work up from there.
*/
-#define AUE_ENDPT_MAX 6
+enum {
+ AUE_BULK_DT_WR,
+ AUE_BULK_DT_RD,
+ AUE_BULK_CS_WR,
+ AUE_BULK_CS_RD,
+ AUE_INTR_DT_RD,
+ AUE_INTR_CS_RD,
+ AUE_N_TRANSFER = 6,
+};
#define AUE_INTR_PKTLEN 0x8
@@ -196,18 +204,16 @@ struct aue_rxpkt {
uint8_t aue_rxstat;
} __packed;
-
struct aue_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct usb2_config_td sc_config_td;
struct usb2_callout sc_watchdog;
struct mtx sc_mtx;
struct aue_rxpkt sc_rxpkt;
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[AUE_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[AUE_N_TRANSFER];
device_t sc_miibus;
device_t sc_dev;
diff --git a/sys/dev/usb2/ethernet/if_axe2.c b/sys/dev/usb2/ethernet/if_axe2.c
index 0231235..dd154c0 100644
--- a/sys/dev/usb2/ethernet/if_axe2.c
+++ b/sys/dev/usb2/ethernet/if_axe2.c
@@ -101,7 +101,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_axe2_reg.h>
+#include <dev/usb2/ethernet/if_axereg.h>
MODULE_DEPEND(axe, usb2_ethernet, 1, 1, 1);
MODULE_DEPEND(axe, usb2_core, 1, 1, 1);
@@ -186,10 +186,11 @@ static void axe_cfg_cmd(struct axe_softc *, uint16_t, uint16_t, uint16_t,
void *);
static void axe_cfg_ax88178_init(struct axe_softc *);
static void axe_cfg_ax88772_init(struct axe_softc *);
+static int axe_get_phyno(struct axe_softc *, int);
-static const struct usb2_config axe_config[AXE_ENDPT_MAX] = {
+static const struct usb2_config axe_config[AXE_N_TRANSFER] = {
- [0] = {
+ [AXE_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -199,7 +200,7 @@ static const struct usb2_config axe_config[AXE_ENDPT_MAX] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [1] = {
+ [AXE_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -212,7 +213,7 @@ static const struct usb2_config axe_config[AXE_ENDPT_MAX] = {
.mh.timeout = 0, /* no timeout */
},
- [2] = {
+ [AXE_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -223,7 +224,7 @@ static const struct usb2_config axe_config[AXE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [AXE_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -234,7 +235,7 @@ static const struct usb2_config axe_config[AXE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [AXE_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -243,7 +244,7 @@ static const struct usb2_config axe_config[AXE_ENDPT_MAX] = {
.mh.callback = &axe_intr_callback,
},
- [5] = {
+ [AXE_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -335,34 +336,26 @@ axe_cfg_miibus_readreg(device_t dev, int phy, int reg)
do_unlock = 1;
}
-#if 0
- /*
- * The chip tells us the MII address of any supported
- * PHYs attached to the chip, so only read from those.
- */
-
- if ((sc->sc_phyaddrs[0] != AXE_NOPHY) && (phy != sc->sc_phyaddrs[0])) {
- val = 0;
- goto done;
- }
- if ((sc->sc_phyaddrs[1] != AXE_NOPHY) && (phy != sc->sc_phyaddrs[1])) {
- val = 0;
- goto done;
- }
-#endif
- if ((sc->sc_phyaddrs[0] != 0xFF) && (sc->sc_phyaddrs[0] != phy)) {
+ if (sc->sc_phyno != phy) {
val = 0;
goto done;
}
+
axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
axe_cfg_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val);
axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
val = le16toh(val);
-
- if (val && (val != 0xffff)) {
- sc->sc_phyaddrs[0] = phy;
+ if ((sc->sc_flags & AXE_FLAG_772) != 0 && reg == MII_BMSR) {
+ /*
+ * BMSR of AX88772 indicates that it supports extended
+ * capability but the extended status register is
+ * revered for embedded ethernet PHY. So clear the
+ * extended capability bit of BMSR.
+ */
+ val &= ~BMSR_EXTCAP;
}
+
done:
if (do_unlock) {
mtx_unlock(&sc->sc_mtx);
@@ -386,10 +379,14 @@ axe_cfg_miibus_writereg(device_t dev, int phy, int reg, int val)
do_unlock = 1;
}
+ if (sc->sc_phyno != phy)
+ goto done;
+
axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
axe_cfg_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val);
axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
+done:
if (do_unlock) {
mtx_unlock(&sc->sc_mtx);
}
@@ -401,6 +398,7 @@ axe_cfg_miibus_statchg(device_t dev)
{
struct axe_softc *sc = device_get_softc(dev);
struct mii_data *mii = GET_MII(sc);
+ struct ifnet *ifp;
uint16_t val;
uint8_t do_unlock;
@@ -412,15 +410,40 @@ axe_cfg_miibus_statchg(device_t dev)
do_unlock = 1;
}
- if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
- val = AXE_MEDIA_FULL_DUPLEX;
- else
- val = 0;
+ ifp = sc->sc_ifp;
+ if (mii == NULL || ifp == NULL ||
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ goto done;
- if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
+ sc->sc_flags &= ~AXE_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:
+ case IFM_100_TX:
+ sc->sc_flags |= AXE_FLAG_LINK;
+ break;
+ case IFM_1000_T:
+ if ((sc->sc_flags & AXE_FLAG_178) == 0)
+ break;
+ sc->sc_flags |= AXE_FLAG_LINK;
+ break;
+ default:
+ break;
+ }
+ }
- val |= (AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC);
+ /* Lost link, do nothing. */
+ if ((sc->sc_flags & AXE_FLAG_LINK) == 0)
+ goto done;
+ val = 0;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ val |= AXE_MEDIA_FULL_DUPLEX;
+ if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
+ val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
+ if ((sc->sc_flags & AXE_FLAG_178) != 0)
+ val |= AXE_178_MEDIA_ENCK;
switch (IFM_SUBTYPE(mii->mii_media_active)) {
case IFM_1000_T:
val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
@@ -434,6 +457,7 @@ axe_cfg_miibus_statchg(device_t dev)
}
}
axe_cfg_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
+done:
if (do_unlock) {
mtx_unlock(&sc->sc_mtx);
}
@@ -467,7 +491,6 @@ axe_cfg_ifmedia_upd(struct axe_softc *sc,
/* not ready */
return;
}
- sc->sc_flags |= AXE_FLAG_WAIT_LINK;
if (mii->mii_instance) {
struct mii_softc *miisc;
@@ -550,6 +573,30 @@ axe_cfg_reset(struct axe_softc *sc)
err = usb2_config_td_sleep(&sc->sc_config_td, hz / 100);
}
+static int
+axe_get_phyno(struct axe_softc *sc, int sel)
+{
+ int phyno;
+
+ switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) {
+ case PHY_TYPE_100_HOME:
+ case PHY_TYPE_GIG:
+ phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]);
+ break;
+ case PHY_TYPE_SPECIAL:
+ /* FALLTHROUGH */
+ case PHY_TYPE_RSVD:
+ /* FALLTHROUGH */
+ case PHY_TYPE_NON_SUP:
+ /* FALLTHROUGH */
+ default:
+ phyno = -1;
+ break;
+ }
+
+ return (phyno);
+}
+
/*
* Probe for a AX88172 chip.
*/
@@ -582,9 +629,6 @@ axe_attach(device_t dev)
int32_t error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -601,7 +645,7 @@ axe_attach(device_t dev)
iface_index = AXE_IFACE_IDX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, axe_config, AXE_ENDPT_MAX,
+ sc->sc_xfer, axe_config, AXE_N_TRANSFER,
sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB "
@@ -617,8 +661,6 @@ axe_attach(device_t dev)
}
mtx_lock(&sc->sc_mtx);
- sc->sc_flags |= AXE_FLAG_WAIT_LINK;
-
/* start setup */
usb2_config_td_queue_command
@@ -687,6 +729,9 @@ axe_cfg_ax88178_init(struct axe_softc *sc)
axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4);
+ /* Enable MII/GMII/RGMII interface to work with external PHY. */
+ axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
+ err = usb2_config_td_sleep(&sc->sc_config_td, hz / 4);
axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
}
@@ -701,7 +746,7 @@ axe_cfg_ax88772_init(struct axe_softc *sc)
axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
err = usb2_config_td_sleep(&sc->sc_config_td, hz / 16);
- if (sc->sc_phyaddrs[1] == AXE_INTPHY) {
+ if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) {
/* ask for the embedded PHY */
axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
err = usb2_config_td_sleep(&sc->sc_config_td, hz / 64);
@@ -752,6 +797,19 @@ axe_cfg_first_time_setup(struct axe_softc *sc,
* Load PHY indexes first. Needed by axe_xxx_init().
*/
axe_cfg_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs);
+#if 1
+ device_printf(sc->sc_dev, "PHYADDR 0x%02x:0x%02x\n",
+ sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]);
+#endif
+ sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
+ if (sc->sc_phyno == -1)
+ sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);
+ if (sc->sc_phyno == -1) {
+ device_printf(sc->sc_dev,
+ "no valid PHY address found, "
+ "assuming PHY address 0\n");
+ sc->sc_phyno = 0;
+ }
if (sc->sc_flags & AXE_FLAG_178) {
axe_cfg_ax88178_init(sc);
@@ -771,12 +829,6 @@ axe_cfg_first_time_setup(struct axe_softc *sc,
*/
axe_cfg_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
- /*
- * Work around broken adapters that appear to lie about
- * their PHY addresses.
- */
- sc->sc_phyaddrs[0] = sc->sc_phyaddrs[1] = 0xFF;
-
mtx_unlock(&sc->sc_mtx);
ifp = if_alloc(IFT_ETHER);
@@ -788,7 +840,6 @@ axe_cfg_first_time_setup(struct axe_softc *sc,
sc->sc_name);
goto done;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "axe", sc->sc_unit);
@@ -858,7 +909,7 @@ axe_detach(device_t dev)
mtx_unlock(&sc->sc_mtx);
/* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, AXE_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER);
/* get rid of any late children */
bus_generic_detach(dev);
@@ -880,7 +931,7 @@ static void
axe_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct axe_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[AXE_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -901,7 +952,7 @@ axe_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & AXE_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[AXE_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -912,7 +963,7 @@ axe_intr_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= AXE_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[AXE_INTR_CS_RD]);
}
return;
}
@@ -922,7 +973,7 @@ static void
axe_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct axe_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[AXE_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1028,7 +1079,7 @@ axe_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & AXE_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -1061,7 +1112,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= AXE_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_RD]);
}
DPRINTF("bulk read error, %s\n",
usb2_errstr(xfer->error));
@@ -1074,7 +1125,7 @@ static void
axe_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct axe_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[AXE_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1105,10 +1156,10 @@ axe_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & AXE_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_WR]);
goto done;
}
- if (sc->sc_flags & AXE_FLAG_WAIT_LINK) {
+ if ((sc->sc_flags & AXE_FLAG_LINK) == 0) {
/*
* don't send anything if there is no link !
*/
@@ -1183,7 +1234,7 @@ done:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= AXE_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[AXE_BULK_CS_WR]);
}
ifp->if_oerrors++;
return;
@@ -1204,19 +1255,17 @@ axe_cfg_tick(struct axe_softc *sc,
return;
}
mii_tick(mii);
-
- mii_pollstat(mii);
-
- if ((sc->sc_flags & AXE_FLAG_WAIT_LINK) &&
- (mii->mii_media_status & IFM_ACTIVE) &&
- (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
- sc->sc_flags &= ~AXE_FLAG_WAIT_LINK;
- }
sc->sc_media_active = mii->mii_media_active;
sc->sc_media_status = mii->mii_media_status;
-
+ if ((sc->sc_flags & AXE_FLAG_LINK) == 0) {
+ axe_cfg_miibus_statchg(sc->sc_dev);
+ /* XXX */
+ if ((sc->sc_flags & AXE_FLAG_LINK) == 0) {
+ sc->sc_media_active = IFM_ETHER | IFM_NONE;
+ sc->sc_media_status = IFM_AVALID;
+ }
+ }
/* start stopped transfers, if any */
-
axe_start_transfers(sc);
}
@@ -1241,9 +1290,9 @@ axe_start_transfers(struct axe_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[4]);
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[AXE_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]);
}
}
@@ -1444,17 +1493,17 @@ axe_cfg_pre_stop(struct axe_softc *sc,
sc->sc_flags &= ~(AXE_FLAG_HL_READY |
AXE_FLAG_LL_READY);
- sc->sc_flags |= AXE_FLAG_WAIT_LINK;
+ sc->sc_flags &= ~AXE_FLAG_LINK;
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[4]);
- usb2_transfer_stop(sc->sc_xfer[5]);
+ usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[AXE_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[AXE_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[AXE_INTR_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[AXE_INTR_CS_RD]);
}
static void
diff --git a/sys/dev/usb2/ethernet/if_axe2_reg.h b/sys/dev/usb2/ethernet/if_axereg.h
index 9228f77..ac3a3d0 100644
--- a/sys/dev/usb2/ethernet/if_axe2_reg.h
+++ b/sys/dev/usb2/ethernet/if_axereg.h
@@ -135,8 +135,23 @@
#define AXE_178_RXCMD_MFB_8192 0x0200
#define AXE_178_RXCMD_MFB_16384 0x0300
-#define AXE_NOPHY 0xE0
-#define AXE_INTPHY 0x10
+#define AXE_PHY_SEL_PRI 1
+#define AXE_PHY_SEL_SEC 0
+#define AXE_PHY_TYPE_MASK 0xE0
+#define AXE_PHY_TYPE_SHIFT 5
+#define AXE_PHY_TYPE(x) \
+ (((x) & AXE_PHY_TYPE_MASK) >> AXE_PHY_TYPE_SHIFT)
+
+#define PHY_TYPE_100_HOME 0 /* 10/100 or 1M HOME PHY */
+#define PHY_TYPE_GIG 1 /* Gigabit PHY */
+#define PHY_TYPE_SPECIAL 4 /* Special case */
+#define PHY_TYPE_RSVD 5 /* Reserved */
+#define PHY_TYPE_NON_SUP 7 /* Non-supported PHY */
+
+#define AXE_PHY_NO_MASK 0x1F
+#define AXE_PHY_NO(x) ((x) & AXE_PHY_NO_MASK)
+
+#define AXE_772_PHY_NO_EPHY 0x10 /* Embedded 10/100 PHY of AX88772 */
#define AXE_BULK_BUF_SIZE 16384 /* bytes */
@@ -146,9 +161,6 @@
#define AXE_CONFIG_IDX 0 /* config number 1 */
#define AXE_IFACE_IDX 0
-/* The interrupt endpoint is currently unused by the ASIX part. */
-#define AXE_ENDPT_MAX 6
-
struct axe_sframe_hdr {
uint16_t len;
uint16_t ilen;
@@ -157,25 +169,37 @@ struct axe_sframe_hdr {
#define GET_MII(sc) ((sc)->sc_miibus ? \
device_get_softc((sc)->sc_miibus) : NULL)
+/* The interrupt endpoint is currently unused by the ASIX part. */
+enum {
+ AXE_BULK_DT_WR,
+ AXE_BULK_DT_RD,
+ AXE_BULK_CS_WR,
+ AXE_BULK_CS_RD,
+ AXE_INTR_DT_RD,
+ AXE_INTR_CS_RD,
+ AXE_N_TRANSFER = 6,
+};
+
struct axe_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct usb2_config_td sc_config_td;
struct usb2_callout sc_watchdog;
struct mtx sc_mtx;
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[AXE_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[AXE_N_TRANSFER];
device_t sc_miibus;
device_t sc_dev;
+ int sc_phyno;
+
uint32_t sc_unit;
uint32_t sc_media_active;
uint32_t sc_media_status;
uint16_t sc_flags;
-#define AXE_FLAG_WAIT_LINK 0x0001
+#define AXE_FLAG_LINK 0x0001
#define AXE_FLAG_INTR_STALL 0x0002
#define AXE_FLAG_READ_STALL 0x0004
#define AXE_FLAG_WRITE_STALL 0x0008
diff --git a/sys/dev/usb2/ethernet/if_cdce2.c b/sys/dev/usb2/ethernet/if_cdce2.c
index 81e8a92..89081d7e 100644
--- a/sys/dev/usb2/ethernet/if_cdce2.c
+++ b/sys/dev/usb2/ethernet/if_cdce2.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_device.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_cdce2_reg.h>
+#include <dev/usb2/ethernet/if_cdcereg.h>
static device_probe_t cdce_probe;
static device_attach_t cdce_attach;
@@ -103,7 +103,7 @@ SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, force_512x4, CTLFLAG_RW,
static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = {
- [0] = {
+ [CDCE_BULK_A] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -122,7 +122,7 @@ static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = {
.md.timeout = 0, /* no timeout */
},
- [1] = {
+ [CDCE_BULK_B] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -141,7 +141,7 @@ static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = {
.md.timeout = 10000, /* 10 seconds */
},
- [2] = {
+ [CDCE_INTR] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -231,9 +231,6 @@ cdce_attach(device_t dev)
uint8_t eaddr[ETHER_ADDR_LEN];
char eaddr_str[5 * ETHER_ADDR_LEN]; /* approx */
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -444,7 +441,6 @@ alloc_transfers:
device_printf(dev, "cannot if_alloc()\n");
goto detach;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "cdce", sc->sc_unit);
@@ -474,7 +470,7 @@ alloc_transfers:
/* start the interrupt transfer, if any */
mtx_lock(&sc->sc_mtx);
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[CDCE_INTR]);
mtx_unlock(&sc->sc_mtx);
return (0); /* success */
@@ -535,8 +531,8 @@ cdce_start_transfers(struct cdce_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[CDCE_BULK_B]);
+ usb2_transfer_start(sc->sc_xfer[CDCE_BULK_A]);
}
}
@@ -853,8 +849,8 @@ cdce_stop(struct cdce_softc *sc)
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_A]);
+ usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_B]);
}
static int
@@ -939,8 +935,8 @@ cdce_init_cb(void *arg)
CDCE_FLAG_LL_READY |
CDCE_FLAG_HL_READY);
- usb2_transfer_set_stall(sc->sc_xfer[0]);
- usb2_transfer_set_stall(sc->sc_xfer[1]);
+ usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_A]);
+ usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_B]);
cdce_start_transfers(sc);
diff --git a/sys/dev/usb2/ethernet/if_cdce2_reg.h b/sys/dev/usb2/ethernet/if_cdcereg.h
index 3b5f45d..277b7d0 100644
--- a/sys/dev/usb2/ethernet/if_cdce2_reg.h
+++ b/sys/dev/usb2/ethernet/if_cdcereg.h
@@ -35,7 +35,6 @@
#ifndef _USB_IF_CDCEREG_H_
#define _USB_IF_CDCEREG_H_
-#define CDCE_N_TRANSFER 3 /* units */
#define CDCE_IND_SIZE_MAX 32 /* bytes */
#define CDCE_512X4_IFQ_MAXLEN MAX((2*CDCE_512X4_FRAMES_MAX), IFQ_MAXLEN)
@@ -54,8 +53,15 @@ struct cdce_mq { /* mini-queue */
uint16_t ifq_len;
};
+enum {
+ CDCE_BULK_A,
+ CDCE_BULK_B,
+ CDCE_INTR,
+ CDCE_N_TRANSFER = 3,
+};
+
struct cdce_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
union cdce_eth_tx sc_tx;
union cdce_eth_rx sc_rx;
@@ -64,7 +70,6 @@ struct cdce_softc {
struct cdce_mq sc_rx_mq;
struct cdce_mq sc_tx_mq;
- struct ifnet *sc_ifp;
struct usb2_xfer *sc_xfer[CDCE_N_TRANSFER];
struct usb2_device *sc_udev;
device_t sc_dev;
diff --git a/sys/dev/usb2/ethernet/if_cue2.c b/sys/dev/usb2/ethernet/if_cue2.c
index 872af03..9a765d8 100644
--- a/sys/dev/usb2/ethernet/if_cue2.c
+++ b/sys/dev/usb2/ethernet/if_cue2.c
@@ -76,7 +76,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_cue2_reg.h>
+#include <dev/usb2/ethernet/if_cuereg.h>
/*
* Various supported device vendors/products.
@@ -135,9 +135,9 @@ SYSCTL_INT(_hw_usb2_cue, OID_AUTO, debug, CTLFLAG_RW, &cue_debug, 0,
"Debug level");
#endif
-static const struct usb2_config cue_config[CUE_ENDPT_MAX] = {
+static const struct usb2_config cue_config[CUE_N_TRANSFER] = {
- [0] = {
+ [CUE_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -147,7 +147,7 @@ static const struct usb2_config cue_config[CUE_ENDPT_MAX] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [1] = {
+ [CUE_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -156,7 +156,7 @@ static const struct usb2_config cue_config[CUE_ENDPT_MAX] = {
.mh.callback = &cue_bulk_read_callback,
},
- [2] = {
+ [CUE_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -167,7 +167,7 @@ static const struct usb2_config cue_config[CUE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [CUE_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -397,9 +397,6 @@ cue_attach(device_t dev)
uint8_t iface_index;
int32_t error;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -412,7 +409,7 @@ cue_attach(device_t dev)
iface_index = CUE_IFACE_IDX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, cue_config, CUE_ENDPT_MAX, sc, &sc->sc_mtx);
+ sc->sc_xfer, cue_config, CUE_N_TRANSFER, sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB "
"transfers failed!\n");
@@ -468,7 +465,6 @@ cue_cfg_first_time_setup(struct cue_softc *sc,
sc->sc_unit);
goto done;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "cue", sc->sc_unit);
@@ -514,7 +510,7 @@ cue_detach(device_t dev)
mtx_unlock(&sc->sc_mtx);
/* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, CUE_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, CUE_N_TRANSFER);
/* get rid of any late children */
bus_generic_detach(dev);
@@ -536,7 +532,7 @@ static void
cue_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct cue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[CUE_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -586,7 +582,7 @@ cue_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & CUE_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[CUE_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -608,7 +604,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= CUE_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[CUE_BULK_CS_RD]);
}
DPRINTF("bulk read error, %s\n",
usb2_errstr(xfer->error));
@@ -660,8 +656,8 @@ cue_start_transfers(struct cue_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[CUE_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[CUE_BULK_DT_WR]);
}
}
@@ -669,7 +665,7 @@ static void
cue_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct cue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[CUE_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -695,7 +691,7 @@ cue_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & CUE_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[CUE_BULK_CS_WR]);
goto done;
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
@@ -738,7 +734,7 @@ done:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= CUE_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[CUE_BULK_CS_WR]);
}
ifp->if_oerrors++;
return;
@@ -904,10 +900,10 @@ cue_cfg_pre_stop(struct cue_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
+ usb2_transfer_stop(sc->sc_xfer[CUE_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[CUE_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[CUE_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[CUE_BULK_CS_RD]);
}
static void
diff --git a/sys/dev/usb2/ethernet/if_cue2_reg.h b/sys/dev/usb2/ethernet/if_cuereg.h
index 5517876..d277a41 100644
--- a/sys/dev/usb2/ethernet/if_cue2_reg.h
+++ b/sys/dev/usb2/ethernet/if_cuereg.h
@@ -113,19 +113,24 @@
#define CUE_IFACE_IDX 0
/* The interrupt endpoint is currently unused by the KLSI part. */
-#define CUE_ENDPT_MAX 4
+enum {
+ CUE_BULK_DT_WR,
+ CUE_BULK_DT_RD,
+ CUE_BULK_CS_WR,
+ CUE_BULK_CS_RD,
+ CUE_N_TRANSFER = 4,
+};
struct cue_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct usb2_config_td sc_config_td;
struct usb2_callout sc_watchdog;
struct mtx sc_mtx;
- struct ifnet *sc_ifp;
device_t sc_dev;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[CUE_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[CUE_N_TRANSFER];
uint32_t sc_unit;
diff --git a/sys/dev/usb2/ethernet/if_kue2.c b/sys/dev/usb2/ethernet/if_kue2.c
index 060ee1e..b4e6bbe 100644
--- a/sys/dev/usb2/ethernet/if_kue2.c
+++ b/sys/dev/usb2/ethernet/if_kue2.c
@@ -90,8 +90,8 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_kue2_reg.h>
-#include <dev/usb2/ethernet/if_kue2_fw.h>
+#include <dev/usb2/ethernet/if_kuereg.h>
+#include <dev/usb2/ethernet/if_kuefw.h>
/*
* Various supported device vendors/products.
@@ -175,9 +175,9 @@ SYSCTL_INT(_hw_usb2_kue, OID_AUTO, debug, CTLFLAG_RW, &kue_debug, 0,
"Debug level");
#endif
-static const struct usb2_config kue_config[KUE_ENDPT_MAX] = {
+static const struct usb2_config kue_config[KUE_N_TRANSFER] = {
- [0] = {
+ [KUE_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -187,7 +187,7 @@ static const struct usb2_config kue_config[KUE_ENDPT_MAX] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [1] = {
+ [KUE_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -197,7 +197,7 @@ static const struct usb2_config kue_config[KUE_ENDPT_MAX] = {
.mh.timeout = 0, /* no timeout */
},
- [2] = {
+ [KUE_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -208,7 +208,7 @@ static const struct usb2_config kue_config[KUE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [KUE_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -459,9 +459,6 @@ kue_attach(device_t dev)
int32_t error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -474,7 +471,7 @@ kue_attach(device_t dev)
iface_index = KUE_IFACE_IDX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, kue_config, KUE_ENDPT_MAX, sc, &sc->sc_mtx);
+ sc->sc_xfer, kue_config, KUE_N_TRANSFER, sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB "
"transfers failed!\n");
@@ -536,7 +533,6 @@ kue_cfg_first_time_setup(struct kue_softc *sc,
sc->sc_unit);
goto done;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "kue", sc->sc_unit);
@@ -581,7 +577,7 @@ kue_detach(device_t dev)
mtx_unlock(&sc->sc_mtx);
/* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, KUE_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, KUE_N_TRANSFER);
/* get rid of any late children */
bus_generic_detach(dev);
@@ -607,7 +603,7 @@ static void
kue_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct kue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[KUE_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -657,7 +653,7 @@ kue_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & KUE_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[KUE_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -679,7 +675,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= KUE_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[KUE_BULK_CS_RD]);
}
DPRINTF("bulk read error, %s\n",
usb2_errstr(xfer->error));
@@ -692,7 +688,7 @@ static void
kue_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct kue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[KUE_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -720,7 +716,7 @@ kue_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & KUE_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[KUE_BULK_CS_WR]);
goto done;
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
@@ -769,7 +765,7 @@ done:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= KUE_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[KUE_BULK_CS_WR]);
}
ifp->if_oerrors++;
return;
@@ -798,8 +794,8 @@ kue_start_transfers(struct kue_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[KUE_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[KUE_BULK_DT_WR]);
}
}
@@ -956,10 +952,10 @@ kue_cfg_pre_stop(struct kue_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
+ usb2_transfer_stop(sc->sc_xfer[KUE_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[KUE_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[KUE_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[KUE_BULK_CS_RD]);
}
static void
diff --git a/sys/dev/usb2/ethernet/if_kue2_fw.h b/sys/dev/usb2/ethernet/if_kuefw.h
index 2b055a9..2b055a9 100644
--- a/sys/dev/usb2/ethernet/if_kue2_fw.h
+++ b/sys/dev/usb2/ethernet/if_kuefw.h
diff --git a/sys/dev/usb2/ethernet/if_kue2_reg.h b/sys/dev/usb2/ethernet/if_kuereg.h
index 989d125..6c0a24d 100644
--- a/sys/dev/usb2/ethernet/if_kue2_reg.h
+++ b/sys/dev/usb2/ethernet/if_kuereg.h
@@ -116,19 +116,25 @@ struct kue_ether_desc {
/* The interrupt endpoint is currently unused by the KLSI part. */
#define KUE_ENDPT_MAX 4
+enum {
+ KUE_BULK_DT_WR,
+ KUE_BULK_DT_RD,
+ KUE_BULK_CS_WR,
+ KUE_BULK_CS_RD,
+ KUE_N_TRANSFER = 4,
+};
struct kue_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct usb2_config_td sc_config_td;
struct usb2_callout sc_watchdog;
struct mtx sc_mtx;
struct kue_ether_desc sc_desc;
- struct ifnet *sc_ifp;
device_t sc_dev;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[KUE_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[KUE_N_TRANSFER];
uint32_t sc_unit;
diff --git a/sys/dev/usb2/ethernet/if_rue2.c b/sys/dev/usb2/ethernet/if_rue2.c
index 5c788cb..93e306f 100644
--- a/sys/dev/usb2/ethernet/if_rue2.c
+++ b/sys/dev/usb2/ethernet/if_rue2.c
@@ -90,7 +90,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_rue2_reg.h>
+#include <dev/usb2/ethernet/if_ruereg.h>
#if USB_DEBUG
static int rue_debug = 0;
@@ -155,9 +155,9 @@ static void rue_ifmedia_sts_cb(struct ifnet *ifp, struct ifmediareq *ifmr);
static int rue_ioctl_cb(struct ifnet *ifp, u_long command, caddr_t data);
static void rue_watchdog(void *arg);
-static const struct usb2_config rue_config[RUE_ENDPT_MAX] = {
+static const struct usb2_config rue_config[RUE_N_TRANSFER] = {
- [0] = {
+ [RUE_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -167,7 +167,7 @@ static const struct usb2_config rue_config[RUE_ENDPT_MAX] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [1] = {
+ [RUE_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -177,7 +177,7 @@ static const struct usb2_config rue_config[RUE_ENDPT_MAX] = {
.mh.timeout = 0, /* no timeout */
},
- [2] = {
+ [RUE_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -188,7 +188,7 @@ static const struct usb2_config rue_config[RUE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [RUE_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -199,7 +199,7 @@ static const struct usb2_config rue_config[RUE_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [RUE_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -208,7 +208,7 @@ static const struct usb2_config rue_config[RUE_ENDPT_MAX] = {
.mh.callback = &rue_intr_callback,
},
- [5] = {
+ [RUE_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -637,9 +637,6 @@ rue_attach(device_t dev)
int32_t error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -655,7 +652,7 @@ rue_attach(device_t dev)
iface_index = RUE_IFACE_IDX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, rue_config, RUE_ENDPT_MAX,
+ sc->sc_xfer, rue_config, RUE_N_TRANSFER,
sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB "
@@ -713,7 +710,6 @@ rue_cfg_first_time_setup(struct rue_softc *sc,
sc->sc_name);
goto done;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "rue", sc->sc_unit);
@@ -784,7 +780,7 @@ rue_detach(device_t dev)
mtx_unlock(&sc->sc_mtx);
/* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, RUE_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, RUE_N_TRANSFER);
/* get rid of any late children */
bus_generic_detach(dev);
@@ -806,7 +802,7 @@ static void
rue_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct rue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[RUE_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -836,7 +832,7 @@ rue_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
if (sc->sc_flags & RUE_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[RUE_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -847,7 +843,7 @@ rue_intr_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= RUE_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[RUE_INTR_CS_RD]);
}
return;
}
@@ -857,7 +853,7 @@ static void
rue_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct rue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[RUE_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -916,7 +912,7 @@ rue_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & RUE_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[RUE_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -938,7 +934,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= RUE_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[RUE_BULK_CS_RD]);
}
DPRINTF("bulk read error, %s\n",
usb2_errstr(xfer->error));
@@ -951,7 +947,7 @@ static void
rue_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct rue_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[RUE_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -977,7 +973,7 @@ rue_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & RUE_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[RUE_BULK_CS_WR]);
goto done;
}
if (sc->sc_flags & RUE_FLAG_WAIT_LINK) {
@@ -1031,7 +1027,7 @@ done:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= RUE_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[RUE_BULK_CS_WR]);
}
ifp->if_oerrors++;
return;
@@ -1089,9 +1085,9 @@ rue_start_transfers(struct rue_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[4]);
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[RUE_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[RUE_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[RUE_BULK_DT_WR]);
}
}
@@ -1325,12 +1321,12 @@ rue_cfg_pre_stop(struct rue_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[4]);
- usb2_transfer_stop(sc->sc_xfer[5]);
+ usb2_transfer_stop(sc->sc_xfer[RUE_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[RUE_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[RUE_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[RUE_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[RUE_INTR_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[RUE_INTR_CS_RD]);
}
static void
diff --git a/sys/dev/usb2/ethernet/if_rue2_reg.h b/sys/dev/usb2/ethernet/if_ruereg.h
index 2c95c22..6e5a885 100644
--- a/sys/dev/usb2/ethernet/if_rue2_reg.h
+++ b/sys/dev/usb2/ethernet/if_ruereg.h
@@ -29,8 +29,6 @@
#define RUE_CONFIG_IDX 0 /* config number 1 */
#define RUE_IFACE_IDX 0
-#define RUE_ENDPT_MAX 6
-
#define RUE_INTR_PKTLEN 0x8
#define RUE_TIMEOUT 50
@@ -165,16 +163,25 @@ struct rue_type {
uint16_t rue_did;
};
+enum {
+ RUE_BULK_DT_WR,
+ RUE_BULK_DT_RD,
+ RUE_BULK_CS_WR,
+ RUE_BULK_CS_RD,
+ RUE_INTR_DT_RD,
+ RUE_INTR_CS_RD,
+ RUE_N_TRANSFER = 6,
+};
+
struct rue_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct usb2_config_td sc_config_td;
struct usb2_callout sc_watchdog;
struct mtx sc_mtx;
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[RUE_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[RUE_N_TRANSFER];
device_t sc_miibus;
device_t sc_dev;
diff --git a/sys/dev/usb2/ethernet/if_udav2.c b/sys/dev/usb2/ethernet/if_udav2.c
index 2cc3596..a5fde41 100644
--- a/sys/dev/usb2/ethernet/if_udav2.c
+++ b/sys/dev/usb2/ethernet/if_udav2.c
@@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_udav2_reg.h>
+#include <dev/usb2/ethernet/if_udavreg.h>
/* prototypes */
@@ -118,9 +118,9 @@ static miibus_readreg_t udav_cfg_miibus_readreg;
static miibus_writereg_t udav_cfg_miibus_writereg;
static miibus_statchg_t udav_cfg_miibus_statchg;
-static const struct usb2_config udav_config[UDAV_ENDPT_MAX] = {
+static const struct usb2_config udav_config[UDAV_N_TRANSFER] = {
- [0] = {
+ [UDAV_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -130,7 +130,7 @@ static const struct usb2_config udav_config[UDAV_ENDPT_MAX] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [1] = {
+ [UDAV_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -140,7 +140,7 @@ static const struct usb2_config udav_config[UDAV_ENDPT_MAX] = {
.mh.timeout = 0, /* no timeout */
},
- [2] = {
+ [UDAV_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -151,7 +151,7 @@ static const struct usb2_config udav_config[UDAV_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UDAV_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -162,7 +162,7 @@ static const struct usb2_config udav_config[UDAV_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [UDAV_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -171,7 +171,7 @@ static const struct usb2_config udav_config[UDAV_ENDPT_MAX] = {
.mh.callback = &udav_intr_callback,
},
- [5] = {
+ [UDAV_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -267,9 +267,6 @@ udav_attach(device_t dev)
int32_t error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -286,7 +283,7 @@ udav_attach(device_t dev)
iface_index = UDAV_IFACE_INDEX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, udav_config, UDAV_ENDPT_MAX, sc, &sc->sc_mtx);
+ sc->sc_xfer, udav_config, UDAV_N_TRANSFER, sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB "
"transfers failed!\n");
@@ -344,7 +341,6 @@ udav_cfg_first_time_setup(struct udav_softc *sc,
sc->sc_name);
goto done;
}
- sc->sc_evilhack = ifp;
ifp->if_softc = sc;
if_initname(ifp, "udav", sc->sc_unit);
@@ -414,7 +410,7 @@ udav_detach(device_t dev)
mtx_unlock(&sc->sc_mtx);
/* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, UDAV_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, UDAV_N_TRANSFER);
/* get rid of any late children */
bus_generic_detach(dev);
@@ -754,9 +750,9 @@ udav_start_transfers(struct udav_softc *sc)
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[4]);
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_BULK_DT_WR]);
}
}
@@ -764,7 +760,7 @@ static void
udav_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct udav_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UDAV_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -792,7 +788,7 @@ udav_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & UDAV_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_BULK_CS_WR]);
goto done;
}
if (sc->sc_flags & UDAV_FLAG_WAIT_LINK) {
@@ -856,7 +852,7 @@ done:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= UDAV_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_BULK_CS_WR]);
}
ifp->if_oerrors++;
return;
@@ -868,7 +864,7 @@ static void
udav_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct udav_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UDAV_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -937,7 +933,7 @@ udav_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & UDAV_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -959,7 +955,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= UDAV_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_BULK_CS_RD]);
}
DPRINTF("bulk read error, %s\n",
usb2_errstr(xfer->error));
@@ -972,7 +968,7 @@ static void
udav_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct udav_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UDAV_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -991,7 +987,7 @@ udav_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & UDAV_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -1002,7 +998,7 @@ udav_intr_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= UDAV_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UDAV_INTR_CS_RD]);
}
return;
}
@@ -1106,12 +1102,12 @@ udav_cfg_pre_stop(struct udav_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[4]);
- usb2_transfer_stop(sc->sc_xfer[5]);
+ usb2_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UDAV_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UDAV_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UDAV_INTR_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UDAV_INTR_CS_RD]);
}
/*
diff --git a/sys/dev/usb2/ethernet/if_udav2_reg.h b/sys/dev/usb2/ethernet/if_udavreg.h
index aa211e6..32a3d08 100644
--- a/sys/dev/usb2/ethernet/if_udav2_reg.h
+++ b/sys/dev/usb2/ethernet/if_udavreg.h
@@ -34,8 +34,6 @@
#define UDAV_IFACE_INDEX 0
#define UDAV_CONFIG_INDEX 0 /* config number 1 */
-#define UDAV_ENDPT_MAX 6 /* units */
-
/* Packet length */
#define UDAV_MIN_FRAME_LEN 60
@@ -136,16 +134,25 @@
#define GET_MII(sc) ((sc)->sc_miibus ? \
device_get_softc((sc)->sc_miibus) : NULL)
+enum {
+ UDAV_BULK_DT_WR,
+ UDAV_BULK_DT_RD,
+ UDAV_BULK_CS_WR,
+ UDAV_BULK_CS_RD,
+ UDAV_INTR_DT_RD,
+ UDAV_INTR_CS_RD,
+ UDAV_N_TRANSFER = 6,
+};
+
struct udav_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct usb2_config_td sc_config_td;
struct usb2_callout sc_watchdog;
struct mtx sc_mtx;
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UDAV_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[UDAV_N_TRANSFER];
device_t sc_miibus;
device_t sc_dev;
diff --git a/sys/dev/usb2/image/uscanner2.c b/sys/dev/usb2/image/uscanner2.c
index fa939ef..1b0afdc 100644
--- a/sys/dev/usb2/image/uscanner2.c
+++ b/sys/dev/usb2/image/uscanner2.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -76,7 +75,6 @@ SYSCTL_INT(_hw_usb2_uscanner, OID_AUTO, debug, CTLFLAG_RW, &uscanner_debug,
*/
#define USCANNER_BSIZE (1 << 15)
#define USCANNER_IFQ_MAXLEN 2
-#define USCANNER_N_TRANSFER 4
/*
* Transfers stallings handling flags definition.
@@ -89,6 +87,14 @@ SYSCTL_INT(_hw_usb2_uscanner, OID_AUTO, debug, CTLFLAG_RW, &uscanner_debug,
*/
#define USCANNER_FLAG_KEEP_OPEN 0x04
+enum {
+ USCANNER_BULK_DT_WR,
+ USCANNER_BULK_DT_RD,
+ USCANNER_BULK_CS_WR,
+ USCANNER_BULK_CS_RD,
+ USCANNER_N_TRANSFER = 4,
+};
+
struct uscanner_softc {
struct usb2_fifo_sc sc_fifo;
struct mtx sc_mtx;
@@ -138,7 +144,7 @@ static struct usb2_fifo_methods uscanner_fifo_methods = {
* transfers.
*/
static const struct usb2_config uscanner_config[USCANNER_N_TRANSFER] = {
- [0] = {
+ [USCANNER_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -147,7 +153,7 @@ static const struct usb2_config uscanner_config[USCANNER_N_TRANSFER] = {
.mh.callback = &uscanner_write_callback,
},
- [1] = {
+ [USCANNER_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -156,7 +162,7 @@ static const struct usb2_config uscanner_config[USCANNER_N_TRANSFER] = {
.mh.callback = &uscanner_read_callback,
},
- [2] = {
+ [USCANNER_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -167,7 +173,7 @@ static const struct usb2_config uscanner_config[USCANNER_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [USCANNER_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00,
.direction = UE_DIR_ANY,
@@ -266,6 +272,7 @@ static const struct usb2_device_id uscanner_devs[] = {
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4100C, 0)},
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4200C, 0)},
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4300C, 0)},
+ {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4470C, 0)},
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4670V, 0)},
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_S20, 0)},
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_5200C, 0)},
@@ -450,7 +457,7 @@ uscanner_read_callback(struct usb2_xfer *xfer)
* solve the situation.
*/
if (sc->sc_flags & USCANNER_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_RD]);
break;
}
if (usb2_fifo_put_bytes_max(f) != 0) {
@@ -462,7 +469,7 @@ uscanner_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= USCANNER_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_RD]);
}
break;
}
@@ -475,7 +482,7 @@ static void
uscanner_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uscanner_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[USCANNER_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -505,7 +512,7 @@ uscanner_write_callback(struct usb2_xfer *xfer)
* solve the situation.
*/
if (sc->sc_flags & USCANNER_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_WR]);
break;
}
/*
@@ -521,7 +528,7 @@ uscanner_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= USCANNER_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_WR]);
}
break;
}
@@ -534,7 +541,7 @@ static void
uscanner_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uscanner_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[USCANNER_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -563,14 +570,14 @@ uscanner_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
}
if (fflags & FREAD) {
if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[1]->max_data_length,
+ sc->sc_xfer[USCANNER_BULK_DT_RD]->max_data_length,
USCANNER_IFQ_MAXLEN)) {
return (ENOMEM);
}
}
if (fflags & FWRITE) {
if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[0]->max_data_length,
+ sc->sc_xfer[USCANNER_BULK_DT_WR]->max_data_length,
USCANNER_IFQ_MAXLEN)) {
return (ENOMEM);
}
@@ -595,7 +602,7 @@ uscanner_start_read(struct usb2_fifo *fifo)
struct uscanner_softc *sc;
sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_DT_RD]);
}
/*
@@ -607,7 +614,7 @@ uscanner_start_write(struct usb2_fifo *fifo)
struct uscanner_softc *sc;
sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_DT_WR]);
}
/*
@@ -619,8 +626,8 @@ uscanner_stop_read(struct usb2_fifo *fifo)
struct uscanner_softc *sc;
sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_DT_RD]);
}
/*
@@ -632,6 +639,6 @@ uscanner_stop_write(struct usb2_fifo *fifo)
struct uscanner_softc *sc;
sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_DT_WR]);
}
diff --git a/sys/dev/usb2/include/usb2_defs.h b/sys/dev/usb2/include/usb2_defs.h
index d791f4d..64caf39 100644
--- a/sys/dev/usb2/include/usb2_defs.h
+++ b/sys/dev/usb2/include/usb2_defs.h
@@ -35,6 +35,10 @@
#define USB_EP_MAX (2*16) /* hardcoded */
#define USB_FIFO_MAX (4 * USB_EP_MAX)
+#define USB_ROOT_HUB_ADDR 1 /* index */
+
+#define USB_MIN_DEVICES 2 /* unused + root HUB */
+
#define USB_MAX_DEVICES USB_DEV_MAX /* including virtual root HUB and
* address zero */
#define USB_MAX_ENDPOINTS USB_EP_MAX /* 2 directions on 16 endpoints */
@@ -56,13 +60,18 @@
/* sanity checks */
#if (USB_FIFO_MAX < USB_EP_MAX)
-#error "Misconfigured limits #1"
+#error "There cannot be less FIFOs than USB endpoints."
#endif
#if (USB_FIFO_MAX & 1)
-#error "Misconfigured limits #2"
+#error "Number of FIFOs must be odd."
#endif
#if (USB_EP_MAX < (2*16))
-#error "Misconfigured limits #3"
+#error "Number of hardware USB endpoints cannot be less than 32."
+#endif
+#if (USB_MAX_DEVICES < USB_MIN_DEVICES)
+#error "Minimum number of devices is greater than maximum number of devices."
+#endif
+#if (USB_ROOT_HUB_ADDR >= USB_MIN_DEVICES)
+#error "The root hub address must be less than USB_MIN_DEVICES."
#endif
-
#endif /* _USB2_DEFS_H_ */
diff --git a/sys/dev/usb2/include/usb2_devid.h b/sys/dev/usb2/include/usb2_devid.h
index 08c4b71..8a39d82 100644
--- a/sys/dev/usb2/include/usb2_devid.h
+++ b/sys/dev/usb2/include/usb2_devid.h
@@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * FreeBSD: head/sys/dev/usb/usbdevs 185998 2008-12-12 18:34:27Z thompsa
+ * FreeBSD: head/sys/dev/usb/usbdevs 188234 2009-02-06 15:03:17Z kevlo
*/
/* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
@@ -158,6 +158,7 @@
#define USB_VENDOR_KYOCERA 0x0482 /* Kyocera Wireless Corp. */
#define USB_VENDOR_STMICRO 0x0483 /* STMicroelectronics */
#define USB_VENDOR_FOXCONN 0x0489 /* Foxconn */
+#define USB_VENDOR_MEIZU 0x0492 /* Meizu Electronics */
#define USB_VENDOR_YAMAHA 0x0499 /* YAMAHA */
#define USB_VENDOR_COMPAQ 0x049f /* Compaq */
#define USB_VENDOR_HITACHI 0x04a4 /* Hitachi */
@@ -533,6 +534,7 @@
#define USB_VENDOR_FOSSIL 0x0e67 /* Fossil, Inc */
#define USB_VENDOR_GMATE 0x0e7e /* G.Mate, Inc */
#define USB_VENDOR_OTI 0x0ea0 /* Ours Technology */
+#define USB_VENDOR_YISO 0x0eab /* Yiso Wireless Co. */
#define USB_VENDOR_PILOTECH 0x0eaf /* Pilotech */
#define USB_VENDOR_NOVATECH 0x0eb0 /* NovaTech */
#define USB_VENDOR_ITEGNO 0x0eba /* iTegno */
@@ -628,6 +630,7 @@
#define USB_VENDOR_LINKSYS3 0x1915 /* Linksys */
#define USB_VENDOR_QUALCOMMINC 0x19d2 /* Qualcomm, Incorporated */
#define USB_VENDOR_STELERA 0x1a8d /* Stelera Wireless */
+#define USB_VENDOR_DRESDENELEKTRONIK 0x1cf1 /* dresden elektronik */
#define USB_VENDOR_DLINK 0x2001 /* D-Link */
#define USB_VENDOR_PLANEX2 0x2019 /* Planex Communications */
#define USB_VENDOR_ERICSSON 0x2282 /* Ericsson */
@@ -814,6 +817,7 @@
/* Alcor Micro, Inc. products */
#define USB_PRODUCT_ALCOR2_KBD_HUB 0x2802 /* Kbd Hub */
+#define USB_PRODUCT_ALCOR_TRANSCEND 0x6387 /* Transcend JetFlash Drive */
#define USB_PRODUCT_ALCOR_MA_KBD_HUB 0x9213 /* MacAlly Kbd Hub */
#define USB_PRODUCT_ALCOR_AU9814 0x9215 /* AU9814 Hub */
#define USB_PRODUCT_ALCOR_UMCR_9361 0x9361 /* USB Multimedia Card Reader */
@@ -1173,6 +1177,9 @@
/* DrayTek products */
#define USB_PRODUCT_DRAYTEK_VIGOR550 0x0550 /* Vigor550 */
+/* dresden elektronik products */
+#define USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD 0x0001 /* SensorTerminalBoard */
+
/* Dynastream Innovations */
#define USB_PRODUCT_DYNASTREAM_ANTDEVBOARD 0x1003 /* ANT dev board */
@@ -1245,12 +1252,18 @@
#define USB_PRODUCT_EPSON_CX5400 0x0808 /* CX5400 scanner */
#define USB_PRODUCT_EPSON_3500 0x080e /* CX-3500/3600/3650 MFP */
#define USB_PRODUCT_EPSON_RX425 0x080f /* Stylus Photo RX425 scanner */
-#define USB_PRODUCT_EPSON_4800 0x0819 /* CX4800 MP scanner */
-#define USB_PRODUCT_EPSON_4200 0x0820 /* CX4200 MP scanner */
-#define USB_PRODUCT_EPSON_5000 0x082b /* DX-50x0 MFP scanner */
-#define USB_PRODUCT_EPSON_6000 0x082e /* DX-60x0 MFP scanner */
-#define USB_PRODUCT_EPSON_DX7400 0x0838 /* DX7400/CX7300 scanner */
-#define USB_PRODUCT_EPSON_DX8400 0x0839 /* DX8400 scanner */
+#define USB_PRODUCT_EPSON_DX3800 0x0818 /* CX3700/CX3800/DX38x0 MFP scanner */
+#define USB_PRODUCT_EPSON_4800 0x0819 /* CX4700/CX4800/DX48x0 MFP scanner */
+#define USB_PRODUCT_EPSON_4200 0x0820 /* CX4100/CX4200/DX4200 MFP scanner */
+#define USB_PRODUCT_EPSON_5000 0x082b /* CX4900/CX5000/DX50x0 MFP scanner */
+#define USB_PRODUCT_EPSON_6000 0x082e /* CX5900/CX6000/DX60x0 MFP scanner */
+#define USB_PRODUCT_EPSON_DX4000 0x082f /* DX4000 MFP scanner */
+#define USB_PRODUCT_EPSON_DX7400 0x0838 /* CX7300/CX7400/DX7400 MFP scanner */
+#define USB_PRODUCT_EPSON_DX8400 0x0839 /* CX8300/CX8400/DX8400 MFP scanner */
+#define USB_PRODUCT_EPSON_SX100 0x0841 /* SX100/NX100 MFP scanner */
+#define USB_PRODUCT_EPSON_NX300 0x0848 /* NX300 MFP scanner */
+#define USB_PRODUCT_EPSON_SX200 0x0849 /* SX200/SX205 MFP scanner */
+#define USB_PRODUCT_EPSON_SX400 0x084a /* SX400/NX400/TX400 MFP scanner */
/* e-TEK Labs products */
#define USB_PRODUCT_ETEK_1COM 0x8007 /* Serial */
@@ -1286,6 +1299,7 @@
#define USB_PRODUCT_FTDI_EMCU2D 0xe88a /* Expert mouseCLOCK USB II */
#define USB_PRODUCT_FTDI_PCMSFU 0xe88b /* Precision Clock MSF USB */
#define USB_PRODUCT_FTDI_EMCU2H 0xe88c /* Expert mouseCLOCK USB II HBG */
+#define USB_PRODUCT_FTDI_MAXSTREAM 0xee18 /* Maxstream PKG-U */
#define USB_PRODUCT_FTDI_USBSERIAL 0xfa00 /* Matrix Orbital USB Serial */
#define USB_PRODUCT_FTDI_MX2_3 0xfa01 /* Matrix Orbital MX2 or MX3 */
#define USB_PRODUCT_FTDI_MX4_5 0xfa02 /* Matrix Orbital MX4 or MX5 */
@@ -1423,6 +1437,7 @@
#define USB_PRODUCT_HP_2200C 0x0605 /* ScanJet 2200C */
#define USB_PRODUCT_HP_5300C 0x0701 /* Scanjet 5300C */
#define USB_PRODUCT_HP_4400C 0x0705 /* Scanjet 4400C */
+#define USB_PRODUCT_HP_4470C 0x0805 /* Scanjet 4470C */
#define USB_PRODUCT_HP_82x0C 0x0b01 /* Scanjet 82x0C */
#define USB_PRODUCT_HP_2300D 0x0b17 /* Laserjet 2300d */
#define USB_PRODUCT_HP_970CSE 0x1004 /* Deskjet 970Cse */
@@ -1500,6 +1515,7 @@
/* Ituner networks products */
#define USB_PRODUCT_ITUNERNET_USBLCD2X20 0x0002 /* USB-LCD 2x20 */
+#define USB_PRODUCT_ITUNERNET_USBLCD4X20 0xc001 /* USB-LCD 4x20 */
/* Jablotron products */
#define USB_PRODUCT_JABLOTRON_PC60B 0x0001 /* PC-60B */
@@ -1654,6 +1670,9 @@
#define USB_PRODUCT_MCT_USB232 0x0210 /* USB-232 Interface */
#define USB_PRODUCT_MCT_SITECOM_USB232 0x0230 /* Sitecom USB-232 Products */
+/* Meizu Electronics */
+#define USB_PRODUCT_MEIZU_M6_SL 0x0140 /* MiniPlayer M6 (SL) */
+
/* Melco, Inc products */
#define USB_PRODUCT_MELCO_LUATX1 0x0001 /* LUA-TX Ethernet */
#define USB_PRODUCT_MELCO_LUATX5 0x0005 /* LUA-TX Ethernet */
@@ -1669,6 +1688,7 @@
#define USB_PRODUCT_MELCO_SG54HP 0x00d8 /* WLI-U2-SG54HP */
#define USB_PRODUCT_MELCO_G54HP 0x00d9 /* WLI-U2-G54HP */
#define USB_PRODUCT_MELCO_KG54L 0x00da /* WLI-U2-KG54L */
+#define USB_PRODUCT_MELCO_SG54HG 0x00f4 /* WLI-U2-SG54HG */
/* Merlin products */
#define USB_PRODUCT_MERLIN_V620 0x1110 /* Merlin V620 */
@@ -1789,6 +1809,7 @@
/* Myson products */
#define USB_PRODUCT_MYSON_HEDEN 0x8818 /* USB-IDE */
+#define USB_PRODUCT_MYSON_STARREADER 0x9920 /* USB flash card adapter */
/* National Semiconductor */
#define USB_PRODUCT_NATIONAL_BEARPAW1200 0x1000 /* BearPaw 1200 */
@@ -1819,6 +1840,7 @@
#define USB_PRODUCT_NETGEAR_WG111V2_2 0x4240 /* PrismGT USB 2.0 WLAN */
#define USB_PRODUCT_NETGEAR_WG111U 0x4300 /* WG111U */
#define USB_PRODUCT_NETGEAR_WG111U_NF 0x4301 /* WG111U (no firmware) */
+#define USB_PRODUCT_NETGEAR_WG111V2 0x6a00 /* WG111V2 */
#define USB_PRODUCT_NETGEAR2_MA101 0x4100 /* MA101 */
#define USB_PRODUCT_NETGEAR2_MA101B 0x4102 /* MA101 Rev B */
#define USB_PRODUCT_NETGEAR3_WG111T 0x4250 /* WG111T */
@@ -2008,6 +2030,7 @@
#define USB_PRODUCT_QUALCOMM2_CDMA_MSM 0x3196 /* CDMA Technologies MSM modem */
#define USB_PRODUCT_QUALCOMMINC_CDMA_MSM 0x0001 /* CDMA Technologies MSM modem */
#define USB_PRODUCT_QUALCOMMINC_ZTE_STOR 0x2000 /* USB ZTE Storage */
+#define USB_PRODUCT_QUALCOMMINC_AC8700 0xfffe /* CDMA 1xEVDO USB modem */
/* Qtronix products */
#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */
@@ -2032,6 +2055,7 @@
/* ReakTek products */
/* Green House and CompUSA OEM this part */
#define USB_PRODUCT_REALTEK_USBKR100 0x8150 /* USBKR100 USB Ethernet */
+#define USB_PRODUCT_REALTEK_RTL8187 0x8187 /* RTL8187 Wireless Adapter */
/* Ricoh products */
#define USB_PRODUCT_RICOH_VGPVCC2 0x1830 /* VGP-VCC2 Camera */
@@ -2469,6 +2493,9 @@
#define USB_PRODUCT_YANO_U640MO 0x0101 /* U640MO-03 */
#define USB_PRODUCT_YANO_FW800HD 0x05fc /* METALWEAR-HDD */
+/* Yiso Wireless Co. products */
+#define USB_PRODUCT_YISO_C893 0xc893 /* CDMA 2000 1xEVDO PC Card */
+
/* Z-Com products */
#define USB_PRODUCT_ZCOM_M4Y750 0x0001 /* M4Y-750 */
#define USB_PRODUCT_ZCOM_XI725 0x0002 /* XI-725/726 */
diff --git a/sys/dev/usb2/include/usb2_devtable.h b/sys/dev/usb2/include/usb2_devtable.h
index e678540..ee67b68 100644
--- a/sys/dev/usb2/include/usb2_devtable.h
+++ b/sys/dev/usb2/include/usb2_devtable.h
@@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * FreeBSD: head/sys/dev/usb/usbdevs 185998 2008-12-12 18:34:27Z thompsa
+ * FreeBSD: head/sys/dev/usb/usbdevs 188234 2009-02-06 15:03:17Z kevlo
*/
/* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
@@ -623,6 +623,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Kbd Hub",
},
{
+ USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND,
+ 0,
+ "Alcor Micro",
+ "Transcend JetFlash Drive",
+ },
+ {
USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_MA_KBD_HUB,
0,
"Alcor Micro",
@@ -2021,6 +2027,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Vigor550",
},
{
+ USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD,
+ 0,
+ "dresden elektronik",
+ "SensorTerminalBoard",
+ },
+ {
USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD,
0,
"Dynastream Innovations",
@@ -2351,40 +2363,76 @@ const struct usb_knowndev usb_knowndevs[] = {
"Stylus Photo RX425 scanner",
},
{
+ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3800,
+ 0,
+ "Seiko Epson",
+ "CX3700/CX3800/DX38x0 MFP scanner",
+ },
+ {
USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4800,
0,
"Seiko Epson",
- "CX4800 MP scanner",
+ "CX4700/CX4800/DX48x0 MFP scanner",
},
{
USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4200,
0,
"Seiko Epson",
- "CX4200 MP scanner",
+ "CX4100/CX4200/DX4200 MFP scanner",
},
{
USB_VENDOR_EPSON, USB_PRODUCT_EPSON_5000,
0,
"Seiko Epson",
- "DX-50x0 MFP scanner",
+ "CX4900/CX5000/DX50x0 MFP scanner",
},
{
USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000,
0,
"Seiko Epson",
- "DX-60x0 MFP scanner",
+ "CX5900/CX6000/DX60x0 MFP scanner",
+ },
+ {
+ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX4000,
+ 0,
+ "Seiko Epson",
+ "DX4000 MFP scanner",
},
{
USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX7400,
0,
"Seiko Epson",
- "DX7400/CX7300 scanner",
+ "CX7300/CX7400/DX7400 MFP scanner",
},
{
USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX8400,
0,
"Seiko Epson",
- "DX8400 scanner",
+ "CX8300/CX8400/DX8400 MFP scanner",
+ },
+ {
+ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX100,
+ 0,
+ "Seiko Epson",
+ "SX100/NX100 MFP scanner",
+ },
+ {
+ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_NX300,
+ 0,
+ "Seiko Epson",
+ "NX300 MFP scanner",
+ },
+ {
+ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX200,
+ 0,
+ "Seiko Epson",
+ "SX200/SX205 MFP scanner",
+ },
+ {
+ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX400,
+ 0,
+ "Seiko Epson",
+ "SX400/NX400/TX400 MFP scanner",
},
{
USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM,
@@ -2495,6 +2543,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Expert mouseCLOCK USB II HBG",
},
{
+ USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MAXSTREAM,
+ 0,
+ "Future Technology Devices",
+ "Maxstream PKG-U",
+ },
+ {
USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBSERIAL,
0,
"Future Technology Devices",
@@ -3041,6 +3095,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Scanjet 4400C",
},
{
+ USB_VENDOR_HP, USB_PRODUCT_HP_4470C,
+ 0,
+ "Hewlett Packard",
+ "Scanjet 4470C",
+ },
+ {
USB_VENDOR_HP, USB_PRODUCT_HP_82x0C,
0,
"Hewlett Packard",
@@ -3347,6 +3407,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"USB-LCD 2x20",
},
{
+ USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20,
+ 0,
+ "I-Tuner Networks",
+ "USB-LCD 4x20",
+ },
+ {
USB_VENDOR_JABLOTRON, USB_PRODUCT_JABLOTRON_PC60B,
0,
"Jablotron",
@@ -3977,6 +4043,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Sitecom USB-232 Products",
},
{
+ USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL,
+ 0,
+ "Meizu Electronics",
+ "MiniPlayer M6 (SL)",
+ },
+ {
USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1,
0,
"Melco",
@@ -4061,6 +4133,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"WLI-U2-KG54L",
},
{
+ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG,
+ 0,
+ "Melco",
+ "WLI-U2-SG54HG",
+ },
+ {
USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620,
0,
"Merlin",
@@ -4541,6 +4619,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"USB-IDE",
},
{
+ USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER,
+ 0,
+ "Myson Technology",
+ "USB flash card adapter",
+ },
+ {
USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200,
0,
"National Semiconductor",
@@ -4649,6 +4733,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"WG111U (no firmware)",
},
{
+ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2,
+ 0,
+ "BayNETGEAR",
+ "WG111V2",
+ },
+ {
USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101,
0,
"Netgear",
@@ -5471,6 +5561,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"USB ZTE Storage",
},
{
+ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_AC8700,
+ 0,
+ "Qualcomm, Incorporated",
+ "CDMA 1xEVDO USB modem",
+ },
+ {
USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N,
0,
"Qtronix",
@@ -5537,6 +5633,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"USBKR100 USB Ethernet",
},
{
+ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187,
+ 0,
+ "Realtek",
+ "RTL8187 Wireless Adapter",
+ },
+ {
USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2,
0,
"Ricoh",
@@ -7145,6 +7247,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"METALWEAR-HDD",
},
{
+ USB_VENDOR_YISO, USB_PRODUCT_YISO_C893,
+ 0,
+ "Yiso Wireless Co.",
+ "CDMA 2000 1xEVDO PC Card",
+ },
+ {
USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750,
0,
"Z-Com",
@@ -7805,6 +7913,12 @@ const struct usb_knowndev usb_knowndevs[] = {
NULL,
},
{
+ USB_VENDOR_MEIZU, 0,
+ USB_KNOWNDEV_NOPROD,
+ "Meizu Electronics",
+ NULL,
+ },
+ {
USB_VENDOR_YAMAHA, 0,
USB_KNOWNDEV_NOPROD,
"YAMAHA",
@@ -10055,6 +10169,12 @@ const struct usb_knowndev usb_knowndevs[] = {
NULL,
},
{
+ USB_VENDOR_YISO, 0,
+ USB_KNOWNDEV_NOPROD,
+ "Yiso Wireless Co.",
+ NULL,
+ },
+ {
USB_VENDOR_PILOTECH, 0,
USB_KNOWNDEV_NOPROD,
"Pilotech",
@@ -10625,6 +10745,12 @@ const struct usb_knowndev usb_knowndevs[] = {
NULL,
},
{
+ USB_VENDOR_DRESDENELEKTRONIK, 0,
+ USB_KNOWNDEV_NOPROD,
+ "dresden elektronik",
+ NULL,
+ },
+ {
USB_VENDOR_DLINK, 0,
USB_KNOWNDEV_NOPROD,
"D-Link",
diff --git a/sys/dev/usb2/include/usb2_error.h b/sys/dev/usb2/include/usb2_error.h
index 86c62c2..91f0245 100644
--- a/sys/dev/usb2/include/usb2_error.h
+++ b/sys/dev/usb2/include/usb2_error.h
@@ -27,42 +27,37 @@
#ifndef _USB2_ERROR_H_
#define _USB2_ERROR_H_
-/*
- * The "USB_STATUS" macro defines all the USB error codes.
- * NOTE: "USB_ERR_NORMAL_COMPLETION" is not an error code.
- * NOTE: "USB_ERR_STARTING" is not an error code.
- */
-#define USB_ERR(m,n)\
-m(n, USB_ERR_NORMAL_COMPLETION)\
-m(n, USB_ERR_PENDING_REQUESTS)\
-m(n, USB_ERR_NOT_STARTED)\
-m(n, USB_ERR_INVAL)\
-m(n, USB_ERR_NOMEM)\
-m(n, USB_ERR_CANCELLED)\
-m(n, USB_ERR_BAD_ADDRESS)\
-m(n, USB_ERR_BAD_BUFSIZE)\
-m(n, USB_ERR_BAD_FLAG)\
-m(n, USB_ERR_NO_CALLBACK)\
-m(n, USB_ERR_IN_USE)\
-m(n, USB_ERR_NO_ADDR)\
-m(n, USB_ERR_NO_PIPE)\
-m(n, USB_ERR_ZERO_NFRAMES)\
-m(n, USB_ERR_ZERO_MAXP)\
-m(n, USB_ERR_SET_ADDR_FAILED)\
-m(n, USB_ERR_NO_POWER)\
-m(n, USB_ERR_TOO_DEEP)\
-m(n, USB_ERR_IOERROR)\
-m(n, USB_ERR_NOT_CONFIGURED)\
-m(n, USB_ERR_TIMEOUT)\
-m(n, USB_ERR_SHORT_XFER)\
-m(n, USB_ERR_STALLED)\
-m(n, USB_ERR_INTERRUPTED)\
-m(n, USB_ERR_DMA_LOAD_FAILED)\
-m(n, USB_ERR_BAD_CONTEXT)\
-m(n, USB_ERR_NO_ROOT_HUB)\
-m(n, USB_ERR_NO_INTR_THREAD)\
-m(n, USB_ERR_NOT_LOCKED)\
-
-USB_MAKE_ENUM(USB_ERR);
+enum { /* keep in sync with usb_errstr_table */
+ USB_ERR_NORMAL_COMPLETION = 0,
+ USB_ERR_PENDING_REQUESTS, /* 1 */
+ USB_ERR_NOT_STARTED, /* 2 */
+ USB_ERR_INVAL, /* 3 */
+ USB_ERR_NOMEM, /* 4 */
+ USB_ERR_CANCELLED, /* 5 */
+ USB_ERR_BAD_ADDRESS, /* 6 */
+ USB_ERR_BAD_BUFSIZE, /* 7 */
+ USB_ERR_BAD_FLAG, /* 8 */
+ USB_ERR_NO_CALLBACK, /* 9 */
+ USB_ERR_IN_USE, /* 10 */
+ USB_ERR_NO_ADDR, /* 11 */
+ USB_ERR_NO_PIPE, /* 12 */
+ USB_ERR_ZERO_NFRAMES, /* 13 */
+ USB_ERR_ZERO_MAXP, /* 14 */
+ USB_ERR_SET_ADDR_FAILED, /* 15 */
+ USB_ERR_NO_POWER, /* 16 */
+ USB_ERR_TOO_DEEP, /* 17 */
+ USB_ERR_IOERROR, /* 18 */
+ USB_ERR_NOT_CONFIGURED, /* 19 */
+ USB_ERR_TIMEOUT, /* 20 */
+ USB_ERR_SHORT_XFER, /* 21 */
+ USB_ERR_STALLED, /* 22 */
+ USB_ERR_INTERRUPTED, /* 23 */
+ USB_ERR_DMA_LOAD_FAILED, /* 24 */
+ USB_ERR_BAD_CONTEXT, /* 25 */
+ USB_ERR_NO_ROOT_HUB, /* 26 */
+ USB_ERR_NO_INTR_THREAD, /* 27 */
+ USB_ERR_NOT_LOCKED, /* 28 */
+ USB_ERR_MAX
+};
#endif /* _USB2_ERROR_H_ */
diff --git a/sys/dev/usb2/include/usb2_hid.h b/sys/dev/usb2/include/usb2_hid.h
index ee07a03..1a8650e 100644
--- a/sys/dev/usb2/include/usb2_hid.h
+++ b/sys/dev/usb2/include/usb2_hid.h
@@ -29,6 +29,8 @@
#ifndef _USB2_HID_H_
#define _USB2_HID_H_
+#include <dev/usb2/include/usb2_endian.h>
+
#define UR_GET_HID_DESCRIPTOR 0x06
#define UDESC_HID 0x21
#define UDESC_REPORT 0x22
diff --git a/sys/dev/usb2/include/usb2_ioctl.h b/sys/dev/usb2/include/usb2_ioctl.h
index 2a679c9..eeafd27 100644
--- a/sys/dev/usb2/include/usb2_ioctl.h
+++ b/sys/dev/usb2/include/usb2_ioctl.h
@@ -39,13 +39,6 @@
#define USB_DEVICE_NAME "usb"
#define USB_GENERIC_NAME "ugen"
-/* definition of USB power mode */
-#define USB_POWER_MODE_OFF 0 /* turn off device */
-#define USB_POWER_MODE_ON 1 /* always on */
-#define USB_POWER_MODE_SAVE 2 /* automatic suspend and resume */
-#define USB_POWER_MODE_SUSPEND 3 /* force suspend */
-#define USB_POWER_MODE_RESUME 4 /* force resume */
-
struct usb2_read_dir {
void *urd_data;
uint32_t urd_startentry;
@@ -230,7 +223,7 @@ struct usb2_gen_quirk {
#define USB_DEVICEENUMERATE _IOW ('U', 6, int)
/* Generic HID device */
-#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb2_gen_descriptor)
+#define USB_GET_REPORT_DESC _IOWR('U', 21, struct usb2_gen_descriptor)
#define USB_SET_IMMED _IOW ('U', 22, int)
#define USB_GET_REPORT _IOWR('U', 23, struct usb2_gen_descriptor)
#define USB_SET_REPORT _IOW ('U', 24, struct usb2_gen_descriptor)
diff --git a/sys/dev/usb2/include/usb2_mfunc.h b/sys/dev/usb2/include/usb2_mfunc.h
index 37be051..0fad203 100644
--- a/sys/dev/usb2/include/usb2_mfunc.h
+++ b/sys/dev/usb2/include/usb2_mfunc.h
@@ -29,14 +29,6 @@
#ifndef _USB2_MFUNC_H_
#define _USB2_MFUNC_H_
-#define USB_MAKE_001(n,ENUM) ENUM,
-#define USB_MAKE_ENUM(m) \
-enum { m(USB_MAKE_001,) m##_MAX }
-
-#define USB_MAKE_002(n,ENUM) #ENUM,
-#define USB_MAKE_DEBUG_TABLE(m) \
-static const char * m[m##_MAX] = { m(USB_MAKE_002,) }
-
#define USB_LOG2(n) ( \
((x) <= (1<<0x00)) ? 0x00 : \
((x) <= (1<<0x01)) ? 0x01 : \
diff --git a/sys/dev/usb2/include/usb2_revision.h b/sys/dev/usb2/include/usb2_revision.h
index b57946c..06d1b21 100644
--- a/sys/dev/usb2/include/usb2_revision.h
+++ b/sys/dev/usb2/include/usb2_revision.h
@@ -27,41 +27,39 @@
#ifndef _USB2_REVISION_H_
#define _USB2_REVISION_H_
-#include <dev/usb2/include/usb2_mfunc.h>
-
/*
* The "USB_SPEED" macro defines all the supported USB speeds.
*/
-#define USB_SPEED(m,n)\
-m(n, USB_SPEED_VARIABLE)\
-m(n, USB_SPEED_LOW)\
-m(n, USB_SPEED_FULL)\
-m(n, USB_SPEED_HIGH)\
-m(n, USB_SPEED_SUPER)\
-
-USB_MAKE_ENUM(USB_SPEED);
+enum {
+ USB_SPEED_VARIABLE,
+ USB_SPEED_LOW,
+ USB_SPEED_FULL,
+ USB_SPEED_HIGH,
+ USB_SPEED_SUPER,
+ USB_SPEED_MAX
+};
/*
* The "USB_REV" macro defines all the supported USB revisions.
*/
-#define USB_REV(m,n)\
-m(n, USB_REV_UNKNOWN)\
-m(n, USB_REV_PRE_1_0)\
-m(n, USB_REV_1_0)\
-m(n, USB_REV_1_1)\
-m(n, USB_REV_2_0)\
-m(n, USB_REV_2_5)\
-m(n, USB_REV_3_0)\
-
-USB_MAKE_ENUM(USB_REV);
+enum {
+ USB_REV_UNKNOWN,
+ USB_REV_PRE_1_0,
+ USB_REV_1_0,
+ USB_REV_1_1,
+ USB_REV_2_0,
+ USB_REV_2_5,
+ USB_REV_3_0,
+ USB_REV_MAX
+};
/*
* The "USB_MODE" macro defines all the supported USB modes.
*/
-#define USB_MODE(m,n)\
-m(n, USB_MODE_HOST)\
-m(n, USB_MODE_DEVICE)\
-
-USB_MAKE_ENUM(USB_MODE);
+enum {
+ USB_MODE_HOST,
+ USB_MODE_DEVICE,
+ USB_MODE_MAX
+};
#endif /* _USB2_REVISION_H_ */
diff --git a/sys/dev/usb2/include/usb2_standard.h b/sys/dev/usb2/include/usb2_standard.h
index 3671a51..f81f346 100644
--- a/sys/dev/usb2/include/usb2_standard.h
+++ b/sys/dev/usb2/include/usb2_standard.h
@@ -48,12 +48,20 @@
#define USB_POWER_DOWN_TIME 200 /* ms */
#define USB_PORT_POWER_DOWN_TIME 100 /* ms */
+/* Definition of software USB power modes */
+#define USB_POWER_MODE_OFF 0 /* turn off device */
+#define USB_POWER_MODE_ON 1 /* always on */
+#define USB_POWER_MODE_SAVE 2 /* automatic suspend and resume */
+#define USB_POWER_MODE_SUSPEND 3 /* force suspend */
+#define USB_POWER_MODE_RESUME 4 /* force resume */
+
#if 0
/* These are the values from the USB specification. */
#define USB_PORT_RESET_DELAY 10 /* ms */
#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */
#define USB_PORT_RESET_RECOVERY 10 /* ms */
#define USB_PORT_POWERUP_DELAY 100 /* ms */
+#define USB_PORT_RESUME_DELAY 20 /* ms */
#define USB_SET_ADDRESS_SETTLE 2 /* ms */
#define USB_RESUME_DELAY (20*5) /* ms */
#define USB_RESUME_WAIT 10 /* ms */
@@ -65,6 +73,7 @@
#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */
#define USB_PORT_RESET_RECOVERY 250 /* ms */
#define USB_PORT_POWERUP_DELAY 300 /* ms */
+#define USB_PORT_RESUME_DELAY (20*2) /* ms */
#define USB_SET_ADDRESS_SETTLE 10 /* ms */
#define USB_RESUME_DELAY (50*5) /* ms */
#define USB_RESUME_WAIT 50 /* ms */
@@ -593,12 +602,12 @@ struct usb2_port_status {
#define UPS_SUSPEND 0x0004
#define UPS_OVERCURRENT_INDICATOR 0x0008
#define UPS_RESET 0x0010
-#define UPS_PORT_MODE_DEVICE 0x0020 /* currently FreeBSD specific */
#define UPS_PORT_POWER 0x0100
#define UPS_LOW_SPEED 0x0200
#define UPS_HIGH_SPEED 0x0400
#define UPS_PORT_TEST 0x0800
#define UPS_PORT_INDICATOR 0x1000
+#define UPS_PORT_MODE_DEVICE 0x8000 /* currently FreeBSD specific */
uWord wPortChange;
#define UPS_C_CONNECT_STATUS 0x0001
#define UPS_C_PORT_ENABLED 0x0002
diff --git a/sys/dev/usb2/input/uhid2.c b/sys/dev/usb2/input/uhid2.c
index 7eec66c..cc16bbc 100644
--- a/sys/dev/usb2/input/uhid2.c
+++ b/sys/dev/usb2/input/uhid2.c
@@ -82,10 +82,16 @@ SYSCTL_INT(_hw_usb2_uhid, OID_AUTO, debug, CTLFLAG_RW,
&uhid_debug, 0, "Debug level");
#endif
-#define UHID_N_TRANSFER 4 /* units */
#define UHID_BSIZE 1024 /* bytes, buffer size */
#define UHID_FRAME_NUM 50 /* bytes, frame number */
+enum {
+ UHID_INTR_DT_RD,
+ UHID_CTRL_DT_WR,
+ UHID_CTRL_DT_RD,
+ UHID_N_TRANSFER,
+};
+
struct uhid_softc {
struct usb2_fifo_sc sc_fifo;
struct mtx sc_mtx;
@@ -107,7 +113,6 @@ struct uhid_softc {
uint8_t sc_fid;
uint8_t sc_flags;
#define UHID_FLAG_IMMED 0x01 /* set if read should be immediate */
-#define UHID_FLAG_INTR_STALL 0x02 /* set if interrupt transfer stalled */
#define UHID_FLAG_STATIC_DESC 0x04 /* set if report descriptors are
* static */
};
@@ -123,7 +128,6 @@ static device_attach_t uhid_attach;
static device_detach_t uhid_detach;
static usb2_callback_t uhid_intr_callback;
-static usb2_callback_t uhid_intr_clear_stall_callback;
static usb2_callback_t uhid_write_callback;
static usb2_callback_t uhid_read_callback;
@@ -167,41 +171,25 @@ uhid_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
- if (sc->sc_flags & UHID_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[1]);
- } else {
- if (usb2_fifo_put_bytes_max(
- sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
+re_submit:
+ if (usb2_fifo_put_bytes_max(
+ sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
+ xfer->frlengths[0] = sc->sc_isize;
+ usb2_start_hardware(xfer);
}
return;
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
- sc->sc_flags |= UHID_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[1]);
+ xfer->flags.stall_pipe = 1;
+ goto re_submit;
}
return;
}
}
static void
-uhid_intr_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct uhid_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UHID_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
uhid_fill_set_report(struct usb2_device_request *req, uint8_t iface_no,
uint8_t type, uint8_t id, uint16_t size)
{
@@ -325,26 +313,16 @@ uhid_read_callback(struct usb2_xfer *xfer)
static const struct usb2_config uhid_config[UHID_N_TRANSFER] = {
- [0] = {
+ [UHID_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
.mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
+ .mh.bufsize = UHID_BSIZE,
.mh.callback = &uhid_intr_callback,
},
- [1] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &uhid_intr_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-
- [2] = {
+ [UHID_CTRL_DT_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -353,7 +331,7 @@ static const struct usb2_config uhid_config[UHID_N_TRANSFER] = {
.mh.timeout = 1000, /* 1 second */
},
- [3] = {
+ [UHID_CTRL_DT_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -369,9 +347,9 @@ uhid_start_read(struct usb2_fifo *fifo)
struct uhid_softc *sc = fifo->priv_sc0;
if (sc->sc_flags & UHID_FLAG_IMMED) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UHID_CTRL_DT_RD]);
} else {
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UHID_INTR_DT_RD]);
}
}
@@ -380,8 +358,8 @@ uhid_stop_read(struct usb2_fifo *fifo)
{
struct uhid_softc *sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UHID_CTRL_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UHID_INTR_DT_RD]);
}
static void
@@ -389,7 +367,7 @@ uhid_start_write(struct usb2_fifo *fifo)
{
struct uhid_softc *sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UHID_CTRL_DT_WR]);
}
static void
@@ -397,7 +375,7 @@ uhid_stop_write(struct usb2_fifo *fifo)
{
struct uhid_softc *sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[2]);
+ usb2_transfer_stop(sc->sc_xfer[UHID_CTRL_DT_WR]);
}
static int
@@ -523,6 +501,8 @@ uhid_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
size = sc->sc_repdesc_size;
}
ugd->ugd_actlen = size;
+ if (ugd->ugd_data == NULL)
+ break; /* descriptor length only */
error = copyout(sc->sc_repdesc_ptr, ugd->ugd_data, size);
break;
@@ -653,9 +633,6 @@ uhid_attach(device_t dev)
DPRINTFN(10, "sc=%p\n", sc);
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
mtx_init(&sc->sc_mtx, "uhid lock", NULL, MTX_DEF | MTX_RECURSE);
diff --git a/sys/dev/usb2/input/ukbd2.c b/sys/dev/usb2/input/ukbd2.c
index 8cff11f..487e560 100644
--- a/sys/dev/usb2/input/ukbd2.c
+++ b/sys/dev/usb2/input/ukbd2.c
@@ -99,7 +99,6 @@ SYSCTL_INT(_hw_usb2_ukbd, OID_AUTO, debug, CTLFLAG_RW,
#define UKBD_DRIVER_NAME "ukbd"
#define UKBD_NMOD 8 /* units */
#define UKBD_NKEYCODE 6 /* units */
-#define UKBD_N_TRANSFER 3 /* units */
#define UKBD_IN_BUF_SIZE (2*(UKBD_NMOD + (2*UKBD_NKEYCODE))) /* bytes */
#define UKBD_IN_BUF_FULL (UKBD_IN_BUF_SIZE / 2) /* bytes */
#define UKBD_NFKEY (sizeof(fkey_tab)/sizeof(fkey_tab[0])) /* units */
@@ -118,6 +117,13 @@ struct ukbd_data {
uint8_t keycode[UKBD_NKEYCODE];
} __packed;
+enum {
+ UKBD_INTR_DT,
+ UKBD_INTR_CS,
+ UKBD_CTRL_LED,
+ UKBD_N_TRANSFER = 3,
+};
+
struct ukbd_softc {
keyboard_t sc_kbd;
keymap_t sc_keymap;
@@ -287,7 +293,7 @@ ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
if (sc->sc_inputs == 0) {
/* start transfer, if not already started */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
}
if (sc->sc_flags & UKBD_FLAG_POLLING) {
DPRINTFN(2, "polling\n");
@@ -451,7 +457,7 @@ static void
ukbd_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ukbd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UKBD_INTR_DT];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -491,7 +497,7 @@ ukbd_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
if (sc->sc_flags & UKBD_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UKBD_INTR_CS]);
return;
}
if (sc->sc_inputs < UKBD_IN_BUF_FULL) {
@@ -508,7 +514,7 @@ ukbd_intr_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= UKBD_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UKBD_INTR_CS]);
}
return;
}
@@ -554,7 +560,7 @@ ukbd_set_leds_callback(struct usb2_xfer *xfer)
static const struct usb2_config ukbd_config[UKBD_N_TRANSFER] = {
- [0] = {
+ [UKBD_INTR_DT] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -563,7 +569,7 @@ static const struct usb2_config ukbd_config[UKBD_N_TRANSFER] = {
.mh.callback = &ukbd_intr_callback,
},
- [1] = {
+ [UKBD_INTR_CS] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -573,7 +579,7 @@ static const struct usb2_config ukbd_config[UKBD_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [2] = {
+ [UKBD_CTRL_LED] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -619,9 +625,6 @@ ukbd_attach(device_t dev)
usb2_error_t err;
uint16_t n;
- if (sc == NULL) {
- return (ENOMEM);
- }
mtx_assert(&Giant, MA_OWNED);
kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
@@ -698,7 +701,7 @@ ukbd_attach(device_t dev)
/* start the keyboard */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
/* start the timer */
@@ -1360,7 +1363,7 @@ ukbd_set_leds(struct ukbd_softc *sc, uint8_t leds)
/* start transfer, if not already started */
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UKBD_CTRL_LED]);
}
static int
diff --git a/sys/dev/usb2/input/ums2.c b/sys/dev/usb2/input/ums2.c
index 0c3fa06..3d7f7f0 100644
--- a/sys/dev/usb2/input/ums2.c
+++ b/sys/dev/usb2/input/ums2.c
@@ -84,10 +84,15 @@ SYSCTL_INT(_hw_usb2_ums, OID_AUTO, debug, CTLFLAG_RW,
#define UMS_BUF_SIZE 8 /* bytes */
#define UMS_IFQ_MAXLEN 50 /* units */
-#define UMS_N_TRANSFER 2 /* units */
#define UMS_BUTTON_MAX 31 /* exclusive, must be less than 32 */
#define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
+enum {
+ UMS_INTR_DT,
+ UMS_INTR_CS,
+ UMS_N_TRANSFER = 2,
+};
+
struct ums_softc {
struct usb2_fifo_sc sc_fifo;
struct mtx sc_mtx;
@@ -159,7 +164,7 @@ static void
ums_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ums_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMS_INTR_DT];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -307,7 +312,7 @@ ums_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & UMS_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UMS_INTR_CS]);
} else {
/* check if we can put more data into the FIFO */
if (usb2_fifo_put_bytes_max(
@@ -322,7 +327,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= UMS_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UMS_INTR_CS]);
}
return;
}
@@ -330,7 +335,7 @@ tr_setup:
static const struct usb2_config ums_config[UMS_N_TRANSFER] = {
- [0] = {
+ [UMS_INTR_DT] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -339,7 +344,7 @@ static const struct usb2_config ums_config[UMS_N_TRANSFER] = {
.mh.callback = &ums_intr_callback,
},
- [1] = {
+ [UMS_INTR_CS] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -555,10 +560,10 @@ ums_attach(device_t dev)
/* Some wheels need the Z axis reversed. */
sc->sc_flags |= UMS_FLAG_REVZ;
}
- if (isize > sc->sc_xfer[0]->max_frame_size) {
+ if (isize > sc->sc_xfer[UMS_INTR_DT]->max_frame_size) {
DPRINTF("WARNING: report size, %d bytes, is larger "
"than interrupt size, %d bytes!\n",
- isize, sc->sc_xfer[0]->max_frame_size);
+ isize, sc->sc_xfer[UMS_INTR_DT]->max_frame_size);
}
/* announce information about the mouse */
@@ -657,7 +662,7 @@ ums_start_read(struct usb2_fifo *fifo)
{
struct ums_softc *sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UMS_INTR_DT]);
}
static void
@@ -665,8 +670,8 @@ ums_stop_read(struct usb2_fifo *fifo)
{
struct ums_softc *sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UMS_INTR_CS]);
+ usb2_transfer_stop(sc->sc_xfer[UMS_INTR_DT]);
usb2_callout_stop(&sc->sc_callout);
}
diff --git a/sys/dev/usb2/misc/udbp2.c b/sys/dev/usb2/misc/udbp2.c
index 03e4d6c..4b4fbfd 100644
--- a/sys/dev/usb2/misc/udbp2.c
+++ b/sys/dev/usb2/misc/udbp2.c
@@ -320,9 +320,6 @@ udbp_attach(device_t dev)
struct udbp_softc *sc = device_get_softc(dev);
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
snprintf(sc->sc_name, sizeof(sc->sc_name),
diff --git a/sys/dev/usb2/misc/ufm2.c b/sys/dev/usb2/misc/ufm2.c
index 376b630..5be828c 100644
--- a/sys/dev/usb2/misc/ufm2.c
+++ b/sys/dev/usb2/misc/ufm2.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -131,9 +130,6 @@ ufm_attach(device_t dev)
struct ufm_softc *sc = device_get_softc(dev);
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_unit = device_get_unit(dev);
diff --git a/sys/dev/usb2/quirk/usb2_quirk.c b/sys/dev/usb2/quirk/usb2_quirk.c
index d1aa732..7a6a39d 100644
--- a/sys/dev/usb2/quirk/usb2_quirk.c
+++ b/sys/dev/usb2/quirk/usb2_quirk.c
@@ -95,6 +95,7 @@ static struct usb2_quirk_entry usb2_quirks[USB_DEV_QUIRKS_MAX] = {
{USB_QUIRK_ENTRY(USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500CAVRLCD, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
{USB_QUIRK_ENTRY(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
{USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
+ {USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
{USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
{USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
@@ -111,7 +112,32 @@ static struct usb2_quirk_entry usb2_quirks[USB_DEV_QUIRKS_MAX] = {
{USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
};
-USB_MAKE_DEBUG_TABLE(USB_QUIRK);
+static const char *usb_quirk_str[USB_QUIRK_MAX] = {
+ [UQ_NONE] = "UQ_NONE",
+ [UQ_AUDIO_SWAP_LR] = "UQ_AUDIO_SWAP_LR",
+ [UQ_AU_INP_ASYNC] = "UQ_AU_INP_ASYNC",
+ [UQ_AU_NO_FRAC] = "UQ_AU_NO_FRAC",
+ [UQ_AU_NO_XU] = "UQ_AU_NO_XU",
+ [UQ_BAD_ADC] = "UQ_BAD_ADC",
+ [UQ_BAD_AUDIO] = "UQ_BAD_AUDIO",
+ [UQ_BROKEN_BIDIR] = "UQ_BROKEN_BIDIR",
+ [UQ_BUS_POWERED] = "UQ_BUS_POWERED",
+ [UQ_HID_IGNORE] = "UQ_HID_IGNORE",
+ [UQ_KBD_IGNORE] = "UQ_KBD_IGNORE",
+ [UQ_MS_BAD_CLASS] = "UQ_MS_BAD_CLASS",
+ [UQ_MS_LEADING_BYTE] = "UQ_MS_LEADING_BYTE",
+ [UQ_MS_REVZ] = "UQ_MS_REVZ",
+ [UQ_NO_STRINGS] = "UQ_NO_STRINGS",
+ [UQ_OPEN_CLEARSTALL] = "UQ_OPEN_CLEARSTALL",
+ [UQ_POWER_CLAIM] = "UQ_POWER_CLAIM",
+ [UQ_SPUR_BUT_UP] = "UQ_SPUR_BUT_UP",
+ [UQ_SWAP_UNICODE] = "UQ_SWAP_UNICODE",
+ [UQ_CFG_INDEX_1] = "UQ_CFG_INDEX_1",
+ [UQ_CFG_INDEX_2] = "UQ_CFG_INDEX_2",
+ [UQ_CFG_INDEX_3] = "UQ_CFG_INDEX_3",
+ [UQ_CFG_INDEX_4] = "UQ_CFG_INDEX_4",
+ [UQ_CFG_INDEX_0] = "UQ_CFG_INDEX_0",
+};
/*------------------------------------------------------------------------*
* usb2_quirkstr
@@ -122,7 +148,7 @@ static const char *
usb2_quirkstr(uint16_t quirk)
{
return ((quirk < USB_QUIRK_MAX) ?
- USB_QUIRK[quirk] : "USB_QUIRK_UNKNOWN");
+ usb_quirk_str[quirk] : "USB_QUIRK_UNKNOWN");
}
/*------------------------------------------------------------------------*
diff --git a/sys/dev/usb2/quirk/usb2_quirk.h b/sys/dev/usb2/quirk/usb2_quirk.h
index 9b57a2e..c9223e8 100644
--- a/sys/dev/usb2/quirk/usb2_quirk.h
+++ b/sys/dev/usb2/quirk/usb2_quirk.h
@@ -28,56 +28,32 @@
#define _USB2_QUIRK_H_
/* NOTE: UQ_NONE is not a valid quirk */
-
-#define USB_QUIRK(m,n) \
- m(n, UQ_NONE) \
- /* left and right sound channels are swapped */ \
- m(n, UQ_AUDIO_SWAP_LR) \
- /* input is async despite claim of adaptive */ \
- m(n, UQ_AU_INP_ASYNC) \
- /* don't adjust for fractional samples */ \
- m(n, UQ_AU_NO_FRAC) \
- /* audio device has broken extension unit */ \
- m(n, UQ_AU_NO_XU) \
- /* bad audio spec version number */ \
- m(n, UQ_BAD_ADC) \
- /* device claims audio class, but isn't */ \
- m(n, UQ_BAD_AUDIO) \
- /* printer has broken bidir mode */ \
- m(n, UQ_BROKEN_BIDIR) \
- /* device is bus powered, despite claim */ \
- m(n, UQ_BUS_POWERED) \
- /* device should be ignored by hid class */ \
- m(n, UQ_HID_IGNORE) \
- /* device should be ignored by kbd class */ \
- m(n, UQ_KBD_IGNORE) \
- /* doesn't identify properly */ \
- m(n, UQ_MS_BAD_CLASS) \
- /* mouse sends an unknown leading byte */ \
- m(n, UQ_MS_LEADING_BYTE) \
- /* mouse has Z-axis reversed */ \
- m(n, UQ_MS_REVZ) \
- /* string descriptors are broken */ \
- m(n, UQ_NO_STRINGS) \
- /* device needs clear endpoint stall */ \
- m(n, UQ_OPEN_CLEARSTALL) \
- /* hub lies about power status */ \
- m(n, UQ_POWER_CLAIM) \
- /* spurious mouse button up events */ \
- m(n, UQ_SPUR_BUT_UP) \
- /* has some Unicode strings swapped */ \
- m(n, UQ_SWAP_UNICODE) \
- /* select configuration index 1 by default */ \
- m(n, UQ_CFG_INDEX_1) \
- /* select configuration index 2 by default */ \
- m(n, UQ_CFG_INDEX_2) \
- /* select configuration index 3 by default */ \
- m(n, UQ_CFG_INDEX_3) \
- /* select configuration index 4 by default */ \
- m(n, UQ_CFG_INDEX_4) \
- /* select configuration index 0 by default */ \
- m(n, UQ_CFG_INDEX_0)
-
-USB_MAKE_ENUM(USB_QUIRK);
+enum { /* keep in sync with usb_quirk_str table */
+ UQ_NONE,
+ UQ_AUDIO_SWAP_LR, /* left and right sound channels are swapped */
+ UQ_AU_INP_ASYNC, /* input is async despite claim of adaptive */
+ UQ_AU_NO_FRAC, /* don't adjust for fractional samples */
+ UQ_AU_NO_XU, /* audio device has broken extension unit */
+ UQ_BAD_ADC, /* bad audio spec version number */
+ UQ_BAD_AUDIO, /* device claims audio class, but isn't */
+ UQ_BROKEN_BIDIR, /* printer has broken bidir mode */
+ UQ_BUS_POWERED, /* device is bus powered, despite claim */
+ UQ_HID_IGNORE, /* device should be ignored by hid class */
+ UQ_KBD_IGNORE, /* device should be ignored by kbd class */
+ UQ_MS_BAD_CLASS, /* doesn't identify properly */
+ UQ_MS_LEADING_BYTE, /* mouse sends an unknown leading byte */
+ UQ_MS_REVZ, /* mouse has Z-axis reversed */
+ UQ_NO_STRINGS, /* string descriptors are broken */
+ UQ_OPEN_CLEARSTALL, /* device needs clear endpoint stall */
+ UQ_POWER_CLAIM, /* hub lies about power status */
+ UQ_SPUR_BUT_UP, /* spurious mouse button up events */
+ UQ_SWAP_UNICODE, /* has some Unicode strings swapped */
+ UQ_CFG_INDEX_1, /* select configuration index 1 by default */
+ UQ_CFG_INDEX_2, /* select configuration index 2 by default */
+ UQ_CFG_INDEX_3, /* select configuration index 3 by default */
+ UQ_CFG_INDEX_4, /* select configuration index 4 by default */
+ UQ_CFG_INDEX_0, /* select configuration index 0 by default */
+ USB_QUIRK_MAX
+};
#endif /* _USB2_QUIRK_H_ */
diff --git a/sys/dev/usb2/serial/u3g2.c b/sys/dev/usb2/serial/u3g2.c
index a15f081..472b74a 100644
--- a/sys/dev/usb2/serial/u3g2.c
+++ b/sys/dev/usb2/serial/u3g2.c
@@ -37,19 +37,20 @@
#include <dev/usb2/include/usb2_standard.h>
#include <dev/usb2/include/usb2_mfunc.h>
#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
+#include <dev/usb2/include/usb2_defs.h>
#define USB_DEBUG_VAR u3g_debug
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_msctest.h>
+#include <dev/usb2/core/usb2_dynamic.h>
+#include <dev/usb2/core/usb2_device.h>
#include <dev/usb2/serial/usb2_serial.h>
@@ -61,21 +62,40 @@ SYSCTL_INT(_hw_usb2_u3g, OID_AUTO, debug, CTLFLAG_RW,
&u3g_debug, 0, "u3g debug level");
#endif
-#define U3G_N_TRANSFER 2
#define U3G_MAXPORTS 4
#define U3G_CONFIG_INDEX 0
#define U3G_BSIZE 2048
+#define U3GSP_GPRS 0
+#define U3GSP_EDGE 1
+#define U3GSP_CDMA 2
+#define U3GSP_UMTS 3
+#define U3GSP_HSDPA 4
+#define U3GSP_HSUPA 5
+#define U3GSP_HSPA 6
+#define U3GSP_MAX 7
+
+#define U3GFL_NONE 0x00 /* No flags */
+#define U3GFL_HUAWEI_INIT 0x01 /* Init command required */
+#define U3GFL_SCSI_EJECT 0x02 /* SCSI eject command required */
+#define U3GFL_SIERRA_INIT 0x04 /* Init command required */
+
struct u3g_speeds_s {
uint32_t ispeed;
uint32_t ospeed;
};
+enum {
+ U3G_BULK_WR,
+ U3G_BULK_RD,
+ U3G_N_TRANSFER = 2,
+};
+
struct u3g_softc {
struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
+ struct usb2_com_softc sc_ucom[U3G_MAXPORTS];
- struct usb2_xfer *sc_xfer[U3G_N_TRANSFER];
+ struct usb2_xfer *sc_xfer[U3G_MAXPORTS][U3G_N_TRANSFER];
struct usb2_device *sc_udev;
uint8_t sc_iface_no; /* interface number */
@@ -98,9 +118,11 @@ static void u3g_stop_read(struct usb2_com_softc *ucom);
static void u3g_start_write(struct usb2_com_softc *ucom);
static void u3g_stop_write(struct usb2_com_softc *ucom);
+static int u3g_driver_loaded(struct module *mod, int what, void *arg);
+
static const struct usb2_config u3g_config[U3G_N_TRANSFER] = {
- [0] = {
+ [U3G_BULK_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -109,7 +131,7 @@ static const struct usb2_config u3g_config[U3G_N_TRANSFER] = {
.mh.callback = &u3g_write_callback,
},
- [1] = {
+ [U3G_BULK_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -151,10 +173,195 @@ static driver_t u3g_driver = {
.size = sizeof(struct u3g_softc),
};
-DRIVER_MODULE(u3g, ushub, u3g_driver, u3g_devclass, NULL, 0);
+DRIVER_MODULE(u3g, ushub, u3g_driver, u3g_devclass, u3g_driver_loaded, 0);
MODULE_DEPEND(u3g, usb2_serial, 1, 1, 1);
MODULE_DEPEND(u3g, usb2_core, 1, 1, 1);
+/* Huawei specific defines */
+
+#define U3GINFO(flag,speed) ((flag)|((speed) * 256))
+#define U3G_GET_SPEED(uaa) (USB_GET_DRIVER_INFO(uaa) / 256)
+
+/*
+ * NOTE: The entries marked with XXX should be checked for the correct
+ * speed indication to set the buffer sizes.
+ */
+static const struct usb2_device_id u3g_devs[] = {
+ /* OEM: Option */
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
+ /* OEM: Qualcomm, Inc. */
+ {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
+ /* OEM: Huawei */
+ {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, U3GINFO(U3GSP_HSDPA, U3GFL_HUAWEI_INIT))},
+ {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, U3GINFO(U3GSP_HSPA, U3GFL_HUAWEI_INIT))},
+ /* OEM: Novatel */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
+ {USB_VPI(USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
+ /* OEM: Merlin */
+ {USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ /* OEM: Sierra Wireless: */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
+ {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, U3GINFO(U3GSP_HSPA, U3GFL_NONE))}, /* XXX */
+ /* Sierra TruInstaller device ID */
+ {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, U3GINFO(U3GSP_UMTS, U3GFL_SIERRA_INIT))},
+};
+
+static void
+u3g_sierra_init(struct usb2_device *udev)
+{
+ struct usb2_device_request req;
+
+ DPRINTFN(0, "\n");
+
+ req.bmRequestType = UT_VENDOR;
+ req.bRequest = UR_SET_INTERFACE;
+ USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
+ USETW(req.wIndex, UHF_PORT_CONNECTION);
+ USETW(req.wLength, 0);
+
+ if (usb2_do_request_flags(udev, NULL, &req,
+ NULL, 0, NULL, USB_MS_HZ)) {
+ /* ignore any errors */
+ }
+ return;
+}
+
+static void
+u3g_huawei_init(struct usb2_device *udev)
+{
+ struct usb2_device_request req;
+
+ DPRINTFN(0, "\n");
+
+ req.bmRequestType = UT_WRITE_DEVICE;
+ req.bRequest = UR_SET_FEATURE;
+ USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
+ USETW(req.wIndex, UHF_PORT_SUSPEND);
+ USETW(req.wLength, 0);
+
+ if (usb2_do_request_flags(udev, NULL, &req,
+ NULL, 0, NULL, USB_MS_HZ)) {
+ /* ignore any errors */
+ }
+ return;
+}
+
+static int
+u3g_lookup_huawei(struct usb2_attach_arg *uaa)
+{
+ /* Calling the lookup function will also set the driver info! */
+ return (usb2_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
+}
+
+/*
+ * The following function handles 3G modem devices (E220, Mobile,
+ * etc.) with auto-install flash disks for Windows/MacOSX on the first
+ * interface. After some command or some delay they change appearance
+ * to a modem.
+ */
+static usb2_error_t
+u3g_test_huawei_autoinst(struct usb2_device *udev,
+ struct usb2_attach_arg *uaa)
+{
+ struct usb2_interface *iface;
+ struct usb2_interface_descriptor *id;
+ uint32_t flags;
+
+ if (udev == NULL) {
+ return (USB_ERR_INVAL);
+ }
+ iface = usb2_get_iface(udev, 0);
+ if (iface == NULL) {
+ return (USB_ERR_INVAL);
+ }
+ id = iface->idesc;
+ if (id == NULL) {
+ return (USB_ERR_INVAL);
+ }
+ if (id->bInterfaceClass != UICLASS_MASS) {
+ return (USB_ERR_INVAL);
+ }
+ if (u3g_lookup_huawei(uaa)) {
+ /* no device match */
+ return (USB_ERR_INVAL);
+ }
+ flags = USB_GET_DRIVER_INFO(uaa);
+
+ if (flags & U3GFL_HUAWEI_INIT) {
+ u3g_huawei_init(udev);
+ } else if (flags & U3GFL_SCSI_EJECT) {
+ return (usb2_test_autoinstall(udev, 0, 1));
+ } else if (flags & U3GFL_SIERRA_INIT) {
+ u3g_sierra_init(udev);
+ } else {
+ /* no quirks */
+ return (USB_ERR_INVAL);
+ }
+ return (0); /* success */
+}
+
+static int
+u3g_driver_loaded(struct module *mod, int what, void *arg)
+{
+ switch (what) {
+ case MOD_LOAD:
+ /* register our autoinstall handler */
+ usb2_test_huawei_autoinst_p = &u3g_test_huawei_autoinst;
+ break;
+ case MOD_UNLOAD:
+ usb2_test_huawei_unload(NULL);
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+ return (0);
+}
+
static int
u3g_probe(device_t self)
{
@@ -169,21 +376,25 @@ u3g_probe(device_t self)
if (uaa->info.bInterfaceClass != UICLASS_VENDOR) {
return (ENXIO);
}
- return (usb2_lookup_huawei(uaa));
+ return (u3g_lookup_huawei(uaa));
}
static int
u3g_attach(device_t dev)
{
+ struct usb2_config u3g_config_tmp[U3G_N_TRANSFER];
struct usb2_attach_arg *uaa = device_get_ivars(dev);
struct u3g_softc *sc = device_get_softc(dev);
+ uint8_t n;
+ uint8_t m;
int error;
DPRINTF("sc=%p\n", sc);
- if (sc == NULL) {
- return (ENOMEM);
- }
+ /* copy in USB config */
+ for (n = 0; n != U3G_N_TRANSFER; n++)
+ u3g_config_tmp[n] = u3g_config[n];
+
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
@@ -191,23 +402,41 @@ u3g_attach(device_t dev)
sc->sc_iface_index = uaa->info.bIfaceIndex;
sc->sc_speed = u3g_speeds[U3G_GET_SPEED(uaa)];
- error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
- sc->sc_xfer, u3g_config, U3G_N_TRANSFER, sc, &Giant);
+ for (m = 0; m != U3G_MAXPORTS; m++) {
- if (error) {
- DPRINTF("could not allocate all pipes\n");
- goto detach;
+ /* update BULK endpoint index */
+ for (n = 0; n != U3G_N_TRANSFER; n++)
+ u3g_config_tmp[n].ep_index = m;
+
+ /* try to allocate a set of BULK endpoints */
+ error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
+ sc->sc_xfer[m], u3g_config_tmp, U3G_N_TRANSFER,
+ &sc->sc_ucom[m], &Giant);
+
+ if (error) {
+ if (m != 0)
+ break; /* end of endpoints */
+ DPRINTF("could not allocate all pipes\n");
+ goto detach;
+ }
+ /* set stall by default */
+ usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_WR]);
+ usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_RD]);
}
- /* set stall by default */
- usb2_transfer_set_stall(sc->sc_xfer[0]);
- usb2_transfer_set_stall(sc->sc_xfer[1]);
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &u3g_callback, &Giant);
+ sc->sc_numports = m;
+
+ error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom,
+ sc->sc_numports, sc, &u3g_callback, &Giant);
if (error) {
DPRINTF("usb2_com_attach failed\n");
goto detach;
}
+ if (sc->sc_numports != 1) {
+ /* be verbose */
+ device_printf(dev, "Found %u ports.\n",
+ (unsigned int)sc->sc_numports);
+ }
return (0);
detach:
@@ -219,12 +448,15 @@ static int
u3g_detach(device_t dev)
{
struct u3g_softc *sc = device_get_softc(dev);
+ uint8_t m;
DPRINTF("sc=%p\n", sc);
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+ /* NOTE: It is not dangerous to detach more ports than attached! */
+ usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, U3G_MAXPORTS);
- usb2_transfer_unsetup(sc->sc_xfer, U3G_N_TRANSFER);
+ for (m = 0; m != U3G_MAXPORTS; m++)
+ usb2_transfer_unsetup(sc->sc_xfer[m], U3G_N_TRANSFER);
return (0);
}
@@ -235,7 +467,7 @@ u3g_start_read(struct usb2_com_softc *ucom)
struct u3g_softc *sc = ucom->sc_parent;
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]);
return;
}
@@ -245,7 +477,7 @@ u3g_stop_read(struct usb2_com_softc *ucom)
struct u3g_softc *sc = ucom->sc_parent;
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]);
return;
}
@@ -254,7 +486,7 @@ u3g_start_write(struct usb2_com_softc *ucom)
{
struct u3g_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]);
return;
}
@@ -263,21 +495,21 @@ u3g_stop_write(struct usb2_com_softc *ucom)
{
struct u3g_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]);
return;
}
static void
u3g_write_callback(struct usb2_xfer *xfer)
{
- struct u3g_softc *sc = xfer->priv_sc;
+ struct usb2_com_softc *ucom = xfer->priv_sc;
uint32_t actlen;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
case USB_ST_SETUP:
tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
+ if (usb2_com_get_data(ucom, xfer->frbuffers, 0,
U3G_BSIZE, &actlen)) {
xfer->frlengths[0] = actlen;
usb2_start_hardware(xfer);
@@ -298,11 +530,11 @@ tr_setup:
static void
u3g_read_callback(struct usb2_xfer *xfer)
{
- struct u3g_softc *sc = xfer->priv_sc;
+ struct usb2_com_softc *ucom = xfer->priv_sc;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
+ usb2_com_put_data(ucom, xfer->frbuffers, 0, xfer->actlen);
case USB_ST_SETUP:
tr_setup:
diff --git a/sys/dev/usb2/serial/uark2.c b/sys/dev/usb2/serial/uark2.c
index bd775b4..1c6558c 100644
--- a/sys/dev/usb2/serial/uark2.c
+++ b/sys/dev/usb2/serial/uark2.c
@@ -34,7 +34,6 @@
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -43,8 +42,6 @@
#define UARK_BUF_SIZE 1024 /* bytes */
-#define UARK_N_TRANSFER 4 /* units */
-
#define UARK_SET_DATA_BITS(x) ((x) - 5)
#define UARK_PARITY_NONE 0x00
@@ -64,6 +61,14 @@
#define UARK_CONFIG_INDEX 0
#define UARK_IFACE_INDEX 0
+enum {
+ UARK_BULK_DT_WR,
+ UARK_BULK_DT_RD,
+ UARK_BULK_CS_WR,
+ UARK_BULK_CS_RD,
+ UARK_N_TRANSFER = 4,
+};
+
struct uark_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
@@ -103,7 +108,7 @@ static void uark_cfg_write(struct uark_softc *, uint16_t, uint16_t);
static const struct usb2_config
uark_xfer_config[UARK_N_TRANSFER] = {
- [0] = {
+ [UARK_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -112,7 +117,7 @@ static const struct usb2_config
.mh.callback = &uark_bulk_write_callback,
},
- [1] = {
+ [UARK_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -121,7 +126,7 @@ static const struct usb2_config
.mh.callback = &uark_bulk_read_callback,
},
- [2] = {
+ [UARK_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -132,7 +137,7 @@ static const struct usb2_config
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UARK_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -204,9 +209,6 @@ uark_attach(device_t dev)
int32_t error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
@@ -260,7 +262,7 @@ uark_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flags & UARK_FLAG_BULK_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -273,7 +275,7 @@ uark_bulk_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UARK_FLAG_BULK_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_WR]);
}
return;
@@ -284,7 +286,7 @@ static void
uark_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uark_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UARK_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -305,7 +307,7 @@ uark_bulk_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & UARK_FLAG_BULK_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -315,7 +317,7 @@ uark_bulk_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UARK_FLAG_BULK_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_RD]);
}
return;
@@ -326,7 +328,7 @@ static void
uark_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uark_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UARK_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -340,7 +342,7 @@ uark_start_read(struct usb2_com_softc *ucom)
{
struct uark_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_RD]);
}
static void
@@ -348,8 +350,8 @@ uark_stop_read(struct usb2_com_softc *ucom)
{
struct uark_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UARK_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_RD]);
}
static void
@@ -357,7 +359,7 @@ uark_start_write(struct usb2_com_softc *ucom)
{
struct uark_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_WR]);
}
static void
@@ -365,8 +367,8 @@ uark_stop_write(struct usb2_com_softc *ucom)
{
struct uark_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UARK_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_WR]);
}
static int
diff --git a/sys/dev/usb2/serial/ubsa2.c b/sys/dev/usb2/serial/ubsa2.c
index 6e84e39..e9b149f 100644
--- a/sys/dev/usb2/serial/ubsa2.c
+++ b/sys/dev/usb2/serial/ubsa2.c
@@ -73,7 +73,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -89,10 +88,9 @@ SYSCTL_INT(_hw_usb2_ubsa, OID_AUTO, debug, CTLFLAG_RW,
&ubsa_debug, 0, "ubsa debug level");
#endif
-#define UBSA_N_TRANSFER 6 /* units */
#define UBSA_BSIZE 1024 /* bytes */
-#define UBSA_CONFIG_INDEX 1
+#define UBSA_CONFIG_INDEX 0
#define UBSA_IFACE_INDEX 0
#define UBSA_REG_BAUDRATE 0x00
@@ -142,6 +140,16 @@ SYSCTL_INT(_hw_usb2_ubsa, OID_AUTO, debug, CTLFLAG_RW,
#define UBSA_MSR_DDSR 0x02 /* DSR has changed state */
#define UBSA_MSR_DCTS 0x01 /* CTS has changed state */
+enum {
+ UBSA_BULK_DT_WR,
+ UBSA_BULK_DT_RD,
+ UBSA_BULK_CS_WR,
+ UBSA_BULK_CS_RD,
+ UBSA_INTR_DT_RD,
+ UBSA_INTR_CS_RD,
+ UBSA_N_TRANSFER = 6,
+};
+
struct ubsa_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
@@ -186,7 +194,7 @@ static void ubsa_cfg_get_status(struct usb2_com_softc *, uint8_t *,
static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
- [0] = {
+ [UBSA_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -195,7 +203,7 @@ static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
.mh.callback = &ubsa_write_callback,
},
- [1] = {
+ [UBSA_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -204,7 +212,7 @@ static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
.mh.callback = &ubsa_read_callback,
},
- [2] = {
+ [UBSA_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -214,7 +222,7 @@ static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UBSA_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -224,7 +232,7 @@ static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [UBSA_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -233,7 +241,7 @@ static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
.mh.callback = &ubsa_intr_callback,
},
- [5] = {
+ [UBSA_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -321,9 +329,6 @@ ubsa_attach(device_t dev)
DPRINTF("sc=%p\n", sc);
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
@@ -527,10 +532,10 @@ ubsa_start_read(struct usb2_com_softc *ucom)
struct ubsa_softc *sc = ucom->sc_parent;
/* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[4]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_INTR_DT_RD]);
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_BULK_DT_RD]);
}
static void
@@ -539,12 +544,12 @@ ubsa_stop_read(struct usb2_com_softc *ucom)
struct ubsa_softc *sc = ucom->sc_parent;
/* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[5]);
- usb2_transfer_stop(sc->sc_xfer[4]);
+ usb2_transfer_stop(sc->sc_xfer[UBSA_INTR_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UBSA_INTR_DT_RD]);
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UBSA_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UBSA_BULK_DT_RD]);
}
static void
@@ -552,7 +557,7 @@ ubsa_start_write(struct usb2_com_softc *ucom)
{
struct ubsa_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_BULK_DT_WR]);
}
static void
@@ -560,8 +565,8 @@ ubsa_stop_write(struct usb2_com_softc *ucom)
{
struct ubsa_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UBSA_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UBSA_BULK_DT_WR]);
}
static void
@@ -585,7 +590,7 @@ ubsa_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UBSA_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -599,7 +604,7 @@ ubsa_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UBSA_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_BULK_CS_WR]);
}
return;
@@ -610,7 +615,7 @@ static void
ubsa_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ubsa_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UBSA_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -630,7 +635,7 @@ ubsa_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UBSA_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -640,7 +645,7 @@ ubsa_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UBSA_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_BULK_CS_RD]);
}
return;
@@ -651,7 +656,7 @@ static void
ubsa_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ubsa_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UBSA_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -691,7 +696,7 @@ ubsa_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UBSA_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -701,7 +706,7 @@ ubsa_intr_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UBSA_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UBSA_INTR_CS_RD]);
}
return;
@@ -712,7 +717,7 @@ static void
ubsa_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ubsa_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UBSA_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/ubser2.c b/sys/dev/usb2/serial/ubser2.c
index 6435796..40366be 100644
--- a/sys/dev/usb2/serial/ubser2.c
+++ b/sys/dev/usb2/serial/ubser2.c
@@ -87,7 +87,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -111,17 +110,19 @@ SYSCTL_INT(_hw_usb2_ubser, OID_AUTO, debug, CTLFLAG_RW,
&ubser_debug, 0, "ubser debug level");
#endif
-#define UBSER_TR_DT_WRITE 0
-#define UBSER_TR_DT_READ 1
-#define UBSER_TR_CS_WRITE 2
-#define UBSER_TR_CS_READ 3
-#define UBSER_TR_MAX 4
+enum {
+ UBSER_BULK_DT_WR,
+ UBSER_BULK_DT_RD,
+ UBSER_BULK_CS_WR,
+ UBSER_BULK_CS_RD,
+ UBSER_N_TRANSFER = 4,
+};
struct ubser_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom[UBSER_UNIT_MAX];
- struct usb2_xfer *sc_xfer[UBSER_TR_MAX];
+ struct usb2_xfer *sc_xfer[UBSER_N_TRANSFER];
struct usb2_device *sc_udev;
uint16_t sc_tx_size;
@@ -157,9 +158,9 @@ static void ubser_stop_read(struct usb2_com_softc *);
static void ubser_start_write(struct usb2_com_softc *);
static void ubser_stop_write(struct usb2_com_softc *);
-static const struct usb2_config ubser_config[UBSER_TR_MAX] = {
+static const struct usb2_config ubser_config[UBSER_N_TRANSFER] = {
- [UBSER_TR_DT_WRITE] = {
+ [UBSER_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -168,7 +169,7 @@ static const struct usb2_config ubser_config[UBSER_TR_MAX] = {
.mh.callback = &ubser_write_callback,
},
- [UBSER_TR_DT_READ] = {
+ [UBSER_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -177,7 +178,7 @@ static const struct usb2_config ubser_config[UBSER_TR_MAX] = {
.mh.callback = &ubser_read_callback,
},
- [UBSER_TR_CS_WRITE] = {
+ [UBSER_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -188,7 +189,7 @@ static const struct usb2_config ubser_config[UBSER_TR_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [UBSER_TR_CS_READ] = {
+ [UBSER_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -255,9 +256,6 @@ ubser_attach(device_t dev)
uint8_t n;
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
@@ -290,11 +288,11 @@ ubser_attach(device_t dev)
device_printf(dev, "found %i serials\n", sc->sc_numser);
error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
- sc->sc_xfer, ubser_config, UBSER_TR_MAX, sc, &Giant);
+ sc->sc_xfer, ubser_config, UBSER_N_TRANSFER, sc, &Giant);
if (error) {
goto detach;
}
- sc->sc_tx_size = sc->sc_xfer[UBSER_TR_DT_WRITE]->max_data_length;
+ sc->sc_tx_size = sc->sc_xfer[UBSER_BULK_DT_WR]->max_data_length;
if (sc->sc_tx_size == 0) {
DPRINTFN(0, "invalid tx_size!\n");
@@ -316,7 +314,7 @@ ubser_attach(device_t dev)
sc->sc_flags |= (UBSER_FLAG_READ_STALL |
UBSER_FLAG_WRITE_STALL);
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_DT_READ]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
mtx_unlock(&Giant);
@@ -342,12 +340,12 @@ ubser_detach(device_t dev)
* completes, it might start other transfers !
*/
mtx_lock(&Giant);
- for (n = 0; n < UBSER_TR_MAX; n++) {
+ for (n = 0; n < UBSER_N_TRANSFER; n++) {
usb2_transfer_stop(sc->sc_xfer[n]);
}
mtx_unlock(&Giant);
- usb2_transfer_unsetup(sc->sc_xfer, UBSER_TR_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
return (0);
}
@@ -414,7 +412,7 @@ static void
ubser_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ubser_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UBSER_TR_DT_WRITE];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UBSER_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -435,7 +433,7 @@ ubser_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flags & UBSER_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_CS_WRITE]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_WR]);
return;
}
do {
@@ -463,7 +461,7 @@ ubser_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UBSER_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_CS_WRITE]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_WR]);
}
return;
@@ -474,7 +472,7 @@ static void
ubser_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ubser_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UBSER_TR_DT_READ];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UBSER_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -507,7 +505,7 @@ ubser_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & UBSER_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_CS_READ]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -517,7 +515,7 @@ tr_setup:
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UBSER_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_CS_READ]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_RD]);
}
return;
@@ -565,7 +563,7 @@ ubser_start_read(struct usb2_com_softc *ucom)
{
struct ubser_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_DT_READ]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
}
static void
@@ -573,8 +571,8 @@ ubser_stop_read(struct usb2_com_softc *ucom)
{
struct ubser_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[UBSER_TR_CS_READ]);
- usb2_transfer_stop(sc->sc_xfer[UBSER_TR_DT_READ]);
+ usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_RD]);
}
static void
@@ -582,7 +580,7 @@ ubser_start_write(struct usb2_com_softc *ucom)
{
struct ubser_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[UBSER_TR_DT_WRITE]);
+ usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_WR]);
}
static void
@@ -590,6 +588,6 @@ ubser_stop_write(struct usb2_com_softc *ucom)
{
struct ubser_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[UBSER_TR_CS_WRITE]);
- usb2_transfer_stop(sc->sc_xfer[UBSER_TR_DT_WRITE]);
+ usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_WR]);
}
diff --git a/sys/dev/usb2/serial/uchcom2.c b/sys/dev/usb2/serial/uchcom2.c
index 2a49c72..c2c39e6 100644
--- a/sys/dev/usb2/serial/uchcom2.c
+++ b/sys/dev/usb2/serial/uchcom2.c
@@ -81,7 +81,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -145,7 +144,16 @@ SYSCTL_INT(_hw_usb2_uchcom, OID_AUTO, debug, CTLFLAG_RW,
#define UCHCOM_INTR_LEAST 4
#define UCHCOM_BULK_BUF_SIZE 1024 /* bytes */
-#define UCHCOM_N_TRANSFER 6 /* units */
+
+enum {
+ UCHCOM_BULK_DT_WR,
+ UCHCOM_BULK_DT_RD,
+ UCHCOM_BULK_CS_WR,
+ UCHCOM_BULK_CS_RD,
+ UCHCOM_INTR_DT_RD,
+ UCHCOM_INTR_CS_RD,
+ UCHCOM_N_TRANSFER = 6,
+};
struct uchcom_softc {
struct usb2_com_super_softc sc_super_ucom;
@@ -196,8 +204,6 @@ static const struct usb2_device_id uchcom_devs[] = {
/* protypes */
-static int uchcom_ioctl(struct usb2_com_softc *, uint32_t, caddr_t, int,
- struct thread *);
static int uchcom_pre_param(struct usb2_com_softc *, struct termios *);
static void uchcom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
uint8_t *);
@@ -232,7 +238,7 @@ static usb2_callback_t uchcom_read_clear_stall_callback;
static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
- [0] = {
+ [UCHCOM_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -241,7 +247,7 @@ static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
.mh.callback = &uchcom_write_callback,
},
- [1] = {
+ [UCHCOM_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -250,7 +256,7 @@ static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
.mh.callback = &uchcom_read_callback,
},
- [2] = {
+ [UCHCOM_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -260,7 +266,7 @@ static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UCHCOM_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -270,7 +276,7 @@ static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [UCHCOM_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -279,7 +285,7 @@ static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
.mh.callback = &uchcom_intr_callback,
},
- [5] = {
+ [UCHCOM_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -297,7 +303,6 @@ struct usb2_com_callback uchcom_callback = {
.usb2_com_cfg_set_break = &uchcom_cfg_set_break,
.usb2_com_cfg_param = &uchcom_cfg_param,
.usb2_com_pre_param = &uchcom_pre_param,
- .usb2_com_ioctl = &uchcom_ioctl,
.usb2_com_start_read = &uchcom_start_read,
.usb2_com_stop_read = &uchcom_stop_read,
.usb2_com_start_write = &uchcom_start_write,
@@ -337,9 +342,6 @@ uchcom_attach(device_t dev)
DPRINTFN(11, "\n");
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
@@ -738,13 +740,6 @@ uchcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
*msr = sc->sc_msr;
}
-static int
-uchcom_ioctl(struct usb2_com_softc *ucom, uint32_t cmd, caddr_t data, int flag,
- struct thread *td)
-{
- return (ENOTTY);
-}
-
static void
uchcom_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
{
@@ -802,10 +797,10 @@ uchcom_start_read(struct usb2_com_softc *ucom)
struct uchcom_softc *sc = ucom->sc_parent;
/* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[4]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
}
static void
@@ -814,11 +809,11 @@ uchcom_stop_read(struct usb2_com_softc *ucom)
struct uchcom_softc *sc = ucom->sc_parent;
/* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[4]);
+ usb2_transfer_stop(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
}
static void
@@ -826,7 +821,7 @@ uchcom_start_write(struct usb2_com_softc *ucom)
{
struct uchcom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
}
static void
@@ -834,8 +829,8 @@ uchcom_stop_write(struct usb2_com_softc *ucom)
{
struct uchcom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
}
/* ----------------------------------------------------------------------
@@ -865,7 +860,7 @@ uchcom_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
if (sc->sc_flag & UCHCOM_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -875,7 +870,7 @@ uchcom_intr_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UCHCOM_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_INTR_CS_RD]);
}
break;
}
@@ -885,7 +880,7 @@ static void
uchcom_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uchcom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UCHCOM_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -904,7 +899,7 @@ uchcom_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UCHCOM_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -920,7 +915,7 @@ uchcom_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UCHCOM_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_WR]);
}
return;
@@ -931,7 +926,7 @@ static void
uchcom_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uchcom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UCHCOM_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -951,7 +946,7 @@ uchcom_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UCHCOM_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -961,7 +956,7 @@ uchcom_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UCHCOM_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_RD]);
}
return;
@@ -972,7 +967,7 @@ static void
uchcom_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uchcom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UCHCOM_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/ucycom2.c b/sys/dev/usb2/serial/ucycom2.c
index 78a1ec0..7a82032 100644
--- a/sys/dev/usb2/serial/ucycom2.c
+++ b/sys/dev/usb2/serial/ucycom2.c
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -58,15 +57,21 @@ __FBSDID("$FreeBSD$");
#define UCYCOM_MAX_IOLEN (1024 + 2) /* bytes */
-#define UCYCOM_ENDPT_MAX 3 /* units */
#define UCYCOM_IFACE_INDEX 0
+enum {
+ UCYCOM_CTRL_RD,
+ UCYCOM_INTR_RD,
+ UCYCOM_INTR_CS,
+ UCYCOM_N_TRANSFER = 3,
+};
+
struct ucycom_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UCYCOM_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[UCYCOM_N_TRANSFER];
uint32_t sc_model;
#define MODEL_CY7C63743 0x63743
@@ -112,9 +117,9 @@ static void ucycom_cfg_write(struct ucycom_softc *, uint32_t, uint8_t);
static int ucycom_pre_param(struct usb2_com_softc *, struct termios *);
static void ucycom_cfg_param(struct usb2_com_softc *, struct termios *);
-static const struct usb2_config ucycom_config[UCYCOM_ENDPT_MAX] = {
+static const struct usb2_config ucycom_config[UCYCOM_N_TRANSFER] = {
- [0] = {
+ [UCYCOM_CTRL_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -124,7 +129,7 @@ static const struct usb2_config ucycom_config[UCYCOM_ENDPT_MAX] = {
.mh.timeout = 1000, /* 1 second */
},
- [1] = {
+ [UCYCOM_INTR_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -133,7 +138,7 @@ static const struct usb2_config ucycom_config[UCYCOM_ENDPT_MAX] = {
.mh.callback = &ucycom_intr_read_callback,
},
- [2] = {
+ [UCYCOM_INTR_CS] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -211,9 +216,6 @@ ucycom_attach(device_t dev)
uint16_t urd_len;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
device_set_usb2_desc(dev);
@@ -262,7 +264,7 @@ ucycom_attach(device_t dev)
iface_index = UCYCOM_IFACE_INDEX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, ucycom_config, UCYCOM_ENDPT_MAX,
+ sc->sc_xfer, ucycom_config, UCYCOM_N_TRANSFER,
sc, &Giant);
if (error) {
device_printf(dev, "allocating USB "
@@ -295,7 +297,7 @@ ucycom_detach(device_t dev)
usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
- usb2_transfer_unsetup(sc->sc_xfer, UCYCOM_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, UCYCOM_N_TRANSFER);
return (0);
}
@@ -314,7 +316,7 @@ ucycom_start_read(struct usb2_com_softc *ucom)
{
struct ucycom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UCYCOM_INTR_RD]);
}
static void
@@ -322,8 +324,8 @@ ucycom_stop_read(struct usb2_com_softc *ucom)
{
struct ucycom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UCYCOM_INTR_CS]);
+ usb2_transfer_stop(sc->sc_xfer[UCYCOM_INTR_RD]);
}
static void
@@ -331,7 +333,7 @@ ucycom_start_write(struct usb2_com_softc *ucom)
{
struct ucycom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UCYCOM_CTRL_RD]);
}
static void
@@ -339,7 +341,7 @@ ucycom_stop_write(struct usb2_com_softc *ucom)
{
struct ucycom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UCYCOM_CTRL_RD]);
}
static void
@@ -515,7 +517,7 @@ static void
ucycom_intr_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ucycom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UCYCOM_INTR_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -580,7 +582,7 @@ ucycom_intr_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & UCYCOM_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UCYCOM_INTR_CS]);
} else {
xfer->frlengths[0] = sc->sc_ilen;
usb2_start_hardware(xfer);
@@ -590,7 +592,7 @@ tr_setup:
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UCYCOM_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UCYCOM_INTR_CS]);
}
return;
diff --git a/sys/dev/usb2/serial/ufoma2.c b/sys/dev/usb2/serial/ufoma2.c
index 52d8a90..9596ebd 100644
--- a/sys/dev/usb2/serial/ufoma2.c
+++ b/sys/dev/usb2/serial/ufoma2.c
@@ -2,7 +2,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-
+#define UFOMA_HANDSFREE
/*-
* Copyright (c) 2005, Takanori Watanabe
* Copyright (c) 2003, M. Warner Losh <imp@freebsd.org>.
@@ -93,7 +93,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -101,6 +100,8 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/serial/usb2_serial.h>
+#include <sys/sysctl.h>
+#include <sys/sbuf.h>
typedef struct ufoma_mobile_acm_descriptor {
uint8_t bFunctionLength;
@@ -142,8 +143,21 @@ typedef struct ufoma_mobile_acm_descriptor {
#define UFOMA_BULK_BUF_SIZE 1024 /* bytes */
-#define UFOMA_CTRL_ENDPT_MAX 4 /* units */
-#define UFOMA_BULK_ENDPT_MAX 4 /* units */
+enum {
+ UFOMA_CTRL_ENDPT_INTR,
+ UFOMA_CTRL_ENDPT_INTR_CLEAR,
+ UFOMA_CTRL_ENDPT_READ,
+ UFOMA_CTRL_ENDPT_WRITE,
+ UFOMA_CTRL_ENDPT_MAX = 4,
+};
+
+enum {
+ UFOMA_BULK_ENDPT_WRITE,
+ UFOMA_BULK_ENDPT_READ,
+ UFOMA_BULK_ENDPT_WRITE_CLEAR,
+ UFOMA_BULK_ENDPT_READ_CLEAR,
+ UFOMA_BULK_ENDPT_MAX = 4,
+};
struct ufoma_softc {
struct usb2_com_super_softc sc_super_ucom;
@@ -161,7 +175,7 @@ struct ufoma_softc {
uint16_t sc_line;
uint8_t sc_num_msg;
- uint8_t sc_is_pseudo;
+ uint8_t sc_nobulk;
uint8_t sc_ctrl_iface_no;
uint8_t sc_ctrl_iface_index;
uint8_t sc_data_iface_no;
@@ -217,10 +231,16 @@ static void ufoma_stop_read(struct usb2_com_softc *);
static void ufoma_start_write(struct usb2_com_softc *);
static void ufoma_stop_write(struct usb2_com_softc *);
+/*sysctl stuff*/
+static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS);
+static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS);
+static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS);
+
+
static const struct usb2_config
ufoma_ctrl_config[UFOMA_CTRL_ENDPT_MAX] = {
- [0] = {
+ [UFOMA_CTRL_ENDPT_INTR] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -229,7 +249,7 @@ static const struct usb2_config
.mh.callback = &ufoma_intr_callback,
},
- [1] = {
+ [UFOMA_CTRL_ENDPT_INTR_CLEAR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -240,7 +260,7 @@ static const struct usb2_config
.mh.interval = 50, /* 50ms */
},
- [2] = {
+ [UFOMA_CTRL_ENDPT_READ] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -250,7 +270,7 @@ static const struct usb2_config
.mh.timeout = 1000, /* 1 second */
},
- [3] = {
+ [UFOMA_CTRL_ENDPT_WRITE] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -264,7 +284,7 @@ static const struct usb2_config
static const struct usb2_config
ufoma_bulk_config[UFOMA_BULK_ENDPT_MAX] = {
- [0] = {
+ [UFOMA_BULK_ENDPT_WRITE] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -273,7 +293,7 @@ static const struct usb2_config
.mh.callback = &ufoma_bulk_write_callback,
},
- [1] = {
+ [UFOMA_BULK_ENDPT_READ] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -282,7 +302,7 @@ static const struct usb2_config
.mh.callback = &ufoma_bulk_read_callback,
},
- [2] = {
+ [UFOMA_BULK_ENDPT_WRITE_CLEAR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -293,7 +313,7 @@ static const struct usb2_config
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UFOMA_BULK_ENDPT_READ_CLEAR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -380,13 +400,13 @@ ufoma_attach(device_t dev)
struct ufoma_softc *sc = device_get_softc(dev);
struct usb2_config_descriptor *cd;
struct usb2_interface_descriptor *id;
+ struct sysctl_ctx_list *sctx;
+ struct sysctl_oid *soid;
+
usb2_mcpc_acm_descriptor *mad;
uint8_t elements;
int32_t error;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -426,9 +446,9 @@ ufoma_attach(device_t dev)
}
if ((mad->bType == UMCPC_ACM_TYPE_AB5) ||
(mad->bType == UMCPC_ACM_TYPE_AB6)) {
- sc->sc_is_pseudo = 1;
+ sc->sc_nobulk = 1;
} else {
- sc->sc_is_pseudo = 0;
+ sc->sc_nobulk = 0;
if (ufoma_modem_setup(dev, sc, uaa)) {
goto detach;
}
@@ -459,6 +479,25 @@ ufoma_attach(device_t dev)
DPRINTF("usb2_com_attach failed\n");
goto detach;
}
+ /*Sysctls*/
+ sctx = device_get_sysctl_ctx(dev);
+ soid = device_get_sysctl_tree(dev);
+
+ SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "supportmode",
+ CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_support,
+ "A", "Supporting port role");
+
+ SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "currentmode",
+ CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_current,
+ "A", "Current port role");
+
+ SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "openmode",
+ CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open,
+ "A", "Mode to transit when port is opened");
+ SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "comunit",
+ CTLFLAG_RD, &(sc->sc_ucom.sc_unit), 0,
+ "Unit number as USB serial");
+
return (0); /* success */
detach:
@@ -672,7 +711,7 @@ static void
ufoma_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ufoma_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_ctrl_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -722,18 +761,18 @@ ufoma_intr_callback(struct usb2_xfer *xfer)
}
switch (pkt.bNotification) {
case UCDC_N_RESPONSE_AVAILABLE:
- if (!(sc->sc_is_pseudo)) {
+ if (!(sc->sc_nobulk)) {
DPRINTF("Wrong serial state!\n");
break;
}
if (sc->sc_num_msg != 0xFF) {
sc->sc_num_msg++;
}
- usb2_transfer_start(sc->sc_ctrl_xfer[3]);
+ usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_READ]);
break;
case UCDC_N_SERIAL_STATE:
- if (sc->sc_is_pseudo) {
+ if (sc->sc_nobulk) {
DPRINTF("Wrong serial state!\n");
break;
}
@@ -774,7 +813,7 @@ ufoma_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & UFOMA_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_ctrl_xfer[1]);
+ usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR_CLEAR]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -785,7 +824,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= UFOMA_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_ctrl_xfer[1]);
+ usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR_CLEAR]);
}
return;
@@ -802,7 +841,7 @@ ufoma_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flags & UFOMA_FLAG_BULK_WRITE_STALL) {
- usb2_transfer_start(sc->sc_bulk_xfer[2]);
+ usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE_CLEAR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -815,7 +854,7 @@ ufoma_bulk_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UFOMA_FLAG_BULK_WRITE_STALL;
- usb2_transfer_start(sc->sc_bulk_xfer[2]);
+ usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE_CLEAR]);
}
return;
@@ -826,7 +865,7 @@ static void
ufoma_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ufoma_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_bulk_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -847,7 +886,7 @@ ufoma_bulk_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & UFOMA_FLAG_BULK_READ_STALL) {
- usb2_transfer_start(sc->sc_bulk_xfer[3]);
+ usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ_CLEAR]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -857,7 +896,7 @@ ufoma_bulk_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UFOMA_FLAG_BULK_READ_STALL;
- usb2_transfer_start(sc->sc_bulk_xfer[3]);
+ usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ_CLEAR]);
}
return;
@@ -868,7 +907,7 @@ static void
ufoma_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ufoma_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_bulk_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -910,7 +949,8 @@ ufoma_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
struct usb2_device_request req;
uint16_t wValue;
- if (sc->sc_is_pseudo) {
+ if (sc->sc_nobulk ||
+ (sc->sc_currentmode == UMCPC_ACM_MODE_OBEX)) {
return;
}
if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK)) {
@@ -961,7 +1001,7 @@ ufoma_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
{
struct ufoma_softc *sc = ucom->sc_parent;
- if (sc->sc_is_pseudo) {
+ if (sc->sc_nobulk) {
return;
}
if (onoff)
@@ -977,7 +1017,7 @@ ufoma_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
{
struct ufoma_softc *sc = ucom->sc_parent;
- if (sc->sc_is_pseudo) {
+ if (sc->sc_nobulk) {
return;
}
if (onoff)
@@ -1001,7 +1041,7 @@ ufoma_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
struct usb2_device_request req;
struct usb2_cdc_line_state ls;
- if (sc->sc_is_pseudo ||
+ if (sc->sc_nobulk ||
(sc->sc_currentmode == UMCPC_ACM_MODE_OBEX)) {
return;
}
@@ -1129,13 +1169,13 @@ ufoma_start_read(struct usb2_com_softc *ucom)
struct ufoma_softc *sc = ucom->sc_parent;
/* start interrupt transfer */
- usb2_transfer_start(sc->sc_ctrl_xfer[0]);
+ usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR]);
/* start data transfer */
- if (sc->sc_is_pseudo) {
- usb2_transfer_start(sc->sc_ctrl_xfer[2]);
+ if (sc->sc_nobulk) {
+ usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_READ]);
} else {
- usb2_transfer_start(sc->sc_bulk_xfer[1]);
+ usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ]);
}
}
@@ -1145,15 +1185,15 @@ ufoma_stop_read(struct usb2_com_softc *ucom)
struct ufoma_softc *sc = ucom->sc_parent;
/* stop interrupt transfer */
- usb2_transfer_stop(sc->sc_ctrl_xfer[1]);
- usb2_transfer_stop(sc->sc_ctrl_xfer[0]);
+ usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR]);
+ usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR_CLEAR]);
/* stop data transfer */
- if (sc->sc_is_pseudo) {
- usb2_transfer_stop(sc->sc_ctrl_xfer[2]);
+ if (sc->sc_nobulk) {
+ usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_READ]);
} else {
- usb2_transfer_stop(sc->sc_bulk_xfer[3]);
- usb2_transfer_stop(sc->sc_bulk_xfer[1]);
+ usb2_transfer_stop(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ_CLEAR]);
+ usb2_transfer_stop(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ]);
}
}
@@ -1162,10 +1202,10 @@ ufoma_start_write(struct usb2_com_softc *ucom)
{
struct ufoma_softc *sc = ucom->sc_parent;
- if (sc->sc_is_pseudo) {
- usb2_transfer_start(sc->sc_ctrl_xfer[3]);
+ if (sc->sc_nobulk) {
+ usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_WRITE]);
} else {
- usb2_transfer_start(sc->sc_bulk_xfer[0]);
+ usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE]);
}
}
@@ -1174,10 +1214,120 @@ ufoma_stop_write(struct usb2_com_softc *ucom)
{
struct ufoma_softc *sc = ucom->sc_parent;
- if (sc->sc_is_pseudo) {
- usb2_transfer_stop(sc->sc_ctrl_xfer[3]);
+ if (sc->sc_nobulk) {
+ usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_WRITE]);
} else {
- usb2_transfer_stop(sc->sc_bulk_xfer[2]);
- usb2_transfer_stop(sc->sc_bulk_xfer[0]);
+ usb2_transfer_stop(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE_CLEAR]);
+ usb2_transfer_stop(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE]);
+ }
+}
+
+struct umcpc_modetostr_tab{
+ int mode;
+ char *str;
+}umcpc_modetostr_tab[]={
+ {UMCPC_ACM_MODE_DEACTIVATED, "deactivated"},
+ {UMCPC_ACM_MODE_MODEM, "modem"},
+ {UMCPC_ACM_MODE_ATCOMMAND, "handsfree"},
+ {UMCPC_ACM_MODE_OBEX, "obex"},
+ {UMCPC_ACM_MODE_VENDOR1, "vendor1"},
+ {UMCPC_ACM_MODE_VENDOR2, "vendor2"},
+ {UMCPC_ACM_MODE_UNLINKED, "unlinked"},
+ {0, NULL}
+};
+
+static char *ufoma_mode_to_str(int mode)
+{
+ int i;
+ for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){
+ if(umcpc_modetostr_tab[i].mode == mode){
+ return umcpc_modetostr_tab[i].str;
+ }
+ }
+ return NULL;
+}
+
+static int ufoma_str_to_mode(char *str)
+{
+ int i;
+ for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){
+ if(strcmp(str, umcpc_modetostr_tab[i].str)==0){
+ return umcpc_modetostr_tab[i].mode;
+ }
+ }
+ return -1;
+}
+
+static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS)
+{
+ struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
+ struct sbuf sb;
+ int i;
+ char *mode;
+
+ sbuf_new(&sb, NULL, 1, SBUF_AUTOEXTEND);
+ for(i = 1; i < sc->sc_modetable[0]; i++){
+ mode = ufoma_mode_to_str(sc->sc_modetable[i]);
+ if(mode !=NULL){
+ sbuf_cat(&sb, mode);
+ }else{
+ sbuf_printf(&sb, "(%02x)", sc->sc_modetable[i]);
+ }
+ if(i < (sc->sc_modetable[0]-1))
+ sbuf_cat(&sb, ",");
+ }
+ sbuf_trim(&sb);
+ sbuf_finish(&sb);
+ sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
+ sbuf_delete(&sb);
+
+ return 0;
+}
+static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS)
+{
+ struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
+ char *mode;
+ char subbuf[]="(XXX)";
+ mode = ufoma_mode_to_str(sc->sc_currentmode);
+ if(!mode){
+ mode = subbuf;
+ snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_currentmode);
+ }
+ sysctl_handle_string(oidp, mode, strlen(mode), req);
+
+ return 0;
+
+}
+static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS)
+{
+ struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
+ char *mode;
+ char subbuf[40];
+ int newmode;
+ int error;
+ int i;
+
+ mode = ufoma_mode_to_str(sc->sc_modetoactivate);
+ if(mode){
+ strncpy(subbuf, mode, sizeof(subbuf));
+ }else{
+ snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_modetoactivate);
+ }
+ error = sysctl_handle_string(oidp, subbuf, sizeof(subbuf), req);
+ if(error != 0 || req->newptr == NULL){
+ return error;
+ }
+
+ if((newmode = ufoma_str_to_mode(subbuf)) == -1){
+ return EINVAL;
+ }
+
+ for(i = 1 ; i < sc->sc_modetable[0] ; i++){
+ if(sc->sc_modetable[i] == newmode){
+ sc->sc_modetoactivate = newmode;
+ return 0;
+ }
}
+
+ return EINVAL;
}
diff --git a/sys/dev/usb2/serial/uftdi2.c b/sys/dev/usb2/serial/uftdi2.c
index 8484afe..c0170df 100644
--- a/sys/dev/usb2/serial/uftdi2.c
+++ b/sys/dev/usb2/serial/uftdi2.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -78,19 +77,26 @@ SYSCTL_INT(_hw_usb2_uftdi, OID_AUTO, debug, CTLFLAG_RW,
#define UFTDI_CONFIG_INDEX 0
#define UFTDI_IFACE_INDEX 0
-#define UFTDI_ENDPT_MAX 4
#define UFTDI_IBUFSIZE 64 /* bytes, maximum number of bytes per
* frame */
#define UFTDI_OBUFSIZE 64 /* bytes, cannot be increased due to
* do size encoding */
+enum {
+ UFTDI_BULK_DT_WR,
+ UFTDI_BULK_DT_RD,
+ UFTDI_BULK_CS_WR,
+ UFTDI_BULK_CS_RD,
+ UFTDI_N_TRANSFER = 4,
+};
+
struct uftdi_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UFTDI_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[UFTDI_N_TRANSFER];
device_t sc_dev;
uint32_t sc_unit;
@@ -148,9 +154,9 @@ static void uftdi_start_write(struct usb2_com_softc *);
static void uftdi_stop_write(struct usb2_com_softc *);
static uint8_t uftdi_8u232am_getrate(uint32_t, uint16_t *);
-static const struct usb2_config uftdi_config[UFTDI_ENDPT_MAX] = {
+static const struct usb2_config uftdi_config[UFTDI_N_TRANSFER] = {
- [0] = {
+ [UFTDI_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -159,7 +165,7 @@ static const struct usb2_config uftdi_config[UFTDI_ENDPT_MAX] = {
.mh.callback = &uftdi_write_callback,
},
- [1] = {
+ [UFTDI_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -168,7 +174,7 @@ static const struct usb2_config uftdi_config[UFTDI_ENDPT_MAX] = {
.mh.callback = &uftdi_read_callback,
},
- [2] = {
+ [UFTDI_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -179,7 +185,7 @@ static const struct usb2_config uftdi_config[UFTDI_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UFTDI_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -227,6 +233,7 @@ MODULE_DEPEND(uftdi, usb2_serial, 1, 1, 1);
MODULE_DEPEND(uftdi, usb2_core, 1, 1, 1);
static struct usb2_device_id uftdi_devs[] = {
+ {USB_VPI(USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, UFTDI_TYPE_SIO)},
{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, UFTDI_TYPE_8U232AM)},
@@ -249,6 +256,7 @@ static struct usb2_device_id uftdi_devs[] = {
{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2D, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PCMSFU, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2H, UFTDI_TYPE_8U232AM)},
+ {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MAXSTREAM, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_US2308, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_VALUECAN, UFTDI_TYPE_8U232AM)},
{USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_NEOVI, UFTDI_TYPE_8U232AM)},
@@ -279,9 +287,6 @@ uftdi_attach(device_t dev)
struct uftdi_softc *sc = device_get_softc(dev);
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
@@ -308,7 +313,7 @@ uftdi_attach(device_t dev)
error = usb2_transfer_setup(uaa->device,
&sc->sc_iface_index, sc->sc_xfer, uftdi_config,
- UFTDI_ENDPT_MAX, sc, &Giant);
+ UFTDI_N_TRANSFER, sc, &Giant);
if (error) {
device_printf(dev, "allocating USB "
@@ -348,7 +353,7 @@ uftdi_detach(device_t dev)
usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
- usb2_transfer_unsetup(sc->sc_xfer, UFTDI_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, UFTDI_N_TRANSFER);
return (0);
}
@@ -425,7 +430,7 @@ uftdi_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UFTDI_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers,
@@ -445,7 +450,7 @@ uftdi_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UFTDI_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_CS_WR]);
}
return;
@@ -456,7 +461,7 @@ static void
uftdi_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uftdi_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UFTDI_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -470,6 +475,7 @@ uftdi_read_callback(struct usb2_xfer *xfer)
{
struct uftdi_softc *sc = xfer->priv_sc;
uint8_t buf[2];
+ uint8_t ftdi_msr;
uint8_t msr;
uint8_t lsr;
@@ -481,9 +487,19 @@ uftdi_read_callback(struct usb2_xfer *xfer)
}
usb2_copy_out(xfer->frbuffers, 0, buf, 2);
- msr = FTDI_GET_MSR(buf);
+ ftdi_msr = FTDI_GET_MSR(buf);
lsr = FTDI_GET_LSR(buf);
+ msr = 0;
+ if (ftdi_msr & FTDI_SIO_CTS_MASK)
+ msr |= SER_CTS;
+ if (ftdi_msr & FTDI_SIO_DSR_MASK)
+ msr |= SER_DSR;
+ if (ftdi_msr & FTDI_SIO_RI_MASK)
+ msr |= SER_RI;
+ if (ftdi_msr & FTDI_SIO_RLSD_MASK)
+ msr |= SER_DCD;
+
if ((sc->sc_msr != msr) ||
((sc->sc_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK))) {
DPRINTF("status change msr=0x%02x (0x%02x) "
@@ -504,7 +520,7 @@ uftdi_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flag & UFTDI_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -514,7 +530,7 @@ tr_setup:
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UFTDI_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_CS_RD]);
}
return;
@@ -525,7 +541,7 @@ static void
uftdi_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uftdi_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UFTDI_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -757,7 +773,7 @@ uftdi_start_read(struct usb2_com_softc *ucom)
{
struct uftdi_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_DT_RD]);
}
static void
@@ -765,8 +781,8 @@ uftdi_stop_read(struct usb2_com_softc *ucom)
{
struct uftdi_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UFTDI_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UFTDI_BULK_DT_RD]);
}
static void
@@ -774,7 +790,7 @@ uftdi_start_write(struct usb2_com_softc *ucom)
{
struct uftdi_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_DT_WR]);
}
static void
@@ -782,8 +798,8 @@ uftdi_stop_write(struct usb2_com_softc *ucom)
{
struct uftdi_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UFTDI_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UFTDI_BULK_DT_WR]);
}
/*------------------------------------------------------------------------*
diff --git a/sys/dev/usb2/serial/ugensa2.c b/sys/dev/usb2/serial/ugensa2.c
index 8be929b..b54a5f8 100644
--- a/sys/dev/usb2/serial/ugensa2.c
+++ b/sys/dev/usb2/serial/ugensa2.c
@@ -54,7 +54,6 @@
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -63,11 +62,18 @@
#include <dev/usb2/serial/usb2_serial.h>
#define UGENSA_BUF_SIZE 2048 /* bytes */
-#define UGENSA_N_TRANSFER 4 /* units */
#define UGENSA_CONFIG_INDEX 0
#define UGENSA_IFACE_INDEX 0
#define UGENSA_IFACE_MAX 8 /* exclusivly */
+enum {
+ UGENSA_BULK_DT_WR,
+ UGENSA_BULK_DT_RD,
+ UGENSA_BULK_CS_WR,
+ UGENSA_BULK_CS_RD,
+ UGENSA_N_TRANSFER = 4,
+};
+
struct ugensa_sub_softc {
struct usb2_com_softc *sc_usb2_com_ptr;
struct usb2_xfer *sc_xfer[UGENSA_N_TRANSFER];
@@ -105,7 +111,7 @@ static void ugensa_stop_write(struct usb2_com_softc *);
static const struct usb2_config
ugensa_xfer_config[UGENSA_N_TRANSFER] = {
- [0] = {
+ [UGENSA_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -114,7 +120,7 @@ static const struct usb2_config
.mh.callback = &ugensa_bulk_write_callback,
},
- [1] = {
+ [UGENSA_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -123,7 +129,7 @@ static const struct usb2_config
.mh.callback = &ugensa_bulk_read_callback,
},
- [2] = {
+ [UGENSA_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -134,7 +140,7 @@ static const struct usb2_config
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UGENSA_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -178,9 +184,6 @@ static const struct usb2_device_id ugensa_devs[] = {
{USB_VPI(USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CDMA_MODEM1, 0)},
{USB_VPI(USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_CDMA_MSM_K, 0)},
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_49GPLUS, 0)},
-/* {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E270, 0)}, */
- {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, 0)},
- {USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, 0)},
{USB_VPI(USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_FLEXPACKGPS, 0)},
};
@@ -212,9 +215,6 @@ ugensa_attach(device_t dev)
uint8_t iface_index;
int x, cnt;
- if (sc == NULL)
- return (ENOMEM);
-
device_set_usb2_desc(dev);
mtx_init(&sc->sc_mtx, "ugensa", NULL, MTX_DEF);
@@ -302,7 +302,7 @@ ugensa_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (ssc->sc_flags & UGENSA_FLAG_BULK_WRITE_STALL) {
- usb2_transfer_start(ssc->sc_xfer[2]);
+ usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0,
@@ -315,7 +315,7 @@ ugensa_bulk_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
ssc->sc_flags |= UGENSA_FLAG_BULK_WRITE_STALL;
- usb2_transfer_start(ssc->sc_xfer[2]);
+ usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_WR]);
}
return;
@@ -326,7 +326,7 @@ static void
ugensa_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ugensa_sub_softc *ssc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = ssc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = ssc->sc_xfer[UGENSA_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -347,7 +347,7 @@ ugensa_bulk_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (ssc->sc_flags & UGENSA_FLAG_BULK_READ_STALL) {
- usb2_transfer_start(ssc->sc_xfer[3]);
+ usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -357,7 +357,7 @@ ugensa_bulk_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
ssc->sc_flags |= UGENSA_FLAG_BULK_READ_STALL;
- usb2_transfer_start(ssc->sc_xfer[3]);
+ usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_CS_RD]);
}
return;
@@ -368,7 +368,7 @@ static void
ugensa_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ugensa_sub_softc *ssc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = ssc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = ssc->sc_xfer[UGENSA_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -383,7 +383,7 @@ ugensa_start_read(struct usb2_com_softc *ucom)
struct ugensa_softc *sc = ucom->sc_parent;
struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
- usb2_transfer_start(ssc->sc_xfer[1]);
+ usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_RD]);
}
static void
@@ -392,8 +392,8 @@ ugensa_stop_read(struct usb2_com_softc *ucom)
struct ugensa_softc *sc = ucom->sc_parent;
struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
- usb2_transfer_stop(ssc->sc_xfer[3]);
- usb2_transfer_stop(ssc->sc_xfer[1]);
+ usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_CS_RD]);
+ usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_RD]);
}
static void
@@ -402,7 +402,7 @@ ugensa_start_write(struct usb2_com_softc *ucom)
struct ugensa_softc *sc = ucom->sc_parent;
struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
- usb2_transfer_start(ssc->sc_xfer[0]);
+ usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_WR]);
}
static void
@@ -411,6 +411,6 @@ ugensa_stop_write(struct usb2_com_softc *ucom)
struct ugensa_softc *sc = ucom->sc_parent;
struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
- usb2_transfer_stop(ssc->sc_xfer[2]);
- usb2_transfer_stop(ssc->sc_xfer[0]);
+ usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_CS_WR]);
+ usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_WR]);
}
diff --git a/sys/dev/usb2/serial/uipaq2.c b/sys/dev/usb2/serial/uipaq2.c
index 064a639..e80b62b 100644
--- a/sys/dev/usb2/serial/uipaq2.c
+++ b/sys/dev/usb2/serial/uipaq2.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -74,13 +73,20 @@ __FBSDID("$FreeBSD$");
#define UIPAQ_IFACE_INDEX 0
#define UIPAQ_BUF_SIZE 1024
-#define UIPAQ_N_DATA_TRANSFER 4
+
+enum {
+ UIPAQ_BULK_DT_WR,
+ UIPAQ_BULK_DT_RD,
+ UIPAQ_BULK_CS_WR,
+ UIPAQ_BULK_CS_RD,
+ UIPAQ_N_TRANSFER = 4,
+};
struct uipaq_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
- struct usb2_xfer *sc_xfer_data[UIPAQ_N_DATA_TRANSFER];
+ struct usb2_xfer *sc_xfer[UIPAQ_N_TRANSFER];
struct usb2_device *sc_udev;
uint16_t sc_line;
@@ -112,9 +118,9 @@ static void uipaq_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
static void uipaq_cfg_set_rts(struct usb2_com_softc *, uint8_t);
static void uipaq_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static const struct usb2_config uipaq_config_data[UIPAQ_N_DATA_TRANSFER] = {
+static const struct usb2_config uipaq_config_data[UIPAQ_N_TRANSFER] = {
- [0] = {
+ [UIPAQ_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -123,7 +129,7 @@ static const struct usb2_config uipaq_config_data[UIPAQ_N_DATA_TRANSFER] = {
.mh.callback = &uipaq_write_callback,
},
- [1] = {
+ [UIPAQ_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -132,7 +138,7 @@ static const struct usb2_config uipaq_config_data[UIPAQ_N_DATA_TRANSFER] = {
.mh.callback = &uipaq_read_callback,
},
- [2] = {
+ [UIPAQ_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -142,7 +148,7 @@ static const struct usb2_config uipaq_config_data[UIPAQ_N_DATA_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UIPAQ_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -1123,9 +1129,6 @@ uipaq_attach(device_t dev)
uint8_t iface_index;
uint8_t i;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
device_set_usb2_desc(dev);
@@ -1151,8 +1154,8 @@ uipaq_attach(device_t dev)
iface_index = UIPAQ_IFACE_INDEX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer_data, uipaq_config_data,
- UIPAQ_N_DATA_TRANSFER, sc, &Giant);
+ sc->sc_xfer, uipaq_config_data,
+ UIPAQ_N_TRANSFER, sc, &Giant);
if (error) {
goto detach;
@@ -1180,7 +1183,7 @@ uipaq_detach(device_t dev)
usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
- usb2_transfer_unsetup(sc->sc_xfer_data, UIPAQ_N_DATA_TRANSFER);
+ usb2_transfer_unsetup(sc->sc_xfer, UIPAQ_N_TRANSFER);
return (0);
}
@@ -1191,7 +1194,7 @@ uipaq_start_read(struct usb2_com_softc *ucom)
struct uipaq_softc *sc = ucom->sc_parent;
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer_data[1]);
+ usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_DT_RD]);
}
static void
@@ -1200,8 +1203,8 @@ uipaq_stop_read(struct usb2_com_softc *ucom)
struct uipaq_softc *sc = ucom->sc_parent;
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer_data[3]);
- usb2_transfer_stop(sc->sc_xfer_data[1]);
+ usb2_transfer_stop(sc->sc_xfer[UIPAQ_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UIPAQ_BULK_DT_RD]);
}
static void
@@ -1209,7 +1212,7 @@ uipaq_start_write(struct usb2_com_softc *ucom)
{
struct uipaq_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer_data[0]);
+ usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_DT_WR]);
}
static void
@@ -1217,8 +1220,8 @@ uipaq_stop_write(struct usb2_com_softc *ucom)
{
struct uipaq_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer_data[2]);
- usb2_transfer_stop(sc->sc_xfer_data[0]);
+ usb2_transfer_stop(sc->sc_xfer[UIPAQ_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UIPAQ_BULK_DT_WR]);
}
static void
@@ -1322,7 +1325,7 @@ uipaq_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UIPAQ_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer_data[2]);
+ usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -1336,7 +1339,7 @@ uipaq_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UIPAQ_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer_data[2]);
+ usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_CS_WR]);
}
return;
@@ -1347,7 +1350,7 @@ static void
uipaq_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uipaq_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_data[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UIPAQ_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1368,7 +1371,7 @@ uipaq_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UIPAQ_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer_data[3]);
+ usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -1378,7 +1381,7 @@ uipaq_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UIPAQ_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer_data[3]);
+ usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_CS_RD]);
}
return;
}
@@ -1388,7 +1391,7 @@ static void
uipaq_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uipaq_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_data[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UIPAQ_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/ulpt2.c b/sys/dev/usb2/serial/ulpt2.c
index 4b9f44b..e1e3dbb 100644
--- a/sys/dev/usb2/serial/ulpt2.c
+++ b/sys/dev/usb2/serial/ulpt2.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -76,7 +75,6 @@ SYSCTL_INT(_hw_usb2_ulpt, OID_AUTO, debug, CTLFLAG_RW,
#define ULPT_BSIZE (1<<15) /* bytes */
#define ULPT_IFQ_MAXLEN 2 /* units */
-#define ULPT_N_TRANSFER 5 /* units */
#define UR_GET_DEVICE_ID 0x00
#define UR_GET_PORT_STATUS 0x01
@@ -88,6 +86,15 @@ SYSCTL_INT(_hw_usb2_ulpt, OID_AUTO, debug, CTLFLAG_RW,
#define LPS_INVERT (LPS_SELECT|LPS_NERR)
#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER)
+enum {
+ ULPT_BULK_DT_WR,
+ ULPT_BULK_DT_RD,
+ ULPT_INTR_DT_RD,
+ ULPT_BULK_CS_WR,
+ ULPT_BULK_CS_RD,
+ ULPT_N_TRANSFER = 5,
+};
+
struct ulpt_softc {
struct usb2_fifo_sc sc_fifo;
struct usb2_fifo_sc sc_fifo_noreset;
@@ -208,7 +215,7 @@ ulpt_write_callback(struct usb2_xfer *xfer)
case USB_ST_TRANSFERRED:
case USB_ST_SETUP:
if (sc->sc_flags & ULPT_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_WR]);
break;
}
if (usb2_fifo_get_data(f, xfer->frbuffers,
@@ -223,7 +230,7 @@ ulpt_write_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= ULPT_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_WR]);
}
break;
}
@@ -233,7 +240,7 @@ static void
ulpt_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ulpt_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[ULPT_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -278,7 +285,7 @@ ulpt_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & ULPT_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[4]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_RD]);
break;
}
if (usb2_fifo_put_bytes_max(f) != 0) {
@@ -295,7 +302,7 @@ ulpt_read_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= ULPT_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[4]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_BULK_CS_RD]);
}
break;
}
@@ -305,7 +312,7 @@ static void
ulpt_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ulpt_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[ULPT_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -368,7 +375,7 @@ ulpt_status_callback(struct usb2_xfer *xfer)
}
static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
- [0] = {
+ [ULPT_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -377,7 +384,7 @@ static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
.mh.callback = &ulpt_write_callback,
},
- [1] = {
+ [ULPT_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -386,7 +393,7 @@ static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
.mh.callback = &ulpt_read_callback,
},
- [2] = {
+ [ULPT_INTR_DT_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -395,7 +402,7 @@ static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
.mh.timeout = 1000, /* 1 second */
},
- [3] = {
+ [ULPT_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -405,7 +412,7 @@ static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [ULPT_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -421,7 +428,7 @@ ulpt_start_read(struct usb2_fifo *fifo)
{
struct ulpt_softc *sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_BULK_DT_RD]);
}
static void
@@ -429,8 +436,8 @@ ulpt_stop_read(struct usb2_fifo *fifo)
{
struct ulpt_softc *sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[4]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_DT_RD]);
}
static void
@@ -438,7 +445,7 @@ ulpt_start_write(struct usb2_fifo *fifo)
{
struct ulpt_softc *sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_BULK_DT_WR]);
}
static void
@@ -446,8 +453,8 @@ ulpt_stop_write(struct usb2_fifo *fifo)
{
struct ulpt_softc *sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_DT_WR]);
}
static int
@@ -477,7 +484,7 @@ unlpt_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
sc->sc_flags |= ULPT_FLAG_READ_STALL;
mtx_unlock(&sc->sc_mtx);
if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[1]->max_data_length,
+ sc->sc_xfer[ULPT_BULK_DT_RD]->max_data_length,
ULPT_IFQ_MAXLEN)) {
return (ENOMEM);
}
@@ -490,7 +497,7 @@ unlpt_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
sc->sc_flags |= ULPT_FLAG_WRITE_STALL;
mtx_unlock(&sc->sc_mtx);
if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[0]->max_data_length,
+ sc->sc_xfer[ULPT_BULK_DT_WR]->max_data_length,
ULPT_IFQ_MAXLEN)) {
return (ENOMEM);
}
@@ -756,7 +763,7 @@ ulpt_watchdog(void *arg)
mtx_assert(&sc->sc_mtx, MA_OWNED);
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[ULPT_INTR_DT_RD]);
usb2_callout_reset(&sc->sc_watchdog,
hz, &ulpt_watchdog, sc);
diff --git a/sys/dev/usb2/serial/umct2.c b/sys/dev/usb2/serial/umct2.c
index 8e20ee7..9395f0b 100644
--- a/sys/dev/usb2/serial/umct2.c
+++ b/sys/dev/usb2/serial/umct2.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -81,14 +80,22 @@ __FBSDID("$FreeBSD$");
#define UMCT_IFACE_INDEX 0
#define UMCT_CONFIG_INDEX 1
-#define UMCT_ENDPT_MAX 6 /* units */
+enum {
+ UMCT_BULK_DT_WR,
+ UMCT_BULK_DT_RD,
+ UMCT_BULK_CS_WR,
+ UMCT_BULK_CS_RD,
+ UMCT_INTR_DT_RD,
+ UMCT_INTR_CS_RD,
+ UMCT_N_TRANSFER = 6,
+};
struct umct_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UMCT_ENDPT_MAX];
+ struct usb2_xfer *sc_xfer[UMCT_N_TRANSFER];
uint32_t sc_unit;
@@ -135,9 +142,9 @@ static void umct_stop_read(struct usb2_com_softc *);
static void umct_start_write(struct usb2_com_softc *);
static void umct_stop_write(struct usb2_com_softc *);
-static const struct usb2_config umct_config[UMCT_ENDPT_MAX] = {
+static const struct usb2_config umct_config[UMCT_N_TRANSFER] = {
- [0] = {
+ [UMCT_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -146,7 +153,7 @@ static const struct usb2_config umct_config[UMCT_ENDPT_MAX] = {
.mh.callback = &umct_write_callback,
},
- [1] = {
+ [UMCT_BULK_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -156,7 +163,7 @@ static const struct usb2_config umct_config[UMCT_ENDPT_MAX] = {
.ep_index = 0, /* first interrupt endpoint */
},
- [2] = {
+ [UMCT_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -167,7 +174,7 @@ static const struct usb2_config umct_config[UMCT_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UMCT_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -178,7 +185,7 @@ static const struct usb2_config umct_config[UMCT_ENDPT_MAX] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [UMCT_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -188,7 +195,7 @@ static const struct usb2_config umct_config[UMCT_ENDPT_MAX] = {
.ep_index = 1, /* second interrupt endpoint */
},
- [5] = {
+ [UMCT_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -266,9 +273,6 @@ umct_attach(device_t dev)
uint16_t maxp;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_unit = device_get_unit(dev);
@@ -281,7 +285,7 @@ umct_attach(device_t dev)
iface_index = UMCT_IFACE_INDEX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, umct_config, UMCT_ENDPT_MAX, sc, &Giant);
+ sc->sc_xfer, umct_config, UMCT_N_TRANSFER, sc, &Giant);
if (error) {
device_printf(dev, "allocating USB "
@@ -293,20 +297,20 @@ umct_attach(device_t dev)
* The only way to differentiate it from the real interrupt
* endpoint is to look at the wMaxPacketSize field.
*/
- maxp = UGETW(sc->sc_xfer[1]->pipe->edesc->wMaxPacketSize);
+ maxp = UGETW(sc->sc_xfer[UMCT_BULK_DT_RD]->pipe->edesc->wMaxPacketSize);
if (maxp == 0x2) {
/* guessed wrong - switch around endpoints */
- struct usb2_xfer *temp = sc->sc_xfer[4];
+ struct usb2_xfer *temp = sc->sc_xfer[UMCT_INTR_DT_RD];
- sc->sc_xfer[4] = sc->sc_xfer[1];
- sc->sc_xfer[1] = temp;
+ sc->sc_xfer[UMCT_INTR_DT_RD] = sc->sc_xfer[UMCT_BULK_DT_RD];
+ sc->sc_xfer[UMCT_BULK_DT_RD] = temp;
- sc->sc_xfer[1]->callback = &umct_read_callback;
- sc->sc_xfer[4]->callback = &umct_intr_callback;
+ sc->sc_xfer[UMCT_BULK_DT_RD]->callback = &umct_read_callback;
+ sc->sc_xfer[UMCT_INTR_DT_RD]->callback = &umct_intr_callback;
}
- sc->sc_obufsize = sc->sc_xfer[0]->max_data_length;
+ sc->sc_obufsize = sc->sc_xfer[UMCT_BULK_DT_WR]->max_data_length;
if (uaa->info.idProduct == USB_PRODUCT_MCT_SITECOM_USB232) {
if (sc->sc_obufsize > 16) {
@@ -332,7 +336,7 @@ umct_detach(device_t dev)
usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
- usb2_transfer_unsetup(sc->sc_xfer, UMCT_ENDPT_MAX);
+ usb2_transfer_unsetup(sc->sc_xfer, UMCT_N_TRANSFER);
return (0);
}
@@ -374,7 +378,7 @@ static void
umct_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct umct_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMCT_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -405,7 +409,7 @@ umct_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & UMCT_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -416,7 +420,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* start clear stall */
sc->sc_flags |= UMCT_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_INTR_CS_RD]);
}
return;
@@ -554,10 +558,10 @@ umct_start_read(struct usb2_com_softc *ucom)
struct umct_softc *sc = ucom->sc_parent;
/* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[4]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_INTR_DT_RD]);
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_BULK_DT_RD]);
}
static void
@@ -566,12 +570,12 @@ umct_stop_read(struct usb2_com_softc *ucom)
struct umct_softc *sc = ucom->sc_parent;
/* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[5]);
- usb2_transfer_stop(sc->sc_xfer[4]);
+ usb2_transfer_stop(sc->sc_xfer[UMCT_INTR_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UMCT_INTR_DT_RD]);
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UMCT_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_RD]);
}
static void
@@ -579,7 +583,7 @@ umct_start_write(struct usb2_com_softc *ucom)
{
struct umct_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_BULK_DT_WR]);
}
static void
@@ -587,8 +591,8 @@ umct_stop_write(struct usb2_com_softc *ucom)
{
struct umct_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UMCT_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_WR]);
}
static void
@@ -601,7 +605,7 @@ umct_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flags & UMCT_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -615,7 +619,7 @@ umct_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UMCT_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_BULK_CS_WR]);
}
return;
@@ -626,7 +630,7 @@ static void
umct_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct umct_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMCT_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -647,7 +651,7 @@ umct_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & UMCT_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -657,7 +661,7 @@ umct_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flags |= UMCT_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UMCT_BULK_CS_RD]);
}
return;
@@ -668,7 +672,7 @@ static void
umct_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct umct_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMCT_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/umodem2.c b/sys/dev/usb2/serial/umodem2.c
index 3720e23..86d2326 100644
--- a/sys/dev/usb2/serial/umodem2.c
+++ b/sys/dev/usb2/serial/umodem2.c
@@ -92,7 +92,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -323,9 +322,6 @@ umodem_attach(device_t dev)
uint8_t i;
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_ctrl_iface_no = uaa->info.bIfaceNum;
diff --git a/sys/dev/usb2/serial/umoscom2.c b/sys/dev/usb2/serial/umoscom2.c
index d2343f1..19be5b2 100644
--- a/sys/dev/usb2/serial/umoscom2.c
+++ b/sys/dev/usb2/serial/umoscom2.c
@@ -28,7 +28,6 @@
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -45,7 +44,6 @@ SYSCTL_INT(_hw_usb2_umoscom, OID_AUTO, debug, CTLFLAG_RW,
#endif
#define UMOSCOM_BUFSIZE 1024 /* bytes */
-#define UMOSCOM_N_DATA_TRANSFER 6 /* units */
#define UMOSCOM_CONFIG_INDEX 0
#define UMOSCOM_IFACE_INDEX 0
@@ -155,11 +153,21 @@ SYSCTL_INT(_hw_usb2_umoscom, OID_AUTO, debug, CTLFLAG_RW,
#define UMOSCOM_BAUD_REF 115200
+enum {
+ UMOSCOM_BULK_DT_WR,
+ UMOSCOM_BULK_DT_RD,
+ UMOSCOM_BULK_CS_WR,
+ UMOSCOM_BULK_CS_RD,
+ UMOSCOM_INTR_DT_RD,
+ UMOSCOM_INTR_CS_RD,
+ UMOSCOM_N_TRANSFER = 6,
+};
+
struct umoscom_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
- struct usb2_xfer *sc_xfer_data[UMOSCOM_N_DATA_TRANSFER];
+ struct usb2_xfer *sc_xfer[UMOSCOM_N_TRANSFER];
struct usb2_device *sc_udev;
uint8_t sc_mcr;
@@ -201,9 +209,9 @@ static void umoscom_stop_read(struct usb2_com_softc *);
static void umoscom_start_write(struct usb2_com_softc *);
static void umoscom_stop_write(struct usb2_com_softc *);
-static const struct usb2_config umoscom_config_data[UMOSCOM_N_DATA_TRANSFER] = {
+static const struct usb2_config umoscom_config_data[UMOSCOM_N_TRANSFER] = {
- [0] = {
+ [UMOSCOM_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -212,7 +220,7 @@ static const struct usb2_config umoscom_config_data[UMOSCOM_N_DATA_TRANSFER] = {
.mh.callback = &umoscom_write_callback,
},
- [1] = {
+ [UMOSCOM_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -221,7 +229,7 @@ static const struct usb2_config umoscom_config_data[UMOSCOM_N_DATA_TRANSFER] = {
.mh.callback = &umoscom_read_callback,
},
- [2] = {
+ [UMOSCOM_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -231,7 +239,7 @@ static const struct usb2_config umoscom_config_data[UMOSCOM_N_DATA_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UMOSCOM_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -241,7 +249,7 @@ static const struct usb2_config umoscom_config_data[UMOSCOM_N_DATA_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [UMOSCOM_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -250,7 +258,7 @@ static const struct usb2_config umoscom_config_data[UMOSCOM_N_DATA_TRANSFER] = {
.mh.callback = &umoscom_intr_callback,
},
- [5] = {
+ [UMOSCOM_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -327,9 +335,6 @@ umoscom_attach(device_t dev)
int error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_udev = uaa->device;
sc->sc_mcr = 0x08; /* enable interrupts */
@@ -339,8 +344,8 @@ umoscom_attach(device_t dev)
iface_index = UMOSCOM_IFACE_INDEX;
error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer_data, umoscom_config_data,
- UMOSCOM_N_DATA_TRANSFER, sc, &Giant);
+ sc->sc_xfer, umoscom_config_data,
+ UMOSCOM_N_TRANSFER, sc, &Giant);
if (error) {
goto detach;
@@ -373,7 +378,7 @@ umoscom_detach(device_t dev)
usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
- usb2_transfer_unsetup(sc->sc_xfer_data, UMOSCOM_N_DATA_TRANSFER);
+ usb2_transfer_unsetup(sc->sc_xfer, UMOSCOM_N_TRANSFER);
return (0);
}
@@ -607,10 +612,10 @@ umoscom_start_read(struct usb2_com_softc *ucom)
#if 0
/* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer_data[4]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
#endif
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer_data[1]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
}
static void
@@ -619,12 +624,12 @@ umoscom_stop_read(struct usb2_com_softc *ucom)
struct umoscom_softc *sc = ucom->sc_parent;
/* stop interrupt transfer */
- usb2_transfer_stop(sc->sc_xfer_data[5]);
- usb2_transfer_stop(sc->sc_xfer_data[4]);
+ usb2_transfer_stop(sc->sc_xfer[UMOSCOM_INTR_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer_data[3]);
- usb2_transfer_stop(sc->sc_xfer_data[1]);
+ usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
}
static void
@@ -632,7 +637,7 @@ umoscom_start_write(struct usb2_com_softc *ucom)
{
struct umoscom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer_data[0]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
}
static void
@@ -640,8 +645,8 @@ umoscom_stop_write(struct usb2_com_softc *ucom)
{
struct umoscom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer_data[2]);
- usb2_transfer_stop(sc->sc_xfer_data[0]);
+ usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
}
static void
@@ -656,7 +661,7 @@ umoscom_write_callback(struct usb2_xfer *xfer)
DPRINTF("\n");
if (sc->sc_flags & UMOSCOM_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer_data[2]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -671,7 +676,7 @@ umoscom_write_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
DPRINTFN(0, "transfer failed\n");
sc->sc_flags |= UMOSCOM_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer_data[2]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_WR]);
}
return;
}
@@ -681,7 +686,7 @@ static void
umoscom_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct umoscom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_data[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMOSCOM_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -704,7 +709,7 @@ umoscom_read_callback(struct usb2_xfer *xfer)
DPRINTF("\n");
if (sc->sc_flags & UMOSCOM_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer_data[3]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -715,7 +720,7 @@ umoscom_read_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
DPRINTFN(0, "transfer failed\n");
sc->sc_flags |= UMOSCOM_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer_data[3]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_RD]);
}
return;
@@ -726,7 +731,7 @@ static void
umoscom_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct umoscom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_data[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMOSCOM_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -751,7 +756,7 @@ umoscom_intr_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & UMOSCOM_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer_data[5]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -762,7 +767,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
DPRINTFN(0, "transfer failed\n");
sc->sc_flags |= UMOSCOM_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer_data[5]);
+ usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_CS_RD]);
}
return;
}
@@ -772,7 +777,7 @@ static void
umoscom_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct umoscom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer_data[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UMOSCOM_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/uplcom2.c b/sys/dev/usb2/serial/uplcom2.c
index 9a51eb5..ddc0a1f 100644
--- a/sys/dev/usb2/serial/uplcom2.c
+++ b/sys/dev/usb2/serial/uplcom2.c
@@ -95,7 +95,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -122,7 +121,6 @@ SYSCTL_INT(_hw_usb2_uplcom, OID_AUTO, debug, CTLFLAG_RW,
#endif
#define UPLCOM_BULK_BUF_SIZE 1024 /* bytes */
-#define UPLCOM_N_TRANSFER 6
#define UPLCOM_SET_REQUEST 0x01
#define UPLCOM_SET_CRTSCTS 0x41
@@ -134,6 +132,16 @@ SYSCTL_INT(_hw_usb2_uplcom, OID_AUTO, debug, CTLFLAG_RW,
#define TYPE_PL2303 0
#define TYPE_PL2303X 1
+enum {
+ UPLCOM_BULK_DT_WR,
+ UPLCOM_BULK_DT_RD,
+ UPLCOM_BULK_CS_WR,
+ UPLCOM_BULK_CS_RD,
+ UPLCOM_INTR_DT_RD,
+ UPLCOM_INTR_CS_RD,
+ UPLCOM_N_TRANSFER = 6,
+};
+
struct uplcom_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
@@ -171,8 +179,6 @@ static void uplcom_start_write(struct usb2_com_softc *);
static void uplcom_stop_write(struct usb2_com_softc *);
static void uplcom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
uint8_t *);
-static int uplcom_ioctl(struct usb2_com_softc *, uint32_t, caddr_t, int,
- struct thread *);
static void uplcom_cfg_do_request(struct uplcom_softc *,
struct usb2_device_request *, void *);
@@ -189,7 +195,7 @@ static usb2_callback_t uplcom_read_clear_stall_callback;
static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
- [0] = {
+ [UPLCOM_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -199,7 +205,7 @@ static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
.if_index = 0,
},
- [1] = {
+ [UPLCOM_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -209,7 +215,7 @@ static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
.if_index = 0,
},
- [2] = {
+ [UPLCOM_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -220,7 +226,7 @@ static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
.if_index = 0,
},
- [3] = {
+ [UPLCOM_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -231,7 +237,7 @@ static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
.if_index = 0,
},
- [4] = {
+ [UPLCOM_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -241,7 +247,7 @@ static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
.if_index = 1,
},
- [5] = {
+ [UPLCOM_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -260,7 +266,6 @@ struct usb2_com_callback uplcom_callback = {
.usb2_com_cfg_set_break = &uplcom_cfg_set_break,
.usb2_com_cfg_param = &uplcom_cfg_param,
.usb2_com_pre_param = &uplcom_pre_param,
- .usb2_com_ioctl = &uplcom_ioctl,
.usb2_com_start_read = &uplcom_start_read,
.usb2_com_stop_read = &uplcom_stop_read,
.usb2_com_start_write = &uplcom_start_write,
@@ -366,9 +371,6 @@ uplcom_attach(device_t dev)
DPRINTFN(11, "\n");
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
DPRINTF("sc = %p\n", sc);
@@ -721,10 +723,10 @@ uplcom_start_read(struct usb2_com_softc *ucom)
struct uplcom_softc *sc = ucom->sc_parent;
/* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[4]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_DT_RD]);
/* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
}
static void
@@ -733,11 +735,11 @@ uplcom_stop_read(struct usb2_com_softc *ucom)
struct uplcom_softc *sc = ucom->sc_parent;
/* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[4]);
+ usb2_transfer_stop(sc->sc_xfer[UPLCOM_INTR_DT_RD]);
/* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
}
static void
@@ -745,7 +747,7 @@ uplcom_start_write(struct usb2_com_softc *ucom)
{
struct uplcom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
}
static void
@@ -753,8 +755,8 @@ uplcom_stop_write(struct usb2_com_softc *ucom)
{
struct uplcom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
}
static void
@@ -768,13 +770,6 @@ uplcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
*msr = sc->sc_msr;
}
-static int
-uplcom_ioctl(struct usb2_com_softc *ucom, uint32_t cmd, caddr_t data, int flag,
- struct thread *td)
-{
- return (ENOTTY);
-}
-
static void
uplcom_intr_callback(struct usb2_xfer *xfer)
{
@@ -808,7 +803,7 @@ uplcom_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
if (sc->sc_flag & UPLCOM_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -818,7 +813,7 @@ uplcom_intr_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UPLCOM_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_CS_RD]);
}
return;
@@ -829,7 +824,7 @@ static void
uplcom_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uplcom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -848,7 +843,7 @@ uplcom_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UPLCOM_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -864,7 +859,7 @@ uplcom_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UPLCOM_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_WR]);
}
return;
@@ -875,7 +870,7 @@ static void
uplcom_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uplcom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -895,7 +890,7 @@ uplcom_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UPLCOM_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -905,7 +900,7 @@ uplcom_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UPLCOM_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_RD]);
}
return;
@@ -916,7 +911,7 @@ static void
uplcom_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uplcom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/usb2_serial.c b/sys/dev/usb2/serial/usb2_serial.c
index 8872c79..565c70b 100644
--- a/sys/dev/usb2/serial/usb2_serial.c
+++ b/sys/dev/usb2/serial/usb2_serial.c
@@ -78,13 +78,10 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/include/usb2_cdc.h>
#define USB_DEBUG_VAR usb2_com_debug
-#define usb2_config_td_cc usb2_com_config_copy
-#define usb2_config_td_softc usb2_com_softc
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_util.h>
@@ -99,30 +96,26 @@ SYSCTL_INT(_hw_usb2_ucom, OID_AUTO, debug, CTLFLAG_RW,
&usb2_com_debug, 0, "ucom debug level");
#endif
-struct usb2_com_config_copy {
- struct usb2_com_softc *cc_softc;
- uint8_t cc_flag0;
- uint8_t cc_flag1;
- uint8_t cc_flag2;
- uint8_t cc_flag3;
-};
-
-static usb2_config_td_command_t usb2_com_config_copy;
-static usb2_config_td_command_t usb2_com_cfg_start_transfers;
-static usb2_config_td_command_t usb2_com_cfg_open;
-static usb2_config_td_command_t usb2_com_cfg_close;
-static usb2_config_td_command_t usb2_com_cfg_break;
-static usb2_config_td_command_t usb2_com_cfg_dtr;
-static usb2_config_td_command_t usb2_com_cfg_rts;
-static usb2_config_td_command_t usb2_com_cfg_status_change;
-static usb2_config_td_command_t usb2_com_cfg_param;
+static usb2_proc_callback_t usb2_com_cfg_start_transfers;
+static usb2_proc_callback_t usb2_com_cfg_open;
+static usb2_proc_callback_t usb2_com_cfg_close;
+static usb2_proc_callback_t usb2_com_cfg_break_on;
+static usb2_proc_callback_t usb2_com_cfg_break_off;
+static usb2_proc_callback_t usb2_com_cfg_dtr_on;
+static usb2_proc_callback_t usb2_com_cfg_dtr_off;
+static usb2_proc_callback_t usb2_com_cfg_rts_on;
+static usb2_proc_callback_t usb2_com_cfg_rts_off;
+static usb2_proc_callback_t usb2_com_cfg_status_change;
+static usb2_proc_callback_t usb2_com_cfg_param;
static uint8_t usb2_com_units_alloc(uint32_t, uint32_t *);
static void usb2_com_units_free(uint32_t, uint32_t);
static int usb2_com_attach_sub(struct usb2_com_softc *);
static void usb2_com_detach_sub(struct usb2_com_softc *);
-static void usb2_com_queue_command(struct usb2_com_softc *,
- usb2_config_td_command_t *, int);
+static void usb2_com_queue_command(struct usb2_com_softc *sc,
+ uint8_t cmd);
+static void usb2_com_wait_command(struct usb2_com_softc *sc,
+ uint8_t cmd);
static void usb2_com_shutdown(struct usb2_com_softc *);
static void usb2_com_start_transfers(struct usb2_com_softc *);
static void usb2_com_break(struct usb2_com_softc *, uint8_t);
@@ -251,9 +244,7 @@ usb2_com_attach(struct usb2_com_super_softc *ssc, struct usb2_com_softc *sc,
if (usb2_com_units_alloc(sub_units, &root_unit)) {
return (ENOMEM);
}
- if (usb2_config_td_setup
- (&ssc->sc_config_td, sc, p_mtx, NULL,
- sizeof(struct usb2_com_config_copy), 24 * sub_units)) {
+ if (usb2_proc_setup(&ssc->sc_config_td, p_mtx, USB_PRI_MED)) {
usb2_com_units_free(root_unit, sub_units);
return (ENOMEM);
}
@@ -285,7 +276,7 @@ usb2_com_detach(struct usb2_com_super_softc *ssc, struct usb2_com_softc *sc,
{
uint32_t n;
- usb2_config_td_drain(&ssc->sc_config_td);
+ usb2_proc_drain(&ssc->sc_config_td);
for (n = 0; n < sub_units; n++, sc++) {
if (sc->sc_flag & UCOM_FLAG_ATTACHED) {
@@ -298,8 +289,7 @@ usb2_com_detach(struct usb2_com_super_softc *ssc, struct usb2_com_softc *sc,
sc->sc_flag &= ~UCOM_FLAG_ATTACHED;
}
}
-
- usb2_config_td_unsetup(&ssc->sc_config_td);
+ usb2_proc_unsetup(&ssc->sc_config_td);
}
static int
@@ -307,6 +297,7 @@ usb2_com_attach_sub(struct usb2_com_softc *sc)
{
struct tty *tp;
int error = 0;
+ uint8_t n;
char buf[32]; /* temporary TTY device name buffer */
tp = tty_alloc(&usb2_com_class, sc, sc->sc_parent_mtx);
@@ -336,6 +327,39 @@ usb2_com_attach_sub(struct usb2_com_softc *sc)
DPRINTF("ttycreate: %s\n", buf);
usb2_cv_init(&sc->sc_cv, "usb2_com");
+ /*
+ * Set all function callback pointers for deferred COM
+ * operations:
+ */
+ for (n = 0; n != 2; n++) {
+ sc->sc_cmds[(2*USB_COM_CFG_START_TRANSFERS) + n].hdr.pm_callback =
+ &usb2_com_cfg_start_transfers;
+ sc->sc_cmds[(2*USB_COM_CFG_OPEN) + n].hdr.pm_callback =
+ &usb2_com_cfg_open;
+ sc->sc_cmds[(2*USB_COM_CFG_CLOSE) + n].hdr.pm_callback =
+ &usb2_com_cfg_close;
+ sc->sc_cmds[(2*USB_COM_CFG_BREAK_ON) + n].hdr.pm_callback =
+ &usb2_com_cfg_break_on;
+ sc->sc_cmds[(2*USB_COM_CFG_BREAK_OFF) + n].hdr.pm_callback =
+ &usb2_com_cfg_break_off;
+ sc->sc_cmds[(2*USB_COM_CFG_DTR_ON) + n].hdr.pm_callback =
+ &usb2_com_cfg_dtr_on;
+ sc->sc_cmds[(2*USB_COM_CFG_DTR_OFF) + n].hdr.pm_callback =
+ &usb2_com_cfg_dtr_off;
+ sc->sc_cmds[(2*USB_COM_CFG_RTS_ON) + n].hdr.pm_callback =
+ &usb2_com_cfg_rts_on;
+ sc->sc_cmds[(2*USB_COM_CFG_RTS_OFF) + n].hdr.pm_callback =
+ &usb2_com_cfg_rts_off;
+ sc->sc_cmds[(2*USB_COM_CFG_STATUS_CHANGE) + n].hdr.pm_callback =
+ &usb2_com_cfg_status_change;
+ sc->sc_cmds[(2*USB_COM_CFG_PARAM) + n].hdr.pm_callback =
+ &usb2_com_cfg_param;
+ }
+
+ /* initialise all callback pointer arguments */
+ for (n = 0; n != (2*USB_COM_CFG_MAX); n++) {
+ sc->sc_cmds[n].cc_softc = sc;
+ }
done:
return (error);
}
@@ -379,27 +403,41 @@ usb2_com_detach_sub(struct usb2_com_softc *sc)
usb2_cv_destroy(&sc->sc_cv);
}
+/*
+ * The following function queues a command for deferred execution.
+ * The following function must be called locked.
+ */
static void
-usb2_com_config_copy(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_queue_command(struct usb2_com_softc *sc, uint8_t cmd)
{
- cc->cc_softc = sc + (refcount % UCOM_SUB_UNIT_MAX);
- cc->cc_flag0 = (refcount / (1 * UCOM_SUB_UNIT_MAX)) % 2;
- cc->cc_flag1 = (refcount / (2 * UCOM_SUB_UNIT_MAX)) % 2;
- cc->cc_flag2 = (refcount / (4 * UCOM_SUB_UNIT_MAX)) % 2;
- cc->cc_flag3 = (refcount / (8 * UCOM_SUB_UNIT_MAX)) % 2;
+ struct usb2_com_super_softc *ssc = sc->sc_super;
+
+ if (usb2_proc_is_gone(&ssc->sc_config_td)) {
+ DPRINTF("proc is gone\n");
+ return; /* nothing to do */
+ }
+
+ if (usb2_proc_msignal(&ssc->sc_config_td,
+ &sc->sc_cmds[2*cmd], &sc->sc_cmds[(2*cmd)+1])) {
+ /* ignore */
+ }
}
+/*
+ * The following function waits until a command has been executed.
+ * The following function must be called locked.
+ */
static void
-usb2_com_queue_command(struct usb2_com_softc *sc, usb2_config_td_command_t *cmd, int flag)
+usb2_com_wait_command(struct usb2_com_softc *sc, uint8_t cmd)
{
struct usb2_com_super_softc *ssc = sc->sc_super;
- usb2_config_td_queue_command
- (&ssc->sc_config_td, &usb2_com_config_copy,
- cmd, (cmd == &usb2_com_cfg_status_change) ? 1 : 0,
- ((sc->sc_local_unit % UCOM_SUB_UNIT_MAX) +
- (flag ? UCOM_SUB_UNIT_MAX : 0)));
+ if (usb2_proc_is_gone(&ssc->sc_config_td)) {
+ DPRINTF("proc is gone\n");
+ return; /* nothing to do */
+ }
+ usb2_proc_mwait(&ssc->sc_config_td,
+ &sc->sc_cmds[2*cmd], &sc->sc_cmds[(2*cmd)+1]);
}
static void
@@ -420,6 +458,8 @@ usb2_com_shutdown(struct usb2_com_softc *sc)
}
/*
+ * This function will sleep "timeout" system ticks.
+ *
* Return values:
* 0: normal delay
* else: config thread is gone
@@ -428,8 +468,26 @@ uint8_t
usb2_com_cfg_sleep(struct usb2_com_softc *sc, uint32_t timeout)
{
struct usb2_com_super_softc *ssc = sc->sc_super;
+ uint8_t is_gone;
+
+ is_gone = usb2_proc_is_gone(&ssc->sc_config_td);
+ if (is_gone)
+ goto done; /* we are detaching */
+ if (timeout == 0)
+ timeout = 1; /* one tick is the least timeout */
+
+ mtx_unlock(sc->sc_parent_mtx);
+
+ if (pause("UCOMWAIT", timeout)) {
+ /* ignore */
+ }
- return (usb2_config_td_sleep(&ssc->sc_config_td, timeout));
+ mtx_lock(sc->sc_parent_mtx);
+
+ /* refresh gone status */
+ is_gone = usb2_proc_is_gone(&ssc->sc_config_td);
+done:
+ return (is_gone);
}
/*
@@ -442,13 +500,15 @@ usb2_com_cfg_is_gone(struct usb2_com_softc *sc)
{
struct usb2_com_super_softc *ssc = sc->sc_super;
- return (usb2_config_td_is_gone(&ssc->sc_config_td));
+ return (usb2_proc_is_gone(&ssc->sc_config_td));
}
static void
-usb2_com_cfg_start_transfers(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_start_transfers(struct usb2_proc_msg *_cc)
{
+ struct usb2_com_command_msg *cc = (void *)_cc;
+ struct usb2_com_softc *sc;
+
sc = cc->cc_softc;
if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
@@ -485,14 +545,16 @@ usb2_com_start_transfers(struct usb2_com_softc *sc)
(sc->sc_callback->usb2_com_start_write) (sc);
}
if (!(sc->sc_flag & UCOM_FLAG_GP_DATA)) {
- usb2_com_queue_command(sc, &usb2_com_cfg_start_transfers, 0);
+ usb2_com_queue_command(sc, USB_COM_CFG_START_TRANSFERS);
}
}
static void
-usb2_com_cfg_open(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_open(struct usb2_proc_msg *_cc)
{
+ struct usb2_com_command_msg *cc = (void *)_cc;
+ struct usb2_com_softc *sc;
+
sc = cc->cc_softc;
DPRINTF("\n");
@@ -550,7 +612,7 @@ usb2_com_open(struct tty *tp)
sc->sc_msr = 0;
sc->sc_mcr = 0;
- usb2_com_queue_command(sc, &usb2_com_cfg_open, 0);
+ usb2_com_queue_command(sc, USB_COM_CFG_OPEN);
usb2_com_start_transfers(sc);
@@ -564,9 +626,11 @@ usb2_com_open(struct tty *tp)
}
static void
-usb2_com_cfg_close(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_close(struct usb2_proc_msg *_cc)
{
+ struct usb2_com_command_msg *cc = (void *)_cc;
+ struct usb2_com_softc *sc;
+
sc = cc->cc_softc;
DPRINTF("\n");
@@ -588,7 +652,7 @@ static void
usb2_com_close(struct tty *tp)
{
struct usb2_com_softc *sc = tty_softc(tp);
-
+
mtx_assert(sc->sc_parent_mtx, MA_OWNED);
DPRINTF("tp=%p\n", tp);
@@ -599,7 +663,9 @@ usb2_com_close(struct tty *tp)
}
usb2_com_shutdown(sc);
- usb2_com_queue_command(sc, &usb2_com_cfg_close, 0);
+ /* Queue and wait for close command to complete */
+ usb2_com_queue_command(sc, USB_COM_CFG_CLOSE);
+ usb2_com_wait_command(sc, USB_COM_CFG_CLOSE);
sc->sc_flag &= ~(UCOM_FLAG_HL_READY |
UCOM_FLAG_WR_START |
@@ -702,22 +768,35 @@ usb2_com_modem(struct tty *tp, int sigon, int sigoff)
}
static void
-usb2_com_cfg_break(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_break(struct usb2_com_command_msg *cc, uint8_t onoff)
{
+ struct usb2_com_softc *sc;
+
sc = cc->cc_softc;
if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
return;
}
- DPRINTF("onoff=%d\n", cc->cc_flag0);
+ DPRINTF("onoff=%d\n", onoff);
if (sc->sc_callback->usb2_com_cfg_set_break) {
- (sc->sc_callback->usb2_com_cfg_set_break) (sc, cc->cc_flag0);
+ (sc->sc_callback->usb2_com_cfg_set_break) (sc, onoff);
}
}
static void
+usb2_com_cfg_break_on(struct usb2_proc_msg *_cc)
+{
+ usb2_com_cfg_break((void *)_cc, 1);
+}
+
+static void
+usb2_com_cfg_break_off(struct usb2_proc_msg *_cc)
+{
+ usb2_com_cfg_break((void *)_cc, 0);
+}
+
+static void
usb2_com_break(struct usb2_com_softc *sc, uint8_t onoff)
{
mtx_assert(sc->sc_parent_mtx, MA_OWNED);
@@ -727,26 +806,40 @@ usb2_com_break(struct usb2_com_softc *sc, uint8_t onoff)
}
DPRINTF("onoff = %d\n", onoff);
- usb2_com_queue_command(sc, &usb2_com_cfg_break, onoff);
+ usb2_com_queue_command(sc, onoff ?
+ USB_COM_CFG_BREAK_ON : USB_COM_CFG_BREAK_OFF);
}
static void
-usb2_com_cfg_dtr(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_dtr(struct usb2_com_command_msg *cc, uint8_t onoff)
{
+ struct usb2_com_softc *sc;
+
sc = cc->cc_softc;
if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
return;
}
- DPRINTF("onoff=%d\n", cc->cc_flag0);
+ DPRINTF("onoff=%d\n", onoff);
if (sc->sc_callback->usb2_com_cfg_set_dtr) {
- (sc->sc_callback->usb2_com_cfg_set_dtr) (sc, cc->cc_flag0);
+ (sc->sc_callback->usb2_com_cfg_set_dtr) (sc, onoff);
}
}
static void
+usb2_com_cfg_dtr_on(struct usb2_proc_msg *_cc)
+{
+ usb2_com_cfg_dtr((void *)_cc, 1);
+}
+
+static void
+usb2_com_cfg_dtr_off(struct usb2_proc_msg *_cc)
+{
+ usb2_com_cfg_dtr((void *)_cc, 0);
+}
+
+static void
usb2_com_dtr(struct usb2_com_softc *sc, uint8_t onoff)
{
mtx_assert(sc->sc_parent_mtx, MA_OWNED);
@@ -756,26 +849,40 @@ usb2_com_dtr(struct usb2_com_softc *sc, uint8_t onoff)
}
DPRINTF("onoff = %d\n", onoff);
- usb2_com_queue_command(sc, &usb2_com_cfg_dtr, onoff);
+ usb2_com_queue_command(sc, onoff ?
+ USB_COM_CFG_DTR_ON : USB_COM_CFG_DTR_OFF);
}
static void
-usb2_com_cfg_rts(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_rts(struct usb2_com_command_msg *cc, uint8_t onoff)
{
+ struct usb2_com_softc *sc;
+
sc = cc->cc_softc;
- DPRINTF("onoff=%d\n", cc->cc_flag0);
+ DPRINTF("onoff=%d\n", onoff);
if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
return;
}
if (sc->sc_callback->usb2_com_cfg_set_rts) {
- (sc->sc_callback->usb2_com_cfg_set_rts) (sc, cc->cc_flag0);
+ (sc->sc_callback->usb2_com_cfg_set_rts) (sc, onoff);
}
}
static void
+usb2_com_cfg_rts_on(struct usb2_proc_msg *_cc)
+{
+ usb2_com_cfg_rts((void *)_cc, 1);
+}
+
+static void
+usb2_com_cfg_rts_off(struct usb2_proc_msg *_cc)
+{
+ usb2_com_cfg_rts((void *)_cc, 0);
+}
+
+static void
usb2_com_rts(struct usb2_com_softc *sc, uint8_t onoff)
{
mtx_assert(sc->sc_parent_mtx, MA_OWNED);
@@ -785,13 +892,15 @@ usb2_com_rts(struct usb2_com_softc *sc, uint8_t onoff)
}
DPRINTF("onoff = %d\n", onoff);
- usb2_com_queue_command(sc, &usb2_com_cfg_rts, onoff);
+ usb2_com_queue_command(sc, onoff ?
+ USB_COM_CFG_RTS_ON : USB_COM_CFG_RTS_OFF);
}
static void
-usb2_com_cfg_status_change(struct usb2_com_softc *sc,
- struct usb2_com_config_copy *cc, uint16_t refcount)
+usb2_com_cfg_status_change(struct usb2_proc_msg *_cc)
{
+ struct usb2_com_command_msg *cc = (void *)_cc;
+ struct usb2_com_softc *sc;
struct tty *tp;
uint8_t new_msr;
@@ -845,13 +954,14 @@ usb2_com_status_change(struct usb2_com_softc *sc)
}
DPRINTF("\n");
- usb2_com_queue_command(sc, &usb2_com_cfg_status_change, 0);
+ usb2_com_queue_command(sc, USB_COM_CFG_STATUS_CHANGE);
}
static void
-usb2_com_cfg_param(struct usb2_com_softc *sc, struct usb2_com_config_copy *cc,
- uint16_t refcount)
+usb2_com_cfg_param(struct usb2_proc_msg *_cc)
{
+ struct usb2_com_command_msg *cc = (void *)_cc;
+ struct usb2_com_softc *sc;
struct termios t_copy;
sc = cc->cc_softc;
@@ -922,7 +1032,7 @@ usb2_com_param(struct tty *tp, struct termios *t)
sc->sc_flag &= ~UCOM_FLAG_GP_DATA;
/* Queue baud rate programming command first */
- usb2_com_queue_command(sc, &usb2_com_cfg_param, 0);
+ usb2_com_queue_command(sc, USB_COM_CFG_PARAM);
/* Queue transfer enable command last */
usb2_com_start_transfers(sc);
diff --git a/sys/dev/usb2/serial/usb2_serial.h b/sys/dev/usb2/serial/usb2_serial.h
index 073208c..3c87a4f 100644
--- a/sys/dev/usb2/serial/usb2_serial.h
+++ b/sys/dev/usb2/serial/usb2_serial.h
@@ -119,11 +119,35 @@ struct usb2_com_callback {
#define ULSR_RXRDY 0x01 /* Byte ready in Receive Buffer */
#define ULSR_RCV_MASK 0x1f /* Mask for incoming data or error */
+/*
+ * List of serial adapter commands or deferred function calls:
+ */
+enum {
+ USB_COM_CFG_START_TRANSFERS,
+ USB_COM_CFG_OPEN,
+ USB_COM_CFG_CLOSE,
+ USB_COM_CFG_BREAK_ON,
+ USB_COM_CFG_BREAK_OFF,
+ USB_COM_CFG_DTR_ON,
+ USB_COM_CFG_DTR_OFF,
+ USB_COM_CFG_RTS_ON,
+ USB_COM_CFG_RTS_OFF,
+ USB_COM_CFG_STATUS_CHANGE,
+ USB_COM_CFG_PARAM,
+ USB_COM_CFG_MAX,
+};
+
+struct usb2_com_command_msg {
+ struct usb2_proc_msg hdr; /* must be first */
+ struct usb2_com_softc *cc_softc;
+};
+
struct usb2_com_super_softc {
- struct usb2_config_td sc_config_td;
+ struct usb2_process sc_config_td;
};
struct usb2_com_softc {
+ struct usb2_com_command_msg sc_cmds[2*USB_COM_CFG_MAX];
struct termios sc_termios_copy;
struct cv sc_cv;
const struct usb2_com_callback *sc_callback;
@@ -146,6 +170,7 @@ struct usb2_com_softc {
uint8_t sc_msr;
uint8_t sc_mcr;
uint8_t sc_ttyfreed; /* set when TTY has been freed */
+ uint8_t sc_last_cmd_flag[USB_COM_CFG_MAX];
};
int usb2_com_attach(struct usb2_com_super_softc *ssc,
diff --git a/sys/dev/usb2/serial/uvisor2.c b/sys/dev/usb2/serial/uvisor2.c
index 3fb5d45..468751e 100644
--- a/sys/dev/usb2/serial/uvisor2.c
+++ b/sys/dev/usb2/serial/uvisor2.c
@@ -66,7 +66,6 @@
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -84,7 +83,6 @@ SYSCTL_INT(_hw_usb2_uvisor, OID_AUTO, debug, CTLFLAG_RW,
#define UVISOR_CONFIG_INDEX 0
#define UVISOR_IFACE_INDEX 0
-#define UVISOR_N_TRANSFER 4 /* units */
#define UVISOR_BUFSIZE 1024 /* bytes */
/* From the Linux driver */
@@ -150,6 +148,14 @@ struct uvisor_palm_connection_info {
} __packed connections[UVISOR_MAX_CONN];
} __packed;
+enum {
+ UVISOR_BULK_DT_WR,
+ UVISOR_BULK_DT_RD,
+ UVISOR_BULK_CS_WR,
+ UVISOR_BULK_CS_RD,
+ UVISOR_N_TRANSFER = 4,
+};
+
struct uvisor_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
@@ -191,7 +197,7 @@ static void uvisor_stop_write(struct usb2_com_softc *);
static const struct usb2_config uvisor_config[UVISOR_N_TRANSFER] = {
- [0] = {
+ [UVISOR_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -200,7 +206,7 @@ static const struct usb2_config uvisor_config[UVISOR_N_TRANSFER] = {
.mh.callback = &uvisor_write_callback,
},
- [1] = {
+ [UVISOR_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -209,7 +215,7 @@ static const struct usb2_config uvisor_config[UVISOR_N_TRANSFER] = {
.mh.callback = &uvisor_read_callback,
},
- [2] = {
+ [UVISOR_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -219,7 +225,7 @@ static const struct usb2_config uvisor_config[UVISOR_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UVISOR_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -315,9 +321,6 @@ uvisor_attach(device_t dev)
DPRINTF("sc=%p\n", sc);
bcopy(uvisor_config, uvisor_config_copy,
sizeof(uvisor_config_copy));
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
@@ -553,7 +556,7 @@ uvisor_start_read(struct usb2_com_softc *ucom)
{
struct uvisor_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_DT_RD]);
}
static void
@@ -561,8 +564,8 @@ uvisor_stop_read(struct usb2_com_softc *ucom)
{
struct uvisor_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_DT_RD]);
}
static void
@@ -570,7 +573,7 @@ uvisor_start_write(struct usb2_com_softc *ucom)
{
struct uvisor_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_DT_WR]);
}
static void
@@ -578,8 +581,8 @@ uvisor_stop_write(struct usb2_com_softc *ucom)
{
struct uvisor_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_DT_WR]);
}
static void
@@ -592,7 +595,7 @@ uvisor_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UVISOR_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -606,7 +609,7 @@ uvisor_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UVISOR_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_WR]);
}
return;
@@ -617,7 +620,7 @@ static void
uvisor_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uvisor_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UVISOR_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -637,7 +640,7 @@ uvisor_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UVISOR_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -647,7 +650,7 @@ uvisor_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UVISOR_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_RD]);
}
return;
@@ -658,7 +661,7 @@ static void
uvisor_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uvisor_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UVISOR_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
diff --git a/sys/dev/usb2/serial/uvscom2.c b/sys/dev/usb2/serial/uvscom2.c
index 8f4094f..05e886e 100644
--- a/sys/dev/usb2/serial/uvscom2.c
+++ b/sys/dev/usb2/serial/uvscom2.c
@@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -123,7 +122,15 @@ SYSCTL_INT(_hw_usb2_uvscom, OID_AUTO, debug, CTLFLAG_RW,
#define UVSCOM_BULK_BUF_SIZE 1024 /* bytes */
-#define UVSCOM_N_TRANSFER 6 /* units */
+enum {
+ UVSCOM_BULK_DT_WR,
+ UVSCOM_BULK_DT_RD,
+ UVSCOM_BULK_CS_WR,
+ UVSCOM_BULK_CS_RD,
+ UVSCOM_INTR_DT_RD,
+ UVSCOM_INTR_CS_RD,
+ UVSCOM_N_TRANSFER = 6,
+};
struct uvscom_softc {
struct usb2_com_super_softc sc_super_ucom;
@@ -172,14 +179,12 @@ static void uvscom_start_write(struct usb2_com_softc *);
static void uvscom_stop_write(struct usb2_com_softc *);
static void uvscom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
uint8_t *);
-static int uvscom_ioctl(struct usb2_com_softc *, uint32_t, caddr_t, int,
- struct thread *);
static void uvscom_cfg_write(struct uvscom_softc *, uint8_t, uint16_t);
static uint16_t uvscom_cfg_read_status(struct uvscom_softc *);
static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
- [0] = {
+ [UVSCOM_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -188,7 +193,7 @@ static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
.mh.callback = &uvscom_write_callback,
},
- [1] = {
+ [UVSCOM_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -197,7 +202,7 @@ static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
.mh.callback = &uvscom_read_callback,
},
- [2] = {
+ [UVSCOM_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -207,7 +212,7 @@ static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [UVSCOM_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -217,7 +222,7 @@ static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [4] = {
+ [UVSCOM_INTR_DT_RD] = {
.type = UE_INTERRUPT,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -226,7 +231,7 @@ static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
.mh.callback = &uvscom_intr_callback,
},
- [5] = {
+ [UVSCOM_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -247,7 +252,6 @@ static const struct usb2_com_callback uvscom_callback = {
.usb2_com_cfg_close = &uvscom_cfg_close,
.usb2_com_pre_open = &uvscom_pre_open,
.usb2_com_pre_param = &uvscom_pre_param,
- .usb2_com_ioctl = &uvscom_ioctl,
.usb2_com_start_read = &uvscom_start_read,
.usb2_com_stop_read = &uvscom_stop_read,
.usb2_com_start_write = &uvscom_start_write,
@@ -311,9 +315,6 @@ uvscom_attach(device_t dev)
struct uvscom_softc *sc = device_get_softc(dev);
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
@@ -342,9 +343,9 @@ uvscom_attach(device_t dev)
goto detach;
}
/* start interrupt pipe */
- USB_XFER_LOCK(sc->sc_xfer[4]);
- usb2_transfer_start(sc->sc_xfer[4]);
- USB_XFER_UNLOCK(sc->sc_xfer[4]);
+ mtx_lock(&Giant);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
+ mtx_unlock(&Giant);
return (0);
@@ -362,8 +363,8 @@ uvscom_detach(device_t dev)
/* stop interrupt pipe */
- if (sc->sc_xfer[4]) {
- usb2_transfer_stop(sc->sc_xfer[4]);
+ if (sc->sc_xfer[UVSCOM_INTR_DT_RD]) {
+ usb2_transfer_stop(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
}
usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
@@ -382,7 +383,7 @@ uvscom_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
case USB_ST_TRANSFERRED:
if (sc->sc_flag & UVSCOM_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_CS_WR]);
return;
}
if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
@@ -396,7 +397,7 @@ uvscom_write_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UVSCOM_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_CS_WR]);
}
return;
@@ -407,7 +408,7 @@ static void
uvscom_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uvscom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UVSCOM_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -427,7 +428,7 @@ uvscom_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flag & UVSCOM_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -437,7 +438,7 @@ uvscom_read_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UVSCOM_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_CS_RD]);
}
return;
@@ -448,7 +449,7 @@ static void
uvscom_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uvscom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UVSCOM_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -496,7 +497,7 @@ uvscom_intr_callback(struct usb2_xfer *xfer)
}
case USB_ST_SETUP:
if (sc->sc_flag & UVSCOM_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_INTR_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -506,7 +507,7 @@ uvscom_intr_callback(struct usb2_xfer *xfer)
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
sc->sc_flag |= UVSCOM_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[5]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_INTR_CS_RD]);
}
return;
@@ -517,7 +518,7 @@ static void
uvscom_intr_clear_stall_callback(struct usb2_xfer *xfer)
{
struct uvscom_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[4];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[UVSCOM_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -715,7 +716,7 @@ uvscom_start_read(struct usb2_com_softc *ucom)
{
struct uvscom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[1]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
}
static void
@@ -723,8 +724,8 @@ uvscom_stop_read(struct usb2_com_softc *ucom)
{
struct uvscom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[3]);
- usb2_transfer_stop(sc->sc_xfer[1]);
+ usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
}
static void
@@ -732,7 +733,7 @@ uvscom_start_write(struct usb2_com_softc *ucom)
{
struct uvscom_softc *sc = ucom->sc_parent;
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
}
static void
@@ -740,8 +741,8 @@ uvscom_stop_write(struct usb2_com_softc *ucom)
{
struct uvscom_softc *sc = ucom->sc_parent;
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[0]);
+ usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
}
static void
@@ -753,13 +754,6 @@ uvscom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
*msr = sc->sc_msr;
}
-static int
-uvscom_ioctl(struct usb2_com_softc *ucom, uint32_t cmd, caddr_t data, int fflag,
- struct thread *td)
-{
- return (ENOTTY);
-}
-
static void
uvscom_cfg_write(struct uvscom_softc *sc, uint8_t index, uint16_t value)
{
diff --git a/sys/dev/usb2/sound/uaudio2.c b/sys/dev/usb2/sound/uaudio2.c
index b843ef1..cf4c160 100644
--- a/sys/dev/usb2/sound/uaudio2.c
+++ b/sys/dev/usb2/sound/uaudio2.c
@@ -80,22 +80,27 @@
#include <dev/sound/chip.h>
#include "feeder_if.h"
+static int uaudio_default_rate = 96000;
+static int uaudio_default_bits = 32;
+static int uaudio_default_channels = 2;
+
#if USB_DEBUG
static int uaudio_debug = 0;
SYSCTL_NODE(_hw_usb2, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, debug, CTLFLAG_RW,
&uaudio_debug, 0, "uaudio debug level");
+SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_rate, CTLFLAG_RW,
+ &uaudio_default_rate, 0, "uaudio default sample rate");
+SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_bits, CTLFLAG_RW,
+ &uaudio_default_bits, 0, "uaudio default sample bits");
+SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_channels, CTLFLAG_RW,
+ &uaudio_default_channels, 0, "uaudio default sample channels");
#endif
-static uint32_t uaudio_default_rate = 96000;
-static uint8_t uaudio_default_bits = 32;
-static uint8_t uaudio_default_channels = 2;
-
+#define UAUDIO_MINFRAMES 16 /* must be factor of 8 due HS-USB */
#define UAUDIO_NCHANBUFS 2 /* number of outstanding request */
-#define UAUDIO_NFRAMES 25 /* ms of sound in each request */
#define UAUDIO_RECURSE_LIMIT 24 /* rounds */
-#define UAUDIO_DEFAULT_BUFSZ ((2 * 96000 * 4 * 2) / (1000 / UAUDIO_NCHANBUFS)) /* bytes */
#define MAKE_WORD(h,l) (((h) << 8) | (l))
#define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1)
@@ -154,6 +159,7 @@ struct uaudio_chan {
uint8_t *cur; /* current position in upper layer
* buffer */
+ uint32_t intr_size; /* in bytes */
uint32_t block_size;
uint32_t sample_rate;
uint32_t format;
@@ -389,36 +395,13 @@ static const char *uaudio_mixer_get_terminal_name(uint16_t);
#endif
static const struct usb2_config
- uaudio_cfg_record_full_speed[UAUDIO_NCHANBUFS] = {
- [0] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_record_callback,
- },
-
- [1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_record_callback,
- },
-};
-
-static const struct usb2_config
- uaudio_cfg_record_high_speed[UAUDIO_NCHANBUFS] = {
+ uaudio_cfg_record[UAUDIO_NCHANBUFS] = {
[0] = {
.type = UE_ISOCHRONOUS,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
.mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = (UAUDIO_NFRAMES * 8),
+ .mh.frames = UAUDIO_MINFRAMES,
.mh.flags = {.short_xfer_ok = 1,},
.mh.callback = &uaudio_chan_record_callback,
},
@@ -428,43 +411,20 @@ static const struct usb2_config
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
.mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = (UAUDIO_NFRAMES * 8),
+ .mh.frames = UAUDIO_MINFRAMES,
.mh.flags = {.short_xfer_ok = 1,},
.mh.callback = &uaudio_chan_record_callback,
},
};
static const struct usb2_config
- uaudio_cfg_play_full_speed[UAUDIO_NCHANBUFS] = {
- [0] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_play_callback,
- },
-
- [1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_NFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_play_callback,
- },
-};
-
-static const struct usb2_config
- uaudio_cfg_play_high_speed[UAUDIO_NCHANBUFS] = {
+ uaudio_cfg_play[UAUDIO_NCHANBUFS] = {
[0] = {
.type = UE_ISOCHRONOUS,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
.mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = (UAUDIO_NFRAMES * 8),
+ .mh.frames = UAUDIO_MINFRAMES,
.mh.flags = {.short_xfer_ok = 1,},
.mh.callback = &uaudio_chan_play_callback,
},
@@ -474,7 +434,7 @@ static const struct usb2_config
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
.mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = (UAUDIO_NFRAMES * 8),
+ .mh.frames = UAUDIO_MINFRAMES,
.mh.flags = {.short_xfer_ok = 1,},
.mh.callback = &uaudio_chan_play_callback,
},
@@ -602,9 +562,6 @@ uaudio_attach(device_t dev)
struct usb2_interface_descriptor *id;
device_t child;
- if (sc == NULL) {
- return (ENOMEM);
- }
sc->sc_play_chan.priv_sc = sc;
sc->sc_rec_chan.priv_sc = sc;
sc->sc_udev = uaa->device;
@@ -706,10 +663,6 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_clas
struct uaudio_softc *sc = device_get_softc(device_get_parent(dev));
char status[SND_STATUSLEN];
- if (bootverbose) {
- device_printf(dev, "using a default buffer "
- "size of %u bytes\n", UAUDIO_DEFAULT_BUFSZ);
- }
uaudio_mixer_init(sc);
if (sc->sc_uq_audio_swap_lr) {
@@ -1066,19 +1019,20 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb2_device *udev,
chan->iface_index = curidx;
chan->iface_alt_index = alt_index;
- chan->usb2_cfg =
- (ep_dir == UE_DIR_IN) ?
- ((fps == 1000) ?
- uaudio_cfg_record_full_speed :
- uaudio_cfg_record_high_speed) :
- ((fps == 1000) ?
- uaudio_cfg_play_full_speed :
- uaudio_cfg_play_high_speed);
-
+ if (ep_dir == UE_DIR_IN)
+ chan->usb2_cfg =
+ uaudio_cfg_record;
+ else
+ chan->usb2_cfg =
+ uaudio_cfg_play;
sample_size = ((chan->p_asf1d->bNrChannels *
chan->p_asf1d->bBitResolution) / 8);
+ /*
+ * NOTE: "chan->bytes_per_frame"
+ * should not be zero!
+ */
chan->bytes_per_frame = ((rate / fps) * sample_size);
if (sc->sc_sndstat_valid) {
@@ -1103,15 +1057,26 @@ uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb2_device *udev)
{
uint32_t rate = uaudio_default_rate;
uint32_t z;
- uint16_t fps = (usb2_get_speed(udev) == USB_SPEED_HIGH) ? 8000 : 1000;
+ uint16_t fps = usb2_get_isoc_fps(udev);
uint8_t bits = uaudio_default_bits;
uint8_t y;
uint8_t channels = uaudio_default_channels;
uint8_t x;
bits -= (bits % 8);
+ if ((bits == 0) || (bits > 32)) {
+ /* set a valid value */
+ bits = 32;
+ }
rate -= (rate % fps);
-
+ if ((rate == 0) || (rate > 192000)) {
+ /* set a valid value */
+ rate = 192000 - (192000 % fps);
+ }
+ if ((channels == 0) || (channels > 2)) {
+ /* set a valid value */
+ channels = 2;
+ }
if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) {
sc->sc_sndstat_valid = 1;
}
@@ -1141,21 +1106,23 @@ uaudio_chan_play_callback(struct usb2_xfer *xfer)
{
struct uaudio_chan *ch = xfer->priv_sc;
uint32_t *p_len = xfer->frlengths;
- uint32_t total = (sndbuf_getblkcnt(ch->pcm_buf) *
- sndbuf_getblksz(ch->pcm_buf)) / 2;
+ uint32_t total;
uint32_t blockcount;
uint32_t n;
uint32_t offset;
/* allow dynamic sizing of play buffer */
+ total = ch->intr_size;
+
+ /* allow dynamic sizing of play buffer */
blockcount = total / ch->bytes_per_frame;
- /* align to 8 units */
- blockcount &= ~7;
+ /* align units */
+ blockcount -= (blockcount % UAUDIO_MINFRAMES);
/* range check - min */
if (blockcount == 0) {
- blockcount = 8;
+ blockcount = UAUDIO_MINFRAMES;
}
/* range check - max */
if (blockcount > xfer->max_frame_count) {
@@ -1230,21 +1197,23 @@ uaudio_chan_record_callback(struct usb2_xfer *xfer)
uint32_t *p_len = xfer->frlengths;
uint32_t n;
uint32_t m;
- uint32_t total = (sndbuf_getblkcnt(ch->pcm_buf) *
- sndbuf_getblksz(ch->pcm_buf)) / 2;
+ uint32_t total;
uint32_t blockcount;
uint32_t offset0;
uint32_t offset1;
/* allow dynamic sizing of play buffer */
+ total = ch->intr_size;
+
+ /* allow dynamic sizing of play buffer */
blockcount = total / ch->bytes_per_frame;
- /* align to 8 units */
- blockcount &= ~7;
+ /* align units */
+ blockcount -= (blockcount % UAUDIO_MINFRAMES);
/* range check - min */
if (blockcount == 0) {
- blockcount = 8;
+ blockcount = UAUDIO_MINFRAMES;
}
/* range check - max */
if (blockcount > xfer->max_frame_count) {
@@ -1326,21 +1295,30 @@ uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
{
struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ?
&sc->sc_play_chan : &sc->sc_rec_chan);
+ uint32_t buf_size;
uint8_t endpoint;
uint8_t iface_index;
uint8_t alt_index;
usb2_error_t err;
- ch->buf = malloc(UAUDIO_DEFAULT_BUFSZ, M_DEVBUF, M_WAITOK | M_ZERO);
+ /* compute required buffer size */
+ buf_size = (ch->bytes_per_frame * UAUDIO_MINFRAMES);
+
+ /* setup interrupt interval */
+ ch->intr_size = buf_size;
+
+ /* double buffering */
+ buf_size *= 2;
+ ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO);
if (ch->buf == NULL) {
goto error;
}
- if (sndbuf_setup(b, ch->buf, UAUDIO_DEFAULT_BUFSZ) != 0) {
+ if (sndbuf_setup(b, ch->buf, buf_size) != 0) {
goto error;
}
ch->start = ch->buf;
- ch->end = ch->buf + UAUDIO_DEFAULT_BUFSZ;
+ ch->end = ch->buf + buf_size;
ch->cur = ch->buf;
ch->pcm_ch = c;
ch->pcm_mtx = c->lock;
@@ -1437,16 +1415,14 @@ int
uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize,
uint32_t blockcount)
{
- uint32_t max = sndbuf_getmaxsize(ch->pcm_buf);
-
- RANGE(blocksize, 128, max / 2);
-
- blockcount = max / blocksize;
- RANGE(blockcount, 2, 512);
+ /* we only support one size */
+ blocksize = ch->intr_size;
+ blockcount = 2;
if ((sndbuf_getblksz(ch->pcm_buf) != blocksize) ||
(sndbuf_getblkcnt(ch->pcm_buf) != blockcount)) {
-
+ DPRINTFN(1, "resizing to %u x "
+ "%u bytes\n", blockcount, blocksize);
if (sndbuf_resize(ch->pcm_buf, blockcount, blocksize)) {
DPRINTFN(0, "failed to resize sound buffer, count=%u, "
"size=%u\n", blockcount, blocksize);
@@ -2672,7 +2648,10 @@ uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb2_device *udev,
DPRINTF("invalid Audio Control header\n");
goto done;
}
- wTotalLen = UGETW(cd->wTotalLength);
+ /* "wTotalLen" is allowed to be corrupt */
+ wTotalLen = UGETW(acdp->wTotalLength) - acdp->bLength;
+
+ /* get USB audio revision */
sc->sc_audio_rev = UGETW(acdp->bcdADC);
DPRINTFN(3, "found AC header, vers=%03x, len=%d\n",
@@ -2939,6 +2918,8 @@ uaudio_mixer_write_cfg_callback(struct usb2_xfer *xfer)
uint8_t chan;
uint8_t buf[2];
+ DPRINTF("\n");
+
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
tr_transferred:
@@ -2998,11 +2979,14 @@ tr_setup:
if (repeat) {
goto tr_setup;
}
- return;
+ break;
default: /* Error */
DPRINTF("error=%s\n", usb2_errstr(xfer->error));
-
+ if (xfer->error == USB_ERR_CANCELLED) {
+ /* do nothing - we are detaching */
+ break;
+ }
goto tr_transferred;
}
}
diff --git a/sys/dev/usb2/storage/ata-usb2.c b/sys/dev/usb2/storage/ata-usb2.c
index 98bb4da..430e59b 100644
--- a/sys/dev/usb2/storage/ata-usb2.c
+++ b/sys/dev/usb2/storage/ata-usb2.c
@@ -328,9 +328,6 @@ atausb2_attach(device_t dev)
uint8_t has_intr;
int err;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->dev = dev;
@@ -773,11 +770,12 @@ atausb2_t_bbb_status_callback(struct usb2_xfer *xfer)
sc->ata_request = NULL;
- USB_XFER_UNLOCK(xfer);
+ /* drop the USB transfer lock while doing the ATA interrupt */
+ mtx_unlock(&sc->locked_mtx);
ata_interrupt(device_get_softc(request->parent));
- USB_XFER_LOCK(xfer);
+ mtx_lock(&sc->locked_mtx);
return;
case USB_ST_SETUP:
diff --git a/sys/dev/usb2/storage/umass2.c b/sys/dev/usb2/storage/umass2.c
index cfdfe77..1674f74 100644
--- a/sys/dev/usb2/storage/umass2.c
+++ b/sys/dev/usb2/storage/umass2.c
@@ -400,6 +400,10 @@ static const struct umass_devdescr umass_devdescr[] = {
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
NO_GETMAXLUN
},
+ {USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_GETMAXLUN
+ },
{USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
NO_INQUIRY
@@ -608,6 +612,10 @@ static const struct umass_devdescr umass_devdescr[] = {
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
NO_INQUIRY | IGNORE_RESIDUE
},
+ {USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_SYNCHRONIZE_CACHE
+ },
{USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
FORCE_SHORT_INQUIRY
@@ -636,10 +644,10 @@ static const struct umass_devdescr umass_devdescr[] = {
UMASS_PROTO_SCSI,
NO_GETMAXLUN
},
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
- },
+ {USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
+ },
{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW, RID_WILDCARD,
UMASS_PROTO_SCSI,
NO_QUIRKS
@@ -912,6 +920,10 @@ static const struct umass_devdescr umass_devdescr[] = {
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
NO_QUIRKS
},
+ {USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY | NO_SYNCHRONIZE_CACHE
+ },
{VID_EOT, PID_EOT, RID_EOT, 0, 0}
};
@@ -1432,9 +1444,6 @@ umass_attach(device_t dev)
struct usb2_interface_descriptor *id;
int32_t err;
- if (sc == NULL) {
- return (ENOMEM);
- }
if (device_get_unit(dev) >= UMASS_MAXUNIT) {
device_printf(dev, "Maxunit(%u) limit reached!\n",
UMASS_MAXUNIT);
@@ -2406,6 +2415,9 @@ umass_t_cbi_data_read_callback(struct usb2_xfer *xfer)
}
xfer->timeout = sc->sc_transfer.data_timeout;
+ if (xfer->flags.ext_buffer) {
+ usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
+ }
xfer->frlengths[0] = max_bulk;
usb2_start_hardware(xfer);
return;
diff --git a/sys/dev/usb2/storage/urio2.c b/sys/dev/usb2/storage/urio2.c
index 2007e15..f5b6315 100644
--- a/sys/dev/usb2/storage/urio2.c
+++ b/sys/dev/usb2/storage/urio2.c
@@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_debug.h>
#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_config_td.h>
#include <dev/usb2/core/usb2_request.h>
#include <dev/usb2/core/usb2_lookup.h>
#include <dev/usb2/core/usb2_util.h>
@@ -213,9 +212,6 @@ urio_attach(device_t dev)
struct urio_softc *sc = device_get_softc(dev);
int error;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
sc->sc_udev = uaa->device;
diff --git a/sys/dev/usb2/storage/ustorage2_fs.c b/sys/dev/usb2/storage/ustorage2_fs.c
index 62981d7..78b0592 100644
--- a/sys/dev/usb2/storage/ustorage2_fs.c
+++ b/sys/dev/usb2/storage/ustorage2_fs.c
@@ -318,9 +318,6 @@ ustorage_fs_attach(device_t dev)
struct usb2_interface_descriptor *id;
int err;
- if (sc == NULL) {
- return (ENOMEM);
- }
/*
* NOTE: the softc struct is bzero-ed in device_set_driver.
* We can safely call ustorage_fs_detach without specifically
@@ -1301,6 +1298,7 @@ ustorage_fs_mode_select(struct ustorage_fs_softc *sc)
static uint8_t
ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc)
{
+#if 0
struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
uint8_t rc;
@@ -1311,6 +1309,7 @@ ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc)
if (rc) {
currlun->sense_data = SS_WRITE_ERROR;
}
+#endif
return (0);
}
diff --git a/sys/dev/usb2/wlan/if_rum2.c b/sys/dev/usb2/wlan/if_rum2.c
index e99881b..8911a6f 100644
--- a/sys/dev/usb2/wlan/if_rum2.c
+++ b/sys/dev/usb2/wlan/if_rum2.c
@@ -49,9 +49,9 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/wlan/usb2_wlan.h>
-#include <dev/usb2/wlan/if_rum2_reg.h>
-#include <dev/usb2/wlan/if_rum2_var.h>
-#include <dev/usb2/wlan/if_rum2_fw.h>
+#include <dev/usb2/wlan/if_rumreg.h>
+#include <dev/usb2/wlan/if_rumvar.h>
+#include <dev/usb2/wlan/if_rumfw.h>
#if USB_DEBUG
static int rum_debug = 0;
@@ -188,6 +188,7 @@ static const struct usb2_device_id rum_devs[] = {
{USB_VPI(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, 0)},
{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP, 0)},
{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP, 0)},
+ {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG, 0)},
{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1, 0)},
{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2, 0)},
{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3, 0)},
@@ -375,7 +376,7 @@ static const struct rfprog rum_rf5225[] = {
};
static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
- [0] = {
+ [RUM_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -385,7 +386,7 @@ static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
.mh.timeout = 5000, /* ms */
},
- [1] = {
+ [RUM_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -394,7 +395,7 @@ static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
.mh.callback = &rum_bulk_read_callback,
},
- [2] = {
+ [RUM_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -404,7 +405,7 @@ static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [RUM_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -461,9 +462,6 @@ rum_attach(device_t dev)
int error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
mtx_init(&sc->sc_mtx, "rum lock", MTX_NETWORK_LOCK,
@@ -789,7 +787,6 @@ rum_cfg_first_time_setup(struct rum_softc *sc,
DPRINTFN(0, "could not if_alloc()!\n");
goto done;
}
- sc->sc_evilhack = ifp;
sc->sc_ifp = ifp;
ic = ifp->if_l2com;
@@ -897,7 +894,7 @@ rum_end_of_commands(struct rum_softc *sc)
sc->sc_flags &= ~RUM_FLAG_WAIT_COMMAND;
/* start write transfer, if not started */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
}
static void
@@ -1075,7 +1072,7 @@ rum_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & RUM_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -1110,7 +1107,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= RUM_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_RD]);
}
return;
@@ -1121,7 +1118,7 @@ static void
rum_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct rum_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1302,7 +1299,7 @@ rum_setup_desc_and_tx(struct rum_softc *sc, struct mbuf *m, uint32_t flags,
/* start write transfer, if not started */
_IF_ENQUEUE(&sc->sc_tx_queue, mm);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
}
static void
@@ -1322,7 +1319,7 @@ rum_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & RUM_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
break;
}
if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) {
@@ -1380,7 +1377,7 @@ rum_bulk_write_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= RUM_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_CS_WR]);
}
ifp->if_oerrors++;
break;
@@ -1391,7 +1388,7 @@ static void
rum_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct rum_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[RUM_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1473,7 +1470,7 @@ rum_start_cb(struct ifnet *ifp)
mtx_lock(&sc->sc_mtx);
/* start write transfer, if not started */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
mtx_unlock(&sc->sc_mtx);
}
@@ -2234,8 +2231,8 @@ rum_cfg_init(struct rum_softc *sc,
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[RUM_BULK_DT_WR]);
/*
* start IEEE802.11 layer
@@ -2293,10 +2290,10 @@ rum_cfg_pre_stop(struct rum_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
+ usb2_transfer_stop(sc->sc_xfer[RUM_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[RUM_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[RUM_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[RUM_BULK_CS_RD]);
/* clean up transmission */
rum_tx_clean_queue(sc);
diff --git a/sys/dev/usb2/wlan/if_rum2_fw.h b/sys/dev/usb2/wlan/if_rumfw.h
index 0f08674..0f08674 100644
--- a/sys/dev/usb2/wlan/if_rum2_fw.h
+++ b/sys/dev/usb2/wlan/if_rumfw.h
diff --git a/sys/dev/usb2/wlan/if_rum2_reg.h b/sys/dev/usb2/wlan/if_rumreg.h
index cc88ef8..cc88ef8 100644
--- a/sys/dev/usb2/wlan/if_rum2_reg.h
+++ b/sys/dev/usb2/wlan/if_rumreg.h
diff --git a/sys/dev/usb2/wlan/if_rum2_var.h b/sys/dev/usb2/wlan/if_rumvar.h
index 8551a41..29ee0a5 100644
--- a/sys/dev/usb2/wlan/if_rum2_var.h
+++ b/sys/dev/usb2/wlan/if_rumvar.h
@@ -17,8 +17,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RUM_N_TRANSFER 4
-
struct rum_node {
struct ieee80211_node ni;
struct ieee80211_amrr_node amn;
@@ -113,8 +111,16 @@ struct rum_ifq {
uint16_t ifq_len;
};
+enum {
+ RUM_BULK_DT_WR,
+ RUM_BULK_DT_RD,
+ RUM_BULK_CS_WR,
+ RUM_BULK_CS_RD,
+ RUM_N_TRANSFER = 4,
+};
+
struct rum_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct rum_ifq sc_tx_queue;
struct usb2_config_td sc_config_td;
@@ -127,7 +133,6 @@ struct rum_softc {
struct rum_tx_radiotap_header sc_txtap;
struct usb2_xfer *sc_xfer[RUM_N_TRANSFER];
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
const struct ieee80211_rate_table *sc_rates;
diff --git a/sys/dev/usb2/wlan/if_ural2.c b/sys/dev/usb2/wlan/if_ural2.c
index 2213439..2a66ce0 100644
--- a/sys/dev/usb2/wlan/if_ural2.c
+++ b/sys/dev/usb2/wlan/if_ural2.c
@@ -55,8 +55,8 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/wlan/usb2_wlan.h>
-#include <dev/usb2/wlan/if_ural2_reg.h>
-#include <dev/usb2/wlan/if_ural2_var.h>
+#include <dev/usb2/wlan/if_uralreg.h>
+#include <dev/usb2/wlan/if_uralvar.h>
#if USB_DEBUG
static int ural_debug = 0;
@@ -189,7 +189,6 @@ static const struct usb2_device_id ural_devs[] = {
{USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570, 0)},
{USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2, 0)},
{USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3, 0)},
- {USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, 0)},
{USB_VPI(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G, 0)},
{USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG, 0)},
{USB_VPI(USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R, 0)},
@@ -368,7 +367,7 @@ static const struct ural_rf5222 ural_rf5222[] = {
};
static const struct usb2_config ural_config[URAL_N_TRANSFER] = {
- [0] = {
+ [URAL_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -378,7 +377,7 @@ static const struct usb2_config ural_config[URAL_N_TRANSFER] = {
.mh.timeout = 5000, /* ms */
},
- [1] = {
+ [URAL_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -387,7 +386,7 @@ static const struct usb2_config ural_config[URAL_N_TRANSFER] = {
.mh.callback = &ural_bulk_read_callback,
},
- [2] = {
+ [URAL_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -397,7 +396,7 @@ static const struct usb2_config ural_config[URAL_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [3] = {
+ [URAL_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -454,9 +453,6 @@ ural_attach(device_t dev)
int error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
device_set_usb2_desc(dev);
mtx_init(&sc->sc_mtx, "ural lock", MTX_NETWORK_LOCK,
@@ -787,8 +783,9 @@ ural_cfg_first_time_setup(struct ural_softc *sc,
/* retrieve MAC address and various other things from EEPROM */
ural_cfg_read_eeprom(sc);
- printf("%s: MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
- sc->sc_name, sc->sc_asic_rev, ural_get_rf(sc->sc_rf_rev));
+ printf("%s: MAC/BBP RT2570 (rev 0x%02x), RF %s (0x%02x)\n",
+ sc->sc_name, sc->sc_asic_rev, ural_get_rf(sc->sc_rf_rev),
+ sc->sc_rf_rev);
mtx_unlock(&sc->sc_mtx);
@@ -800,7 +797,6 @@ ural_cfg_first_time_setup(struct ural_softc *sc,
DPRINTFN(0, "could not if_alloc()!\n");
goto done;
}
- sc->sc_evilhack = ifp;
sc->sc_ifp = ifp;
ic = ifp->if_l2com;
@@ -881,7 +877,7 @@ ural_end_of_commands(struct ural_softc *sc)
sc->sc_flags &= ~URAL_FLAG_WAIT_COMMAND;
/* start write transfer, if not started */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_DT_WR]);
}
static void
@@ -958,8 +954,11 @@ ural_config_copy(struct ural_softc *sc,
static const char *
ural_get_rf(int rev)
{
+ ; /* style fix */
+
switch (rev) {
- case RAL_RF_2522:return "RT2522";
+ case RAL_RF_2522:
+ return "RT2522";
case RAL_RF_2523:
return "RT2523";
case RAL_RF_2524:
@@ -1074,7 +1073,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
tr_setup:
if (sc->sc_flags & URAL_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -1112,7 +1111,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= URAL_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[3]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_CS_RD]);
}
return;
@@ -1123,7 +1122,7 @@ static void
ural_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ural_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[1];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[URAL_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1290,7 +1289,7 @@ ural_setup_desc_and_tx(struct ural_softc *sc, struct mbuf *m,
/* start write transfer, if not started */
_IF_ENQUEUE(&sc->sc_tx_queue, mm);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_DT_WR]);
}
static void
@@ -1310,7 +1309,7 @@ ural_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & URAL_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_CS_WR]);
break;
}
if (sc->sc_flags & URAL_FLAG_WAIT_COMMAND) {
@@ -1368,7 +1367,7 @@ ural_bulk_write_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= URAL_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[2]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_CS_WR]);
}
ifp->if_oerrors++;
break;
@@ -1379,7 +1378,7 @@ static void
ural_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct ural_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[URAL_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -1465,7 +1464,7 @@ ural_start_cb(struct ifnet *ifp)
mtx_lock(&sc->sc_mtx);
/* start write transfer, if not started */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_DT_WR]);
mtx_unlock(&sc->sc_mtx);
}
@@ -2157,8 +2156,8 @@ ural_cfg_init(struct ural_softc *sc,
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[URAL_BULK_DT_WR]);
/*
* start IEEE802.11 layer
@@ -2216,10 +2215,10 @@ ural_cfg_pre_stop(struct ural_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[0]);
- usb2_transfer_stop(sc->sc_xfer[1]);
- usb2_transfer_stop(sc->sc_xfer[2]);
- usb2_transfer_stop(sc->sc_xfer[3]);
+ usb2_transfer_stop(sc->sc_xfer[URAL_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[URAL_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[URAL_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[URAL_BULK_CS_RD]);
/* clean up transmission */
ural_tx_clean_queue(sc);
diff --git a/sys/dev/usb2/wlan/if_ural2_reg.h b/sys/dev/usb2/wlan/if_uralreg.h
index 1837693..1837693 100644
--- a/sys/dev/usb2/wlan/if_ural2_reg.h
+++ b/sys/dev/usb2/wlan/if_uralreg.h
diff --git a/sys/dev/usb2/wlan/if_ural2_var.h b/sys/dev/usb2/wlan/if_uralvar.h
index c91643c..bab8965 100644
--- a/sys/dev/usb2/wlan/if_ural2_var.h
+++ b/sys/dev/usb2/wlan/if_uralvar.h
@@ -17,8 +17,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define URAL_N_TRANSFER 4
-
struct ural_node {
struct ieee80211_node ni;
struct ieee80211_amrr_node amn;
@@ -113,8 +111,16 @@ struct ural_ifq {
uint16_t ifq_len;
};
+enum {
+ URAL_BULK_DT_WR,
+ URAL_BULK_DT_RD,
+ URAL_BULK_CS_WR,
+ URAL_BULK_CS_RD,
+ URAL_N_TRANSFER = 4,
+};
+
struct ural_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct ural_ifq sc_tx_queue;
struct usb2_config_td sc_config_td;
@@ -127,7 +133,6 @@ struct ural_softc {
struct ural_tx_radiotap_header sc_txtap;
struct usb2_xfer *sc_xfer[URAL_N_TRANSFER];
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
const struct ieee80211_rate_table *sc_rates;
diff --git a/sys/dev/usb2/wlan/if_zyd2.c b/sys/dev/usb2/wlan/if_zyd2.c
index 2e29d37..5b61f00 100644
--- a/sys/dev/usb2/wlan/if_zyd2.c
+++ b/sys/dev/usb2/wlan/if_zyd2.c
@@ -49,8 +49,8 @@ __FBSDID("$FreeBSD$");
#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/wlan/usb2_wlan.h>
-#include <dev/usb2/wlan/if_zyd2_reg.h>
-#include <dev/usb2/wlan/if_zyd2_fw.h>
+#include <dev/usb2/wlan/if_zydreg.h>
+#include <dev/usb2/wlan/if_zydfw.h>
#if USB_DEBUG
static int zyd_debug = 0;
@@ -155,6 +155,7 @@ static int zyd_newstate_cb(struct ieee80211vap *,
static void zyd_cfg_amrr_start(struct zyd_softc *);
static void zyd_update_mcast_cb(struct ifnet *);
static void zyd_update_promisc_cb(struct ifnet *);
+static void zyd_cfg_get_macaddr(struct zyd_softc *sc);
static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
@@ -215,7 +216,7 @@ static const struct usb2_device_id zyd_devs[] = {
};
static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
- [ZYD_TR_BULK_DT_WR] = {
+ [ZYD_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -226,7 +227,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.mh.timeout = 10000, /* 10 seconds */
},
- [ZYD_TR_BULK_DT_RD] = {
+ [ZYD_BULK_DT_RD] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -236,7 +237,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.ep_index = 0,
},
- [ZYD_TR_BULK_CS_WR] = {
+ [ZYD_BULK_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -247,7 +248,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [ZYD_TR_BULK_CS_RD] = {
+ [ZYD_BULK_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -258,7 +259,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [ZYD_TR_INTR_DT_WR] = {
+ [ZYD_INTR_DT_WR] = {
.type = UE_BULK_INTR,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
@@ -269,7 +270,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.ep_index = 1,
},
- [ZYD_TR_INTR_DT_RD] = {
+ [ZYD_INTR_DT_RD] = {
.type = UE_BULK_INTR,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
@@ -279,7 +280,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.ep_index = 1,
},
- [ZYD_TR_INTR_CS_WR] = {
+ [ZYD_INTR_CS_WR] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -290,7 +291,7 @@ static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
.mh.interval = 50, /* 50ms */
},
- [ZYD_TR_INTR_CS_RD] = {
+ [ZYD_INTR_CS_RD] = {
.type = UE_CONTROL,
.endpoint = 0x00, /* Control pipe */
.direction = UE_DIR_ANY,
@@ -372,7 +373,7 @@ static void
zyd_intr_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct zyd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_TR_INTR_DT_RD];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_INTR_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -419,7 +420,7 @@ zyd_intr_read_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
if (sc->sc_flags & ZYD_FLAG_INTR_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_CS_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_RD]);
break;
}
xfer->frlengths[0] = xfer->max_data_length;
@@ -433,7 +434,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= ZYD_FLAG_INTR_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_CS_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_RD]);
}
break;
}
@@ -528,7 +529,7 @@ repeat:
/* wait for data */
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]);
if (usb2_cv_timedwait(&sc->sc_intr_cv,
&sc->sc_mtx, hz / 2)) {
@@ -570,7 +571,7 @@ skip0:
* We have fetched the data from the shared buffer and it is
* safe to restart the interrupt transfer!
*/
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]);
done:
return;
}
@@ -579,7 +580,7 @@ static void
zyd_intr_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct zyd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_TR_INTR_DT_WR];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_INTR_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -601,7 +602,7 @@ zyd_intr_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & ZYD_FLAG_INTR_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_CS_WR]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_WR]);
goto wakeup;
}
if (sc->sc_intr_owakeup) {
@@ -620,7 +621,7 @@ zyd_intr_write_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= ZYD_FLAG_INTR_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_CS_WR]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_WR]);
}
goto wakeup;
}
@@ -656,7 +657,7 @@ zyd_cfg_usb2_intr_write(struct zyd_softc *sc, const void *data,
sc->sc_intr_obuf.code = htole16(code);
bcopy(data, sc->sc_intr_obuf.data, size);
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_DT_WR]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_WR]);
while (sc->sc_intr_owakeup) {
if (usb2_cv_timedwait(&sc->sc_intr_cv,
@@ -758,11 +759,22 @@ zyd_cfg_rfwrite(struct zyd_softc *sc, uint32_t value)
zyd_cfg_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + (2 * rf->width), NULL, 0, 0);
}
+/*------------------------------------------------------------------------*
+ * zyd_cfg_rfwrite_cr
+ *------------------------------------------------------------------------*/
+static void
+zyd_cfg_rfwrite_cr(struct zyd_softc *sc, uint32_t val)
+{
+ zyd_cfg_write16(sc, ZYD_CR244, (val >> 16) & 0xff);
+ zyd_cfg_write16(sc, ZYD_CR243, (val >> 8) & 0xff);
+ zyd_cfg_write16(sc, ZYD_CR242, (val >> 0) & 0xff);
+}
+
static void
zyd_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
{
struct zyd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_TR_BULK_DT_RD];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_BULK_DT_RD];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -911,7 +923,7 @@ tr_setup:
DPRINTF("setup\n");
if (sc->sc_flags & ZYD_FLAG_BULK_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_BULK_CS_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_RD]);
} else {
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
@@ -961,7 +973,7 @@ tr_setup:
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= ZYD_FLAG_BULK_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_BULK_CS_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_RD]);
}
break;
}
@@ -1057,9 +1069,6 @@ zyd_attach(device_t dev)
int error;
uint8_t iface_index;
- if (sc == NULL) {
- return (ENOMEM);
- }
if (uaa->info.bcdDevice < 0x4330) {
device_printf(dev, "device version mismatch: 0x%X "
"(only >= 43.30 supported)\n",
@@ -1148,10 +1157,24 @@ zyd_cfg_unlock_phy(struct zyd_softc *sc)
static void
zyd_cfg_set_beacon_interval(struct zyd_softc *sc, uint32_t bintval)
{
- /* XXX this is probably broken.. */
- zyd_cfg_write32(sc, ZYD_CR_ATIM_WND_PERIOD, bintval - 2);
- zyd_cfg_write32(sc, ZYD_CR_PRE_TBTT, bintval - 1);
- zyd_cfg_write32(sc, ZYD_CR_BCN_INTERVAL, bintval);
+ uint32_t val;
+
+ zyd_cfg_read32(sc, ZYD_CR_ATIM_WND_PERIOD, &val);
+ sc->sc_atim_wnd = val;
+ zyd_cfg_read32(sc, ZYD_CR_PRE_TBTT, &val);
+ sc->sc_pre_tbtt = val;
+ sc->sc_bcn_int = bintval;
+
+ if (sc->sc_bcn_int <= 5)
+ sc->sc_bcn_int = 5;
+ if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int)
+ sc->sc_pre_tbtt = sc->sc_bcn_int - 1;
+ if (sc->sc_atim_wnd >= sc->sc_pre_tbtt)
+ sc->sc_atim_wnd = sc->sc_pre_tbtt - 1;
+
+ zyd_cfg_write32(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd);
+ zyd_cfg_write32(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt);
+ zyd_cfg_write32(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int);
}
/*
@@ -1163,7 +1186,7 @@ zyd_rf_name(uint8_t type)
static const char *const zyd_rfs[] = {
"unknown", "unknown", "UW2451", "UCHIP", "AL2230",
"AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT",
- "PV2000", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
+ "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
"PHILIPS"
};
@@ -1235,36 +1258,106 @@ static void
zyd_cfg_rf_al2230_init(struct zyd_softc *sc, struct zyd_rf *rf)
{
static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
- static const uint32_t rfini[] = ZYD_AL2230_RF;
+ static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
+ static const struct zyd_phy_pair phypll[] = {
+ {ZYD_CR251, 0x2f}, {ZYD_CR251, 0x3f},
+ {ZYD_CR138, 0x28}, {ZYD_CR203, 0x06}
+ };
+ static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1;
+ static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2;
+ static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3;
uint32_t i;
/* init RF-dependent PHY registers */
- for (i = 0; i != INDEXES(phyini); i++) {
+ for (i = 0; i != INDEXES(phyini); i++)
zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val);
- }
- /* init AL2230 radio */
- for (i = 0; i != INDEXES(rfini); i++) {
- zyd_cfg_rfwrite(sc, rfini[i]);
+ if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0)) {
+ for (i = 0; i != INDEXES(phy2230s); i++)
+ zyd_cfg_write16(sc, phy2230s[i].reg, phy2230s[i].val);
}
+ /* init AL2230 radio */
+ for (i = 0; i != INDEXES(rfini1); i++)
+ zyd_cfg_rfwrite(sc, rfini1[i]);
+
+ if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0))
+ zyd_cfg_rfwrite(sc, 0x000824);
+ else
+ zyd_cfg_rfwrite(sc, 0x0005a4);
+
+ for (i = 0; i != INDEXES(rfini2); i++)
+ zyd_cfg_rfwrite(sc, rfini2[i]);
+
+ for (i = 0; i != INDEXES(phypll); i++)
+ zyd_cfg_write16(sc, phypll[i].reg, phypll[i].val);
+
+ for (i = 0; i != INDEXES(rfini3); i++)
+ zyd_cfg_rfwrite(sc, rfini3[i]);
+}
+
+static void
+zyd_cfg_rf_al2230_fini(struct zyd_softc *sc, struct zyd_rf *rf)
+{
+ static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1;
+ uint32_t i;
+
+ for (i = 0; i != INDEXES(phy); i++)
+ zyd_cfg_write16(sc, phy[i].reg, phy[i].val);
+
+ if (sc->sc_newphy != 0)
+ zyd_cfg_write16(sc, ZYD_CR9, 0xe1);
+ zyd_cfg_write16(sc, ZYD_CR203, 0x6);
}
static void
zyd_cfg_rf_al2230_init_b(struct zyd_softc *sc, struct zyd_rf *rf)
{
static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
- static const uint32_t rfini[] = ZYD_AL2230_RF_B;
+ static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
+ static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2;
+ static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3;
+ static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
+ static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1;
+ static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2;
+ static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3;
+ static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE;
uint32_t i;
+ for (i = 0; i != INDEXES(phy1); i++)
+ zyd_cfg_write16(sc, phy1[i].reg, phy1[i].val);
+
/* init RF-dependent PHY registers */
- for (i = 0; i != INDEXES(phyini); i++) {
+ for (i = 0; i != INDEXES(phyini); i++)
zyd_cfg_write16(sc, phyini[i].reg, phyini[i].val);
- }
- /* init AL2230 radio */
- for (i = 0; i != INDEXES(rfini); i++) {
- zyd_cfg_rfwrite(sc, rfini[i]);
- }
+ if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0))
+ for (i = 0; i != INDEXES(phy2230s); i++)
+ zyd_cfg_write16(sc, phy2230s[i].reg, phy2230s[i].val);
+
+ for (i = 0; i != 3; i++)
+ zyd_cfg_rfwrite_cr(sc, zyd_al2230_chtable[0][i]);
+
+ for (i = 0; i != INDEXES(rfini_part1); i++)
+ zyd_cfg_rfwrite_cr(sc, rfini_part1[i]);
+
+ if ((sc->sc_rf_rev == ZYD_RF_AL2230S) || (sc->sc_al2230s != 0))
+ zyd_cfg_rfwrite(sc, 0x241000);
+ else
+ zyd_cfg_rfwrite(sc, 0x25a000);
+
+ for (i = 0; i != INDEXES(rfini_part2); i++)
+ zyd_cfg_rfwrite_cr(sc, rfini_part2[i]);
+
+ for (i = 0; i != INDEXES(phy2); i++)
+ zyd_cfg_write16(sc, phy2[i].reg, phy2[i].val);
+
+ for (i = 0; i != INDEXES(rfini_part3); i++)
+ zyd_cfg_rfwrite_cr(sc, rfini_part3[i]);
+
+ for (i = 0; i < INDEXES(phy3); i++)
+ zyd_cfg_write16(sc, phy3[i].reg, phy3[i].val);
+
+ zyd_cfg_rf_al2230_fini(sc, rf);
}
/*
@@ -1274,16 +1367,60 @@ static void
zyd_cfg_rf_al2230_set_channel(struct zyd_softc *sc, struct zyd_rf *rf,
uint8_t channel)
{
+ static const struct zyd_phy_pair phy1[] = {
+ {ZYD_CR138, 0x28}, {ZYD_CR203, 0x06},
+ };
static const struct {
uint32_t r1, r2, r3;
} rfprog[] = ZYD_AL2230_CHANTABLE;
+ uint32_t i;
zyd_cfg_rfwrite(sc, rfprog[channel - 1].r1);
zyd_cfg_rfwrite(sc, rfprog[channel - 1].r2);
zyd_cfg_rfwrite(sc, rfprog[channel - 1].r3);
- zyd_cfg_write16(sc, ZYD_CR138, 0x28);
- zyd_cfg_write16(sc, ZYD_CR203, 0x06);
+ for (i = 0; i != INDEXES(phy1); i++)
+ zyd_cfg_write16(sc, phy1[i].reg, phy1[i].val);
+}
+
+static void
+zyd_cfg_rf_al2230_set_channel_b(struct zyd_softc *sc,
+ struct zyd_rf *rf, uint8_t chan)
+{
+ static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
+ static const struct {
+ uint32_t r1, r2, r3;
+ } rfprog[] = ZYD_AL2230_CHANTABLE_B;
+ uint32_t i;
+
+ for (i = 0; i != INDEXES(phy1); i++)
+ zyd_cfg_write16(sc, phy1[i].reg, phy1[i].val);
+
+ zyd_cfg_rfwrite_cr(sc, rfprog[chan - 1].r1);
+ zyd_cfg_rfwrite_cr(sc, rfprog[chan - 1].r2);
+ zyd_cfg_rfwrite_cr(sc, rfprog[chan - 1].r3);
+
+ zyd_cfg_rf_al2230_fini(sc, rf);
+}
+
+#define ZYD_AL2230_PHY_BANDEDGE6 \
+{ \
+ { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
+ { ZYD_CR47, 0x1e } \
+}
+
+static void
+zyd_cfg_rf_al2230_bandedge6(struct zyd_softc *sc,
+ struct zyd_rf *rf, uint8_t chan)
+{
+ struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
+ uint32_t i;
+
+ if ((chan == 1) || (chan == 11))
+ r[0].val = 0x12;
+
+ for (i = 0; i < INDEXES(r); i++)
+ zyd_cfg_write16(sc, r[i].reg, r[i].val);
}
/*
@@ -1413,7 +1550,6 @@ zyd_cfg_rf_al2210_set_channel(struct zyd_softc *sc, struct zyd_rf *rf,
zyd_cfg_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
zyd_cfg_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
zyd_cfg_write32(sc, ZYD_CR_RFCFG, 0x05);
-
zyd_cfg_write32(sc, ZYD_CR_RFCFG, 0x00);
zyd_cfg_write16(sc, ZYD_CR47, 0x1e);
@@ -1617,12 +1753,16 @@ zyd_cfg_rf_init_hw(struct zyd_softc *sc, struct zyd_rf *rf)
rf->width = 24; /* 24-bit RF values */
break;
case ZYD_RF_AL2230:
- if (sc->sc_mac_rev == ZYD_ZD1211B)
+ case ZYD_RF_AL2230S:
+ if (sc->sc_mac_rev == ZYD_ZD1211B) {
rf->cfg_init_hw = zyd_cfg_rf_al2230_init_b;
- else
+ rf->cfg_set_channel = zyd_cfg_rf_al2230_set_channel_b;
+ } else {
rf->cfg_init_hw = zyd_cfg_rf_al2230_init;
+ rf->cfg_set_channel = zyd_cfg_rf_al2230_set_channel;
+ }
rf->cfg_switch_radio = zyd_cfg_rf_al2230_switch_radio;
- rf->cfg_set_channel = zyd_cfg_rf_al2230_set_channel;
+ rf->cfg_bandedge6 = zyd_cfg_rf_al2230_bandedge6;
rf->width = 24; /* 24-bit RF values */
break;
case ZYD_RF_AL7230B:
@@ -1689,6 +1829,9 @@ zyd_cfg_hw_init(struct zyd_softc *sc)
zyd_cfg_write32(sc, ZYD_CR_GPI_EN, 0);
zyd_cfg_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
+ /* set mandatory rates - XXX assumes 802.11b/g */
+ zyd_cfg_write32(sc, ZYD_MAC_MAN_RATE, 0x150f);
+
/* disable interrupts */
zyd_cfg_write32(sc, ZYD_CR_INTERRUPT, 0);
@@ -1698,7 +1841,7 @@ zyd_cfg_hw_init(struct zyd_softc *sc)
for (; phyp->reg != 0; phyp++) {
zyd_cfg_write16(sc, phyp->reg, phyp->val);
}
- if (sc->sc_fix_cr157) {
+ if ((sc->sc_mac_rev == ZYD_ZD1211) && sc->sc_fix_cr157) {
zyd_cfg_read32(sc, ZYD_EEPROM_PHY_REG, &tmp);
zyd_cfg_write32(sc, ZYD_CR157, tmp >> 8);
}
@@ -1707,20 +1850,6 @@ zyd_cfg_hw_init(struct zyd_softc *sc)
/* HMAC init */
zyd_cfg_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020);
zyd_cfg_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
-
- if (sc->sc_mac_rev == ZYD_ZD1211) {
- zyd_cfg_write32(sc, ZYD_MAC_RETRY, 0x00000002);
- } else {
- zyd_cfg_write32(sc, ZYD_MACB_MAX_RETRY, 0x02020202);
- zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
- zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
- zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
- zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
- zyd_cfg_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
- zyd_cfg_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
- zyd_cfg_write32(sc, ZYD_MACB_TXOP, 0x01800824);
- }
-
zyd_cfg_write32(sc, ZYD_MAC_SNIFFER, 0x00000000);
zyd_cfg_write32(sc, ZYD_MAC_RXFILTER, 0x00000000);
zyd_cfg_write32(sc, ZYD_MAC_GHTBL, 0x00000000);
@@ -1732,12 +1861,28 @@ zyd_cfg_hw_init(struct zyd_softc *sc)
zyd_cfg_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080);
zyd_cfg_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
zyd_cfg_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
- zyd_cfg_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0547c032);
zyd_cfg_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
zyd_cfg_write32(sc, ZYD_CR_PS_CTRL, 0x10000000);
zyd_cfg_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
- zyd_cfg_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
+ zyd_cfg_write32(sc, ZYD_MAC_AFTER_PNP, 1);
zyd_cfg_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
+ zyd_cfg_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032);
+ zyd_cfg_write32(sc, ZYD_MAC_CAM_MODE, 0x3);
+
+ if (sc->sc_mac_rev == ZYD_ZD1211) {
+ zyd_cfg_write32(sc, ZYD_MAC_RETRY, 0x00000002);
+ zyd_cfg_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
+ } else {
+ zyd_cfg_write32(sc, ZYD_MACB_MAX_RETRY, 0x02020202);
+ zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
+ zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
+ zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
+ zyd_cfg_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
+ zyd_cfg_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
+ zyd_cfg_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
+ zyd_cfg_write32(sc, ZYD_MACB_TXOP, 0x01800824);
+ zyd_cfg_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff);
+ }
/* init beacon interval to 100ms */
zyd_cfg_set_beacon_interval(sc, 100);
@@ -1756,20 +1901,19 @@ zyd_cfg_read_eeprom(struct zyd_softc *sc)
uint16_t val;
/* read MAC address */
- zyd_cfg_read32(sc, ZYD_EEPROM_MAC_ADDR_P1, &tmp);
- sc->sc_myaddr[0] = tmp & 0xff;
- sc->sc_myaddr[1] = tmp >> 8;
- sc->sc_myaddr[2] = tmp >> 16;
- sc->sc_myaddr[3] = tmp >> 24;
- zyd_cfg_read32(sc, ZYD_EEPROM_MAC_ADDR_P2, &tmp);
- sc->sc_myaddr[4] = tmp & 0xff;
- sc->sc_myaddr[5] = tmp >> 8;
+ zyd_cfg_get_macaddr(sc);
+ /* read product data */
zyd_cfg_read32(sc, ZYD_EEPROM_POD, &tmp);
sc->sc_rf_rev = tmp & 0x0f;
- sc->sc_fix_cr47 = (tmp >> 8) & 0x01;
+ sc->sc_ledtype = (tmp >> 4) & 0x01;
+ sc->sc_cckgain = (tmp >> 8) & 0x01;
sc->sc_fix_cr157 = (tmp >> 13) & 0x01;
sc->sc_pa_rev = (tmp >> 16) & 0x0f;
+ sc->sc_al2230s = (tmp >> 7) & 0x01;
+ sc->sc_bandedge6 = (tmp >> 21) & 0x01;
+ sc->sc_newphy = (tmp >> 31) & 0x01;
+ sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1;
/* read regulatory domain (currently unused) */
zyd_cfg_read32(sc, ZYD_EEPROM_SUBID, &tmp);
@@ -1801,6 +1945,21 @@ zyd_cfg_read_eeprom(struct zyd_softc *sc)
}
static void
+zyd_cfg_get_macaddr(struct zyd_softc *sc)
+{
+ struct usb2_device_request req;
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = ZYD_READFWDATAREQ;
+ USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, IEEE80211_ADDR_LEN);
+
+ zyd_cfg_usbrequest(sc, &req, sc->sc_myaddr);
+ return;
+}
+
+static void
zyd_cfg_set_mac_addr(struct zyd_softc *sc, const uint8_t *addr)
{
uint32_t tmp;
@@ -1916,7 +2075,6 @@ zyd_cfg_first_time_setup(struct zyd_softc *sc,
sc->sc_name);
goto done;
}
- sc->sc_evilhack = ifp;
sc->sc_ifp = ifp;
ic = ifp->if_l2com;
@@ -1983,7 +2141,7 @@ zyd_cfg_first_time_setup(struct zyd_softc *sc,
if (bootverbose) {
ieee80211_announce(ic);
}
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]);
done:
return;
}
@@ -2270,17 +2428,18 @@ zyd_cfg_set_chan(struct zyd_softc *sc,
zyd_cfg_write16(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]);
zyd_cfg_write16(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]);
zyd_cfg_write16(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]);
-
zyd_cfg_write16(sc, ZYD_CR68, sc->sc_pwr_cal[chan - 1]);
-
zyd_cfg_write16(sc, ZYD_CR69, 0x28);
zyd_cfg_write16(sc, ZYD_CR69, 0x2a);
}
- if (sc->sc_fix_cr47) {
+ if (sc->sc_cckgain) {
/* set CCK baseband gain from EEPROM */
zyd_cfg_read32(sc, ZYD_EEPROM_PHY_REG, &tmp);
zyd_cfg_write16(sc, ZYD_CR47, tmp & 0xff);
}
+ if (sc->sc_bandedge6 && (sc->sc_rf.cfg_bandedge6 != NULL)) {
+ (sc->sc_rf.cfg_bandedge6) (sc, &sc->sc_rf, chan);
+ }
zyd_cfg_write32(sc, ZYD_CR_CONFIG_PHILIPS, 0);
zyd_cfg_unlock_phy(sc);
@@ -2349,7 +2508,7 @@ zyd_cfg_init(struct zyd_softc *sc,
else if (cc->ic_curmode == IEEE80211_MODE_11A)
zyd_cfg_write32(sc, ZYD_MAC_BAS_RATE, 0x1500);
else /* assumes 802.11b/g */
- zyd_cfg_write32(sc, ZYD_MAC_BAS_RATE, 0x000f);
+ zyd_cfg_write32(sc, ZYD_MAC_BAS_RATE, 0xff0f);
/* set mandatory rates */
if (cc->ic_curmode == IEEE80211_MODE_11B)
@@ -2379,8 +2538,8 @@ zyd_cfg_init(struct zyd_softc *sc,
/*
* start the USB transfers, if not already started:
*/
- usb2_transfer_start(sc->sc_xfer[1]);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_RD]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]);
/*
* start IEEE802.11 layer
@@ -2413,10 +2572,10 @@ zyd_cfg_pre_stop(struct zyd_softc *sc,
/*
* stop all the transfers, if not already stopped:
*/
- usb2_transfer_stop(sc->sc_xfer[ZYD_TR_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[ZYD_TR_BULK_DT_RD]);
- usb2_transfer_stop(sc->sc_xfer[ZYD_TR_BULK_CS_WR]);
- usb2_transfer_stop(sc->sc_xfer[ZYD_TR_BULK_CS_RD]);
+ usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_DT_WR]);
+ usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_DT_RD]);
+ usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_CS_WR]);
+ usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_CS_RD]);
/* clean up transmission */
zyd_tx_clean_queue(sc);
@@ -2506,7 +2665,7 @@ zyd_start_cb(struct ifnet *ifp)
struct zyd_softc *sc = ifp->if_softc;
mtx_lock(&sc->sc_mtx);
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_BULK_DT_WR]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]);
mtx_unlock(&sc->sc_mtx);
}
@@ -2514,7 +2673,7 @@ static void
zyd_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
{
struct zyd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_TR_BULK_DT_WR];
+ struct usb2_xfer *xfer_other = sc->sc_xfer[ZYD_BULK_DT_WR];
if (usb2_clear_stall_callback(xfer, xfer_other)) {
DPRINTF("stall cleared\n");
@@ -2618,7 +2777,7 @@ zyd_setup_desc_and_tx(struct zyd_softc *sc, struct mbuf *m,
/* start write transfer, if not started */
_IF_ENQUEUE(&sc->sc_tx_queue, mm);
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]);
}
static void
@@ -2639,7 +2798,7 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer)
case USB_ST_SETUP:
if (sc->sc_flags & ZYD_FLAG_BULK_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_BULK_CS_WR]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_WR]);
DPRINTFN(11, "write stalled\n");
break;
}
@@ -2685,7 +2844,7 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer)
if (xfer->error != USB_ERR_CANCELLED) {
/* try to clear stall first */
sc->sc_flags |= ZYD_FLAG_BULK_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[ZYD_TR_BULK_CS_WR]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_WR]);
}
ifp->if_oerrors++;
break;
@@ -2857,7 +3016,7 @@ zyd_end_of_commands(struct zyd_softc *sc)
sc->sc_flags &= ~ZYD_FLAG_WAIT_COMMAND;
/* start write transfer, if not started */
- usb2_transfer_start(sc->sc_xfer[0]);
+ usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_WR]);
}
static void
diff --git a/sys/dev/usb2/wlan/if_zyd2_fw.h b/sys/dev/usb2/wlan/if_zydfw.h
index 3c176e4..3c176e4 100644
--- a/sys/dev/usb2/wlan/if_zyd2_fw.h
+++ b/sys/dev/usb2/wlan/if_zydfw.h
diff --git a/sys/dev/usb2/wlan/if_zyd2_reg.h b/sys/dev/usb2/wlan/if_zydreg.h
index bdf1bc0..2c7d90c 100644
--- a/sys/dev/usb2/wlan/if_zyd2_reg.h
+++ b/sys/dev/usb2/wlan/if_zydreg.h
@@ -101,6 +101,7 @@
#define ZYD_MAC_CONT_WIN_LIMIT 0x96f0 /* Contention window limit */
#define ZYD_MAC_TX_PKT 0x96f4 /* Tx total packet count read */
#define ZYD_MAC_DL_CTRL 0x96f8 /* Download control */
+#define ZYD_MAC_CAM_MODE 0x9700 /* CAM: Continuous Access Mode */
#define ZYD_MACB_TXPWR_CTL1 0x9b00
#define ZYD_MACB_TXPWR_CTL2 0x9b04
#define ZYD_MACB_TXPWR_CTL3 0x9b08
@@ -127,8 +128,8 @@
#define ZYD_EEPROM_PWR_CAL 0xf81f /* Calibration */
#define ZYD_EEPROM_PWR_INT 0xf827 /* Calibration */
#define ZYD_EEPROM_ALLOWEDCHAN 0xf82f /* Allowed CH mask, 1 bit each */
-#define ZYD_EEPROM_PHY_REG 0xf831 /* PHY registers */
#define ZYD_EEPROM_DEVICE_VER 0xf837 /* Device version */
+#define ZYD_EEPROM_PHY_REG 0xf83c /* PHY registers */
#define ZYD_EEPROM_36M_CAL 0xf83f /* Calibration */
#define ZYD_EEPROM_11A_INT 0xf847 /* Interpolation */
#define ZYD_EEPROM_48M_CAL 0xf84f /* Calibration */
@@ -161,7 +162,7 @@
#define ZYD_RF_AL2210 0x7
#define ZYD_RF_MAXIM_NEW 0x8
#define ZYD_RF_GCT 0x9
-#define ZYD_RF_PV2000 0xa /* not supported yet */
+#define ZYD_RF_AL2230S 0xa
#define ZYD_RF_RALINK 0xb /* not supported yet */
#define ZYD_RF_INTERSIL 0xc /* not supported yet */
#define ZYD_RF_RFMD 0xd
@@ -437,7 +438,7 @@
{ ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \
{ ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \
{ ZYD_CR43, 0x10 }, { ZYD_CR44, 0x12 }, { ZYD_CR46, 0xff }, \
- { ZYD_CR47, 0x08 }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \
+ { ZYD_CR47, 0x1e }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \
{ ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \
{ ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \
{ ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \
@@ -459,7 +460,7 @@
{ ZYD_CR5, 0x00 }, { ZYD_CR6, 0x00 }, { ZYD_CR7, 0x00 }, \
{ ZYD_CR8, 0x00 }, { ZYD_CR9, 0x20 }, { ZYD_CR12, 0xf0 }, \
{ ZYD_CR20, 0x0e }, { ZYD_CR21, 0x0e }, { ZYD_CR27, 0x10 }, \
- { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x30 }, { ZYD_CR83, 0x24 }, \
+ { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x1E }, { ZYD_CR83, 0x24 }, \
{ ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0C }, \
{ ZYD_CR87, 0x12 }, { ZYD_CR88, 0x0C }, { ZYD_CR89, 0x00 }, \
{ ZYD_CR90, 0x10 }, { ZYD_CR91, 0x08 }, { ZYD_CR93, 0x00 }, \
@@ -470,19 +471,18 @@
{ ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, \
{ ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, \
{ ZYD_CR117, 0xfc }, { ZYD_CR118, 0xfa }, { ZYD_CR120, 0x4f }, \
- { ZYD_CR123, 0x27 }, { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, \
- { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
- { ZYD_CR131, 0x0C }, { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, \
- { ZYD_CR138, 0xa0 }, { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, \
- { ZYD_CR141, 0x82 }, { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, \
- { ZYD_CR144, 0x6c }, { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, \
- { ZYD_CR149, 0x50 }, { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, \
- { ZYD_CR160, 0xfe }, { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, \
- { ZYD_CR163, 0xfa }, { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, \
- { ZYD_CR166, 0xbe }, { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, \
- { ZYD_CR169, 0xba }, { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, \
- { ZYD_CR204, 0x7d }, { ZYD_CR203, 0x30 }, \
- { 0, 0 } \
+ { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, { ZYD_CR128, 0x14 }, \
+ { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0C }, \
+ { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, { ZYD_CR138, 0xa0 }, \
+ { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, { ZYD_CR141, 0x82 }, \
+ { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \
+ { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, { ZYD_CR149, 0x50 }, \
+ { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, { ZYD_CR160, 0xfe }, \
+ { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, { ZYD_CR163, 0xfa }, \
+ { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, { ZYD_CR166, 0xbe }, \
+ { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, { ZYD_CR169, 0xba }, \
+ { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, { ZYD_CR204, 0x7d }, \
+ { ZYD_CR203, 0x30 }, { 0, 0} \
}
#define ZYD_DEF_PHYB \
@@ -590,8 +590,6 @@
{ 0x181a60, 0x1c0000 } \
}
-
-
#define ZYD_AL2230_PHY \
{ \
{ ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, \
@@ -617,34 +615,73 @@
#define ZYD_AL2230_PHY_B \
{ \
- { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2b }, \
+ { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2B }, \
{ ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x93 }, \
{ ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, { ZYD_CR33, 0x28 }, \
{ ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, \
{ ZYD_CR44, 0x32 }, { ZYD_CR46, 0x99 }, { ZYD_CR47, 0x1e }, \
- { ZYD_CR48, 0x00 }, { ZYD_CR49, 0x00 }, { ZYD_CR51, 0x01 }, \
+ { ZYD_CR48, 0x06 }, { ZYD_CR49, 0xf9 }, { ZYD_CR51, 0x01 }, \
{ ZYD_CR52, 0x80 }, { ZYD_CR53, 0x7e }, { ZYD_CR65, 0x00 }, \
{ ZYD_CR66, 0x00 }, { ZYD_CR67, 0x00 }, { ZYD_CR68, 0x00 }, \
{ ZYD_CR69, 0x28 }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \
{ ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \
{ ZYD_CR91, 0x00 }, { ZYD_CR92, 0x0a }, { ZYD_CR98, 0x8d }, \
- { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR106, 0x24 }, \
- { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, { ZYD_CR110, 0x1f }, \
- { ZYD_CR111, 0x1f }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \
+ { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
+ { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, \
+ { ZYD_CR110, 0x1f }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \
+ { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \
{ ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfa }, \
{ ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x6c }, \
{ ZYD_CR122, 0xfc }, { ZYD_CR123, 0x57 }, { ZYD_CR125, 0xad }, \
{ ZYD_CR126, 0x6c }, { ZYD_CR127, 0x03 }, { ZYD_CR137, 0x50 }, \
{ ZYD_CR138, 0xa8 }, { ZYD_CR144, 0xac }, { ZYD_CR150, 0x0d }, \
- { ZYD_CR252, 0x00 }, { ZYD_CR253, 0x00 } \
+ { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 } \
}
-#define ZYD_AL2230_RF \
+#define ZYD_AL2230_PHY_PART1 \
+{ \
+ { ZYD_CR240, 0x57 }, { ZYD_CR9, 0xe0 } \
+}
+
+#define ZYD_AL2230_PHY_PART2 \
+{ \
+ { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x7f }, \
+}
+
+#define ZYD_AL2230_PHY_PART3 \
+{ \
+ { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
+}
+
+#define ZYD_AL2230S_PHY_INIT \
+{ \
+ { ZYD_CR47, 0x1e }, { ZYD_CR106, 0x22 }, { ZYD_CR107, 0x2a }, \
+ { ZYD_CR109, 0x13 }, { ZYD_CR118, 0xf8 }, { ZYD_CR119, 0x12 }, \
+ { ZYD_CR122, 0xe0 }, { ZYD_CR128, 0x10 }, { ZYD_CR129, 0x0e }, \
+ { ZYD_CR130, 0x10 } \
+}
+
+#define ZYD_AL2230_PHY_FINI_PART1 \
+{ \
+ { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR79, 0x58 }, \
+ { ZYD_CR12, 0xf0 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x58 }, \
+ { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 }, \
+}
+
+#define ZYD_AL2230_RF_PART1 \
+{ \
+ 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3 \
+}
+
+#define ZYD_AL2230_RF_PART2 \
{ \
- 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3, \
0x000da4, 0x0f4dc5, 0x0805b6, 0x011687, 0x000688, 0x0403b9, \
- 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f, 0x00d00f, \
- 0x004c0f, 0x00540f, 0x00700f, 0x00500f \
+ 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f \
+}
+
+#define ZYD_AL2230_RF_PART3 \
+{ \
+ 0x00d00f, 0x004c0f, 0x00540f, 0x00700f, 0x00500f \
}
#define ZYD_AL2230_RF_B \
@@ -654,6 +691,22 @@
0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00580f \
}
+#define ZYD_AL2230_RF_B_PART1 \
+{ \
+ 0x8cccd0, 0x481dc0, 0xcfff00, 0x25a000 \
+}
+
+#define ZYD_AL2230_RF_B_PART2 \
+{ \
+ 0x25a000, 0xa3b2f0, 0x6da010, 0xe36280, 0x116000, 0x9dc020, \
+ 0x5ddb00, 0xd99000, 0x3ffbd0, 0xb00000, 0xf01a00 \
+}
+
+#define ZYD_AL2230_RF_B_PART3 \
+{ \
+ 0xf01b00, 0xf01e00, 0xf01a00 \
+}
+
#define ZYD_AL2230_CHANTABLE \
{ \
{ 0x03f790, 0x033331, 0x00000d }, \
@@ -672,7 +725,23 @@
{ 0x03e7c0, 0x066661, 0x00000d } \
}
-
+#define ZYD_AL2230_CHANTABLE_B \
+{ \
+ { 0x09efc0, 0x8cccc0, 0xb00000 }, \
+ { 0x09efc0, 0x8cccd0, 0xb00000 }, \
+ { 0x09e7c0, 0x8cccc0, 0xb00000 }, \
+ { 0x09e7c0, 0x8cccd0, 0xb00000 }, \
+ { 0x05efc0, 0x8cccc0, 0xb00000 }, \
+ { 0x05efc0, 0x8cccd0, 0xb00000 }, \
+ { 0x05e7c0, 0x8cccc0, 0xb00000 }, \
+ { 0x05e7c0, 0x8cccd0, 0xb00000 }, \
+ { 0x0defc0, 0x8cccc0, 0xb00000 }, \
+ { 0x0defc0, 0x8cccd0, 0xb00000 }, \
+ { 0x0de7c0, 0x8cccc0, 0xb00000 }, \
+ { 0x0de7c0, 0x8cccd0, 0xb00000 }, \
+ { 0x03efc0, 0x8cccc0, 0xb00000 }, \
+ { 0x03e7c0, 0x866660, 0xb00000 } \
+}
#define ZYD_AL7230B_PHY_1 \
{ \
@@ -744,8 +813,6 @@
{ 0x03ec00, 0x866660 } \
}
-
-
#define ZYD_AL2210_PHY \
{ \
{ ZYD_CR9, 0xe0 }, { ZYD_CR10, 0x91 }, { ZYD_CR12, 0x90 }, \
@@ -771,8 +838,6 @@
0x019a80, 0x019b40 \
}
-
-
#define ZYD_GCT_PHY \
{ \
{ ZYD_CR47, 0x1e }, { ZYD_CR15, 0xdc }, { ZYD_CR113, 0xc0 }, \
@@ -801,8 +866,6 @@
0x1a3000, 0x1ab000 \
}
-
-
#define ZYD_MAXIM_PHY \
{ \
{ ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \
@@ -855,8 +918,6 @@
{ 0x199a4, 0x20a53 } \
}
-
-
#define ZYD_MAXIM2_PHY \
{ \
{ ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \
@@ -919,6 +980,7 @@
*/
#define ZYD_DOWNLOADREQ 0x30
#define ZYD_DOWNLOADSTS 0x31
+#define ZYD_READFWDATAREQ 0x32
/* possible values for register ZYD_CR_INTERRUPT */
#define ZYD_HWINT_MASK 0x004f0000
@@ -950,10 +1012,15 @@
/* helpers for register ZYD_MAC_RXFILTER */
#define ZYD_FILTER_MONITOR 0xffffffff
-#define ZYD_FILTER_BSS \
- (ZYD_FILTER_ASS_RSP | ZYD_FILTER_REASS_RSP | \
- ZYD_FILTER_PRB_RSP | ZYD_FILTER_BCN | ZYD_FILTER_DEASS | \
- ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH)
+#define ZYD_FILTER_BSS \
+ (ZYD_FILTER_ASS_REQ | ZYD_FILTER_ASS_RSP | \
+ ZYD_FILTER_REASS_REQ | ZYD_FILTER_REASS_RSP | \
+ ZYD_FILTER_PRB_REQ | ZYD_FILTER_PRB_RSP | \
+ (0x3 << 6) | \
+ ZYD_FILTER_BCN | ZYD_FILTER_ATIM | ZYD_FILTER_DEASS | \
+ ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH | \
+ (0x7 << 13) | \
+ ZYD_FILTER_PS_POLL | ZYD_FILTER_ACK)
#define ZYD_FILTER_HOSTAP \
(ZYD_FILTER_ASS_REQ | ZYD_FILTER_REASS_REQ | \
ZYD_FILTER_PRB_REQ | ZYD_FILTER_DEASS | ZYD_FILTER_AUTH | \
@@ -1138,19 +1205,9 @@ struct zyd_rf {
void (*cfg_init_hw) (struct zyd_softc *, struct zyd_rf *);
void (*cfg_switch_radio) (struct zyd_softc *, uint8_t on);
void (*cfg_set_channel) (struct zyd_softc *, struct zyd_rf *, uint8_t);
- uint8_t width;
-};
+ void (*cfg_bandedge6) (struct zyd_softc *, struct zyd_rf *, uint8_t);
-enum {
- ZYD_TR_BULK_DT_WR,
- ZYD_TR_BULK_DT_RD,
- ZYD_TR_BULK_CS_WR,
- ZYD_TR_BULK_CS_RD,
- ZYD_TR_INTR_DT_WR,
- ZYD_TR_INTR_DT_RD,
- ZYD_TR_INTR_CS_WR,
- ZYD_TR_INTR_CS_RD,
- ZYD_N_TRANSFER,
+ uint8_t width;
};
struct zyd_ifq {
@@ -1215,8 +1272,20 @@ struct zyd_config_copy {
uint8_t if_broadcastaddr[IEEE80211_ADDR_LEN];
};
+enum {
+ ZYD_BULK_DT_WR,
+ ZYD_BULK_DT_RD,
+ ZYD_BULK_CS_WR,
+ ZYD_BULK_CS_RD,
+ ZYD_INTR_DT_WR,
+ ZYD_INTR_DT_RD,
+ ZYD_INTR_CS_WR,
+ ZYD_INTR_CS_RD,
+ ZYD_N_TRANSFER = 8,
+};
+
struct zyd_softc {
- void *sc_evilhack; /* XXX this pointer must be first */
+ struct ifnet *sc_ifp;
struct zyd_rf sc_rf;
struct usb2_callout sc_watchdog;
@@ -1230,7 +1299,6 @@ struct zyd_softc {
struct zyd_ifq sc_tx_queue;
struct cv sc_intr_cv;
- struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
struct usb2_xfer *sc_xfer[ZYD_N_TRANSFER];
const struct ieee80211_rate_table *sc_rates;
@@ -1239,6 +1307,10 @@ struct zyd_softc {
uint32_t sc_rxtap_len;
uint32_t sc_txtap_len;
uint32_t sc_unit;
+ uint32_t sc_atim_wnd;
+ uint32_t sc_pre_tbtt;
+ uint32_t sc_bcn_int;
+
int sc_ns_arg;
uint16_t sc_firmware_base;
@@ -1254,7 +1326,12 @@ struct zyd_softc {
uint8_t sc_mac_rev;
uint8_t sc_rf_rev;
uint8_t sc_pa_rev;
- uint8_t sc_fix_cr47;
+ uint8_t sc_al2230s;
+ uint8_t sc_cckgain;
+ uint8_t sc_bandedge6;
+ uint8_t sc_newphy;
+ uint8_t sc_ledtype;
+ uint8_t sc_txled;
uint8_t sc_fix_cr157;
uint8_t sc_pwr_cal[14];
uint8_t sc_pwr_int[14];
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index a418c6d..259f2f6 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -1135,8 +1135,8 @@ open_device(blkif_t *blkif)
}
blkif->media_num_sectors = blkif->media_size >> blkif->sector_size_shift;
- blkif->major = umajor(vattr.va_rdev);
- blkif->minor = uminor(vattr.va_rdev);
+ blkif->major = major(vattr.va_rdev);
+ blkif->minor = minor(vattr.va_rdev);
DPRINTF("opened dev=%s major=%d minor=%d sector_size=%u media_size=%lld\n",
blkif->dev_name, blkif->major, blkif->minor, blkif->sector_size, blkif->media_size);
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index dc36007..fdebc9d 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -40,10 +40,10 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <machine/vmparam.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/xen_intr.h>
-#include <machine/xen/evtchn.h>
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/protocols.h>
#include <xen/xenbus/xenbusvar.h>
@@ -214,7 +214,7 @@ xlvbd_add(device_t dev, blkif_sector_t capacity,
struct xb_softc *sc;
int unit, error = 0;
const char *name;
-
+
blkfront_vdevice_to_unit(vdevice, &unit, &name);
sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
@@ -227,12 +227,12 @@ xlvbd_add(device_t dev, blkif_sector_t capacity,
memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
sc->xb_disk = disk_alloc();
- sc->xb_disk->d_unit = unit;
+ sc->xb_disk->d_unit = sc->xb_unit;
sc->xb_disk->d_open = blkif_open;
sc->xb_disk->d_close = blkif_close;
sc->xb_disk->d_ioctl = blkif_ioctl;
sc->xb_disk->d_strategy = xb_strategy;
- sc->xb_disk->d_name = "xbd";
+ sc->xb_disk->d_name = name;
sc->xb_disk->d_drv1 = sc;
sc->xb_disk->d_sectorsize = sector_size;
@@ -329,8 +329,8 @@ blkfront_attach(device_t dev)
/* FIXME: Use dynamic device id if this is not set. */
err = xenbus_scanf(XBT_NIL, xenbus_get_node(dev),
- "virtual-device", "%i", &vdevice);
- if (err != 1) {
+ "virtual-device", NULL, "%i", &vdevice);
+ if (err) {
xenbus_dev_fatal(dev, err, "reading virtual-device");
printf("couldn't find virtual device");
return (err);
@@ -363,9 +363,8 @@ blkfront_attach(device_t dev)
info->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
err = talk_to_backend(dev, info);
- if (err) {
- return err;
- }
+ if (err)
+ return (err);
return (0);
}
@@ -381,7 +380,8 @@ blkfront_resume(device_t dev)
blkif_free(info, 1);
err = talk_to_backend(dev, info);
- if (!err)
+
+ if (info->connected == BLKIF_STATE_SUSPENDED && !err)
blkif_recover(info);
return err;
@@ -427,7 +427,7 @@ talk_to_backend(device_t dev, struct blkfront_info *info)
}
err = xenbus_transaction_end(xbt, 0);
if (err) {
- if (err == -EAGAIN)
+ if (err == EAGAIN)
goto again;
xenbus_dev_fatal(dev, err, "completing transaction");
goto destroy_blkring;
@@ -450,7 +450,7 @@ static int
setup_blkring(device_t dev, struct blkfront_info *info)
{
blkif_sring_t *sring;
- int err;
+ int error;
info->ring_ref = GRANT_INVALID_REF;
@@ -462,28 +462,27 @@ setup_blkring(device_t dev, struct blkfront_info *info)
SHARED_RING_INIT(sring);
FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
- err = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT));
- if (err < 0) {
+ error = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT),
+ &info->ring_ref);
+ if (error) {
free(sring, M_DEVBUF);
info->ring.sring = NULL;
goto fail;
}
- info->ring_ref = err;
- err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
+ error = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
"xbd", (driver_intr_t *)blkif_int, info,
- INTR_TYPE_BIO | INTR_MPSAFE, NULL);
- if (err <= 0) {
- xenbus_dev_fatal(dev, err,
+ INTR_TYPE_BIO | INTR_MPSAFE, &info->irq);
+ if (error) {
+ xenbus_dev_fatal(dev, error,
"bind_evtchn_to_irqhandler failed");
goto fail;
}
- info->irq = err;
- return 0;
+ return (0);
fail:
blkif_free(info, 0);
- return err;
+ return (error);
}
@@ -999,7 +998,7 @@ blkif_free(struct blkfront_info *info, int suspend)
info->ring.sring = NULL;
}
if (info->irq)
- unbind_from_irqhandler(info->irq, info);
+ unbind_from_irqhandler(info->irq);
info->irq = 0;
}
diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c
index 5b556c2..a3d616a 100644
--- a/sys/dev/xen/console/console.c
+++ b/sys/dev/xen/console/console.c
@@ -15,8 +15,8 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/stdarg.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
#include <sys/cons.h>
#include <sys/priv.h>
#include <sys/proc.h>
@@ -75,17 +75,17 @@ static unsigned int wc, wp; /* write_cons, write_prod */
#define XCUNIT(x) (dev2unit(x))
#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN))
#define CN_LOCK_INIT(x, _name) \
- mtx_init(&x, _name, NULL, MTX_SPIN|MTX_RECURSE)
+ mtx_init(&x, _name, NULL, MTX_DEF|MTX_RECURSE)
#define CN_LOCK(l) \
do { \
if (panicstr == NULL) \
- mtx_lock_spin(&(l)); \
+ mtx_lock(&(l)); \
} while (0)
#define CN_UNLOCK(l) \
do { \
if (panicstr == NULL) \
- mtx_unlock_spin(&(l)); \
+ mtx_unlock(&(l)); \
} while (0)
#define CN_LOCK_ASSERT(x) mtx_assert(&x, MA_OWNED)
#define CN_LOCK_DESTROY(x) mtx_destroy(&x)
@@ -216,6 +216,8 @@ xc_probe(device_t dev)
static int
xc_attach(device_t dev)
{
+ int error;
+ struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev);
if (xen_start_info->flags & SIF_INITDOMAIN) {
xc_consdev.cn_putc = xccnputc_dom0;
@@ -232,14 +234,15 @@ xc_attach(device_t dev)
callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, xccons);
if (xen_start_info->flags & SIF_INITDOMAIN) {
- PANIC_IF(bind_virq_to_irqhandler(
- VIRQ_CONSOLE,
- 0,
- "console",
- NULL,
- xencons_priv_interrupt,
- INTR_TYPE_TTY) < 0);
+ error = bind_virq_to_irqhandler(
+ VIRQ_CONSOLE,
+ 0,
+ "console",
+ NULL,
+ xencons_priv_interrupt,
+ sc, INTR_TYPE_TTY, NULL);
+ KASSERT(error >= 0, ("can't register console interrupt"));
}
diff --git a/sys/dev/xen/console/xencons_ring.c b/sys/dev/xen/console/xencons_ring.c
index 3d232376..596b5de 100644
--- a/sys/dev/xen/console/xencons_ring.c
+++ b/sys/dev/xen/console/xencons_ring.c
@@ -15,19 +15,20 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/stdarg.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
#include <sys/cons.h>
#include <dev/xen/console/xencons_ring.h>
-#include <machine/xen/evtchn.h>
+#include <xen/evtchn.h>
#include <xen/interface/io/console.h>
#define console_evtchn console.domU.evtchn
extern char *console_page;
-
+extern struct mtx cn_mtx;
+
static inline struct xencons_interface *
xencons_interface(void)
{
@@ -82,6 +83,7 @@ xencons_handle_input(void *unused)
struct xencons_interface *intf;
XENCONS_RING_IDX cons, prod;
+ mtx_lock(&cn_mtx);
intf = xencons_interface();
cons = intf->in_cons;
@@ -99,6 +101,7 @@ xencons_handle_input(void *unused)
notify_remote_via_evtchn(xen_start_info->console_evtchn);
xencons_tx();
+ mtx_unlock(&cn_mtx);
}
void
diff --git a/sys/dev/xen/evtchn/evtchn_dev.c b/sys/dev/xen/evtchn/evtchn_dev.c
index a206708..6925a22 100644
--- a/sys/dev/xen/evtchn/evtchn_dev.c
+++ b/sys/dev/xen/evtchn/evtchn_dev.c
@@ -26,13 +26,13 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen-os.h>
-#include <machine/xen_intr.h>
+#include <xen/xen_intr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/synch_bitops.h>
-#include <machine/hypervisor.h>
+#include <xen/hypervisor.h>
typedef struct evtchn_sotfc {
diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c
index 950a68c..a6111e2 100644
--- a/sys/dev/xen/netback/netback.c
+++ b/sys/dev/xen/netback/netback.c
@@ -30,6 +30,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -57,6 +58,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
+#ifdef SCTP
+#include <netinet/sctp.h>
+#include <netinet/sctp_crc32.h>
+#endif
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
@@ -295,6 +300,11 @@ fixup_checksum(struct mbuf *m)
htons(IPPROTO_TCP + (iplen - iphlen)));
th->th_sum = in_cksum_skip(m, iplen + sizeof(*eh), sizeof(*eh) + iphlen);
m->m_pkthdr.csum_flags &= ~CSUM_TCP;
+#ifdef SCTP
+ } else if (sw_csum & CSUM_SCTP) {
+ sctp_delayed_cksum(m);
+ sw_csum &= ~CSUM_SCTP;
+#endif
} else {
u_short csum;
struct udphdr *uh = (struct udphdr *)((caddr_t)ip + iphlen);
@@ -908,7 +918,8 @@ netif_rx(netif_t *netif)
#ifdef XEN_NETBACK_FIXUP_CSUM
/* Check if we need to compute a checksum. This happens */
/* when bridging from one domain to another. */
- if ((m->m_pkthdr.csum_flags & CSUM_DELAY_DATA))
+ if ((m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) ||
+ (m->m_pkthdr.csum_flags & CSUM_SCTP))
fixup_checksum(m);
#endif
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index 607628f..dbf5013 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -24,6 +24,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/kernel.h>
@@ -62,9 +63,9 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
#include <xen/gnttab.h>
#include <xen/interface/memory.h>
#include <dev/xen/netfront/mbufq.h>
@@ -363,24 +364,25 @@ makembuf (struct mbuf *buf)
static int
xen_net_read_mac(device_t dev, uint8_t mac[])
{
- char *s;
- int i;
- char *e;
- char *macstr = xenbus_read(XBT_NIL, xenbus_get_node(dev), "mac", NULL);
- if (IS_ERR(macstr)) {
- return PTR_ERR(macstr);
- }
+ int error, i;
+ char *s, *e, *macstr;
+
+ error = xenbus_read(XBT_NIL, xenbus_get_node(dev), "mac", NULL,
+ (void **) &macstr);
+ if (error)
+ return (error);
+
s = macstr;
for (i = 0; i < ETHER_ADDR_LEN; i++) {
mac[i] = strtoul(s, &e, 16);
if (s == e || (e[0] != ':' && e[0] != 0)) {
free(macstr, M_DEVBUF);
- return ENOENT;
+ return (ENOENT);
}
s = &e[1];
}
free(macstr, M_DEVBUF);
- return 0;
+ return (0);
}
/**
@@ -422,13 +424,11 @@ netfront_attach(device_t dev)
* leave the device-layer structures intact so that this is transparent to the
* rest of the kernel.
*/
-static int
+static int
netfront_resume(device_t dev)
{
struct netfront_info *info = device_get_softc(dev);
-
- DPRINTK("%s\n", xenbus_get_node(dev));
-
+
netif_disconnect_backend(info);
return (0);
}
@@ -532,7 +532,7 @@ setup_device(device_t dev, struct netfront_info *info)
{
netif_tx_sring_t *txs;
netif_rx_sring_t *rxs;
- int err;
+ int error;
struct ifnet *ifp;
ifp = info->xn_ifp;
@@ -545,51 +545,45 @@ setup_device(device_t dev, struct netfront_info *info)
txs = (netif_tx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
if (!txs) {
- err = ENOMEM;
- xenbus_dev_fatal(dev, err, "allocating tx ring page");
+ error = ENOMEM;
+ xenbus_dev_fatal(dev, error, "allocating tx ring page");
goto fail;
}
SHARED_RING_INIT(txs);
FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
- err = xenbus_grant_ring(dev, virt_to_mfn(txs));
- if (err < 0)
+ error = xenbus_grant_ring(dev, virt_to_mfn(txs), &info->tx_ring_ref);
+ if (error)
goto fail;
- info->tx_ring_ref = err;
rxs = (netif_rx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
if (!rxs) {
- err = ENOMEM;
- xenbus_dev_fatal(dev, err, "allocating rx ring page");
+ error = ENOMEM;
+ xenbus_dev_fatal(dev, error, "allocating rx ring page");
goto fail;
}
SHARED_RING_INIT(rxs);
FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
- err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
- if (err < 0)
+ error = xenbus_grant_ring(dev, virt_to_mfn(rxs), &info->rx_ring_ref);
+ if (error)
goto fail;
- info->rx_ring_ref = err;
-#if 0
- network_connect(info);
-#endif
- err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
- "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL);
+ error = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
+ "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, &info->irq);
- if (err <= 0) {
- xenbus_dev_fatal(dev, err,
+ if (error) {
+ xenbus_dev_fatal(dev, error,
"bind_evtchn_to_irqhandler failed");
goto fail;
}
- info->irq = err;
-
+
show_device(info);
- return 0;
+ return (0);
fail:
netif_free(info);
- return err;
+ return (error);
}
/**
@@ -1225,7 +1219,7 @@ xennet_get_responses(struct netfront_info *np,
MULTI_update_va_mapping(mcl, (u_long)vaddr,
(((vm_paddr_t)mfn) << PAGE_SHIFT) | PG_RW |
PG_V | PG_M | PG_A, 0);
- pfn = (uint32_t)m->m_ext.ext_arg1;
+ pfn = (uintptr_t)m->m_ext.ext_arg1;
mmu->ptr = ((vm_paddr_t)mfn << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE;
mmu->val = pfn;
@@ -1241,11 +1235,12 @@ xennet_get_responses(struct netfront_info *np,
gnttab_release_grant_reference(&np->gref_rx_head, ref);
next:
- if (m != NULL) {
- m->m_len = rx->status;
- m->m_data += rx->offset;
- m0->m_pkthdr.len += rx->status;
- }
+ if (m == NULL)
+ break;
+
+ m->m_len = rx->status;
+ m->m_data += rx->offset;
+ m0->m_pkthdr.len += rx->status;
if (!(rx->flags & NETRXF_more_data))
break;
@@ -1557,18 +1552,18 @@ xn_stop(struct netfront_info *sc)
int
network_connect(struct netfront_info *np)
{
- int i, requeue_idx, err;
+ int i, requeue_idx, error;
grant_ref_t ref;
netif_rx_request_t *req;
u_int feature_rx_copy, feature_rx_flip;
- err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
- "feature-rx-copy", "%u", &feature_rx_copy);
- if (err != 1)
+ error = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
+ "feature-rx-copy", NULL, "%u", &feature_rx_copy);
+ if (error)
feature_rx_copy = 0;
- err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
- "feature-rx-flip", "%u", &feature_rx_flip);
- if (err != 1)
+ error = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
+ "feature-rx-flip", NULL, "%u", &feature_rx_flip);
+ if (error)
feature_rx_flip = 1;
/*
@@ -1581,9 +1576,9 @@ network_connect(struct netfront_info *np)
XN_LOCK(np);
/* Recovery procedure: */
- err = talk_to_backend(np->xbdev, np);
- if (err)
- return (err);
+ error = talk_to_backend(np->xbdev, np);
+ if (error)
+ return (error);
/* Step 1: Reinitialise variables. */
netif_release_tx_bufs(np);
@@ -1591,6 +1586,7 @@ network_connect(struct netfront_info *np)
/* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
struct mbuf *m;
+ u_long pfn;
if (np->rx_mbufs[i] == NULL)
continue;
@@ -1598,15 +1594,16 @@ network_connect(struct netfront_info *np)
m = np->rx_mbufs[requeue_idx] = xennet_get_rx_mbuf(np, i);
ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i);
req = RING_GET_REQUEST(&np->rx, requeue_idx);
+ pfn = vtophys(mtod(m, vm_offset_t)) >> PAGE_SHIFT;
if (!np->copying_receiver) {
gnttab_grant_foreign_transfer_ref(ref,
xenbus_get_otherend_id(np->xbdev),
- vtophys(mtod(m, vm_offset_t)));
+ pfn);
} else {
gnttab_grant_foreign_access_ref(ref,
xenbus_get_otherend_id(np->xbdev),
- vtophys(mtod(m, vm_offset_t)), 0);
+ PFNTOMFN(pfn), 0);
}
req->gref = ref;
req->id = requeue_idx;
@@ -1707,7 +1704,7 @@ create_netdev(device_t dev)
ifp = np->xn_ifp = if_alloc(IFT_ETHER);
ifp->if_softc = np;
if_initname(ifp, "xn", device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = xn_ioctl;
ifp->if_output = ether_output;
ifp->if_start = xn_start;
@@ -1777,11 +1774,14 @@ static void netif_free(struct netfront_info *info)
#endif
}
-
-
static void netif_disconnect_backend(struct netfront_info *info)
{
- xn_stop(info);
+ XN_RX_LOCK(info);
+ XN_TX_LOCK(info);
+ netfront_carrier_off(info);
+ XN_TX_UNLOCK(info);
+ XN_RX_UNLOCK(info);
+
end_access(info->tx_ring_ref, info->tx.sring);
end_access(info->rx_ring_ref, info->rx.sring);
info->tx_ring_ref = GRANT_INVALID_REF;
@@ -1789,12 +1789,9 @@ static void netif_disconnect_backend(struct netfront_info *info)
info->tx.sring = NULL;
info->rx.sring = NULL;
-#if 0
if (info->irq)
- unbind_from_irqhandler(info->irq, info->netdev);
-#else
- panic("FIX ME");
-#endif
+ unbind_from_irqhandler(info->irq);
+
info->irq = 0;
}
diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c
index 9d87352..ae6d3f8 100644
--- a/sys/fs/cd9660/cd9660_lookup.c
+++ b/sys/fs/cd9660/cd9660_lookup.c
@@ -94,28 +94,33 @@ cd9660_lookup(ap)
struct iso_node *dp; /* inode for directory being searched */
struct iso_mnt *imp; /* filesystem that directory is in */
struct buf *bp; /* a buffer of directory entries */
- struct iso_directory_record *ep = 0;/* the current directory entry */
+ struct iso_directory_record *ep;/* the current directory entry */
+ struct iso_directory_record *ep2;/* copy of current directory entry */
int entryoffsetinblock; /* offset of ep in bp's buffer */
int saveoffset = 0; /* offset of last directory entry in dir */
+ doff_t i_diroff; /* cached i_diroff value. */
+ doff_t i_offset; /* cached i_offset value. */
int numdirpasses; /* strategy for directory search */
doff_t endsearch; /* offset to end directory search */
struct vnode *pdp; /* saved dp during symlink work */
struct vnode *tdp; /* returned by cd9660_vget_internal */
u_long bmask; /* block offset mask */
int error;
- ino_t ino = 0, saved_ino;
- int reclen;
+ ino_t ino, i_ino;
+ int ltype, reclen;
u_short namelen;
int isoflags;
char altname[NAME_MAX];
int res;
int assoc, len;
char *name;
+ struct mount *mp;
struct vnode **vpp = ap->a_vpp;
struct componentname *cnp = ap->a_cnp;
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
+ ep2 = ep = NULL;
bp = NULL;
*vpp = NULL;
vdp = ap->a_dvp;
@@ -125,9 +130,11 @@ cd9660_lookup(ap)
/*
* We now have a segment name to search for, and a directory to search.
*/
-
+ ino = reclen = 0;
+ i_diroff = dp->i_diroff;
len = cnp->cn_namelen;
name = cnp->cn_nameptr;
+
/*
* A leading `=' means, we are looking for an associated file
*/
@@ -149,15 +156,14 @@ cd9660_lookup(ap)
* of simplicity.
*/
bmask = imp->im_bmask;
- if (nameiop != LOOKUP || dp->i_diroff == 0 ||
- dp->i_diroff > dp->i_size) {
+ if (nameiop != LOOKUP || i_diroff == 0 || i_diroff > dp->i_size) {
entryoffsetinblock = 0;
- dp->i_offset = 0;
+ i_offset = 0;
numdirpasses = 1;
} else {
- dp->i_offset = dp->i_diroff;
- if ((entryoffsetinblock = dp->i_offset & bmask) &&
- (error = cd9660_blkatoff(vdp, (off_t)dp->i_offset, NULL, &bp)))
+ i_offset = i_diroff;
+ if ((entryoffsetinblock = i_offset & bmask) &&
+ (error = cd9660_blkatoff(vdp, (off_t)i_offset, NULL, &bp)))
return (error);
numdirpasses = 2;
nchstats.ncs_2passes++;
@@ -165,17 +171,17 @@ cd9660_lookup(ap)
endsearch = dp->i_size;
searchloop:
- while (dp->i_offset < endsearch) {
+ while (i_offset < endsearch) {
/*
* If offset is on a block boundary,
* read the next directory block.
* Release previous if it exists.
*/
- if ((dp->i_offset & bmask) == 0) {
+ if ((i_offset & bmask) == 0) {
if (bp != NULL)
brelse(bp);
if ((error =
- cd9660_blkatoff(vdp, (off_t)dp->i_offset, NULL, &bp)) != 0)
+ cd9660_blkatoff(vdp, (off_t)i_offset, NULL, &bp)) != 0)
return (error);
entryoffsetinblock = 0;
}
@@ -188,8 +194,8 @@ searchloop:
reclen = isonum_711(ep->length);
if (reclen == 0) {
/* skip to next block, if any */
- dp->i_offset =
- (dp->i_offset & ~bmask) + imp->logical_block_size;
+ i_offset =
+ (i_offset & ~bmask) + imp->logical_block_size;
continue;
}
@@ -224,7 +230,7 @@ searchloop:
* Save directory entry's inode number and
* release directory buffer.
*/
- dp->i_ino = isodirino(ep, imp);
+ i_ino = isodirino(ep, imp);
goto found;
}
if (namelen != 1
@@ -241,7 +247,7 @@ searchloop:
else
ino = dbtob(bp->b_blkno)
+ entryoffsetinblock;
- saveoffset = dp->i_offset;
+ saveoffset = i_offset;
} else if (ino)
goto foundino;
#ifdef NOSORTBUG /* On some CDs directory entries are not sorted correctly */
@@ -257,22 +263,22 @@ searchloop:
ino = isodirino(ep, imp);
else
ino = dbtob(bp->b_blkno) + entryoffsetinblock;
- dp->i_ino = ino;
- cd9660_rrip_getname(ep,altname,&namelen,&dp->i_ino,imp);
+ i_ino = ino;
+ cd9660_rrip_getname(ep, altname, &namelen, &i_ino, imp);
if (namelen == cnp->cn_namelen
&& !bcmp(name,altname,namelen))
goto found;
ino = 0;
break;
}
- dp->i_offset += reclen;
+ i_offset += reclen;
entryoffsetinblock += reclen;
}
if (ino) {
foundino:
- dp->i_ino = ino;
- if (saveoffset != dp->i_offset) {
- if (lblkno(imp, dp->i_offset) !=
+ i_ino = ino;
+ if (saveoffset != i_offset) {
+ if (lblkno(imp, i_offset) !=
lblkno(imp, saveoffset)) {
if (bp != NULL)
brelse(bp);
@@ -283,7 +289,8 @@ foundino:
entryoffsetinblock = saveoffset & bmask;
ep = (struct iso_directory_record *)
((char *)bp->b_data + entryoffsetinblock);
- dp->i_offset = saveoffset;
+ reclen = isonum_711(ep->length);
+ i_offset = saveoffset;
}
goto found;
}
@@ -294,8 +301,8 @@ notfound:
*/
if (numdirpasses == 2) {
numdirpasses--;
- dp->i_offset = 0;
- endsearch = dp->i_diroff;
+ i_offset = 0;
+ endsearch = i_diroff;
goto searchloop;
}
if (bp != NULL)
@@ -320,10 +327,10 @@ found:
* in the cache as to where the entry was found.
*/
if ((flags & ISLASTCN) && nameiop == LOOKUP)
- dp->i_diroff = dp->i_offset;
+ dp->i_diroff = i_offset;
/*
- * Step through the translation in the name. We do not `iput' the
+ * Step through the translation in the name. We do not `vput' the
* directory because we may need it again if a symbolic link
* is relative to the current directory. Instead we save it
* unlocked as "pdp". We must get the target inode before unlocking
@@ -333,7 +340,7 @@ found:
* when following backward pointers ".." we must unlock the
* parent directory before getting the requested directory.
* There is a potential race condition here if both the current
- * and parent directories are removed before the `iget' for the
+ * and parent directories are removed before the `vget' for the
* inode associated with ".." returns. We hope that this occurs
* infrequently since we cannot avoid this race condition without
* implementing a sophisticated deadlock detection algorithm.
@@ -342,30 +349,75 @@ found:
* that point backwards in the directory structure.
*/
pdp = vdp;
+
/*
- * If ino is different from dp->i_ino,
+ * Make a copy of the directory entry for non "." lookups so
+ * we can drop the buffer before calling vget() to avoid a
+ * lock order reversal between the vnode lock and the buffer
+ * lock.
+ */
+ if (dp->i_number != i_ino) {
+ ep2 = malloc(reclen, M_TEMP, M_WAITOK);
+ bcopy(ep, ep2, reclen);
+ ep = ep2;
+ }
+ brelse(bp);
+
+ /*
+ * If ino is different from i_ino,
* it's a relocated directory.
*/
if (flags & ISDOTDOT) {
- saved_ino = dp->i_ino;
- VOP_UNLOCK(pdp, 0); /* race to get the inode */
- error = cd9660_vget_internal(vdp->v_mount, saved_ino,
- LK_EXCLUSIVE, &tdp,
- saved_ino != ino, ep);
- brelse(bp);
- vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
+ /*
+ * Expanded copy of vn_vget_ino() so that we can use
+ * cd9660_vget_internal().
+ */
+ mp = pdp->v_mount;
+ ltype = VOP_ISLOCKED(pdp);
+ for (;;) {
+ error = vfs_busy(mp, MBF_NOWAIT);
+ if (error == 0)
+ break;
+ VOP_UNLOCK(pdp, 0);
+ pause("vn_vget", 1);
+ vn_lock(pdp, ltype | LK_RETRY);
+ if (pdp->v_iflag & VI_DOOMED)
+ return (ENOENT);
+ }
+ VOP_UNLOCK(pdp, 0);
+ error = cd9660_vget_internal(vdp->v_mount, i_ino,
+ cnp->cn_lkflags, &tdp,
+ i_ino != ino, ep);
+ free(ep2, M_TEMP);
+ vfs_unbusy(mp);
+ vn_lock(pdp, ltype | LK_RETRY);
+ if (pdp->v_iflag & VI_DOOMED) {
+ if (error == 0)
+ vput(tdp);
+ error = ENOENT;
+ }
if (error)
return (error);
*vpp = tdp;
- } else if (dp->i_number == dp->i_ino) {
- brelse(bp);
+ } else if (dp->i_number == i_ino) {
VREF(vdp); /* we want ourself, ie "." */
+ /*
+ * When we lookup "." we still can be asked to lock it
+ * differently.
+ */
+ ltype = cnp->cn_lkflags & LK_TYPE_MASK;
+ if (ltype != VOP_ISLOCKED(vdp)) {
+ if (ltype == LK_EXCLUSIVE)
+ vn_lock(vdp, LK_UPGRADE | LK_RETRY);
+ else /* if (ltype == LK_SHARED) */
+ vn_lock(vdp, LK_DOWNGRADE | LK_RETRY);
+ }
*vpp = vdp;
} else {
- error = cd9660_vget_internal(vdp->v_mount, dp->i_ino,
- LK_EXCLUSIVE, &tdp,
- dp->i_ino != ino, ep);
- brelse(bp);
+ error = cd9660_vget_internal(vdp->v_mount, i_ino,
+ cnp->cn_lkflags, &tdp,
+ i_ino != ino, ep);
+ free(ep2, M_TEMP);
if (error)
return (error);
*vpp = tdp;
diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c
index 90be9f3..64d449e 100644
--- a/sys/fs/cd9660/cd9660_node.c
+++ b/sys/fs/cd9660/cd9660_node.c
@@ -92,7 +92,6 @@ cd9660_reclaim(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
- struct iso_node *ip = VTOI(vp);
if (prtactive && vrefcnt(vp) != 0)
vprint("cd9660_reclaim: pushing active", vp);
@@ -108,8 +107,6 @@ cd9660_reclaim(ap)
/*
* Purge old data structures associated with the inode.
*/
- if (ip->i_mnt->im_devvp)
- vrele(ip->i_mnt->im_devvp);
free(vp->v_data, M_ISOFSNODE);
vp->v_data = NULL;
return (0);
diff --git a/sys/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h
index 1675f80..80e233e 100644
--- a/sys/fs/cd9660/cd9660_node.h
+++ b/sys/fs/cd9660/cd9660_node.h
@@ -64,8 +64,6 @@ struct iso_node {
struct lockf *i_lockf; /* head of byte-level lock list */
doff_t i_endoff; /* end of useful stuff in directory */
doff_t i_diroff; /* offset in dir, where we found last entry */
- doff_t i_offset; /* offset of free space in directory */
- ino_t i_ino; /* inode number of found directory */
long iso_extent; /* extent of file */
unsigned long i_size;
diff --git a/sys/fs/cd9660/cd9660_rrip.c b/sys/fs/cd9660/cd9660_rrip.c
index 739972b..9a32e9b 100644
--- a/sys/fs/cd9660/cd9660_rrip.c
+++ b/sys/fs/cd9660/cd9660_rrip.c
@@ -416,9 +416,9 @@ cd9660_rrip_device(p,ana)
low = isonum_733(p->dev_t_low);
if (high == 0)
- ana->inop->inode.iso_rdev = makedev(umajor(low), uminor(low));
+ ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
else
- ana->inop->inode.iso_rdev = makedev(high, uminor(low));
+ ana->inop->inode.iso_rdev = makedev(high, minor(low));
ana->fields &= ~ISO_SUSP_DEVICE;
return ISO_SUSP_DEVICE;
}
diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index 6654d01..b8ec72a 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/cd9660/cd9660_vfsops.c
@@ -264,7 +264,7 @@ iso_mountfs(devvp, mp)
vdp = (struct iso_volume_descriptor *)bp->b_data;
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
if (bcmp (vdp->id_sierra, ISO_SIERRA_ID,
- sizeof vdp->id) != 0) {
+ sizeof vdp->id_sierra) != 0) {
error = EINVAL;
goto out;
} else
@@ -375,6 +375,7 @@ iso_mountfs(devvp, mp)
mp->mnt_maxsymlinklen = 0;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
+ mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED;
MNT_IUNLOCK(mp);
isomp->im_mountp = mp;
isomp->im_dev = dev;
@@ -545,7 +546,7 @@ cd9660_root(mp, flags, vpp, td)
* With RRIP we must use the `.' entry of the root directory.
* Simply tell vget, that it's a relocated directory.
*/
- return (cd9660_vget_internal(mp, ino, LK_EXCLUSIVE, vpp,
+ return (cd9660_vget_internal(mp, ino, flags, vpp,
imp->iso_ftype == ISO_FTYPE_RRIP, dp));
}
@@ -659,6 +660,22 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
if (error || *vpp != NULL)
return (error);
+ /*
+ * We must promote to an exclusive lock for vnode creation. This
+ * can happen if lookup is passed LOCKSHARED.
+ */
+ if ((flags & LK_TYPE_MASK) == LK_SHARED) {
+ flags &= ~LK_TYPE_MASK;
+ flags |= LK_EXCLUSIVE;
+ }
+
+ /*
+ * We do not lock vnode creation as it is believed to be too
+ * expensive for such rare case as simultaneous creation of vnode
+ * for same ino by different processes. We just allow them to race
+ * and check later to decide who wins. Let the race begin!
+ */
+
imp = VFSTOISOFS(mp);
dev = imp->im_dev;
@@ -739,7 +756,6 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
bp = 0;
ip->i_mnt = imp;
- VREF(imp->im_devvp);
if (relocated) {
/*
@@ -797,6 +813,7 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
vp->v_op = &cd9660_fifoops;
break;
default:
+ VN_LOCK_ASHARE(vp);
break;
}
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c
index e9d6680..4d67251 100644
--- a/sys/fs/cd9660/cd9660_vnops.c
+++ b/sys/fs/cd9660/cd9660_vnops.c
@@ -168,10 +168,14 @@ cd9660_open(ap)
int a_fdidx;
} */ *ap;
{
- struct iso_node *ip = VTOI(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct iso_node *ip = VTOI(vp);
- vnode_create_vobject(ap->a_vp, ip->i_size, ap->a_td);
- return 0;
+ if (vp->v_type == VCHR || vp->v_type == VBLK)
+ return (EOPNOTSUPP);
+
+ vnode_create_vobject(vp, ip->i_size, ap->a_td);
+ return (0);
}
diff --git a/sys/fs/coda/coda_vfsops.c b/sys/fs/coda/coda_vfsops.c
index de6e855..5ce6499 100644
--- a/sys/fs/coda/coda_vfsops.c
+++ b/sys/fs/coda/coda_vfsops.c
@@ -266,7 +266,6 @@ coda_root(struct mount *vfsp, int flags, struct vnode **vpp,
struct thread *td)
{
struct coda_mntinfo *mi = vftomi(vfsp);
- struct vnode **result;
int error;
struct proc *p = td->td_proc;
CodaFid VFid;
@@ -274,7 +273,6 @@ coda_root(struct mount *vfsp, int flags, struct vnode **vpp,
ENTRY;
MARK_ENTRY(CODA_ROOT_STATS);
- result = NULL;
if (vfsp == mi->mi_vfsp) {
/*
* Cache the root across calls. We only need to pass the
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c
index 028f5c9..4041911 100644
--- a/sys/fs/devfs/devfs_devs.c
+++ b/sys/fs/devfs/devfs_devs.c
@@ -103,8 +103,9 @@ sysctl_devname(SYSCTL_HANDLER_ARGS)
return (error);
}
-SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY,
- NULL, 0, sysctl_devname, "", "devname(3) handler");
+SYSCTL_PROC(_kern, OID_AUTO, devname,
+ CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY|CTLFLAG_MPSAFE,
+ NULL, 0, sysctl_devname, "", "devname(3) handler");
SYSCTL_INT(_debug_sizeof, OID_AUTO, cdev, CTLFLAG_RD,
0, sizeof(struct cdev), "sizeof(struct cdev)");
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index e0672da..e164dc2 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -540,12 +540,28 @@ devfs_close_f(struct file *fp, struct thread *td)
return (error);
}
-/* ARGSUSED */
static int
devfs_fsync(struct vop_fsync_args *ap)
{
- if (!vn_isdisk(ap->a_vp, NULL))
+ int error;
+ struct bufobj *bo;
+ struct devfs_dirent *de;
+
+ if (!vn_isdisk(ap->a_vp, &error)) {
+ bo = &ap->a_vp->v_bufobj;
+ de = ap->a_vp->v_data;
+ if (error == ENXIO && bo->bo_dirty.bv_cnt > 0) {
+ printf("Device %s went missing before all of the data "
+ "could be written to it; expect data loss.\n",
+ de->de_dirent->d_name);
+
+ error = vop_stdfsync(ap);
+ if (bo->bo_dirty.bv_cnt != 0 || error != 0)
+ panic("devfs_fsync: vop_stdfsync failed.");
+ }
+
return (0);
+ }
return (vop_stdfsync(ap));
}
@@ -1058,7 +1074,7 @@ devfs_readdir(struct vop_readdir_args *ap)
struct devfs_dirent *dd;
struct devfs_dirent *de;
struct devfs_mount *dmp;
- off_t off, oldoff;
+ off_t off;
int *tmp_ncookies = NULL;
if (ap->a_vp->v_type != VDIR)
@@ -1097,7 +1113,6 @@ devfs_readdir(struct vop_readdir_args *ap)
error = 0;
de = ap->a_vp->v_data;
off = 0;
- oldoff = uio->uio_offset;
TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
if (dd->de_flags & DE_WHITEOUT)
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index a875c05..c8bc5ab4 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -149,7 +149,7 @@ fifo_cleanup(struct vnode *vp)
{
struct fifoinfo *fip = vp->v_fifoinfo;
- ASSERT_VOP_LOCKED(vp, "fifo_cleanup");
+ ASSERT_VOP_ELOCKED(vp, "fifo_cleanup");
if (fip->fi_readers == 0 && fip->fi_writers == 0) {
vp->v_fifoinfo = NULL;
(void)soclose(fip->fi_readsock);
@@ -422,8 +422,11 @@ fifo_close(ap)
struct vnode *vp = ap->a_vp;
struct fifoinfo *fip = vp->v_fifoinfo;
- ASSERT_VOP_LOCKED(vp, "fifo_close");
- KASSERT(fip != NULL, ("fifo_close: no v_fifoinfo"));
+ ASSERT_VOP_ELOCKED(vp, "fifo_close");
+ if (fip == NULL) {
+ printf("fifo_close: no v_fifoinfo %p\n", vp);
+ return (0);
+ }
if (ap->a_fflag & FREAD) {
fip->fi_readers--;
if (fip->fi_readers == 0)
@@ -465,6 +468,7 @@ fifo_print(ap)
struct vnode *a_vp;
} */ *ap;
{
+ printf(" ");
fifo_printinfo(ap->a_vp);
printf("\n");
return (0);
diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c
index 36d3dd5..a20614b 100644
--- a/sys/fs/hpfs/hpfs_vfsops.c
+++ b/sys/fs/hpfs/hpfs_vfsops.c
@@ -109,7 +109,6 @@ hpfs_mount (
{
int err = 0, error;
struct vnode *devvp;
- struct hpfsmount *hpmp = 0;
struct nameidata ndp;
struct export_args export;
char *from;
@@ -134,8 +133,6 @@ hpfs_mount (
if (mp->mnt_flag & MNT_UPDATE) {
dprintf(("hpfs_omount: MNT_UPDATE: "));
- hpmp = VFSTOHPFS(mp);
-
if (from == NULL) {
error = vfs_copyopt(mp->mnt_optnew, "export",
&export, sizeof export);
@@ -337,13 +334,11 @@ hpfs_unmount(
int mntflags,
struct thread *td)
{
- int error, flags, ronly;
+ int error, flags;
register struct hpfsmount *hpmp = VFSTOHPFS(mp);
dprintf(("hpfs_unmount():\n"));
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
-
flags = 0;
if(mntflags & MNT_FORCE)
flags |= FORCECLOSE;
diff --git a/sys/fs/msdosfs/msdosfs_conv.c b/sys/fs/msdosfs/msdosfs_conv.c
index 25efcc5..50dc1a0 100644
--- a/sys/fs/msdosfs/msdosfs_conv.c
+++ b/sys/fs/msdosfs/msdosfs_conv.c
@@ -1060,8 +1060,11 @@ mbnambuf_write(struct mbnambuf *nbp, char *name, int id)
char *slot;
size_t count, newlen;
- KASSERT(nbp->nb_len == 0 || id == nbp->nb_last_id - 1,
- ("non-decreasing id: id %d, last id %d", id, nbp->nb_last_id));
+ if (nbp->nb_len != 0 && id != nbp->nb_last_id - 1) {
+ printf("msdosfs: non-decreasing id: id %d, last id %d\n",
+ id, nbp->nb_last_id);
+ return;
+ }
/* Will store this substring in a WIN_CHARS-aligned slot. */
slot = &nbp->nb_buf[id * WIN_CHARS];
diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
index d461484..e1e0053 100644
--- a/sys/fs/msdosfs/msdosfs_denode.c
+++ b/sys/fs/msdosfs/msdosfs_denode.c
@@ -168,6 +168,7 @@ deget(pmp, dirclust, diroffset, depp)
ldep->de_dirclust = dirclust;
ldep->de_diroffset = diroffset;
ldep->de_inode = inode;
+ ldep->de_dev = pmp->pm_devvp->v_rdev;
fc_purge(ldep, 0); /* init the fat cache for this denode */
lockmgr(nvp->v_vnlock, LK_EXCLUSIVE, NULL);
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index b51d8cd..5a6823f 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -658,7 +658,6 @@ null_reclaim(struct vop_reclaim_args *ap)
struct vnode *vp = ap->a_vp;
struct null_node *xp = VTONULL(vp);
struct vnode *lowervp = xp->null_lowervp;
- struct lock *vnlock;
if (lowervp)
null_hashrem(xp);
@@ -669,7 +668,6 @@ null_reclaim(struct vop_reclaim_args *ap)
VI_LOCK(vp);
vp->v_data = NULL;
vp->v_object = NULL;
- vnlock = vp->v_vnlock;
vp->v_vnlock = &vp->v_lock;
if (lowervp) {
lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_INTERLOCK, VI_MTX(vp));
diff --git a/sys/fs/nwfs/nwfs_subr.c b/sys/fs/nwfs/nwfs_subr.c
index 4d55972..732651f 100644
--- a/sys/fs/nwfs/nwfs_subr.c
+++ b/sys/fs/nwfs/nwfs_subr.c
@@ -179,7 +179,6 @@ ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
{
struct nwmount *nmp;
struct nwnode *dnp;
- struct ncp_conn *conn;
int error;
if (!dvp || dvp->v_type != VDIR) {
@@ -188,7 +187,6 @@ ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
}
dnp = VTONW(dvp);
nmp = VTONWFS(dvp);
- conn = NWFSTOCONN(nmp);
if (len == 1 && name[0] == '.') {
if (dnp->n_flag & NVOLUME) {
diff --git a/sys/fs/nwfs/nwfs_vnops.c b/sys/fs/nwfs/nwfs_vnops.c
index ca0a887..7ed5d85 100644
--- a/sys/fs/nwfs/nwfs_vnops.c
+++ b/sys/fs/nwfs/nwfs_vnops.c
@@ -627,7 +627,6 @@ nwfs_mkdir(ap)
struct componentname *cnp = ap->a_cnp;
int len=cnp->cn_namelen;
struct ncp_open_info no;
- struct nwnode *np;
struct vnode *newvp = (struct vnode *)0;
ncpfid fid;
int error = 0;
@@ -651,7 +650,6 @@ nwfs_mkdir(ap)
fid.f_id = no.fattr.dirEntNum;
error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &newvp);
if (!error) {
- np = VTONW(newvp);
newvp->v_type = VDIR;
*ap->a_vpp = newvp;
}
@@ -786,7 +784,6 @@ static int nwfs_strategy (ap)
struct buf *bp=ap->a_bp;
struct ucred *cr;
struct thread *td;
- int error = 0;
NCPVNDEBUG("\n");
if (bp->b_flags & B_ASYNC)
@@ -803,7 +800,7 @@ static int nwfs_strategy (ap)
* otherwise just do it ourselves.
*/
if ((bp->b_flags & B_ASYNC) == 0 )
- error = nwfs_doio(ap->a_vp, bp, cr, td);
+ (void)nwfs_doio(ap->a_vp, bp, cr, td);
return (0);
}
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index 0d41345..ed04d38 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -46,6 +46,9 @@
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
+#ifdef COMPAT_IA32
+#include <sys/sysent.h>
+#endif
#include <sys/uio.h>
#include <sys/vnode.h>
@@ -59,15 +62,6 @@
#include <vm/vm_page.h>
#include <vm/vm_object.h>
-#ifdef COMPAT_IA32
-#include <sys/procfs.h>
-#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
-
-extern struct sysentvec ia32_freebsd_sysvec;
-#endif
-
-
#define MEBUFFERSIZE 256
/*
@@ -104,8 +98,8 @@ procfs_doprocmap(PFS_FILL_ARGS)
return (EOPNOTSUPP);
#ifdef COMPAT_IA32
- if (curthread->td_proc->p_sysent == &ia32_freebsd_sysvec) {
- if (p->p_sysent != &ia32_freebsd_sysvec)
+ if (curproc->p_sysent->sv_flags & SV_ILP32) {
+ if (!(p->p_sysent->sv_flags & SV_ILP32))
return (EOPNOTSUPP);
wrap32 = 1;
}
@@ -230,7 +224,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
error = 0;
break;
}
- if (last_timestamp + 1 != map->timestamp) {
+ if (last_timestamp != map->timestamp) {
/*
* Look again for the entry because the map was
* modified while it was unlocked. Specifically,
diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c
index eac35eb..551ae6a 100644
--- a/sys/fs/pseudofs/pseudofs_vncache.c
+++ b/sys/fs/pseudofs/pseudofs_vncache.c
@@ -111,7 +111,7 @@ int
pfs_vncache_alloc(struct mount *mp, struct vnode **vpp,
struct pfs_node *pn, pid_t pid)
{
- struct pfs_vdata *pvd;
+ struct pfs_vdata *pvd, *pvd2;
struct vnode *vp;
int error;
@@ -146,19 +146,12 @@ retry:
}
}
mtx_unlock(&pfs_vncache_mutex);
- ++pfs_vncache_misses;
/* nope, get a new one */
pvd = malloc(sizeof *pvd, M_PFSVNCACHE, M_WAITOK);
- mtx_lock(&pfs_vncache_mutex);
- if (++pfs_vncache_entries > pfs_vncache_maxentries)
- pfs_vncache_maxentries = pfs_vncache_entries;
- mtx_unlock(&pfs_vncache_mutex);
+ pvd->pvd_next = pvd->pvd_prev = NULL;
error = getnewvnode("pseudofs", mp, &pfs_vnodeops, vpp);
if (error) {
- mtx_lock(&pfs_vncache_mutex);
- --pfs_vncache_entries;
- mtx_unlock(&pfs_vncache_mutex);
free(pvd, M_PFSVNCACHE);
return (error);
}
@@ -200,14 +193,36 @@ retry:
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
error = insmntque(*vpp, mp);
if (error != 0) {
- mtx_lock(&pfs_vncache_mutex);
- --pfs_vncache_entries;
- mtx_unlock(&pfs_vncache_mutex);
- free(pvd, M_PFSVNCACHE);
*vpp = NULLVP;
return (error);
}
+retry2:
mtx_lock(&pfs_vncache_mutex);
+ /*
+ * Other thread may race with us, creating the entry we are
+ * going to insert into the cache. Recheck after
+ * pfs_vncache_mutex is reacquired.
+ */
+ for (pvd2 = pfs_vncache; pvd2; pvd2 = pvd2->pvd_next) {
+ if (pvd2->pvd_pn == pn && pvd2->pvd_pid == pid &&
+ pvd2->pvd_vnode->v_mount == mp) {
+ vp = pvd2->pvd_vnode;
+ VI_LOCK(vp);
+ mtx_unlock(&pfs_vncache_mutex);
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread) == 0) {
+ ++pfs_vncache_hits;
+ vgone(*vpp);
+ vput(*vpp);
+ *vpp = vp;
+ cache_purge(vp);
+ return (0);
+ }
+ goto retry2;
+ }
+ }
+ ++pfs_vncache_misses;
+ if (++pfs_vncache_entries > pfs_vncache_maxentries)
+ pfs_vncache_maxentries = pfs_vncache_entries;
pvd->pvd_prev = NULL;
pvd->pvd_next = pfs_vncache;
if (pvd->pvd_next)
@@ -232,7 +247,7 @@ pfs_vncache_free(struct vnode *vp)
pvd->pvd_next->pvd_prev = pvd->pvd_prev;
if (pvd->pvd_prev)
pvd->pvd_prev->pvd_next = pvd->pvd_next;
- else
+ else if (pfs_vncache == pvd)
pfs_vncache = pvd->pvd_next;
--pfs_vncache_entries;
mtx_unlock(&pfs_vncache_mutex);
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index ef91bfd..c5c14b1 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -310,6 +310,84 @@ pfs_getextattr(struct vop_getextattr_args *va)
}
/*
+ * Convert a vnode to its component name
+ */
+static int
+pfs_vptocnp(struct vop_vptocnp_args *ap)
+{
+ struct vnode *vp = ap->a_vp;
+ struct vnode **dvp = ap->a_vpp;
+ struct pfs_vdata *pvd = vp->v_data;
+ struct pfs_node *pd = pvd->pvd_pn;
+ struct pfs_node *pn;
+ struct mount *mp;
+ char *buf = ap->a_buf;
+ int *buflen = ap->a_buflen;
+ char pidbuf[PFS_NAMELEN];
+ pid_t pid = pvd->pvd_pid;
+ int len, i, error, locked;
+
+ i = *buflen;
+ error = 0;
+
+ pfs_lock(pd);
+
+ if (vp->v_type == VDIR && pd->pn_type == pfstype_root) {
+ *dvp = vp;
+ vhold(*dvp);
+ pfs_unlock(pd);
+ PFS_RETURN (0);
+ } else if (vp->v_type == VDIR && pd->pn_type == pfstype_procdir) {
+ len = snprintf(pidbuf, sizeof(pidbuf), "%d", pid);
+ i -= len;
+ if (i < 0) {
+ error = ENOMEM;
+ goto failed;
+ }
+ bcopy(pidbuf, buf + i, len);
+ } else {
+ i -= strlen(pd->pn_name);
+ if (i < 0) {
+ error = ENOMEM;
+ goto failed;
+ }
+ bcopy(pd->pn_name, buf + i, strlen(pd->pn_name));
+ }
+
+ pn = pd->pn_parent;
+ pfs_unlock(pd);
+
+ mp = vp->v_mount;
+ error = vfs_busy(mp, 0);
+ if (error)
+ return (error);
+
+ /*
+ * vp is held by caller.
+ */
+ locked = VOP_ISLOCKED(vp);
+ VOP_UNLOCK(vp, 0);
+
+ error = pfs_vncache_alloc(mp, dvp, pn, pid);
+ if (error) {
+ vn_lock(vp, locked | LK_RETRY);
+ vfs_unbusy(mp);
+ PFS_RETURN(error);
+ }
+
+ *buflen = i;
+ vhold(*dvp);
+ vput(*dvp);
+ vn_lock(vp, locked | LK_RETRY);
+ vfs_unbusy(mp);
+
+ PFS_RETURN (0);
+failed:
+ pfs_unlock(pd);
+ PFS_RETURN(error);
+}
+
+/*
* Look up a file or directory
*/
static int
@@ -476,7 +554,7 @@ pfs_read(struct vop_read_args *va)
struct uio *uio = va->a_uio;
struct proc *proc;
struct sbuf *sb = NULL;
- int error;
+ int error, locked;
unsigned int buflen, offset, resid;
PFS_TRACE(("%s", pn->pn_name));
@@ -502,13 +580,15 @@ pfs_read(struct vop_read_args *va)
PROC_UNLOCK(proc);
}
+ vhold(vn);
+ locked = VOP_ISLOCKED(vn);
+ VOP_UNLOCK(vn, 0);
+
if (pn->pn_flags & PFS_RAWRD) {
PFS_TRACE(("%lu resid", (unsigned long)uio->uio_resid));
error = pn_fill(curthread, proc, pn, NULL, uio);
PFS_TRACE(("%lu resid", (unsigned long)uio->uio_resid));
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (error);
+ goto ret;
}
/* beaucoup sanity checks so we don't ask for bogus allocation */
@@ -518,34 +598,35 @@ pfs_read(struct vop_read_args *va)
(buflen = offset + resid + 1) < offset || buflen > INT_MAX) {
if (proc != NULL)
PRELE(proc);
- PFS_RETURN (EINVAL);
+ error = EINVAL;
+ goto ret;
}
if (buflen > MAXPHYS + 1) {
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (EIO);
+ error = EIO;
+ goto ret;
}
sb = sbuf_new(sb, NULL, buflen, 0);
if (sb == NULL) {
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (EIO);
+ error = EIO;
+ goto ret;
}
error = pn_fill(curthread, proc, pn, sb, uio);
- if (proc != NULL)
- PRELE(proc);
-
if (error) {
sbuf_delete(sb);
- PFS_RETURN (error);
+ goto ret;
}
sbuf_finish(sb);
error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
sbuf_delete(sb);
+ret:
+ vn_lock(vn, locked | LK_RETRY);
+ vdrop(vn);
+ if (proc != NULL)
+ PRELE(proc);
PFS_RETURN (error);
}
@@ -887,6 +968,7 @@ struct vop_vector pfs_vnodeops = {
.vop_rmdir = VOP_EOPNOTSUPP,
.vop_setattr = pfs_setattr,
.vop_symlink = VOP_EOPNOTSUPP,
+ .vop_vptocnp = pfs_vptocnp,
.vop_write = pfs_write,
/* XXX I've probably forgotten a few that need VOP_EOPNOTSUPP */
};
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index 9b1e76d..0fd0233 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -850,7 +850,6 @@ smbfs_strategy (ap)
struct buf *bp=ap->a_bp;
struct ucred *cr;
struct thread *td;
- int error = 0;
SMBVDEBUG("\n");
if (bp->b_flags & B_ASYNC)
@@ -863,7 +862,7 @@ smbfs_strategy (ap)
cr = bp->b_wcred;
if ((bp->b_flags & B_ASYNC) == 0 )
- error = smbfs_doio(ap->a_vp, bp, cr, td);
+ (void)smbfs_doio(ap->a_vp, bp, cr, td);
return (0);
}
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index fad3196..c0c6b50 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -1259,12 +1259,10 @@ tmpfs_update(struct vnode *vp)
int
tmpfs_truncate(struct vnode *vp, off_t length)
{
- boolean_t extended;
int error;
struct tmpfs_node *node;
node = VP_TO_TMPFS_NODE(vp);
- extended = length > node->tn_size;
if (length < 0) {
error = EINVAL;
diff --git a/sys/fs/udf/ecma167-udf.h b/sys/fs/udf/ecma167-udf.h
index 2d78758..30f8c8e 100644
--- a/sys/fs/udf/ecma167-udf.h
+++ b/sys/fs/udf/ecma167-udf.h
@@ -354,6 +354,18 @@ struct file_entry {
#define UDF_FENTRY_PERM_GRP_MASK 0xE0
#define UDF_FENTRY_PERM_OWNER_MASK 0x1C00
+/* Path Component [4/14.16.1] */
+struct path_component {
+ uint8_t type;
+ uint8_t length;
+ uint16_t version;
+ uint8_t identifier[0];
+} __packed;
+#define UDF_PATH_ROOT 2
+#define UDF_PATH_DOTDOT 3
+#define UDF_PATH_DOT 4
+#define UDF_PATH_PATH 5
+
union dscrptr {
struct desc_tag tag;
struct anchor_vdp avdp;
diff --git a/sys/fs/udf/udf.h b/sys/fs/udf/udf.h
index 05eb2e4..fe16bf5 100644
--- a/sys/fs/udf/udf.h
+++ b/sys/fs/udf/udf.h
@@ -137,3 +137,5 @@ int udf_vget(struct mount *, ino_t, int, struct vnode **);
extern uma_zone_t udf_zone_trans;
extern uma_zone_t udf_zone_node;
extern uma_zone_t udf_zone_ds;
+
+extern struct vop_vector udf_fifoops;
diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c
index 5120187..faab9df 100644
--- a/sys/fs/udf/udf_vfsops.c
+++ b/sys/fs/udf/udf_vfsops.c
@@ -680,6 +680,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
break;
case 9:
vp->v_type = VFIFO;
+ vp->v_op = &udf_fifoops;
break;
case 10:
vp->v_type = VSOCK;
diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c
index 77b11fe..a80c3ce 100644
--- a/sys/fs/udf/udf_vnops.c
+++ b/sys/fs/udf/udf_vnops.c
@@ -48,6 +48,7 @@
#include <vm/uma.h>
+#include <fs/fifofs/fifo.h>
#include <fs/udf/ecma167-udf.h>
#include <fs/udf/osta.h>
#include <fs/udf/udf.h>
@@ -60,9 +61,11 @@ static vop_getattr_t udf_getattr;
static vop_open_t udf_open;
static vop_ioctl_t udf_ioctl;
static vop_pathconf_t udf_pathconf;
+static vop_print_t udf_print;
static vop_read_t udf_read;
static vop_readdir_t udf_readdir;
static vop_readlink_t udf_readlink;
+static vop_setattr_t udf_setattr;
static vop_strategy_t udf_strategy;
static vop_bmap_t udf_bmap;
static vop_cachedlookup_t udf_lookup;
@@ -84,14 +87,26 @@ static struct vop_vector udf_vnodeops = {
.vop_lookup = vfs_cache_lookup,
.vop_open = udf_open,
.vop_pathconf = udf_pathconf,
+ .vop_print = udf_print,
.vop_read = udf_read,
.vop_readdir = udf_readdir,
.vop_readlink = udf_readlink,
.vop_reclaim = udf_reclaim,
+ .vop_setattr = udf_setattr,
.vop_strategy = udf_strategy,
.vop_vptofh = udf_vptofh,
};
+struct vop_vector udf_fifoops = {
+ .vop_default = &fifo_specops,
+ .vop_access = udf_access,
+ .vop_getattr = udf_getattr,
+ .vop_print = udf_print,
+ .vop_reclaim = udf_reclaim,
+ .vop_setattr = udf_setattr,
+ .vop_vptofh = udf_vptofh,
+};
+
MALLOC_DEFINE(M_UDFFID, "udf_fid", "UDF FileId structure");
MALLOC_DEFINE(M_UDFDS, "udf_ds", "UDF Dirstream structure");
@@ -318,6 +333,38 @@ udf_getattr(struct vop_getattr_args *a)
return (0);
}
+static int
+udf_setattr(struct vop_setattr_args *a)
+{
+ struct vnode *vp;
+ struct vattr *vap;
+
+ vp = a->a_vp;
+ vap = a->a_vap;
+ if (vap->va_flags != (u_long)VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
+ vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
+ vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL)
+ return (EROFS);
+ if (vap->va_size != (u_quad_t)VNOVAL) {
+ switch (vp->v_type) {
+ case VDIR:
+ return (EISDIR);
+ case VLNK:
+ case VREG:
+ return (EROFS);
+ case VCHR:
+ case VBLK:
+ case VSOCK:
+ case VFIFO:
+ case VNON:
+ case VBAD:
+ case VMARKER:
+ return (0);
+ }
+ }
+ return (0);
+}
+
/*
* File specific ioctls.
*/
@@ -354,6 +401,20 @@ udf_pathconf(struct vop_pathconf_args *a)
}
}
+static int
+udf_print(struct vop_print_args *ap)
+{
+ struct vnode *vp = ap->a_vp;
+ struct udf_node *node = VTON(vp);
+
+ printf(" ino %lu, on dev %s", (u_long)node->hash_id,
+ devtoname(node->udfmp->im_dev));
+ if (vp->v_type == VFIFO)
+ fifo_printinfo(vp);
+ printf("\n");
+ return (0);
+}
+
#define lblkno(udfmp, loc) ((loc) >> (udfmp)->bshift)
#define blkoff(udfmp, loc) ((loc) & (udfmp)->bmask)
#define lblktosize(imp, blk) ((blk) << (udfmp)->bshift)
@@ -798,12 +859,121 @@ udf_readdir(struct vop_readdir_args *a)
return (error);
}
-/* Are there any implementations out there that do soft-links? */
static int
udf_readlink(struct vop_readlink_args *ap)
{
- printf("%s called\n", __func__);
- return (EOPNOTSUPP);
+ struct path_component *pc, *end;
+ struct vnode *vp;
+ struct uio uio;
+ struct iovec iov[1];
+ struct udf_node *node;
+ void *buf;
+ char *cp;
+ int error, len, root;
+
+ /*
+ * A symbolic link in UDF is a list of variable-length path
+ * component structures. We build a pathname in the caller's
+ * uio by traversing this list.
+ */
+ vp = ap->a_vp;
+ node = VTON(vp);
+ len = le64toh(node->fentry->inf_len);
+ buf = malloc(iov[0].iov_len, M_DEVBUF, M_WAITOK);
+ iov[0].iov_base = buf;
+ iov[0].iov_len = len;
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = 0;
+ uio.uio_resid = iov[0].iov_len;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_READ;
+ uio.uio_td = curthread;
+ error = VOP_READ(vp, &uio, 0, ap->a_cred);
+ if (error)
+ goto error;
+
+ pc = buf;
+ end = (void *)((char *)buf + len);
+ root = 0;
+ while (pc < end) {
+ switch (pc->type) {
+ case UDF_PATH_ROOT:
+ /* Only allow this at the beginning of a path. */
+ if ((void *)pc != buf) {
+ error = EINVAL;
+ goto error;
+ }
+ cp = "/";
+ len = 1;
+ root = 1;
+ break;
+ case UDF_PATH_DOT:
+ cp = ".";
+ len = 1;
+ break;
+ case UDF_PATH_DOTDOT:
+ cp = "..";
+ len = 2;
+ break;
+ case UDF_PATH_PATH:
+ if (pc->length == 0) {
+ error = EINVAL;
+ goto error;
+ }
+ /*
+ * XXX: We only support CS8 which appears to map
+ * to ASCII directly.
+ */
+ switch (pc->identifier[0]) {
+ case 8:
+ cp = pc->identifier + 1;
+ len = pc->length - 1;
+ break;
+ default:
+ error = EOPNOTSUPP;
+ goto error;
+ }
+ break;
+ default:
+ error = EINVAL;
+ goto error;
+ }
+
+ /*
+ * If this is not the first component, insert a path
+ * separator.
+ */
+ if (pc != buf) {
+ /* If we started with root we already have a "/". */
+ if (root)
+ goto skipslash;
+ root = 0;
+ if (ap->a_uio->uio_resid < 1) {
+ error = ENAMETOOLONG;
+ goto error;
+ }
+ error = uiomove("/", 1, ap->a_uio);
+ if (error)
+ break;
+ }
+ skipslash:
+
+ /* Append string at 'cp' of length 'len' to our path. */
+ if (len > ap->a_uio->uio_resid) {
+ error = ENAMETOOLONG;
+ goto error;
+ }
+ error = uiomove(cp, len, ap->a_uio);
+ if (error)
+ break;
+
+ /* Advance to next component. */
+ pc = (void *)((char *)pc + 4 + pc->length);
+ }
+error:
+ free(buf, M_DEVBUF);
+ return (error);
}
static int
@@ -892,7 +1062,6 @@ udf_lookup(struct vop_cachedlookup_args *a)
struct udf_mnt *udfmp;
struct fileid_desc *fid = NULL;
struct udf_dirstream *ds;
- struct thread *td;
u_long nameiop;
u_long flags;
char *nameptr;
@@ -909,7 +1078,6 @@ udf_lookup(struct vop_cachedlookup_args *a)
nameptr = a->a_cnp->cn_nameptr;
namelen = a->a_cnp->cn_namelen;
fsize = le64toh(node->fentry->inf_len);
- td = a->a_cnp->cn_thread;
/*
* If this is a LOOKUP and we've already partially searched through
diff --git a/sys/geom/geom.h b/sys/geom/geom.h
index 8bf9439..a916ec5 100644
--- a/sys/geom/geom.h
+++ b/sys/geom/geom.h
@@ -227,10 +227,11 @@ void g_error_provider(struct g_provider *pp, int error);
struct g_provider *g_provider_by_name(char const *arg);
int g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len);
#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof *(v))
-int g_handleattr(struct bio *bp, const char *attribute, void *val, int len);
+int g_handleattr(struct bio *bp, const char *attribute, const void *val,
+ int len);
int g_handleattr_int(struct bio *bp, const char *attribute, int val);
int g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val);
-int g_handleattr_str(struct bio *bp, const char *attribute, char *str);
+int g_handleattr_str(struct bio *bp, const char *attribute, const char *str);
struct g_consumer * g_new_consumer(struct g_geom *gp);
struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...);
struct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...);
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 8bf6981..b40dea0 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -72,25 +72,14 @@ static struct cdevsw g_dev_cdevsw = {
static g_taste_t g_dev_taste;
static g_orphan_t g_dev_orphan;
-static g_init_t g_dev_init;
static struct g_class g_dev_class = {
.name = "DEV",
.version = G_VERSION,
.taste = g_dev_taste,
.orphan = g_dev_orphan,
- .init = g_dev_init,
};
-static struct unrhdr *unithdr; /* Locked by topology */
-
-static void
-g_dev_init(struct g_class *mp)
-{
-
- unithdr = new_unrhdr(0, INT_MAX, NULL);
-}
-
void
g_dev_print(void)
{
@@ -126,7 +115,6 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
struct g_consumer *cp;
int error;
struct cdev *dev;
- u_int unit;
g_trace(G_T_TOPOLOGY, "dev_taste(%s,%s)", mp->name, pp->name);
g_topology_assert();
@@ -138,8 +126,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
error = g_attach(cp, pp);
KASSERT(error == 0,
("g_dev_taste(%s) failed to g_attach, err=%d", pp->name, error));
- unit = alloc_unr(unithdr);
- dev = make_dev(&g_dev_cdevsw, unit,
+ dev = make_dev(&g_dev_cdevsw, 0,
UID_ROOT, GID_OPERATOR, 0640, gp->name);
if (pp->flags & G_PF_CANDELETE)
dev->si_flags |= SI_CANDELETE;
@@ -432,7 +419,6 @@ g_dev_orphan(struct g_consumer *cp)
{
struct g_geom *gp;
struct cdev *dev;
- u_int unit;
g_topology_assert();
gp = cp->geom;
@@ -444,9 +430,7 @@ g_dev_orphan(struct g_consumer *cp)
set_dumper(NULL);
/* Destroy the struct cdev *so we get no more requests */
- unit = dev2unit(dev);
destroy_dev(dev);
- free_unr(unithdr, unit);
/* Wait for the cows to come home */
while (cp->nstart != cp->nend)
diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
index 21509aa6a..b67c0d5 100644
--- a/sys/geom/geom_subr.c
+++ b/sys/geom/geom_subr.c
@@ -858,14 +858,14 @@ g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val)
}
int
-g_handleattr_str(struct bio *bp, const char *attribute, char *str)
+g_handleattr_str(struct bio *bp, const char *attribute, const char *str)
{
return (g_handleattr(bp, attribute, str, 0));
}
int
-g_handleattr(struct bio *bp, const char *attribute, void *val, int len)
+g_handleattr(struct bio *bp, const char *attribute, const void *val, int len)
{
int error = 0;
@@ -882,12 +882,13 @@ g_handleattr(struct bio *bp, const char *attribute, void *val, int len)
}
} else if (bp->bio_length == len) {
bcopy(val, bp->bio_data, len);
- bp->bio_completed = len;
} else {
printf("%s: %s bio_length %jd len %d -> EFAULT\n", __func__,
bp->bio_to->name, (intmax_t)bp->bio_length, len);
error = EFAULT;
}
+ if (error == 0)
+ bp->bio_completed = bp->bio_length;
g_io_deliver(bp, error);
return (1);
}
diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c
index 86c909d..1fce07a 100644
--- a/sys/geom/geom_vfs.c
+++ b/sys/geom/geom_vfs.c
@@ -71,6 +71,16 @@ g_vfs_done(struct bio *bip)
struct buf *bp;
int vfslocked;
+ /*
+ * Provider ('bio_to') could have withered away sometime
+ * between incrementing the 'nend' in g_io_deliver() and now,
+ * making 'bio_to' a dangling pointer. We cannot do that
+ * in g_wither_geom(), as it would require going over
+ * the 'g_bio_run_up' list, resetting the pointer.
+ */
+ if (bip->bio_from->provider == NULL)
+ bip->bio_to = NULL;
+
if (bip->bio_error) {
printf("g_vfs_done():");
g_print_bio(bip);
@@ -136,7 +146,7 @@ g_vfs_orphan(struct g_consumer *cp)
g_detach(cp);
/*
- * Do not destroy the geom. Filesystem will do this during unmount.
+ * Do not destroy the geom. Filesystem will do that during unmount.
*/
}
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index ad84956..0ad3c61 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -182,10 +182,8 @@ g_part_geometry(struct g_part_table *table, struct g_consumer *cp,
u_int heads, sectors;
int idx;
- if (g_getattr("GEOM::fwsectors", cp, &sectors) != 0 ||
- sectors < 1 || sectors > 63 ||
- g_getattr("GEOM::fwheads", cp, &heads) != 0 ||
- heads < 1 || heads > 255) {
+ if (g_getattr("GEOM::fwsectors", cp, &sectors) != 0 || sectors == 0 ||
+ g_getattr("GEOM::fwheads", cp, &heads) != 0 || heads == 0) {
table->gpt_fixgeom = 0;
table->gpt_heads = 0;
table->gpt_sectors = 0;
diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c
index f0f1474..c7d9d97 100644
--- a/sys/geom/part/g_part_pc98.c
+++ b/sys/geom/part/g_part_pc98.c
@@ -333,7 +333,7 @@ g_part_pc98_probe(struct g_part_table *table, struct g_consumer *cp)
struct g_provider *pp;
u_char *buf, *p;
int error, index, res, sum;
- uint16_t magic;
+ uint16_t magic, ecyl, scyl;
pp = cp->provider;
@@ -365,11 +365,15 @@ g_part_pc98_probe(struct g_part_table *table, struct g_consumer *cp)
for (index = 0; index < NDOSPART; index++) {
p = buf + SECSIZE + index * DOSPARTSIZE;
- if (p[2] != 0 || p[3] != 0)
- goto out;
- if (p[1] == 0)
+ if (p[0] == 0 || p[1] == 0) /* !dp_mid || !dp_sid */
continue;
- if (le16dec(p + 10) == 0)
+ scyl = le16dec(p + 10);
+ ecyl = le16dec(p + 14);
+ if (scyl == 0 || ecyl == 0)
+ goto out;
+ if (p[8] == p[12] && /* dp_ssect == dp_esect */
+ p[9] == p[13] && /* dp_shd == dp_ehd */
+ scyl == ecyl)
goto out;
}
diff --git a/sys/geom/part/g_part_vtoc8.c b/sys/geom/part/g_part_vtoc8.c
index 0fae760..78212c3 100644
--- a/sys/geom/part/g_part_vtoc8.c
+++ b/sys/geom/part/g_part_vtoc8.c
@@ -371,7 +371,7 @@ g_part_vtoc8_read(struct g_part_table *basetable, struct g_consumer *cp)
msize = pp->mediasize / pp->sectorsize;
sectors = be16dec(&table->vtoc.nsecs);
- if (sectors < 1 || sectors > 63)
+ if (sectors < 1)
goto invalid_label;
if (sectors != basetable->gpt_sectors && !basetable->gpt_fixgeom) {
g_part_geometry_heads(msize, sectors, &chs, &heads);
@@ -382,13 +382,21 @@ g_part_vtoc8_read(struct g_part_table *basetable, struct g_consumer *cp)
}
heads = be16dec(&table->vtoc.nheads);
- if (heads < 1 || heads > 255)
+ if (heads < 1)
goto invalid_label;
if (heads != basetable->gpt_heads && !basetable->gpt_fixgeom)
basetable->gpt_heads = heads;
- if (sectors != basetable->gpt_sectors ||
- heads != basetable->gpt_heads)
- printf("GEOM: %s: geometry does not match label.\n", pp->name);
+ /*
+ * Except for ATA disks > 32GB, Solaris uses the native geometry
+ * as reported by the target for the labels while da(4) typically
+ * uses a synthetic one so we don't complain too loudly if these
+ * geometries don't match.
+ */
+ if (bootverbose && (sectors != basetable->gpt_sectors ||
+ heads != basetable->gpt_heads))
+ printf("GEOM: %s: geometry does not match VTOC8 label "
+ "(label: %uh,%us GEOM: %uh,%us).\n", pp->name, heads,
+ sectors, basetable->gpt_heads, basetable->gpt_sectors);
table->secpercyl = heads * sectors;
cyls = be16dec(&table->vtoc.ncyls);
@@ -402,7 +410,7 @@ g_part_vtoc8_read(struct g_part_table *basetable, struct g_consumer *cp)
withtags = (be32dec(&table->vtoc.sanity) == VTOC_SANITY) ? 1 : 0;
if (!withtags) {
- printf("GEOM: %s: adding VTOC information.\n", pp->name);
+ printf("GEOM: %s: adding VTOC8 information.\n", pp->name);
be32enc(&table->vtoc.version, VTOC_VERSION);
bzero(&table->vtoc.volume, VTOC_VOLUME_LEN);
be16enc(&table->vtoc.nparts, VTOC8_NPARTS);
@@ -444,7 +452,7 @@ g_part_vtoc8_read(struct g_part_table *basetable, struct g_consumer *cp)
return (0);
invalid_label:
- printf("GEOM: %s: invalid disklabel.\n", pp->name);
+ printf("GEOM: %s: invalid VTOC8 label.\n", pp->name);
return (EINVAL);
}
diff --git a/sys/gnu/fs/ext2fs/ext2_bitops.h b/sys/gnu/fs/ext2fs/ext2_bitops.h
index 0ee54a1..c01150f 100644
--- a/sys/gnu/fs/ext2fs/ext2_bitops.h
+++ b/sys/gnu/fs/ext2fs/ext2_bitops.h
@@ -84,7 +84,7 @@ find_next_zero_bit(void *data, size_t sz, size_t ofs)
mask = ~0U << (ofs & 31);
bit = *p | ~mask;
if (bit != ~0U)
- return (ffs(~bit) + ofs - 1);
+ return (ffs(~bit) + (ofs & ~31U) - 1);
p++;
ofs = (ofs + 31U) & ~31U;
}
diff --git a/sys/gnu/fs/ext2fs/ext2_fs.h b/sys/gnu/fs/ext2fs/ext2_fs.h
index 1b2f3c2..c1d6ffd 100644
--- a/sys/gnu/fs/ext2fs/ext2_fs.h
+++ b/sys/gnu/fs/ext2fs/ext2_fs.h
@@ -150,8 +150,8 @@
#else /* !notyet */
#define EXT2_INODES_PER_BLOCK(s) ((s)->s_inodes_per_block)
/* Should be sizeof(struct ext2_inode): */
-#define EXT2_INODE_SIZE 128
-#define EXT2_FIRST_INO 11
+#define EXT2_INODE_SIZE(s) ((s)->s_inode_size)
+#define EXT2_FIRST_INO(s) ((s)->s_first_inode)
#endif /* notyet */
/*
diff --git a/sys/gnu/fs/ext2fs/ext2_fs_sb.h b/sys/gnu/fs/ext2fs/ext2_fs_sb.h
index 89d829e..ae5c268 100644
--- a/sys/gnu/fs/ext2fs/ext2_fs_sb.h
+++ b/sys/gnu/fs/ext2fs/ext2_fs_sb.h
@@ -63,6 +63,8 @@ struct ext2_sb_info {
unsigned long s_db_per_group; /* Number of descriptor blocks per group */
unsigned long s_desc_per_block; /* Number of group descriptors per block */
unsigned long s_groups_count; /* Number of groups in the fs */
+ unsigned long s_first_inode; /* First inode on fs */
+ unsigned int s_inode_size; /* Size for inode with extra data */
struct buffer_head * s_sbh; /* Buffer containing the super block */
struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
diff --git a/sys/gnu/fs/ext2fs/ext2_inode.c b/sys/gnu/fs/ext2fs/ext2_inode.c
index e0b79ba..0a62c30 100644
--- a/sys/gnu/fs/ext2fs/ext2_inode.c
+++ b/sys/gnu/fs/ext2fs/ext2_inode.c
@@ -91,7 +91,7 @@ ext2_update(vp, waitfor)
return (error);
}
ext2_i2ei(ip, (struct ext2_inode *)((char *)bp->b_data +
- EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)));
+ EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)));
if (waitfor && (vp->v_mount->mnt_kern_flag & MNTK_ASYNC) == 0)
return (bwrite(bp));
else {
diff --git a/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c b/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c
index d617014..b3263b4 100644
--- a/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c
+++ b/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c
@@ -225,7 +225,7 @@ void ext2_free_inode (struct inode * inode)
sb = inode->i_e2fs;
lock_super (DEVVP(inode));
- if (inode->i_number < EXT2_FIRST_INO ||
+ if (inode->i_number < EXT2_FIRST_INO(sb) ||
inode->i_number > sb->s_es->s_inodes_count) {
printf ("free_inode reserved inode or nonexistent inode");
unlock_super (DEVVP(inode));
@@ -435,7 +435,7 @@ repeat:
goto repeat;
}
j += i * EXT2_INODES_PER_GROUP(sb) + 1;
- if (j < EXT2_FIRST_INO || j > es->s_inodes_count) {
+ if (j < EXT2_FIRST_INO(sb) || j > es->s_inodes_count) {
printf ( "ext2_new_inode:"
"reserved inode or inode > inodes count - "
"block_group = %d,inode=%d", i, j);
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index c196fa9..5f4a84a 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -5,7 +5,7 @@
* University of Utah, Department of Computer Science
*/
/*-
- * Copyright (c) 1989, 1991, 1993, 1994
+ * Copyright (c) 1989, 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -120,7 +120,7 @@ static int compute_sb_data(struct vnode * devvp,
static const char *ext2_opts[] = { "from", "export", "acls", "noexec",
"noatime", "union", "suiddir", "multilabel", "nosymfollow",
"noclusterr", "noclusterw", "force", NULL };
-
+
/*
* VFS Operations.
*
@@ -318,7 +318,7 @@ static int ext2_check_descriptors (struct ext2_sb_info * sb)
{
/* examine next descriptor block */
if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
- gdp = (struct ext2_group_desc *)
+ gdp = (struct ext2_group_desc *)
sb->s_group_desc[desc_block++]->b_data;
if (gdp->bg_block_bitmap < block ||
gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
@@ -398,19 +398,19 @@ static int compute_sb_data(devvp, es, fs)
int logic_sb_block = 1; /* XXX for now */
#if 1
-#define V(v)
+#define V(v)
#else
-#define V(v) printf(#v"= %d\n", fs->v);
+#define V(v) printf(#v"= %lu\n", (unsigned long)fs->v);
#endif
- fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
+ fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
V(s_blocksize)
fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size;
V(s_bshift)
fs->s_fsbtodb = es->s_log_block_size + 1;
V(s_fsbtodb)
fs->s_qbmask = fs->s_blocksize - 1;
- V(s_bmask)
+ V(s_qbmask)
fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es);
V(s_blocksize_bits)
fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size;
@@ -424,7 +424,11 @@ static int compute_sb_data(devvp, es, fs)
V(s_frags_per_group)
fs->s_inodes_per_group = es->s_inodes_per_group;
V(s_inodes_per_group)
- fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE;
+ fs->s_inode_size = es->s_inode_size;
+ V(s_inode_size)
+ fs->s_first_inode = es->s_first_ino;
+ V(s_first_inode);
+ fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs);
V(s_inodes_per_block)
fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block;
V(s_itb_per_group)
@@ -445,14 +449,14 @@ static int compute_sb_data(devvp, es, fs)
M_EXT2MNT, M_WAITOK);
/* adjust logic_sb_block */
- if(fs->s_blocksize > SBSIZE)
+ if(fs->s_blocksize > SBSIZE)
/* Godmar thinks: if the blocksize is greater than 1024, then
- the superblock is logically part of block zero.
+ the superblock is logically part of block zero.
*/
logic_sb_block = 0;
-
+
for (i = 0; i < db_count; i++) {
- error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1),
+ error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1),
fs->s_blocksize, NOCRED, &fs->s_group_desc[i]);
if(error) {
for (j = 0; j < i; j++)
@@ -578,7 +582,7 @@ loop:
return (error);
}
ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data +
- EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip);
+ EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)), ip);
brelse(bp);
VOP_UNLOCK(vp, 0);
vrele(vp);
@@ -663,9 +667,9 @@ ext2_mountfs(devvp, mp)
we dynamically allocate both an ext2_sb_info and an ext2_super_block
while Linux keeps the super block in a locked buffer
*/
- ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
+ ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
M_EXT2MNT, M_WAITOK);
- ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
+ ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
M_EXT2MNT, M_WAITOK);
bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
@@ -678,7 +682,7 @@ ext2_mountfs(devvp, mp)
bp = NULL;
fs = ump->um_e2fs;
fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */
- /* if the fs is not mounted read-only, make sure the super block is
+ /* if the fs is not mounted read-only, make sure the super block is
always written back on a sync()
*/
fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
@@ -704,7 +708,7 @@ ext2_mountfs(devvp, mp)
ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
- if (ronly == 0)
+ if (ronly == 0)
ext2_sbupdate(ump, MNT_WAIT);
return (0);
out:
@@ -757,7 +761,7 @@ ext2_unmount(mp, mntflags, td)
}
/* release buffers containing group descriptors */
- for(i = 0; i < fs->s_db_per_group; i++)
+ for(i = 0; i < fs->s_db_per_group; i++)
ULCK_BUF(fs->s_group_desc[i])
bsd_free(fs->s_group_desc, M_EXT2MNT);
@@ -834,19 +838,19 @@ ext2_statfs(mp, sbp, td)
nsb++;
} else
nsb = fs->s_groups_count;
- overhead = es->s_first_data_block +
+ overhead = es->s_first_data_block +
/* Superblocks and block group descriptors: */
nsb * (1 + fs->s_db_per_group) +
/* Inode bitmap, block bitmap, and inode table: */
fs->s_groups_count * (1 + 1 + fs->s_itb_per_group);
- sbp->f_bsize = EXT2_FRAG_SIZE(fs);
+ sbp->f_bsize = EXT2_FRAG_SIZE(fs);
sbp->f_iosize = EXT2_BLOCK_SIZE(fs);
sbp->f_blocks = es->s_blocks_count - overhead;
- sbp->f_bfree = es->s_free_blocks_count;
- sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count;
- sbp->f_files = es->s_inodes_count;
- sbp->f_ffree = es->s_free_inodes_count;
+ sbp->f_bfree = es->s_free_blocks_count;
+ sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count;
+ sbp->f_files = es->s_inodes_count;
+ sbp->f_ffree = es->s_free_inodes_count;
return (0);
}
@@ -996,7 +1000,7 @@ ext2_vget(mp, ino, flags, vpp)
/* Read in the disk contents for the inode, copy into the inode. */
#if 0
-printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
+printf("ext2_vget(%d) dbn= %lu ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
#endif
if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
(int)fs->s_blocksize, NOCRED, &bp)) != 0) {
@@ -1012,7 +1016,7 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
return (error);
}
/* convert ext2 inode to dinode */
- ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
+ ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
ino_to_fsbo(fs, ino)), ip);
ip->i_block_group = ino_to_cg(fs, ino);
ip->i_next_alloc_block = 0;
@@ -1020,7 +1024,7 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
ip->i_prealloc_count = 0;
ip->i_prealloc_block = 0;
/* now we want to make sure that block pointers for unused
- blocks are zeroed out - ext2_balloc depends on this
+ blocks are zeroed out - ext2_balloc depends on this
although for regular files and directories only
*/
if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) {
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index c30f124..33c8858 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -1,8 +1,8 @@
#
# GENERIC -- Generic kernel configuration file for FreeBSD/i386
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -26,6 +26,12 @@ ident GENERIC
# To statically compile in device wiring instead of /boot/device.hints
#hints "GENERIC.hints" # Default places to look for devices.
+# Use the following to compile in values accessible to the kernel
+# through getenv() (or kenv(1) in userland). The format of the file
+# is 'variable=value', see kenv(1)
+#
+# env "GENERIC.env"
+
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options SCHED_ULE # ULE scheduler
@@ -65,6 +71,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options STOP_NMI # Stop CPUS using NMI instead of IPI
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+#options KDTRACE_HOOKS # Kernel DTrace hooks
# Debugging for use in -current
options KDB # Enable kernel debugger support.
@@ -268,7 +275,7 @@ device ath_hal # pci/cardbus chip support
options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors
device ath_rate_sample # SampleRate tx rate control for ath
device ral # Ralink Technology RT2500 wireless NICs.
-#device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs.
+device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs.
#device wl # Older non 802.11 Wavelan wireless NIC.
# Pseudo devices.
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 582784f..1b7edf7 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -347,6 +347,9 @@ device pci
# AGP GART support
device agp
+# AGP debugging.
+options AGP_DEBUG
+
#####################################################################
# HARDWARE DEVICE CONFIGURATION
@@ -539,8 +542,6 @@ hint.mse.0.irq="5"
# ctau: Cronyx Tau sync dual port V.35/RS-232/RS-530/RS-449/X.21/G.703/E1
# serial adaptor (requires sppp (default), or NETGRAPH if
# NETGRAPH_CRONYX is configured)
-# cx: Cronyx Sigma multiport sync/async adapter (requires sppp (default),
-# or NETGRAPH if NETGRAPH_CRONYX is configured)
# ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503
# HP PC Lan+, various PC Card devices
# (requires miibus)
@@ -554,7 +555,6 @@ hint.mse.0.irq="5"
# ral: Ralink Technology IEEE 802.11 wireless adapter
# sbni: Granch SBNI12-xx ISA and PCI adapters
# sr: RISCom/N2 hdlc sync 1/2 port V.35/X.21 serial driver (requires sppp)
-# ural: Ralink Technology RT2500USB IEEE 802.11 wireless adapter
# wl: Lucent Wavelan (ISA card only).
# wpi: Intel 3945ABG Wireless LAN controller
@@ -714,10 +714,11 @@ device glxsb # AMD Geode LX Security Block
#
# apm: Laptop Advanced Power Management (experimental)
# ipmi: Intelligent Platform Management Interface
-# pmtimer: Timer device driver for power management events (APM or ACPI)
# smapi: System Management Application Program Interface driver
# smbios: DMI/SMBIOS entry point
# vpd: Vital Product Data kernel interface
+# pmtimer: Adjust system timer at wakeup time
+# pbio: Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724)
# spic: Sony Programmable I/O controller (VAIO notebooks)
# asmc: Apple System Management Controller
@@ -749,8 +750,7 @@ device ipmi
device smapi
device smbios
device vpd
-device pmtimer # Adjust system timer at wakeup time
-# Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724)
+device pmtimer
device pbio
hint.pbio.0.at="isa"
hint.pbio.0.port="0x360"
diff --git a/sys/i386/conf/USB2 b/sys/i386/conf/USB2
new file mode 100644
index 0000000..a01f492
--- /dev/null
+++ b/sys/i386/conf/USB2
@@ -0,0 +1,114 @@
+#
+# USB2 -- Generic kernel configuration file for FreeBSD/i386 with USBng
+# stack.
+#
+# $FreeBSD$
+
+include GENERIC
+
+ident USB2-GENERIC
+
+# Remove support for the old USB stack.
+nodevice uhci
+nodevice ohci
+nodevice ehci
+nodevice usb
+nodevice ugen
+nodevice uhid
+nodevice ukbd
+nodevice ulpt
+nodevice umass
+nodevice ums
+nodevice ural
+nodevice rum
+nodevice zyd
+nodevice urio
+nodevice uscanner
+# USB Serial devices
+nodevice ucom
+nodevice u3g
+nodevice uark
+nodevice ubsa
+nodevice uftdi
+nodevice uipaq
+nodevice uplcom
+nodevice uslcom
+nodevice uvisor
+nodevice uvscom
+# USB Ethernet, requires miibus
+nodevice aue
+nodevice axe
+nodevice cdce
+nodevice cue
+nodevice kue
+nodevice rue
+nodevice udav
+
+#
+# The following drivers belong to the new USB stack.
+#
+
+# USB core support
+device usb2_core
+
+# USB controller support
+device usb2_controller
+device usb2_controller_ehci
+device usb2_controller_ohci
+device usb2_controller_uhci
+
+# USB mass storage support
+device usb2_storage
+device usb2_storage_mass
+
+# USB ethernet support, requires miibus
+device usb2_ethernet
+device usb2_ethernet_aue
+device usb2_ethernet_axe
+device usb2_ethernet_cdce
+device usb2_ethernet_cue
+device usb2_ethernet_kue
+device usb2_ethernet_rue
+device usb2_ethernet_dav
+
+# USB wireless LAN support
+device usb2_wlan
+device usb2_wlan_rum
+device usb2_wlan_ral
+device usb2_wlan_zyd
+
+# USB serial device support
+device usb2_serial
+device usb2_serial_ark
+device usb2_serial_bsa
+device usb2_serial_bser
+device usb2_serial_chcom
+device usb2_serial_cycom
+device usb2_serial_foma
+device usb2_serial_ftdi
+device usb2_serial_gensa
+device usb2_serial_ipaq
+device usb2_serial_lpt
+device usb2_serial_mct
+device usb2_serial_modem
+device usb2_serial_moscom
+device usb2_serial_plcom
+device usb2_serial_visor
+device usb2_serial_vscom
+
+# USB bluetooth support
+#device usb2_bluetooth
+#device usb2_bluetooth_ng
+
+# USB input device support
+device usb2_input
+device usb2_input_hid
+device usb2_input_kbd
+device usb2_input_ms
+
+# USB sound and MIDI device support
+#device usb2_sound
+
+# USB scanner support
+device usb2_image
+device usb2_scanner
diff --git a/sys/i386/conf/XEN b/sys/i386/conf/XEN
index 9295844..7ddc776 100644
--- a/sys/i386/conf/XEN
+++ b/sys/i386/conf/XEN
@@ -9,9 +9,9 @@ ident XEN
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions MODULES_OVERRIDE=""
-#options SCHED_ULE # ULE scheduler
-#options PREEMPTION # Enable kernel thread preemption
-options SCHED_4BSD
+options SCHED_ULE # ULE scheduler
+options PREEMPTION # Enable kernel thread preemption
+#options SCHED_4BSD
options INET # InterNETworking
options INET6 # IPv6 communications protocols
diff --git a/sys/i386/cpufreq/est.c b/sys/i386/cpufreq/est.c
index 05fe612..a8cebd0 100644
--- a/sys/i386/cpufreq/est.c
+++ b/sys/i386/cpufreq/est.c
@@ -55,10 +55,6 @@ __FBSDID("$FreeBSD$");
#define MSR_MISC_ENABLE 0x1a0
#define MSR_SS_ENABLE (1<<16)
-#ifndef CPU_VENDOR_CENTAUR
-#define CPU_VENDOR_CENTAUR 0x111d
-#endif
-
/* Frequency and MSR control values. */
typedef struct {
uint16_t freq;
diff --git a/sys/i386/cpufreq/smist.c b/sys/i386/cpufreq/smist.c
index a267226..5cfd72b 100644
--- a/sys/i386/cpufreq/smist.c
+++ b/sys/i386/cpufreq/smist.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <machine/bus.h>
+#include <machine/cputypes.h>
#include <machine/md_var.h>
#include <machine/vm86.h>
@@ -285,7 +286,7 @@ smist_identify(driver_t *driver, device_t parent)
return;
/* Check for a supported processor */
- if (strcmp(cpu_vendor, "GenuineIntel") != 0)
+ if (cpu_vendor_id != CPU_VENDOR_INTEL)
return;
switch (cpu_id & 0xff0) {
case 0x680: /* Pentium III [coppermine] */
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index 059e2ab..7c6acf0 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -234,7 +234,7 @@ ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat));
#endif
#ifdef XEN
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
ASSYM(PC_CR3, offsetof(struct pcpu, pc_cr3));
ASSYM(HYPERVISOR_VIRT_START, __HYPERVISOR_VIRT_START);
#endif
diff --git a/sys/i386/i386/i686_mem.c b/sys/i386/i386/i686_mem.c
index ab9aadf..fc88be1 100644
--- a/sys/i386/i386/i686_mem.c
+++ b/sys/i386/i386/i686_mem.c
@@ -678,9 +678,17 @@ i686_mem_drvinit(void *unused)
return;
if ((cpu_id & 0xf00) != 0x600 && (cpu_id & 0xf00) != 0xf00)
return;
- if (cpu_vendor_id != CPU_VENDOR_INTEL &&
- cpu_vendor_id != CPU_VENDOR_AMD)
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_INTEL:
+ case CPU_VENDOR_AMD:
+ break;
+ case CPU_VENDOR_CENTAUR:
+ if (cpu_exthigh >= 0x80000008)
+ break;
+ /* FALLTHROUGH */
+ default:
return;
+ }
mem_range_softc.mr_op = &i686_mrops;
}
SYSINIT(i686memdev, SI_SUB_DRIVERS, SI_ORDER_FIRST, i686_mem_drvinit, NULL);
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index cf70af7..d2a0292 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -606,6 +606,9 @@ printcpuinfo(void)
case 0x6d0:
strcpy(cpu_model, "VIA C7 Esther");
break;
+ case 0x6f0:
+ strcpy(cpu_model, "VIA Nano");
+ break;
default:
strcpy(cpu_model, "VIA/IDT Unknown");
}
@@ -856,6 +859,9 @@ printcpuinfo(void)
);
}
+ if (cpu_vendor_id == CPU_VENDOR_CENTAUR)
+ print_via_padlock_info();
+
if ((cpu_feature & CPUID_HTT) &&
cpu_vendor_id == CPU_VENDOR_AMD)
cpu_feature &= ~CPUID_HTT;
@@ -879,6 +885,12 @@ printcpuinfo(void)
I386_CPU_MODEL(cpu_id) >= 0x3))
tsc_is_invariant = 1;
break;
+ case CPU_VENDOR_CENTAUR:
+ if (I386_CPU_FAMILY(cpu_id) == 0x6 &&
+ I386_CPU_MODEL(cpu_id) >= 0xf &&
+ (rdmsr(0x1203) & 0x100000000ULL) == 0)
+ tsc_is_invariant = 1;
+ break;
}
if (tsc_is_invariant)
printf("\n TSC: P-state invariant");
@@ -915,8 +927,6 @@ printcpuinfo(void)
printf("\n CPU cache: write-through mode");
#endif
}
- if (cpu_vendor_id == CPU_VENDOR_CENTAUR)
- print_via_padlock_info();
/* Avoid ugly blank lines: only print newline when we have to. */
if (*cpu_vendor || cpu_id)
@@ -1568,6 +1578,7 @@ print_via_padlock_info(void)
return;
case 0x6a0:
case 0x6d0:
+ case 0x6f0:
break;
default:
return;
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 3fde0bc..e1c38ba 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -650,7 +650,7 @@ initializecpu(void)
init_6x86MX();
break;
case CPU_686:
- if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
+ if (cpu_vendor_id == CPU_VENDOR_INTEL) {
switch (cpu_id & 0xff0) {
case 0x610:
init_ppro();
@@ -659,7 +659,7 @@ initializecpu(void)
init_mendocino();
break;
}
- } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+ } else if (cpu_vendor_id == CPU_VENDOR_AMD) {
#if defined(I686_CPU) && defined(CPU_ATHLON_SSE_HACK)
/*
* Sometimes the BIOS doesn't enable SSE instructions.
@@ -678,7 +678,7 @@ initializecpu(void)
cpu_feature = regs[3];
}
#endif
- } else if (strcmp(cpu_vendor, "CentaurHauls") == 0) {
+ } else if (cpu_vendor_id == CPU_VENDOR_CENTAUR) {
switch (cpu_id & 0xff0) {
case 0x690:
if ((cpu_id & 0xf) < 3)
@@ -686,6 +686,7 @@ initializecpu(void)
/* fall through. */
case 0x6a0:
case 0x6d0:
+ case 0x6f0:
init_via();
break;
default:
@@ -718,7 +719,7 @@ initializecpu(void)
* CPU_UPGRADE_HW_CACHE option in your kernel configuration file.
* This option eliminates unneeded cache flush instruction(s).
*/
- if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+ if (cpu_vendor_id == CPU_VENDOR_CYRIX) {
switch (cpu) {
#ifdef I486_CPU
case CPU_486DLC:
@@ -737,7 +738,7 @@ initializecpu(void)
default:
break;
}
- } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+ } else if (cpu_vendor_id == CPU_VENDOR_AMD) {
switch (cpu_id & 0xFF0) {
case 0x470: /* Enhanced Am486DX2 WB */
case 0x490: /* Enhanced Am486DX4 WB */
@@ -745,7 +746,7 @@ initializecpu(void)
need_pre_dma_flush = 1;
break;
}
- } else if (strcmp(cpu_vendor, "IBM") == 0) {
+ } else if (cpu_vendor_id == CPU_VENDOR_IBM) {
need_post_dma_flush = 1;
} else {
#ifdef CPU_I486_ON_386
@@ -941,7 +942,7 @@ DB_SHOW_COMMAND(cyrixreg, cyrixreg)
u_char ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0;
cr0 = rcr0();
- if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
+ if (cpu_vendor_id == CPU_VENDOR_CYRIX) {
eflags = read_eflags();
disable_intr();
diff --git a/sys/i386/i386/io_apic.c b/sys/i386/i386/io_apic.c
index b038724..f63f28f 100644
--- a/sys/i386/i386/io_apic.c
+++ b/sys/i386/i386/io_apic.c
@@ -327,39 +327,56 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id)
{
struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
struct ioapic *io = (struct ioapic *)isrc->is_pic;
+ u_int old_vector;
+ u_int old_id;
+ /*
+ * keep 1st core as the destination for NMI
+ */
+ if (intpin->io_irq == IRQ_NMI)
+ apic_id = 0;
+
+ /*
+ * Set us up to free the old irq.
+ */
+ old_vector = intpin->io_vector;
+ old_id = intpin->io_cpu;
+ if (old_vector && apic_id == old_id)
+ return;
+
+ /*
+ * Allocate an APIC vector for this interrupt pin. Once
+ * we have a vector we program the interrupt pin.
+ */
intpin->io_cpu = apic_id;
+ intpin->io_vector = apic_alloc_vector(apic_id, intpin->io_irq);
if (bootverbose) {
- printf("ioapic%u: Assigning ", io->io_id);
+ printf("ioapic%u: routing intpin %u (", io->io_id,
+ intpin->io_intpin);
ioapic_print_irq(intpin);
- printf(" to local APIC %u\n", intpin->io_cpu);
+ printf(") to lapic %u vector %u\n", intpin->io_cpu,
+ intpin->io_vector);
}
ioapic_program_intpin(intpin);
+ /*
+ * Free the old vector after the new one is established. This is done
+ * to prevent races where we could miss an interrupt.
+ */
+ if (old_vector)
+ apic_free_vector(old_id, old_vector, intpin->io_irq);
}
static void
ioapic_enable_intr(struct intsrc *isrc)
{
struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
- struct ioapic *io = (struct ioapic *)isrc->is_pic;
- if (intpin->io_vector == 0) {
- /*
- * Allocate an APIC vector for this interrupt pin. Once
- * we have a vector we program the interrupt pin.
- */
- intpin->io_vector = apic_alloc_vector(intpin->io_irq);
- if (bootverbose) {
- printf("ioapic%u: routing intpin %u (", io->io_id,
- intpin->io_intpin);
- ioapic_print_irq(intpin);
- printf(") to vector %u\n", intpin->io_vector);
- }
- ioapic_program_intpin(intpin);
- apic_enable_vector(intpin->io_vector);
- }
+ if (intpin->io_vector == 0)
+ ioapic_assign_cpu(isrc, pcpu_find(0)->pc_apic_id);
+ apic_enable_vector(intpin->io_cpu, intpin->io_vector);
}
+
static void
ioapic_disable_intr(struct intsrc *isrc)
{
@@ -369,11 +386,11 @@ ioapic_disable_intr(struct intsrc *isrc)
if (intpin->io_vector != 0) {
/* Mask this interrupt pin and free its APIC vector. */
vector = intpin->io_vector;
- apic_disable_vector(vector);
+ apic_disable_vector(intpin->io_cpu, vector);
intpin->io_masked = 1;
intpin->io_vector = 0;
ioapic_program_intpin(intpin);
- apic_free_vector(vector, intpin->io_irq);
+ apic_free_vector(intpin->io_cpu, vector, intpin->io_irq);
}
}
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
index 2394e20..f543e68 100644
--- a/sys/i386/i386/local_apic.c
+++ b/sys/i386/i386/local_apic.c
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
#include <sys/smp.h>
#include <vm/vm.h>
@@ -109,6 +111,8 @@ struct lapic {
u_long la_hard_ticks;
u_long la_stat_ticks;
u_long la_prof_ticks;
+ /* Include IDT_SYSCALL to make indexing easier. */
+ u_int la_ioint_irqs[APIC_NUM_IOINTS + 1];
} static lapics[MAX_APIC_ID + 1];
/* XXX: should thermal be an NMI? */
@@ -134,8 +138,6 @@ static inthand_t *ioint_handlers[] = {
IDTVEC(apic_isr7), /* 224 - 255 */
};
-/* Include IDT_SYSCALL to make indexing easier. */
-static u_int ioint_irqs[APIC_NUM_IOINTS + 1];
static u_int32_t lapic_timer_divisors[] = {
APIC_TDCR_1, APIC_TDCR_2, APIC_TDCR_4, APIC_TDCR_8, APIC_TDCR_16,
@@ -216,7 +218,6 @@ lapic_init(vm_paddr_t addr)
/* Perform basic initialization of the BSP's local APIC. */
lapic_enable();
- ioint_irqs[IDT_SYSCALL - APIC_IO_INTS] = IRQ_SYSCALL;
/* Set BSP's per-CPU local APIC ID. */
PCPU_SET(apic_id, lapic_id());
@@ -224,7 +225,6 @@ lapic_init(vm_paddr_t addr)
/* Local APIC timer interrupt. */
setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
- ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] = IRQ_TIMER;
/* XXX: error/thermal interrupts */
}
@@ -256,6 +256,9 @@ lapic_create(u_int apic_id, int boot_cpu)
lapics[apic_id].la_lvts[i] = lvts[i];
lapics[apic_id].la_lvts[i].lvt_active = 0;
}
+ lapics[apic_id].la_ioint_irqs[IDT_SYSCALL - APIC_IO_INTS] = IRQ_SYSCALL;
+ lapics[apic_id].la_ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] =
+ IRQ_TIMER;
#ifdef SMP
cpu_add(apic_id, boot_cpu);
@@ -666,7 +669,8 @@ lapic_handle_intr(int vector, struct trapframe *frame)
if (vector == -1)
panic("Couldn't get vector from ISR!");
- isrc = intr_lookup_source(apic_idt_to_irq(vector));
+ isrc = intr_lookup_source(apic_idt_to_irq(PCPU_GET(apic_id),
+ vector));
intr_execute_handlers(isrc, frame);
}
@@ -781,9 +785,19 @@ lapic_timer_enable_intr(void)
lapic->lvt_timer = value;
}
+u_int
+apic_cpuid(u_int apic_id)
+{
+#ifdef SMP
+ return apic_cpuids[apic_id];
+#else
+ return 0;
+#endif
+}
+
/* Request a free IDT vector to be used by the specified IRQ. */
u_int
-apic_alloc_vector(u_int irq)
+apic_alloc_vector(u_int apic_id, u_int irq)
{
u_int vector;
@@ -795,9 +809,9 @@ apic_alloc_vector(u_int irq)
*/
mtx_lock_spin(&icu_lock);
for (vector = 0; vector < APIC_NUM_IOINTS; vector++) {
- if (ioint_irqs[vector] != 0)
+ if (lapics[apic_id].la_ioint_irqs[vector] != 0)
continue;
- ioint_irqs[vector] = irq;
+ lapics[apic_id].la_ioint_irqs[vector] = irq;
mtx_unlock_spin(&icu_lock);
return (vector + APIC_IO_INTS);
}
@@ -812,7 +826,7 @@ apic_alloc_vector(u_int irq)
* satisfied, 0 is returned.
*/
u_int
-apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
+apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
{
u_int first, run, vector;
@@ -835,7 +849,7 @@ apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
for (vector = 0; vector < APIC_NUM_IOINTS; vector++) {
/* Vector is in use, end run. */
- if (ioint_irqs[vector] != 0) {
+ if (lapics[apic_id].la_ioint_irqs[vector] != 0) {
run = 0;
first = 0;
continue;
@@ -855,7 +869,8 @@ apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
/* Found a run, assign IRQs and return the first vector. */
for (vector = 0; vector < count; vector++)
- ioint_irqs[first + vector] = irqs[vector];
+ lapics[apic_id].la_ioint_irqs[first + vector] =
+ irqs[vector];
mtx_unlock_spin(&icu_lock);
return (first + APIC_IO_INTS);
}
@@ -864,8 +879,14 @@ apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
return (0);
}
+/*
+ * Enable a vector for a particular apic_id. Since all lapics share idt
+ * entries and ioint_handlers this enables the vector on all lapics. lapics
+ * which do not have the vector configured would report spurious interrupts
+ * should it fire.
+ */
void
-apic_enable_vector(u_int vector)
+apic_enable_vector(u_int apic_id, u_int vector)
{
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
@@ -876,7 +897,7 @@ apic_enable_vector(u_int vector)
}
void
-apic_disable_vector(u_int vector)
+apic_disable_vector(u_int apic_id, u_int vector)
{
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
@@ -888,27 +909,42 @@ apic_disable_vector(u_int vector)
/* Release an APIC vector when it's no longer in use. */
void
-apic_free_vector(u_int vector, u_int irq)
+apic_free_vector(u_int apic_id, u_int vector, u_int irq)
{
+ struct thread *td;
KASSERT(vector >= APIC_IO_INTS && vector != IDT_SYSCALL &&
vector <= APIC_IO_INTS + APIC_NUM_IOINTS,
("Vector %u does not map to an IRQ line", vector));
KASSERT(irq < NUM_IO_INTS, ("Invalid IRQ %u", irq));
- KASSERT(ioint_irqs[vector - APIC_IO_INTS] == irq, ("IRQ mismatch"));
+ KASSERT(lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] ==
+ irq, ("IRQ mismatch"));
+
+ /*
+ * Bind us to the cpu that owned the vector before freeing it so
+ * we don't lose an interrupt delivery race.
+ */
+ td = curthread;
+ thread_lock(td);
+ if (sched_is_bound(td))
+ panic("apic_free_vector: Thread already bound.\n");
+ sched_bind(td, apic_cpuid(apic_id));
mtx_lock_spin(&icu_lock);
- ioint_irqs[vector - APIC_IO_INTS] = 0;
+ lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] = 0;
mtx_unlock_spin(&icu_lock);
+ sched_unbind(td);
+ thread_unlock(td);
+
}
/* Map an IDT vector (APIC) to an IRQ (interrupt source). */
u_int
-apic_idt_to_irq(u_int vector)
+apic_idt_to_irq(u_int apic_id, u_int vector)
{
KASSERT(vector >= APIC_IO_INTS && vector != IDT_SYSCALL &&
vector <= APIC_IO_INTS + APIC_NUM_IOINTS,
("Vector %u does not map to an IRQ line", vector));
- return (ioint_irqs[vector - APIC_IO_INTS]);
+ return (lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS]);
}
#ifdef DDB
@@ -919,6 +955,7 @@ DB_SHOW_COMMAND(apic, db_show_apic)
{
struct intsrc *isrc;
int i, verbose;
+ u_int apic_id;
u_int irq;
if (strcmp(modif, "vv") == 0)
@@ -927,9 +964,14 @@ DB_SHOW_COMMAND(apic, db_show_apic)
verbose = 1;
else
verbose = 0;
- for (i = 0; i < APIC_NUM_IOINTS + 1 && !db_pager_quit; i++) {
- irq = ioint_irqs[i];
- if (irq != 0 && irq != IRQ_SYSCALL) {
+ for (apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) {
+ if (lapics[apic_id].la_present == 0)
+ continue;
+ db_printf("Interrupts bound to lapic %u\n", apic_id);
+ for (i = 0; i < APIC_NUM_IOINTS + 1 && !db_pager_quit; i++) {
+ irq = lapics[apic_id].la_ioint_irqs[i];
+ if (irq == 0 || irq == IRQ_SYSCALL)
+ continue;
db_printf("vec 0x%2x -> ", i + APIC_IO_INTS);
if (irq == IRQ_TIMER)
db_printf("lapic timer\n");
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 7ca2493..94ac670 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -338,7 +338,7 @@ NON_GPROF_ENTRY(sigcode)
pushl %eax
testl $PSL_VM,UC_EFLAGS(%eax)
jne 1f
- movl UC_GS(%eax),%gs /* restore %gs */
+ mov UC_GS(%eax),%gs /* restore %gs */
1:
movl $SYS_sigreturn,%eax
pushl %eax /* junk to fake return addr. */
@@ -355,7 +355,7 @@ freebsd4_sigcode:
pushl %eax
testl $PSL_VM,UC4_EFLAGS(%eax)
jne 1f
- movl UC4_GS(%eax),%gs /* restore %gs */
+ mov UC4_GS(%eax),%gs /* restore %gs */
1:
movl $344,%eax /* 4.x SYS_sigreturn */
pushl %eax /* junk to fake return addr. */
@@ -373,7 +373,7 @@ osigcode:
pushl %eax
testl $PSL_VM,SC_PS(%eax)
jne 9f
- movl SC_GS(%eax),%gs /* restore %gs */
+ mov SC_GS(%eax),%gs /* restore %gs */
9:
movl $103,%eax /* 3.x SYS_sigreturn */
pushl %eax /* junk to fake return addr. */
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index d824b26..803d8d1 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -144,11 +144,11 @@ uint32_t arch_i386_xbox_memsize = 0;
#ifdef XEN
/* XEN includes */
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
void Xhypervisor_callback(void);
void failsafe_callback(void);
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index bf8a2c6..d871017 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -206,6 +206,7 @@ struct cpu_info {
int cpu_disabled:1;
} static cpu_info[MAX_APIC_ID + 1];
int cpu_apic_ids[MAXCPU];
+int apic_cpuids[MAX_APIC_ID + 1];
/* Holds pending bitmap based IPIs per CPU */
static volatile u_int cpu_ipi_pending[MAXCPU];
@@ -397,6 +398,7 @@ cpu_mp_start(void)
KASSERT(boot_cpu_id == PCPU_GET(apic_id),
("BSP's APIC ID doesn't match boot_cpu_id"));
cpu_apic_ids[0] = boot_cpu_id;
+ apic_cpuids[boot_cpu_id] = 0;
assign_cpu_ids();
@@ -705,6 +707,7 @@ assign_cpu_ids(void)
if (mp_ncpus < MAXCPU) {
cpu_apic_ids[mp_ncpus] = i;
+ apic_cpuids[i] = mp_ncpus;
mp_ncpus++;
} else
cpu_info[i].cpu_disabled = 1;
diff --git a/sys/i386/i386/msi.c b/sys/i386/i386/msi.c
index f8d92d6..8b18a10 100644
--- a/sys/i386/i386/msi.c
+++ b/sys/i386/i386/msi.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
+#include <machine/specialreg.h>
#include <dev/pci/pcivar.h>
/* Fields in address for Intel MSI messages. */
@@ -160,7 +161,9 @@ msi_enable_intr(struct intsrc *isrc)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
- apic_enable_vector(msi->msi_vector);
+ if (msi->msi_vector == 0)
+ msi_assign_cpu(isrc, 0);
+ apic_enable_vector(msi->msi_cpu, msi->msi_vector);
}
static void
@@ -168,7 +171,7 @@ msi_disable_intr(struct intsrc *isrc)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
- apic_disable_vector(msi->msi_vector);
+ apic_disable_vector(msi->msi_cpu, msi->msi_vector);
}
static int
@@ -198,23 +201,52 @@ static void
msi_assign_cpu(struct intsrc *isrc, u_int apic_id)
{
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
-
+ int old_vector;
+ u_int old_id;
+ int vector;
+
+ /* Store information to free existing irq. */
+ old_vector = msi->msi_vector;
+ old_id = msi->msi_cpu;
+ if (old_vector && old_id == apic_id)
+ return;
+ /* Allocate IDT vector on this cpu. */
+ vector = apic_alloc_vector(apic_id, msi->msi_irq);
+ if (vector == 0)
+ return; /* XXX alloc_vector panics on failure. */
msi->msi_cpu = apic_id;
+ msi->msi_vector = vector;
if (bootverbose)
- printf("msi: Assigning %s IRQ %d to local APIC %u\n",
+ printf("msi: Assigning %s IRQ %d to local APIC %u vector %u\n",
msi->msi_msix ? "MSI-X" : "MSI", msi->msi_irq,
- msi->msi_cpu);
+ msi->msi_cpu, msi->msi_vector);
pci_remap_msi_irq(msi->msi_dev, msi->msi_irq);
+ /*
+ * Free the old vector after the new one is established. This is done
+ * to prevent races where we could miss an interrupt.
+ */
+ if (old_vector)
+ apic_free_vector(old_id, old_vector, msi->msi_irq);
}
+
void
msi_init(void)
{
/* Check if we have a supported CPU. */
- if (!(cpu_vendor_id == CPU_VENDOR_INTEL ||
- cpu_vendor_id == CPU_VENDOR_AMD))
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_INTEL:
+ case CPU_VENDOR_AMD:
+ break;
+ case CPU_VENDOR_CENTAUR:
+ if (I386_CPU_FAMILY(cpu_id) == 0x6 &&
+ I386_CPU_MODEL(cpu_id) >= 0xf)
+ break;
+ /* FALLTHROUGH */
+ default:
return;
+ }
msi_enabled = 1;
intr_register_pic(&msi_pic);
@@ -253,7 +285,7 @@ int
msi_alloc(device_t dev, int count, int maxcount, int *irqs)
{
struct msi_intsrc *msi, *fsrc;
- int cnt, i, vector;
+ int cnt, i;
if (!msi_enabled)
return (ENXIO);
@@ -299,22 +331,12 @@ again:
/* Ok, we now have the IRQs allocated. */
KASSERT(cnt == count, ("count mismatch"));
- /* Allocate 'count' IDT vectors. */
- vector = apic_alloc_vectors(irqs, count, maxcount);
- if (vector == 0) {
- mtx_unlock(&msi_lock);
- return (ENOSPC);
- }
-
/* Assign IDT vectors and make these messages owned by 'dev'. */
fsrc = (struct msi_intsrc *)intr_lookup_source(irqs[0]);
for (i = 0; i < count; i++) {
msi = (struct msi_intsrc *)intr_lookup_source(irqs[i]);
msi->msi_dev = dev;
- msi->msi_vector = vector + i;
- if (bootverbose)
- printf("msi: routing MSI IRQ %d to vector %u\n",
- msi->msi_irq, msi->msi_vector);
+ msi->msi_vector = 0;
msi->msi_first = fsrc;
KASSERT(msi->msi_intsrc.is_handlers == 0,
("dead MSI has handlers"));
@@ -367,14 +389,18 @@ msi_release(int *irqs, int count)
KASSERT(msi->msi_dev == first->msi_dev, ("owner mismatch"));
msi->msi_first = NULL;
msi->msi_dev = NULL;
- apic_free_vector(msi->msi_vector, msi->msi_irq);
+ if (msi->msi_vector)
+ apic_free_vector(msi->msi_cpu, msi->msi_vector,
+ msi->msi_irq);
msi->msi_vector = 0;
}
/* Clear out the first message. */
first->msi_first = NULL;
first->msi_dev = NULL;
- apic_free_vector(first->msi_vector, first->msi_irq);
+ if (first->msi_vector)
+ apic_free_vector(first->msi_cpu, first->msi_vector,
+ first->msi_irq);
first->msi_vector = 0;
first->msi_count = 0;
@@ -423,7 +449,7 @@ int
msix_alloc(device_t dev, int *irq)
{
struct msi_intsrc *msi;
- int i, vector;
+ int i;
if (!msi_enabled)
return (ENXIO);
@@ -458,15 +484,9 @@ again:
goto again;
}
- /* Allocate an IDT vector. */
- vector = apic_alloc_vector(i);
- if (bootverbose)
- printf("msi: routing MSI-X IRQ %d to vector %u\n", msi->msi_irq,
- vector);
-
/* Setup source. */
msi->msi_dev = dev;
- msi->msi_vector = vector;
+ msi->msi_vector = 0;
msi->msi_msix = 1;
KASSERT(msi->msi_intsrc.is_handlers == 0, ("dead MSI-X has handlers"));
@@ -498,7 +518,8 @@ msix_release(int irq)
/* Clear out the message. */
msi->msi_dev = NULL;
- apic_free_vector(msi->msi_vector, msi->msi_irq);
+ if (msi->msi_vector)
+ apic_free_vector(msi->msi_cpu, msi->msi_vector, msi->msi_irq);
msi->msi_vector = 0;
msi->msi_msix = 0;
diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s
index 27a0094..0c07871 100644
--- a/sys/i386/i386/swtch.s
+++ b/sys/i386/i386/swtch.s
@@ -130,7 +130,7 @@ ENTRY(cpu_switch)
movl %ebp,PCB_EBP(%edx)
movl %esi,PCB_ESI(%edx)
movl %edi,PCB_EDI(%edx)
- movl %gs,PCB_GS(%edx)
+ mov %gs,PCB_GS(%edx)
pushfl /* PSL */
popl PCB_PSL(%edx)
/* Test if debug registers should be saved. */
@@ -313,7 +313,7 @@ sw1:
/* This must be done after loading the user LDT. */
.globl cpu_switch_load_gs
cpu_switch_load_gs:
- movl PCB_GS(%edx),%gs
+ mov PCB_GS(%edx),%gs
/* Test if debug registers should be restored. */
testl $PCB_DBREGS,PCB_FLAGS(%edx)
@@ -383,7 +383,7 @@ ENTRY(savectx)
movl %ebp,PCB_EBP(%ecx)
movl %esi,PCB_ESI(%ecx)
movl %edi,PCB_EDI(%ecx)
- movl %gs,PCB_GS(%ecx)
+ mov %gs,PCB_GS(%ecx)
pushfl
popl PCB_PSL(%ecx)
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 502be4d..2a6ca0f 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#ifdef XEN
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#endif
#ifdef PC98
#include <pc98/cbus/cbus.h>
@@ -616,7 +616,10 @@ cpu_reset_real()
disable_intr();
#ifdef XEN
- HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+ if (smp_processor_id() == 0)
+ HYPERVISOR_shutdown(SHUTDOWN_reboot);
+ else
+ HYPERVISOR_shutdown(SHUTDOWN_poweroff);
#endif
#ifdef CPU_ELAN
if (elan_mmcr != NULL)
diff --git a/sys/i386/ibcs2/ibcs2_sysi86.c b/sys/i386/ibcs2/ibcs2_sysi86.c
index 4d76218..12d5c4a 100644
--- a/sys/i386/ibcs2/ibcs2_sysi86.c
+++ b/sys/i386/ibcs2/ibcs2_sysi86.c
@@ -74,15 +74,11 @@ ibcs2_sysi86(struct thread *td, struct ibcs2_sysi86_args *args)
case SETNAME: { /* set hostname given string w/ len <= 7 chars */
int name[2];
- int error;
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, 0, 0, 0,
- args->arg, 7, 0, 0);
- mtx_unlock(&Giant);
- return (error);
+ return (userland_sysctl(td, name, 2, 0, 0, 0,
+ args->arg, 7, 0, 0));
}
case SI86_MEM: /* size of physical memory */
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index c33c0a9..c64dae3 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
@@ -187,14 +187,17 @@ inthand_t
IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
extern vm_paddr_t lapic_paddr;
-
-u_int apic_alloc_vector(u_int irq);
-u_int apic_alloc_vectors(u_int *irqs, u_int count, u_int align);
-void apic_disable_vector(u_int vector);
-void apic_enable_vector(u_int vector);
-void apic_free_vector(u_int vector, u_int irq);
-u_int apic_idt_to_irq(u_int vector);
+extern int apic_cpuids[];
+
+u_int apic_alloc_vector(u_int apic_id, u_int irq);
+u_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count,
+ u_int align);
+void apic_disable_vector(u_int apic_id, u_int vector);
+void apic_enable_vector(u_int apic_id, u_int vector);
+void apic_free_vector(u_int apic_id, u_int vector, u_int irq);
+u_int apic_idt_to_irq(u_int apic_id, u_int vector);
void apic_register_enumerator(struct apic_enumerator *enumerator);
+u_int apic_cpuid(u_int apic_id);
void *ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase);
int ioapic_disable_pin(void *cookie, u_int pin);
int ioapic_get_vector(void *cookie, u_int pin);
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 4bf93b1..ad5fc4c 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -497,7 +497,7 @@ static __inline u_int
rfs(void)
{
u_int sel;
- __asm __volatile("movl %%fs,%0" : "=rm" (sel));
+ __asm __volatile("mov %%fs,%0" : "=rm" (sel));
return (sel);
}
@@ -513,7 +513,7 @@ static __inline u_int
rgs(void)
{
u_int sel;
- __asm __volatile("movl %%gs,%0" : "=rm" (sel));
+ __asm __volatile("mov %%gs,%0" : "=rm" (sel));
return (sel);
}
@@ -537,7 +537,7 @@ static __inline u_int
rss(void)
{
u_int sel;
- __asm __volatile("movl %%ss,%0" : "=rm" (sel));
+ __asm __volatile("mov %%ss,%0" : "=rm" (sel));
return (sel);
}
@@ -552,13 +552,13 @@ rtr(void)
static __inline void
load_fs(u_int sel)
{
- __asm __volatile("movl %0,%%fs" : : "rm" (sel));
+ __asm __volatile("mov %0,%%fs" : : "rm" (sel));
}
static __inline void
load_gs(u_int sel)
{
- __asm __volatile("movl %0,%%gs" : : "rm" (sel));
+ __asm __volatile("mov %0,%%gs" : : "rm" (sel));
}
static __inline void
diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h
index 2aeb0c9..4593077 100644
--- a/sys/i386/include/intr_machdep.h
+++ b/sys/i386/include/intr_machdep.h
@@ -47,7 +47,7 @@
* IRQ values beyond 256 are used by MSI. We leave 255 unused to avoid
* confusion since 255 is used in PCI to indicate an invalid IRQ.
*/
-#define NUM_MSI_INTS 128
+#define NUM_MSI_INTS 512
#define FIRST_MSI_INT 256
#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS)
diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h
index e1a707d..2851709 100644
--- a/sys/i386/include/xen/xenfunc.h
+++ b/sys/i386/include/xen/xenfunc.h
@@ -33,7 +33,7 @@
#define _XEN_XENFUNC_H_
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xenpmap.h>
#include <machine/segments.h>
#include <sys/pcpu.h>
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 6be3da9..29dc2ca 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#ifdef XEN
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#endif
#ifdef DEV_ISA
diff --git a/sys/i386/linux/linux_locore.s b/sys/i386/linux/linux_locore.s
index 044e8e2..a3e0e7dc 100644
--- a/sys/i386/linux/linux_locore.s
+++ b/sys/i386/linux/linux_locore.s
@@ -8,7 +8,7 @@
NON_GPROF_ENTRY(linux_sigcode)
call *LINUX_SIGF_HANDLER(%esp)
leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
- movl LINUX_SC_GS(%ebx),%gs
+ mov LINUX_SC_GS(%ebx),%gs
movl %esp, %ebx /* pass sigframe */
push %eax /* fake ret addr */
movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
@@ -20,7 +20,7 @@ linux_rt_sigcode:
call *LINUX_RT_SIGF_HANDLER(%esp)
leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */
- movl LINUX_SC_GS(%ecx),%gs
+ mov LINUX_SC_GS(%ecx),%gs
push %eax /* fake ret addr */
movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
int $0x80 /* enter kernel with args */
diff --git a/sys/i386/svr4/svr4_locore.s b/sys/i386/svr4/svr4_locore.s
index 6274ad2..8c0c60a 100644
--- a/sys/i386/svr4/svr4_locore.s
+++ b/sys/i386/svr4/svr4_locore.s
@@ -14,7 +14,7 @@ NON_GPROF_ENTRY(svr4_sigcode)
testl $PSL_VM,SVR4_UC_EFLAGS(%eax)
jnz 1f
#endif
- movl SVR4_UC_GS(%eax),%gs
+ mov SVR4_UC_GS(%eax),%gs
1: pushl %eax # pointer to ucontext
pushl $1 # set context
movl $svr4_sys_context,%eax
diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c
index 3b4b6f3..acdf8da 100644
--- a/sys/i386/xen/clock.c
+++ b/sys/i386/xen/clock.c
@@ -78,11 +78,11 @@ __FBSDID("$FreeBSD$");
#include <i386/isa/isa.h>
#include <isa/rtc.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/pmap.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/xen/xenfunc.h>
#include <xen/interface/vcpu.h>
@@ -246,24 +246,29 @@ static void __get_time_values_from_xen(void)
shared_info_t *s = HYPERVISOR_shared_info;
struct vcpu_time_info *src;
struct shadow_time_info *dst;
+ uint32_t pre_version, post_version;
src = &s->vcpu_info[smp_processor_id()].time;
dst = &per_cpu(shadow_time, smp_processor_id());
+ spinlock_enter();
do {
- dst->version = src->version;
+ pre_version = dst->version = src->version;
rmb();
dst->tsc_timestamp = src->tsc_timestamp;
dst->system_timestamp = src->system_time;
dst->tsc_to_nsec_mul = src->tsc_to_system_mul;
dst->tsc_shift = src->tsc_shift;
rmb();
+ post_version = src->version;
}
- while ((src->version & 1) | (dst->version ^ src->version));
+ while ((pre_version & 1) | (pre_version ^ post_version));
dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
+ spinlock_exit();
}
+
static inline int time_values_up_to_date(int cpu)
{
struct vcpu_time_info *src;
@@ -311,62 +316,15 @@ clkintr(void *arg)
}
/* Process elapsed ticks since last call. */
- if (delta >= NS_PER_TICK) {
- processed_system_time += (delta / NS_PER_TICK) * NS_PER_TICK;
- per_cpu(processed_system_time, cpu) += (delta_cpu / NS_PER_TICK) * NS_PER_TICK;
- }
- if (PCPU_GET(cpuid) == 0)
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
- else
- hardclock_cpu(TRAPF_USERMODE(frame));
-
- /*
- * Take synchronised time from Xen once a minute if we're not
- * synchronised ourselves, and we haven't chosen to keep an independent
- * time base.
- */
-
- if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
- update_wallclock();
- tc_setclock(&shadow_tv);
- }
-
- /* XXX TODO */
- return (FILTER_HANDLED);
-}
-
-int clkintr2(void *arg);
-
-int
-clkintr2(void *arg)
-{
- int64_t delta_cpu, delta;
- struct trapframe *frame = (struct trapframe *)arg;
- int cpu = smp_processor_id();
- struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
-
- do {
- __get_time_values_from_xen();
-
- delta = delta_cpu =
- shadow->system_timestamp + get_nsec_offset(shadow);
- delta -= processed_system_time;
- delta_cpu -= per_cpu(processed_system_time, cpu);
-
- } while (!time_values_up_to_date(cpu));
-
- if (unlikely(delta < (int64_t)0) || unlikely(delta_cpu < (int64_t)0)) {
- printf("Timer ISR: Time went backwards: %lld\n", delta);
- return (FILTER_HANDLED);
- }
-
- /* Process elapsed ticks since last call. */
- if (delta >= NS_PER_TICK) {
- processed_system_time += (delta / NS_PER_TICK) * NS_PER_TICK;
- per_cpu(processed_system_time, cpu) += (delta_cpu / NS_PER_TICK) * NS_PER_TICK;
+ while (delta >= NS_PER_TICK) {
+ delta -= NS_PER_TICK;
+ processed_system_time += NS_PER_TICK;
+ per_cpu(processed_system_time, cpu) += NS_PER_TICK;
+ if (PCPU_GET(cpuid) == 0)
+ hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+ else
+ hardclock_cpu(TRAPF_USERMODE(frame));
}
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-
/*
* Take synchronised time from Xen once a minute if we're not
* synchronised ourselves, and we haven't chosen to keep an independent
@@ -381,14 +339,25 @@ clkintr2(void *arg)
/* XXX TODO */
return (FILTER_HANDLED);
}
-
static uint32_t
getit(void)
{
struct shadow_time_info *shadow;
+ uint64_t time;
+ uint32_t local_time_version;
+
shadow = &per_cpu(shadow_time, smp_processor_id());
- __get_time_values_from_xen();
- return shadow->system_timestamp + get_nsec_offset(shadow);
+
+ do {
+ local_time_version = shadow->version;
+ barrier();
+ time = shadow->system_timestamp + get_nsec_offset(shadow);
+ if (!time_values_up_to_date(smp_processor_id()))
+ __get_time_values_from_xen(/*cpu */);
+ barrier();
+ } while (local_time_version != shadow->version);
+
+ return (time);
}
@@ -552,7 +521,6 @@ startrtclock()
timer_freq = xen_timecounter.tc_frequency = 1000000000LL;
tc_init(&xen_timecounter);
-
rdtscll(alarm);
}
@@ -791,18 +759,20 @@ static struct vcpu_set_periodic_timer xen_set_periodic_tick;
void
cpu_initclocks(void)
{
- int time_irq;
-
+ unsigned int time_irq;
+ int error;
+
xen_set_periodic_tick.period_ns = NS_PER_TICK;
HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0,
&xen_set_periodic_tick);
-
- if ((time_irq = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
- clkintr, NULL,
- INTR_TYPE_CLK | INTR_FAST)) < 0) {
+
+ error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
+ clkintr, NULL, NULL,
+ INTR_TYPE_CLK | INTR_FAST, &time_irq);
+ if (error)
panic("failed to register clock interrupt\n");
- }
+
/* should fast clock be enabled ? */
@@ -811,18 +781,19 @@ cpu_initclocks(void)
int
ap_cpu_initclocks(int cpu)
{
- int time_irq;
+ unsigned int time_irq;
+ int error;
xen_set_periodic_tick.period_ns = NS_PER_TICK;
HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
&xen_set_periodic_tick);
-
- if ((time_irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, "clk",
- clkintr2, NULL,
- INTR_TYPE_CLK | INTR_FAST)) < 0) {
+ error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
+ clkintr, NULL, NULL,
+ INTR_TYPE_CLK | INTR_FAST, &time_irq);
+ if (error)
panic("failed to register clock interrupt\n");
- }
+
return (0);
}
@@ -900,13 +871,44 @@ xen_get_offset(void)
return edx;
}
#endif
+
+/* Convert jiffies to system time. */
+static uint64_t
+ticks_to_system_time(unsigned long newticks)
+{
+#if 0
+ unsigned long seq;
+#endif
+ long delta;
+ uint64_t st;
+
+
+ delta = newticks - ticks;
+ if (delta < 1) {
+ /* Triggers in some wrap-around cases, but that's okay:
+ * we just end up with a shorter timeout. */
+ st = processed_system_time + NS_PER_TICK;
+ } else if (((unsigned long)delta >> (BITS_PER_LONG-3)) != 0) {
+ /* Very long timeout means there is no pending timer.
+ * We indicate this to Xen by passing zero timeout. */
+ st = 0;
+ } else {
+ st = processed_system_time + delta * (uint64_t)NS_PER_TICK;
+ }
+
+ return (st);
+}
+
void
idle_block(void)
{
+ uint64_t timeout;
- __get_time_values_from_xen();
- PANIC_IF(HYPERVISOR_set_timer_op(processed_system_time + NS_PER_TICK) != 0);
- HYPERVISOR_sched_op(SCHEDOP_block, 0);
+ timeout = ticks_to_system_time(ticks + 1) + NS_PER_TICK/2;
+
+ __get_time_values_from_xen();
+ PANIC_IF(HYPERVISOR_set_timer_op(timeout) != 0);
+ HYPERVISOR_sched_op(SCHEDOP_block, 0);
}
int
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index 4b6c77c..3389b79 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -85,9 +85,9 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/xen-os.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/xen_intr.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/xen_intr.h>
+#include <xen/hypervisor.h>
#include <xen/interface/vcpu.h>
#define stop_cpus_with_nmi 0
@@ -137,6 +137,7 @@ struct cpu_info {
int cpu_disabled:1;
} static cpu_info[MAX_APIC_ID + 1];
int cpu_apic_ids[MAXCPU];
+int apic_cpuids[MAX_APIC_ID + 1];
/* Holds pending bitmap based IPIs per CPU */
static volatile u_int cpu_ipi_pending[MAXCPU];
@@ -284,6 +285,7 @@ cpu_mp_start(void)
KASSERT(boot_cpu_id == PCPU_GET(apic_id),
("BSP's APIC ID doesn't match boot_cpu_id"));
cpu_apic_ids[0] = boot_cpu_id;
+ apic_cpuids[boot_cpu_id] = 0;
assign_cpu_ids();
@@ -464,7 +466,8 @@ static int
xen_smp_intr_init(unsigned int cpu)
{
int rc;
-
+ unsigned int irq;
+
per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) = -1;
sprintf(resched_name[cpu], "resched%u", cpu);
@@ -472,22 +475,22 @@ xen_smp_intr_init(unsigned int cpu)
cpu,
resched_name[cpu],
smp_reschedule_interrupt,
- INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE);
+ INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE, &irq);
printf("cpu=%d irq=%d vector=%d\n",
cpu, rc, RESCHEDULE_VECTOR);
- per_cpu(resched_irq, cpu) = rc;
+ per_cpu(resched_irq, cpu) = irq;
sprintf(callfunc_name[cpu], "callfunc%u", cpu);
rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
cpu,
callfunc_name[cpu],
smp_call_function_interrupt,
- INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE);
+ INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE, &irq);
if (rc < 0)
goto fail;
- per_cpu(callfunc_irq, cpu) = rc;
+ per_cpu(callfunc_irq, cpu) = irq;
printf("cpu=%d irq=%d vector=%d\n",
cpu, rc, CALL_FUNCTION_VECTOR);
@@ -500,9 +503,9 @@ xen_smp_intr_init(unsigned int cpu)
fail:
if (per_cpu(resched_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
+ unbind_from_irqhandler(per_cpu(resched_irq, cpu));
if (per_cpu(callfunc_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
+ unbind_from_irqhandler(per_cpu(callfunc_irq, cpu));
return rc;
}
@@ -706,6 +709,7 @@ assign_cpu_ids(void)
if (mp_ncpus < MAXCPU) {
cpu_apic_ids[mp_ncpus] = i;
+ apic_cpuids[i] = mp_ncpus;
mp_ncpus++;
} else
cpu_info[i].cpu_disabled = 1;
diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c
index 99edc50..c6c7d53 100644
--- a/sys/i386/xen/mptable.c
+++ b/sys/i386/xen/mptable.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/mptable.h>
#include <machine/specialreg.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/smp.h>
#include <xen/interface/vcpu.h>
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index d646458..6ad67ff 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -154,7 +154,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <xen/interface/xen.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/hypercall.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index 9f48702..c99d754 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$");
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
#include <machine/xen/xenpmap.h>
@@ -1130,13 +1130,13 @@ initvalues(start_info_t *startinfo)
trap_info_t trap_table[] = {
{ 0, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(div)},
- { 1, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dbg)},
- { 3, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bpt)},
+ { 1, 0|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dbg)},
+ { 3, 3|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bpt)},
{ 4, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(ofl)},
/* This is UPL on Linux and KPL on BSD */
{ 5, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bnd)},
{ 6, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(ill)},
- { 7, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dna)},
+ { 7, 0|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dna)},
/*
* { 8, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(XXX)},
* no handler for double fault
@@ -1146,7 +1146,7 @@ trap_info_t trap_table[] = {
{11, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(missing)},
{12, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(stk)},
{13, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(prot)},
- {14, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(page)},
+ {14, 0|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(page)},
{15, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(rsvd)},
{16, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(fpu)},
{17, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(align)},
diff --git a/sys/ia64/conf/NOTES b/sys/ia64/conf/NOTES
index de9eae2..138396a 100644
--- a/sys/ia64/conf/NOTES
+++ b/sys/ia64/conf/NOTES
@@ -101,6 +101,9 @@ options VGA_WIDTH90 # support 90 column modes
# Debugging.
options VGA_DEBUG
+# AGP debugging.
+options AGP_DEBUG
+
# The following devices are not supported.
nodevice fdc
nooption FDC_DEBUG
diff --git a/sys/ia64/ia64/mca.c b/sys/ia64/ia64/mca.c
index bba0bfb..e25031d 100644
--- a/sys/ia64/ia64/mca.c
+++ b/sys/ia64/ia64/mca.c
@@ -42,6 +42,16 @@
MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture");
+struct mca_info {
+ STAILQ_ENTRY(mca_info) mi_link;
+ char mi_name[32];
+ size_t mi_recsz;
+ char mi_record[0];
+};
+
+static STAILQ_HEAD(, mca_info) mca_records =
+ STAILQ_HEAD_INITIALIZER(mca_records);
+
int64_t mca_info_size[SAL_INFO_TYPES];
vm_offset_t mca_info_block;
struct mtx mca_info_block_lock;
@@ -76,14 +86,32 @@ mca_sysctl_handler(SYSCTL_HANDLER_ARGS)
}
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)
{
struct ia64_sal_result result;
struct mca_record_header *hdr;
- struct sysctl_oid *oidp;
- char *name, *state;
+ struct mca_info *rec;
uint64_t seqnr;
- size_t recsz, totsz;
+ size_t recsz;
/*
* Don't try to get the state if we couldn't get the size of
@@ -95,9 +123,8 @@ 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) {
@@ -111,11 +138,13 @@ ia64_mca_save_state(int type)
mtx_unlock_spin(&mca_info_block_lock);
- totsz = sizeof(struct sysctl_oid) + recsz + 32;
- oidp = malloc(totsz, M_MCA, M_NOWAIT|M_ZERO);
- state = (char*)(oidp + 1);
- name = state + recsz;
- sprintf(name, "%lld", (long long)seqnr);
+ rec = malloc(sizeof(struct mca_info) + recsz, M_MCA,
+ M_NOWAIT | M_ZERO);
+ if (rec == NULL)
+ /* XXX: Not sure what to do. */
+ return;
+
+ sprintf(rec->mi_name, "%lld", (long long)seqnr);
mtx_lock_spin(&mca_info_block_lock);
@@ -133,24 +162,14 @@ ia64_mca_save_state(int type)
mca_info_block, 0, 0, 0, 0);
if (seqnr != hdr->rh_seqnr) {
mtx_unlock_spin(&mca_info_block_lock);
- free(oidp, M_MCA);
+ free(rec, M_MCA);
+ mtx_lock_spin(&mca_info_block_lock);
continue;
}
}
- bcopy((char*)mca_info_block, state, recsz);
-
- oidp->oid_parent = &sysctl__hw_mca_children;
- oidp->oid_number = OID_AUTO;
- oidp->oid_kind = CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_DYN;
- oidp->oid_arg1 = state;
- oidp->oid_arg2 = recsz;
- oidp->oid_name = name;
- oidp->oid_handler = mca_sysctl_handler;
- oidp->oid_fmt = "S,MCA";
- oidp->oid_descr = "Error record";
-
- sysctl_register_oid(oidp);
+ rec->mi_recsz = recsz;
+ bcopy((char*)mca_info_block, rec->mi_record, recsz);
if (mca_count > 0) {
if (seqnr < mca_first)
@@ -161,6 +180,7 @@ ia64_mca_save_state(int type)
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
@@ -168,8 +188,6 @@ ia64_mca_save_state(int type)
*/
result = ia64_sal_entry(SAL_CLEAR_STATE_INFO, type, 0, 0, 0,
0, 0, 0);
-
- mtx_unlock_spin(&mca_info_block_lock);
}
}
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index c97a912..6b559a0 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -239,9 +239,11 @@ 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 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);
static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
vm_page_t m);
@@ -799,11 +801,23 @@ retry:
PMAP_LOCK(pmap);
else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap))
continue;
+ pmap->pm_stats.resident_count--;
oldpmap = pmap_switch(pmap);
pte = pmap_find_vhpt(va);
KASSERT(pte != NULL, ("pte"));
- pmap_remove_pte(pmap, pte, va, pv, 1);
+ pmap_remove_vhpt(va);
+ pmap_invalidate_page(pmap, va);
pmap_switch(oldpmap);
+ if (pmap_accessed(pte))
+ vm_page_flag_set(m, PG_REFERENCED);
+ if (pmap_dirty(pte))
+ vm_page_dirty(m);
+ pmap_free_pte(pte, va);
+ TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
+ m->md.pv_list_count--;
+ TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+ if (TAILQ_EMPTY(&m->md.pv_list))
+ vm_page_flag_clear(m, PG_WRITEABLE);
if (pmap != locked_pmap)
PMAP_UNLOCK(pmap);
if (allocated_pv == NULL)
diff --git a/sys/ia64/include/mca.h b/sys/ia64/include/mca.h
index 997c221..75831c7 100644
--- a/sys/ia64/include/mca.h
+++ b/sys/ia64/include/mca.h
@@ -239,6 +239,7 @@ 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/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 431ee38..ec96974 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -822,7 +822,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
uprintf("ELF interpreter %s not found\n", interp);
return (error);
}
- }
+ } else
+ addr = 0;
/*
* Construct auxargs table (used by the fixup routine)
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 1c8e7bd..b311d30 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -498,8 +498,8 @@ statclock(int usermode)
rss = pgtok(vmspace_resident_count(vm));
if (ru->ru_maxrss < rss)
ru->ru_maxrss = rss;
- CTR4(KTR_SCHED, "statclock: %p(%s) prio %d stathz %d",
- td, td->td_name, td->td_priority, (stathz)?stathz:hz);
+ KTR_POINT2(KTR_SCHED, "thread", sched_tdname(td), "statclock",
+ "prio:%d", td->td_priority, "stathz:%d", (stathz)?stathz:hz);
thread_lock_flags(td, MTX_QUIET);
sched_clock(td);
thread_unlock(td);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c981411..648d27e 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1703,14 +1703,16 @@ fdfree(struct thread *td)
FILEDESC_XUNLOCK(fdp);
if (i > 0)
return;
- /*
- * We are the last reference to the structure, so we can
- * safely assume it will not change out from under us.
- */
+
fpp = fdp->fd_ofiles;
for (i = fdp->fd_lastfile; i-- >= 0; fpp++) {
- if (*fpp)
- (void) closef(*fpp, td);
+ if (*fpp) {
+ FILEDESC_XLOCK(fdp);
+ fp = *fpp;
+ *fpp = NULL;
+ FILEDESC_XUNLOCK(fdp);
+ (void) closef(fp, td);
+ }
}
FILEDESC_XLOCK(fdp);
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 0059b8f..e802780 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -217,7 +217,7 @@ prison_check_conflicting_ips(struct prison *p)
if ((p->pr_ip4s >= 1 && pr->pr_ip4s > 1) ||
(p->pr_ip4s > 1 && pr->pr_ip4s >= 1)) {
for (i = 0; i < p->pr_ip4s; i++) {
- if (_prison_check_ip4(pr, &p->pr_ip4[i]))
+ if (_prison_check_ip4(pr, &p->pr_ip4[i]) == 0)
return (EINVAL);
}
}
@@ -226,7 +226,7 @@ prison_check_conflicting_ips(struct prison *p)
if ((p->pr_ip6s >= 1 && pr->pr_ip6s > 1) ||
(p->pr_ip6s > 1 && pr->pr_ip6s >= 1)) {
for (i = 0; i < p->pr_ip6s; i++) {
- if (_prison_check_ip6(pr, &p->pr_ip6[i]))
+ if (_prison_check_ip6(pr, &p->pr_ip6[i]) == 0)
return (EINVAL);
}
}
@@ -293,7 +293,8 @@ jail_copyin_ips(struct jail *j)
}
j->ip4 = ip4;
- }
+ } else
+ j->ip4 = NULL;
#endif
#ifdef INET6
if (j->ip6s > 0) {
@@ -320,7 +321,8 @@ jail_copyin_ips(struct jail *j)
}
j->ip6 = ip6;
- }
+ } else
+ j->ip6 = NULL;
#endif
return (0);
@@ -805,12 +807,13 @@ prison_proc_free(struct prison *pr)
* Pass back primary IPv4 address of this jail.
*
* If not jailed return success but do not alter the address. Caller has to
- * make sure to intialize it correctly (INADDR_ANY).
+ * make sure to intialize it correctly (e.g. INADDR_ANY).
*
- * Returns 0 on success, 1 on error. Address returned in NBO.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address returned in NBO.
*/
int
-prison_getip4(struct ucred *cred, struct in_addr *ia)
+prison_get_ip4(struct ucred *cred, struct in_addr *ia)
{
KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
@@ -821,7 +824,7 @@ prison_getip4(struct ucred *cred, struct in_addr *ia)
return (0);
if (cred->cr_prison->pr_ip4 == NULL)
- return (1);
+ return (EAFNOSUPPORT);
ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
return (0);
@@ -831,8 +834,9 @@ prison_getip4(struct ucred *cred, struct in_addr *ia)
* Make sure our (source) address is set to something meaningful to this
* jail.
*
- * Returns 0 on success, 1 on error. Address passed in in NBO and returned
- * in NBO.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address passed in in NBO and returned in NBO.
*/
int
prison_local_ip4(struct ucred *cred, struct in_addr *ia)
@@ -845,7 +849,7 @@ prison_local_ip4(struct ucred *cred, struct in_addr *ia)
if (!jailed(cred))
return (0);
if (cred->cr_prison->pr_ip4 == NULL)
- return (1);
+ return (EAFNOSUPPORT);
ia0.s_addr = ntohl(ia->s_addr);
if (ia0.s_addr == INADDR_LOOPBACK) {
@@ -853,25 +857,23 @@ prison_local_ip4(struct ucred *cred, struct in_addr *ia)
return (0);
}
- /*
- * In case there is only 1 IPv4 address, bind directly.
- */
- if (ia0.s_addr == INADDR_ANY && cred->cr_prison->pr_ip4s == 1) {
- ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
+ if (ia0.s_addr == INADDR_ANY) {
+ /*
+ * In case there is only 1 IPv4 address, bind directly.
+ */
+ if (cred->cr_prison->pr_ip4s == 1)
+ ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
return (0);
}
- if (ia0.s_addr == INADDR_ANY || prison_check_ip4(cred, ia))
- return (0);
-
- return (1);
+ return (_prison_check_ip4(cred->cr_prison, ia));
}
/*
* Rewrite destination address in case we will connect to loopback address.
*
- * Returns 0 on success, 1 on error. Address passed in in NBO and returned
- * in NBO.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address passed in in NBO and returned in NBO.
*/
int
prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
@@ -883,7 +885,8 @@ prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
if (!jailed(cred))
return (0);
if (cred->cr_prison->pr_ip4 == NULL)
- return (1);
+ return (EAFNOSUPPORT);
+
if (ntohl(ia->s_addr) == INADDR_LOOPBACK) {
ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
return (0);
@@ -896,23 +899,22 @@ prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
}
/*
- * Check if given address belongs to the jail referenced by cred.
+ * Check if given address belongs to the jail referenced by cred/prison.
*
- * Returns 1 if address belongs to jail, 0 if not. Address passed in in NBO.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv4.
+ * Address passed in in NBO.
*/
static int
_prison_check_ip4(struct prison *pr, struct in_addr *ia)
{
int i, a, z, d;
- if (pr->pr_ip4 == NULL)
- return (0);
-
/*
* Check the primary IP.
*/
if (pr->pr_ip4[0].s_addr == ia->s_addr)
- return (1);
+ return (0);
/*
* All the other IPs are sorted so we can do a binary search.
@@ -927,9 +929,10 @@ _prison_check_ip4(struct prison *pr, struct in_addr *ia)
else if (d < 0)
a = i + 1;
else
- return (1);
+ return (0);
}
- return (0);
+
+ return (EADDRNOTAVAIL);
}
int
@@ -940,7 +943,9 @@ prison_check_ip4(struct ucred *cred, struct in_addr *ia)
KASSERT(ia != NULL, ("%s: ia is NULL", __func__));
if (!jailed(cred))
- return (1);
+ return (0);
+ if (cred->cr_prison->pr_ip4 == NULL)
+ return (EAFNOSUPPORT);
return (_prison_check_ip4(cred->cr_prison, ia));
}
@@ -951,12 +956,12 @@ prison_check_ip4(struct ucred *cred, struct in_addr *ia)
* Pass back primary IPv6 address for this jail.
*
* If not jailed return success but do not alter the address. Caller has to
- * make sure to intialize it correctly (IN6ADDR_ANY_INIT).
+ * make sure to intialize it correctly (e.g. IN6ADDR_ANY_INIT).
*
- * Returns 0 on success, 1 on error.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
*/
int
-prison_getip6(struct ucred *cred, struct in6_addr *ia6)
+prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
{
KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
@@ -965,7 +970,8 @@ prison_getip6(struct ucred *cred, struct in6_addr *ia6)
if (!jailed(cred))
return (0);
if (cred->cr_prison->pr_ip6 == NULL)
- return (1);
+ return (EAFNOSUPPORT);
+
bcopy(&cred->cr_prison->pr_ip6[0], ia6, sizeof(struct in6_addr));
return (0);
}
@@ -976,7 +982,8 @@ prison_getip6(struct ucred *cred, struct in6_addr *ia6)
* v6only should be set based on (inp->inp_flags & IN6P_IPV6_V6ONLY != 0)
* when needed while binding.
*
- * Returns 0 on success, 1 on error.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv6.
*/
int
prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
@@ -988,32 +995,32 @@ prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
if (!jailed(cred))
return (0);
if (cred->cr_prison->pr_ip6 == NULL)
- return (1);
+ return (EAFNOSUPPORT);
+
if (IN6_IS_ADDR_LOOPBACK(ia6)) {
bcopy(&cred->cr_prison->pr_ip6[0], ia6,
sizeof(struct in6_addr));
return (0);
}
- /*
- * In case there is only 1 IPv6 address, and v6only is true, then
- * bind directly.
- */
- if (v6only != 0 && IN6_IS_ADDR_UNSPECIFIED(ia6) &&
- cred->cr_prison->pr_ip6s == 1) {
- bcopy(&cred->cr_prison->pr_ip6[0], ia6,
- sizeof(struct in6_addr));
+ if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
+ /*
+ * In case there is only 1 IPv6 address, and v6only is true,
+ * then bind directly.
+ */
+ if (v6only != 0 && cred->cr_prison->pr_ip6s == 1)
+ bcopy(&cred->cr_prison->pr_ip6[0], ia6,
+ sizeof(struct in6_addr));
return (0);
}
- if (IN6_IS_ADDR_UNSPECIFIED(ia6) || prison_check_ip6(cred, ia6))
- return (0);
- return (1);
+
+ return (_prison_check_ip6(cred->cr_prison, ia6));
}
/*
* Rewrite destination address in case we will connect to loopback address.
*
- * Returns 0 on success, 1 on error.
+ * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
*/
int
prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
@@ -1025,7 +1032,8 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
if (!jailed(cred))
return (0);
if (cred->cr_prison->pr_ip6 == NULL)
- return (1);
+ return (EAFNOSUPPORT);
+
if (IN6_IS_ADDR_LOOPBACK(ia6)) {
bcopy(&cred->cr_prison->pr_ip6[0], ia6,
sizeof(struct in6_addr));
@@ -1039,23 +1047,21 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
}
/*
- * Check if given address belongs to the jail referenced by cred.
+ * Check if given address belongs to the jail referenced by cred/prison.
*
- * Returns 1 if address belongs to jail, 0 if not.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv6.
*/
static int
_prison_check_ip6(struct prison *pr, struct in6_addr *ia6)
{
int i, a, z, d;
- if (pr->pr_ip6 == NULL)
- return (0);
-
/*
* Check the primary IP.
*/
if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], ia6))
- return (1);
+ return (0);
/*
* All the other IPs are sorted so we can do a binary search.
@@ -1070,9 +1076,10 @@ _prison_check_ip6(struct prison *pr, struct in6_addr *ia6)
else if (d < 0)
a = i + 1;
else
- return (1);
+ return (0);
}
- return (0);
+
+ return (EADDRNOTAVAIL);
}
int
@@ -1083,18 +1090,63 @@ prison_check_ip6(struct ucred *cred, struct in6_addr *ia6)
KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__));
if (!jailed(cred))
- return (1);
+ return (0);
+ if (cred->cr_prison->pr_ip6 == NULL)
+ return (EAFNOSUPPORT);
return (_prison_check_ip6(cred->cr_prison, ia6));
}
#endif
/*
+ * Check if a jail supports the given address family.
+ *
+ * Returns 0 if not jailed or the address family is supported, EAFNOSUPPORT
+ * if not.
+ */
+int
+prison_check_af(struct ucred *cred, int af)
+{
+ int error;
+
+ KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
+
+
+ if (!jailed(cred))
+ return (0);
+
+ error = 0;
+ switch (af)
+ {
+#ifdef INET
+ case AF_INET:
+ if (cred->cr_prison->pr_ip4 == NULL)
+ error = EAFNOSUPPORT;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (cred->cr_prison->pr_ip6 == NULL)
+ error = EAFNOSUPPORT;
+ break;
+#endif
+ case AF_LOCAL:
+ case AF_ROUTE:
+ break;
+ default:
+ if (jail_socket_unixiproute_only)
+ error = EAFNOSUPPORT;
+ }
+ return (error);
+}
+
+/*
* Check if given address belongs to the jail referenced by cred (wrapper to
* prison_check_ip[46]).
*
- * Returns 1 if address belongs to jail, 0 if not. IPv4 Address passed in in
- * NBO.
+ * Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
+ * the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow
+ * the address family. IPv4 Address passed in in NBO.
*/
int
prison_if(struct ucred *cred, struct sockaddr *sa)
@@ -1105,35 +1157,31 @@ prison_if(struct ucred *cred, struct sockaddr *sa)
#ifdef INET6
struct sockaddr_in6 *sai6;
#endif
- int ok;
+ int error;
KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
KASSERT(sa != NULL, ("%s: sa is NULL", __func__));
- ok = 0;
- switch(sa->sa_family)
+ error = 0;
+ switch (sa->sa_family)
{
#ifdef INET
case AF_INET:
sai = (struct sockaddr_in *)sa;
- if (prison_check_ip4(cred, &sai->sin_addr))
- ok = 1;
+ error = prison_check_ip4(cred, &sai->sin_addr);
break;
-
#endif
#ifdef INET6
case AF_INET6:
sai6 = (struct sockaddr_in6 *)sa;
- if (prison_check_ip6(cred, (struct in6_addr *)&sai6->sin6_addr))
- ok = 1;
+ error = prison_check_ip6(cred, &sai6->sin6_addr);
break;
-
#endif
default:
- if (!jail_socket_unixiproute_only)
- ok = 1;
+ if (jailed(cred) && jail_socket_unixiproute_only)
+ error = EAFNOSUPPORT;
}
- return (ok);
+ return (error);
}
/*
@@ -1527,8 +1575,9 @@ sysctl_jail_list(SYSCTL_HANDLER_ARGS)
return (error);
}
-SYSCTL_OID(_security_jail, OID_AUTO, list, CTLTYPE_STRUCT | CTLFLAG_RD,
- NULL, 0, sysctl_jail_list, "S", "List of active jails");
+SYSCTL_OID(_security_jail, OID_AUTO, list,
+ CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_jail_list, "S", "List of active jails");
static int
sysctl_jail_jailed(SYSCTL_HANDLER_ARGS)
@@ -1540,8 +1589,9 @@ sysctl_jail_jailed(SYSCTL_HANDLER_ARGS)
return (error);
}
-SYSCTL_PROC(_security_jail, OID_AUTO, jailed, CTLTYPE_INT | CTLFLAG_RD,
- NULL, 0, sysctl_jail_jailed, "I", "Process in jail?");
+SYSCTL_PROC(_security_jail, OID_AUTO, jailed,
+ CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_jail_jailed, "I", "Process in jail?");
#ifdef DDB
DB_SHOW_COMMAND(jails, db_show_jails)
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 1683a5a..7805b01 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -293,10 +293,10 @@ linker_file_register_sysctls(linker_file_t lf)
if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
return;
- mtx_lock(&Giant);
+ sysctl_lock();
for (oidp = start; oidp < stop; oidp++)
sysctl_register_oid(*oidp);
- mtx_unlock(&Giant);
+ sysctl_unlock();
}
static void
@@ -310,10 +310,10 @@ linker_file_unregister_sysctls(linker_file_t lf)
if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
return;
- mtx_lock(&Giant);
+ sysctl_lock();
for (oidp = start; oidp < stop; oidp++)
sysctl_unregister_oid(*oidp);
- mtx_unlock(&Giant);
+ sysctl_unlock();
}
static int
@@ -643,8 +643,11 @@ linker_file_unload(linker_file_t file, int flags)
* link error.
*/
if (file->flags & LINKER_FILE_LINKED) {
+ file->flags &= ~LINKER_FILE_LINKED;
+ KLD_UNLOCK();
linker_file_sysuninit(file);
linker_file_unregister_sysctls(file);
+ KLD_LOCK();
}
TAILQ_REMOVE(&linker_files, file, link);
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 2bb02fd..b2294f8 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -897,14 +897,14 @@ lockmgr_printinfo(struct lock *lk)
uintptr_t x;
if (lk->lk_lock == LK_UNLOCKED)
- printf(" lock type %s: UNLOCKED\n", lk->lock_object.lo_name);
+ printf("lock type %s: UNLOCKED\n", lk->lock_object.lo_name);
else if (lk->lk_lock & LK_SHARE)
- printf(" lock type %s: SHARED (count %ju)\n",
+ printf("lock type %s: SHARED (count %ju)\n",
lk->lock_object.lo_name,
(uintmax_t)LK_SHARERS(lk->lk_lock));
else {
td = lockmgr_xholder(lk);
- printf(" lock type %s: EXCL by thread %p (pid %d)\n",
+ printf("lock type %s: EXCL by thread %p (pid %d)\n",
lk->lock_object.lo_name, td, td->td_proc->p_pid);
}
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 54434e2..02a1e7e 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -329,7 +329,6 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
int indx;
caddr_t va;
uma_zone_t zone;
- uma_keg_t keg;
#if defined(DIAGNOSTIC) || defined(DEBUG_REDZONE)
unsigned long osize = size;
#endif
@@ -378,18 +377,16 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
size = (size & ~KMEM_ZMASK) + KMEM_ZBASE;
indx = kmemsize[size >> KMEM_ZSHIFT];
zone = kmemzones[indx].kz_zone;
- keg = zone->uz_keg;
#ifdef MALLOC_PROFILE
krequests[size >> KMEM_ZSHIFT]++;
#endif
va = uma_zalloc(zone, flags);
if (va != NULL)
- size = keg->uk_size;
+ size = zone->uz_size;
malloc_type_zone_allocated(mtp, va == NULL ? 0 : size, indx);
} else {
size = roundup(size, PAGE_SIZE);
zone = NULL;
- keg = NULL;
va = uma_large_malloc(size, flags);
malloc_type_allocated(mtp, va == NULL ? 0 : size);
}
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index a7810ef..26b0250 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -420,6 +420,7 @@ mb_ctor_mbuf(void *mem, int size, void *arg, int how)
m->m_pkthdr.csum_data = 0;
m->m_pkthdr.tso_segsz = 0;
m->m_pkthdr.ether_vtag = 0;
+ m->m_pkthdr.flowid = 0;
SLIST_INIT(&m->m_pkthdr.tags);
#ifdef MAC
/* If the label init fails, fail the alloc */
@@ -644,6 +645,7 @@ mb_ctor_pack(void *mem, int size, void *arg, int how)
m->m_pkthdr.csum_data = 0;
m->m_pkthdr.tso_segsz = 0;
m->m_pkthdr.ether_vtag = 0;
+ m->m_pkthdr.flowid = 0;
SLIST_INIT(&m->m_pkthdr.tags);
#ifdef MAC
/* If the label init fails, fail the alloc */
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index afe0153..80c1789 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -87,19 +87,19 @@ SYSCTL_NODE(, OID_AUTO, regression, CTLFLAG_RW, 0,
"Regression test MIB");
#endif
-SYSCTL_STRING(_kern, OID_AUTO, ident, CTLFLAG_RD,
+SYSCTL_STRING(_kern, OID_AUTO, ident, CTLFLAG_RD|CTLFLAG_MPSAFE,
kern_ident, 0, "Kernel identifier");
-SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD,
+SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD|CTLFLAG_MPSAFE,
osrelease, 0, "Operating system release");
SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD,
0, BSD, "Operating system revision");
-SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD,
+SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD|CTLFLAG_MPSAFE,
version, 0, "Kernel version");
-SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD,
+SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD|CTLFLAG_MPSAFE,
ostype, 0, "Operating system type");
/*
@@ -165,8 +165,9 @@ sysctl_kern_arnd(SYSCTL_HANDLER_ARGS)
return (SYSCTL_OUT(req, buf, len));
}
-SYSCTL_PROC(_kern, KERN_ARND, arandom, CTLTYPE_OPAQUE | CTLFLAG_RD,
- NULL, 0, sysctl_kern_arnd, "", "arc4rand");
+SYSCTL_PROC(_kern, KERN_ARND, arandom,
+ CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_kern_arnd, "", "arc4rand");
static int
sysctl_hw_physmem(SYSCTL_HANDLER_ARGS)
@@ -267,7 +268,7 @@ sysctl_hostname(SYSCTL_HANDLER_ARGS)
}
SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
- CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_PRISON,
+ CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_PRISON|CTLFLAG_MPSAFE,
0, 0, sysctl_hostname, "A", "Hostname");
static int regression_securelevel_nonmonotonic = 0;
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 9c6225f..1c44f01 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1280,7 +1280,7 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS)
struct proc *p;
struct vnode *vp;
char *retbuf, *freebuf;
- int error;
+ int error, vfslocked;
if (arglen != 1)
return (EINVAL);
@@ -1306,7 +1306,9 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS)
if (*pidp != -1)
PROC_UNLOCK(p);
error = vn_fullpath(req->td, vp, &retbuf, &freebuf);
+ vfslocked = VFS_LOCK_GIANT(vp->v_mount);
vrele(vp);
+ VFS_UNLOCK_GIANT(vfslocked);
if (error)
return (error);
error = SYSCTL_OUT(req, retbuf, strlen(retbuf) + 1);
@@ -1500,7 +1502,7 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
vm_map_lock_read(map);
if (error)
break;
- if (last_timestamp + 1 != map->timestamp) {
+ if (last_timestamp != map->timestamp) {
vm_map_lookup_entry(map, addr - 1, &tmp_entry);
entry = tmp_entry;
}
@@ -1677,7 +1679,7 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS)
vm_map_lock_read(map);
if (error)
break;
- if (last_timestamp + 1 != map->timestamp) {
+ if (last_timestamp != map->timestamp) {
vm_map_lookup_entry(map, addr - 1, &tmp_entry);
entry = tmp_entry;
}
@@ -1793,82 +1795,85 @@ repeat:
SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table");
-SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT,
- 0, 0, sysctl_kern_proc, "S,proc", "Return entire process table");
+SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT|
+ CTLFLAG_MPSAFE, 0, 0, sysctl_kern_proc, "S,proc",
+ "Return entire process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_RGID, rgid, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_RGID, rgid, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_SESSION, sid, CTLFLAG_RD,
- sysctl_kern_proc, "Process table");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_SESSION, sid, CTLFLAG_RD |
+ CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Process table");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_PROC, proc, CTLFLAG_RD,
+static SYSCTL_NODE(_kern_proc, KERN_PROC_PROC, proc, CTLFLAG_RD | CTLFLAG_MPSAFE,
sysctl_kern_proc, "Return process table, no threads");
static SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args,
- CTLFLAG_RW | CTLFLAG_ANYBODY,
+ CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
sysctl_kern_proc_args, "Process argument list");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_PATHNAME, pathname, CTLFLAG_RD,
- sysctl_kern_proc_pathname, "Process executable path");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_PATHNAME, pathname, CTLFLAG_RD |
+ CTLFLAG_MPSAFE, sysctl_kern_proc_pathname, "Process executable path");
-static SYSCTL_NODE(_kern_proc, KERN_PROC_SV_NAME, sv_name, CTLFLAG_RD,
- sysctl_kern_proc_sv_name, "Process syscall vector name (ABI type)");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_SV_NAME, sv_name, CTLFLAG_RD |
+ CTLFLAG_MPSAFE, sysctl_kern_proc_sv_name,
+ "Process syscall vector name (ABI type)");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_GID | KERN_PROC_INC_THREAD), gid_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_PGRP | KERN_PROC_INC_THREAD), pgrp_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_RGID | KERN_PROC_INC_THREAD), rgid_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_SESSION | KERN_PROC_INC_THREAD),
- sid_td, CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ sid_td, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_TTY | KERN_PROC_INC_THREAD), tty_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_UID | KERN_PROC_INC_THREAD), uid_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_RUID | KERN_PROC_INC_THREAD), ruid_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_PID | KERN_PROC_INC_THREAD), pid_td,
- CTLFLAG_RD, sysctl_kern_proc, "Process table");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table");
static SYSCTL_NODE(_kern_proc, (KERN_PROC_PROC | KERN_PROC_INC_THREAD), proc_td,
- CTLFLAG_RD, sysctl_kern_proc, "Return process table, no threads");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc,
+ "Return process table, no threads");
#ifdef COMPAT_FREEBSD7
-static SYSCTL_NODE(_kern_proc, KERN_PROC_OVMMAP, ovmmap, CTLFLAG_RD,
- sysctl_kern_proc_ovmmap, "Old Process vm map entries");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_OVMMAP, ovmmap, CTLFLAG_RD |
+ CTLFLAG_MPSAFE, sysctl_kern_proc_ovmmap, "Old Process vm map entries");
#endif
-static SYSCTL_NODE(_kern_proc, KERN_PROC_VMMAP, vmmap, CTLFLAG_RD,
- sysctl_kern_proc_vmmap, "Process vm map entries");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_VMMAP, vmmap, CTLFLAG_RD |
+ CTLFLAG_MPSAFE, sysctl_kern_proc_vmmap, "Process vm map entries");
#if defined(STACK) || defined(DDB)
-static SYSCTL_NODE(_kern_proc, KERN_PROC_KSTACK, kstack, CTLFLAG_RD,
- sysctl_kern_proc_kstack, "Process kernel stacks");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_KSTACK, kstack, CTLFLAG_RD |
+ CTLFLAG_MPSAFE, sysctl_kern_proc_kstack, "Process kernel stacks");
#endif
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 53e3ced..bc539af 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -71,6 +71,13 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#endif
+#define KTDSTATE(td) \
+ (((td)->td_inhibitors & TDI_SLEEPING) != 0 ? "sleep" : \
+ ((td)->td_inhibitors & TDI_SUSPENDED) != 0 ? "suspended" : \
+ ((td)->td_inhibitors & TDI_SWAPPED) != 0 ? "swapped" : \
+ ((td)->td_inhibitors & TDI_LOCK) != 0 ? "blocked" : \
+ ((td)->td_inhibitors & TDI_IWAIT) != 0 ? "iwait" : "yielding")
+
static void synch_setup(void *dummy);
SYSINIT(synch_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, synch_setup,
NULL);
@@ -425,25 +432,19 @@ mi_switch(int flags, struct thread *newtd)
td->td_tid, td->td_sched, p->p_pid, td->td_name);
#if (KTR_COMPILE & KTR_SCHED) != 0
if (TD_IS_IDLETHREAD(td))
- CTR3(KTR_SCHED, "mi_switch: %p(%s) prio %d idle",
- td, td->td_name, td->td_priority);
- else if (newtd != NULL)
- CTR5(KTR_SCHED,
- "mi_switch: %p(%s) prio %d preempted by %p(%s)",
- td, td->td_name, td->td_priority, newtd,
- newtd->td_name);
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "idle",
+ "prio:%d", td->td_priority);
else
- CTR6(KTR_SCHED,
- "mi_switch: %p(%s) prio %d inhibit %d wmesg %s lock %s",
- td, td->td_name, td->td_priority,
- td->td_inhibitors, td->td_wmesg, td->td_lockname);
+ KTR_STATE3(KTR_SCHED, "thread", sched_tdname(td), KTDSTATE(td),
+ "prio:%d", td->td_priority, "wmesg:\"%s\"", td->td_wmesg,
+ "lockname:\"%s\"", td->td_lockname);
#endif
#ifdef XEN
PT_UPDATES_FLUSH();
#endif
sched_switch(td, newtd, flags);
- CTR3(KTR_SCHED, "mi_switch: running %p(%s) prio %d",
- td, td->td_name, td->td_priority);
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "running",
+ "prio:%d", td->td_priority);
CTR4(KTR_PROC, "mi_switch: new thread %ld (td_sched %p, pid %ld, %s)",
td->td_tid, td->td_sched, p->p_pid, td->td_name);
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index a094d42..9e15b9c 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -65,23 +65,41 @@ static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
/*
- * Locking - this locks the sysctl tree in memory.
+ * The sysctllock protects the MIB tree. It also protects sysctl
+ * contexts used with dynamic sysctls. The sysctl_register_oid() and
+ * sysctl_unregister_oid() routines require the sysctllock to already
+ * be held, so the sysctl_lock() and sysctl_unlock() routines are
+ * provided for the few places in the kernel which need to use that
+ * API rather than using the dynamic API. Use of the dynamic API is
+ * strongly encouraged for most code.
+ *
+ * This lock is also used to serialize userland sysctl requests. Some
+ * sysctls wire user memory, and serializing the requests limits the
+ * amount of wired user memory in use.
*/
static struct sx sysctllock;
-#define SYSCTL_LOCK() sx_xlock(&sysctllock)
-#define SYSCTL_UNLOCK() sx_xunlock(&sysctllock)
+#define SYSCTL_SLOCK() sx_slock(&sysctllock)
+#define SYSCTL_SUNLOCK() sx_sunlock(&sysctllock)
+#define SYSCTL_XLOCK() sx_xlock(&sysctllock)
+#define SYSCTL_XUNLOCK() sx_xunlock(&sysctllock)
+#define SYSCTL_ASSERT_XLOCKED() sx_assert(&sysctllock, SA_XLOCKED)
+#define SYSCTL_ASSERT_LOCKED() sx_assert(&sysctllock, SA_LOCKED)
#define SYSCTL_INIT() sx_init(&sysctllock, "sysctl lock")
static int sysctl_root(SYSCTL_HANDLER_ARGS);
struct sysctl_oid_list sysctl__children; /* root list */
+static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del,
+ int recurse);
+
static struct sysctl_oid *
sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
{
struct sysctl_oid *oidp;
+ SYSCTL_ASSERT_LOCKED();
SLIST_FOREACH(oidp, list, oid_link) {
if (strcmp(oidp->oid_name, name) == 0) {
return (oidp);
@@ -95,6 +113,19 @@ sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
*
* Order by number in each list.
*/
+void
+sysctl_lock(void)
+{
+
+ SYSCTL_XLOCK();
+}
+
+void
+sysctl_unlock(void)
+{
+
+ SYSCTL_XUNLOCK();
+}
void
sysctl_register_oid(struct sysctl_oid *oidp)
@@ -107,6 +138,7 @@ sysctl_register_oid(struct sysctl_oid *oidp)
* First check if another oid with the same name already
* exists in the parent's list.
*/
+ SYSCTL_ASSERT_XLOCKED();
p = sysctl_find_oidname(oidp->oid_name, parent);
if (p != NULL) {
if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
@@ -159,6 +191,7 @@ sysctl_unregister_oid(struct sysctl_oid *oidp)
struct sysctl_oid *p;
int error;
+ SYSCTL_ASSERT_XLOCKED();
error = ENOENT;
if (oidp->oid_number == OID_AUTO) {
error = EINVAL;
@@ -190,6 +223,12 @@ sysctl_ctx_init(struct sysctl_ctx_list *c)
if (c == NULL) {
return (EINVAL);
}
+
+ /*
+ * No locking here, the caller is responsible for not adding
+ * new nodes to a context until after this function has
+ * returned.
+ */
TAILQ_INIT(c);
return (0);
}
@@ -208,8 +247,9 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
* XXX This algorithm is a hack. But I don't know any
* XXX better solution for now...
*/
+ SYSCTL_XLOCK();
TAILQ_FOREACH(e, clist, link) {
- error = sysctl_remove_oid(e->entry, 0, 0);
+ error = sysctl_remove_oid_locked(e->entry, 0, 0);
if (error)
break;
}
@@ -226,19 +266,22 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
sysctl_register_oid(e1->entry);
e1 = TAILQ_PREV(e1, sysctl_ctx_list, link);
}
- if (error)
+ if (error) {
+ SYSCTL_XUNLOCK();
return(EBUSY);
+ }
/* Now really delete the entries */
e = TAILQ_FIRST(clist);
while (e != NULL) {
e1 = TAILQ_NEXT(e, link);
- error = sysctl_remove_oid(e->entry, 1, 0);
+ error = sysctl_remove_oid_locked(e->entry, 1, 0);
if (error)
panic("sysctl_remove_oid: corrupt tree, entry: %s",
e->entry->oid_name);
free(e, M_SYSCTLOID);
e = e1;
}
+ SYSCTL_XUNLOCK();
return (error);
}
@@ -248,6 +291,7 @@ sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
{
struct sysctl_ctx_entry *e;
+ SYSCTL_ASSERT_XLOCKED();
if (clist == NULL || oidp == NULL)
return(NULL);
e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK);
@@ -262,6 +306,7 @@ sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
{
struct sysctl_ctx_entry *e;
+ SYSCTL_ASSERT_LOCKED();
if (clist == NULL || oidp == NULL)
return(NULL);
TAILQ_FOREACH(e, clist, link) {
@@ -283,13 +328,17 @@ sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
if (clist == NULL || oidp == NULL)
return (EINVAL);
+ SYSCTL_XLOCK();
e = sysctl_ctx_entry_find(clist, oidp);
if (e != NULL) {
TAILQ_REMOVE(clist, e, link);
+ SYSCTL_XUNLOCK();
free(e, M_SYSCTLOID);
return (0);
- } else
+ } else {
+ SYSCTL_XUNLOCK();
return (ENOENT);
+ }
}
/*
@@ -301,9 +350,21 @@ sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
int
sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
{
+ int error;
+
+ SYSCTL_XLOCK();
+ error = sysctl_remove_oid_locked(oidp, del, recurse);
+ SYSCTL_XUNLOCK();
+ return (error);
+}
+
+static int
+sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse)
+{
struct sysctl_oid *p;
int error;
+ SYSCTL_ASSERT_XLOCKED();
if (oidp == NULL)
return(EINVAL);
if ((oidp->oid_kind & CTLFLAG_DYN) == 0) {
@@ -322,7 +383,8 @@ sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
SLIST_FOREACH(p, SYSCTL_CHILDREN(oidp), oid_link) {
if (!recurse)
return (ENOTEMPTY);
- error = sysctl_remove_oid(p, del, recurse);
+ error = sysctl_remove_oid_locked(p, del,
+ recurse);
if (error)
return (error);
}
@@ -367,6 +429,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
if (parent == NULL)
return(NULL);
/* Check if the node already exists, otherwise create it */
+ SYSCTL_XLOCK();
oidp = sysctl_find_oidname(name, parent);
if (oidp != NULL) {
if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
@@ -374,8 +437,10 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
/* Update the context */
if (clist != NULL)
sysctl_ctx_entry_add(clist, oidp);
+ SYSCTL_XUNLOCK();
return (oidp);
} else {
+ SYSCTL_XUNLOCK();
printf("can't re-use a leaf (%s)!\n", name);
return (NULL);
}
@@ -413,6 +478,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
sysctl_ctx_entry_add(clist, oidp);
/* Register this oid */
sysctl_register_oid(oidp);
+ SYSCTL_XUNLOCK();
return (oidp);
}
@@ -426,12 +492,14 @@ sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
char *newname;
void *oldname;
- oldname = (void *)(uintptr_t)(const void *)oidp->oid_name;
len = strlen(name);
newname = malloc(len + 1, M_SYSCTLOID, M_WAITOK);
bcopy(name, newname, len + 1);
newname[len] = '\0';
+ SYSCTL_XLOCK();
+ oldname = (void *)(uintptr_t)(const void *)oidp->oid_name;
oidp->oid_name = newname;
+ SYSCTL_XUNLOCK();
free(oldname, M_SYSCTLOID);
}
@@ -443,15 +511,21 @@ sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent)
{
struct sysctl_oid *oidp;
- if (oid->oid_parent == parent)
+ SYSCTL_XLOCK();
+ if (oid->oid_parent == parent) {
+ SYSCTL_XUNLOCK();
return (0);
+ }
oidp = sysctl_find_oidname(oid->oid_name, parent);
- if (oidp != NULL)
+ if (oidp != NULL) {
+ SYSCTL_XUNLOCK();
return (EEXIST);
+ }
sysctl_unregister_oid(oid);
oid->oid_parent = parent;
oid->oid_number = OID_AUTO;
sysctl_register_oid(oid);
+ SYSCTL_XUNLOCK();
return (0);
}
@@ -466,8 +540,10 @@ sysctl_register_all(void *arg)
struct sysctl_oid **oidp;
SYSCTL_INIT();
+ SYSCTL_XLOCK();
SET_FOREACH(oidp, sysctl_set)
sysctl_register_oid(*oidp);
+ SYSCTL_XUNLOCK();
}
SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_all, 0);
@@ -497,6 +573,7 @@ sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
int k;
struct sysctl_oid *oidp;
+ SYSCTL_ASSERT_LOCKED();
SLIST_FOREACH(oidp, l, oid_link) {
for (k=0; k<i; k++)
@@ -555,6 +632,7 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
char buf[10];
+ SYSCTL_ASSERT_LOCKED();
while (namelen) {
if (!lsp) {
snprintf(buf,sizeof(buf),"%d",*name);
@@ -606,6 +684,7 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
{
struct sysctl_oid *oidp;
+ SYSCTL_ASSERT_LOCKED();
*len = level;
SLIST_FOREACH(oidp, lsp, oid_link) {
*next = oidp->oid_number;
@@ -686,6 +765,8 @@ name2oid (char *name, int *oid, int *len, struct sysctl_oid **oidpp)
struct sysctl_oid_list *lsp = &sysctl__children;
char *p;
+ SYSCTL_ASSERT_LOCKED();
+
if (!*name)
return (ENOENT);
@@ -742,6 +823,8 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
int error, oid[CTL_MAXNAME], len;
struct sysctl_oid *op = 0;
+ SYSCTL_ASSERT_LOCKED();
+
if (!req->newlen)
return (ENOENT);
if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */
@@ -768,8 +851,8 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
return (error);
}
-SYSCTL_PROC(_sysctl, 3, name2oid, CTLFLAG_RW|CTLFLAG_ANYBODY, 0, 0,
- sysctl_sysctl_name2oid, "I", "");
+SYSCTL_PROC(_sysctl, 3, name2oid, CTLFLAG_RW|CTLFLAG_ANYBODY|CTLFLAG_MPSAFE,
+ 0, 0, sysctl_sysctl_name2oid, "I", "");
static int
sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
@@ -791,7 +874,8 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
}
-static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD, sysctl_sysctl_oidfmt, "");
+static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE,
+ sysctl_sysctl_oidfmt, "");
static int
sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
@@ -1085,15 +1169,13 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
req.newfunc = sysctl_new_kernel;
req.lock = REQ_LOCKED;
- SYSCTL_LOCK();
-
+ SYSCTL_SLOCK();
error = sysctl_root(0, name, namelen, &req);
+ SYSCTL_SUNLOCK();
if (req.lock == REQ_WIRED && req.validlen > 0)
vsunlock(req.oldptr, req.validlen);
- SYSCTL_UNLOCK();
-
if (error && error != ENOMEM)
return (error);
@@ -1118,6 +1200,14 @@ kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
oid[1] = 3; /* name2oid */
oidlen = sizeof(oid);
+ /*
+ * XXX: Prone to a possible race condition between lookup and
+ * execution? Maybe put locking around it?
+ *
+ * Userland is just as racy, so I think the current implementation
+ * is fine.
+ */
+
error = kernel_sysctl(td, oid, 2, oid, &oidlen,
(void *)name, strlen(name), &plen, flags);
if (error)
@@ -1227,6 +1317,7 @@ sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
struct sysctl_oid *oid;
int indx;
+ SYSCTL_ASSERT_LOCKED();
oid = SLIST_FIRST(&sysctl__children);
indx = 0;
while (oid && indx < CTL_MAXNAME) {
@@ -1270,6 +1361,8 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
struct sysctl_oid *oid;
int error, indx, lvl;
+ SYSCTL_ASSERT_LOCKED();
+
error = sysctl_find_oid(arg1, arg2, &oid, &indx, req);
if (error)
return (error);
@@ -1324,7 +1417,11 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
if (error != 0)
return (error);
#endif
+ if (!(oid->oid_kind & CTLFLAG_MPSAFE))
+ mtx_lock(&Giant);
error = oid->oid_handler(oid, arg1, arg2, req);
+ if (!(oid->oid_kind & CTLFLAG_MPSAFE))
+ mtx_unlock(&Giant);
return (error);
}
@@ -1342,7 +1439,7 @@ struct sysctl_args {
int
__sysctl(struct thread *td, struct sysctl_args *uap)
{
- int error, name[CTL_MAXNAME];
+ int error, i, name[CTL_MAXNAME];
size_t j;
if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
@@ -1352,20 +1449,16 @@ __sysctl(struct thread *td, struct sysctl_args *uap)
if (error)
return (error);
- mtx_lock(&Giant);
-
error = userland_sysctl(td, name, uap->namelen,
uap->old, uap->oldlenp, 0,
uap->new, uap->newlen, &j, 0);
if (error && error != ENOMEM)
- goto done2;
+ return (error);
if (uap->oldlenp) {
- int i = copyout(&j, uap->oldlenp, sizeof(j));
+ i = copyout(&j, uap->oldlenp, sizeof(j));
if (i)
- error = i;
+ return (i);
}
-done2:
- mtx_unlock(&Giant);
return (error);
}
@@ -1414,7 +1507,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
req.newfunc = sysctl_new_user;
req.lock = REQ_LOCKED;
- SYSCTL_LOCK();
+ SYSCTL_XLOCK();
CURVNET_SET(TD_TO_VNET(curthread));
for (;;) {
@@ -1426,12 +1519,12 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
uio_yield();
}
+ CURVNET_RESTORE();
+ SYSCTL_XUNLOCK();
+
if (req.lock == REQ_WIRED && req.validlen > 0)
vsunlock(req.oldptr, req.validlen);
- CURVNET_RESTORE();
- SYSCTL_UNLOCK();
-
if (error && error != ENOMEM)
return (error);
@@ -1443,217 +1536,3 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
}
return (error);
}
-
-#ifdef COMPAT_43
-#include <sys/socket.h>
-#include <vm/vm_param.h>
-
-#define KINFO_PROC (0<<8)
-#define KINFO_RT (1<<8)
-#define KINFO_VNODE (2<<8)
-#define KINFO_FILE (3<<8)
-#define KINFO_METER (4<<8)
-#define KINFO_LOADAVG (5<<8)
-#define KINFO_CLOCKRATE (6<<8)
-
-/* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
-#define KINFO_BSDI_SYSINFO (101<<8)
-
-/*
- * XXX this is bloat, but I hope it's better here than on the potentially
- * limited kernel stack... -Peter
- */
-
-static struct {
- int bsdi_machine; /* "i386" on BSD/386 */
-/* ^^^ this is an offset to the string, relative to the struct start */
- char *pad0;
- long pad1;
- long pad2;
- long pad3;
- u_long pad4;
- u_long pad5;
- u_long pad6;
-
- int bsdi_ostype; /* "BSD/386" on BSD/386 */
- int bsdi_osrelease; /* "1.1" on BSD/386 */
- long pad7;
- long pad8;
- char *pad9;
-
- long pad10;
- long pad11;
- int pad12;
- long pad13;
- quad_t pad14;
- long pad15;
-
- struct timeval pad16;
- /* we dont set this, because BSDI's uname used gethostname() instead */
- int bsdi_hostname; /* hostname on BSD/386 */
-
- /* the actual string data is appended here */
-
-} bsdi_si;
-
-/*
- * this data is appended to the end of the bsdi_si structure during copyout.
- * The "char *" offsets are relative to the base of the bsdi_si struct.
- * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
- * should not exceed the length of the buffer here... (or else!! :-)
- */
-static char bsdi_strings[80]; /* It had better be less than this! */
-
-#ifndef _SYS_SYSPROTO_H_
-struct getkerninfo_args {
- int op;
- char *where;
- size_t *size;
- int arg;
-};
-#endif
-int
-ogetkerninfo(struct thread *td, struct getkerninfo_args *uap)
-{
- int error, name[6];
- size_t size;
- u_int needed = 0;
-
- mtx_lock(&Giant);
-
- switch (uap->op & 0xff00) {
-
- case KINFO_RT:
- name[0] = CTL_NET;
- name[1] = PF_ROUTE;
- name[2] = 0;
- name[3] = (uap->op & 0xff0000) >> 16;
- name[4] = uap->op & 0xff;
- name[5] = uap->arg;
- error = userland_sysctl(td, name, 6, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_VNODE:
- name[0] = CTL_KERN;
- name[1] = KERN_VNODE;
- error = userland_sysctl(td, name, 2, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_PROC:
- name[0] = CTL_KERN;
- name[1] = KERN_PROC;
- name[2] = uap->op & 0xff;
- name[3] = uap->arg;
- error = userland_sysctl(td, name, 4, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_FILE:
- name[0] = CTL_KERN;
- name[1] = KERN_FILE;
- error = userland_sysctl(td, name, 2, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_METER:
- name[0] = CTL_VM;
- name[1] = VM_TOTAL;
- error = userland_sysctl(td, name, 2, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_LOADAVG:
- name[0] = CTL_VM;
- name[1] = VM_LOADAVG;
- error = userland_sysctl(td, name, 2, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_CLOCKRATE:
- name[0] = CTL_KERN;
- name[1] = KERN_CLOCKRATE;
- error = userland_sysctl(td, name, 2, uap->where, uap->size,
- 0, 0, 0, &size, 0);
- break;
-
- case KINFO_BSDI_SYSINFO: {
- /*
- * this is pretty crude, but it's just enough for uname()
- * from BSDI's 1.x libc to work.
- *
- * *size gives the size of the buffer before the call, and
- * the amount of data copied after a successful call.
- * If successful, the return value is the amount of data
- * available, which can be larger than *size.
- *
- * BSDI's 2.x product apparently fails with ENOMEM if *size
- * is too small.
- */
-
- u_int left;
- char *s;
-
- bzero((char *)&bsdi_si, sizeof(bsdi_si));
- bzero(bsdi_strings, sizeof(bsdi_strings));
-
- s = bsdi_strings;
-
- bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
- strcpy(s, ostype);
- s += strlen(s) + 1;
-
- bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
- strcpy(s, osrelease);
- s += strlen(s) + 1;
-
- bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
- strcpy(s, machine);
- s += strlen(s) + 1;
-
- needed = sizeof(bsdi_si) + (s - bsdi_strings);
-
- if ((uap->where == NULL) || (uap->size == NULL)) {
- /* process is asking how much buffer to supply.. */
- size = needed;
- error = 0;
- break;
- }
-
- if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
- break;
-
- /* if too much buffer supplied, trim it down */
- if (size > needed)
- size = needed;
-
- /* how much of the buffer is remaining */
- left = size;
-
- if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
- break;
-
- /* is there any point in continuing? */
- if (left > sizeof(bsdi_si)) {
- left -= sizeof(bsdi_si);
- error = copyout(&bsdi_strings,
- uap->where + sizeof(bsdi_si), left);
- }
- break;
- }
-
- default:
- error = EOPNOTSUPP;
- break;
- }
- if (error == 0) {
- td->td_retval[0] = needed ? needed : size;
- if (uap->size) {
- error = copyout(&size, uap->size, sizeof(size));
- }
- }
- mtx_unlock(&Giant);
- return (error);
-}
-#endif /* COMPAT_43 */
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index bd754b1..7df03dc 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -37,6 +37,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_kdtrace.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -49,10 +51,19 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/sdt.h>
#include <sys/sleepqueue.h>
#include <sys/sysctl.h>
#include <sys/smp.h>
+SDT_PROVIDER_DEFINE(callout_execute);
+SDT_PROBE_DEFINE(callout_execute, kernel, , callout_start);
+SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_start, 0,
+ "struct callout *");
+SDT_PROBE_DEFINE(callout_execute, kernel, , callout_end);
+SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_end, 0,
+ "struct callout *");
+
static int avg_depth;
SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0,
"Average number of items examined per softclock call. Units = 1/1000");
@@ -395,7 +406,11 @@ softclock(void *arg)
binuptime(&bt1);
#endif
THREAD_NO_SLEEPING();
+ SDT_PROBE(callout_execute, kernel, ,
+ callout_start, c, 0, 0, 0, 0);
c_func(c_arg);
+ SDT_PROBE(callout_execute, kernel, ,
+ callout_end, c, 0, 0, 0, 0);
THREAD_SLEEPING_OK();
#ifdef DIAGNOSTIC
binuptime(&bt2);
@@ -414,6 +429,7 @@ softclock(void *arg)
lastfunc = c_func;
}
#endif
+ CTR1(KTR_CALLOUT, "callout %p finished", c);
if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0)
class->lc_unlock(c_lock);
skip:
diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c
index b894ae6..e60d05e 100644
--- a/sys/kern/kern_xxx.c
+++ b/sys/kern/kern_xxx.c
@@ -42,10 +42,12 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/utsname.h>
#include <sys/vimage.h>
+#include <vm/vm_param.h>
#if defined(COMPAT_43)
@@ -62,16 +64,12 @@ ogethostname(td, uap)
struct gethostname_args *uap;
{
int name[2];
- int error;
size_t len = uap->len;
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, uap->hostname, &len,
- 1, 0, 0, 0, 0);
- mtx_unlock(&Giant);
- return(error);
+ return (userland_sysctl(td, name, 2, uap->hostname, &len,
+ 1, 0, 0, 0, 0));
}
#ifndef _SYS_SYSPROTO_H_
@@ -87,15 +85,11 @@ osethostname(td, uap)
register struct sethostname_args *uap;
{
int name[2];
- int error;
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, 0, 0, 0, uap->hostname,
- uap->len, 0, 0);
- mtx_unlock(&Giant);
- return (error);
+ return (userland_sysctl(td, name, 2, 0, 0, 0, uap->hostname,
+ uap->len, 0, 0));
}
#ifndef _SYS_SYSPROTO_H_
@@ -146,6 +140,212 @@ oquota(td, uap)
return (ENOSYS);
}
+
+#define KINFO_PROC (0<<8)
+#define KINFO_RT (1<<8)
+#define KINFO_VNODE (2<<8)
+#define KINFO_FILE (3<<8)
+#define KINFO_METER (4<<8)
+#define KINFO_LOADAVG (5<<8)
+#define KINFO_CLOCKRATE (6<<8)
+
+/* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
+#define KINFO_BSDI_SYSINFO (101<<8)
+
+/*
+ * XXX this is bloat, but I hope it's better here than on the potentially
+ * limited kernel stack... -Peter
+ */
+
+static struct {
+ int bsdi_machine; /* "i386" on BSD/386 */
+/* ^^^ this is an offset to the string, relative to the struct start */
+ char *pad0;
+ long pad1;
+ long pad2;
+ long pad3;
+ u_long pad4;
+ u_long pad5;
+ u_long pad6;
+
+ int bsdi_ostype; /* "BSD/386" on BSD/386 */
+ int bsdi_osrelease; /* "1.1" on BSD/386 */
+ long pad7;
+ long pad8;
+ char *pad9;
+
+ long pad10;
+ long pad11;
+ int pad12;
+ long pad13;
+ quad_t pad14;
+ long pad15;
+
+ struct timeval pad16;
+ /* we dont set this, because BSDI's uname used gethostname() instead */
+ int bsdi_hostname; /* hostname on BSD/386 */
+
+ /* the actual string data is appended here */
+
+} bsdi_si;
+
+/*
+ * this data is appended to the end of the bsdi_si structure during copyout.
+ * The "char *" offsets are relative to the base of the bsdi_si struct.
+ * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
+ * should not exceed the length of the buffer here... (or else!! :-)
+ */
+static char bsdi_strings[80]; /* It had better be less than this! */
+
+#ifndef _SYS_SYSPROTO_H_
+struct getkerninfo_args {
+ int op;
+ char *where;
+ size_t *size;
+ int arg;
+};
+#endif
+int
+ogetkerninfo(struct thread *td, struct getkerninfo_args *uap)
+{
+ int error, name[6];
+ size_t size;
+ u_int needed = 0;
+
+ switch (uap->op & 0xff00) {
+
+ case KINFO_RT:
+ name[0] = CTL_NET;
+ name[1] = PF_ROUTE;
+ name[2] = 0;
+ name[3] = (uap->op & 0xff0000) >> 16;
+ name[4] = uap->op & 0xff;
+ name[5] = uap->arg;
+ error = userland_sysctl(td, name, 6, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_VNODE:
+ name[0] = CTL_KERN;
+ name[1] = KERN_VNODE;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_PROC:
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = uap->op & 0xff;
+ name[3] = uap->arg;
+ error = userland_sysctl(td, name, 4, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_FILE:
+ name[0] = CTL_KERN;
+ name[1] = KERN_FILE;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_METER:
+ name[0] = CTL_VM;
+ name[1] = VM_TOTAL;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_LOADAVG:
+ name[0] = CTL_VM;
+ name[1] = VM_LOADAVG;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_CLOCKRATE:
+ name[0] = CTL_KERN;
+ name[1] = KERN_CLOCKRATE;
+ error = userland_sysctl(td, name, 2, uap->where, uap->size,
+ 0, 0, 0, &size, 0);
+ break;
+
+ case KINFO_BSDI_SYSINFO: {
+ /*
+ * this is pretty crude, but it's just enough for uname()
+ * from BSDI's 1.x libc to work.
+ *
+ * *size gives the size of the buffer before the call, and
+ * the amount of data copied after a successful call.
+ * If successful, the return value is the amount of data
+ * available, which can be larger than *size.
+ *
+ * BSDI's 2.x product apparently fails with ENOMEM if *size
+ * is too small.
+ */
+
+ u_int left;
+ char *s;
+
+ bzero((char *)&bsdi_si, sizeof(bsdi_si));
+ bzero(bsdi_strings, sizeof(bsdi_strings));
+
+ s = bsdi_strings;
+
+ bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
+ strcpy(s, ostype);
+ s += strlen(s) + 1;
+
+ bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
+ strcpy(s, osrelease);
+ s += strlen(s) + 1;
+
+ bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
+ strcpy(s, machine);
+ s += strlen(s) + 1;
+
+ needed = sizeof(bsdi_si) + (s - bsdi_strings);
+
+ if ((uap->where == NULL) || (uap->size == NULL)) {
+ /* process is asking how much buffer to supply.. */
+ size = needed;
+ error = 0;
+ break;
+ }
+
+ if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
+ break;
+
+ /* if too much buffer supplied, trim it down */
+ if (size > needed)
+ size = needed;
+
+ /* how much of the buffer is remaining */
+ left = size;
+
+ if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
+ break;
+
+ /* is there any point in continuing? */
+ if (left > sizeof(bsdi_si)) {
+ left -= sizeof(bsdi_si);
+ error = copyout(&bsdi_strings,
+ uap->where + sizeof(bsdi_si), left);
+ }
+ break;
+ }
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ if (error == 0) {
+ td->td_retval[0] = needed ? needed : size;
+ if (uap->size) {
+ error = copyout(&size, uap->size, sizeof(size));
+ }
+ }
+ return (error);
+}
#endif /* COMPAT_43 */
#ifdef COMPAT_FREEBSD4
@@ -173,11 +373,10 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap)
name[0] = CTL_KERN;
name[1] = KERN_OSTYPE;
len = sizeof (uap->name->sysname);
- mtx_lock(&Giant);
error = userland_sysctl(td, name, 2, uap->name->sysname, &len,
1, 0, 0, 0, 0);
if (error)
- goto done2;
+ return (error);
subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0);
name[1] = KERN_HOSTNAME;
@@ -185,7 +384,7 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap)
error = userland_sysctl(td, name, 2, uap->name->nodename, &len,
1, 0, 0, 0, 0);
if (error)
- goto done2;
+ return (error);
subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0);
name[1] = KERN_OSRELEASE;
@@ -193,7 +392,7 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap)
error = userland_sysctl(td, name, 2, uap->name->release, &len,
1, 0, 0, 0, 0);
if (error)
- goto done2;
+ return (error);
subyte( uap->name->release + sizeof(uap->name->release) - 1, 0);
/*
@@ -202,7 +401,7 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap)
error = userland_sysctl(td, name, 2, uap->name->version, &len,
1, 0, 0, 0, 0);
if (error)
- goto done2;
+ return (error);
subyte( uap->name->version + sizeof(uap->name->version) - 1, 0);
*/
@@ -214,11 +413,11 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap)
for(us = uap->name->version; *s && *s != ':'; s++) {
error = subyte( us++, *s);
if (error)
- goto done2;
+ return (error);
}
error = subyte( us++, 0);
if (error)
- goto done2;
+ return (error);
name[0] = CTL_HW;
name[1] = HW_MACHINE;
@@ -226,11 +425,9 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap)
error = userland_sysctl(td, name, 2, uap->name->machine, &len,
1, 0, 0, 0, 0);
if (error)
- goto done2;
+ return (error);
subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0);
-done2:
- mtx_unlock(&Giant);
- return (error);
+ return (0);
}
#ifndef _SYS_SYSPROTO_H_
@@ -245,16 +442,12 @@ freebsd4_getdomainname(struct thread *td,
struct freebsd4_getdomainname_args *uap)
{
int name[2];
- int error;
size_t len = uap->len;
name[0] = CTL_KERN;
name[1] = KERN_NISDOMAINNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, uap->domainname, &len,
- 1, 0, 0, 0, 0);
- mtx_unlock(&Giant);
- return(error);
+ return (userland_sysctl(td, name, 2, uap->domainname, &len,
+ 1, 0, 0, 0, 0));
}
#ifndef _SYS_SYSPROTO_H_
@@ -269,14 +462,10 @@ freebsd4_setdomainname(struct thread *td,
struct freebsd4_setdomainname_args *uap)
{
int name[2];
- int error;
name[0] = CTL_KERN;
name[1] = KERN_NISDOMAINNAME;
- mtx_lock(&Giant);
- error = userland_sysctl(td, name, 2, 0, 0, 0, uap->domainname,
- uap->len, 0, 0);
- mtx_unlock(&Giant);
- return (error);
+ return (userland_sysctl(td, name, 2, 0, 0, 0, uap->domainname,
+ uap->len, 0, 0));
}
#endif /* COMPAT_FREEBSD4 */
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 88a5494..4fe1c14 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -82,6 +82,8 @@ dtrace_vtime_switch_func_t dtrace_vtime_switch_func;
#endif
#define NICE_WEIGHT 1 /* Priorities per nice level. */
+#define TS_NAME_LEN (MAXCOMLEN + sizeof(" td ") + sizeof(__XSTRING(UINT_MAX)))
+
/*
* The schedulable entity that runs a context.
* This is an extension to the thread structure and is tailored to
@@ -93,6 +95,9 @@ struct td_sched {
int ts_slptime; /* (j) Seconds !RUNNING. */
int ts_flags;
struct runq *ts_runq; /* runq the thread is currently on */
+#ifdef KTR
+ char ts_name[TS_NAME_LEN];
+#endif
};
/* flags kept in td_flags */
@@ -243,15 +248,17 @@ SYSCTL_INT(_kern_sched, OID_AUTO, followon, CTLFLAG_RW,
static __inline void
sched_load_add(void)
{
+
sched_tdcnt++;
- CTR1(KTR_SCHED, "global load: %d", sched_tdcnt);
+ KTR_COUNTER0(KTR_SCHED, "load", "global load", sched_tdcnt);
}
static __inline void
sched_load_rem(void)
{
+
sched_tdcnt--;
- CTR1(KTR_SCHED, "global load: %d", sched_tdcnt);
+ KTR_COUNTER0(KTR_SCHED, "load", "global load", sched_tdcnt);
}
/*
* Arrange to reschedule if necessary, taking the priorities and
@@ -705,8 +712,9 @@ void
sched_exit(struct proc *p, struct thread *td)
{
- CTR3(KTR_SCHED, "sched_exit: %p(%s) prio %d",
- td, td->td_name, td->td_priority);
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "proc exit",
+ "prio:td", td->td_priority);
+
PROC_LOCK_ASSERT(p, MA_OWNED);
sched_exit_thread(FIRST_THREAD_IN_PROC(p), td);
}
@@ -715,8 +723,8 @@ void
sched_exit_thread(struct thread *td, struct thread *child)
{
- CTR3(KTR_SCHED, "sched_exit_thread: %p(%s) prio %d",
- child, child->td_name, child->td_priority);
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(child), "exit",
+ "prio:td", child->td_priority);
thread_lock(td);
td->td_estcpu = ESTCPULIM(td->td_estcpu + child->td_estcpu);
thread_unlock(td);
@@ -773,10 +781,16 @@ sched_class(struct thread *td, int class)
static void
sched_priority(struct thread *td, u_char prio)
{
- CTR6(KTR_SCHED, "sched_prio: %p(%s) prio %d newprio %d by %p(%s)",
- td, td->td_name, td->td_priority, prio, curthread,
- curthread->td_name);
+
+ KTR_POINT3(KTR_SCHED, "thread", sched_tdname(td), "priority change",
+ "prio:%d", td->td_priority, "new prio:%d", prio, KTR_ATTR_LINKED,
+ sched_tdname(curthread));
+ if (td != curthread && prio > td->td_priority) {
+ KTR_POINT3(KTR_SCHED, "thread", sched_tdname(curthread),
+ "lend prio", "prio:%d", td->td_priority, "new prio:%d",
+ prio, KTR_ATTR_LINKED, sched_tdname(td));
+ }
THREAD_LOCK_ASSERT(td, MA_OWNED);
if (td->td_priority == prio)
return;
@@ -1205,9 +1219,13 @@ sched_add(struct thread *td, int flags)
("sched_add: bad thread state"));
KASSERT(td->td_flags & TDF_INMEM,
("sched_add: thread swapped out"));
- CTR5(KTR_SCHED, "sched_add: %p(%s) prio %d by %p(%s)",
- td, td->td_name, td->td_priority, curthread,
- curthread->td_name);
+
+ KTR_STATE2(KTR_SCHED, "thread", sched_tdname(td), "runq add",
+ "prio:%d", td->td_priority, KTR_ATTR_LINKED,
+ sched_tdname(curthread));
+ KTR_POINT1(KTR_SCHED, "thread", sched_tdname(curthread), "wokeup",
+ KTR_ATTR_LINKED, sched_tdname(td));
+
/*
* Now that the thread is moving to the run-queue, set the lock
@@ -1289,9 +1307,11 @@ sched_add(struct thread *td, int flags)
("sched_add: bad thread state"));
KASSERT(td->td_flags & TDF_INMEM,
("sched_add: thread swapped out"));
- CTR5(KTR_SCHED, "sched_add: %p(%s) prio %d by %p(%s)",
- td, td->td_name, td->td_priority, curthread,
- curthread->td_name);
+ KTR_STATE2(KTR_SCHED, "thread", sched_tdname(td), "runq add",
+ "prio:%d", td->td_priority, KTR_ATTR_LINKED,
+ sched_tdname(curthread));
+ KTR_POINT1(KTR_SCHED, "thread", sched_tdname(curthread), "wokeup",
+ KTR_ATTR_LINKED, sched_tdname(td));
/*
* Now that the thread is moving to the run-queue, set the lock
@@ -1336,9 +1356,9 @@ sched_rem(struct thread *td)
KASSERT(TD_ON_RUNQ(td),
("sched_rem: thread not on run queue"));
mtx_assert(&sched_lock, MA_OWNED);
- CTR5(KTR_SCHED, "sched_rem: %p(%s) prio %d by %p(%s)",
- td, td->td_name, td->td_priority, curthread,
- curthread->td_name);
+ KTR_STATE2(KTR_SCHED, "thread", sched_tdname(td), "runq rem",
+ "prio:%d", td->td_priority, KTR_ATTR_LINKED,
+ sched_tdname(curthread));
if ((td->td_proc->p_flag & P_NOLOAD) == 0)
sched_load_rem();
@@ -1570,6 +1590,22 @@ sched_fork_exit(struct thread *td)
THREAD_LOCK_ASSERT(td, MA_OWNED | MA_NOTRECURSED);
}
+char *
+sched_tdname(struct thread *td)
+{
+#ifdef KTR
+ struct td_sched *ts;
+
+ ts = td->td_sched;
+ if (ts->ts_name[0] == '\0')
+ snprintf(ts->ts_name, sizeof(ts->ts_name),
+ "%s tid %d", td->td_name, td->td_tid);
+ return (ts->ts_name);
+#else
+ return (td->td_name);
+#endif
+}
+
void
sched_affinity(struct thread *td)
{
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 2c2d906..96f7280 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -86,6 +86,10 @@ dtrace_vtime_switch_func_t dtrace_vtime_switch_func;
#define KTR_ULE 0
+#define TS_NAME_LEN (MAXCOMLEN + sizeof(" td ") + sizeof(__XSTRING(UINT_MAX)))
+#define TDQ_NAME_LEN (sizeof("sched lock ") + sizeof(__XSTRING(MAXCPU)))
+#define TDQ_LOADNAME_LEN (PCPU_NAME_LEN + sizeof(" load"))
+
/*
* Thread scheduler specific section. All fields are protected
* by the thread lock.
@@ -101,6 +105,9 @@ struct td_sched {
int ts_ltick; /* Last tick that we were running on */
int ts_ftick; /* First tick that we were running on */
int ts_ticks; /* Tick count */
+#ifdef KTR
+ char ts_name[TS_NAME_LEN];
+#endif
};
/* flags kept in ts_flags */
#define TSF_BOUND 0x0001 /* Thread can not migrate. */
@@ -216,7 +223,10 @@ struct tdq {
struct runq tdq_realtime; /* real-time run queue. */
struct runq tdq_timeshare; /* timeshare run queue. */
struct runq tdq_idle; /* Queue of IDLE threads. */
- char tdq_name[sizeof("sched lock") + 6];
+ char tdq_name[TDQ_NAME_LEN];
+#ifdef KTR
+ char tdq_loadname[TDQ_LOADNAME_LEN];
+#endif
} __aligned(64);
/* Idle thread states and config. */
@@ -489,7 +499,7 @@ tdq_load_add(struct tdq *tdq, struct thread *td)
tdq->tdq_load++;
if ((td->td_proc->p_flag & P_NOLOAD) == 0)
tdq->tdq_sysload++;
- CTR2(KTR_SCHED, "cpu %d load: %d", TDQ_ID(tdq), tdq->tdq_load);
+ KTR_COUNTER0(KTR_SCHED, "load", tdq->tdq_loadname, tdq->tdq_load);
}
/*
@@ -508,7 +518,7 @@ tdq_load_rem(struct tdq *tdq, struct thread *td)
tdq->tdq_load--;
if ((td->td_proc->p_flag & P_NOLOAD) == 0)
tdq->tdq_sysload--;
- CTR1(KTR_SCHED, "load: %d", tdq->tdq_load);
+ KTR_COUNTER0(KTR_SCHED, "load", tdq->tdq_loadname, tdq->tdq_load);
}
/*
@@ -1237,6 +1247,10 @@ tdq_setup(struct tdq *tdq)
"sched lock %d", (int)TDQ_ID(tdq));
mtx_init(&tdq->tdq_lock, tdq->tdq_name, "sched lock",
MTX_SPIN | MTX_RECURSE);
+#ifdef KTR
+ snprintf(tdq->tdq_loadname, sizeof(tdq->tdq_loadname),
+ "CPU %d load", (int)TDQ_ID(tdq));
+#endif
}
#ifdef SMP
@@ -1559,9 +1573,14 @@ sched_thread_priority(struct thread *td, u_char prio)
struct tdq *tdq;
int oldpri;
- CTR6(KTR_SCHED, "sched_prio: %p(%s) prio %d newprio %d by %p(%s)",
- td, td->td_name, td->td_priority, prio, curthread,
- curthread->td_name);
+ KTR_POINT3(KTR_SCHED, "thread", sched_tdname(td), "prio",
+ "prio:%d", td->td_priority, "new prio:%d", prio,
+ KTR_ATTR_LINKED, sched_tdname(curthread));
+ if (td != curthread && prio > td->td_priority) {
+ KTR_POINT3(KTR_SCHED, "thread", sched_tdname(curthread),
+ "lend prio", "prio:%d", td->td_priority, "new prio:%d",
+ prio, KTR_ATTR_LINKED, sched_tdname(td));
+ }
ts = td->td_sched;
THREAD_LOCK_ASSERT(td, MA_OWNED);
if (td->td_priority == prio)
@@ -1990,6 +2009,9 @@ sched_fork_thread(struct thread *td, struct thread *child)
ts2->ts_slptime = ts->ts_slptime;
ts2->ts_runtime = ts->ts_runtime;
ts2->ts_slice = 1; /* Attempt to quickly learn interactivity. */
+#ifdef KTR
+ bzero(ts2->ts_name, sizeof(ts2->ts_name));
+#endif
}
/*
@@ -2012,10 +2034,9 @@ void
sched_exit(struct proc *p, struct thread *child)
{
struct thread *td;
-
- CTR3(KTR_SCHED, "sched_exit: %p(%s) prio %d",
- child, child->td_name, child->td_priority);
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(child), "proc exit",
+ "prio:td", child->td_priority);
PROC_LOCK_ASSERT(p, MA_OWNED);
td = FIRST_THREAD_IN_PROC(p);
sched_exit_thread(td, child);
@@ -2031,9 +2052,8 @@ void
sched_exit_thread(struct thread *td, struct thread *child)
{
- CTR3(KTR_SCHED, "sched_exit_thread: %p(%s) prio %d",
- child, child->td_name, child->td_priority);
-
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(child), "thread exit",
+ "prio:td", child->td_priority);
/*
* Give the child's runtime to the parent without returning the
* sleep time as a penalty to the parent. This causes shells that
@@ -2291,9 +2311,12 @@ sched_add(struct thread *td, int flags)
#ifdef SMP
int cpu;
#endif
- CTR5(KTR_SCHED, "sched_add: %p(%s) prio %d by %p(%s)",
- td, td->td_name, td->td_priority, curthread,
- curthread->td_name);
+
+ KTR_STATE2(KTR_SCHED, "thread", sched_tdname(td), "runq add",
+ "prio:%d", td->td_priority, KTR_ATTR_LINKED,
+ sched_tdname(curthread));
+ KTR_POINT1(KTR_SCHED, "thread", sched_tdname(curthread), "wokeup",
+ KTR_ATTR_LINKED, sched_tdname(td));
THREAD_LOCK_ASSERT(td, MA_OWNED);
/*
* Recalculate the priority before we select the target cpu or
@@ -2337,9 +2360,8 @@ sched_rem(struct thread *td)
{
struct tdq *tdq;
- CTR5(KTR_SCHED, "sched_rem: %p(%s) prio %d by %p(%s)",
- td, td->td_name, td->td_priority, curthread,
- curthread->td_name);
+ KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "runq rem",
+ "prio:%d", td->td_priority);
tdq = TDQ_CPU(td->td_sched->ts_cpu);
TDQ_LOCK_ASSERT(tdq, MA_OWNED);
MPASS(td->td_lock == TDQ_LOCKPTR(tdq));
@@ -2605,6 +2627,25 @@ sched_fork_exit(struct thread *td)
&TDQ_LOCKPTR(tdq)->lock_object, 0, 0, __FILE__, __LINE__);
}
+/*
+ * Create on first use to catch odd startup conditons.
+ */
+char *
+sched_tdname(struct thread *td)
+{
+#ifdef KTR
+ struct td_sched *ts;
+
+ ts = td->td_sched;
+ if (ts->ts_name[0] == '\0')
+ snprintf(ts->ts_name, sizeof(ts->ts_name),
+ "%s tid %d", td->td_name, td->td_tid);
+ return (ts->ts_name);
+#else
+ return (td->td_name);
+#endif
+}
+
#ifdef SMP
/*
diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c
index 75a97b2..12c69ce 100644
--- a/sys/kern/subr_autoconf.c
+++ b/sys/kern/subr_autoconf.c
@@ -91,8 +91,7 @@ run_interrupt_driven_config_hooks_warning(int warned)
}
static void
-run_interrupt_driven_config_hooks(dummy)
- void *dummy;
+run_interrupt_driven_config_hooks(void *dummy)
{
struct intr_config_hook *hook_entry, *next_entry;
int warned;
@@ -127,8 +126,7 @@ SYSINIT(intr_config_hooks, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_FIRST,
* be used to complete initialization.
*/
int
-config_intrhook_establish(hook)
- struct intr_config_hook *hook;
+config_intrhook_establish(struct intr_config_hook *hook)
{
struct intr_config_hook *hook_entry;
@@ -151,8 +149,7 @@ config_intrhook_establish(hook)
}
void
-config_intrhook_disestablish(hook)
- struct intr_config_hook *hook;
+config_intrhook_disestablish(struct intr_config_hook *hook)
{
struct intr_config_hook *hook_entry;
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 10fc81a..a74bb51 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -741,10 +741,10 @@ sysctl_devctl_disable(SYSCTL_HANDLER_ARGS)
/* End of /dev/devctl code */
-TAILQ_HEAD(,device) bus_data_devices;
+static TAILQ_HEAD(,device) bus_data_devices;
static int bus_data_generation = 1;
-kobj_method_t null_methods[] = {
+static kobj_method_t null_methods[] = {
{ 0, 0 }
};
@@ -1735,7 +1735,7 @@ device_probe_child(device_t dev, device_t child)
driverlink_t best = NULL;
driverlink_t dl;
int result, pri = 0;
- int hasclass = (child->devclass != 0);
+ int hasclass = (child->devclass != NULL);
GIANT_REQUIRED;
@@ -2014,7 +2014,7 @@ device_print_prettyname(device_t dev)
{
const char *name = device_get_name(dev);
- if (name == 0)
+ if (name == NULL)
return (printf("unknown: "));
return (printf("%s%d: ", name, device_get_unit(dev)));
}
@@ -3842,7 +3842,7 @@ root_bus_module_handler(module_t mod, int what, void* arg)
static moduledata_t root_bus_mod = {
"rootbus",
root_bus_module_handler,
- 0
+ NULL
};
DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
diff --git a/sys/kern/subr_clist.c b/sys/kern/subr_clist.c
index 65a03b8..524f2c0 100644
--- a/sys/kern/subr_clist.c
+++ b/sys/kern/subr_clist.c
@@ -38,58 +38,15 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/clist.h>
-static void clist_init(void *);
-SYSINIT(clist, SI_SUB_CLIST, SI_ORDER_FIRST, clist_init, NULL);
-
static MALLOC_DEFINE(M_CLIST, "clist", "clist queue blocks");
-static struct cblock *cfreelist = 0;
-int cfreecount = 0;
-static int cslushcount;
-static int ctotcount;
-
-#ifndef INITIAL_CBLOCKS
-#define INITIAL_CBLOCKS 50
-#endif
+static struct cblock *cfreelist = NULL;
static struct cblock *cblock_alloc(void);
static void cblock_alloc_cblocks(int number);
static void cblock_free(struct cblock *cblockp);
static void cblock_free_cblocks(int number);
-#include "opt_ddb.h"
-#ifdef DDB
-#include <ddb/ddb.h>
-
-DB_SHOW_COMMAND(cbstat, cbstat)
-{
- int cbsize = CBSIZE;
-
- printf(
- "tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n",
- ctotcount * cbsize, ctotcount * cbsize - cfreecount, cfreecount,
- cfreecount - cslushcount * cbsize, cslushcount * cbsize);
-}
-#endif /* DDB */
-
-/*
- * Called from init_main.c
- */
-/* ARGSUSED*/
-static void
-clist_init(void *dummy)
-{
- /*
- * Allocate an initial base set of cblocks as a 'slush'.
- * We allocate non-slush cblocks with each initial tty_open() and
- * deallocate them with each tty_close().
- * We should adjust the slush allocation. This can't be done in
- * the i/o routines because they are sometimes called from
- * interrupt handlers when it may be unsafe to call malloc().
- */
- cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS);
-}
-
/*
* Remove a cblock from the cfreelist queue and return a pointer
* to it.
@@ -104,7 +61,6 @@ cblock_alloc(void)
panic("clist reservation botch");
cfreelist = cblockp->c_next;
cblockp->c_next = NULL;
- cfreecount -= CBSIZE;
return (cblockp);
}
@@ -116,7 +72,6 @@ cblock_free(struct cblock *cblockp)
{
cblockp->c_next = cfreelist;
cfreelist = cblockp;
- cfreecount += CBSIZE;
}
/*
@@ -129,19 +84,13 @@ cblock_alloc_cblocks(int number)
struct cblock *cbp;
for (i = 0; i < number; ++i) {
- cbp = malloc(sizeof *cbp, M_CLIST, M_NOWAIT);
- if (cbp == NULL) {
- printf(
-"cblock_alloc_cblocks: M_NOWAIT malloc failed, trying M_WAITOK\n");
- cbp = malloc(sizeof *cbp, M_CLIST, M_WAITOK);
- }
+ cbp = malloc(sizeof *cbp, M_CLIST, M_WAITOK);
/*
* Freed cblocks have zero quotes and garbage elsewhere.
* Set the may-have-quote bit to force zeroing the quotes.
*/
cblock_free(cbp);
}
- ctotcount += number;
}
/*
@@ -184,7 +133,6 @@ cblock_free_cblocks(int number)
for (i = 0; i < number; ++i)
free(cblock_alloc(), M_CLIST);
- ctotcount -= number;
}
/*
@@ -237,8 +185,7 @@ getc(struct clist *clistp)
clistp->c_cf = clistp->c_cl = NULL;
}
cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
+ --clistp->c_cbcount;
}
}
@@ -285,8 +232,7 @@ q_to_b(struct clist *clistp, char *dest, int amount)
clistp->c_cf = clistp->c_cl = NULL;
}
cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
+ --clistp->c_cbcount;
}
}
@@ -328,8 +274,7 @@ ndflush(struct clist *clistp, int amount)
clistp->c_cf = clistp->c_cl = NULL;
}
cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
+ --clistp->c_cbcount;
}
}
@@ -364,12 +309,8 @@ putc(char chr, struct clist *clistp)
struct cblock *prev = (cblockp - 1);
if (clistp->c_cbcount >= clistp->c_cbreserved) {
- if (clistp->c_cbcount >= clistp->c_cbmax
- || cslushcount <= 0) {
- splx(s);
- return (-1);
- }
- --cslushcount;
+ splx(s);
+ return (-1);
}
cblockp = cblock_alloc();
clistp->c_cbcount++;
@@ -430,12 +371,8 @@ b_to_q(char *src, int amount, struct clist *clistp)
struct cblock *prev = cblockp - 1;
if (clistp->c_cbcount >= clistp->c_cbreserved) {
- if (clistp->c_cbcount >= clistp->c_cbmax
- || cslushcount <= 0) {
- splx(s);
- return (amount);
- }
- --cslushcount;
+ splx(s);
+ return (amount);
}
cblockp = cblock_alloc();
clistp->c_cbcount++;
@@ -478,7 +415,7 @@ b_to_q(char *src, int amount, struct clist *clistp)
int
unputc(struct clist *clistp)
{
- struct cblock *cblockp = 0, *cbp = 0;
+ struct cblock *cblockp = NULL, *cbp = NULL;
int s;
int chr = -1;
@@ -510,8 +447,7 @@ unputc(struct clist *clistp)
*/
clistp->c_cl = (char *)(cbp+1);
cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
+ --clistp->c_cbcount;
cbp->c_next = NULL;
}
}
@@ -523,8 +459,7 @@ unputc(struct clist *clistp)
if ((clistp->c_cc == 0) && clistp->c_cl) {
cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
cblock_free(cblockp);
- if (--clistp->c_cbcount >= clistp->c_cbreserved)
- ++cslushcount;
+ --clistp->c_cbcount;
clistp->c_cf = clistp->c_cl = NULL;
}
diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c
index 8a7eff5..bbfed44 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -407,10 +407,10 @@ sysctl_devstat(SYSCTL_HANDLER_ARGS)
* Sysctl entries for devstat. The first one is a node that all the rest
* hang off of.
*/
-SYSCTL_NODE(_kern, OID_AUTO, devstat, CTLFLAG_RD, 0, "Device Statistics");
+SYSCTL_NODE(_kern, OID_AUTO, devstat, CTLFLAG_RD, NULL, "Device Statistics");
SYSCTL_PROC(_kern_devstat, OID_AUTO, all, CTLFLAG_RD|CTLTYPE_OPAQUE,
- 0, 0, sysctl_devstat, "S,devstat", "All devices in the devstat list");
+ NULL, 0, sysctl_devstat, "S,devstat", "All devices in the devstat list");
/*
* Export the number of devices in the system so that userland utilities
* can determine how much memory to allocate to hold all the devices.
@@ -534,4 +534,4 @@ devstat_free(struct devstat *dsp)
}
SYSCTL_INT(_debug_sizeof, OID_AUTO, devstat, CTLFLAG_RD,
- 0, sizeof(struct devstat), "sizeof(struct devstat)");
+ NULL, sizeof(struct devstat), "sizeof(struct devstat)");
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index c8ed9ce..b32d1e8 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -144,9 +144,7 @@ bioq_takefirst(struct bio_queue_head *head)
* This implements the one-way scan which optimizes disk seek times.
*/
void
-bioq_disksort(bioq, bp)
- struct bio_queue_head *bioq;
- struct bio *bp;
+bioq_disksort(struct bio_queue_head *bioq, struct bio *bp)
{
struct bio *bq;
struct bio *bn;
diff --git a/sys/kern/subr_firmware.c b/sys/kern/subr_firmware.c
index 24b829e..6a36c24 100644
--- a/sys/kern/subr_firmware.c
+++ b/sys/kern/subr_firmware.c
@@ -525,7 +525,7 @@ firmware_modevent(module_t mod, int type, void *unused)
static moduledata_t firmware_mod = {
"firmware",
firmware_modevent,
- 0
+ NULL
};
DECLARE_MODULE(firmware, firmware_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
MODULE_VERSION(firmware, 1);
diff --git a/sys/kern/subr_kobj.c b/sys/kern/subr_kobj.c
index bc36667..03bf35f 100644
--- a/sys/kern/subr_kobj.c
+++ b/sys/kern/subr_kobj.c
@@ -207,7 +207,7 @@ kobj_lookup_method_class(kobj_class_t cls, kobjop_desc_t desc)
}
}
- return 0;
+ return NULL;
}
static kobj_method_t*
@@ -230,7 +230,7 @@ kobj_lookup_method_mi(kobj_class_t cls,
}
}
- return 0;
+ return NULL;
}
kobj_method_t*
@@ -261,7 +261,7 @@ kobj_class_free(kobj_class_t cls)
{
int i;
kobj_method_t *m;
- void* ops = 0;
+ void* ops = NULL;
KOBJ_ASSERT(MA_NOTOWNED);
KOBJ_LOCK();
@@ -281,7 +281,7 @@ kobj_class_free(kobj_class_t cls)
* Free memory and clean up.
*/
ops = cls->ops;
- cls->ops = 0;
+ cls->ops = NULL;
}
KOBJ_UNLOCK();
@@ -302,7 +302,7 @@ kobj_create(kobj_class_t cls,
*/
obj = malloc(cls->size, mtype, mflags | M_ZERO);
if (!obj)
- return 0;
+ return NULL;
kobj_init(obj, cls);
return obj;
@@ -355,7 +355,7 @@ kobj_delete(kobj_t obj, struct malloc_type *mtype)
if (!refs)
kobj_class_free(cls);
- obj->ops = 0;
+ obj->ops = NULL;
if (mtype)
free(obj, mtype);
}
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
index 67fe14d..f626ddb 100644
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -73,7 +73,9 @@ __FBSDID("$FreeBSD$");
#define MAXFILES (maxproc * 2)
#endif
-enum VM_GUEST { VM_GUEST_NO, VM_GUEST_VM, VM_GUEST_XEN };
+/* Values of enum VM_GUEST members are used as indices in
+ * vm_guest_sysctl_names */
+enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS);
diff --git a/sys/kern/subr_pcpu.c b/sys/kern/subr_pcpu.c
index e9fb8d0d..ea25aa7 100644
--- a/sys/kern/subr_pcpu.c
+++ b/sys/kern/subr_pcpu.c
@@ -76,6 +76,9 @@ pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
cpu_pcpu_init(pcpu, cpuid, size);
pcpu->pc_rm_queue.rmq_next = &pcpu->pc_rm_queue;
pcpu->pc_rm_queue.rmq_prev = &pcpu->pc_rm_queue;
+#ifdef KTR
+ snprintf(pcpu->pc_name, sizeof(pcpu->pc_name), "CPU %d", cpuid);
+#endif
}
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 0057d9a..0598f49 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -959,7 +959,7 @@ sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
}
SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD,
- 0, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
+ NULL, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
static int msgbuf_clearflag;
diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c
index 5a70482..be98d44 100644
--- a/sys/kern/subr_prof.c
+++ b/sys/kern/subr_prof.c
@@ -404,9 +404,7 @@ struct profil_args {
#endif
/* ARGSUSED */
int
-profil(td, uap)
- struct thread *td;
- register struct profil_args *uap;
+profil(struct thread *td, struct profil_args *uap)
{
struct uprof *upp;
struct proc *p;
diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c
index ac1644c..8730a5b 100644
--- a/sys/kern/subr_rman.c
+++ b/sys/kern/subr_rman.c
@@ -99,7 +99,7 @@ struct resource_i {
int r_rid; /* optional rid for this resource. */
};
-int rman_debug = 0;
+static int rman_debug = 0;
TUNABLE_INT("debug.rman_debug", &rman_debug);
SYSCTL_INT(_debug, OID_AUTO, rman_debug, CTLFLAG_RW,
&rman_debug, 0, "rman debug");
diff --git a/sys/kern/subr_rtc.c b/sys/kern/subr_rtc.c
index 1ec10fa..0f3ec17 100644
--- a/sys/kern/subr_rtc.c
+++ b/sys/kern/subr_rtc.c
@@ -154,7 +154,7 @@ inittodr(time_t base)
* Write system time back to RTC
*/
void
-resettodr()
+resettodr(void)
{
struct timespec ts;
int error;
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index b7fbbd1..14d1297 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -115,7 +115,7 @@ static volatile int smp_rv_ncpus;
static void (*volatile smp_rv_setup_func)(void *arg);
static void (*volatile smp_rv_action_func)(void *arg);
static void (*volatile smp_rv_teardown_func)(void *arg);
-static void * volatile smp_rv_func_arg;
+static void *volatile smp_rv_func_arg;
static volatile int smp_rv_waiters[3];
/*
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index 050d713..9059a15 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -114,7 +114,7 @@ _taskqueue_create(const char *name, int mflags,
queue = malloc(sizeof(struct taskqueue), M_TASKQUEUE, mflags | M_ZERO);
if (!queue)
- return 0;
+ return NULL;
STAILQ_INIT(&queue->tq_queue);
queue->tq_name = name;
@@ -213,7 +213,7 @@ taskqueue_enqueue(struct taskqueue *queue, struct task *task)
if (!prev || prev->ta_priority >= task->ta_priority) {
STAILQ_INSERT_TAIL(&queue->tq_queue, task, ta_link);
} else {
- prev = 0;
+ prev = NULL;
for (ins = STAILQ_FIRST(&queue->tq_queue); ins;
prev = ins, ins = STAILQ_NEXT(ins, ta_link))
if (ins->ta_priority < task->ta_priority)
@@ -423,11 +423,11 @@ taskqueue_thread_enqueue(void *context)
wakeup_one(tq);
}
-TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0,
+TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, NULL,
swi_add(NULL, "task queue", taskqueue_swi_run, NULL, SWI_TQ,
INTR_MPSAFE, &taskqueue_ih));
-TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, 0,
+TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, NULL,
swi_add(NULL, "Giant taskq", taskqueue_swi_giant_run,
NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih));
@@ -462,6 +462,6 @@ taskqueue_fast_run(void *dummy)
taskqueue_run(taskqueue_fast);
}
-TASKQUEUE_FAST_DEFINE(fast, taskqueue_fast_enqueue, 0,
+TASKQUEUE_FAST_DEFINE(fast, taskqueue_fast_enqueue, NULL,
swi_add(NULL, "Fast task queue", taskqueue_fast_run, NULL,
SWI_TQ_FAST, INTR_MPSAFE, &taskqueue_fast_ih));
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index ce6aad1..3fba3fb 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -127,6 +127,7 @@ __FBSDID("$FreeBSD$");
#define LI_RECURSEMASK 0x0000ffff /* Recursion depth of lock instance. */
#define LI_EXCLUSIVE 0x00010000 /* Exclusive lock instance. */
+#define LI_NORELEASE 0x00020000 /* Lock not allowed to be released. */
/* Define this to check for blessed mutexes */
#undef BLESSING
@@ -234,8 +235,8 @@ struct witness {
uint16_t w_num_descendants; /* direct/indirect
* descendant count */
int16_t w_ddb_level;
- int w_displayed:1;
- int w_reversed:1;
+ unsigned w_displayed:1;
+ unsigned w_reversed:1;
};
STAILQ_HEAD(witness_list, witness);
@@ -367,6 +368,7 @@ static struct witness_lock_order_data *witness_lock_order_get(
struct witness *parent,
struct witness *child);
static void witness_list_lock(struct lock_instance *instance);
+static void witness_setflag(struct lock_object *lock, int flag, int set);
#ifdef KDB
#define witness_debugger(c) _witness_debugger(c, __func__)
@@ -374,7 +376,7 @@ static void witness_list_lock(struct lock_instance *instance);
#define witness_debugger(c)
#endif
-SYSCTL_NODE(_debug, OID_AUTO, witness, CTLFLAG_RW, 0, "Witness Locking");
+SYSCTL_NODE(_debug, OID_AUTO, witness, CTLFLAG_RW, NULL, "Witness Locking");
/*
* If set to 0, lock order checking is disabled. If set to -1,
@@ -1509,6 +1511,11 @@ found:
instance->li_line);
panic("share->uexcl");
}
+ if ((instance->li_flags & LI_NORELEASE) != 0 && witness_watch > 0) {
+ printf("forbidden unlock of (%s) %s @ %s:%d\n", class->lc_name,
+ lock->lo_name, file, line);
+ panic("lock marked norelease");
+ }
/* If we are recursed, unrecurse. */
if ((instance->li_flags & LI_RECURSEMASK) > 0) {
@@ -2224,6 +2231,48 @@ witness_assert(struct lock_object *lock, int flags, const char *file, int line)
#endif /* INVARIANT_SUPPORT */
}
+static void
+witness_setflag(struct lock_object *lock, int flag, int set)
+{
+ struct lock_list_entry *lock_list;
+ struct lock_instance *instance;
+ struct lock_class *class;
+
+ if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
+ return;
+ class = LOCK_CLASS(lock);
+ if (class->lc_flags & LC_SLEEPLOCK)
+ lock_list = curthread->td_sleeplocks;
+ else {
+ if (witness_skipspin)
+ return;
+ lock_list = PCPU_GET(spinlocks);
+ }
+ instance = find_instance(lock_list, lock);
+ if (instance == NULL)
+ panic("%s: lock (%s) %s not locked", __func__,
+ class->lc_name, lock->lo_name);
+
+ if (set)
+ instance->li_flags |= flag;
+ else
+ instance->li_flags &= ~flag;
+}
+
+void
+witness_norelease(struct lock_object *lock)
+{
+
+ witness_setflag(lock, LI_NORELEASE, 1);
+}
+
+void
+witness_releaseok(struct lock_object *lock)
+{
+
+ witness_setflag(lock, LI_NORELEASE, 0);
+}
+
#ifdef DDB
static void
witness_ddb_list(struct thread *td)
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 03901fc..3209610 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -886,6 +886,71 @@ done:
return (error);
}
+/*
+ * Convert a select bit set to poll flags.
+ *
+ * The backend always returns POLLHUP/POLLERR if appropriate and we
+ * return this as a set bit in any set.
+ */
+static int select_flags[3] = {
+ POLLRDNORM | POLLHUP | POLLERR,
+ POLLWRNORM | POLLHUP | POLLERR,
+ POLLRDBAND | POLLHUP | POLLERR
+};
+
+/*
+ * Compute the fo_poll flags required for a fd given by the index and
+ * bit position in the fd_mask array.
+ */
+static __inline int
+selflags(fd_mask **ibits, int idx, fd_mask bit)
+{
+ int flags;
+ int msk;
+
+ flags = 0;
+ for (msk = 0; msk < 3; msk++) {
+ if (ibits[msk] == NULL)
+ continue;
+ if ((ibits[msk][idx] & bit) == 0)
+ continue;
+ flags |= select_flags[msk];
+ }
+ return (flags);
+}
+
+/*
+ * Set the appropriate output bits given a mask of fired events and the
+ * input bits originally requested.
+ */
+static __inline int
+selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
+{
+ int msk;
+ int n;
+
+ n = 0;
+ for (msk = 0; msk < 3; msk++) {
+ if ((events & select_flags[msk]) == 0)
+ continue;
+ if (ibits[msk] == NULL)
+ continue;
+ if ((ibits[msk][idx] & bit) == 0)
+ continue;
+ /*
+ * XXX Check for a duplicate set. This can occur because a
+ * socket calls selrecord() twice for each poll() call
+ * resulting in two selfds per real fd. selrescan() will
+ * call selsetbits twice as a result.
+ */
+ if ((obits[msk][idx] & bit) != 0)
+ continue;
+ obits[msk][idx] |= bit;
+ n++;
+ }
+
+ return (n);
+}
/*
* Traverse the list of fds attached to this thread's seltd and check for
@@ -894,18 +959,18 @@ done:
static int
selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
{
+ struct filedesc *fdp;
+ struct selinfo *si;
struct seltd *stp;
struct selfd *sfp;
struct selfd *sfn;
- struct selinfo *si;
struct file *fp;
- int msk, fd;
- int n = 0;
- /* Note: backend also returns POLLHUP/POLLERR if appropriate. */
- static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND };
- struct filedesc *fdp = td->td_proc->p_fd;
+ fd_mask bit;
+ int fd, ev, n, idx;
+ fdp = td->td_proc->p_fd;
stp = td->td_sel;
+ n = 0;
FILEDESC_SLOCK(fdp);
STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) {
fd = (int)(uintptr_t)sfp->sf_cookie;
@@ -918,18 +983,11 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
FILEDESC_SUNLOCK(fdp);
return (EBADF);
}
- for (msk = 0; msk < 3; msk++) {
- if (ibits[msk] == NULL)
- continue;
- if ((ibits[msk][fd/NFDBITS] &
- ((fd_mask) 1 << (fd % NFDBITS))) == 0)
- continue;
- if (fo_poll(fp, flag[msk], td->td_ucred, td)) {
- obits[msk][(fd)/NFDBITS] |=
- ((fd_mask)1 << ((fd) % NFDBITS));
- n++;
- }
- }
+ idx = fd / NFDBITS;
+ bit = (fd_mask)1 << (fd % NFDBITS);
+ ev = fo_poll(fp, selflags(ibits, idx, bit), td->td_ucred, td);
+ if (ev != 0)
+ n += selsetbits(ibits, obits, idx, bit, ev);
}
FILEDESC_SUNLOCK(fdp);
stp->st_flags = 0;
@@ -947,38 +1005,33 @@ selscan(td, ibits, obits, nfd)
fd_mask **ibits, **obits;
int nfd;
{
- int msk, i, fd;
- fd_mask bits;
+ struct filedesc *fdp;
struct file *fp;
- int n = 0;
- /* Note: backend also returns POLLHUP/POLLERR if appropriate. */
- static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND };
- struct filedesc *fdp = td->td_proc->p_fd;
+ fd_mask bit;
+ int ev, flags, end, fd;
+ int n, idx;
+ fdp = td->td_proc->p_fd;
+ n = 0;
FILEDESC_SLOCK(fdp);
- for (msk = 0; msk < 3; msk++) {
- if (ibits[msk] == NULL)
- continue;
- for (i = 0; i < nfd; i += NFDBITS) {
- bits = ibits[msk][i/NFDBITS];
- /* ffs(int mask) not portable, fd_mask is long */
- for (fd = i; bits && fd < nfd; fd++, bits >>= 1) {
- if (!(bits & 1))
- continue;
- if ((fp = fget_locked(fdp, fd)) == NULL) {
- FILEDESC_SUNLOCK(fdp);
- return (EBADF);
- }
- selfdalloc(td, (void *)(uintptr_t)fd);
- if (fo_poll(fp, flag[msk], td->td_ucred,
- td)) {
- obits[msk][(fd)/NFDBITS] |=
- ((fd_mask)1 << ((fd) % NFDBITS));
- n++;
- }
+ for (idx = 0, fd = 0; fd < nfd; idx++) {
+ end = imin(fd + NFDBITS, nfd);
+ for (bit = 1; fd < end; bit <<= 1, fd++) {
+ /* Compute the list of events we're interested in. */
+ flags = selflags(ibits, idx, bit);
+ if (flags == 0)
+ continue;
+ if ((fp = fget_locked(fdp, fd)) == NULL) {
+ FILEDESC_SUNLOCK(fdp);
+ return (EBADF);
}
+ selfdalloc(td, (void *)(uintptr_t)fd);
+ ev = fo_poll(fp, flags, td->td_ucred, td);
+ if (ev != 0)
+ n += selsetbits(ibits, obits, idx, bit, ev);
}
}
+
FILEDESC_SUNLOCK(fdp);
td->td_retval[0] = n;
return (0);
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index 80d07ba..0112a04 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -88,7 +88,7 @@ int semop(struct thread *td, struct semop_args *uap);
static struct sem_undo *semu_alloc(struct thread *td);
static int semundo_adjust(struct thread *td, struct sem_undo **supptr,
- int semid, int semnum, int adjval);
+ int semid, int semseq, int semnum, int adjval);
static void semundo_clear(int semid, int semnum);
/* XXX casting to (sy_call_t *) is bogus, as usual. */
@@ -98,15 +98,17 @@ static sy_call_t *semcalls[] = {
};
static struct mtx sem_mtx; /* semaphore global lock */
+static struct mtx sem_undo_mtx;
static int semtot = 0;
static struct semid_kernel *sema; /* semaphore id pool */
static struct mtx *sema_mtx; /* semaphore id pool mutexes*/
static struct sem *sem; /* semaphore pool */
-SLIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */
+LIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */
+LIST_HEAD(, sem_undo) semu_free_list; /* list of free undo structures */
static int *semu; /* undo structure pool */
static eventhandler_tag semexit_tag;
-#define SEMUNDO_MTX sem_mtx
+#define SEMUNDO_MTX sem_undo_mtx
#define SEMUNDO_LOCK() mtx_lock(&SEMUNDO_MTX);
#define SEMUNDO_UNLOCK() mtx_unlock(&SEMUNDO_MTX);
#define SEMUNDO_LOCKASSERT(how) mtx_assert(&SEMUNDO_MTX, (how));
@@ -122,13 +124,14 @@ struct sem {
* Undo structure (one per process)
*/
struct sem_undo {
- SLIST_ENTRY(sem_undo) un_next; /* ptr to next active undo structure */
+ LIST_ENTRY(sem_undo) un_next; /* ptr to next active undo structure */
struct proc *un_proc; /* owner of this structure */
short un_cnt; /* # of active entries */
struct undo {
short un_adjval; /* adjust on exit values */
short un_num; /* semaphore # */
int un_id; /* semid */
+ unsigned short un_seq;
} un_ent[1]; /* undo entries */
};
@@ -250,12 +253,15 @@ seminit(void)
}
for (i = 0; i < seminfo.semmni; i++)
mtx_init(&sema_mtx[i], "semid", NULL, MTX_DEF);
+ LIST_INIT(&semu_free_list);
for (i = 0; i < seminfo.semmnu; i++) {
struct sem_undo *suptr = SEMU(i);
suptr->un_proc = NULL;
+ LIST_INSERT_HEAD(&semu_free_list, suptr, un_next);
}
- SLIST_INIT(&semu_list);
+ LIST_INIT(&semu_list);
mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
+ mtx_init(&sem_undo_mtx, "semu", NULL, MTX_DEF);
semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
EVENTHANDLER_PRI_ANY);
}
@@ -265,6 +271,7 @@ semunload(void)
{
int i;
+ /* XXXKIB */
if (semtot != 0)
return (EBUSY);
@@ -279,6 +286,7 @@ semunload(void)
for (i = 0; i < seminfo.semmni; i++)
mtx_destroy(&sema_mtx[i]);
mtx_destroy(&sem_mtx);
+ mtx_destroy(&sem_undo_mtx);
return (0);
}
@@ -350,69 +358,31 @@ semsys(td, uap)
*/
static struct sem_undo *
-semu_alloc(td)
- struct thread *td;
+semu_alloc(struct thread *td)
{
- int i;
struct sem_undo *suptr;
- struct sem_undo **supptr;
- int attempt;
SEMUNDO_LOCKASSERT(MA_OWNED);
- /*
- * Try twice to allocate something.
- * (we'll purge an empty structure after the first pass so
- * two passes are always enough)
- */
-
- for (attempt = 0; attempt < 2; attempt++) {
- /*
- * Look for a free structure.
- * Fill it in and return it if we find one.
- */
-
- for (i = 0; i < seminfo.semmnu; i++) {
- suptr = SEMU(i);
- if (suptr->un_proc == NULL) {
- SLIST_INSERT_HEAD(&semu_list, suptr, un_next);
- suptr->un_cnt = 0;
- suptr->un_proc = td->td_proc;
- return(suptr);
- }
- }
-
- /*
- * We didn't find a free one, if this is the first attempt
- * then try to free a structure.
- */
+ if ((suptr = LIST_FIRST(&semu_free_list)) == NULL)
+ return (NULL);
+ LIST_REMOVE(suptr, un_next);
+ LIST_INSERT_HEAD(&semu_list, suptr, un_next);
+ suptr->un_cnt = 0;
+ suptr->un_proc = td->td_proc;
+ return (suptr);
+}
- if (attempt == 0) {
- /* All the structures are in use - try to free one */
- int did_something = 0;
+static int
+semu_try_free(struct sem_undo *suptr)
+{
- SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list,
- un_next) {
- if (suptr->un_cnt == 0) {
- suptr->un_proc = NULL;
- did_something = 1;
- *supptr = SLIST_NEXT(suptr, un_next);
- break;
- }
- }
+ SEMUNDO_LOCKASSERT(MA_OWNED);
- /* If we didn't free anything then just give-up */
- if (!did_something)
- return(NULL);
- } else {
- /*
- * The second pass failed even though we freed
- * something after the first pass!
- * This is IMPOSSIBLE!
- */
- panic("semu_alloc - second attempt failed");
- }
- }
- return (NULL);
+ if (suptr->un_cnt != 0)
+ return (0);
+ LIST_REMOVE(suptr, un_next);
+ LIST_INSERT_HEAD(&semu_free_list, suptr, un_next);
+ return (1);
}
/*
@@ -420,11 +390,8 @@ semu_alloc(td)
*/
static int
-semundo_adjust(td, supptr, semid, semnum, adjval)
- struct thread *td;
- struct sem_undo **supptr;
- int semid, semnum;
- int adjval;
+semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
+ int semseq, int semnum, int adjval)
{
struct proc *p = td->td_proc;
struct sem_undo *suptr;
@@ -437,7 +404,7 @@ semundo_adjust(td, supptr, semid, semnum, adjval)
suptr = *supptr;
if (suptr == NULL) {
- SLIST_FOREACH(suptr, &semu_list, un_next) {
+ LIST_FOREACH(suptr, &semu_list, un_next) {
if (suptr->un_proc == p) {
*supptr = suptr;
break;
@@ -448,7 +415,7 @@ semundo_adjust(td, supptr, semid, semnum, adjval)
return(0);
suptr = semu_alloc(td);
if (suptr == NULL)
- return(ENOSPC);
+ return (ENOSPC);
*supptr = suptr;
}
}
@@ -472,58 +439,59 @@ semundo_adjust(td, supptr, semid, semnum, adjval)
if (i < suptr->un_cnt)
suptr->un_ent[i] =
suptr->un_ent[suptr->un_cnt];
+ if (suptr->un_cnt == 0)
+ semu_try_free(suptr);
}
- return(0);
+ return (0);
}
/* Didn't find the right entry - create it */
if (adjval == 0)
- return(0);
+ return (0);
if (adjval > seminfo.semaem || adjval < -seminfo.semaem)
return (ERANGE);
if (suptr->un_cnt != seminfo.semume) {
sunptr = &suptr->un_ent[suptr->un_cnt];
suptr->un_cnt++;
sunptr->un_adjval = adjval;
- sunptr->un_id = semid; sunptr->un_num = semnum;
+ sunptr->un_id = semid;
+ sunptr->un_num = semnum;
+ sunptr->un_seq = semseq;
} else
- return(EINVAL);
- return(0);
+ return (EINVAL);
+ return (0);
}
static void
-semundo_clear(semid, semnum)
- int semid, semnum;
+semundo_clear(int semid, int semnum)
{
- struct sem_undo *suptr;
+ struct sem_undo *suptr, *suptr1;
+ struct undo *sunptr;
+ int i;
SEMUNDO_LOCKASSERT(MA_OWNED);
- SLIST_FOREACH(suptr, &semu_list, un_next) {
- struct undo *sunptr = &suptr->un_ent[0];
- int i = 0;
-
- while (i < suptr->un_cnt) {
- if (sunptr->un_id == semid) {
- if (semnum == -1 || sunptr->un_num == semnum) {
- suptr->un_cnt--;
- if (i < suptr->un_cnt) {
- suptr->un_ent[i] =
- suptr->un_ent[suptr->un_cnt];
- continue;
- }
+ LIST_FOREACH_SAFE(suptr, &semu_list, un_next, suptr1) {
+ sunptr = &suptr->un_ent[0];
+ for (i = 0; i < suptr->un_cnt; i++, sunptr++) {
+ if (sunptr->un_id != semid)
+ continue;
+ if (semnum == -1 || sunptr->un_num == semnum) {
+ suptr->un_cnt--;
+ if (i < suptr->un_cnt) {
+ suptr->un_ent[i] =
+ suptr->un_ent[suptr->un_cnt];
+ continue;
}
- if (semnum != -1)
- break;
+ semu_try_free(suptr);
}
- i++, sunptr++;
+ if (semnum != -1)
+ break;
}
}
}
static int
-semvalid(semid, semakptr)
- int semid;
- struct semid_kernel *semakptr;
+semvalid(int semid, struct semid_kernel *semakptr)
{
return ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
@@ -542,9 +510,7 @@ struct __semctl_args {
};
#endif
int
-__semctl(td, uap)
- struct thread *td;
- struct __semctl_args *uap;
+__semctl(struct thread *td, struct __semctl_args *uap)
{
struct semid_ds dsbuf;
union semun arg, semun;
@@ -655,6 +621,8 @@ kern_semctl(struct thread *td, int semid, int semnum, int cmd,
semakptr = &sema[semidx];
sema_mtxp = &sema_mtx[semidx];
+ if (cmd == IPC_RMID)
+ mtx_lock(&sem_mtx);
mtx_lock(sema_mtxp);
#ifdef MAC
error = mac_sysvsem_check_semctl(cred, semakptr, cmd);
@@ -673,22 +641,29 @@ kern_semctl(struct thread *td, int semid, int semnum, int cmd,
goto done2;
semakptr->u.sem_perm.cuid = cred->cr_uid;
semakptr->u.sem_perm.uid = cred->cr_uid;
- semtot -= semakptr->u.sem_nsems;
+ semakptr->u.sem_perm.mode = 0;
+ SEMUNDO_LOCK();
+ semundo_clear(semidx, -1);
+ SEMUNDO_UNLOCK();
+#ifdef MAC
+ mac_sysvsem_cleanup(semakptr);
+#endif
+ wakeup(semakptr);
+ for (i = 0; i < seminfo.semmni; i++) {
+ if ((sema[i].u.sem_perm.mode & SEM_ALLOC) &&
+ sema[i].u.sem_base > semakptr->u.sem_base)
+ mtx_lock_flags(&sema_mtx[i], LOP_DUPOK);
+ }
for (i = semakptr->u.sem_base - sem; i < semtot; i++)
sem[i] = sem[i + semakptr->u.sem_nsems];
for (i = 0; i < seminfo.semmni; i++) {
if ((sema[i].u.sem_perm.mode & SEM_ALLOC) &&
- sema[i].u.sem_base > semakptr->u.sem_base)
+ sema[i].u.sem_base > semakptr->u.sem_base) {
sema[i].u.sem_base -= semakptr->u.sem_nsems;
+ mtx_unlock(&sema_mtx[i]);
+ }
}
- semakptr->u.sem_perm.mode = 0;
-#ifdef MAC
- mac_sysvsem_cleanup(semakptr);
-#endif
- SEMUNDO_LOCK();
- semundo_clear(semidx, -1);
- SEMUNDO_UNLOCK();
- wakeup(semakptr);
+ semtot -= semakptr->u.sem_nsems;
break;
case IPC_SET:
@@ -855,6 +830,8 @@ kern_semctl(struct thread *td, int semid, int semnum, int cmd,
done2:
mtx_unlock(sema_mtxp);
+ if (cmd == IPC_RMID)
+ mtx_unlock(&sem_mtx);
if (array != NULL)
free(array, M_TEMP);
return(error);
@@ -868,9 +845,7 @@ struct semget_args {
};
#endif
int
-semget(td, uap)
- struct thread *td;
- struct semget_args *uap;
+semget(struct thread *td, struct semget_args *uap)
{
int semid, error = 0;
int key = uap->key;
@@ -882,7 +857,7 @@ semget(td, uap)
if (!jail_sysvipc_allowed && jailed(td->td_ucred))
return (ENOSYS);
- mtx_lock(&Giant);
+ mtx_lock(&sem_mtx);
if (key != IPC_PRIVATE) {
for (semid = 0; semid < seminfo.semmni; semid++) {
if ((sema[semid].u.sem_perm.mode & SEM_ALLOC) &&
@@ -939,6 +914,9 @@ semget(td, uap)
goto done2;
}
DPRINTF(("semid %d is available\n", semid));
+ mtx_lock(&sema_mtx[semid]);
+ KASSERT((sema[semid].u.sem_perm.mode & SEM_ALLOC) == 0,
+ ("Lost semaphore %d", semid));
sema[semid].u.sem_perm.key = key;
sema[semid].u.sem_perm.cuid = cred->cr_uid;
sema[semid].u.sem_perm.uid = cred->cr_uid;
@@ -957,6 +935,7 @@ semget(td, uap)
#ifdef MAC
mac_sysvsem_create(cred, &sema[semid]);
#endif
+ mtx_unlock(&sema_mtx[semid]);
DPRINTF(("sembase = %p, next = %p\n",
sema[semid].u.sem_base, &sem[semtot]));
} else {
@@ -968,7 +947,7 @@ semget(td, uap)
found:
td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].u.sem_perm);
done2:
- mtx_unlock(&Giant);
+ mtx_unlock(&sem_mtx);
return (error);
}
@@ -980,9 +959,7 @@ struct semop_args {
};
#endif
int
-semop(td, uap)
- struct thread *td;
- struct semop_args *uap;
+semop(struct thread *td, struct semop_args *uap)
{
#define SMALL_SOPS 8
struct sembuf small_sops[SMALL_SOPS];
@@ -997,6 +974,7 @@ semop(td, uap)
size_t i, j, k;
int error;
int do_wakeup, do_undos;
+ unsigned short seq;
#ifdef SEM_DEBUG
sops = NULL;
@@ -1036,7 +1014,8 @@ semop(td, uap)
error = EINVAL;
goto done2;
}
- if (semakptr->u.sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
+ seq = semakptr->u.sem_perm.seq;
+ if (seq != IPCID_TO_SEQ(uap->semid)) {
error = EINVAL;
goto done2;
}
@@ -1160,8 +1139,9 @@ semop(td, uap)
/*
* Make sure that the semaphore still exists
*/
+ seq = semakptr->u.sem_perm.seq;
if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
- semakptr->u.sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
+ seq != IPCID_TO_SEQ(uap->semid)) {
error = EIDRM;
goto done2;
}
@@ -1213,7 +1193,7 @@ done:
adjval = sops[i].sem_op;
if (adjval == 0)
continue;
- error = semundo_adjust(td, &suptr, semid,
+ error = semundo_adjust(td, &suptr, semid, seq,
sops[i].sem_num, -adjval);
if (error == 0)
continue;
@@ -1234,7 +1214,7 @@ done:
adjval = sops[k].sem_op;
if (adjval == 0)
continue;
- if (semundo_adjust(td, &suptr, semid,
+ if (semundo_adjust(td, &suptr, semid, seq,
sops[k].sem_num, adjval) != 0)
panic("semop - can't undo undos");
}
@@ -1281,28 +1261,28 @@ done2:
* semaphores.
*/
static void
-semexit_myhook(arg, p)
- void *arg;
- struct proc *p;
+semexit_myhook(void *arg, struct proc *p)
{
struct sem_undo *suptr;
- struct sem_undo **supptr;
+ struct semid_kernel *semakptr;
+ struct mtx *sema_mtxp;
+ int semid, semnum, adjval, ix;
+ unsigned short seq;
/*
* Go through the chain of undo vectors looking for one
* associated with this process.
*/
SEMUNDO_LOCK();
- SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list, un_next) {
- if (suptr->un_proc == p) {
- *supptr = SLIST_NEXT(suptr, un_next);
+ LIST_FOREACH(suptr, &semu_list, un_next) {
+ if (suptr->un_proc == p)
break;
- }
}
- SEMUNDO_UNLOCK();
-
- if (suptr == NULL)
+ if (suptr == NULL) {
+ SEMUNDO_UNLOCK();
return;
+ }
+ LIST_REMOVE(suptr, un_next);
DPRINTF(("proc @%p has undo structure with %d entries\n", p,
suptr->un_cnt));
@@ -1311,21 +1291,21 @@ semexit_myhook(arg, p)
* If there are any active undo elements then process them.
*/
if (suptr->un_cnt > 0) {
- int ix;
-
+ SEMUNDO_UNLOCK();
for (ix = 0; ix < suptr->un_cnt; ix++) {
- int semid = suptr->un_ent[ix].un_id;
- int semnum = suptr->un_ent[ix].un_num;
- int adjval = suptr->un_ent[ix].un_adjval;
- struct semid_kernel *semakptr;
- struct mtx *sema_mtxp;
-
+ semid = suptr->un_ent[ix].un_id;
+ semnum = suptr->un_ent[ix].un_num;
+ adjval = suptr->un_ent[ix].un_adjval;
+ seq = suptr->un_ent[ix].un_seq;
semakptr = &sema[semid];
sema_mtxp = &sema_mtx[semid];
+
mtx_lock(sema_mtxp);
- SEMUNDO_LOCK();
- if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0)
- panic("semexit - semid not allocated");
+ if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
+ (semakptr->u.sem_perm.seq != seq)) {
+ mtx_unlock(sema_mtxp);
+ continue;
+ }
if (semnum >= semakptr->u.sem_nsems)
panic("semexit - semnum out of range");
@@ -1336,29 +1316,26 @@ semexit_myhook(arg, p)
suptr->un_ent[ix].un_adjval,
semakptr->u.sem_base[semnum].semval));
- if (adjval < 0) {
- if (semakptr->u.sem_base[semnum].semval <
- -adjval)
- semakptr->u.sem_base[semnum].semval = 0;
- else
- semakptr->u.sem_base[semnum].semval +=
- adjval;
- } else
+ if (adjval < 0 && semakptr->u.sem_base[semnum].semval <
+ -adjval)
+ semakptr->u.sem_base[semnum].semval = 0;
+ else
semakptr->u.sem_base[semnum].semval += adjval;
wakeup(semakptr);
DPRINTF(("semexit: back from wakeup\n"));
mtx_unlock(sema_mtxp);
- SEMUNDO_UNLOCK();
}
+ SEMUNDO_LOCK();
}
/*
* Deallocate the undo vector.
*/
DPRINTF(("removing vector\n"));
- SEMUNDO_LOCK();
suptr->un_proc = NULL;
+ suptr->un_cnt = 0;
+ LIST_INSERT_HEAD(&semu_free_list, suptr, un_next);
SEMUNDO_UNLOCK();
}
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index adf24b5..d73683c 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -291,11 +291,12 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
}
}
- if (TTY_CALLOUT(tp, dev)) {
+ if (dev == dev_console)
+ tp->t_flags |= TF_OPENED_CONS;
+ else if (TTY_CALLOUT(tp, dev))
tp->t_flags |= TF_OPENED_OUT;
- } else {
+ else
tp->t_flags |= TF_OPENED_IN;
- }
done: tp->t_flags &= ~TF_OPENCLOSE;
ttydev_leave(tp);
@@ -311,11 +312,25 @@ ttydev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
tty_lock(tp);
/*
+ * Don't actually close the device if it is being used as the
+ * console.
+ */
+ MPASS((tp->t_flags & TF_OPENED) != TF_OPENED);
+ if (dev == dev_console)
+ tp->t_flags &= ~TF_OPENED_CONS;
+ else
+ tp->t_flags &= ~(TF_OPENED_IN|TF_OPENED_OUT);
+
+ if (tp->t_flags & TF_OPENED) {
+ tty_unlock(tp);
+ return (0);
+ }
+
+ /*
* This can only be called once. The callin and the callout
* devices cannot be opened at the same time.
*/
- MPASS((tp->t_flags & TF_OPENED) != TF_OPENED);
- tp->t_flags &= ~(TF_OPENED|TF_EXCLUDE|TF_STOPPED);
+ tp->t_flags &= ~(TF_EXCLUDE|TF_STOPPED);
/* Properly wake up threads that are stuck - revoke(). */
tp->t_revokecnt++;
@@ -876,9 +891,6 @@ tty_alloc(struct ttydevsw *tsw, void *sc, struct mtx *mutex)
cv_init(&tp->t_bgwait, "ttybg");
cv_init(&tp->t_dcdwait, "ttydcd");
- ttyinq_init(&tp->t_inq);
- ttyoutq_init(&tp->t_outq);
-
/* Allow drivers to use a custom mutex to lock the TTY. */
if (mutex != NULL) {
tp->t_mtx = mutex;
@@ -1045,7 +1057,7 @@ sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
return (error);
}
-SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
+SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE,
0, 0, sysctl_kern_ttys, "S,xtty", "List of TTYs");
/*
@@ -1792,13 +1804,14 @@ ttyconsdev_write(struct cdev *dev, struct uio *uio, int ioflag)
}
/*
- * /dev/console is a little different than normal TTY's. Unlike regular
- * TTY device nodes, this device node will not revoke the entire TTY
- * upon closure and all data written to it will be logged.
+ * /dev/console is a little different than normal TTY's. When opened,
+ * it determines which TTY to use. When data gets written to it, it
+ * will be logged in the kernel message buffer.
*/
static struct cdevsw ttyconsdev_cdevsw = {
.d_version = D_VERSION,
.d_open = ttyconsdev_open,
+ .d_close = ttydev_close,
.d_read = ttydev_read,
.d_write = ttyconsdev_write,
.d_ioctl = ttydev_ioctl,
@@ -1840,33 +1853,34 @@ static struct {
char val;
} ttystates[] = {
#if 0
- { TF_NOPREFIX, 'N' },
+ { TF_NOPREFIX, 'N' },
#endif
- { TF_INITLOCK, 'I' },
- { TF_CALLOUT, 'C' },
+ { TF_INITLOCK, 'I' },
+ { TF_CALLOUT, 'C' },
/* Keep these together -> 'Oi' and 'Oo'. */
- { TF_OPENED, 'O' },
- { TF_OPENED_IN, 'i' },
- { TF_OPENED_OUT,'o' },
+ { TF_OPENED, 'O' },
+ { TF_OPENED_IN, 'i' },
+ { TF_OPENED_OUT, 'o' },
+ { TF_OPENED_CONS, 'c' },
- { TF_GONE, 'G' },
- { TF_OPENCLOSE, 'B' },
- { TF_ASYNC, 'Y' },
- { TF_LITERAL, 'L' },
+ { TF_GONE, 'G' },
+ { TF_OPENCLOSE, 'B' },
+ { TF_ASYNC, 'Y' },
+ { TF_LITERAL, 'L' },
/* Keep these together -> 'Hi' and 'Ho'. */
- { TF_HIWAT, 'H' },
- { TF_HIWAT_IN, 'i' },
- { TF_HIWAT_OUT, 'o' },
+ { TF_HIWAT, 'H' },
+ { TF_HIWAT_IN, 'i' },
+ { TF_HIWAT_OUT, 'o' },
- { TF_STOPPED, 'S' },
- { TF_EXCLUDE, 'X' },
- { TF_BYPASS, 'l' },
- { TF_ZOMBIE, 'Z' },
- { TF_HOOK, 's' },
+ { TF_STOPPED, 'S' },
+ { TF_EXCLUDE, 'X' },
+ { TF_BYPASS, 'l' },
+ { TF_ZOMBIE, 'Z' },
+ { TF_HOOK, 's' },
- { 0, '\0' },
+ { 0, '\0'},
};
#define TTY_FLAG_BITS \
diff --git a/sys/kern/tty_info.c b/sys/kern/tty_info.c
index de06775..cbd7402 100644
--- a/sys/kern/tty_info.c
+++ b/sys/kern/tty_info.c
@@ -285,6 +285,8 @@ tty_info(struct tty *tp)
state = "suspended";
else if (TD_AWAITING_INTR(td))
state = "intrwait";
+ else if (pick->p_state == PRS_ZOMBIE)
+ state = "zombie";
else
state = "unknown";
pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT;
diff --git a/sys/kern/tty_inq.c b/sys/kern/tty_inq.c
index fc99729..f36ae05 100644
--- a/sys/kern/tty_inq.c
+++ b/sys/kern/tty_inq.c
@@ -79,13 +79,43 @@ SYSCTL_LONG(_kern, OID_AUTO, tty_inq_nslow, CTLFLAG_RD,
((tib)->tib_quotes[(boff) / BMSIZE] &= ~(1 << ((boff) % BMSIZE)))
struct ttyinq_block {
- TAILQ_ENTRY(ttyinq_block) tib_list;
- uint32_t tib_quotes[TTYINQ_QUOTESIZE];
- char tib_data[TTYINQ_DATASIZE];
+ struct ttyinq_block *tib_prev;
+ struct ttyinq_block *tib_next;
+ uint32_t tib_quotes[TTYINQ_QUOTESIZE];
+ char tib_data[TTYINQ_DATASIZE];
};
static uma_zone_t ttyinq_zone;
+#define TTYINQ_INSERT_TAIL(ti, tib) do { \
+ if (ti->ti_end == 0) { \
+ tib->tib_prev = NULL; \
+ tib->tib_next = ti->ti_firstblock; \
+ ti->ti_firstblock = tib; \
+ } else { \
+ tib->tib_prev = ti->ti_lastblock; \
+ tib->tib_next = ti->ti_lastblock->tib_next; \
+ ti->ti_lastblock->tib_next = tib; \
+ } \
+ if (tib->tib_next != NULL) \
+ tib->tib_next->tib_prev = tib; \
+ ti->ti_nblocks++; \
+} while (0)
+
+#define TTYINQ_REMOVE_HEAD(ti) do { \
+ ti->ti_firstblock = ti->ti_firstblock->tib_next; \
+ if (ti->ti_firstblock != NULL) \
+ ti->ti_firstblock->tib_prev = NULL; \
+ ti->ti_nblocks--; \
+} while (0)
+
+#define TTYINQ_RECYCLE(ti, tib) do { \
+ if (ti->ti_quota <= ti->ti_nblocks) \
+ uma_zfree(ttyinq_zone, tib); \
+ else \
+ TTYINQ_INSERT_TAIL(ti, tib); \
+} while (0)
+
void
ttyinq_setsize(struct ttyinq *ti, struct tty *tp, size_t size)
{
@@ -108,8 +138,7 @@ ttyinq_setsize(struct ttyinq *ti, struct tty *tp, size_t size)
tib = uma_zalloc(ttyinq_zone, M_WAITOK);
tty_lock(tp);
- TAILQ_INSERT_TAIL(&ti->ti_list, tib, tib_list);
- ti->ti_nblocks++;
+ TTYINQ_INSERT_TAIL(ti, tib);
}
}
@@ -121,10 +150,9 @@ ttyinq_free(struct ttyinq *ti)
ttyinq_flush(ti);
ti->ti_quota = 0;
- while ((tib = TAILQ_FIRST(&ti->ti_list)) != NULL) {
- TAILQ_REMOVE(&ti->ti_list, tib, tib_list);
+ while ((tib = ti->ti_firstblock) != NULL) {
+ TTYINQ_REMOVE_HEAD(ti);
uma_zfree(ttyinq_zone, tib);
- ti->ti_nblocks--;
}
MPASS(ti->ti_nblocks == 0);
@@ -145,7 +173,7 @@ ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
/* See if there still is data. */
if (ti->ti_begin == ti->ti_linestart)
return (0);
- tib = TAILQ_FIRST(&ti->ti_list);
+ tib = ti->ti_firstblock;
if (tib == NULL)
return (0);
@@ -176,8 +204,7 @@ ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
* Fast path: zero copy. Remove the first block,
* so we can unlock the TTY temporarily.
*/
- TAILQ_REMOVE(&ti->ti_list, tib, tib_list);
- ti->ti_nblocks--;
+ TTYINQ_REMOVE_HEAD(ti);
ti->ti_begin = 0;
/*
@@ -185,11 +212,10 @@ ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
* fix up the block offsets.
*/
#define CORRECT_BLOCK(t) do { \
- if (t <= TTYINQ_DATASIZE) { \
+ if (t <= TTYINQ_DATASIZE) \
t = 0; \
- } else { \
+ else \
t -= TTYINQ_DATASIZE; \
- } \
} while (0)
CORRECT_BLOCK(ti->ti_linestart);
CORRECT_BLOCK(ti->ti_reprint);
@@ -207,12 +233,7 @@ ttyinq_read_uio(struct ttyinq *ti, struct tty *tp, struct uio *uio,
tty_lock(tp);
/* Block can now be readded to the list. */
- if (ti->ti_quota <= ti->ti_nblocks) {
- uma_zfree(ttyinq_zone, tib);
- } else {
- TAILQ_INSERT_TAIL(&ti->ti_list, tib, tib_list);
- ti->ti_nblocks++;
- }
+ TTYINQ_RECYCLE(ti, tib);
} else {
char ob[TTYINQ_DATASIZE - 1];
atomic_add_long(&ttyinq_nslow, 1);
@@ -264,25 +285,27 @@ ttyinq_write(struct ttyinq *ti, const void *buf, size_t nbytes, int quote)
size_t l;
while (nbytes > 0) {
- tib = ti->ti_lastblock;
boff = ti->ti_end % TTYINQ_DATASIZE;
if (ti->ti_end == 0) {
/* First time we're being used or drained. */
MPASS(ti->ti_begin == 0);
- tib = ti->ti_lastblock = TAILQ_FIRST(&ti->ti_list);
+ tib = ti->ti_firstblock;
if (tib == NULL) {
/* Queue has no blocks. */
break;
}
+ ti->ti_lastblock = tib;
} else if (boff == 0) {
/* We reached the end of this block on last write. */
- tib = TAILQ_NEXT(tib, tib_list);
+ tib = ti->ti_lastblock->tib_next;
if (tib == NULL) {
/* We've reached the watermark. */
break;
}
ti->ti_lastblock = tib;
+ } else {
+ tib = ti->ti_lastblock;
}
/* Don't copy more than was requested. */
@@ -328,7 +351,7 @@ size_t
ttyinq_findchar(struct ttyinq *ti, const char *breakc, size_t maxlen,
char *lastc)
{
- struct ttyinq_block *tib = TAILQ_FIRST(&ti->ti_list);
+ struct ttyinq_block *tib = ti->ti_firstblock;
unsigned int boff = ti->ti_begin;
unsigned int bend = MIN(MIN(TTYINQ_DATASIZE, ti->ti_linestart),
ti->ti_begin + maxlen);
@@ -402,8 +425,7 @@ ttyinq_unputchar(struct ttyinq *ti)
if (--ti->ti_end % TTYINQ_DATASIZE == 0) {
/* Roll back to the previous block. */
- ti->ti_lastblock = TAILQ_PREV(ti->ti_lastblock,
- ttyinq_bhead, tib_list);
+ ti->ti_lastblock = ti->ti_lastblock->tib_prev;
/*
* This can only fail if we are unputchar()'ing the
* first character in the queue.
@@ -437,7 +459,7 @@ ttyinq_line_iterate(struct ttyinq *ti,
/* Use the proper block when we're at the queue head. */
if (offset == 0)
- tib = TAILQ_FIRST(&ti->ti_list);
+ tib = ti->ti_firstblock;
/* Iterate all characters and call the iterator function. */
for (; offset < ti->ti_end; offset++) {
@@ -449,7 +471,7 @@ ttyinq_line_iterate(struct ttyinq *ti,
/* Last byte iterated - go to the next block. */
if (boff == TTYINQ_DATASIZE - 1)
- tib = TAILQ_NEXT(tib, tib_list);
+ tib = tib->tib_next;
MPASS(tib != NULL);
}
}
diff --git a/sys/kern/tty_outq.c b/sys/kern/tty_outq.c
index d55ec15..719c1a4 100644
--- a/sys/kern/tty_outq.c
+++ b/sys/kern/tty_outq.c
@@ -61,12 +61,35 @@ SYSCTL_LONG(_kern, OID_AUTO, tty_outq_nslow, CTLFLAG_RD,
&ttyoutq_nslow, 0, "Buffered reads to userspace on output");
struct ttyoutq_block {
- STAILQ_ENTRY(ttyoutq_block) tob_list;
- char tob_data[TTYOUTQ_DATASIZE];
+ struct ttyoutq_block *tob_next;
+ char tob_data[TTYOUTQ_DATASIZE];
};
static uma_zone_t ttyoutq_zone;
+#define TTYOUTQ_INSERT_TAIL(to, tob) do { \
+ if (to->to_end == 0) { \
+ tob->tob_next = to->to_firstblock; \
+ to->to_firstblock = tob; \
+ } else { \
+ tob->tob_next = to->to_lastblock->tob_next; \
+ to->to_lastblock->tob_next = tob; \
+ } \
+ to->to_nblocks++; \
+} while (0)
+
+#define TTYOUTQ_REMOVE_HEAD(to) do { \
+ to->to_firstblock = to->to_firstblock->tob_next; \
+ to->to_nblocks--; \
+} while (0)
+
+#define TTYOUTQ_RECYCLE(to, tob) do { \
+ if (to->to_quota <= to->to_nblocks) \
+ uma_zfree(ttyoutq_zone, tob); \
+ else \
+ TTYOUTQ_INSERT_TAIL(to, tob); \
+} while(0)
+
void
ttyoutq_flush(struct ttyoutq *to)
{
@@ -97,8 +120,7 @@ ttyoutq_setsize(struct ttyoutq *to, struct tty *tp, size_t size)
tob = uma_zalloc(ttyoutq_zone, M_WAITOK);
tty_lock(tp);
- STAILQ_INSERT_TAIL(&to->to_list, tob, tob_list);
- to->to_nblocks++;
+ TTYOUTQ_INSERT_TAIL(to, tob);
}
}
@@ -110,10 +132,9 @@ ttyoutq_free(struct ttyoutq *to)
ttyoutq_flush(to);
to->to_quota = 0;
- while ((tob = STAILQ_FIRST(&to->to_list)) != NULL) {
- STAILQ_REMOVE_HEAD(&to->to_list, tob_list);
+ while ((tob = to->to_firstblock) != NULL) {
+ TTYOUTQ_REMOVE_HEAD(to);
uma_zfree(ttyoutq_zone, tob);
- to->to_nblocks--;
}
MPASS(to->to_nblocks == 0);
@@ -131,7 +152,7 @@ ttyoutq_read(struct ttyoutq *to, void *buf, size_t len)
/* See if there still is data. */
if (to->to_begin == to->to_end)
break;
- tob = STAILQ_FIRST(&to->to_list);
+ tob = to->to_firstblock;
if (tob == NULL)
break;
@@ -146,30 +167,25 @@ ttyoutq_read(struct ttyoutq *to, void *buf, size_t len)
TTYOUTQ_DATASIZE);
clen = cend - cbegin;
- if (cend == TTYOUTQ_DATASIZE || cend == to->to_end) {
+ /* Copy the data out of the buffers. */
+ memcpy(cbuf, tob->tob_data + cbegin, clen);
+ cbuf += clen;
+ len -= clen;
+
+ if (cend == to->to_end) {
+ /* Read the complete queue. */
+ to->to_begin = 0;
+ to->to_end = 0;
+ } else if (cend == TTYOUTQ_DATASIZE) {
/* Read the block until the end. */
- STAILQ_REMOVE_HEAD(&to->to_list, tob_list);
- if (to->to_quota < to->to_nblocks) {
- uma_zfree(ttyoutq_zone, tob);
- to->to_nblocks--;
- } else {
- STAILQ_INSERT_TAIL(&to->to_list, tob, tob_list);
- }
+ TTYOUTQ_REMOVE_HEAD(to);
to->to_begin = 0;
- if (to->to_end <= TTYOUTQ_DATASIZE) {
- to->to_end = 0;
- } else {
- to->to_end -= TTYOUTQ_DATASIZE;
- }
+ to->to_end -= TTYOUTQ_DATASIZE;
+ TTYOUTQ_RECYCLE(to, tob);
} else {
/* Read the block partially. */
to->to_begin += clen;
}
-
- /* Copy the data out of the buffers. */
- memcpy(cbuf, tob->tob_data + cbegin, clen);
- cbuf += clen;
- len -= clen;
}
return (cbuf - (char *)buf);
@@ -197,7 +213,7 @@ ttyoutq_read_uio(struct ttyoutq *to, struct tty *tp, struct uio *uio)
/* See if there still is data. */
if (to->to_begin == to->to_end)
return (0);
- tob = STAILQ_FIRST(&to->to_list);
+ tob = to->to_firstblock;
if (tob == NULL)
return (0);
@@ -226,14 +242,12 @@ ttyoutq_read_uio(struct ttyoutq *to, struct tty *tp, struct uio *uio)
* Fast path: zero copy. Remove the first block,
* so we can unlock the TTY temporarily.
*/
- STAILQ_REMOVE_HEAD(&to->to_list, tob_list);
- to->to_nblocks--;
+ TTYOUTQ_REMOVE_HEAD(to);
to->to_begin = 0;
- if (to->to_end <= TTYOUTQ_DATASIZE) {
+ if (to->to_end <= TTYOUTQ_DATASIZE)
to->to_end = 0;
- } else {
+ else
to->to_end -= TTYOUTQ_DATASIZE;
- }
/* Temporary unlock and copy the data to userspace. */
tty_unlock(tp);
@@ -241,12 +255,7 @@ ttyoutq_read_uio(struct ttyoutq *to, struct tty *tp, struct uio *uio)
tty_lock(tp);
/* Block can now be readded to the list. */
- if (to->to_quota <= to->to_nblocks) {
- uma_zfree(ttyoutq_zone, tob);
- } else {
- STAILQ_INSERT_TAIL(&to->to_list, tob, tob_list);
- to->to_nblocks++;
- }
+ TTYOUTQ_RECYCLE(to, tob);
} else {
char ob[TTYOUTQ_DATASIZE - 1];
atomic_add_long(&ttyoutq_nslow, 1);
@@ -280,26 +289,27 @@ ttyoutq_write(struct ttyoutq *to, const void *buf, size_t nbytes)
size_t l;
while (nbytes > 0) {
- /* Offset in current block. */
- tob = to->to_lastblock;
boff = to->to_end % TTYOUTQ_DATASIZE;
if (to->to_end == 0) {
/* First time we're being used or drained. */
MPASS(to->to_begin == 0);
- tob = to->to_lastblock = STAILQ_FIRST(&to->to_list);
+ tob = to->to_firstblock;
if (tob == NULL) {
/* Queue has no blocks. */
break;
}
+ to->to_lastblock = tob;
} else if (boff == 0) {
/* We reached the end of this block on last write. */
- tob = STAILQ_NEXT(tob, tob_list);
+ tob = to->to_lastblock->tob_next;
if (tob == NULL) {
/* We've reached the watermark. */
break;
}
to->to_lastblock = tob;
+ } else {
+ tob = to->to_lastblock;
}
/* Don't copy more than was requested. */
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 9c26799..97af90d 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -55,16 +55,15 @@ SYSCTL_UINT(_kern, OID_AUTO, tty_pty_warningcnt, CTLFLAG_RW,
static int
ptydev_fdopen(struct cdev *dev, int fflags, struct thread *td, struct file *fp)
{
- int u, error;
- char name[] = "ttyXX";
+ int error;
+ char name[6]; /* "ttyXX" */
if (!atomic_cmpset_ptr((uintptr_t *)&dev->si_drv1, 0, 1))
return (EBUSY);
/* Generate device name and create PTY. */
- u = dev2unit(dev);
- name[3] = u >> 8;
- name[4] = u;
+ strcpy(name, devtoname(dev));
+ name[0] = 't';
error = pts_alloc_external(fflags & (FREAD|FWRITE), td, fp, dev, name);
if (error != 0) {
@@ -93,7 +92,6 @@ static void
pty_clone(void *arg, struct ucred *cr, char *name, int namelen,
struct cdev **dev)
{
- int u;
/* Cloning is already satisfied. */
if (*dev != NULL)
@@ -114,8 +112,7 @@ pty_clone(void *arg, struct ucred *cr, char *name, int namelen,
return;
/* Create the controller device node. */
- u = (unsigned int)name[3] << 8 | name[4];
- *dev = make_dev_credf(MAKEDEV_REF, &ptydev_cdevsw, u,
+ *dev = make_dev_credf(MAKEDEV_REF, &ptydev_cdevsw, 0,
NULL, UID_ROOT, GID_WHEEL, 0666, name);
}
diff --git a/sys/kern/uipc_cow.c b/sys/kern/uipc_cow.c
index 2e29ee3..52988dd 100644
--- a/sys/kern/uipc_cow.c
+++ b/sys/kern/uipc_cow.c
@@ -129,7 +129,11 @@ socow_setup(struct mbuf *m0, struct uio *uio)
* set up COW
*/
vm_page_lock_queues();
- vm_page_cowsetup(pp);
+ if (vm_page_cowsetup(pp) != 0) {
+ vm_page_unhold(pp);
+ vm_page_unlock_queues();
+ return (0);
+ }
/*
* wire the page for I/O
diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c
index c2a0937..17d455f 100644
--- a/sys/kern/uipc_debug.c
+++ b/sys/kern/uipc_debug.c
@@ -322,7 +322,6 @@ db_print_protosw(struct protosw *pr, const char *prname, int indent)
db_print_indent(indent);
db_printf("pr_ctloutput: %p ", pr->pr_ctloutput);
- db_printf("pr_ousrreq: %p ", pr->pr_ousrreq);
db_printf("pr_init: %p\n", pr->pr_init);
db_print_indent(indent);
@@ -331,7 +330,6 @@ db_print_protosw(struct protosw *pr, const char *prname, int indent)
db_printf("pr_drain: %p\n", pr->pr_drain);
db_print_indent(indent);
- db_printf("pr_ousrreq: %p\n", pr->pr_ousrreq);
}
static void
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index 2b2f5c8..9c9b05f 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -72,7 +72,7 @@ static void pfslowtimo(void *);
struct domain *domains; /* registered protocol domains */
int domain_init_status = 0;
-struct mtx dom_mtx; /* domain list lock */
+static struct mtx dom_mtx; /* domain list lock */
MTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF);
/*
@@ -338,13 +338,13 @@ found:
* Protect us against races when two protocol registrations for
* the same protocol happen at the same time.
*/
- mtx_lock(&Giant);
+ mtx_lock(&dom_mtx);
/* The new protocol must not yet exist. */
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
if ((pr->pr_type == npr->pr_type) &&
(pr->pr_protocol == npr->pr_protocol)) {
- mtx_unlock(&Giant);
+ mtx_unlock(&dom_mtx);
return (EEXIST); /* XXX: Check only protocol? */
}
/* While here, remember the first free spacer. */
@@ -354,7 +354,7 @@ found:
/* If no free spacer is found we can't add the new protocol. */
if (fpr == NULL) {
- mtx_unlock(&Giant);
+ mtx_unlock(&dom_mtx);
return (ENOMEM);
}
@@ -362,7 +362,7 @@ found:
bcopy(npr, fpr, sizeof(*fpr));
/* Job is done, no more protection required. */
- mtx_unlock(&Giant);
+ mtx_unlock(&dom_mtx);
/* Initialize and activate the protocol. */
protosw_init(fpr);
@@ -398,13 +398,13 @@ found:
dpr = NULL;
/* Lock out everyone else while we are manipulating the protosw. */
- mtx_lock(&Giant);
+ mtx_lock(&dom_mtx);
/* The protocol must exist and only once. */
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
if ((pr->pr_type == type) && (pr->pr_protocol == protocol)) {
if (dpr != NULL) {
- mtx_unlock(&Giant);
+ mtx_unlock(&dom_mtx);
return (EMLINK); /* Should not happen! */
} else
dpr = pr;
@@ -413,7 +413,7 @@ found:
/* Protocol does not exist. */
if (dpr == NULL) {
- mtx_unlock(&Giant);
+ mtx_unlock(&dom_mtx);
return (EPROTONOSUPPORT);
}
@@ -426,7 +426,6 @@ found:
dpr->pr_output = NULL;
dpr->pr_ctlinput = NULL;
dpr->pr_ctloutput = NULL;
- dpr->pr_ousrreq = NULL;
dpr->pr_init = NULL;
dpr->pr_fasttimo = NULL;
dpr->pr_slowtimo = NULL;
@@ -434,7 +433,7 @@ found:
dpr->pr_usrreqs = &nousrreqs;
/* Job is done, not more protection required. */
- mtx_unlock(&Giant);
+ mtx_unlock(&dom_mtx);
return (0);
}
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index f574325..bf24132 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1271,6 +1271,10 @@ m_copyback(struct mbuf *m0, int off, int len, c_caddr_t cp)
m = m->m_next;
}
while (len > 0) {
+ if (m->m_next == NULL && (len > m->m_len - off)) {
+ m->m_len += min(len - (m->m_len - off),
+ M_TRAILINGSPACE(m));
+ }
mlen = min (m->m_len - off, len);
bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen);
cp += mlen;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 1d76b15..9d9a731 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -347,15 +347,8 @@ socreate(int dom, struct socket **aso, int type, int proto,
prp->pr_usrreqs->pru_attach == pru_attach_notsupp)
return (EPROTONOSUPPORT);
- if (jailed(cred) && jail_socket_unixiproute_only &&
- prp->pr_domain->dom_family != PF_LOCAL &&
- prp->pr_domain->dom_family != PF_INET &&
-#ifdef INET6
- prp->pr_domain->dom_family != PF_INET6 &&
-#endif
- prp->pr_domain->dom_family != PF_ROUTE) {
+ if (prison_check_af(cred, prp->pr_domain->dom_family) != 0)
return (EPROTONOSUPPORT);
- }
if (prp->pr_type != type)
return (EPROTOTYPE);
@@ -1858,7 +1851,7 @@ soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio,
struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
{
struct mbuf *m, *m2;
- int flags, len, error, offset;
+ int flags, len, error;
struct protosw *pr = so->so_proto;
struct mbuf *nextrecord;
@@ -2008,7 +2001,6 @@ soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio,
}
KASSERT(m->m_type == MT_DATA, ("soreceive_dgram: !data"));
- offset = 0;
while (m != NULL && uio->uio_resid > 0) {
len = uio->uio_resid;
if (len > m->m_len)
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 2e27bd4..84ebdee 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -754,7 +754,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
{
struct unpcb *unp, *unp2;
struct socket *so2;
- u_int mbcnt, sbcc;
+ u_int mbcnt_delta, sbcc;
u_long newhiwat;
int error = 0;
@@ -884,7 +884,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
control = NULL;
} else
sbappend_locked(&so2->so_rcv, m);
- mbcnt = so2->so_rcv.sb_mbcnt - unp2->unp_mbcnt;
+ mbcnt_delta = so2->so_rcv.sb_mbcnt - unp2->unp_mbcnt;
unp2->unp_mbcnt = so2->so_rcv.sb_mbcnt;
sbcc = so2->so_rcv.sb_cc;
sorwakeup_locked(so2);
@@ -893,7 +893,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
newhiwat = so->so_snd.sb_hiwat - (sbcc - unp2->unp_cc);
(void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat,
newhiwat, RLIM_INFINITY);
- so->so_snd.sb_mbmax -= mbcnt;
+ so->so_snd.sb_mbmax -= mbcnt_delta;
SOCKBUF_UNLOCK(&so->so_snd);
unp2->unp_cc = sbcc;
UNP_PCB_UNLOCK(unp2);
@@ -1229,14 +1229,14 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
unp3->unp_addr = (struct sockaddr_un *) sa;
sa = NULL;
}
+
/*
- * unp_peercred management:
- *
* The connecter's (client's) credentials are copied from its
* process structure at the time of connect() (which is now).
*/
cru2x(td->td_ucred, &unp3->unp_peercred);
unp3->unp_flags |= UNP_HAVEPC;
+
/*
* The receiver's (server's) credentials are copied from the
* unp_peercred member of socket on which the former called
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 14e980d..7cd077b 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -2824,7 +2824,7 @@ int
freebsd32_aio_waitcomplete(struct thread *td,
struct freebsd32_aio_waitcomplete_args *uap)
{
- struct timespec ts32;
+ struct timespec32 ts32;
struct timespec ts, *tsp;
int error;
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index f75963d..667ea2d 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3920,6 +3920,7 @@ DB_SHOW_COMMAND(buffer, db_show_buffer)
}
db_printf("\n");
}
+ db_printf(" ");
lockmgr_printinfo(&bp->b_lock);
}
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 6fad06e..9654433 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -42,9 +42,9 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
-#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/proc.h>
+#include <sys/rwlock.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysproto.h>
@@ -109,11 +109,14 @@ SYSCTL_ULONG(_debug, OID_AUTO, numcachepl, CTLFLAG_RD, &numcachepl, 0, "");
#endif
struct nchstats nchstats; /* cache effectiveness statistics */
-static struct mtx cache_lock;
-MTX_SYSINIT(vfscache, &cache_lock, "Name Cache", MTX_DEF);
+static struct rwlock cache_lock;
+RW_SYSINIT(vfscache, &cache_lock, "Name Cache");
-#define CACHE_LOCK() mtx_lock(&cache_lock)
-#define CACHE_UNLOCK() mtx_unlock(&cache_lock)
+#define CACHE_UPGRADE_LOCK() rw_try_upgrade(&cache_lock)
+#define CACHE_RLOCK() rw_rlock(&cache_lock)
+#define CACHE_RUNLOCK() rw_runlock(&cache_lock)
+#define CACHE_WLOCK() rw_wlock(&cache_lock)
+#define CACHE_WUNLOCK() rw_wunlock(&cache_lock)
/*
* UMA zones for the VFS cache.
@@ -162,9 +165,10 @@ static u_long numposzaps; STATNODE(CTLFLAG_RD, numposzaps, &numposzaps);
static u_long numposhits; STATNODE(CTLFLAG_RD, numposhits, &numposhits);
static u_long numnegzaps; STATNODE(CTLFLAG_RD, numnegzaps, &numnegzaps);
static u_long numneghits; STATNODE(CTLFLAG_RD, numneghits, &numneghits);
+static u_long numupgrades; STATNODE(CTLFLAG_RD, numupgrades, &numupgrades);
-SYSCTL_OPAQUE(_vfs_cache, OID_AUTO, nchstats, CTLFLAG_RD, &nchstats,
- sizeof(nchstats), "LU", "VFS cache effectiveness statistics");
+SYSCTL_OPAQUE(_vfs_cache, OID_AUTO, nchstats, CTLFLAG_RD | CTLFLAG_MPSAFE,
+ &nchstats, sizeof(nchstats), "LU", "VFS cache effectiveness statistics");
@@ -200,20 +204,21 @@ sysctl_debug_hashstat_rawnchash(SYSCTL_HANDLER_ARGS)
/* Scan hash tables for applicable entries */
for (ncpp = nchashtbl; n_nchash > 0; n_nchash--, ncpp++) {
- CACHE_LOCK();
+ CACHE_RLOCK();
count = 0;
LIST_FOREACH(ncp, ncpp, nc_hash) {
count++;
}
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
error = SYSCTL_OUT(req, &count, sizeof(count));
if (error)
return (error);
}
return (0);
}
-SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnchash, CTLTYPE_INT|CTLFLAG_RD,
- 0, 0, sysctl_debug_hashstat_rawnchash, "S,int", "nchash chain lengths");
+SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnchash, CTLTYPE_INT|CTLFLAG_RD|
+ CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_rawnchash, "S,int",
+ "nchash chain lengths");
static int
sysctl_debug_hashstat_nchash(SYSCTL_HANDLER_ARGS)
@@ -234,11 +239,11 @@ sysctl_debug_hashstat_nchash(SYSCTL_HANDLER_ARGS)
/* Scan hash tables for applicable entries */
for (ncpp = nchashtbl; n_nchash > 0; n_nchash--, ncpp++) {
count = 0;
- CACHE_LOCK();
+ CACHE_RLOCK();
LIST_FOREACH(ncp, ncpp, nc_hash) {
count++;
}
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
if (count)
used++;
if (maxlength < count)
@@ -260,8 +265,9 @@ sysctl_debug_hashstat_nchash(SYSCTL_HANDLER_ARGS)
return (error);
return (0);
}
-SYSCTL_PROC(_debug_hashstat, OID_AUTO, nchash, CTLTYPE_INT|CTLFLAG_RD,
- 0, 0, sysctl_debug_hashstat_nchash, "I", "nchash chain lengths");
+SYSCTL_PROC(_debug_hashstat, OID_AUTO, nchash, CTLTYPE_INT|CTLFLAG_RD|
+ CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_nchash, "I",
+ "nchash chain lengths");
/*
* cache_zap():
@@ -275,7 +281,7 @@ cache_zap(ncp)
{
struct vnode *vp;
- mtx_assert(&cache_lock, MA_OWNED);
+ rw_assert(&cache_lock, RA_WLOCKED);
CTR2(KTR_VFS, "cache_zap(%p) vp %p", ncp, ncp->nc_vp);
vp = NULL;
LIST_REMOVE(ncp, nc_hash);
@@ -322,16 +328,19 @@ cache_lookup(dvp, vpp, cnp)
{
struct namecache *ncp;
u_int32_t hash;
- int error, ltype;
+ int error, ltype, wlocked;
if (!doingcache) {
cnp->cn_flags &= ~MAKEENTRY;
return (0);
}
retry:
- CACHE_LOCK();
+ CACHE_RLOCK();
+ wlocked = 0;
numcalls++;
+ error = 0;
+retry_wlocked:
if (cnp->cn_nameptr[0] == '.') {
if (cnp->cn_namelen == 1) {
*vpp = dvp;
@@ -344,8 +353,7 @@ retry:
dotdothits++;
if (dvp->v_dd == NULL ||
(cnp->cn_flags & MAKEENTRY) == 0) {
- CACHE_UNLOCK();
- return (0);
+ goto unlock;
}
*vpp = dvp->v_dd;
CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..",
@@ -364,23 +372,24 @@ retry:
}
/* We failed to find an entry */
- if (ncp == 0) {
+ if (ncp == NULL) {
if ((cnp->cn_flags & MAKEENTRY) == 0) {
nummisszap++;
} else {
nummiss++;
}
nchstats.ncs_miss++;
- CACHE_UNLOCK();
- return (0);
+ goto unlock;
}
/* We don't want to have an entry, so dump it */
if ((cnp->cn_flags & MAKEENTRY) == 0) {
numposzaps++;
nchstats.ncs_badhits++;
+ if (!wlocked && !CACHE_UPGRADE_LOCK())
+ goto wlock;
cache_zap(ncp);
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
return (0);
}
@@ -398,11 +407,15 @@ retry:
if (cnp->cn_nameiop == CREATE) {
numnegzaps++;
nchstats.ncs_badhits++;
+ if (!wlocked && !CACHE_UPGRADE_LOCK())
+ goto wlock;
cache_zap(ncp);
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
return (0);
}
+ if (!wlocked && !CACHE_UPGRADE_LOCK())
+ goto wlock;
numneghits++;
/*
* We found a "negative" match, so we shift it to the end of
@@ -415,9 +428,20 @@ retry:
nchstats.ncs_neghits++;
if (ncp->nc_flag & NCF_WHITE)
cnp->cn_flags |= ISWHITEOUT;
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
return (ENOENT);
+wlock:
+ /*
+ * We need to update the cache after our lookup, so upgrade to
+ * a write lock and retry the operation.
+ */
+ CACHE_RUNLOCK();
+ CACHE_WLOCK();
+ numupgrades++;
+ wlocked = 1;
+ goto retry_wlocked;
+
success:
/*
* On success we return a locked and ref'd vnode as per the lookup
@@ -425,7 +449,10 @@ success:
*/
if (dvp == *vpp) { /* lookup on "." */
VREF(*vpp);
- CACHE_UNLOCK();
+ if (wlocked)
+ CACHE_WUNLOCK();
+ else
+ CACHE_RUNLOCK();
/*
* When we lookup "." we still can be asked to lock it
* differently...
@@ -451,7 +478,10 @@ success:
VOP_UNLOCK(dvp, 0);
}
VI_LOCK(*vpp);
- CACHE_UNLOCK();
+ if (wlocked)
+ CACHE_WUNLOCK();
+ else
+ CACHE_RUNLOCK();
error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread);
if (cnp->cn_flags & ISDOTDOT)
vn_lock(dvp, ltype | LK_RETRY);
@@ -464,6 +494,13 @@ success:
ASSERT_VOP_ELOCKED(*vpp, "cache_lookup");
}
return (-1);
+
+unlock:
+ if (wlocked)
+ CACHE_WUNLOCK();
+ else
+ CACHE_RUNLOCK();
+ return (0);
}
/*
@@ -489,6 +526,12 @@ cache_enter(dvp, vp, cnp)
if (!doingcache)
return;
+ /*
+ * Avoid blowout in namecache entries.
+ */
+ if (numcache >= desiredvnodes * 2)
+ return;
+
if (cnp->cn_nameptr[0] == '.') {
if (cnp->cn_namelen == 1) {
return;
@@ -501,10 +544,10 @@ cache_enter(dvp, vp, cnp)
* cache_purge() time.
*/
if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') {
- CACHE_LOCK();
+ CACHE_WLOCK();
if (!TAILQ_EMPTY(&dvp->v_cache_dst))
dvp->v_dd = vp;
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
return;
}
}
@@ -523,31 +566,21 @@ cache_enter(dvp, vp, cnp)
hash = fnv_32_buf(cnp->cn_nameptr, len, FNV1_32_INIT);
bcopy(cnp->cn_nameptr, ncp->nc_name, len);
hash = fnv_32_buf(&dvp, sizeof(dvp), hash);
- CACHE_LOCK();
+ CACHE_WLOCK();
/*
- * See if this vnode is already in the cache with this name.
- * This can happen with concurrent lookups of the same path
- * name.
+ * See if this vnode or negative entry is already in the cache
+ * with this name. This can happen with concurrent lookups of
+ * the same path name.
*/
- if (vp) {
- TAILQ_FOREACH(n2, &vp->v_cache_dst, nc_dst) {
- if (n2->nc_dvp == dvp &&
- n2->nc_nlen == cnp->cn_namelen &&
- !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) {
- CACHE_UNLOCK();
- cache_free(ncp);
- return;
- }
- }
- } else {
- TAILQ_FOREACH(n2, &ncneg, nc_dst) {
- if (n2->nc_nlen == cnp->cn_namelen &&
- !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) {
- CACHE_UNLOCK();
- cache_free(ncp);
- return;
- }
+ ncpp = NCHHASH(hash);
+ LIST_FOREACH(n2, ncpp, nc_hash) {
+ if (n2->nc_dvp == dvp &&
+ n2->nc_nlen == cnp->cn_namelen &&
+ !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) {
+ CACHE_WUNLOCK();
+ cache_free(ncp);
+ return;
}
}
@@ -565,7 +598,6 @@ cache_enter(dvp, vp, cnp)
* Insert the new namecache entry into the appropriate chain
* within the cache entries table.
*/
- ncpp = NCHHASH(hash);
LIST_INSERT_HEAD(ncpp, ncp, nc_hash);
if (LIST_EMPTY(&dvp->v_cache_src)) {
hold = 1;
@@ -590,7 +622,7 @@ cache_enter(dvp, vp, cnp)
vhold(dvp);
if (zap)
cache_zap(ncp);
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
}
/*
@@ -621,13 +653,13 @@ cache_purge(vp)
{
CTR1(KTR_VFS, "cache_purge(%p)", vp);
- CACHE_LOCK();
+ CACHE_WLOCK();
while (!LIST_EMPTY(&vp->v_cache_src))
cache_zap(LIST_FIRST(&vp->v_cache_src));
while (!TAILQ_EMPTY(&vp->v_cache_dst))
cache_zap(TAILQ_FIRST(&vp->v_cache_dst));
vp->v_dd = NULL;
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
}
/*
@@ -641,14 +673,14 @@ cache_purgevfs(mp)
struct namecache *ncp, *nnp;
/* Scan hash tables for applicable entries */
- CACHE_LOCK();
+ CACHE_WLOCK();
for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
LIST_FOREACH_SAFE(ncp, ncpp, nc_hash, nnp) {
if (ncp->nc_dvp->v_mount == mp)
cache_zap(ncp);
}
}
- CACHE_UNLOCK();
+ CACHE_WUNLOCK();
}
/*
@@ -848,7 +880,7 @@ vn_vptocnp(struct vnode **vp, char **bp, char *buf, u_int *buflen)
int error, vfslocked;
vhold(*vp);
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
vfslocked = VFS_LOCK_GIANT((*vp)->v_mount);
vn_lock(*vp, LK_SHARED | LK_RETRY);
error = VOP_VPTOCNP(*vp, &dvp, buf, buflen);
@@ -861,10 +893,10 @@ vn_vptocnp(struct vnode **vp, char **bp, char *buf, u_int *buflen)
}
*bp = buf + *buflen;
*vp = dvp;
- CACHE_LOCK();
+ CACHE_RLOCK();
if ((*vp)->v_iflag & VI_DOOMED) {
/* forced unmount */
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
vdrop(*vp);
return (ENOENT);
}
@@ -890,7 +922,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
error = 0;
slash_prefixed = 0;
- CACHE_LOCK();
+ CACHE_RLOCK();
numfullpathcalls++;
if (vp->v_type != VDIR) {
ncp = TAILQ_FIRST(&vp->v_cache_dst);
@@ -899,7 +931,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
*--bp = ncp->nc_name[i];
if (bp == buf) {
numfullpathfail4++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
return (ENOMEM);
}
vp = ncp->nc_dvp;
@@ -913,7 +945,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
buflen--;
if (buflen < 0) {
numfullpathfail4++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
return (ENOMEM);
}
slash_prefixed = 1;
@@ -921,7 +953,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
while (vp != rdir && vp != rootvnode) {
if (vp->v_vflag & VV_ROOT) {
if (vp->v_iflag & VI_DOOMED) { /* forced unmount */
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
error = EBADF;
break;
}
@@ -930,7 +962,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
}
if (vp->v_type != VDIR) {
numfullpathfail1++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
error = ENOTDIR;
break;
}
@@ -942,7 +974,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
*--bp = ncp->nc_name[i];
if (bp == buf) {
numfullpathfail4++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
error = ENOMEM;
break;
}
@@ -957,7 +989,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
buflen--;
if (buflen < 0) {
numfullpathfail4++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
error = ENOMEM;
break;
}
@@ -968,14 +1000,14 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
if (!slash_prefixed) {
if (bp == buf) {
numfullpathfail4++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
return (ENOMEM);
} else {
*--bp = '/';
}
}
numfullpathfound++;
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
*retbuf = bp;
return (0);
@@ -987,15 +1019,15 @@ vn_commname(struct vnode *vp, char *buf, u_int buflen)
struct namecache *ncp;
int l;
- CACHE_LOCK();
+ CACHE_RLOCK();
ncp = TAILQ_FIRST(&vp->v_cache_dst);
if (!ncp) {
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
return (ENOENT);
}
l = min(ncp->nc_nlen, buflen - 1);
memcpy(buf, ncp->nc_name, l);
- CACHE_UNLOCK();
+ CACHE_RUNLOCK();
buf[l] = '\0';
return (0);
}
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index cd2b9cc..e19a386 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -87,52 +87,65 @@ extattrctl(td, uap)
AUDIT_ARG(text, attrname);
vfslocked = fnvfslocked = 0;
- /*
- * uap->filename is not always defined. If it is, grab a vnode lock,
- * which VFS_EXTATTRCTL() will later release.
- */
+ mp = NULL;
filename_vp = NULL;
if (uap->filename != NULL) {
- NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF |
- AUDITVNODE2, UIO_USERSPACE, uap->filename, td);
+ NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE2,
+ UIO_USERSPACE, uap->filename, td);
error = namei(&nd);
if (error)
return (error);
fnvfslocked = NDHASGIANT(&nd);
filename_vp = nd.ni_vp;
- NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
+ NDFREE(&nd, NDF_NO_VP_RELE);
}
/* uap->path is always defined. */
- NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE,
- uap->path, td);
+ NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF | AUDITVNODE1,
+ UIO_USERSPACE, uap->path, td);
error = namei(&nd);
- if (error) {
- if (filename_vp != NULL)
- vput(filename_vp);
+ if (error)
goto out;
- }
vfslocked = NDHASGIANT(&nd);
mp = nd.ni_vp->v_mount;
- error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
- NDFREE(&nd, 0);
+ error = vfs_busy(mp, 0);
if (error) {
- if (filename_vp != NULL)
- vput(filename_vp);
+ NDFREE(&nd, 0);
+ mp = NULL;
goto out;
}
+ VOP_UNLOCK(nd.ni_vp, 0);
+ error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
+ NDFREE(&nd, NDF_NO_VP_UNLOCK);
+ if (error)
+ goto out;
+ if (filename_vp != NULL) {
+ /*
+ * uap->filename is not always defined. If it is,
+ * grab a vnode lock, which VFS_EXTATTRCTL() will
+ * later release.
+ */
+ error = vn_lock(filename_vp, LK_EXCLUSIVE);
+ if (error) {
+ vn_finished_write(mp_writable);
+ goto out;
+ }
+ }
error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace,
uap->attrname != NULL ? attrname : NULL, td);
vn_finished_write(mp_writable);
+out:
+ if (mp != NULL)
+ vfs_unbusy(mp);
+
/*
* VFS_EXTATTRCTL will have unlocked, but not de-ref'd, filename_vp,
* so vrele it if it is defined.
*/
if (filename_vp != NULL)
vrele(filename_vp);
-out:
VFS_UNLOCK_GIANT(fnvfslocked);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 3ce65ed..4367b8c 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -165,12 +165,15 @@ vfs_register(struct vfsconf *vfc)
* preserved by re-registering the oid after modifying its
* number.
*/
+ sysctl_lock();
SLIST_FOREACH(oidp, &sysctl__vfs_children, oid_link)
if (strcmp(oidp->oid_name, vfc->vfc_name) == 0) {
sysctl_unregister_oid(oidp);
oidp->oid_number = vfc->vfc_typenum;
sysctl_register_oid(oidp);
+ break;
}
+ sysctl_unlock();
/*
* Initialise unused ``struct vfsops'' fields, to use
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 2b870f0..1f767a3 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -386,6 +386,8 @@ nmount(td, uap)
u_int iovcnt;
AUDIT_ARG(fflags, uap->flags);
+ CTR4(KTR_VFS, "%s: iovp %p with iovcnt %d and flags %d", __func__,
+ uap->iovp, uap->iovcnt, uap->flags);
/*
* Filter out MNT_ROOTFS. We do not want clients of nmount() in
@@ -400,16 +402,24 @@ nmount(td, uap)
* Check that we have an even number of iovec's
* and that we have at least two options.
*/
- if ((iovcnt & 1) || (iovcnt < 4))
+ if ((iovcnt & 1) || (iovcnt < 4)) {
+ CTR2(KTR_VFS, "%s: failed for invalid iovcnt %d", __func__,
+ uap->iovcnt);
return (EINVAL);
+ }
error = copyinuio(uap->iovp, iovcnt, &auio);
- if (error)
+ if (error) {
+ CTR2(KTR_VFS, "%s: failed for invalid uio op with %d errno",
+ __func__, error);
return (error);
+ }
iov = auio->uio_iov;
for (i = 0; i < iovcnt; i++) {
if (iov->iov_len > MMAXOPTIONLEN) {
free(auio, M_IOV);
+ CTR1(KTR_VFS, "%s: failed for invalid new auio",
+ __func__);
return (EINVAL);
}
iov++;
@@ -429,6 +439,7 @@ void
vfs_ref(struct mount *mp)
{
+ CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
MNT_ILOCK(mp);
MNT_REF(mp);
MNT_IUNLOCK(mp);
@@ -438,6 +449,7 @@ void
vfs_rel(struct mount *mp)
{
+ CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
MNT_ILOCK(mp);
MNT_REL(mp);
MNT_IUNLOCK(mp);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index eb02693..6f1cdf3 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -341,6 +341,7 @@ vfs_busy(struct mount *mp, int flags)
{
MPASS((flags & ~MBF_MASK) == 0);
+ CTR3(KTR_VFS, "%s: mp %p with flags %d", __func__, mp, flags);
MNT_ILOCK(mp);
MNT_REF(mp);
@@ -348,6 +349,8 @@ vfs_busy(struct mount *mp, int flags)
if (flags & MBF_NOWAIT || mp->mnt_kern_flag & MNTK_REFEXPIRE) {
MNT_REL(mp);
MNT_IUNLOCK(mp);
+ CTR1(KTR_VFS, "%s: failed busying before sleeping",
+ __func__);
return (ENOENT);
}
if (flags & MBF_MNTLSTLOCK)
@@ -358,6 +361,7 @@ vfs_busy(struct mount *mp, int flags)
MNT_IUNLOCK(mp);
if (flags & MBF_MNTLSTLOCK)
mtx_lock(&mountlist_mtx);
+ CTR1(KTR_VFS, "%s: failed busying after sleep", __func__);
return (ENOENT);
}
if (flags & MBF_MNTLSTLOCK)
@@ -374,11 +378,14 @@ void
vfs_unbusy(struct mount *mp)
{
+ CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
MNT_ILOCK(mp);
MNT_REL(mp);
+ KASSERT(mp->mnt_lockref > 0, ("negative mnt_lockref"));
mp->mnt_lockref--;
if (mp->mnt_lockref == 0 && (mp->mnt_kern_flag & MNTK_DRAINING) != 0) {
MPASS(mp->mnt_kern_flag & MNTK_UNMOUNT);
+ CTR1(KTR_VFS, "%s: waking up waiters", __func__);
mp->mnt_kern_flag &= ~MNTK_DRAINING;
wakeup(&mp->mnt_lockref);
}
@@ -393,6 +400,7 @@ vfs_getvfs(fsid_t *fsid)
{
struct mount *mp;
+ CTR2(KTR_VFS, "%s: fsid %p", __func__, fsid);
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
@@ -403,6 +411,7 @@ vfs_getvfs(fsid_t *fsid)
}
}
mtx_unlock(&mountlist_mtx);
+ CTR2(KTR_VFS, "%s: lookup failed for %p id", __func__, fsid);
return ((struct mount *) 0);
}
@@ -416,6 +425,7 @@ vfs_busyfs(fsid_t *fsid)
struct mount *mp;
int error;
+ CTR2(KTR_VFS, "%s: fsid %p", __func__, fsid);
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
@@ -428,6 +438,7 @@ vfs_busyfs(fsid_t *fsid)
return (mp);
}
}
+ CTR2(KTR_VFS, "%s: lookup failed for %p id", __func__, fsid);
mtx_unlock(&mountlist_mtx);
return ((struct mount *) 0);
}
@@ -498,6 +509,7 @@ vfs_getnewfsid(struct mount *mp)
fsid_t tfsid;
int mtype;
+ CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
mtx_lock(&mntid_mtx);
mtype = mp->mnt_vfc->vfc_typenum;
tfsid.val[1] = mtype;
@@ -755,14 +767,12 @@ static void
vnlru_proc(void)
{
struct mount *mp, *nmp;
- int done;
+ int done, vfslocked;
struct proc *p = vnlruproc;
EVENTHANDLER_REGISTER(shutdown_pre_sync, kproc_shutdown, p,
SHUTDOWN_PRI_FIRST);
- mtx_lock(&Giant);
-
for (;;) {
kproc_suspend_check(p);
mtx_lock(&vnode_free_list_mtx);
@@ -779,19 +789,13 @@ vnlru_proc(void)
done = 0;
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
- int vfsunlocked;
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
- if (!VFS_NEEDSGIANT(mp)) {
- mtx_unlock(&Giant);
- vfsunlocked = 1;
- } else
- vfsunlocked = 0;
+ vfslocked = VFS_LOCK_GIANT(mp);
done += vlrureclaim(mp);
- if (vfsunlocked)
- mtx_lock(&Giant);
+ VFS_UNLOCK_GIANT(vfslocked);
mtx_lock(&mountlist_mtx);
nmp = TAILQ_NEXT(mp, mnt_list);
vfs_unbusy(mp);
@@ -830,7 +834,7 @@ vdestroy(struct vnode *vp)
{
struct bufobj *bo;
- CTR1(KTR_VFS, "vdestroy vp %p", vp);
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
mtx_lock(&vnode_free_list_mtx);
numvnodes--;
mtx_unlock(&vnode_free_list_mtx);
@@ -875,20 +879,27 @@ vtryrecycle(struct vnode *vp)
{
struct mount *vnmp;
- CTR1(KTR_VFS, "vtryrecycle: trying vp %p", vp);
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
VNASSERT(vp->v_holdcnt, vp,
("vtryrecycle: Recycling vp %p without a reference.", vp));
/*
* This vnode may found and locked via some other list, if so we
* can't recycle it yet.
*/
- if (VOP_LOCK(vp, LK_EXCLUSIVE | LK_NOWAIT) != 0)
+ if (VOP_LOCK(vp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
+ CTR2(KTR_VFS,
+ "%s: impossible to recycle, vp %p lock is already held",
+ __func__, vp);
return (EWOULDBLOCK);
+ }
/*
* Don't recycle if its filesystem is being suspended.
*/
if (vn_start_write(vp, &vnmp, V_NOWAIT) != 0) {
VOP_UNLOCK(vp, 0);
+ CTR2(KTR_VFS,
+ "%s: impossible to recycle, cannot start the write for %p",
+ __func__, vp);
return (EBUSY);
}
/*
@@ -901,13 +912,15 @@ vtryrecycle(struct vnode *vp)
if (vp->v_usecount) {
VOP_UNLOCK(vp, LK_INTERLOCK);
vn_finished_write(vnmp);
+ CTR2(KTR_VFS,
+ "%s: impossible to recycle, %p is already referenced",
+ __func__, vp);
return (EBUSY);
}
if ((vp->v_iflag & VI_DOOMED) == 0)
vgonel(vp);
VOP_UNLOCK(vp, LK_INTERLOCK);
vn_finished_write(vnmp);
- CTR1(KTR_VFS, "vtryrecycle: recycled vp %p", vp);
return (0);
}
@@ -921,6 +934,7 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
struct vnode *vp = NULL;
struct bufobj *bo;
+ CTR3(KTR_VFS, "%s: mp %p with tag %s", __func__, mp, tag);
mtx_lock(&vnode_free_list_mtx);
/*
* Lend our context to reclaim vnodes if they've exceeded the max.
@@ -1003,7 +1017,6 @@ alloc:
vp->v_vflag |= VV_NOKNOTE;
}
- CTR2(KTR_VFS, "getnewvnode: mp %p vp %p", mp, vp);
*vpp = vp;
return (0);
}
@@ -1156,7 +1169,7 @@ bufobj_invalbuf(struct bufobj *bo, int flags, int slpflag, int slptimeo)
/*
* Destroy the copy in the VM cache, too.
*/
- if (bo->bo_object != NULL) {
+ if (bo->bo_object != NULL && (flags & (V_ALT | V_NORMAL)) == 0) {
VM_OBJECT_LOCK(bo->bo_object);
vm_object_page_remove(bo->bo_object, 0, 0,
(flags & V_SAVE) ? TRUE : FALSE);
@@ -1181,7 +1194,7 @@ int
vinvalbuf(struct vnode *vp, int flags, int slpflag, int slptimeo)
{
- CTR2(KTR_VFS, "vinvalbuf vp %p flags %d", vp, flags);
+ CTR3(KTR_VFS, "%s: vp %p with flags %d", __func__, vp, flags);
ASSERT_VOP_LOCKED(vp, "vinvalbuf");
return (bufobj_invalbuf(&vp->v_bufobj, flags, slpflag, slptimeo));
}
@@ -1273,7 +1286,9 @@ vtruncbuf(struct vnode *vp, struct ucred *cred, struct thread *td,
int trunclbn;
struct bufobj *bo;
- CTR2(KTR_VFS, "vtruncbuf vp %p length %jd", vp, length);
+ CTR5(KTR_VFS, "%s: vp %p with cred %p and block %d:%ju", __func__,
+ vp, cred, blksize, (uintmax_t)length);
+
/*
* Round up to the *next* lbn.
*/
@@ -1982,8 +1997,7 @@ static void
v_incr_usecount(struct vnode *vp)
{
- CTR3(KTR_VFS, "v_incr_usecount: vp %p holdcnt %d usecount %d\n",
- vp, vp->v_holdcnt, vp->v_usecount);
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
vp->v_usecount++;
if (vp->v_type == VCHR && vp->v_rdev != NULL) {
dev_lock();
@@ -2001,8 +2015,7 @@ static void
v_upgrade_usecount(struct vnode *vp)
{
- CTR3(KTR_VFS, "v_upgrade_usecount: vp %p holdcnt %d usecount %d\n",
- vp, vp->v_holdcnt, vp->v_usecount);
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
vp->v_usecount++;
if (vp->v_type == VCHR && vp->v_rdev != NULL) {
dev_lock();
@@ -2020,11 +2033,10 @@ static void
v_decr_usecount(struct vnode *vp)
{
- CTR3(KTR_VFS, "v_decr_usecount: vp %p holdcnt %d usecount %d\n",
- vp, vp->v_holdcnt, vp->v_usecount);
ASSERT_VI_LOCKED(vp, __FUNCTION__);
VNASSERT(vp->v_usecount > 0, vp,
("v_decr_usecount: negative usecount"));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
vp->v_usecount--;
if (vp->v_type == VCHR && vp->v_rdev != NULL) {
dev_lock();
@@ -2044,11 +2056,10 @@ static void
v_decr_useonly(struct vnode *vp)
{
- CTR3(KTR_VFS, "v_decr_useonly: vp %p holdcnt %d usecount %d\n",
- vp, vp->v_holdcnt, vp->v_usecount);
ASSERT_VI_LOCKED(vp, __FUNCTION__);
VNASSERT(vp->v_usecount > 0, vp,
("v_decr_useonly: negative usecount"));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
vp->v_usecount--;
if (vp->v_type == VCHR && vp->v_rdev != NULL) {
dev_lock();
@@ -2073,11 +2084,15 @@ vget(struct vnode *vp, int flags, struct thread *td)
VFS_ASSERT_GIANT(vp->v_mount);
VNASSERT((flags & LK_TYPE_MASK) != 0, vp,
("vget: invalid lock operation"));
+ CTR3(KTR_VFS, "%s: vp %p with flags %d", __func__, vp, flags);
+
if ((flags & LK_INTERLOCK) == 0)
VI_LOCK(vp);
vholdl(vp);
if ((error = vn_lock(vp, flags | LK_INTERLOCK)) != 0) {
vdrop(vp);
+ CTR2(KTR_VFS, "%s: impossible to lock vnode %p", __func__,
+ vp);
return (error);
}
if (vp->v_iflag & VI_DOOMED && (flags & LK_RETRY) == 0)
@@ -2108,6 +2123,7 @@ void
vref(struct vnode *vp)
{
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
VI_LOCK(vp);
v_incr_usecount(vp);
VI_UNLOCK(vp);
@@ -2152,6 +2168,7 @@ vrele(struct vnode *vp)
/* Skip this v_writecount check if we're going to panic below. */
VNASSERT(vp->v_writecount < vp->v_usecount || vp->v_usecount < 1, vp,
("vrele: missed vn_close"));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) &&
vp->v_usecount == 1)) {
@@ -2165,6 +2182,7 @@ vrele(struct vnode *vp)
VI_UNLOCK(vp);
panic("vrele: negative ref cnt");
}
+ CTR2(KTR_VFS, "%s: return vnode %p to the freelist", __func__, vp);
/*
* We want to hold the vnode until the inactive finishes to
* prevent vgone() races. We drop the use count here and the
@@ -2205,6 +2223,7 @@ vput(struct vnode *vp)
KASSERT(vp != NULL, ("vput: null vp"));
ASSERT_VOP_LOCKED(vp, "vput");
VFS_ASSERT_GIANT(vp->v_mount);
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
VI_LOCK(vp);
/* Skip this v_writecount check if we're going to panic below. */
VNASSERT(vp->v_writecount < vp->v_usecount || vp->v_usecount < 1, vp,
@@ -2224,6 +2243,7 @@ vput(struct vnode *vp)
#endif
panic("vput: negative ref cnt");
}
+ CTR2(KTR_VFS, "%s: return to freelist the vnode %p", __func__, vp);
/*
* We want to hold the vnode until the inactive finishes to
* prevent vgone() races. We drop the use count here and the
@@ -2265,6 +2285,7 @@ void
vholdl(struct vnode *vp)
{
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
vp->v_holdcnt++;
if (VSHOULDBUSY(vp))
vbusy(vp);
@@ -2292,11 +2313,14 @@ vdropl(struct vnode *vp)
{
ASSERT_VI_LOCKED(vp, "vdropl");
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
if (vp->v_holdcnt <= 0)
panic("vdrop: holdcnt %d", vp->v_holdcnt);
vp->v_holdcnt--;
if (vp->v_holdcnt == 0) {
if (vp->v_iflag & VI_DOOMED) {
+ CTR2(KTR_VFS, "%s: destroying the vnode %p", __func__,
+ vp);
vdestroy(vp);
return;
} else
@@ -2319,6 +2343,7 @@ vinactive(struct vnode *vp, struct thread *td)
ASSERT_VI_LOCKED(vp, "vinactive");
VNASSERT((vp->v_iflag & VI_DOINGINACT) == 0, vp,
("vinactive: recursed on VI_DOINGINACT"));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
vp->v_iflag |= VI_DOINGINACT;
vp->v_iflag &= ~VI_OWEINACT;
VI_UNLOCK(vp);
@@ -2361,7 +2386,8 @@ vflush( struct mount *mp, int rootrefs, int flags, struct thread *td)
struct vattr vattr;
int busy = 0, error;
- CTR1(KTR_VFS, "vflush: mp %p", mp);
+ CTR4(KTR_VFS, "%s: mp %p with rootrefs %d and flags %d", __func__, mp,
+ rootrefs, flags);
if (rootrefs > 0) {
KASSERT((flags & (SKIPSYSTEM | WRITECLOSE)) == 0,
("vflush: bad args"));
@@ -2369,8 +2395,11 @@ vflush( struct mount *mp, int rootrefs, int flags, struct thread *td)
* Get the filesystem root vnode. We can vput() it
* immediately, since with rootrefs > 0, it won't go away.
*/
- if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rootvp, td)) != 0)
+ if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rootvp, td)) != 0) {
+ CTR2(KTR_VFS, "%s: vfs_root lookup failed with %d",
+ __func__, error);
return (error);
+ }
vput(rootvp);
}
@@ -2457,8 +2486,11 @@ loop:
} else
VI_UNLOCK(rootvp);
}
- if (busy)
+ if (busy) {
+ CTR2(KTR_VFS, "%s: failing as %d vnodes are busy", __func__,
+ busy);
return (EBUSY);
+ }
for (; rootrefs > 0; rootrefs--)
vrele(rootvp);
return (0);
@@ -2473,6 +2505,7 @@ vrecycle(struct vnode *vp, struct thread *td)
int recycled;
ASSERT_VOP_ELOCKED(vp, "vrecycle");
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
recycled = 0;
VI_LOCK(vp);
if (vp->v_usecount == 0) {
@@ -2506,11 +2539,11 @@ vgonel(struct vnode *vp)
int active;
struct mount *mp;
- CTR1(KTR_VFS, "vgonel: vp %p", vp);
ASSERT_VOP_ELOCKED(vp, "vgonel");
ASSERT_VI_LOCKED(vp, "vgonel");
VNASSERT(vp->v_holdcnt, vp,
("vgonel: vp %p has no reference.", vp));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
td = curthread;
/*
@@ -2686,7 +2719,6 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
vp->v_object->resident_page_count);
printf(" ");
lockmgr_printinfo(vp->v_vnlock);
- printf("\n");
if (vp->v_data != NULL)
VOP_PRINT(vp);
}
@@ -3107,7 +3139,9 @@ vfs_unmountall(void)
int error;
KASSERT(curthread != NULL, ("vfs_unmountall: NULL curthread"));
+ CTR1(KTR_VFS, "%s: unmounting all filesystems", __func__);
td = curthread;
+
/*
* Since this only runs when rebooting, it is not interlocked.
*/
@@ -3148,6 +3182,7 @@ vfs_msync(struct mount *mp, int flags)
struct vnode *vp, *mvp;
struct vm_object *obj;
+ CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
MNT_ILOCK(mp);
MNT_VNODE_FOREACH(vp, mp, mvp) {
VI_LOCK(vp);
@@ -3187,7 +3222,6 @@ static void
vfree(struct vnode *vp)
{
- CTR1(KTR_VFS, "vfree vp %p", vp);
ASSERT_VI_LOCKED(vp, "vfree");
mtx_lock(&vnode_free_list_mtx);
VNASSERT(vp->v_op != NULL, vp, ("vfree: vnode already reclaimed."));
@@ -3195,6 +3229,7 @@ vfree(struct vnode *vp)
VNASSERT(VSHOULDFREE(vp), vp, ("vfree: freeing when we shouldn't"));
VNASSERT((vp->v_iflag & VI_DOOMED) == 0, vp,
("vfree: Freeing doomed vnode"));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
if (vp->v_iflag & VI_AGE) {
TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
} else {
@@ -3212,10 +3247,10 @@ vfree(struct vnode *vp)
static void
vbusy(struct vnode *vp)
{
- CTR1(KTR_VFS, "vbusy vp %p", vp);
ASSERT_VI_LOCKED(vp, "vbusy");
VNASSERT((vp->v_iflag & VI_FREE) != 0, vp, ("vnode not free"));
VNASSERT(vp->v_op != NULL, vp, ("vbusy: vnode already reclaimed."));
+ CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
mtx_lock(&vnode_free_list_mtx);
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
@@ -4206,18 +4241,14 @@ vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off)
/*
* Mark for update the access time of the file if the filesystem
- * supports VA_MARK_ATIME. This functionality is used by execve
- * and mmap, so we want to avoid the synchronous I/O implied by
- * directly setting va_atime for the sake of efficiency.
+ * supports VOP_MARKATIME. This functionality is used by execve and
+ * mmap, so we want to avoid the I/O implied by directly setting
+ * va_atime for the sake of efficiency.
*/
void
vfs_mark_atime(struct vnode *vp, struct ucred *cred)
{
- struct vattr atimeattr;
- if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0) {
- VATTR_NULL(&atimeattr);
- atimeattr.va_vaflags |= VA_MARK_ATIME;
- (void)VOP_SETATTR(vp, &atimeattr, cred);
- }
+ if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
+ (void)VOP_MARKATIME(vp);
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 4d3978a..be3dc76 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -395,14 +395,16 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
vfs_ref(mp);
VOP_UNLOCK(vp, 0);
fdrop(fp, td);
- if (vp->v_iflag & VI_DOOMED) {
+ if (mp == NULL) {
error = EBADF;
goto out;
}
error = vfs_busy(mp, 0);
vfs_rel(mp);
- if (error)
- goto out;
+ if (error) {
+ VFS_UNLOCK_GIANT(vfslocked);
+ return (error);
+ }
#ifdef MAC
error = mac_mount_check_stat(td->td_ucred, mp);
if (error)
@@ -758,7 +760,7 @@ fchdir(td, uap)
VREF(vp);
fdrop(fp, td);
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ vn_lock(vp, LK_SHARED | LK_RETRY);
AUDIT_ARG(vnode, vp, ARG_VNODE1);
error = change_dir(vp, td);
while (!error && (mp = vp->v_mountedhere) != NULL) {
@@ -766,7 +768,7 @@ fchdir(td, uap)
if (vfs_busy(mp, 0))
continue;
tvfslocked = VFS_LOCK_GIANT(mp);
- error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td);
+ error = VFS_ROOT(mp, LK_SHARED, &tdp, td);
vfs_unbusy(mp);
if (error) {
VFS_UNLOCK_GIANT(tvfslocked);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 03b8ba1..e210fee 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1286,3 +1286,35 @@ vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace,
return (error);
}
+
+int
+vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp)
+{
+ struct mount *mp;
+ int ltype, error;
+
+ mp = vp->v_mount;
+ ltype = VOP_ISLOCKED(vp);
+ KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
+ ("vn_vget_ino: vp not locked"));
+ for (;;) {
+ error = vfs_busy(mp, MBF_NOWAIT);
+ if (error == 0)
+ break;
+ VOP_UNLOCK(vp, 0);
+ pause("vn_vget", 1);
+ vn_lock(vp, ltype | LK_RETRY);
+ if (vp->v_iflag & VI_DOOMED)
+ return (ENOENT);
+ }
+ VOP_UNLOCK(vp, 0);
+ error = VFS_VGET(mp, ino, lkflags, rvp);
+ vfs_unbusy(mp);
+ vn_lock(vp, ltype | LK_RETRY);
+ if (vp->v_iflag & VI_DOOMED) {
+ if (error == 0)
+ vput(*rvp);
+ error = ENOENT;
+ }
+ return (error);
+}
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 36ea434..ad4d1f7 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -171,6 +171,11 @@ vop_setattr {
IN struct ucred *cred;
};
+%% markatime vp L L L
+
+vop_markatime {
+ IN struct vnode *vp;
+};
%% read vp L L L
diff --git a/sys/mips/idt/idtpci.c b/sys/mips/idt/idtpci.c
index c7e3161..32033d4 100644
--- a/sys/mips/idt/idtpci.c
+++ b/sys/mips/idt/idtpci.c
@@ -125,8 +125,6 @@ struct idtpci_softc {
struct rman sc_mem_rman[2];
struct rman sc_io_rman[2];
struct rman sc_irq_rman;
- uint32_t sc_mem;
- uint32_t sc_io;
};
static uint32_t
@@ -155,9 +153,6 @@ idtpci_attach(device_t dev)
sc->sc_dev = dev;
sc->sc_busno = busno;
- sc->sc_io = 0;
- sc->sc_mem = 0;
-
/* TODO: Check for host mode */
/* Enabled PCI, IG mode, EAP mode */
@@ -240,7 +235,6 @@ idtpci_attach(device_t dev)
}
/* Use KSEG1 to access IO ports for it is uncached */
- sc->sc_io = 0;
sc->sc_io_rman[0].rm_type = RMAN_ARRAY;
sc->sc_io_rman[0].rm_descr = "IDTPCI I/O Ports window 1";
if (rman_init(&sc->sc_io_rman[0]) != 0 ||
@@ -258,7 +252,6 @@ idtpci_attach(device_t dev)
}
/* Use KSEG1 to access PCI memory for it is uncached */
- sc->sc_mem = 0;
sc->sc_mem_rman[0].rm_type = RMAN_ARRAY;
sc->sc_mem_rman[0].rm_descr = "IDTPCI PCI Memory window 1";
if (rman_init(&sc->sc_mem_rman[0]) != 0 ||
diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h
index 2151348..355cca5 100644
--- a/sys/mips/include/pmap.h
+++ b/sys/mips/include/pmap.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1991 Regents of the University of California.
* All rights reserved.
*
@@ -47,10 +47,8 @@
#define _MACHINE_PMAP_H_
#include <machine/vmparam.h>
+#include <machine/pte.h>
-/*
- * Pte related macros
- */
#define VADDR(pdi, pti) ((vm_offset_t)(((pdi)<<PDRSHIFT)|((pti)<<PAGE_SHIFT)))
#define NKPT 120 /* actual number of kernel page tables */
@@ -65,11 +63,9 @@
#ifndef LOCORE
#include <sys/queue.h>
-#include <machine/pte.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
-
/*
* Pmap stuff
*/
@@ -104,10 +100,7 @@ struct pmap {
typedef struct pmap *pmap_t;
-#ifdef _KERNEL
-#include <sys/lock.h>
-#include <sys/proc.h>
-#include <vm/vm_map.h>
+#ifdef _KERNEL
pt_entry_t *pmap_pte(pmap_t, vm_offset_t);
pd_entry_t pmap_segmap(pmap_t pmap, vm_offset_t va);
@@ -132,8 +125,6 @@ extern pmap_t kernel_pmap;
#define PMAP_LGMEM_UNLOCK(sysmap) mtx_unlock(&(sysmap)->lock)
#define PMAP_LGMEM_DESTROY(sysmap) mtx_destroy(&(sysmap)->lock)
-#endif /* _KERNEL */
-
/*
* For each vm_page_t, there is a list of all currently valid virtual
* mappings of that page. An entry is a pv_entry_t, the list is pv_table.
@@ -148,18 +139,10 @@ typedef struct pv_entry {
} *pv_entry_t;
-#ifdef _KERNEL
-
#if defined(DIAGNOSTIC)
#define PMAP_DIAGNOSTIC
#endif
-#if !defined(PMAP_DIAGNOSTIC)
-#define PMAP_INLINE __inline
-#else
-#define PMAP_INLINE
-#endif
-
extern vm_offset_t avail_end;
extern vm_offset_t avail_start;
extern vm_offset_t phys_avail[];
@@ -182,9 +165,8 @@ vm_offset_t pmap_steal_memory(vm_size_t size);
void pmap_set_modified(vm_offset_t pa);
int page_is_managed(vm_offset_t pa);
void pmap_page_is_free(vm_page_t m);
-void pmap_kushmem_reattach(struct proc *);
- /* PMAP_INLINE */ void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
- /* PMAP_INLINE */ void pmap_kremove(vm_offset_t va);
+void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
+void pmap_kremove(vm_offset_t va);
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
void pmap_kenter_temporary_free(vm_paddr_t pa);
int pmap_compute_pages_to_dump(void);
diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c
index 2bb8958..e8f7ffd 100644
--- a/sys/mips/malta/gt_pci.c
+++ b/sys/mips/malta/gt_pci.c
@@ -457,21 +457,7 @@ gt_pci_write_config(device_t dev, int bus, int slot, int func, int reg,
* Should we set the mode explicitly during chip
* Initialization?
*/
- switch(reg % 4)
- {
- case 3:
- shift = 24;
- break;
- case 2:
- shift = 16;
- break;
- case 1:
- shift = 8;
- break;
- default:
- shift = 0;
- break;
- }
+ shift = 8 * (reg & 3);
switch(bytes)
{
diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c
index b51330f..ee3e170 100644
--- a/sys/mips/mips/busdma_machdep.c
+++ b/sys/mips/mips/busdma_machdep.c
@@ -25,8 +25,6 @@
*
*/
-#define NO_DMA
-
/*-
* Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
* All rights reserved.
diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c
index 6eac8f7..f9596e2 100644
--- a/sys/mips/mips/cpu.c
+++ b/sys/mips/mips/cpu.c
@@ -22,9 +22,11 @@
* 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/kernel.h>
#include <sys/module.h>
@@ -132,6 +134,8 @@ mips_cpu_init(void)
mips_icache_sync_all();
mips_dcache_wbinv_all();
+ /* Print some info about CPU */
+ cpu_identify();
}
void
diff --git a/sys/mips/mips/elf64_machdep.c b/sys/mips/mips/elf64_machdep.c
new file mode 100644
index 0000000..e5a2f5d
--- /dev/null
+++ b/sys/mips/mips/elf64_machdep.c
@@ -0,0 +1,117 @@
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * 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.
+ *
+ * from: src/sys/i386/i386/elf_machdep.c,v 1.20 2004/08/11 02:35:05 marcel
+ */
+
+#define __ELF_WORD_SIZE 64
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/linker.h>
+#include <sys/sysent.h>
+#include <sys/imgact_elf.h>
+#include <sys/syscall.h>
+#include <sys/signalvar.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+
+#include <machine/elf.h>
+#include <machine/md_var.h>
+
+struct sysentvec elf64_freebsd_sysvec = {
+ .sv_size = SYS_MAXSYSCALL,
+ .sv_table = sysent,
+ .sv_mask = 0,
+ .sv_sigsize = 0,
+ .sv_sigtbl = NULL,
+ .sv_errsize = 0,
+ .sv_errtbl = NULL,
+ .sv_transtrap = NULL,
+ .sv_fixup = __elfN(freebsd_fixup),
+ .sv_sendsig = sendsig,
+ .sv_sigcode = sigcode,
+ .sv_szsigcode = &szsigcode,
+ .sv_prepsyscall = NULL,
+ .sv_name = "FreeBSD ELF64",
+ .sv_coredump = __elfN(coredump),
+ .sv_imgact_try = NULL,
+ .sv_minsigstksz = MINSIGSTKSZ,
+ .sv_pagesize = PAGE_SIZE,
+ .sv_minuser = VM_MIN_ADDRESS,
+ .sv_maxuser = VM_MAXUSER_ADDRESS,
+ .sv_usrstack = USRSTACK,
+ .sv_psstrings = PS_STRINGS,
+ .sv_stackprot = VM_PROT_ALL,
+ .sv_copyout_strings = exec_copyout_strings,
+ .sv_setregs = exec_setregs,
+ .sv_fixlimit = NULL,
+ .sv_maxssiz = NULL,
+ .sv_flags = SV_ABI_FREEBSD | SV_LP64
+};
+
+static Elf64_Brandinfo freebsd_brand_gnutools_info64 = {
+ .brand = ELFOSABI_NONE,
+ .machine = EM_MIPS,
+ .compat_3_brand = "Unix System V ABI",
+ .emul_path = NULL,
+ .interp_path = "/libexec/ld-elf.so.1",
+ .sysvec = &elf64_freebsd_sysvec,
+ .interp_path = "/libexec/ld-elf.so.1",
+ .flags = BI_CAN_EXEC_DYN
+};
+
+SYSINIT(gnu_mips_elf64, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t) elf64_insert_brand_entry,
+ &freebsd_brand_gnutools_info64);
+
+static Elf64_Brandinfo freebsd_brand_info64 = {
+ .brand = ELFOSABI_FREEBSD,
+ .machine = EM_MIPS,
+ .compat_3_brand = "FreeBSD",
+ .emul_path = NULL,
+ .interp_path = "/libexec/ld-elf.so.1",
+ .sysvec = &elf64_freebsd_sysvec,
+ .interp_newpath = NULL,
+ .flags = 0
+};
+
+SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t) elf64_insert_brand_entry,
+ &freebsd_brand_info64);
+
+void
+elf64_dump_thread(struct thread *td __unused, void *dst __unused,
+ size_t *off __unused)
+{
+}
diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c
index 501162f..9aa3044 100644
--- a/sys/mips/mips/machdep.c
+++ b/sys/mips/mips/machdep.c
@@ -36,7 +36,7 @@
*
* from: @(#)machdep.c 8.3 (Berkeley) 1/12/94
* Id: machdep.c,v 1.33 1998/09/15 10:58:54 pefo Exp
- * JNPR: machdep.c,v 1.11.2.3 2007/08/29 12:24:49 girish
+ * JNPR: machdep.c,v 1.11.2.3 2007/08/29 12:24:49
*/
#include <sys/cdefs.h>
@@ -82,12 +82,10 @@ __FBSDID("$FreeBSD$");
#include <machine/pltfm.h>
#include <net/netisr.h>
#include <machine/md_var.h>
-#if 0
-#include <machine/defs.h>
-#endif
#include <machine/clock.h>
#include <machine/asm.h>
#include <machine/bootinfo.h>
+#include <machine/hwfunc.h>
#ifdef DDB
#include <sys/kdb.h>
#include <ddb/ddb.h>
@@ -104,12 +102,7 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "Machine class")
static char cpu_model[30];
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "Machine model");
-#if 0 /* see comment below */
-static void getmemsize(void);
-#endif
-
int cold = 1;
-int Maxmem;
long realmem = 0;
int cpu_clock = MIPS_DEFAULT_HZ;
SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
@@ -165,12 +158,10 @@ cpu_startup(void *dummy)
if (boothowto & RB_VERBOSE)
bootverbose++;
- /*
- * Good {morning,afternoon,evening,night}.
- */
- printf("real memory = %lu (%luK bytes)\n", ptoa(Maxmem),
- ptoa(Maxmem) / 1024);
- realmem = Maxmem;
+ bootverbose++;
+ printf("real memory = %lu (%luK bytes)\n", ptoa(realmem),
+ ptoa(realmem) / 1024);
+
/*
* Display any holes after the first chunk of extended memory.
*/
@@ -205,8 +196,8 @@ cpu_startup(void *dummy)
void
cpu_reset(void)
{
- for (;;)
- ;
+
+ platform_reset();
}
/* Get current clock frequency for the given cpu id. */
@@ -214,7 +205,7 @@ int
cpu_est_clockrate(int cpu_id, uint64_t *rate)
{
- return (ENXIO);
+ return (ENXIO);
}
/*
@@ -227,8 +218,10 @@ cpu_halt(void)
;
}
-#ifdef PORT_TO_JMIPS
+SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, CTLFLAG_RD, &bootinfo,
+ bootinfo, "Bootinfo struct: kernel filename, BIOS harddisk geometry, etc");
+#ifdef PORT_TO_JMIPS
static int
sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS)
{
@@ -237,19 +230,8 @@ sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT | CTLFLAG_RW,
&adjkerntz, 0, sysctl_machdep_adjkerntz, "I",
"Local offset from GMT in seconds");
-#endif /* PORT_TO_JMIPS */
-
-#ifdef PORT_TO_JMIPS
-/* art */
SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, CTLFLAG_RW,
&disable_rtc_set, 0, "Disable setting the real time clock to system time");
-#endif /* PORT_TO_JMIPS */
-
-SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, CTLFLAG_RD, &bootinfo,
- bootinfo, "Bootinfo struct: kernel filename, BIOS harddisk geometry, etc");
-
-#ifdef PORT_TO_JMIPS
-/* dchu */
SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW,
&wall_cmos_clock, 0, "Wall CMOS clock assumed");
#endif /* PORT_TO_JMIPS */
@@ -257,7 +239,6 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW,
/*
* Initialize mips and configure to run kernel
*/
-
void
mips_proc0_init(void)
{
@@ -282,6 +263,7 @@ mips_proc0_init(void)
thread0.td_pcb = (struct pcb *)(thread0.td_md.md_realstack +
(thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1;
thread0.td_frame = &thread0.td_pcb->pcb_regs;
+
/*
* There is no need to initialize md_upte array for thread0 as it's
* located in .bss section and should be explicitly zeroed during
@@ -294,116 +276,6 @@ mips_proc0_init(void)
struct msgbuf *msgbufp=0;
-#if 0
-/*
- * This code has been moved to the platform_init code. The only
- * thing that's beign done here that hasn't been moved is the wired tlb
- * pool stuff. I'm still trying to understand that feature..., since
- * it maps from the end the kernel to 0x08000000 somehow. But the stuff
- * was stripped out, so it is hard to say what's going on....
- */
-u_int32_t freemem_start;
-
-static void
-getmemsize()
-{
- vm_offset_t kern_start, kern_end;
- vm_offset_t AllowMem, memsize;
- const char *cp;
- size_t sz;
- int phys_avail_cnt;
-
- /* Determine memory layout */
- phys_avail_cnt = 0;
- kern_start = mips_trunc_page(MIPS_CACHED_TO_PHYS(btext));
- if (kern_start < freemem_start)
-panic("kernel load address too low, overlapping with memory reserved for FPC IPC\n");
-
- if (kern_start > freemem_start) {
- phys_avail[phys_avail_cnt++] = freemem_start;
- /*
- * Since the stack is setup just before kern_start,
- * leave some space for stack to grow
- */
- phys_avail[phys_avail_cnt++] = kern_start - PAGE_SIZE * 3;
- MIPS_DEBUG_PRINT("phys_avail : %p - %p", \
- phys_avail[phys_avail_cnt-2], phys_avail[phys_avail_cnt-1]);
- }
-
- kern_end = (vm_offset_t) end;
- kern_end = (vm_offset_t) mips_round_page(kern_end);
- MIPS_DEBUG_PRINT("kern_start : 0x%x, kern_end : 0x%x", btext, kern_end);
- phys_avail[phys_avail_cnt++] = MIPS_CACHED_TO_PHYS(kern_end);
-
- if (need_wired_tlb_page_pool) {
- mips_wired_tlb_physmem_start = MIPS_CACHED_TO_PHYS(kern_end);
- mips_wired_tlb_physmem_end = 0x08000000;
- MIPS_DEBUG_PRINT("%s: unmapped page start [0x%x] end[0x%x]\n",\
- __FUNCTION__, mips_wired_tlb_physmem_start, \
- mips_wired_tlb_physmem_end);
- if (mips_wired_tlb_physmem_start > mips_wired_tlb_physmem_end)
- panic("Error in Page table page physical address assignment\n");
- }
-
- if (bootinfo.bi_memsizes_valid)
- memsize = bootinfo.bi_basemem * 1024;
- else {
- memsize = SDRAM_MEM_SIZE;
- }
-
- /*
- * hw.physmem is a size in bytes; we also allow k, m, and g suffixes
- * for the appropriate modifiers.
- */
- if ((cp = getenv("hw.physmem")) != NULL) {
- vm_offset_t sanity;
- char *ep;
-
- sanity = AllowMem = strtouq(cp, &ep, 0);
- if ((ep != cp) && (*ep != 0)) {
- switch(*ep) {
- case 'g':
- case 'G':
- AllowMem <<= 10;
- case 'm':
- case 'M':
- AllowMem <<= 10;
- case 'k':
- case 'K':
- AllowMem <<= 10;
- break;
- default:
- AllowMem = sanity = 0;
- }
- if (AllowMem < sanity)
- AllowMem = 0;
- }
- if (!AllowMem || (AllowMem < (kern_end - KERNBASE)))
- printf("Ignoring invalid hw.physmem size of '%s'\n", cp);
- } else
- AllowMem = 0;
-
- if (AllowMem)
- memsize = (memsize > AllowMem) ? AllowMem : memsize;
-
- phys_avail[phys_avail_cnt++] = SDRAM_ADDR_START + memsize;
- MIPS_DEBUG_PRINT("phys_avail : 0x%x - 0x%x", \
- phys_avail[phys_avail_cnt-2], phys_avail[phys_avail_cnt-1]);
- phys_avail[phys_avail_cnt] = 0;
-
- physmem = btoc(memsize);
- Maxmem = physmem;
-
- /*
- * Initialize error message buffer (at high end of memory).
- */
- sz = round_page(MSGBUF_SIZE);
- msgbufp = (struct msgbuf *) pmap_steal_memory(sz);
- msgbufinit(msgbufp, sz);
- printf("%s: msgbufp[size=%d] = 0x%p\n", __FUNCTION__, sz, msgbufp);
-}
-#endif
-
/*
* Initialize the hardware exception vectors, and the jump table used to
* call locore cache and TLB management functions, based on the kind
@@ -489,7 +361,6 @@ set_dbregs(struct thread *td, struct dbreg *dbregs)
return (ENOSYS);
}
-int spinco;
void
spinlock_enter(void)
{
@@ -535,16 +406,16 @@ cpu_idle(int busy)
panic("ints disabled in idleproc!");
}
-int
-cpu_idle_wakeup(int cpu)
+void
+dumpsys(struct dumperinfo *di __unused)
{
- return (0);
+ printf("Kernel dumps not implemented on this architecture\n");
}
-void
-dumpsys(struct dumperinfo *di __unused)
+int
+cpu_idle_wakeup(int cpu)
{
- printf("Kernel dumps not implemented on this architecture\n");
+ return (0);
}
diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c
index 8ee4bcf..64cba66 100644
--- a/sys/mips/mips/nexus.c
+++ b/sys/mips/mips/nexus.c
@@ -58,6 +58,12 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/vmparam.h>
+#ifdef NEXUS_DEBUG
+#define dprintf printf
+#else
+#define dprintf(x, arg...)
+#endif /* NEXUS_DEBUG */
+
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
@@ -253,7 +259,7 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit)
resource_long_value(dname, dunit, "maddr", &maddr);
resource_int_value(dname, dunit, "msize", &msize);
- printf("%s: discovered hinted child %s at maddr %p(%d)\n",
+ dprintf("%s: discovered hinted child %s at maddr %p(%d)\n",
__func__, device_get_nameunit(child),
(void *)(intptr_t)maddr, msize);
@@ -298,10 +304,10 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct rman *rm;
int isdefault, needactivate, passthrough;
- printf("%s: entry (%p, %p, %d, %p, %p, %p, %ld, %d)\n",
+ dprintf("%s: entry (%p, %p, %d, %p, %p, %p, %ld, %d)\n",
__func__, bus, child, type, rid, (void *)(intptr_t)start,
(void *)(intptr_t)end, count, flags);
- printf("%s: requested rid is %d\n", __func__, *rid);
+ dprintf("%s: requested rid is %d\n", __func__, *rid);
isdefault = (start == 0UL && end == ~0UL && count == 1);
needactivate = flags & RF_ACTIVE;
@@ -408,7 +414,7 @@ nexus_set_resource(device_t dev, device_t child, int type, int rid,
struct resource_list *rl = &ndev->nx_resources;
struct resource_list_entry *rle;
- printf("%s: entry (%p, %p, %d, %d, %p, %ld)\n",
+ dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n",
__func__, dev, child, type, rid, (void *)(intptr_t)start, count);
rle = resource_list_add(rl, type, rid, start, start + count - 1,
@@ -443,7 +449,7 @@ nexus_delete_resource(device_t dev, device_t child, int type, int rid)
struct nexus_device *ndev = DEVTONX(child);
struct resource_list *rl = &ndev->nx_resources;
- printf("%s: entry\n", __func__);
+ dprintf("%s: entry\n", __func__);
resource_list_delete(rl, type, rid);
}
@@ -452,7 +458,7 @@ static int
nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- printf("%s: entry\n", __func__);
+ dprintf("%s: entry\n", __func__);
if (rman_get_flags(r) & RF_ACTIVE) {
int error = bus_deactivate_resource(child, type, rid, r);
diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
index 7256fc2..082cac1 100644
--- a/sys/mips/mips/pmap.c
+++ b/sys/mips/mips/pmap.c
@@ -103,6 +103,8 @@ __FBSDID("$FreeBSD$");
#define PMAP_DIAGNOSTIC
#endif
+#undef PMAP_DEBUG
+
#ifndef PMAP_SHPGPERPROC
#define PMAP_SHPGPERPROC 200
#endif
@@ -488,7 +490,6 @@ pmap_nw_modified(pt_entry_t pte)
#endif
-
static void
pmap_invalidate_all(pmap_t pmap)
{
@@ -672,6 +673,9 @@ pmap_kenter(vm_offset_t va, vm_paddr_t pa)
register pt_entry_t *pte;
pt_entry_t npte, opte;
+#ifdef PMAP_DEBUG
+ printf("pmap_kenter: va: 0x%08x -> pa: 0x%08x\n", va, pa);
+#endif
npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W;
if (is_cacheable_mem(pa))
@@ -1778,6 +1782,9 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t fault_type, vm_page_t m, vm_pr
validate:
rw = init_pte_prot(va, m, prot);
+#ifdef PMAP_DEBUG
+ printf("pmap_enter: va: 0x%08x -> pa: 0x%08x\n", va, pa);
+#endif
/*
* Now validate mapping with desired protection/wiring.
*/
@@ -2147,9 +2154,10 @@ pmap_zero_page(vm_page_t m)
#endif
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_CACHED(phys);
+ va = MIPS_PHYS_TO_UNCACHED(phys);
bzero((caddr_t)va, PAGE_SIZE);
+ mips_dcache_wbinv_range(va, PAGE_SIZE);
} else {
int cpu;
struct local_sysmaps *sysm;
@@ -2202,8 +2210,9 @@ pmap_zero_page_area(vm_page_t m, int off, int size)
} else
#endif
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_CACHED(phys);
+ va = MIPS_PHYS_TO_UNCACHED(phys);
bzero((char *)(caddr_t)va + off, size);
+ mips_dcache_wbinv_range(va + off, size);
} else {
int cpu;
struct local_sysmaps *sysm;
@@ -2240,8 +2249,9 @@ pmap_zero_page_idle(vm_page_t m)
} else
#endif
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
- va = MIPS_PHYS_TO_CACHED(phys);
+ va = MIPS_PHYS_TO_UNCACHED(phys);
bzero((caddr_t)va, PAGE_SIZE);
+ mips_dcache_wbinv_range(va, PAGE_SIZE);
} else {
int cpu;
struct local_sysmaps *sysm;
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 97d7cf2..0bc256b 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -299,6 +299,7 @@ SUBDIR= ${_3dfx} \
uplcom \
ural \
urio \
+ ${_urtw} \
usb \
usb2 \
uscanner \
@@ -438,6 +439,7 @@ _stg= stg
_streams= streams
_tmpfs= tmpfs
_upgt= upgt
+_urtw= urtw
_wi= wi
_xe= xe
.if ${MK_ZFS} != "no" || defined(ALL_MODULES)
@@ -553,6 +555,11 @@ _nxge= nxge
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
_opensolaris= opensolaris
.endif
+.if ${MK_CRYPT} != "no" || defined(ALL_MODULES)
+.if exists(${.CURDIR}/../crypto/via)
+_padlock= padlock
+.endif
+.endif
_pccard= pccard
_rdma= rdma
_safe= safe
@@ -564,6 +571,7 @@ _sppp= sppp
_tmpfs= tmpfs
_twa= twa
_upgt= upgt
+_urtw= urtw
_wi= wi
_wpi= wpi
_wpifw= wpifw
diff --git a/sys/modules/agp/Makefile b/sys/modules/agp/Makefile
index 4e2735e..0411363 100644
--- a/sys/modules/agp/Makefile
+++ b/sys/modules/agp/Makefile
@@ -12,7 +12,7 @@ SRCS+= agp_i810.c agp_intel.c agp_via.c agp_sis.c agp_ali.c agp_amd.c \
SRCS+= agp_amd64.c
.endif
.if ${MACHINE_ARCH} == "amd64"
-SRCS+= agp_amd64.c agp_i810.c
+SRCS+= agp_amd64.c agp_i810.c agp_via.c
.endif
SRCS+= device_if.h bus_if.h agp_if.h pci_if.h
SRCS+= opt_bus.h
diff --git a/sys/modules/iwnfw/Makefile b/sys/modules/iwnfw/Makefile
index 66a55be..498afcf 100644
--- a/sys/modules/iwnfw/Makefile
+++ b/sys/modules/iwnfw/Makefile
@@ -4,7 +4,6 @@
KMOD= iwnfw
FIRMWS= iwlwifi-4965-4.44.17.fw:iwnfw:44417
-FIRMWARE_LICENSE= intel_iwn
CLEANFILES= iwlwifi-4965-4.44.17.fw
diff --git a/sys/modules/sound/driver/Makefile b/sys/modules/sound/driver/Makefile
index 27c3dbe..f070119 100644
--- a/sys/modules/sound/driver/Makefile
+++ b/sys/modules/sound/driver/Makefile
@@ -1,15 +1,22 @@
# $FreeBSD$
+SUBDIR= ad1816 als4000 atiixp cs4281 csa ds1 emu10k1 emu10kx
+SUBDIR+= envy24 envy24ht es137x ess fm801 hda ich maestro maestro3
+SUBDIR+= neomagic sb16 sb8 sbc solo spicds t4dwave via8233
+SUBDIR+= via82c686 vibes driver uaudio
+
+.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64"
+SUBDIR+= cmi mss
+.endif
+
.if ${MACHINE_ARCH} == "sparc64"
.if ${MACHINE} == "sparc64"
-audiocs= audiocs
+SUBDIR+= audiocs
.endif
-SUBDIR= ${audiocs} es137x
-.else
-SUBDIR= ad1816 als4000 atiixp cmi cs4281 csa ds1 emu10k1 emu10kx
-SUBDIR+= envy24 envy24ht es137x ess fm801 hda ich maestro maestro3
-SUBDIR+= mss neomagic sb16 sb8 sbc solo spicds t4dwave via8233
-SUBDIR+= via82c686 vibes driver uaudio
+.endif
+
+.if ${MACHINE_ARCH} == "powerpc"
+SUBDIR+= ai2s davbus
.endif
.include <bsd.subdir.mk>
diff --git a/sys/modules/sound/driver/ai2s/Makefile b/sys/modules/sound/driver/ai2s/Makefile
new file mode 100644
index 0000000..d693ddf
--- /dev/null
+++ b/sys/modules/sound/driver/ai2s/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../dev/sound/macio
+
+KMOD= snd_ai2s
+SRCS= device_if.h bus_if.h ofw_bus_if.h
+SRCS+= channel_if.h feeder_if.h mixer_if.h
+SRCS+= snapper.c tumbler.c aoa.c i2s.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/sound/driver/au88x0/Makefile b/sys/modules/sound/driver/au88x0/Makefile
deleted file mode 100644
index b00a90f4..0000000
--- a/sys/modules/sound/driver/au88x0/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../../../dev/sound/pci
-
-KMOD= snd_au88x0
-SRCS= device_if.h bus_if.h pci_if.h
-SRCS+= au88x0.c
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/sound/driver/davbus/Makefile b/sys/modules/sound/driver/davbus/Makefile
new file mode 100644
index 0000000..b5616fe
--- /dev/null
+++ b/sys/modules/sound/driver/davbus/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../dev/sound/macio
+
+KMOD= snd_davbus
+SRCS= device_if.h bus_if.h ofw_bus_if.h
+SRCS+= channel_if.h feeder_if.h mixer_if.h
+SRCS+= aoa.c davbus.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/urtw/Makefile b/sys/modules/urtw/Makefile
new file mode 100644
index 0000000..3857e4a
--- /dev/null
+++ b/sys/modules/urtw/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../dev/usb
+
+KMOD = if_urtw
+SRCS = if_urtw.c if_urtwvar.h if_urtwreg.h opt_usb.h device_if.h \
+ bus_if.h usbdevs.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/usb2/Makefile b/sys/modules/usb2/Makefile
index 8785d65..f0e1340 100644
--- a/sys/modules/usb2/Makefile
+++ b/sys/modules/usb2/Makefile
@@ -30,7 +30,9 @@ SUBDIR += bluetooth
SUBDIR += bluetooth_ng
SUBDIR += bluetooth_fw
SUBDIR += controller
+.if ${MACHINE_ARCH} == "arm"
SUBDIR += controller_at91dci
+.endif
SUBDIR += controller_ehci
SUBDIR += controller_musb
SUBDIR += controller_ohci
@@ -57,7 +59,7 @@ SUBDIR += misc_fm
SUBDIR += quirk
SUBDIR += scanner
SUBDIR += serial
-#SUBDIR += serial_3g
+SUBDIR += serial_3g
SUBDIR += serial_ark
SUBDIR += serial_bsa
SUBDIR += serial_bser
@@ -87,4 +89,3 @@ SUBDIR += wlan_rum
SUBDIR += wlan_zyd
.include <bsd.subdir.mk>
-
diff --git a/sys/modules/usb2/controller_atmegadci/Makefile b/sys/modules/usb2/controller_atmegadci/Makefile
new file mode 100644
index 0000000..24845be0
--- /dev/null
+++ b/sys/modules/usb2/controller_atmegadci/Makefile
@@ -0,0 +1,41 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+S=${.CURDIR}/../../..
+
+.PATH: $S/dev/usb2/controller
+
+KMOD=usb2_controller_atmegadci
+SRCS=
+SRCS+= bus_if.h usb2_if.h device_if.h vnode_if.h
+SRCS+= opt_usb.h pci_if.h opt_bus.h card_if.h
+SRCS+= atmegadci.c
+.if defined(HAS_ATMELARM)
+SRCS+= atmegadci_atmelarm.c
+.endif
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/usb2/serial_3g/Makefile b/sys/modules/usb2/serial_3g/Makefile
new file mode 100644
index 0000000..1361083
--- /dev/null
+++ b/sys/modules/usb2/serial_3g/Makefile
@@ -0,0 +1,38 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+S=${.CURDIR}/../../..
+
+.PATH: $S/dev/usb2/serial
+
+KMOD=usb2_serial_3g
+SRCS=
+SRCS+= bus_if.h usb2_if.h device_if.h vnode_if.h
+SRCS+= opt_usb.h opt_bus.h opt_compat.h
+SRCS+= u3g2.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/net/if.c b/sys/net/if.c
index 070202c..6966a51 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -97,6 +97,8 @@ struct vnet_net vnet_net_0;
#endif
#endif
+static int slowtimo_started;
+
SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
@@ -124,6 +126,7 @@ static int ifconf(u_long, caddr_t);
static void if_freemulti(struct ifmultiaddr *);
static void if_grow(void);
static void if_init(void *);
+static void if_check(void *);
static void if_qflush(struct ifnet *);
static void if_route(struct ifnet *, int flag, int fam);
static int if_setflag(struct ifnet *, int, int, int *, int);
@@ -185,7 +188,7 @@ VNET_MOD_DECLARE(NET, net, vnet_net_iattach, vnet_net_idetach,
* System initialization
*/
SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL);
-SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_slowtimo, NULL);
+SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_check, NULL);
MALLOC_DEFINE(M_IFNET, "ifnet", "interface internals");
MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
@@ -425,6 +428,18 @@ if_grow(void)
V_ifindex_table = e;
}
+static void
+if_check(void *dummy __unused)
+{
+
+ /*
+ * If at least one interface added during boot uses
+ * if_watchdog then start the timer.
+ */
+ if (slowtimo_started)
+ if_slowtimo(0);
+}
+
/*
* Allocate a struct ifnet and an index for an interface. A layer 2
* common structure will also be allocated if an allocation routine is
@@ -647,9 +662,17 @@ if_attach(struct ifnet *ifp)
/* Announce the interface. */
rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
- if (ifp->if_watchdog != NULL)
+ if (ifp->if_watchdog != NULL) {
if_printf(ifp,
"WARNING: using obsoleted if_watchdog interface\n");
+
+ /*
+ * Note that we need if_slowtimo(). If this happens after
+ * boot, then call if_slowtimo() directly.
+ */
+ if (atomic_cmpset_int(&slowtimo_started, 0, 1) && !cold)
+ if_slowtimo(0);
+ }
if (ifp->if_flags & IFF_NEEDSGIANT)
if_printf(ifp,
"WARNING: using obsoleted IFF_NEEDSGIANT flag\n");
@@ -2248,8 +2271,7 @@ again:
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct sockaddr *sa = ifa->ifa_addr;
- if (jailed(curthread->td_ucred) &&
- !prison_if(curthread->td_ucred, sa))
+ if (prison_if(curthread->td_ucred, sa) != 0)
continue;
addrs++;
#ifdef COMPAT_43
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 73a08dd..e74bb74 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -299,6 +299,8 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID);
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+ csum_flags |= CSUM_SCTP_VALID;
m->m_pkthdr.csum_flags |= csum_flags;
m->m_pkthdr.csum_data = 0xffff;
return (if_simloop(ifp, m, dst->sa_family, 0));
@@ -339,6 +341,8 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID);
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+ csum_flags |= CSUM_SCTP_VALID;
if (m->m_flags & M_BCAST) {
struct mbuf *n;
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index a3d1b05..2287f92 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -219,10 +219,11 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
log(LOG_INFO, "%s: RTM_ADD publish "
"(proxy only) is invalid\n",
__func__);
- RTFREE(rt);
+ if (rt)
+ RTFREE_LOCKED(rt);
return EINVAL;
}
- RTFREE(rt);
+ RTFREE_LOCKED(rt);
flags |= LLE_PROXY;
}
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 4b42527..6ba0aff 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -38,6 +38,7 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipx.h"
+#include "opt_mac.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,6 +83,8 @@
#include <netatalk/at_var.h>
#endif
+#include <security/mac/mac_framework.h>
+
#ifdef TINY_LOMTU
#define LOMTU (1024+512)
#elif defined(LARGE_LOMTU)
@@ -176,9 +179,20 @@ looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct rtentry *rt)
{
u_int32_t af;
+#ifdef MAC
+ int error;
+#endif
M_ASSERTPKTHDR(m); /* check if we have the packet header */
+#ifdef MAC
+ error = mac_ifnet_check_transmit(ifp, m);
+ if (error) {
+ m_freem(m);
+ return (error);
+ }
+#endif
+
if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
m_freem(m);
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
@@ -230,6 +244,10 @@ if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen)
m_tag_delete_nonpersistent(m);
m->m_pkthdr.rcvif = ifp;
+#ifdef MAC
+ mac_ifnet_create_mbuf(ifp, m);
+#endif
+
/*
* Let BPF see incoming packet in the following manner:
* - Emulated packet loopback for a simplex interface
diff --git a/sys/net/route.c b/sys/net/route.c
index 1f3e096..e06c059 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -350,7 +350,7 @@ rtfree(struct rtentry *rt)
*/
RT_REMREF(rt);
if (rt->rt_refcnt > 0) {
- log(LOG_DEBUG, "%s: %p has %d refs\t", __func__, rt, rt->rt_refcnt);
+ log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt);
goto done;
}
diff --git a/sys/net/route.h b/sys/net/route.h
index ed43496..44b04ac 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -173,7 +173,8 @@ struct ortentry {
/* 0x80 unused, was RTF_DELCLONE */
/* 0x100 unused, was RTF_CLONING */
#define RTF_XRESOLVE 0x200 /* external daemon resolves name */
-/* 0x400 unused, was RTF_LLINFO */
+#define RTF_LLINFO 0x400 /* DEPRECATED - exists ONLY for backward
+ compatibility */
#define RTF_LLDATA 0x400 /* used by apps to add/del L2 entries */
#define RTF_STATIC 0x800 /* manually added */
#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 3c1436c..91aec20 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -31,6 +31,7 @@
*/
#include "opt_sctp.h"
#include "opt_mpath.h"
+#include "opt_route.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -336,55 +337,48 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
struct rtentry *rt, union sockaddr_union *saun, struct ucred *cred)
{
+ /* First, see if the returned address is part of the jail. */
+ if (prison_if(cred, rt->rt_ifa->ifa_addr) == 0) {
+ info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+ return (0);
+ }
+
switch (info->rti_info[RTAX_DST]->sa_family) {
#ifdef INET
case AF_INET:
{
struct in_addr ia;
+ struct ifaddr *ifa;
+ int found;
+ found = 0;
/*
- * 1. Check if the returned address is part of the jail.
+ * Try to find an address on the given outgoing interface
+ * that belongs to the jail.
*/
- ia = ((struct sockaddr_in *)rt->rt_ifa->ifa_addr)->sin_addr;
- if (prison_check_ip4(cred, &ia) != 0) {
- info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
-
- } else {
- struct ifaddr *ifa;
- int found;
-
- found = 0;
-
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ struct sockaddr *sa;
+ sa = ifa->ifa_addr;
+ if (sa->sa_family != AF_INET)
+ continue;
+ ia = ((struct sockaddr_in *)sa)->sin_addr;
+ if (prison_check_ip4(cred, &ia) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
/*
- * 2. Try to find an address on the given outgoing
- * interface that belongs to the jail.
+ * As a last resort return the 'default' jail address.
*/
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- struct sockaddr *sa;
- sa = ifa->ifa_addr;
- if (sa->sa_family != AF_INET)
- continue;
- ia = ((struct sockaddr_in *)sa)->sin_addr;
- if (prison_check_ip4(cred, &ia) != 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- /*
- * 3. As a last resort return the 'default'
- * jail address.
- */
- if (prison_getip4(cred, &ia) != 0)
- return (ESRCH);
- }
- bzero(&saun->sin, sizeof(struct sockaddr_in));
- saun->sin.sin_len = sizeof(struct sockaddr_in);
- saun->sin.sin_family = AF_INET;
- saun->sin.sin_addr.s_addr = ia.s_addr;
- info->rti_info[RTAX_IFA] =
- (struct sockaddr *)&saun->sin;
+ if (prison_get_ip4(cred, &ia) != 0)
+ return (ESRCH);
}
+ bzero(&saun->sin, sizeof(struct sockaddr_in));
+ saun->sin.sin_len = sizeof(struct sockaddr_in);
+ saun->sin.sin_family = AF_INET;
+ saun->sin.sin_addr.s_addr = ia.s_addr;
+ info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin;
break;
}
#endif
@@ -392,54 +386,40 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
case AF_INET6:
{
struct in6_addr ia6;
+ struct ifaddr *ifa;
+ int found;
+ found = 0;
/*
- * 1. Check if the returned address is part of the jail.
+ * Try to find an address on the given outgoing interface
+ * that belongs to the jail.
*/
- bcopy(&((struct sockaddr_in6 *)rt->rt_ifa->ifa_addr)->sin6_addr,
- &ia6, sizeof(struct in6_addr));
- if (prison_check_ip6(cred, &ia6) != 0) {
- info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
- } else {
- struct ifaddr *ifa;
- int found;
-
- found = 0;
-
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ struct sockaddr *sa;
+ sa = ifa->ifa_addr;
+ if (sa->sa_family != AF_INET6)
+ continue;
+ bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
+ &ia6, sizeof(struct in6_addr));
+ if (prison_check_ip6(cred, &ia6) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
/*
- * 2. Try to find an address on the given outgoing
- * interface that belongs to the jail.
+ * As a last resort return the 'default' jail address.
*/
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- struct sockaddr *sa;
- sa = ifa->ifa_addr;
- if (sa->sa_family != AF_INET6)
- continue;
- bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
- &ia6, sizeof(struct in6_addr));
- if (prison_check_ip6(cred, &ia6) != 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- /*
- * 3. As a last resort return the 'default'
- * jail address.
- */
- if (prison_getip6(cred, &ia6) != 0)
- return (ESRCH);
- }
- bzero(&saun->sin6, sizeof(struct sockaddr_in6));
- saun->sin6.sin6_len = sizeof(struct sockaddr_in6);
- saun->sin6.sin6_family = AF_INET6;
- bcopy(&ia6, &saun->sin6.sin6_addr,
- sizeof(struct in6_addr));
- if (sa6_recoverscope(&saun->sin6) != 0)
+ if (prison_get_ip6(cred, &ia6) != 0)
return (ESRCH);
- info->rti_info[RTAX_IFA] =
- (struct sockaddr *)&saun->sin6;
}
+ bzero(&saun->sin6, sizeof(struct sockaddr_in6));
+ saun->sin6.sin6_len = sizeof(struct sockaddr_in6);
+ saun->sin6.sin6_family = AF_INET6;
+ bcopy(&ia6, &saun->sin6.sin6_addr, sizeof(struct in6_addr));
+ if (sa6_recoverscope(&saun->sin6) != 0)
+ return (ESRCH);
+ info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin6;
break;
}
#endif
@@ -611,6 +591,13 @@ route_output(struct mbuf *m, struct socket *so)
case RTM_GET:
report:
RT_LOCK_ASSERT(rt);
+ if ((rt->rt_flags & RTF_HOST) == 0
+ ? jailed(curthread->td_ucred)
+ : prison_if(curthread->td_ucred,
+ rt_key(rt)) != 0) {
+ RT_UNLOCK(rt);
+ senderr(ESRCH);
+ }
info.rti_info[RTAX_DST] = rt_key(rt);
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
info.rti_info[RTAX_NETMASK] = rt_mask(rt);
@@ -620,17 +607,11 @@ route_output(struct mbuf *m, struct socket *so)
if (ifp) {
info.rti_info[RTAX_IFP] =
ifp->if_addr->ifa_addr;
- if (jailed(so->so_cred)) {
- error = rtm_get_jailed(
- &info, ifp, rt, &saun,
- so->so_cred);
- if (error != 0) {
- RT_UNLOCK(rt);
- senderr(ESRCH);
- }
- } else {
- info.rti_info[RTAX_IFA] =
- rt->rt_ifa->ifa_addr;
+ error = rtm_get_jailed(&info, ifp, rt,
+ &saun, curthread->td_ucred);
+ if (error != 0) {
+ RT_UNLOCK(rt);
+ senderr(error);
}
if (ifp->if_flags & IFF_POINTOPOINT)
info.rti_info[RTAX_BRD] =
@@ -1256,6 +1237,10 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
return 0;
+ if ((rt->rt_flags & RTF_HOST) == 0
+ ? jailed(w->w_req->td->td_ucred)
+ : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0)
+ return (0);
bzero((caddr_t)&info, sizeof(info));
info.rti_info[RTAX_DST] = rt_key(rt);
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
@@ -1316,8 +1301,8 @@ sysctl_iflist(int af, struct walkarg *w)
while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) {
if (af && af != ifa->ifa_addr->sa_family)
continue;
- if (jailed(curthread->td_ucred) &&
- !prison_if(curthread->td_ucred, ifa->ifa_addr))
+ if (prison_if(w->w_req->td->td_ucred,
+ ifa->ifa_addr) != 0)
continue;
info.rti_info[RTAX_IFA] = ifa->ifa_addr;
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
@@ -1344,7 +1329,7 @@ done:
return (error);
}
-int
+static int
sysctl_ifmalist(int af, struct walkarg *w)
{
INIT_VNET_NET(curvnet);
@@ -1365,8 +1350,8 @@ sysctl_ifmalist(int af, struct walkarg *w)
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (af && af != ifma->ifma_addr->sa_family)
continue;
- if (jailed(curproc->p_ucred) &&
- !prison_if(curproc->p_ucred, ifma->ifma_addr))
+ if (prison_if(w->w_req->td->td_ucred,
+ ifma->ifma_addr) != 0)
continue;
info.rti_info[RTAX_IFA] = ifma->ifma_addr;
info.rti_info[RTAX_GATEWAY] =
@@ -1436,7 +1421,8 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
* take care of llinfo entries, the caller must
* specify an AF
*/
- if (w.w_op == NET_RT_FLAGS && w.w_arg == 0) {
+ if (w.w_op == NET_RT_FLAGS &&
+ (w.w_arg == 0 || w.w_arg & RTF_LLINFO)) {
if (af != 0)
error = lltable_sysctl_dumparp(af, w.w_req);
else
@@ -1447,7 +1433,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
* take care of routing entries
*/
for (error = 0; error == 0 && i <= lim; i++)
- if ((rnh = V_rt_tables[curthread->td_proc->p_fibnum][i]) != NULL) {
+ if ((rnh = V_rt_tables[req->td->td_proc->p_fibnum][i]) != NULL) {
RADIX_NODE_HEAD_LOCK(rnh);
error = rnh->rnh_walktree(rnh,
sysctl_dumpentry, &w);
diff --git a/sys/net80211/_ieee80211.h b/sys/net80211/_ieee80211.h
index f5858fe..f018f89 100644
--- a/sys/net80211/_ieee80211.h
+++ b/sys/net80211/_ieee80211.h
@@ -135,6 +135,9 @@ struct ieee80211_channel {
int8_t ic_minpower; /* minimum tx power in .5 dBm */
uint8_t ic_state; /* dynamic state */
uint8_t ic_extieee; /* HT40 extension channel number */
+ int8_t ic_maxantgain; /* maximum antenna gain in .5 dBm */
+ uint8_t ic_pad;
+ uint16_t ic_devdata; /* opaque device/driver data */
};
#define IEEE80211_CHAN_MAX 256
@@ -143,8 +146,11 @@ struct ieee80211_channel {
#define IEEE80211_CHAN_ANYC \
((struct ieee80211_channel *) IEEE80211_CHAN_ANY)
-/* bits 0-3 are for private use by drivers */
/* channel attributes */
+#define IEEE80211_CHAN_PRIV0 0x00000001 /* driver private bit 0 */
+#define IEEE80211_CHAN_PRIV1 0x00000002 /* driver private bit 1 */
+#define IEEE80211_CHAN_PRIV2 0x00000004 /* driver private bit 2 */
+#define IEEE80211_CHAN_PRIV3 0x00000008 /* driver private bit 3 */
#define IEEE80211_CHAN_TURBO 0x00000010 /* Turbo channel */
#define IEEE80211_CHAN_CCK 0x00000020 /* CCK channel */
#define IEEE80211_CHAN_OFDM 0x00000040 /* OFDM channel */
@@ -169,6 +175,11 @@ struct ieee80211_channel {
#define IEEE80211_CHAN_HT40 (IEEE80211_CHAN_HT40U | IEEE80211_CHAN_HT40D)
#define IEEE80211_CHAN_HT (IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40)
+#define IEEE80211_CHAN_BITS \
+ "\20\1PRIV0\2PRIV2\3PRIV3\4PRIV4\5TURBO\6CCK\7OFDM\0102GHZ\0115GHZ" \
+ "\12PASSIVE\13DYN\14GFSK\15GSM\16STURBO\17HALF\20QUARTER\21HT20" \
+ "\22HT40U\23HT40D\24DFS\0254MSXMIT\26NOADHOC\27NOHOSTAP\03011D"
+
/*
* Useful combinations of channel characteristics.
*/
@@ -183,9 +194,9 @@ struct ieee80211_channel {
#define IEEE80211_CHAN_G \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
#define IEEE80211_CHAN_108A \
- (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+ (IEEE80211_CHAN_A | IEEE80211_CHAN_TURBO)
#define IEEE80211_CHAN_108G \
- (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+ (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
#define IEEE80211_CHAN_ST \
(IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO)
@@ -223,9 +234,9 @@ struct ieee80211_channel {
#define IEEE80211_IS_CHAN_PASSIVE(_c) \
(((_c)->ic_flags & IEEE80211_CHAN_PASSIVE) != 0)
#define IEEE80211_IS_CHAN_OFDM(_c) \
- (((_c)->ic_flags & IEEE80211_CHAN_OFDM) != 0)
+ (((_c)->ic_flags & (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)) != 0)
#define IEEE80211_IS_CHAN_CCK(_c) \
- (((_c)->ic_flags & IEEE80211_CHAN_CCK) != 0)
+ (((_c)->ic_flags & (IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN)) != 0)
#define IEEE80211_IS_CHAN_GFSK(_c) \
(((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0)
#define IEEE80211_IS_CHAN_TURBO(_c) \
@@ -273,12 +284,15 @@ struct ieee80211_channel {
/* dynamic state */
#define IEEE80211_CHANSTATE_RADAR 0x01 /* radar detected */
#define IEEE80211_CHANSTATE_CACDONE 0x02 /* CAC completed */
+#define IEEE80211_CHANSTATE_CWINT 0x04 /* interference detected */
#define IEEE80211_CHANSTATE_NORADAR 0x10 /* post notify on radar clear */
#define IEEE80211_IS_CHAN_RADAR(_c) \
(((_c)->ic_state & IEEE80211_CHANSTATE_RADAR) != 0)
#define IEEE80211_IS_CHAN_CACDONE(_c) \
(((_c)->ic_state & IEEE80211_CHANSTATE_CACDONE) != 0)
+#define IEEE80211_IS_CHAN_CWINT(_c) \
+ (((_c)->ic_state & IEEE80211_CHANSTATE_CWINT) != 0)
/* ni_chan encoding for FH phy */
#define IEEE80211_FH_CHANMOD 80
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index e0a9432..4dd8776 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -126,6 +126,21 @@ ieee80211_chan_init(struct ieee80211com *ic)
for (i = 0; i < ic->ic_nchans; i++) {
c = &ic->ic_channels[i];
KASSERT(c->ic_flags != 0, ("channel with no flags"));
+ /*
+ * Help drivers that work only with frequencies by filling
+ * in IEEE channel #'s if not already calculated. Note this
+ * mimics similar work done in ieee80211_setregdomain when
+ * changing regulatory state.
+ */
+ if (c->ic_ieee == 0)
+ c->ic_ieee = ieee80211_mhz2ieee(c->ic_freq,c->ic_flags);
+ if (IEEE80211_IS_CHAN_HT40(c) && c->ic_extieee == 0)
+ c->ic_extieee = ieee80211_mhz2ieee(c->ic_freq +
+ (IEEE80211_IS_CHAN_HT40U(c) ? 20 : -20),
+ c->ic_flags);
+ /* default max tx power to max regulatory */
+ if (c->ic_maxpower == 0)
+ c->ic_maxpower = 2*c->ic_maxregpower;
setbit(ic->ic_chan_avail, c->ic_ieee);
/*
* Identify mode capabilities.
@@ -169,6 +184,7 @@ ieee80211_chan_init(struct ieee80211com *ic)
DEFAULTRATES(IEEE80211_MODE_11A, ieee80211_rateset_11a);
DEFAULTRATES(IEEE80211_MODE_TURBO_A, ieee80211_rateset_11a);
DEFAULTRATES(IEEE80211_MODE_TURBO_G, ieee80211_rateset_11g);
+ DEFAULTRATES(IEEE80211_MODE_STURBO_A, ieee80211_rateset_11a);
/*
* Set auto mode to reset active channel state and any desired channel.
@@ -362,6 +378,21 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
if (flags & IEEE80211_CLONE_WDSLEGACY)
vap->iv_flags_ext |= IEEE80211_FEXT_WDSLEGACY;
break;
+#ifdef IEEE80211_SUPPORT_TDMA
+ case IEEE80211_M_AHDEMO:
+ if (flags & IEEE80211_CLONE_TDMA) {
+ /* NB: checked before clone operation allowed */
+ KASSERT(ic->ic_caps & IEEE80211_C_TDMA,
+ ("not TDMA capable, ic_caps 0x%x", ic->ic_caps));
+ /*
+ * Propagate TDMA capability to mark vap; this
+ * cannot be removed and is used to distinguish
+ * regular ahdemo operation from ahdemo+tdma.
+ */
+ vap->iv_caps |= IEEE80211_C_TDMA;
+ }
+ break;
+#endif
}
/* auto-enable s/w beacon miss support */
if (flags & IEEE80211_CLONE_NOBEACONS)
@@ -441,7 +472,8 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
vap->iv_opmode == IEEE80211_M_STA, media_change, media_stat);
ieee80211_media_status(ifp, &imr);
/* NB: strip explicit mode; we're actually in autoselect */
- ifmedia_set(&vap->iv_media, imr.ifm_active &~ IFM_MMASK);
+ ifmedia_set(&vap->iv_media,
+ imr.ifm_active &~ (IFM_MMASK | IFM_IEEE80211_TURBO));
if (maxrate)
ifp->if_baudrate = IF_Mbps(maxrate);
@@ -826,16 +858,16 @@ addmedia(struct ifmedia *media, int caps, int addsta, int mode, int mword)
ifmedia_add(media, \
IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
static const u_int mopts[IEEE80211_MODE_MAX] = {
- IFM_AUTO,
- IFM_IEEE80211_11A,
- IFM_IEEE80211_11B,
- IFM_IEEE80211_11G,
- IFM_IEEE80211_FH,
- IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
- IFM_IEEE80211_11G | IFM_IEEE80211_TURBO,
- IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
- IFM_IEEE80211_11NA,
- IFM_IEEE80211_11NG,
+ [IEEE80211_MODE_AUTO] = IFM_AUTO,
+ [IEEE80211_MODE_11A] = IFM_IEEE80211_11A,
+ [IEEE80211_MODE_11B] = IFM_IEEE80211_11B,
+ [IEEE80211_MODE_11G] = IFM_IEEE80211_11G,
+ [IEEE80211_MODE_FH] = IFM_IEEE80211_FH,
+ [IEEE80211_MODE_TURBO_A] = IFM_IEEE80211_11A|IFM_IEEE80211_TURBO,
+ [IEEE80211_MODE_TURBO_G] = IFM_IEEE80211_11G|IFM_IEEE80211_TURBO,
+ [IEEE80211_MODE_STURBO_A] = IFM_IEEE80211_11A|IFM_IEEE80211_TURBO,
+ [IEEE80211_MODE_11NA] = IFM_IEEE80211_11NA,
+ [IEEE80211_MODE_11NG] = IFM_IEEE80211_11NG,
};
u_int mopt;
@@ -965,7 +997,8 @@ ieee80211_media_init(struct ieee80211com *ic)
ieee80211com_media_change, ieee80211com_media_status);
/* NB: strip explicit mode; we're actually in autoselect */
ifmedia_set(&ic->ic_media,
- media_status(ic->ic_opmode, ic->ic_curchan) &~ IFM_MMASK);
+ media_status(ic->ic_opmode, ic->ic_curchan) &~
+ (IFM_MMASK | IFM_IEEE80211_TURBO));
if (maxrate)
ifp->if_baudrate = IF_Mbps(maxrate);
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index d8fc7dd..fb63507 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -502,6 +502,11 @@ struct ieee80211_frame_bar {
#define IEEE80211_CAPINFO_DSSSOFDM 0x2000
/* bits 14-15 are reserved */
+#define IEEE80211_CAPINFO_BITS \
+ "\20\1ESS\2IBSS\3CF_POLLABLE\4CF_POLLREQ\5PRIVACY\6SHORT_PREAMBLE" \
+ "\7PBCC\10CHNL_AGILITY\11SPECTRUM_MGMT\13SHORT_SLOTTIME\14RSN" \
+ "\16DSSOFDM"
+
/*
* 802.11i/WPA information element (maximally sized).
*/
@@ -562,6 +567,11 @@ struct ieee80211_ie_htcap {
#define IEEE80211_HTCAP_40INTOLERANT 0x4000 /* 40MHz intolerant */
#define IEEE80211_HTCAP_LSIGTXOPPROT 0x8000 /* L-SIG TXOP prot */
+#define IEEE80211_HTCAP_BITS \
+ "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
+ "\13DELBA\14AMSDU(7935)\15DSSSCCK40\16PSMP\1740INTOLERANT" \
+ "\20LSIGTXOPPROT"
+
/* HT parameters (hc_param) */
#define IEEE80211_HTCAP_MAXRXAMPDU 0x03 /* max rx A-MPDU factor */
#define IEEE80211_HTCAP_MAXRXAMPDU_S 0
@@ -754,6 +764,9 @@ struct ieee80211_ath_ie {
#define IEEE80211_ERP_USE_PROTECTION 0x02
#define IEEE80211_ERP_LONG_PREAMBLE 0x04
+#define IEEE80211_ERP_BITS \
+ "\20\1NON_ERP_PRESENT\2USE_PROTECTION\3LONG_PREAMBLE"
+
#define ATH_OUI 0x7f0300 /* Atheros OUI */
#define ATH_OUI_TYPE 0x01
#define ATH_OUI_SUBTYPE 0x01
@@ -1064,4 +1077,26 @@ struct ieee80211_duration {
#define ATH_FF_SNAP_ORGCODE_1 0x03
#define ATH_FF_SNAP_ORGCODE_2 0x7f
+struct ieee80211_tdma_param {
+ u_int8_t tdma_id; /* IEEE80211_ELEMID_VENDOR */
+ u_int8_t tdma_len;
+ u_int8_t tdma_oui[3]; /* 0x00, 0x03, 0x7f */
+ u_int8_t tdma_type; /* OUI type */
+ u_int8_t tdma_subtype; /* OUI subtype */
+ u_int8_t tdma_version; /* spec revision */
+ u_int8_t tdma_slot; /* station slot # */
+ u_int8_t tdma_slotcnt; /* bss slot count */
+ u_int16_t tdma_slotlen; /* bss slot len (100us) */
+ u_int8_t tdma_bintval; /* beacon interval (superframes) */
+ u_int8_t tdma_inuse[1]; /* slot occupancy map */
+ u_int8_t tdma_pad[2];
+ u_int8_t tdma_tstamp[8]; /* timestamp from last beacon */
+} __packed;
+
+/* NB: Atheros allocated the OUI for this purpose ~3 years ago but beware ... */
+#define TDMA_OUI ATH_OUI
+#define TDMA_OUI_TYPE 0x02
+#define TDMA_SUBTYPE_PARAM 0x01
+#define TDMA_VERSION 2
+
#endif /* _NET80211_IEEE80211_H_ */
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index b8a5f7f..7e64964 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -57,6 +57,9 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_adhoc.h>
#include <net80211/ieee80211_input.h>
+#ifdef IEEE80211_SUPPORT_TDMA
+#include <net80211/ieee80211_tdma.h>
+#endif
#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2)
@@ -96,6 +99,15 @@ adhoc_vattach(struct ieee80211vap *vap)
else
vap->iv_recv_mgmt = ahdemo_recv_mgmt;
vap->iv_opdetach = adhoc_vdetach;
+#ifdef IEEE80211_SUPPORT_TDMA
+ /*
+ * Throw control to tdma support. Note we do this
+ * after setting up our callbacks so it can piggyback
+ * on top of us.
+ */
+ if (vap->iv_caps & IEEE80211_C_TDMA)
+ ieee80211_tdma_vattach(vap);
+#endif
}
/*
@@ -355,6 +367,19 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
ni == vap->iv_bss &&
!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
/*
+ * Beware of frames that come in too early; we
+ * can receive broadcast frames and creating sta
+ * entries will blow up because there is no bss
+ * channel yet.
+ */
+ if (vap->iv_state != IEEE80211_S_RUN) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, "data", "not in RUN state (%s)",
+ ieee80211_state_name[vap->iv_state]);
+ vap->iv_stats.is_rx_badstate++;
+ goto err;
+ }
+ /*
* Fake up a node for this newly
* discovered member of the IBSS.
*/
diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h
index 40a6b03..3f8f64e 100644
--- a/sys/net80211/ieee80211_crypto.h
+++ b/sys/net80211/ieee80211_crypto.h
@@ -104,6 +104,10 @@ struct ieee80211_key {
(IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT)
#define IEEE80211_KEY_SWMIC (IEEE80211_KEY_SWENMIC | IEEE80211_KEY_SWDEMIC)
+#define IEEE80211_KEY_BITS \
+ "\20\1XMIT\2RECV\3GROUP\4SWENCRYPT\5SWDECRYPT\6SWENMIC\7SWDEMIC" \
+ "\10DEVKEY\11CIPHER0\12CIPHER1"
+
#define IEEE80211_KEYIX_NONE ((ieee80211_keyix) -1)
/*
@@ -131,6 +135,9 @@ struct ieee80211_key {
#define IEEE80211_CRYPTO_TKIPMIC (1<<IEEE80211_CIPHER_TKIPMIC)
#define IEEE80211_CRYPTO_CKIP (1<<IEEE80211_CIPHER_CKIP)
+#define IEEE80211_CRYPTO_BITS \
+ "\20\1WEP\2TKIP\3AES\4AES_CCM\5TKIPMIC\6CKIP"
+
#if defined(__KERNEL__) || defined(_KERNEL)
struct ieee80211com;
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index 59c6a46..4e3406b 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -51,66 +51,6 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#include <ddb/db_sym.h>
-#define IEEE80211_MSG_BITS \
- "\20\3IOCTL\4WDS\5ACTION\6RATECTL\7ROAM\10INACT\11DOTH\12SUPERG" \
- "\13WME\14ACL\15WPA\16RADKEYS\17RADDUMP\20RADIUS\21DOT1X\22POWER" \
- "\23STATE\24OUTPUT\25SCAN\26AUTH\27ASSOC\30NODE\31ELEMID\32XRATE" \
- "\33INPUT\34CRYPTO\35DUPMPKTS\36DEBUG\3711N"
-
-#define IEEE80211_F_BITS \
- "\20\1TURBOP\2COMP\3FF\4BURST\5PRIVACY\6PUREG\10SCAN\11ASCAN\12SIBSS" \
- "\13SHSLOT\14PMGTON\15DESBSSID\16WME\17BGSCAN\20SWRETRY\21TXPOW_FIXED" \
- "\22IBSSON\23SHPREAMBLE\24DATAPAD\25USEPROT\26USERBARKER\27CSAPENDING" \
- "\30WPA1\31WPA2\32DROPUNENC\33COUNTERM\34HIDESSID\35NOBRIDG\36PCF" \
- "\37DOTH\40DWDS"
-
-#define IEEE80211_FEXT_BITS \
- "\20\1NONHT_PR\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
- "\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\22WDSLEGACY\23PROBECHAN\24HT" \
- "\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX\30AMSDU_RX\31USEHT40\32PUREN" \
- "\33SHORTGI20\34SHORTGI40\35HTCOMPAT\36RIFS"
-
-#define IEEE80211_FVEN_BITS "\20"
-
-#define IEEE80211_C_BITS \
- "\20\1STA\7FF\10TURBOP\11IBSS\12PMGT" \
- "\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \
- "\21MONITOR\22DFS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
- "\37TXFRAG"
-
-#define IEEE80211_C_CRYPTO_BITS \
- "\20\1WEP\2TKIP\3AES\4AES_CCM\5TKIPMIC\6CKIP\12PMGT"
-
-#define IEEE80211_C_HTCAP_BITS \
- "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
- "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
-
-/* NB: policy bits not included */
-#define IEEE80211_CHAN_BITS \
- "\20\5TURBO\6CCK\7OFDM\0102GHZ\0115GHZ\12PASSIVE\13DYN\14GFSK" \
- "\15STURBO\16HALF\17QUARTER\20HT20\21HT40U\22HT40D\23DFS"
-
-#define IEEE80211_NODE_BITS \
- "\20\1AUTH\2QOS\3ERP\5PWR_MGT\6AREF\7HT\10HTCOMPAT\11WPS\12TSN" \
- "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS\17RIFS\20SGI20\21SGI40" \
- "\22ASSOCID"
-
-#define IEEE80211_ERP_BITS \
- "\20\1NON_ERP_PRESENT\2USE_PROTECTION\3LONG_PREAMBLE"
-
-#define IEEE80211_CAPINFO_BITS \
- "\20\1ESS\2IBSS\3CF_POLLABLE\4CF_POLLREQ\5PRIVACY\6SHORT_PREAMBLE" \
- "\7PBCC\10CHNL_AGILITY\11SPECTRUM_MGMT\13SHORT_SLOTTIME\14RSN" \
- "\16DSSOFDM"
-
-#define IEEE80211_HTCAP_BITS \
- "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
- "\13DELBA\14AMSDU(7935)\15DSSSCCK40\16PSMP\1740INTOLERANT" \
- "\20LSIGTXOPPROT"
-
-#define IEEE80211_AGGR_BITS \
- "\20\1IMMEDIATE\2XCHGPEND\3RUNNING\4SETUP\5NAK"
-
#define DB_PRINTSYM(prefix, addr) \
db_printf(prefix " "); \
db_printsym((db_addr_t) addr, DB_STGY_ANY); \
@@ -121,6 +61,8 @@ static void _db_show_vap(const struct ieee80211vap *, int);
static void _db_show_com(const struct ieee80211com *,
int showvaps, int showsta, int showprocs);
+static void _db_show_node_table(const char *tag,
+ const struct ieee80211_node_table *);
static void _db_show_channel(const char *tag, const struct ieee80211_channel *);
static void _db_show_ssid(const char *tag, int ix, int len, const uint8_t *);
static void _db_show_appie(const char *tag, const struct ieee80211_appie *);
@@ -140,6 +82,15 @@ DB_SHOW_COMMAND(sta, db_show_sta)
_db_show_sta((const struct ieee80211_node *) addr);
}
+DB_SHOW_COMMAND(statab, db_show_statab)
+{
+ if (!have_addr) {
+ db_printf("usage: show statab <addr>\n");
+ return;
+ }
+ _db_show_node_table("", (const struct ieee80211_node_table *) addr);
+}
+
DB_SHOW_COMMAND(vap, db_show_vap)
{
int i, showprocs = 0;
@@ -279,6 +230,7 @@ _db_show_sta(const struct ieee80211_node *ni)
ni->ni_rxfragstamp);
db_printf("\trxfrag[0] %p rxfrag[1] %p rxfrag[2] %p\n",
ni->ni_rxfrag[0], ni->ni_rxfrag[1], ni->ni_rxfrag[2]);
+ _db_show_key("\tucastkey", 0, &ni->ni_ucastkey);
db_printf("\trstamp %u avgrssi 0x%x (rssi %d) noise %d\n",
ni->ni_rstamp, ni->ni_avgrssi,
IEEE80211_RSSI_GET(ni->ni_avgrssi), ni->ni_noise);
@@ -501,7 +453,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
db_printf("\tflags_ven=%b\n", ic->ic_flags_ven, IEEE80211_FVEN_BITS);
db_printf("\tcaps=%b\n", ic->ic_caps, IEEE80211_C_BITS);
db_printf("\tcryptocaps=%b\n",
- ic->ic_cryptocaps, IEEE80211_C_CRYPTO_BITS);
+ ic->ic_cryptocaps, IEEE80211_CRYPTO_BITS);
db_printf("\thtcaps=%b\n", ic->ic_htcaps, IEEE80211_HTCAP_BITS);
#if 0
@@ -568,9 +520,12 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
db_printf("\n");
db_printf("\tmax_keyix %d", ic->ic_max_keyix);
- db_printf(" sta %p", &ic->ic_sta);
db_printf(" wme %p", &ic->ic_wme);
+ if (!showsta)
+ db_printf(" sta %p", &ic->ic_sta);
db_printf("\n");
+ if (showsta)
+ _db_show_node_table("\t", &ic->ic_sta);
db_printf("\tprotmode %d", ic->ic_protmode);
db_printf(" nonerpsta %u", ic->ic_nonerpsta);
@@ -635,6 +590,26 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
}
static void
+_db_show_node_table(const char *tag, const struct ieee80211_node_table *nt)
+{
+ int i;
+
+ db_printf("%s%s@%p:\n", tag, nt->nt_name, nt);
+ db_printf("%s nodelock %p", tag, &nt->nt_nodelock);
+ db_printf(" inact_init %d", nt->nt_inact_init);
+ db_printf(" scanlock %p", &nt->nt_scanlock);
+ db_printf(" scangen %u\n", nt->nt_scangen);
+ db_printf("%s keyixmax %d keyixmap %p\n",
+ tag, nt->nt_keyixmax, nt->nt_keyixmap);
+ for (i = 0; i < nt->nt_keyixmax; i++) {
+ const struct ieee80211_node *ni = nt->nt_keyixmap[i];
+ if (ni != NULL)
+ db_printf("%s [%3u] %p %s\n", tag, i, ni,
+ ether_sprintf(ni->ni_macaddr));
+ }
+}
+
+static void
_db_show_channel(const char *tag, const struct ieee80211_channel *c)
{
db_printf("%s ", tag);
@@ -643,7 +618,7 @@ _db_show_channel(const char *tag, const struct ieee80211_channel *c)
else if (c == IEEE80211_CHAN_ANYC)
db_printf("<ANY>");
else
- db_printf("[%u (%u) flags=%b maxreg %u maxpow %u minpow %u state 0x%x extieee %u]",
+ db_printf("[%u (%u) flags=%b maxreg %d maxpow %d minpow %d state 0x%x extieee %u]",
c->ic_freq, c->ic_ieee,
c->ic_flags, IEEE80211_CHAN_BITS,
c->ic_maxregpower, c->ic_maxpower, c->ic_minpower,
@@ -698,8 +673,6 @@ _db_show_key(const char *tag, int ix, const struct ieee80211_key *wk)
const struct ieee80211_cipher *cip = wk->wk_cipher;
int keylen = wk->wk_keylen;
- if ((wk->wk_flags & IEEE80211_KEY_DEVKEY) == 0)
- return;
db_printf(tag, ix);
switch (cip->ic_cipher) {
case IEEE80211_CIPHER_WEP:
@@ -730,6 +703,8 @@ _db_show_key(const char *tag, int ix, const struct ieee80211_key *wk)
cip->ic_cipher, wk->wk_keyix, 8*keylen);
break;
}
+ if (wk->wk_rxkeyix != wk->wk_keyix)
+ db_printf(" rxkeyix %u", wk->wk_rxkeyix);
if (memcmp(wk->wk_key, zerodata, keylen) != 0) {
int i;
@@ -743,22 +718,9 @@ _db_show_key(const char *tag, int ix, const struct ieee80211_key *wk)
if (cip->ic_cipher != IEEE80211_CIPHER_WEP &&
wk->wk_keytsc != 0)
db_printf(" tsc %ju", (uintmax_t)wk->wk_keytsc);
- if (wk->wk_flags != 0) {
- const char *sep = " ";
-
- if (wk->wk_flags & IEEE80211_KEY_XMIT)
- db_printf("%stx", sep), sep = "+";
- if (wk->wk_flags & IEEE80211_KEY_RECV)
- db_printf("%srx", sep), sep = "+";
- if (wk->wk_flags & IEEE80211_KEY_DEFAULT)
- db_printf("%sdef", sep), sep = "+";
- if (wk->wk_flags & IEEE80211_KEY_SWCRYPT)
- db_printf("%sswcrypt", sep), sep = "+";
- if (wk->wk_flags & IEEE80211_KEY_SWMIC)
- db_printf("%sswmic", sep), sep = "+";
- }
- db_printf("\n");
+ db_printf(" flags=%b", wk->wk_flags, IEEE80211_KEY_BITS);
}
+ db_printf("\n");
}
static void
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 60de0f4..5f44f1c 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2003-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -124,6 +124,16 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
ieee80211_opmode_name[cp.icp_opmode]);
return EOPNOTSUPP;
}
+ if ((cp.icp_flags & IEEE80211_CLONE_TDMA) &&
+#ifdef IEEE80211_SUPPORT_TDMA
+ (ic->ic_caps & IEEE80211_C_TDMA) == 0
+#else
+ (1)
+#endif
+ ) {
+ if_printf(ifp, "TDMA not supported\n");
+ return EOPNOTSUPP;
+ }
vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
cp.icp_flags & IEEE80211_CLONE_MACADDR ?
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index c333954..e0f831b 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -355,7 +355,7 @@ hostap_deliver_data(struct ieee80211vap *vap,
if (mcopy != NULL) {
int len, err;
len = mcopy->m_pkthdr.len;
- err = (ifp->if_transmit)(ifp, mcopy);
+ err = ifp->if_transmit(ifp, mcopy);
if (err) {
/* NB: IFQ_HANDOFF reclaims mcopy */
} else {
diff --git a/sys/net80211/ieee80211_ht.h b/sys/net80211/ieee80211_ht.h
index 49d3209..b2b2132 100644
--- a/sys/net80211/ieee80211_ht.h
+++ b/sys/net80211/ieee80211_ht.h
@@ -71,6 +71,9 @@ struct ieee80211_tx_ampdu {
(((tap)->txa_flags & \
(IEEE80211_AGGR_RUNNING|IEEE80211_AGGR_XCHGPEND|IEEE80211_AGGR_NAK)) != 0)
+#define IEEE80211_AGGR_BITS \
+ "\20\1IMMEDIATE\2XCHGPEND\3RUNNING\4SETUP\5NAK"
+
/*
* Traffic estimator support. We estimate packets/sec for
* each AC that is setup for AMPDU or will potentially be
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index e68bb6c..23f770b 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -635,6 +635,10 @@ ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
scan->wme = frm;
else if (isatherosoui(frm))
scan->ath = frm;
+#ifdef IEEE80211_SUPPORT_TDMA
+ else if (istdmaoui(frm))
+ scan->tdma = frm;
+#endif
else if (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) {
/*
* Accept pre-draft HT ie's if the
diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h
index dd41d7c..b656c55 100644
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -125,6 +125,12 @@ isatherosoui(const uint8_t *frm)
}
static __inline int
+istdmaoui(const uint8_t *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI);
+}
+
+static __inline int
ishtcapoui(const uint8_t *frm)
{
return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTCAP<<24)|BCM_OUI);
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index b967e47..db36adb 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -62,6 +63,9 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_ioctl.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_input.h>
+#ifdef IEEE80211_SUPPORT_TDMA
+#include <net80211/ieee80211_tdma.h>
+#endif
#define IS_UP_AUTO(_vap) \
(IFNET_IS_UP_RUNNING(vap->iv_ifp) && \
@@ -692,21 +696,29 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
{
struct ieee80211_devcaps_req *dc;
struct ieee80211req_chaninfo *ci;
- int error;
+ int maxchans, error;
- if (ireq->i_len != sizeof(struct ieee80211_devcaps_req))
+ maxchans = 1 + ((ireq->i_len - sizeof(struct ieee80211_devcaps_req)) /
+ sizeof(struct ieee80211_channel));
+ /* NB: require 1 so we know ic_nchans is accessible */
+ if (maxchans < 1)
return EINVAL;
- dc = (struct ieee80211_devcaps_req *) malloc(
- sizeof(struct ieee80211_devcaps_req), M_TEMP, M_NOWAIT | M_ZERO);
+ /* constrain max request size, 2K channels is ~24Kbytes */
+ if (maxchans > 2048)
+ maxchans = 2048;
+ dc = (struct ieee80211_devcaps_req *)
+ malloc(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP, M_NOWAIT | M_ZERO);
if (dc == NULL)
return ENOMEM;
dc->dc_drivercaps = ic->ic_caps;
dc->dc_cryptocaps = ic->ic_cryptocaps;
dc->dc_htcaps = ic->ic_htcaps;
ci = &dc->dc_chaninfo;
- ic->ic_getradiocaps(ic, &ci->ic_nchans, ci->ic_chans);
+ ic->ic_getradiocaps(ic, maxchans, &ci->ic_nchans, ci->ic_chans);
+ KASSERT(ci->ic_nchans <= maxchans,
+ ("nchans %d maxchans %d", ci->ic_nchans, maxchans));
ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans);
- error = copyout(dc, ireq->i_data, sizeof(*dc));
+ error = copyout(dc, ireq->i_data, IEEE80211_DEVCAPS_SPACE(dc));
free(dc, M_TEMP);
return error;
}
@@ -1089,6 +1101,14 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd,
ireq->i_val =
(vap->iv_flags_ext & IEEE80211_FEXT_RIFS) != 0;
break;
+#ifdef IEEE80211_SUPPORT_TDMA
+ case IEEE80211_IOC_TDMA_SLOT:
+ case IEEE80211_IOC_TDMA_SLOTCNT:
+ case IEEE80211_IOC_TDMA_SLOTLEN:
+ case IEEE80211_IOC_TDMA_BINTERVAL:
+ error = ieee80211_tdma_ioctl_get80211(vap, ireq);
+ break;
+#endif
default:
error = EINVAL;
break;
@@ -1554,17 +1574,21 @@ static __noinline int
ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
struct ieee80211com *ic = vap->iv_ic;
- struct ieee80211req_chanlist list;
- u_char chanlist[IEEE80211_CHAN_BYTES];
- int i, nchan, error;
+ uint8_t *chanlist, *list;
+ int i, nchan, maxchan, error;
- if (ireq->i_len != sizeof(list))
- return EINVAL;
- error = copyin(ireq->i_data, &list, sizeof(list));
+ if (ireq->i_len > sizeof(ic->ic_chan_active))
+ ireq->i_len = sizeof(ic->ic_chan_active);
+ list = malloc(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP,
+ M_NOWAIT | M_ZERO);
+ if (list == NULL)
+ return ENOMEM;
+ error = copyin(ireq->i_data, list, ireq->i_len);
if (error)
return error;
- memset(chanlist, 0, sizeof(chanlist));
nchan = 0;
+ chanlist = list + ireq->i_len; /* NB: zero'd already */
+ maxchan = ireq->i_len * NBBY;
for (i = 0; i < ic->ic_nchans; i++) {
const struct ieee80211_channel *c = &ic->ic_channels[i];
/*
@@ -1572,7 +1596,7 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
* available channels so users can do things like specify
* 1-255 to get all available channels.
*/
- if (isset(list.ic_channels, c->ic_ieee)) {
+ if (c->ic_ieee < maxchan && isset(list, c->ic_ieee)) {
setbit(chanlist, c->ic_ieee);
nchan++;
}
@@ -1582,8 +1606,9 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */
isclr(chanlist, ic->ic_bsschan->ic_ieee))
ic->ic_bsschan = IEEE80211_CHAN_ANYC;
- memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active));
+ memcpy(ic->ic_chan_active, chanlist, IEEE80211_CHAN_BYTES);
ieee80211_scan_flush(vap);
+ free(list, M_TEMP);
return ENETRESET;
}
@@ -1981,17 +2006,34 @@ ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
const struct ieee80211req *ireq)
{
struct ieee80211_regdomain_req *reg;
- int error;
-
- if (ireq->i_len != sizeof(struct ieee80211_regdomain_req))
+ int nchans, error;
+
+ nchans = 1 + ((ireq->i_len - sizeof(struct ieee80211_regdomain_req)) /
+ sizeof(struct ieee80211_channel));
+ if (!(1 <= nchans && nchans <= IEEE80211_CHAN_MAX)) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
+ "%s: bad # chans, i_len %d nchans %d\n", __func__,
+ ireq->i_len, nchans);
return EINVAL;
- reg = (struct ieee80211_regdomain_req *) malloc(
- sizeof(struct ieee80211_regdomain_req), M_TEMP, M_NOWAIT);
- if (reg == NULL)
+ }
+ reg = (struct ieee80211_regdomain_req *)
+ malloc(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP, M_NOWAIT);
+ if (reg == NULL) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
+ "%s: no memory, nchans %d\n", __func__, nchans);
return ENOMEM;
- error = copyin(ireq->i_data, reg, sizeof(*reg));
- if (error == 0)
- error = ieee80211_setregdomain(vap, reg);
+ }
+ error = copyin(ireq->i_data, reg, IEEE80211_REGDOMAIN_SIZE(nchans));
+ if (error == 0) {
+ /* NB: validate inline channel count against storage size */
+ if (reg->chaninfo.ic_nchans != nchans) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
+ "%s: chan cnt mismatch, %d != %d\n", __func__,
+ reg->chaninfo.ic_nchans, nchans);
+ error = EINVAL;
+ } else
+ error = ieee80211_setregdomain(vap, reg);
+ }
free(reg, M_TEMP);
return (error == 0 ? ENETRESET : error);
@@ -2685,6 +2727,7 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
break;
case 3:
if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA)
+ return EOPNOTSUPP;
flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
break;
default: /* Can't set any -> error */
@@ -3105,6 +3148,14 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
if (isvapht(vap))
error = ERESTART;
break;
+#ifdef IEEE80211_SUPPORT_TDMA
+ case IEEE80211_IOC_TDMA_SLOT:
+ case IEEE80211_IOC_TDMA_SLOTCNT:
+ case IEEE80211_IOC_TDMA_SLOTLEN:
+ case IEEE80211_IOC_TDMA_BINTERVAL:
+ error = ieee80211_tdma_ioctl_set80211(vap, ireq);
+ break;
+#endif
default:
error = EINVAL;
break;
@@ -3213,6 +3264,8 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ieee80211_stop_locked(vap);
}
IEEE80211_UNLOCK(ic);
+ /* Wait for parent ioctl handler if it was queued */
+ taskqueue_drain(taskqueue_thread, &ic->ic_parent_task);
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index cf4678b..367f505 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -216,7 +216,8 @@ struct ieee80211_stats {
uint8_t is_rx_disassoc_code; /* last rx'd disassoc reason */
uint8_t is_rx_authfail_code; /* last rx'd auth fail reason */
uint32_t is_beacon_miss; /* beacon miss notification */
- uint32_t is_spare[13];
+ uint32_t is_rx_badstate; /* rx discard state != RUN */
+ uint32_t is_spare[12];
};
/*
@@ -298,13 +299,13 @@ struct ieee80211req_maclist {
};
/*
- * Set the active channel list. Note this list is
- * intersected with the available channel list in
- * calculating the set of channels actually used in
- * scanning.
+ * Set the active channel list by IEEE channel #: each channel
+ * to be marked active is set in a bit vector. Note this list is
+ * intersected with the available channel list in calculating
+ * the set of channels actually used in scanning.
*/
struct ieee80211req_chanlist {
- uint8_t ic_channels[IEEE80211_CHAN_BYTES];
+ uint8_t ic_channels[32]; /* NB: can be variable length */
};
/*
@@ -312,8 +313,13 @@ struct ieee80211req_chanlist {
*/
struct ieee80211req_chaninfo {
u_int ic_nchans;
- struct ieee80211_channel ic_chans[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel ic_chans[1]; /* NB: variable length */
};
+#define IEEE80211_CHANINFO_SIZE(_nchan) \
+ (sizeof(struct ieee80211req_chaninfo) + \
+ (((_nchan)-1) * sizeof(struct ieee80211_channel)))
+#define IEEE80211_CHANINFO_SPACE(_ci) \
+ IEEE80211_CHANINFO_SIZE((_ci)->ic_nchans)
/*
* Retrieve the WPA/RSN information element for an associated station.
@@ -462,6 +468,11 @@ struct ieee80211_regdomain_req {
struct ieee80211_regdomain rd;
struct ieee80211req_chaninfo chaninfo;
};
+#define IEEE80211_REGDOMAIN_SIZE(_nchan) \
+ (sizeof(struct ieee80211_regdomain_req) + \
+ (((_nchan)-1) * sizeof(struct ieee80211_channel)))
+#define IEEE80211_REGDOMAIN_SPACE(_req) \
+ IEEE80211_REGDOMAIN_SIZE((_req)->chaninfo.ic_nchans)
/*
* Get driver capabilities. Driver, hardware crypto, and
@@ -474,6 +485,11 @@ struct ieee80211_devcaps_req {
uint32_t dc_htcaps; /* HT/802.11n support */
struct ieee80211req_chaninfo dc_chaninfo;
};
+#define IEEE80211_DEVCAPS_SIZE(_nchan) \
+ (sizeof(struct ieee80211_devcaps_req) + \
+ (((_nchan)-1) * sizeof(struct ieee80211_channel)))
+#define IEEE80211_DEVCAPS_SPACE(_dc) \
+ IEEE80211_DEVCAPS_SIZE((_dc)->dc_chaninfo.ic_nchans)
struct ieee80211_chanswitch_req {
struct ieee80211_channel csa_chan; /* new channel */
@@ -612,6 +628,11 @@ struct ieee80211req {
#define IEEE80211_IOC_SMPS 110 /* MIMO power save */
#define IEEE80211_IOC_RIFS 111 /* RIFS config (on, off) */
+#define IEEE80211_IOC_TDMA_SLOT 201 /* TDMA: assigned slot */
+#define IEEE80211_IOC_TDMA_SLOTCNT 202 /* TDMA: slots in bss */
+#define IEEE80211_IOC_TDMA_SLOTLEN 203 /* TDMA: slot length (usecs) */
+#define IEEE80211_IOC_TDMA_BINTERVAL 204 /* TDMA: beacon intvl (slots) */
+
/*
* Parameters for controlling a scan requested with
* IEEE80211_IOC_SCAN_REQ.
@@ -738,6 +759,7 @@ struct ieee80211_clone_params {
#define IEEE80211_CLONE_NOBEACONS 0x0002 /* don't setup beacon timers */
#define IEEE80211_CLONE_WDSLEGACY 0x0004 /* legacy WDS processing */
#define IEEE80211_CLONE_MACADDR 0x0008 /* use specified mac addr */
+#define IEEE80211_CLONE_TDMA 0x0010 /* operate in TDMA mode */
#endif /* __FreeBSD__ */
#endif /* _NET80211_IEEE80211_IOCTL_H_ */
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index e3028d9..088dbbc 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,9 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_input.h>
+#ifdef IEEE80211_SUPPORT_TDMA
+#include <net80211/ieee80211_tdma.h>
+#endif
#include <net80211/ieee80211_wds.h>
#include <net/bpf.h>
@@ -224,20 +227,25 @@ static void
node_setuptxparms(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
+ enum ieee80211_phymode mode;
if (ni->ni_flags & IEEE80211_NODE_HT) {
if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
- ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11NA];
+ mode = IEEE80211_MODE_11NA;
else
- ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11NG];
+ mode = IEEE80211_MODE_11NG;
} else { /* legacy rate handling */
- if (IEEE80211_IS_CHAN_A(ni->ni_chan))
- ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11A];
+ /* NB: 108A/108G should be handled as 11a/11g respectively */
+ if (IEEE80211_IS_CHAN_ST(ni->ni_chan))
+ mode = IEEE80211_MODE_STURBO_A;
+ else if (IEEE80211_IS_CHAN_A(ni->ni_chan))
+ mode = IEEE80211_MODE_11A;
else if (ni->ni_flags & IEEE80211_NODE_ERP)
- ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11G];
+ mode = IEEE80211_MODE_11G;
else
- ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11B];
+ mode = IEEE80211_MODE_11B;
}
+ ni->ni_txparms = &vap->iv_txparms[mode];
}
/*
@@ -337,6 +345,9 @@ ieee80211_create_ibss(struct ieee80211vap* vap, struct ieee80211_channel *chan)
if (vap->iv_flags & IEEE80211_F_DESBSSID)
IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_des_bssid);
else
+#ifdef IEEE80211_SUPPORT_TDMA
+ if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
+#endif
memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN);
}
/*
@@ -732,7 +743,10 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan,
ni->ni_erp = se->se_erp;
IEEE80211_RSSI_LPF(ni->ni_avgrssi, se->se_rssi);
ni->ni_noise = se->se_noise;
- ni->ni_flags |= IEEE80211_NODE_ASSOCID;
+ if (vap->iv_opmode == IEEE80211_M_STA) {
+ /* NB: only infrastructure mode requires an associd */
+ ni->ni_flags |= IEEE80211_NODE_ASSOCID;
+ }
if (ieee80211_ies_init(&ni->ni_ies, se->se_ies.data, se->se_ies.len)) {
ieee80211_ies_expand(&ni->ni_ies);
@@ -742,6 +756,10 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan,
ieee80211_parse_htcap(ni, ni->ni_ies.htcap_ie);
if (ni->ni_ies.htinfo_ie != NULL)
ieee80211_parse_htinfo(ni, ni->ni_ies.htinfo_ie);
+#ifdef IEEE80211_SUPPORT_TDMA
+ if (ni->ni_ies.tdma_ie != NULL)
+ ieee80211_parse_tdma(ni, ni->ni_ies.tdma_ie);
+#endif
}
vap->iv_dtim_period = se->se_dtimperiod;
@@ -855,6 +873,10 @@ ieee80211_ies_expand(struct ieee80211_ies *ies)
ies->wme_ie = ie;
else if (isatherosoui(ie))
ies->ath_ie = ie;
+#ifdef IEEE80211_SUPPORT_TDMA
+ else if (istdmaoui(ie))
+ ies->tdma_ie = ie;
+#endif
break;
case IEEE80211_ELEMID_RSN:
ies->rsn_ie = ie;
@@ -1334,6 +1356,10 @@ ieee80211_init_neighbor(struct ieee80211_node *ni,
if (ieee80211_ies_init(&ni->ni_ies, sp->ies, sp->ies_len)) {
ieee80211_ies_expand(&ni->ni_ies);
+ if (ni->ni_ies.wme_ie != NULL)
+ ni->ni_flags |= IEEE80211_NODE_QOS;
+ else
+ ni->ni_flags &= ~IEEE80211_NODE_QOS;
if (ni->ni_ies.ath_ie != NULL)
ieee80211_parse_ath(ni, ni->ni_ies.ath_ie);
}
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index bd304d5..589ad52 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -80,6 +80,7 @@ struct ieee80211_ies {
uint8_t *ath_ie; /* captured Atheros ie */
uint8_t *htcap_ie; /* captured HTCAP ie */
uint8_t *htinfo_ie; /* captured HTINFO ie */
+ uint8_t *tdma_ie; /* captured TDMA ie */
/* NB: these must be the last members of this structure */
uint8_t *data; /* frame data > 802.11 header */
int len; /* data size in bytes */
@@ -205,6 +206,11 @@ MALLOC_DECLARE(M_80211_NODE_IE);
IEEE80211_NODE_MIMO_RTS | IEEE80211_NODE_RIFS | \
IEEE80211_NODE_SGI20 | IEEE80211_NODE_SGI40)
+#define IEEE80211_NODE_BITS \
+ "\20\1AUTH\2QOS\3ERP\5PWR_MGT\6AREF\7HT\10HTCOMPAT\11WPS\12TSN" \
+ "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS\17RIFS\20SGI20\21SGI40" \
+ "\22ASSOCID"
+
#define IEEE80211_NODE_AID(ni) IEEE80211_AID(ni->ni_associd)
#define IEEE80211_NODE_STAT(ni,stat) (ni->ni_stats.ns_##stat++)
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 050d892..f589aa9 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
+#ifdef IEEE80211_SUPPORT_TDMA
+#include <net80211/ieee80211_tdma.h>
+#endif
#include <net80211/ieee80211_wds.h>
#ifdef INET
@@ -266,7 +269,7 @@ ieee80211_start(struct ifnet *ifp)
m->m_pkthdr.rcvif = (void *)ni;
/* XXX defer if_start calls? */
- error = (parent->if_transmit)(parent, m);
+ error = parent->if_transmit(parent, m);
if (error != 0) {
/* NB: IFQ_HANDOFF reclaims mbuf */
ieee80211_free_node(ni);
@@ -2500,6 +2503,7 @@ ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm,
* [tlv] WME parameters
* [tlv] Vendor OUI HT capabilities (optional)
* [tlv] Vendor OUI HT information (optional)
+ * [tlv] TDMA parameters (optional)
* [tlv] application data (optional)
*/
@@ -2589,6 +2593,12 @@ ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm,
frm = ieee80211_add_htcap_vendor(frm, ni);
frm = ieee80211_add_htinfo_vendor(frm, ni);
}
+#ifdef IEEE80211_SUPPORT_TDMA
+ if (vap->iv_caps & IEEE80211_C_TDMA) {
+ bo->bo_tdma = frm;
+ frm = ieee80211_add_tdma(frm, vap);
+ }
+#endif
if (vap->iv_appie_beacon != NULL) {
bo->bo_appie = frm;
bo->bo_appie_len = vap->iv_appie_beacon->ie_len;
@@ -2637,6 +2647,7 @@ ieee80211_beacon_alloc(struct ieee80211_node *ni,
* XXX Vendor-specific OIDs (e.g. Atheros)
* [tlv] WPA parameters
* [tlv] WME parameters
+ * [tlv] TDMA parameters (optional)
* [tlv] application data (optional)
* NB: we allocate the max space required for the TIM bitmap.
* XXX how big is this?
@@ -2661,6 +2672,10 @@ ieee80211_beacon_alloc(struct ieee80211_node *ni,
+ 4+2*sizeof(struct ieee80211_ie_htinfo)/* HT info */
+ (vap->iv_caps & IEEE80211_C_WME ? /* WME */
sizeof(struct ieee80211_wme_param) : 0)
+#ifdef IEEE80211_SUPPORT_TDMA
+ + (vap->iv_caps & IEEE80211_C_TDMA ? /* TDMA */
+ sizeof(struct ieee80211_tdma_param) : 0)
+#endif
+ IEEE80211_MAX_APPIE
;
m = ieee80211_getmgtframe(&frm,
@@ -2779,7 +2794,14 @@ ieee80211_beacon_update(struct ieee80211_node *ni,
ieee80211_ht_update_beacon(vap, bo);
clrbit(bo->bo_flags, IEEE80211_BEACON_HTINFO);
}
-
+#ifdef IEEE80211_SUPPORT_TDMA
+ if (vap->iv_caps & IEEE80211_C_TDMA) {
+ /*
+ * NB: the beacon is potentially updated every TBTT.
+ */
+ ieee80211_tdma_update_beacon(vap, bo);
+ }
+#endif
if (vap->iv_opmode == IEEE80211_M_HOSTAP) { /* NB: no IBSS support*/
struct ieee80211_tim_ie *tie =
(struct ieee80211_tim_ie *) bo->bo_tim;
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index e25d103..f7395b6 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -291,6 +291,7 @@ struct ieee80211_beacon_offsets {
uint8_t *bo_cfp; /* start of CFParms element */
uint8_t *bo_tim; /* start of atim/dtim */
uint8_t *bo_wme; /* start of WME parameters */
+ uint8_t *bo_tdma; /* start of TDMA parameters */
uint8_t *bo_tim_trailer;/* start of fixed-size trailer */
uint16_t bo_tim_len; /* atim/dtim length in bytes */
uint16_t bo_tim_trailer_len;/* tim trailer length in bytes */
@@ -325,6 +326,7 @@ enum {
IEEE80211_BEACON_APPIE = 5, /* Application IE's */
IEEE80211_BEACON_CFP = 6, /* CFParms */
IEEE80211_BEACON_CSA = 7, /* Channel Switch Announcement */
+ IEEE80211_BEACON_TDMA = 9, /* TDMA Info */
};
int ieee80211_beacon_update(struct ieee80211_node *,
struct ieee80211_beacon_offsets *, struct mbuf *, int mcast);
diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c
index 724d00b..da3bfcc 100644
--- a/sys/net80211/ieee80211_regdomain.c
+++ b/sys/net80211/ieee80211_regdomain.c
@@ -44,12 +44,14 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_regdomain.h>
static void
-null_getradiocaps(struct ieee80211com *ic, int *n, struct ieee80211_channel *c)
+null_getradiocaps(struct ieee80211com *ic, int maxchan,
+ int *n, struct ieee80211_channel *c)
{
/* just feed back the current channel list */
- *n = ic->ic_nchans;
- memcpy(c, ic->ic_channels,
- ic->ic_nchans*sizeof(struct ieee80211_channel));
+ if (maxchan > ic->ic_nchans)
+ maxchan = ic->ic_nchans;
+ memcpy(c, ic->ic_channels, maxchan*sizeof(struct ieee80211_channel));
+ *n = maxchan;
}
static int
@@ -69,7 +71,7 @@ ieee80211_regdomain_attach(struct ieee80211com *ic)
ic->ic_regdomain.location = ' '; /* both */
ic->ic_regdomain.isocc[0] = 'U'; /* XXX */
ic->ic_regdomain.isocc[1] = 'S'; /* XXX */
- /* XXX? too late to setup default channel list */
+ /* NB: driver calls ieee80211_init_channels or similar */
}
ic->ic_getradiocaps = null_getradiocaps;
ic->ic_setregdomain = null_setregdomain;
@@ -373,6 +375,13 @@ ieee80211_setregdomain(struct ieee80211vap *vap,
c->ic_maxpower = 2*c->ic_maxregpower;
}
IEEE80211_LOCK(ic);
+ /* XXX bandaid; a running vap will likely crash */
+ if (!allvapsdown(ic)) {
+ IEEE80211_UNLOCK(ic);
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
+ "%s: reject: vaps are running\n", __func__);
+ return EBUSY;
+ }
error = ic->ic_setregdomain(ic, &reg->rd,
reg->chaninfo.ic_nchans, reg->chaninfo.ic_chans);
if (error != 0) {
@@ -381,13 +390,6 @@ ieee80211_setregdomain(struct ieee80211vap *vap,
"%s: driver rejected request, error %u\n", __func__, error);
return error;
}
- /* XXX bandaid; a running vap will likely crash */
- if (!allvapsdown(ic)) {
- IEEE80211_UNLOCK(ic);
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
- "%s: reject: vaps are running\n", __func__);
- return EBUSY;
- }
/*
* Commit: copy in new channel table and reset media state.
* On return the state machines will be clocked so all vaps
diff --git a/sys/net80211/ieee80211_regdomain.h b/sys/net80211/ieee80211_regdomain.h
index c9c0823..8942dd9 100644
--- a/sys/net80211/ieee80211_regdomain.h
+++ b/sys/net80211/ieee80211_regdomain.h
@@ -142,11 +142,6 @@ enum ISOCountryCode {
CTRY_ITALY = 380, /* Italy */
CTRY_JAMAICA = 388, /* Jamaica */
CTRY_JAPAN = 392, /* Japan */
- CTRY_JAPAN1 = 393, /* Japan (JP1) */
- CTRY_JAPAN2 = 394, /* Japan (JP0) */
- CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
- CTRY_JAPAN4 = 396, /* Japan (JE1) */
- CTRY_JAPAN5 = 397, /* Japan (JE2) */
CTRY_JORDAN = 400, /* Jordan */
CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
CTRY_KENYA = 404, /* Kenya */
@@ -209,6 +204,38 @@ enum ISOCountryCode {
CTRY_VIET_NAM = 704, /* Viet Nam */
CTRY_YEMEN = 887, /* Yemen */
CTRY_ZIMBABWE = 716, /* Zimbabwe */
+
+ /* NB: from here down not listed in 3166; they come from Atheros */
+ CTRY_DEBUG = 0x1ff, /* debug */
+ CTRY_DEFAULT = 0, /* default */
+
+ CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/
+ CTRY_KOREA_ROC3 = 412, /* South Korea */
+
+ CTRY_JAPAN1 = 393, /* Japan (JP1) */
+ CTRY_JAPAN2 = 394, /* Japan (JP0) */
+ CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
+ CTRY_JAPAN4 = 396, /* Japan (JE1) */
+ CTRY_JAPAN5 = 397, /* Japan (JE2) */
+ CTRY_JAPAN6 = 399, /* Japan (JP6) */
+ CTRY_JAPAN7 = 4007, /* Japan (J7) */
+ CTRY_JAPAN8 = 4008, /* Japan (J8) */
+ CTRY_JAPAN9 = 4009, /* Japan (J9) */
+ CTRY_JAPAN10 = 4010, /* Japan (J10) */
+ CTRY_JAPAN11 = 4011, /* Japan (J11) */
+ CTRY_JAPAN12 = 4012, /* Japan (J12) */
+ CTRY_JAPAN13 = 4013, /* Japan (J13) */
+ CTRY_JAPAN14 = 4014, /* Japan (J14) */
+ CTRY_JAPAN15 = 4015, /* Japan (J15) */
+ CTRY_JAPAN16 = 4016, /* Japan (J16) */
+ CTRY_JAPAN17 = 4017, /* Japan (J17) */
+ CTRY_JAPAN18 = 4018, /* Japan (J18) */
+ CTRY_JAPAN19 = 4019, /* Japan (J19) */
+ CTRY_JAPAN20 = 4020, /* Japan (J20) */
+ CTRY_JAPAN21 = 4021, /* Japan (J21) */
+ CTRY_JAPAN22 = 4022, /* Japan (J22) */
+ CTRY_JAPAN23 = 4023, /* Japan (J23) */
+ CTRY_JAPAN24 = 4024, /* Japan (J24) */
};
enum RegdomainCode {
@@ -225,21 +252,27 @@ enum RegdomainCode {
SKU_APAC3 = 0x5d, /* Asia Pacific w/o ISM band */
SKU_ROW = 0x81, /* China/Taiwan/Rest of World */
SKU_NONE = 0xf0, /* "Region Free" */
- SKU_DEBUG = 0x1ff
+ SKU_DEBUG = 0x1ff,
+
+ /* NB: from here down private */
+ SKU_SR9 = 0x0298, /* Ubiquiti SR9 (900MHz/GSM) */
+ SKU_XR9 = 0x0299, /* Ubiquiti XR9 (900MHz/GSM) */
+ SKU_GZ901 = 0x029a, /* Zcomax GZ-901 (900MHz/GSM) */
};
#if defined(__KERNEL__) || defined(_KERNEL)
-#define CTRY_DEBUG 0x1ff /* debug */
-#define CTRY_DEFAULT 0 /* default */
-
+struct ieee80211com;
void ieee80211_regdomain_attach(struct ieee80211com *);
void ieee80211_regdomain_detach(struct ieee80211com *);
+struct ieee80211vap;
void ieee80211_regdomain_vattach(struct ieee80211vap *);
void ieee80211_regdomain_vdetach(struct ieee80211vap *);
+struct ieee80211_regdomain;
int ieee80211_init_channels(struct ieee80211com *,
const struct ieee80211_regdomain *, const uint8_t bands[]);
-void ieee80211_sort_channels(struct ieee80211_channel chans[], int nchans);
+struct ieee80211_channel;
+void ieee80211_sort_channels(struct ieee80211_channel *chans, int nchans);
struct ieee80211_appie;
struct ieee80211_appie *ieee80211_alloc_countryie(struct ieee80211com *);
struct ieee80211_regdomain_req;
diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h
index df6ce1f7..3b58cff 100644
--- a/sys/net80211/ieee80211_scan.h
+++ b/sys/net80211/ieee80211_scan.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2005-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -209,6 +209,7 @@ struct ieee80211_scanparams {
uint8_t *htcap;
uint8_t *htinfo;
uint8_t *ath;
+ uint8_t *tdma;
};
/*
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
index 15e4ff6..6d6b5b2 100644
--- a/sys/net80211/ieee80211_scan_sta.c
+++ b/sys/net80211/ieee80211_scan_sta.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_input.h>
#include <net80211/ieee80211_regdomain.h>
+#ifdef IEEE80211_SUPPORT_TDMA
+#include <net80211/ieee80211_tdma.h>
+#endif
#include <net/bpf.h>
@@ -119,6 +122,10 @@ static void sta_flush_table(struct sta_table *);
#define MATCH_NOTSEEN 0x0080 /* not seen in recent scans */
#define MATCH_RSSI 0x0100 /* rssi deemed too low to use */
#define MATCH_CC 0x0200 /* country code mismatch */
+#define MATCH_TDMA_NOIE 0x0400 /* no TDMA ie */
+#define MATCH_TDMA_NOTMASTER 0x0800 /* not TDMA master */
+#define MATCH_TDMA_NOSLOT 0x1000 /* all TDMA slots occupied */
+#define MATCH_TDMA_LOCAL 0x2000 /* local address */
static int match_bss(struct ieee80211vap *,
const struct ieee80211_scan_state *, struct sta_entry *, int);
static void adhoc_age(struct ieee80211_scan_state *);
@@ -388,12 +395,12 @@ find11gchannel(struct ieee80211com *ic, int i, int freq)
*/
for (j = i+1; j < ic->ic_nchans; j++) {
c = &ic->ic_channels[j];
- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_G(c))
return c;
}
for (j = 0; j < i; j++) {
c = &ic->ic_channels[j];
- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_G(c))
return c;
}
return NULL;
@@ -870,6 +877,20 @@ match_ssid(const uint8_t *ie,
return 0;
}
+#ifdef IEEE80211_SUPPORT_TDMA
+static int
+tdma_isfull(const struct ieee80211_tdma_param *tdma)
+{
+ int slot, slotcnt;
+
+ slotcnt = tdma->tdma_slotcnt;
+ for (slot = slotcnt-1; slot >= 0; slot--)
+ if (isclr(tdma->tdma_inuse, slot))
+ return 0;
+ return 1;
+}
+#endif /* IEEE80211_SUPPORT_TDMA */
+
/*
* Test a scan candidate for suitability/compatibility.
*/
@@ -900,6 +921,36 @@ match_bss(struct ieee80211vap *vap,
if (vap->iv_opmode == IEEE80211_M_IBSS) {
if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
fail |= MATCH_CAPINFO;
+#ifdef IEEE80211_SUPPORT_TDMA
+ } else if (vap->iv_opmode == IEEE80211_M_AHDEMO) {
+ /*
+ * Adhoc demo network setup shouldn't really be scanning
+ * but just in case skip stations operating in IBSS or
+ * BSS mode.
+ */
+ if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS))
+ fail |= MATCH_CAPINFO;
+ /*
+ * TDMA operation cannot coexist with a normal 802.11 network;
+ * skip if IBSS or ESS capabilities are marked and require
+ * the beacon have a TDMA ie present.
+ */
+ if (vap->iv_caps & IEEE80211_C_TDMA) {
+ const struct ieee80211_tdma_param *tdma =
+ (const struct ieee80211_tdma_param *)se->se_ies.tdma_ie;
+
+ if (tdma == NULL)
+ fail |= MATCH_TDMA_NOIE;
+ else if (tdma->tdma_slot != 0)
+ fail |= MATCH_TDMA_NOTMASTER;
+ else if (tdma_isfull(tdma))
+ fail |= MATCH_TDMA_NOSLOT;
+#if 0
+ else if (ieee80211_local_address(se->se_macaddr))
+ fail |= MATCH_TDMA_LOCAL;
+#endif
+ }
+#endif /* IEEE80211_SUPPORT_TDMA */
} else {
if ((se->se_capinfo & IEEE80211_CAPINFO_ESS) == 0)
fail |= MATCH_CAPINFO;
@@ -977,6 +1028,12 @@ match_bss(struct ieee80211vap *vap,
fail & MATCH_FAILS ? '=' :
fail & MATCH_NOTSEEN ? '^' :
fail & MATCH_CC ? '$' :
+#ifdef IEEE80211_SUPPORT_TDMA
+ fail & MATCH_TDMA_NOIE ? '&' :
+ fail & MATCH_TDMA_NOTMASTER ? ':' :
+ fail & MATCH_TDMA_NOSLOT ? '@' :
+ fail & MATCH_TDMA_LOCAL ? '#' :
+#endif
fail ? '-' : '+', ether_sprintf(se->se_macaddr));
printf(" %s%c", ether_sprintf(se->se_bssid),
fail & MATCH_BSSID ? '!' : ' ');
@@ -1449,7 +1506,14 @@ adhoc_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
if (ss->ss_flags & IEEE80211_SCAN_NOJOIN)
return 0;
notfound:
+ /* NB: never auto-start a tdma network for slot !0 */
+#ifdef IEEE80211_SUPPORT_TDMA
+ if (vap->iv_des_nssid &&
+ ((vap->iv_caps & IEEE80211_C_TDMA) == 0 ||
+ ieee80211_tdma_getslot(vap) == 0)) {
+#else
if (vap->iv_des_nssid) {
+#endif
/*
* No existing adhoc network to join and we have
* an ssid; start one up. If no channel was
diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c
new file mode 100644
index 0000000..d41e039
--- /dev/null
+++ b/sys/net80211/ieee80211_tdma.c
@@ -0,0 +1,731 @@
+/*-
+ * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2007-2009 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.
+ *
+ * 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>
+#ifdef __FreeBSD__
+__FBSDID("$FreeBSD$");
+#endif
+
+/*
+ * IEEE 802.11 TDMA mode support.
+ */
+#include "opt_inet.h"
+#include "opt_wlan.h"
+
+#ifdef IEEE80211_SUPPORT_TDMA
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_llc.h>
+#include <net/ethernet.h>
+
+#include <net/bpf.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_tdma.h>
+#include <net80211/ieee80211_input.h>
+
+#include "opt_tdma.h"
+#ifndef TDMA_SLOTLEN_DEFAULT
+#define TDMA_SLOTLEN_DEFAULT 10*1000 /* 10ms */
+#endif
+#ifndef TDMA_SLOTCNT_DEFAULT
+#define TDMA_SLOTCNT_DEFAULT 2 /* 2x (pt-to-pt) */
+#endif
+#ifndef TDMA_BINTVAL_DEFAULT
+#define TDMA_BINTVAL_DEFAULT 5 /* 5x ~= 100TU beacon intvl */
+#endif
+#ifndef TDMA_TXRATE_11B_DEFAULT
+#define TDMA_TXRATE_11B_DEFAULT 2*11
+#endif
+#ifndef TDMA_TXRATE_11G_DEFAULT
+#define TDMA_TXRATE_11G_DEFAULT 2*24
+#endif
+#ifndef TDMA_TXRATE_11A_DEFAULT
+#define TDMA_TXRATE_11A_DEFAULT 2*24
+#endif
+#ifndef TDMA_TXRATE_STURBO_A_DEFAULT
+#define TDMA_TXRATE_STURBO_A_DEFAULT 2*24
+#endif
+#ifndef TDMA_TXRATE_11NA_DEFAULT
+#define TDMA_TXRATE_11NA_DEFAULT (4 | IEEE80211_RATE_MCS)
+#endif
+#ifndef TDMA_TXRATE_11NG_DEFAULT
+#define TDMA_TXRATE_11NG_DEFAULT (4 | IEEE80211_RATE_MCS)
+#endif
+
+static void tdma_vdetach(struct ieee80211vap *vap);
+static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int);
+static void tdma_beacon_miss(struct ieee80211vap *vap);
+static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *,
+ int subtype, int rssi, int noise, uint32_t rstamp);
+static int tdma_update(struct ieee80211vap *vap,
+ const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni,
+ int pickslot);
+static int tdma_process_params(struct ieee80211_node *ni,
+ const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh);
+
+static void
+settxparms(struct ieee80211vap *vap, enum ieee80211_phymode mode, int rate)
+{
+ vap->iv_txparms[mode].ucastrate = rate;
+ vap->iv_txparms[mode].mcastrate = rate;
+}
+
+static void
+setackpolicy(struct ieee80211com *ic, int noack)
+{
+ struct ieee80211_wme_state *wme = &ic->ic_wme;
+ int ac;
+
+ for (ac = 0; ac < WME_NUM_AC; ac++) {
+ wme->wme_chanParams.cap_wmeParams[ac].wmep_noackPolicy = noack;
+ wme->wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy = noack;
+ }
+}
+
+void
+ieee80211_tdma_vattach(struct ieee80211vap *vap)
+{
+ struct ieee80211_tdma_state *ts;
+
+ KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
+ ("not a tdma vap, caps 0x%x", vap->iv_caps));
+
+ ts = (struct ieee80211_tdma_state *) malloc(
+ sizeof(struct ieee80211_tdma_state), M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (ts == NULL) {
+ printf("%s: cannot allocate TDMA state block\n", __func__);
+ /* NB: fall back to adhdemo mode */
+ vap->iv_caps &= ~IEEE80211_C_TDMA;
+ return;
+ }
+ /* NB: default configuration is passive so no beacons */
+ ts->tdma_slotlen = TDMA_SLOTLEN_DEFAULT;
+ ts->tdma_slotcnt = TDMA_SLOTCNT_DEFAULT;
+ ts->tdma_bintval = TDMA_BINTVAL_DEFAULT;
+ ts->tdma_slot = 1; /* passive operation */
+
+ /* setup default fixed rates */
+ settxparms(vap, IEEE80211_MODE_11A, TDMA_TXRATE_11A_DEFAULT);
+ settxparms(vap, IEEE80211_MODE_11B, TDMA_TXRATE_11B_DEFAULT);
+ settxparms(vap, IEEE80211_MODE_11G, TDMA_TXRATE_11G_DEFAULT);
+ settxparms(vap, IEEE80211_MODE_STURBO_A, TDMA_TXRATE_STURBO_A_DEFAULT);
+ settxparms(vap, IEEE80211_MODE_11NA, TDMA_TXRATE_11NA_DEFAULT);
+ settxparms(vap, IEEE80211_MODE_11NG, TDMA_TXRATE_11NG_DEFAULT);
+
+ setackpolicy(vap->iv_ic, 1); /* disable ACK's */
+
+ ts->tdma_opdetach = vap->iv_opdetach;
+ vap->iv_opdetach = tdma_vdetach;
+ ts->tdma_newstate = vap->iv_newstate;
+ vap->iv_newstate = tdma_newstate;
+ vap->iv_bmiss = tdma_beacon_miss;
+ ts->tdma_recv_mgmt = vap->iv_recv_mgmt;
+ vap->iv_recv_mgmt = tdma_recv_mgmt;
+
+ vap->iv_tdma = ts;
+}
+
+static void
+tdma_vdetach(struct ieee80211vap *vap)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ ts->tdma_opdetach(vap);
+ free(vap->iv_tdma, M_80211_VAP);
+
+ setackpolicy(vap->iv_ic, 0); /* enable ACK's */
+}
+
+/*
+ * TDMA state machine handler.
+ */
+static int
+tdma_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+ enum ieee80211_state ostate;
+ int status;
+
+ IEEE80211_LOCK_ASSERT(vap->iv_ic);
+
+ ostate = vap->iv_state;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
+ __func__, ieee80211_state_name[ostate],
+ ieee80211_state_name[nstate], arg);
+
+ if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
+ callout_stop(&vap->iv_swbmiss);
+ if (nstate == IEEE80211_S_SCAN &&
+ (ostate == IEEE80211_S_INIT || ostate == IEEE80211_S_RUN) &&
+ ts->tdma_slot != 0) {
+ /*
+ * Override adhoc behaviour when operating as a slave;
+ * we need to scan even if the channel is locked.
+ */
+ vap->iv_state = nstate; /* state transition */
+ ieee80211_cancel_scan(vap); /* background scan */
+ if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) {
+ ieee80211_check_scan(vap,
+ vap->iv_scanreq_flags,
+ vap->iv_scanreq_duration,
+ vap->iv_scanreq_mindwell,
+ vap->iv_scanreq_maxdwell,
+ vap->iv_scanreq_nssid, vap->iv_scanreq_ssid);
+ vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
+ } else
+ ieee80211_check_scan_current(vap);
+ status = 0;
+ } else {
+ status = ts->tdma_newstate(vap, nstate, arg);
+ }
+ if (status == 0 &&
+ nstate == IEEE80211_S_RUN && ostate != IEEE80211_S_RUN &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) &&
+ ts->tdma_slot != 0) {
+ /*
+ * Start s/w beacon miss timer for slave devices w/o
+ * hardware support. The 2x is a fudge for our doing
+ * this in software.
+ */
+ vap->iv_swbmiss_period = IEEE80211_TU_TO_TICKS(
+ 2 * vap->iv_bmissthreshold * ts->tdma_bintval *
+ ((ts->tdma_slotcnt * ts->tdma_slotlen) / 1024));
+ vap->iv_swbmiss_count = 0;
+ callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period,
+ ieee80211_swbmiss, vap);
+ }
+ return status;
+}
+
+static void
+tdma_beacon_miss(struct ieee80211vap *vap)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ KASSERT((vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scanning"));
+ KASSERT(vap->iv_state == IEEE80211_S_RUN,
+ ("wrong state %d", vap->iv_state));
+
+ IEEE80211_DPRINTF(vap,
+ IEEE80211_MSG_STATE | IEEE80211_MSG_TDMA | IEEE80211_MSG_DEBUG,
+ "beacon miss, mode %u state %s\n",
+ vap->iv_opmode, ieee80211_state_name[vap->iv_state]);
+
+ if (ts->tdma_peer != NULL) { /* XXX? can this be null? */
+ ieee80211_notify_node_leave(vap->iv_bss);
+ ts->tdma_peer = NULL;
+ /*
+ * Treat beacon miss like an associate failure wrt the
+ * scan policy; this forces the entry in the scan cache
+ * to be ignored after several tries.
+ */
+ ieee80211_scan_assoc_fail(vap, vap->iv_bss->ni_macaddr,
+ IEEE80211_STATUS_TIMEOUT);
+ }
+#if 0
+ ts->tdma_inuse = 0; /* clear slot usage */
+#endif
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+}
+
+static void
+tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
+ int subtype, int rssi, int noise, uint32_t rstamp)
+{
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ if (subtype == IEEE80211_FC0_SUBTYPE_BEACON &&
+ (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+ struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
+ struct ieee80211_scanparams scan;
+
+ if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ return;
+ if (scan.tdma == NULL) {
+ /*
+ * TDMA stations must beacon a TDMA ie; ignore
+ * any other station.
+ * XXX detect overlapping bss and change channel
+ */
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
+ wh, ieee80211_mgt_subtype_name[subtype >>
+ IEEE80211_FC0_SUBTYPE_SHIFT],
+ "%s", "no TDMA ie");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ return;
+ }
+ if (ni == vap->iv_bss &&
+ !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
+ /*
+ * Fake up a node for this newly
+ * discovered member of the IBSS.
+ */
+ ni = ieee80211_add_neighbor(vap, wh, &scan);
+ if (ni == NULL) {
+ /* NB: stat kept for alloc failure */
+ return;
+ }
+ }
+ /*
+ * Check for state updates.
+ */
+ if (IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
+ /*
+ * Count frame now that we know it's to be processed.
+ */
+ vap->iv_stats.is_rx_beacon++;
+ IEEE80211_NODE_STAT(ni, rx_beacons);
+ /*
+ * Record tsf of last beacon. NB: this must be
+ * done before calling tdma_process_params
+ * as deeper routines reference it.
+ */
+ memcpy(&ni->ni_tstamp.data, scan.tstamp,
+ sizeof(ni->ni_tstamp.data));
+ /*
+ * Count beacon frame for s/w bmiss handling.
+ */
+ vap->iv_swbmiss_count++;
+ vap->iv_bmiss_count = 0;
+ /*
+ * Process tdma ie. The contents are used to sync
+ * the slot timing, reconfigure the bss, etc.
+ */
+ (void) tdma_process_params(ni, scan.tdma, rstamp, wh);
+ return;
+ }
+ /*
+ * NB: defer remaining work to the adhoc code; this causes
+ * 2x parsing of the frame but should happen infrequently
+ */
+ }
+ ts->tdma_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp);
+}
+
+/*
+ * Update TDMA state on receipt of a beacon frame with
+ * a TDMA information element. The sender's identity
+ * is provided so we can track who our peer is. If pickslot
+ * is non-zero we scan the slot allocation state in the ie
+ * locate a free slot for our use.
+ */
+static int
+tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma,
+ struct ieee80211_node *ni, int pickslot)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+ int slotlen, slotcnt, slot, bintval;
+
+ KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
+ ("not a tdma vap, caps 0x%x", vap->iv_caps));
+
+ slotlen = le16toh(tdma->tdma_slotlen);
+ slotcnt = tdma->tdma_slotcnt;
+ bintval = tdma->tdma_bintval;
+
+ /* XXX rate-limit printf's */
+ if (!(2 <= slotcnt && slotcnt <= IEEE80211_TDMA_MAXSLOTS)) {
+ printf("%s: bogus slot cnt %u\n", __func__, slotcnt);
+ return 0;
+ }
+ /* XXX magic constants */
+ if (slotlen < 2 || slotlen > (0xfffff/100)) {
+ printf("%s: bogus slot len %u\n", __func__, slotlen);
+ return 0;
+ }
+ if (bintval < 1) {
+ printf("%s: bogus beacon interval %u\n", __func__, bintval);
+ return 0;
+ }
+ if (pickslot) {
+ /*
+ * Pick unoccupied slot. Note we never choose slot 0.
+ */
+ for (slot = slotcnt-1; slot > 0; slot--)
+ if (isclr(tdma->tdma_inuse, slot))
+ break;
+ if (slot <= 0) {
+ printf("%s: no free slot, slotcnt %u inuse: 0x%x\n",
+ __func__, slotcnt, tdma->tdma_inuse[0]);
+ /* XXX need to do something better */
+ return 0;
+ }
+ } else
+ slot = ts->tdma_slot;
+
+ if (slotcnt != ts->tdma_slotcnt ||
+ 100*slotlen != ts->tdma_slotlen ||
+ bintval != ts->tdma_bintval ||
+ slot != ts->tdma_slot ||
+ ts->tdma_peer != ni) {
+ /*
+ * New/changed parameters; update runtime state.
+ */
+ /* XXX overwrites user parameters */
+ ts->tdma_slotcnt = slotcnt;
+ ts->tdma_slotlen = 100*slotlen;
+ ts->tdma_slot = slot;
+ ts->tdma_bintval = bintval;
+ /* mark beacon to be updated before next xmit */
+ ieee80211_beacon_notify(vap, IEEE80211_BEACON_TDMA);
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_TDMA,
+ "%s: slot %u slotcnt %u slotlen %u us bintval %u\n",
+ __func__, slot, slotcnt, 100*slotlen, tdma->tdma_bintval);
+ }
+ /*
+ * Notify driver. Note we can be called before
+ * entering RUN state if we scanned and are
+ * joining an existing bss. In that case do not
+ * call the driver because not all necessary state
+ * has been setup. The next beacon will dtrt.
+ */
+ if (vap->iv_state == IEEE80211_S_RUN)
+ vap->iv_ic->ic_tdma_update(ni, tdma);
+ /*
+ * Dispatch join event on first beacon from new master.
+ */
+ if (ts->tdma_peer != ni) {
+ if (ts->tdma_peer != NULL)
+ ieee80211_notify_node_leave(vap->iv_bss);
+ ieee80211_notify_node_join(ni, 1);
+ /* NB: no reference, we just use the address */
+ ts->tdma_peer = ni;
+ }
+ return 1;
+}
+
+/*
+ * Process received TDMA parameters.
+ */
+static int
+tdma_process_params(struct ieee80211_node *ni,
+ const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+ const struct ieee80211_tdma_param *tdma =
+ (const struct ieee80211_tdma_param *) ie;
+ u_int len = ie[1];
+
+ KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
+ ("not a tdma vap, caps 0x%x", vap->iv_caps));
+
+ if (len < sizeof(*tdma) - 2) {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
+ wh, "tdma", "too short, len %u", len);
+ return IEEE80211_REASON_IE_INVALID;
+ }
+ if (tdma->tdma_version != TDMA_VERSION) {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
+ wh, "tdma", "bad version %u", tdma->tdma_version);
+ return IEEE80211_REASON_IE_INVALID;
+ }
+ /*
+ * Can reach here while scanning, update
+ * operational state only in RUN state.
+ */
+ if (vap->iv_state == IEEE80211_S_RUN) {
+ if (tdma->tdma_slot != ts->tdma_slot &&
+ isclr(ts->tdma_inuse, tdma->tdma_slot)) {
+ IEEE80211_NOTE(vap, IEEE80211_MSG_TDMA, ni,
+ "discovered in slot %u", tdma->tdma_slot);
+ setbit(ts->tdma_inuse, tdma->tdma_slot);
+ /* XXX dispatch event only when operating as master */
+ if (ts->tdma_slot == 0)
+ ieee80211_notify_node_join(ni, 1);
+ }
+ setbit(ts->tdma_active, tdma->tdma_slot);
+ if (tdma->tdma_slot == ts->tdma_slot-1) {
+ /*
+ * Slave tsf synchronization to station
+ * just before us in the schedule. The driver
+ * is responsible for copying the timestamp
+ * of the received beacon into our beacon
+ * frame so the sender can calculate round
+ * trip time. We cannot do that here because
+ * we don't know how to update our beacon frame.
+ */
+ (void) tdma_update(vap, tdma, ni, 0);
+ /* XXX reschedule swbmiss timer on parameter change */
+ } else if (tdma->tdma_slot == ts->tdma_slot+1) {
+ uint64_t tstamp;
+ int32_t rtt;
+ /*
+ * Use returned timstamp to calculate the
+ * roundtrip time.
+ */
+ memcpy(&tstamp, tdma->tdma_tstamp, 8);
+ /* XXX use only 15 bits of rstamp */
+ rtt = rstamp - (le64toh(tstamp) & 0x7fff);
+ if (rtt < 0)
+ rtt += 0x7fff;
+ /* XXX hack to quiet normal use */
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOT1X,
+ "tdma rtt %5u [rstamp %5u tstamp %llu]\n",
+ rtt, rstamp,
+ (unsigned long long) le64toh(tstamp));
+ } else if (tdma->tdma_slot == ts->tdma_slot &&
+ le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) {
+ /*
+ * Station using the same slot as us and has
+ * been around longer than us; we must move.
+ * Note this can happen if stations do not
+ * see each other while scanning.
+ */
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_TDMA,
+ "slot %u collision rxtsf %llu tsf %llu\n",
+ tdma->tdma_slot,
+ (unsigned long long) le64toh(ni->ni_tstamp.tsf),
+ vap->iv_bss->ni_tstamp.tsf);
+ setbit(ts->tdma_inuse, tdma->tdma_slot);
+
+ (void) tdma_update(vap, tdma, ni, 1);
+ }
+ }
+ return 0;
+}
+
+int
+ieee80211_tdma_getslot(struct ieee80211vap *vap)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
+ ("not a tdma vap, caps 0x%x", vap->iv_caps));
+ return ts->tdma_slot;
+}
+
+/*
+ * Parse a TDMA ie on station join and use it to setup node state.
+ */
+void
+ieee80211_parse_tdma(struct ieee80211_node *ni, const uint8_t *ie)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+
+ if (vap->iv_caps & IEEE80211_C_TDMA) {
+ const struct ieee80211_tdma_param *tdma =
+ (const struct ieee80211_tdma_param *)ie;
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+ /*
+ * Adopt TDMA configuration when joining an
+ * existing network.
+ */
+ setbit(ts->tdma_inuse, tdma->tdma_slot);
+ (void) tdma_update(vap, tdma, ni, 1);
+ /*
+ * Propagate capabilities based on the local
+ * configuration and the remote station's advertised
+ * capabilities. In particular this permits us to
+ * enable use of QoS to disable ACK's.
+ */
+ if ((vap->iv_flags & IEEE80211_F_WME) &&
+ ni->ni_ies.wme_ie != NULL)
+ ni->ni_flags |= IEEE80211_NODE_QOS;
+ }
+}
+
+#define TDMA_OUI_BYTES 0x00, 0x03, 0x7f
+/*
+ * Add a TDMA parameters element to a frame.
+ */
+uint8_t *
+ieee80211_add_tdma(uint8_t *frm, struct ieee80211vap *vap)
+{
+#define ADDSHORT(frm, v) do { \
+ frm[0] = (v) & 0xff; \
+ frm[1] = (v) >> 8; \
+ frm += 2; \
+} while (0)
+ static const struct ieee80211_tdma_param param = {
+ .tdma_id = IEEE80211_ELEMID_VENDOR,
+ .tdma_len = sizeof(struct ieee80211_tdma_param) - 2,
+ .tdma_oui = { TDMA_OUI_BYTES },
+ .tdma_type = TDMA_OUI_TYPE,
+ .tdma_subtype = TDMA_SUBTYPE_PARAM,
+ .tdma_version = TDMA_VERSION,
+ };
+ const struct ieee80211_tdma_state *tdma = vap->iv_tdma;
+ uint16_t slotlen;
+
+ KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
+ ("not a tdma vap, caps 0x%x", vap->iv_caps));
+
+ memcpy(frm, &param, sizeof(param));
+ frm += __offsetof(struct ieee80211_tdma_param, tdma_slot);
+ *frm++ = tdma->tdma_slot;
+ *frm++ = tdma->tdma_slotcnt;
+ /* NB: convert units to fit in 16-bits */
+ slotlen = tdma->tdma_slotlen / 100; /* 100us units */
+ ADDSHORT(frm, slotlen);
+ *frm++ = tdma->tdma_bintval;
+ *frm++ = tdma->tdma_inuse[0];
+ frm += 10; /* pad+timestamp */
+ return frm;
+#undef ADDSHORT
+}
+#undef TDMA_OUI_BYTES
+
+/*
+ * Update TDMA state at TBTT.
+ */
+void
+ieee80211_tdma_update_beacon(struct ieee80211vap *vap,
+ struct ieee80211_beacon_offsets *bo)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
+ ("not a tdma vap, caps 0x%x", vap->iv_caps));
+
+ if (isset(bo->bo_flags, IEEE80211_BEACON_TDMA)) {
+ (void) ieee80211_add_tdma(bo->bo_tdma, vap);
+ clrbit(bo->bo_flags, IEEE80211_BEACON_TDMA);
+ }
+ if (ts->tdma_slot != 0) /* only on master */
+ return;
+ if (ts->tdma_count <= 0) {
+ /*
+ * Time to update the mask of active/inuse stations.
+ * We track stations that we've received a beacon
+ * frame from and update this mask periodically.
+ * This allows us to miss a few beacons before marking
+ * a slot free for re-use.
+ */
+ ts->tdma_inuse[0] = ts->tdma_active[0];
+ ts->tdma_active[0] = 0x01;
+ /* update next time 'round */
+ /* XXX use notify framework */
+ setbit(bo->bo_flags, IEEE80211_BEACON_TDMA);
+ /* NB: use s/w beacon miss threshold; may be too high */
+ ts->tdma_count = vap->iv_bmissthreshold-1;
+ } else
+ ts->tdma_count--;
+}
+
+int
+ieee80211_tdma_ioctl_get80211(struct ieee80211vap *vap,
+ struct ieee80211req *ireq)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
+ return EOPNOTSUPP;
+
+ switch (ireq->i_type) {
+ case IEEE80211_IOC_TDMA_SLOT:
+ ireq->i_val = ts->tdma_slot;
+ break;
+ case IEEE80211_IOC_TDMA_SLOTCNT:
+ ireq->i_val = ts->tdma_slotcnt;
+ break;
+ case IEEE80211_IOC_TDMA_SLOTLEN:
+ ireq->i_val = ts->tdma_slotlen;
+ break;
+ case IEEE80211_IOC_TDMA_BINTERVAL:
+ ireq->i_val = ts->tdma_bintval;
+ break;
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+
+int
+ieee80211_tdma_ioctl_set80211(struct ieee80211vap *vap,
+ struct ieee80211req *ireq)
+{
+ struct ieee80211_tdma_state *ts = vap->iv_tdma;
+
+ if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
+ return EOPNOTSUPP;
+
+ switch (ireq->i_type) {
+ case IEEE80211_IOC_TDMA_SLOT:
+ if (!(0 <= ireq->i_val && ireq->i_val <= ts->tdma_slotcnt))
+ return EINVAL;
+ if (ireq->i_val != ts->tdma_slot) {
+ ts->tdma_slot = ireq->i_val;
+ return ERESTART;
+ }
+ break;
+ case IEEE80211_IOC_TDMA_SLOTCNT:
+ if (!(2 <= ireq->i_val &&
+ ireq->i_val <= IEEE80211_TDMA_MAXSLOTS))
+ return EINVAL;
+ if (ireq->i_val != ts->tdma_slotcnt) {
+ ts->tdma_slotcnt = ireq->i_val;
+ return ERESTART;
+ }
+ break;
+ case IEEE80211_IOC_TDMA_SLOTLEN:
+ /*
+ * XXX
+ * 150 insures at least 1/8 TU
+ * 0xfffff is the max duration for bursting
+ * (implict by way of 16-bit data type for i_val)
+ */
+ if (ireq->i_val < 150)
+ return EINVAL;
+ if (ireq->i_val != ts->tdma_slotlen) {
+ ts->tdma_slotlen = ireq->i_val;
+ return ERESTART;
+ }
+ break;
+ case IEEE80211_IOC_TDMA_BINTERVAL:
+ if (ireq->i_val < 1)
+ return EINVAL;
+ if (ireq->i_val != ts->tdma_bintval) {
+ ts->tdma_bintval = ireq->i_val;
+ return ERESTART;
+ }
+ break;
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+#endif /* IEEE80211_SUPPORT_TDMA */
diff --git a/sys/net80211/ieee80211_tdma.h b/sys/net80211/ieee80211_tdma.h
new file mode 100644
index 0000000..c5ac3a2
--- /dev/null
+++ b/sys/net80211/ieee80211_tdma.h
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2007-2009 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.
+ *
+ * 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 _NET80211_IEEE80211_TDMA_H_
+#define _NET80211_IEEE80211_TDMA_H_
+
+/*
+ * TDMA-mode implementation definitions.
+ */
+struct ieee80211_tdma_state {
+ u_int tdma_slotlen; /* bss slot length (us) */
+ uint8_t tdma_slotcnt; /* bss slot count */
+ uint8_t tdma_bintval; /* beacon interval (slots) */
+ uint8_t tdma_slot; /* station slot # */
+ uint8_t tdma_inuse[1]; /* mask of slots in use */
+#define IEEE80211_TDMA_MAXSLOTS 8
+ void *tdma_peer; /* peer station cookie */
+ uint8_t tdma_active[1]; /* mask of active slots */
+ int tdma_count; /* active/inuse countdown */
+
+ /* parent method pointers */
+ int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state,
+ int arg);
+ void (*tdma_recv_mgmt)(struct ieee80211_node *,
+ struct mbuf *, int, int, int, uint32_t);
+ void (*tdma_opdetach)(struct ieee80211vap *);
+};
+
+void ieee80211_tdma_vattach(struct ieee80211vap *);
+
+int ieee80211_tdma_getslot(struct ieee80211vap *vap);
+void ieee80211_parse_tdma(struct ieee80211_node *ni, const uint8_t *ie);
+uint8_t *ieee80211_add_tdma(uint8_t *frm, struct ieee80211vap *vap);
+struct ieee80211_beacon_offsets;
+void ieee80211_tdma_update_beacon(struct ieee80211vap *vap,
+ struct ieee80211_beacon_offsets *bo);
+struct ieee80211req;
+int ieee80211_tdma_ioctl_get80211(struct ieee80211vap *vap,
+ struct ieee80211req *ireq);
+int ieee80211_tdma_ioctl_set80211(struct ieee80211vap *vap,
+ struct ieee80211req *ireq);
+#endif /* !_NET80211_IEEE80211_TDMA_H_ */
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index ccd95d0..0a0f19f 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -105,6 +105,8 @@ struct ieee80211_appie {
uint8_t ie_data[]; /* user-specified IE's */
};
+struct ieee80211_tdma_param;
+
struct ieee80211com {
struct ifnet *ic_ifp; /* associated device */
ieee80211_com_lock_t ic_comlock; /* state update lock */
@@ -206,7 +208,7 @@ struct ieee80211com {
ieee80211vap_attach ic_vattach[IEEE80211_OPMODE_MAX];
/* return hardware/radio capabilities */
void (*ic_getradiocaps)(struct ieee80211com *,
- int *, struct ieee80211_channel []);
+ int, int *, struct ieee80211_channel []);
/* check and/or prepare regdomain state change */
int (*ic_setregdomain)(struct ieee80211com *,
struct ieee80211_regdomain *,
@@ -226,6 +228,9 @@ struct ieee80211com {
void (*ic_update_promisc)(struct ifnet *);
/* new station association callback/notification */
void (*ic_newassoc)(struct ieee80211_node *, int);
+ /* TDMA update notification */
+ void (*ic_tdma_update)(struct ieee80211_node *,
+ const struct ieee80211_tdma_param *);
/* node state management */
struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
@@ -279,6 +284,7 @@ struct ieee80211com {
};
struct ieee80211_aclator;
+struct ieee80211_tdma_state;
struct ieee80211vap {
struct ifmedia iv_media; /* interface media config */
@@ -389,6 +395,8 @@ struct ieee80211vap {
const struct ieee80211_aclator *iv_acl; /* acl glue */
void *iv_as; /* private aclator state */
+ struct ieee80211_tdma_state *iv_tdma; /* tdma state */
+
/* operate-mode detach hook */
void (*iv_opdetach)(struct ieee80211vap *);
/* receive processing */
@@ -461,6 +469,13 @@ MALLOC_DECLARE(M_80211_VAP);
#define IEEE80211_F_DOTH 0x40000000 /* CONF: 11h enabled */
#define IEEE80211_F_DWDS 0x80000000 /* CONF: Dynamic WDS enabled */
+#define IEEE80211_F_BITS \
+ "\20\1TURBOP\2COMP\3FF\4BURST\5PRIVACY\6PUREG\10SCAN\11ASCAN\12SIBSS" \
+ "\13SHSLOT\14PMGTON\15DESBSSID\16WME\17BGSCAN\20SWRETRY\21TXPOW_FIXED" \
+ "\22IBSSON\23SHPREAMBLE\24DATAPAD\25USEPROT\26USERBARKER\27CSAPENDING" \
+ "\30WPA1\31WPA2\32DROPUNENC\33COUNTERM\34HIDESSID\35NOBRIDG\36PCF" \
+ "\37DOTH\40DWDS"
+
/* Atheros protocol-specific flags */
#define IEEE80211_F_ATHEROS \
(IEEE80211_F_FF | IEEE80211_F_COMP | IEEE80211_F_TURBOP)
@@ -497,6 +512,14 @@ MALLOC_DECLARE(M_80211_VAP);
#define IEEE80211_FEXT_HTCOMPAT 0x10000000 /* CONF: HT vendor OUI's */
#define IEEE80211_FEXT_RIFS 0x20000000 /* CONF: RIFS enabled */
+#define IEEE80211_FEXT_BITS \
+ "\20\1NONHT_PR\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
+ "\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\22WDSLEGACY\23PROBECHAN\24HT" \
+ "\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX\30AMSDU_RX\31USEHT40\32PUREN" \
+ "\33SHORTGI20\34SHORTGI40\35HTCOMPAT\36RIFS"
+
+#define IEEE80211_FVEN_BITS "\20"
+
/* ic_caps/iv_caps: device driver capabilities */
/* 0x2f available */
#define IEEE80211_C_STA 0x00000001 /* CAPABILITY: STA available */
@@ -522,11 +545,19 @@ MALLOC_DECLARE(M_80211_VAP);
/* 0x10000000 reserved */
#define IEEE80211_C_BGSCAN 0x20000000 /* CAPABILITY: bg scanning */
#define IEEE80211_C_TXFRAG 0x40000000 /* CAPABILITY: tx fragments */
+#define IEEE80211_C_TDMA 0x80000000 /* CAPABILITY: TDMA avail */
/* XXX protection/barker? */
#define IEEE80211_C_OPMODE \
(IEEE80211_C_STA | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | \
- IEEE80211_C_AHDEMO | IEEE80211_C_MONITOR | IEEE80211_C_WDS)
+ IEEE80211_C_AHDEMO | IEEE80211_C_MONITOR | IEEE80211_C_WDS | \
+ IEEE80211_C_TDMA)
+
+#define IEEE80211_C_BITS \
+ "\20\1STA\7FF\10TURBOP\11IBSS\12PMGT" \
+ "\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \
+ "\21MONITOR\22DFS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
+ "\37TXFRAG\40TDMA"
/*
* ic_htcaps/iv_htcaps: HT-specific device/driver capabilities
@@ -541,6 +572,10 @@ MALLOC_DECLARE(M_80211_VAP);
#define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/
#define IEEE80211_HTC_RIFS 0x00100000 /* CAPABILITY: RIFS support */
+#define IEEE80211_C_HTCAP_BITS \
+ "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
+ "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
+
void ieee80211_ifattach(struct ieee80211com *);
void ieee80211_ifdetach(struct ieee80211com *);
int ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *,
@@ -680,9 +715,16 @@ ieee80211_htchanflags(const struct ieee80211_channel *c)
#define IEEE80211_MSG_ACTION 0x00000010 /* action frame handling */
#define IEEE80211_MSG_WDS 0x00000008 /* WDS handling */
#define IEEE80211_MSG_IOCTL 0x00000004 /* ioctl handling */
+#define IEEE80211_MSG_TDMA 0x00000002 /* TDMA handling */
#define IEEE80211_MSG_ANY 0xffffffff /* anything */
+#define IEEE80211_MSG_BITS \
+ "\20\3IOCTL\4WDS\5ACTION\6RATECTL\7ROAM\10INACT\11DOTH\12SUPERG" \
+ "\13WME\14ACL\15WPA\16RADKEYS\17RADDUMP\20RADIUS\21DOT1X\22POWER" \
+ "\23STATE\24OUTPUT\25SCAN\26AUTH\27ASSOC\30NODE\31ELEMID\32XRATE" \
+ "\33INPUT\34CRYPTO\35DUPMPKTS\36DEBUG\3711N"
+
#ifdef IEEE80211_DEBUG
#define ieee80211_msg(_vap, _m) ((_vap)->iv_debug & (_m))
#define IEEE80211_DPRINTF(_vap, _m, _fmt, ...) do { \
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index fe59293..2501cb50 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -278,7 +278,7 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m)
mcopy->m_flags |= M_MCAST | M_WDS;
mcopy->m_pkthdr.rcvif = (void *) ni;
- err = (parent->if_transmit)(parent, mcopy);
+ err = parent->if_transmit(parent, mcopy);
if (err) {
/* NB: IFQ_HANDOFF reclaims mbuf */
ifp->if_oerrors++;
diff --git a/sys/netatalk/ddp_usrreq.c b/sys/netatalk/ddp_usrreq.c
index 3db88cf..7ea8f4f 100644
--- a/sys/netatalk/ddp_usrreq.c
+++ b/sys/netatalk/ddp_usrreq.c
@@ -75,11 +75,9 @@ static struct ifqueue atintrq1, atintrq2, aarpintrq;
static int
ddp_attach(struct socket *so, int proto, struct thread *td)
{
- struct ddpcb *ddp;
int error = 0;
- ddp = sotoddpcb(so);
- KASSERT(ddp == NULL, ("ddp_attach: ddp != NULL"));
+ KASSERT(sotoddpcb(so) == NULL, ("ddp_attach: ddp != NULL"));
/*
* Allocate socket buffer space first so that it's present
@@ -175,10 +173,8 @@ ddp_disconnect(struct socket *so)
static int
ddp_shutdown(struct socket *so)
{
- struct ddpcb *ddp;
- ddp = sotoddpcb(so);
- KASSERT(ddp != NULL, ("ddp_shutdown: ddp == NULL"));
+ KASSERT(sotoddpcb(so) != NULL, ("ddp_shutdown: ddp == NULL"));
socantsendmore(so);
return (0);
diff --git a/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c b/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
index b2df2a7..923ecfc 100644
--- a/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
+++ b/sys/netgraph/bluetooth/l2cap/ng_l2cap_llpi.c
@@ -116,10 +116,14 @@ ng_l2cap_lp_con_req(ng_l2cap_p l2cap, bdaddr_p bdaddr)
NG_SEND_MSG_HOOK(error, l2cap->node, msg, l2cap->hci, 0);
if (error != 0) {
- if ((error = ng_l2cap_lp_untimeout(con)) != 0)
- return (error);
+ if (ng_l2cap_lp_untimeout(con) == 0)
+ ng_l2cap_free_con(con);
- ng_l2cap_free_con(con);
+ /*
+ * Do not free connection if ng_l2cap_lp_untimeout() failed
+ * let timeout handler deal with it. Always return error to
+ * the caller.
+ */
}
return (error);
@@ -213,8 +217,8 @@ ng_l2cap_lp_con_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
NG_L2CAP_ALERT(
"%s: %s - invalid LP_ConnectInd message size\n",
__func__, NG_NODE_NAME(l2cap->node));
- error = EMSGSIZE;
- goto out;
+
+ return (EMSGSIZE);
}
ep = (ng_hci_lp_con_ind_ep *) (msg->data);
@@ -227,8 +231,8 @@ ng_l2cap_lp_con_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
"Connection already exists, state=%d, con_handle=%d\n",
__func__, NG_NODE_NAME(l2cap->node), con->state,
con->con_handle);
- error = EEXIST;
- goto out;
+
+ return (EEXIST);
}
/* Check if lower layer protocol is still connected */
@@ -236,24 +240,22 @@ ng_l2cap_lp_con_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
NG_L2CAP_ERR(
"%s: %s - hook \"%s\" is not connected or valid",
__func__, NG_NODE_NAME(l2cap->node), NG_L2CAP_HOOK_HCI);
- error = ENOTCONN;
- goto out;
+
+ return (ENOTCONN);
}
/* Create and intialize new connection descriptor */
con = ng_l2cap_new_con(l2cap, &ep->bdaddr);
- if (con == NULL) {
- error = ENOMEM;
- goto out;
- }
+ if (con == NULL)
+ return (ENOMEM);
/* Create and send LP_ConnectRsp event */
NG_MKMESSAGE(rsp, NGM_HCI_COOKIE, NGM_HCI_LP_CON_RSP,
sizeof(*rp), M_NOWAIT);
if (rsp == NULL) {
ng_l2cap_free_con(con);
- error = ENOMEM;
- goto out;
+
+ return (ENOMEM);
}
rp = (ng_hci_lp_con_rsp_ep *)(rsp->data);
@@ -266,14 +268,18 @@ ng_l2cap_lp_con_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
NG_SEND_MSG_HOOK(error, l2cap->node, rsp, l2cap->hci, 0);
if (error != 0) {
- if ((error = ng_l2cap_lp_untimeout(con)) != 0)
- goto out;
+ if (ng_l2cap_lp_untimeout(con) == 0)
+ ng_l2cap_free_con(con);
- ng_l2cap_free_con(con);
+ /*
+ * Do not free connection if ng_l2cap_lp_untimeout() failed
+ * let timeout handler deal with it. Always return error to
+ * the caller.
+ */
}
-out:
+
return (error);
-} /* ng_hci_lp_con_ind */
+} /* ng_l2cap_lp_con_ind */
/*
* Process LP_DisconnectInd event from the lower layer protocol. We have been
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
index ecfa36d..7d07dfb 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
@@ -947,11 +947,6 @@ ng_btsocket_l2cap_raw_control(struct socket *so, u_long cmd, caddr_t data,
ng_l2cap_l2ca_ping_ip *ip = NULL;
ng_l2cap_l2ca_ping_op *op = NULL;
- if (!(pcb->flags & NG_BTSOCKET_L2CAP_RAW_PRIVILEGED)) {
- error = EPERM;
- break;
- }
-
if ((p->echo_size != 0 && p->echo_data == NULL) ||
p->echo_size > NG_L2CAP_MAX_ECHO_SIZE) {
error = EINVAL;
diff --git a/sys/netgraph/ng_deflate.c b/sys/netgraph/ng_deflate.c
index 84609e3..b248a83 100644
--- a/sys/netgraph/ng_deflate.c
+++ b/sys/netgraph/ng_deflate.c
@@ -459,6 +459,13 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
return (ENOMEM);
}
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL) {
+ priv->stats.Errors++;
+ return (ENOMEM);
+ }
+
/* Work with contiguous regions of memory. */
m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
outlen = DEFLATE_BUF_SIZE;
@@ -497,19 +504,19 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
priv->stats.FramesUncomp++;
priv->stats.OutOctets+=inlen;
} else {
- NG_FREE_M(m);
-
/* Install header. */
((u_int16_t *)priv->outbuf)[0] = htons(PROT_COMPD);
((u_int16_t *)priv->outbuf)[1] = htons(priv->seqnum);
/* Return packet in an mbuf. */
- *resultp = m_devget((caddr_t)priv->outbuf, outlen, 0, NULL,
- NULL);
- if (*resultp == NULL) {
+ m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
+ if (m->m_pkthdr.len < outlen) {
+ m_freem(m);
priv->stats.Errors++;
return (ENOMEM);
- };
+ } else if (outlen < m->m_pkthdr.len)
+ m_adj(m, outlen - m->m_pkthdr.len);
+ *resultp = m;
priv->stats.FramesComp++;
priv->stats.OutOctets+=outlen;
}
@@ -546,6 +553,13 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
return (ENOMEM);
}
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL) {
+ priv->stats.Errors++;
+ return (ENOMEM);
+ }
+
/* Work with contiguous regions of memory. */
m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
@@ -610,25 +624,24 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
/* Calculate resulting size. */
outlen -= priv->cx.avail_out;
- NG_FREE_M(m);
-
/* Decompress protocol. */
if ((priv->outbuf[1] & 0x01) != 0) {
priv->outbuf[0] = 0;
/* Return packet in an mbuf. */
- *resultp = m_devget((caddr_t)priv->outbuf, outlen, 0,
- NULL, NULL);
+ m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
} else {
outlen--;
/* Return packet in an mbuf. */
- *resultp = m_devget((caddr_t)(priv->outbuf + 1),
- outlen, 0, NULL, NULL);
+ m_copyback(m, 0, outlen, (caddr_t)(priv->outbuf + 1));
}
- if (*resultp == NULL) {
+ if (m->m_pkthdr.len < outlen) {
+ m_freem(m);
priv->stats.Errors++;
priv->seqnum = 0;
return (ENOMEM);
- };
+ } else if (outlen < m->m_pkthdr.len)
+ m_adj(m, outlen - m->m_pkthdr.len);
+ *resultp = m;
priv->stats.FramesPlain++;
priv->stats.OutOctets+=outlen;
diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c
index 2295004..a22b85a 100644
--- a/sys/netgraph/ng_iface.c
+++ b/sys/netgraph/ng_iface.c
@@ -356,6 +356,7 @@ static int
ng_iface_output(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt0)
{
+ struct m_tag *mtag;
uint32_t af;
int error;
@@ -366,6 +367,23 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m,
return (ENETDOWN);
}
+ /* Protect from deadly infinite recursion. */
+ while ((mtag = m_tag_locate(m, MTAG_NGIF, MTAG_NGIF_CALLED, NULL))) {
+ if (*(struct ifnet **)(mtag + 1) == ifp) {
+ log(LOG_NOTICE, "Loop detected on %s\n", ifp->if_xname);
+ m_freem(m);
+ return (EDEADLK);
+ }
+ }
+ mtag = m_tag_alloc(MTAG_NGIF, MTAG_NGIF_CALLED, sizeof(struct ifnet *),
+ M_NOWAIT);
+ if (mtag == NULL) {
+ m_freem(m);
+ return (ENOMEM);
+ }
+ *(struct ifnet **)(mtag + 1) = ifp;
+ m_tag_prepend(m, mtag);
+
/* BPF writes need to be handled specially. */
if (dst->sa_family == AF_UNSPEC) {
bcopy(dst->sa_data, &af, sizeof(af));
diff --git a/sys/netgraph/ng_iface.h b/sys/netgraph/ng_iface.h
index 54dfa8c..58fb442 100644
--- a/sys/netgraph/ng_iface.h
+++ b/sys/netgraph/ng_iface.h
@@ -72,4 +72,7 @@ enum {
NGM_IFACE_GET_IFINDEX,
};
+#define MTAG_NGIF NGM_IFACE_COOKIE
+#define MTAG_NGIF_CALLED 0 | MTAG_PERSISTENT
+
#endif /* _NETGRAPH_NG_IFACE_H_ */
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c
index 5a6c302..e934481 100644
--- a/sys/netgraph/ng_mppc.c
+++ b/sys/netgraph/ng_mppc.c
@@ -470,6 +470,11 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
u_int16_t header;
struct mbuf *m = *datap;
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL)
+ return (ENOMEM);
+
/* Initialize */
header = d->cc;
@@ -484,22 +489,29 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
if ((d->cfg.bits & MPPC_BIT) != 0) {
u_short flags = MPPC_MANDATORY_COMPRESS_FLAGS;
u_char *inbuf, *outbuf;
- int outlen, inlen;
+ int outlen, inlen, ina;
u_char *source, *dest;
u_long sourceCnt, destCnt;
int rtn;
/* Work with contiguous regions of memory. */
inlen = m->m_pkthdr.len;
- inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
- if (inbuf == NULL)
- goto err1;
- m_copydata(m, 0, inlen, (caddr_t)inbuf);
+ if (m->m_next == NULL) {
+ inbuf = mtod(m, u_char *);
+ ina = 0;
+ } else {
+ inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
+ if (inbuf == NULL)
+ goto err1;
+ m_copydata(m, 0, inlen, (caddr_t)inbuf);
+ ina = 1;
+ }
outlen = MPPC_MAX_BLOWUP(inlen);
outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT);
if (outbuf == NULL) {
- free(inbuf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
err1:
m_freem(m);
MPPC_InitCompressionHistory(d->history);
@@ -529,16 +541,21 @@ err1:
header |= MPPC_FLAG_RESTART;
/* Replace m by the compresed one. */
- m_freem(m);
- m = m_devget((caddr_t)outbuf, outlen, 0, NULL, NULL);
+ m_copyback(m, 0, outlen, (caddr_t)outbuf);
+ if (m->m_pkthdr.len < outlen) {
+ m_freem(m);
+ m = NULL;
+ } else if (outlen < m->m_pkthdr.len)
+ m_adj(m, outlen - m->m_pkthdr.len);
}
d->flushed = (rtn & MPPC_EXPANDED) != 0
|| (flags & MPPC_SAVE_HISTORY) == 0;
- free(inbuf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
free(outbuf, M_NETGRAPH_MPPC);
- /* Check m_devget() result. */
+ /* Check mbuf chain reload result. */
if (m == NULL) {
if (!d->flushed) {
MPPC_InitCompressionHistory(d->history);
@@ -557,18 +574,6 @@ err1:
/* Set header bits */
header |= MPPC_FLAG_ENCRYPTED;
- /* We must own the mbuf chain exclusively to modify it. */
- m = m_unshare(m, M_DONTWAIT);
- if (m == NULL) {
- if (!d->flushed) {
-#ifdef NETGRAPH_MPPC_COMPRESSION
- MPPC_InitCompressionHistory(d->history);
-#endif
- d->flushed = 1;
- }
- return (ENOMEM);
- }
-
/* Update key if it's time */
if ((d->cfg.bits & MPPE_STATELESS) != 0
|| (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
@@ -615,6 +620,11 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
u_int numLost;
struct mbuf *m = *datap;
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL)
+ return (ENOMEM);
+
/* Pull off header */
if (m->m_pkthdr.len < MPPC_HDRLEN) {
m_freem(m);
@@ -694,11 +704,6 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
d->cfg.startkey, d->key, &d->rc4);
}
- /* We must own the mbuf chain exclusively to modify it. */
- m = m_unshare(m, M_DONTWAIT);
- if (m == NULL)
- return (ENOMEM);
-
/* Decrypt packet */
m1 = m;
while (m1 != NULL) {
@@ -734,36 +739,43 @@ failed:
/* Decompress packet */
if ((header & MPPC_FLAG_COMPRESSED) != 0) {
int flags = MPPC_MANDATORY_DECOMPRESS_FLAGS;
- u_char *decompbuf, *source, *dest;
+ u_char *inbuf, *outbuf;
+ int inlen, outlen, ina;
+ u_char *source, *dest;
u_long sourceCnt, destCnt;
- int decomplen, rtn;
- u_char *buf;
- int len;
+ int rtn;
/* Copy payload into a contiguous region of memory. */
- len = m->m_pkthdr.len;
- buf = malloc(len, M_NETGRAPH_MPPC, M_NOWAIT);
- if (buf == NULL) {
- m_freem(m);
- return (ENOMEM);
+ inlen = m->m_pkthdr.len;
+ if (m->m_next == NULL) {
+ inbuf = mtod(m, u_char *);
+ ina = 0;
+ } else {
+ inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT);
+ if (inbuf == NULL) {
+ m_freem(m);
+ return (ENOMEM);
+ }
+ m_copydata(m, 0, inlen, (caddr_t)inbuf);
+ ina = 1;
}
- m_copydata(m, 0, len, (caddr_t)buf);
/* Allocate a buffer for decompressed data */
- decompbuf = malloc(MPPC_DECOMP_BUFSIZE + MPPC_DECOMP_SAFETY,
+ outbuf = malloc(MPPC_DECOMP_BUFSIZE + MPPC_DECOMP_SAFETY,
M_NETGRAPH_MPPC, M_NOWAIT);
- if (decompbuf == NULL) {
+ if (outbuf == NULL) {
m_freem(m);
- free(buf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
return (ENOMEM);
}
- decomplen = MPPC_DECOMP_BUFSIZE;
+ outlen = MPPC_DECOMP_BUFSIZE;
/* Prepare to decompress */
- source = buf;
- sourceCnt = len;
- dest = decompbuf;
- destCnt = decomplen;
+ source = inbuf;
+ sourceCnt = inlen;
+ dest = outbuf;
+ destCnt = outlen;
if ((header & MPPC_FLAG_RESTART) != 0)
flags |= MPPC_RESTART_HISTORY;
@@ -777,18 +789,24 @@ failed:
|| (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) {
log(LOG_ERR, "%s: decomp returned 0x%x",
__func__, rtn);
- free(buf, M_NETGRAPH_MPPC);
- free(decompbuf, M_NETGRAPH_MPPC);
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
+ free(outbuf, M_NETGRAPH_MPPC);
goto failed;
}
/* Replace compressed data with decompressed data */
- free(buf, M_NETGRAPH_MPPC);
- len = decomplen - destCnt;
+ if (ina)
+ free(inbuf, M_NETGRAPH_MPPC);
+ outlen -= destCnt;
- m_freem(m);
- m = m_devget((caddr_t)decompbuf, len, 0, NULL, NULL);
- free(decompbuf, M_NETGRAPH_MPPC);
+ m_copyback(m, 0, outlen, (caddr_t)outbuf);
+ if (m->m_pkthdr.len < outlen) {
+ m_freem(m);
+ m = NULL;
+ } else if (outlen < m->m_pkthdr.len)
+ m_adj(m, outlen - m->m_pkthdr.len);
+ free(outbuf, M_NETGRAPH_MPPC);
}
#endif
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
index ec5d62b..b2b0cb0 100644
--- a/sys/netgraph/ng_ppp.c
+++ b/sys/netgraph/ng_ppp.c
@@ -128,7 +128,6 @@ MALLOC_DEFINE(M_NETGRAPH_PPP, "netgraph_ppp", "netgraph ppp node");
#define PROT_VJUNCOMP 0x002f
/* Multilink PPP definitions */
-#define MP_MIN_MRRU 1500 /* per RFC 1990 */
#define MP_INITIAL_SEQ 0 /* per RFC 1990 */
#define MP_MIN_LINK_MRU 32
@@ -1985,6 +1984,12 @@ ng_ppp_mp_xmit(node_p node, item_p item, uint16_t proto)
priv->activeLinks[0], plen));
}
+ /* Check peer's MRRU for this bundle. */
+ if (plen > priv->conf.mrru) {
+ NG_FREE_ITEM(item);
+ return (EMSGSIZE);
+ }
+
/* Extract mbuf. */
NGI_GET_M(item, m);
@@ -2540,10 +2545,6 @@ ng_ppp_config_valid(node_p node, const struct ng_ppp_node_conf *newConf)
return (0);
}
- /* Check bundle parameters */
- if (newConf->bund.enableMultilink && newConf->bund.mrru < MP_MIN_MRRU)
- return (0);
-
/* Disallow changes to multi-link configuration while MP is active */
if (priv->numActiveLinks > 0 && newNumLinksActive > 0) {
if (!priv->conf.enableMultilink
diff --git a/sys/netgraph/ng_pred1.c b/sys/netgraph/ng_pred1.c
index 981448e..5f01e88 100644
--- a/sys/netgraph/ng_pred1.c
+++ b/sys/netgraph/ng_pred1.c
@@ -400,11 +400,16 @@ ng_pred1_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
return (ENOMEM);
}
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL) {
+ priv->stats.Errors++;
+ return (ENOMEM);
+ }
+
/* Work with contiguous regions of memory. */
m_copydata(m, 0, inlen, (caddr_t)(priv->inbuf + 2));
- NG_FREE_M(m);
-
lenn = htons(inlen & 0x7FFF);
/* Compute FCS. */
@@ -437,12 +442,14 @@ ng_pred1_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
outlen += 2;
/* Return packet in an mbuf. */
- *resultp = m_devget((caddr_t)out, outlen, 0, NULL, NULL);
- if (*resultp == NULL) {
- priv->stats.Errors++;
- return (ENOMEM);
- };
-
+ m_copyback(m, 0, outlen, (caddr_t)out);
+ if (m->m_pkthdr.len < outlen) {
+ m_freem(m);
+ priv->stats.Errors++;
+ return (ENOMEM);
+ } else if (outlen < m->m_pkthdr.len)
+ m_adj(m, outlen - m->m_pkthdr.len);
+ *resultp = m;
priv->stats.OutOctets += outlen;
return (0);
@@ -471,6 +478,13 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
return (ENOMEM);
}
+ /* We must own the mbuf chain exclusively to modify it. */
+ m = m_unshare(m, M_DONTWAIT);
+ if (m == NULL) {
+ priv->stats.Errors++;
+ return (ENOMEM);
+ }
+
/* Work with contiguous regions of memory. */
m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
@@ -485,13 +499,12 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
/* Is data compressed or not really? */
if (cf) {
- NG_FREE_M(m);
-
priv->stats.FramesComp++;
len1 = Pred1Decompress(node, priv->inbuf + 2, priv->outbuf,
inlen - 4, PRED1_BUF_SIZE);
if (len != len1) {
/* Error is detected. Send reset request */
+ m_freem(m);
priv->stats.Errors++;
log(LOG_NOTICE, "ng_pred1: Comp length error (%d) "
"--> len (%d)\n", len, len1);
@@ -510,17 +523,21 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
fcs = Crc16(fcs, priv->inbuf + inlen - 2, 2);
if (fcs != PPP_GOODFCS) {
+ m_freem(m);
priv->stats.Errors++;
log(LOG_NOTICE, "ng_pred1: Pred1: Bad CRC-16\n");
return (EIO);
}
/* Return packet in an mbuf. */
- *resultp = m_devget((caddr_t)priv->outbuf, len, 0, NULL, NULL);
- if (*resultp == NULL) {
+ m_copyback(m, 0, len, (caddr_t)priv->outbuf);
+ if (m->m_pkthdr.len < len) {
+ m_freem(m);
priv->stats.Errors++;
return (ENOMEM);
- };
+ } else if (len < m->m_pkthdr.len)
+ m_adj(m, len - m->m_pkthdr.len);
+ *resultp = m;
} else {
priv->stats.FramesUncomp++;
diff --git a/sys/netgraph/ng_vjc.c b/sys/netgraph/ng_vjc.c
index 5714ac0..797b995 100644
--- a/sys/netgraph/ng_vjc.c
+++ b/sys/netgraph/ng_vjc.c
@@ -249,6 +249,9 @@ ng_vjc_constructor(node_p node)
NG_NODE_SET_PRIVATE(node, priv);
+ /* slcompress is not thread-safe. Protect it's state here. */
+ NG_NODE_FORCE_WRITER(node);
+
/* Done */
return (0);
}
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 3f11e82..bf1ebae 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -41,7 +41,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/socket.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
+#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/vimage.h>
@@ -261,13 +263,19 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
LIST_FOREACH(iap, INADDR_HASH(dst.s_addr), ia_hash)
if (iap->ia_ifp == ifp &&
iap->ia_addr.sin_addr.s_addr == dst.s_addr) {
- ia = iap;
+ if (td == NULL || prison_check_ip4(
+ td->td_ucred, &dst) == 0)
+ ia = iap;
break;
}
if (ia == NULL)
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
iap = ifatoia(ifa);
if (iap->ia_addr.sin_family == AF_INET) {
+ if (td != NULL &&
+ prison_check_ip4(td->td_ucred,
+ &iap->ia_addr.sin_addr) != 0)
+ continue;
ia = iap;
break;
}
@@ -995,9 +1003,6 @@ in_purgemaddrs(struct ifnet *ifp)
struct in_multi *inm;
struct in_multi *oinm;
-#ifdef DIAGNOSTIC
- printf("%s: purging ifp %p\n", __func__, ifp);
-#endif
IFF_LOCKGIANT(ifp);
IN_MULTI_LOCK();
LIST_FOREACH_SAFE(inm, &V_in_multihead, inm_link, oinm) {
@@ -1106,9 +1111,10 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
hashkey = sin->sin_addr.s_addr;
lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
LIST_FOREACH(lle, lleh, lle_next) {
+ struct sockaddr_in *sa2 = (struct sockaddr_in *)L3_ADDR(lle);
if (lle->la_flags & LLE_DELETED)
continue;
- if (bcmp(L3_ADDR(lle), l3addr, sizeof(struct sockaddr_in)) == 0)
+ if (sa2->sin_addr.s_addr == sin->sin_addr.s_addr)
break;
}
if (lle == NULL) {
@@ -1153,7 +1159,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
lle = (void *)-1;
}
- if (lle != NULL && lle != (void *)-1) {
+ if (LLE_IS_VALID(lle)) {
if (flags & LLE_EXCLUSIVE)
LLE_WLOCK(lle);
else
@@ -1192,6 +1198,9 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
/* skip deleted entries */
if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID)
continue;
+ /* Skip if jailed and not a valid IP of the prison. */
+ if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
+ continue;
/*
* produce a msg made of:
* struct rt_msghdr;
@@ -1200,6 +1209,10 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
*/
bzero(&arpc, sizeof(arpc));
arpc.rtm.rtm_msglen = sizeof(arpc);
+ arpc.rtm.rtm_version = RTM_VERSION;
+ arpc.rtm.rtm_type = RTM_GET;
+ arpc.rtm.rtm_flags = RTF_UP;
+ arpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
arpc.sin.sin_family = AF_INET;
arpc.sin.sin_len = sizeof(arpc.sin);
arpc.sin.sin_addr.s_addr = SIN(lle)->sin_addr.s_addr;
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index b969bdf..591e766 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -441,6 +441,8 @@ __END_DECLS
#define IP_FAITH 22 /* bool; accept FAITH'ed connections */
#define IP_ONESBCAST 23 /* bool: send all-ones broadcast */
+#define IP_NONLOCALOK 24 /* bool: allow bind to spoof non-local addresses;
+ requires kernel compile option IP_NONLOCALBIND */
#define IP_FW_TABLE_ADD 40 /* add entry */
#define IP_FW_TABLE_DEL 41 /* delete entry */
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 6d1c2aa..3014bc3 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -35,6 +35,7 @@
__FBSDID("$FreeBSD$");
#include "opt_ddb.h"
+#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include "opt_mac.h"
@@ -312,7 +313,10 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
return (EINVAL);
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
wild = INPLOOKUP_WILDCARD;
- if (nam) {
+ if (nam == NULL) {
+ if ((error = prison_local_ip4(cred, &laddr)) != 0)
+ return (error);
+ } else {
sin = (struct sockaddr_in *)nam;
if (nam->sa_len != sizeof (*sin))
return (EINVAL);
@@ -324,8 +328,9 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
#endif
- if (prison_local_ip4(cred, &sin->sin_addr))
- return (EINVAL);
+ error = prison_local_ip4(cred, &sin->sin_addr);
+ if (error)
+ return (error);
if (sin->sin_port != *lportp) {
/* Don't allow the port to change. */
if (*lportp != 0)
@@ -346,7 +351,16 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
} else if (sin->sin_addr.s_addr != INADDR_ANY) {
sin->sin_port = 0; /* yech... */
bzero(&sin->sin_zero, sizeof(sin->sin_zero));
- if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
+ /*
+ * Is the address a local IP address?
+ * If INP_NONLOCALOK is set, then the socket may be bound
+ * to any endpoint address, local or not.
+ */
+ if (
+#if defined(IP_NONLOCALBIND)
+ ((inp->inp_flags & INP_NONLOCALOK) == 0) &&
+#endif
+ (ifa_ifwithaddr((struct sockaddr *)sin) == 0))
return (EADDRNOTAVAIL);
}
laddr = sin->sin_addr;
@@ -381,8 +395,6 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
t->inp_cred->cr_uid))
return (EADDRINUSE);
}
- if (prison_local_ip4(cred, &sin->sin_addr))
- return (EADDRNOTAVAIL);
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
lport, wild, cred);
if (t && (t->inp_vflag & INP_TIMEWAIT)) {
@@ -416,9 +428,6 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
u_short first, last, aux;
int count;
- if (prison_local_ip4(cred, &laddr))
- return (EINVAL);
-
if (inp->inp_flags & INP_HIGHPORT) {
first = V_ipport_hifirstauto; /* sysctl */
last = V_ipport_hilastauto;
@@ -483,8 +492,6 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
} while (in_pcblookup_local(pcbinfo, laddr,
lport, wild, cred));
}
- if (prison_local_ip4(cred, &laddr))
- return (EINVAL);
*laddrp = laddr.s_addr;
*lportp = lport;
return (0);
@@ -604,7 +611,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
if (sa->sa_family != AF_INET)
continue;
sin = (struct sockaddr_in *)sa;
- if (prison_check_ip4(cred, &sin->sin_addr)) {
+ if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
ia = (struct in_ifaddr *)ifa;
break;
}
@@ -615,8 +622,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
}
/* 3. As a last resort return the 'default' jail address. */
- if (prison_getip4(cred, laddr) != 0)
- error = EADDRNOTAVAIL;
+ error = prison_get_ip4(cred, laddr);
goto done;
}
@@ -641,7 +647,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
/* Jailed. */
/* 1. Check if the iface address belongs to the jail. */
sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr;
- if (prison_check_ip4(cred, &sin->sin_addr)) {
+ if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
goto done;
@@ -657,7 +663,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
if (sa->sa_family != AF_INET)
continue;
sin = (struct sockaddr_in *)sa;
- if (prison_check_ip4(cred, &sin->sin_addr)) {
+ if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
ia = (struct in_ifaddr *)ifa;
break;
}
@@ -668,8 +674,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
}
/* 3. As a last resort return the 'default' jail address. */
- if (prison_getip4(cred, laddr) != 0)
- error = EADDRNOTAVAIL;
+ error = prison_get_ip4(cred, laddr);
goto done;
}
@@ -719,7 +724,8 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
if (sa->sa_family != AF_INET)
continue;
sin = (struct sockaddr_in *)sa;
- if (prison_check_ip4(cred, &sin->sin_addr)) {
+ if (prison_check_ip4(cred,
+ &sin->sin_addr) == 0) {
ia = (struct in_ifaddr *)ifa;
break;
}
@@ -731,8 +737,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
}
/* 3. As a last resort return the 'default' jail address. */
- if (prison_getip4(cred, laddr) != 0)
- error = EADDRNOTAVAIL;
+ error = prison_get_ip4(cred, laddr);
goto done;
}
@@ -766,7 +771,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
struct sockaddr_in *sin = (struct sockaddr_in *)nam;
struct in_ifaddr *ia;
struct inpcb *oinp;
- struct in_addr laddr, faddr, jailia;
+ struct in_addr laddr, faddr;
u_short lport, fport;
int error;
@@ -799,15 +804,11 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
* choose the broadcast address for that interface.
*/
if (faddr.s_addr == INADDR_ANY) {
- if (cred != NULL && jailed(cred)) {
- if (prison_getip4(cred, &jailia) != 0)
- return (EADDRNOTAVAIL);
- faddr.s_addr = jailia.s_addr;
- } else {
- faddr =
- IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->
- sin_addr;
- }
+ faddr =
+ IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr;
+ if (cred != NULL &&
+ (error = prison_get_ip4(cred, &faddr)) != 0)
+ return (error);
} else if (faddr.s_addr == (u_long)INADDR_BROADCAST &&
(TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags &
IFF_BROADCAST))
@@ -1365,7 +1366,8 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
injail = jailed(inp->inp_cred);
if (injail) {
- if (!prison_check_ip4(inp->inp_cred, &laddr))
+ if (prison_check_ip4(inp->inp_cred,
+ &laddr) != 0)
continue;
} else {
if (local_exact != NULL)
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 01636fe..acc6404 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -411,6 +411,8 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
#define INP_FAITH 0x200 /* accept FAITH'ed connections */
#define INP_RECVTTL 0x400 /* receive incoming IP TTL */
#define INP_DONTFRAG 0x800 /* don't fragment packet */
+#define INP_NONLOCALOK 0x1000 /* Allow bind to spoof any address */
+ /* - requires options IP_NONLOCALBIND */
#define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index d6eb16f..c2e3191 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_ipfw.h"
#include "opt_mac.h"
+#include "opt_sctp.h"
#ifndef INET
#error "IPDIVERT requires INET."
#endif
@@ -76,6 +77,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_var.h>
#include <netinet/ip_fw.h>
#include <netinet/vinet.h>
+#ifdef SCTP
+#include <netinet/sctp_crc32.h>
+#endif
#include <security/mac/mac_framework.h>
@@ -222,7 +226,14 @@ divert_packet(struct mbuf *m, int incoming)
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
ip->ip_len = htons(ip->ip_len);
}
-
+#ifdef SCTP
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP) {
+ ip->ip_len = ntohs(ip->ip_len);
+ sctp_delayed_cksum(m);
+ m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+ ip->ip_len = htons(ip->ip_len);
+ }
+#endif
/*
* Record receive interface address, if any.
* But only for incoming packets.
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 1f2e67d..133166e 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -197,6 +197,7 @@ SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
NULL, IPFW_DEFAULT_RULE, "The default/max possible rule number.");
SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
NULL, IPFW_TABLES_MAX, "The maximum number of tables.");
+#endif /* SYSCTL_NODE */
/*
* Description of dynamic rules.
@@ -277,6 +278,7 @@ static u_int32_t dyn_count; /* # of dynamic rules */
static u_int32_t dyn_max; /* max # of dynamic rules */
#endif /* VIMAGE_GLOBALS */
+#ifdef SYSCTL_NODE
SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_buckets,
CTLFLAG_RW, dyn_buckets, 0, "Number of dyn. buckets");
SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
@@ -302,18 +304,19 @@ SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
"Lifetime of dyn. rules for other situations");
SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_keepalive,
CTLFLAG_RW, dyn_keepalive, 0, "Enable keepalives for dyn. rules");
-
+#endif /* SYSCTL_NODE */
#ifdef INET6
/*
* IPv6 specific variables
*/
+#ifdef SYSCTL_NODE
SYSCTL_DECL(_net_inet6_ip6);
+#endif /* SYSCTL_NODE */
static struct sysctl_ctx_list ip6_fw_sysctl_ctx;
static struct sysctl_oid *ip6_fw_sysctl_tree;
#endif /* INET6 */
-#endif /* SYSCTL_NODE */
#ifdef VIMAGE_GLOBALS
static int fw_deny_unknown_exthdrs;
@@ -2251,6 +2254,7 @@ ipfw_chk(struct ip_fw_args *args)
if (m->m_flags & M_SKIP_FIREWALL)
return (IP_FW_PASS); /* accept */
+ dst_ip.s_addr = 0; /* make sure it is initialized */
pktlen = m->m_pkthdr.len;
args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */
proto = args->f_id.proto = 0; /* mark f_id invalid */
@@ -2708,7 +2712,7 @@ check_body:
uint32_t a =
(cmd->opcode == O_IP_DST_LOOKUP) ?
dst_ip.s_addr : src_ip.s_addr;
- uint32_t v;
+ uint32_t v = 0;
match = lookup_table(chain, cmd->arg1, a,
&v);
diff --git a/sys/netinet/ip_fw_nat.c b/sys/netinet/ip_fw_nat.c
index 332c026..6ba0412 100644
--- a/sys/netinet/ip_fw_nat.c
+++ b/sys/netinet/ip_fw_nat.c
@@ -326,12 +326,10 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
else
retval = LibAliasOut(t->lib, c,
mcl->m_len + M_TRAILINGSPACE(mcl));
-#ifdef _ALIAS_SCTP
if (retval == PKT_ALIAS_RESPOND) {
m->m_flags |= M_SKIP_FIREWALL;
retval = PKT_ALIAS_OK;
}
-#endif
if (retval != PKT_ALIAS_OK &&
retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
/* XXX - should i add some logging? */
@@ -407,7 +405,6 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
}
args->m = mcl;
-
return (IP_FW_NAT);
}
diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c
index a1e082b..77e9aa7 100644
--- a/sys/netinet/ip_ipsec.c
+++ b/sys/netinet/ip_ipsec.c
@@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$");
#include "opt_ipsec.h"
+#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -56,6 +57,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_options.h>
#include <netinet/ip_ipsec.h>
#include <netinet/vinet.h>
+#ifdef SCTP
+#include <netinet/sctp_crc32.h>
+#endif
#include <machine/in_cksum.h>
@@ -328,7 +332,12 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error,
in_delayed_cksum(*m);
(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
-
+#ifdef SCTP
+ if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) {
+ sctp_delayed_cksum(*m);
+ (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+ }
+#endif
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 6cda8aa..feacb51 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -33,10 +33,12 @@
__FBSDID("$FreeBSD$");
#include "opt_ipfw.h"
+#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_mac.h"
#include "opt_mbuf_stress_test.h"
#include "opt_mpath.h"
+#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,6 +71,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_var.h>
#include <netinet/ip_options.h>
#include <netinet/vinet.h>
+#ifdef SCTP
+#include <netinet/sctp.h>
+#include <netinet/sctp_crc32.h>
+#endif
#ifdef IPSEC
#include <netinet/ip_ipsec.h>
@@ -95,6 +101,12 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_frag_size, CTLFLAG_RW,
&mbuf_frag_size, 0, "Fragment outgoing mbufs to this size");
#endif
+#if defined(IP_NONLOCALBIND)
+static int ip_nonlocalok = 0;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, nonlocalok,
+ CTLFLAG_RW|CTLFLAG_SECURE, &ip_nonlocalok, 0, "");
+#endif
+
static void ip_mloopback
(struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
@@ -478,7 +490,10 @@ sendit:
}
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_IP, m);
goto done;
} else
@@ -495,6 +510,10 @@ sendit:
CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
m->m_pkthdr.csum_data = 0xffff;
}
+#ifdef SCTP
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+ m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID;
+#endif
m->m_pkthdr.csum_flags |=
CSUM_IP_CHECKED | CSUM_IP_VALID;
@@ -529,6 +548,12 @@ passout:
in_delayed_cksum(m);
sw_csum &= ~CSUM_DELAY_DATA;
}
+#ifdef SCTP
+ if (sw_csum & CSUM_SCTP) {
+ sctp_delayed_cksum(m);
+ sw_csum &= ~CSUM_SCTP;
+ }
+#endif
m->m_pkthdr.csum_flags &= ifp->if_hwassist;
/*
@@ -663,7 +688,13 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
in_delayed_cksum(m0);
m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
-
+#ifdef SCTP
+ if (m0->m_pkthdr.csum_flags & CSUM_SCTP &&
+ (if_hwassist_flags & CSUM_IP_FRAGS) == 0) {
+ sctp_delayed_cksum(m0);
+ m0->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+ }
+#endif
if (len > PAGE_SIZE) {
/*
* Fragment large datagrams such that each segment
@@ -866,6 +897,14 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
return (error);
}
+#if defined(IP_NONLOCALBIND)
+ case IP_NONLOCALOK:
+ if (! ip_nonlocalok) {
+ error = ENOPROTOOPT;
+ break;
+ }
+ /* FALLTHROUGH */
+#endif
case IP_TOS:
case IP_TTL:
case IP_MINTTL:
@@ -892,7 +931,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
break;
case IP_MINTTL:
- if (optval > 0 && optval <= MAXTTL)
+ if (optval >= 0 && optval <= MAXTTL)
inp->inp_ip_minttl = optval;
else
error = EINVAL;
@@ -937,6 +976,11 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
case IP_DONTFRAG:
OPTSET(INP_DONTFRAG);
break;
+#if defined(IP_NONLOCALBIND)
+ case IP_NONLOCALOK:
+ OPTSET(INP_NONLOCALOK);
+ break;
+#endif
}
break;
#undef OPTSET
diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c
index cfef491..9d80da9 100644
--- a/sys/netinet/libalias/alias.c
+++ b/sys/netinet/libalias/alias.c
@@ -111,13 +111,6 @@ __FBSDID("$FreeBSD$");
See HISTORY file for additional revisions.
*/
-/**
- * Modifications to add sctp functionality by David A. Hayes
- * $Id: alias.c 122 2008-06-25 06:50:47Z dhayes $
- * All are inclosed in #ifdef _ALIAS_SCTP
- *
- */
-
#ifdef _KERNEL
#include <sys/param.h>
#include <sys/systm.h>
@@ -144,17 +137,11 @@ __FBSDID("$FreeBSD$");
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
#include <netinet/libalias/alias_mod.h>
-#ifdef _ALIAS_SCTP
-#include <netinet/libalias/alias_sctp.h>
-#endif
#else
#include <err.h>
#include "alias.h"
#include "alias_local.h"
#include "alias_mod.h"
-#ifdef _ALIAS_SCTP
-#include "alias_sctp.h"
-#endif
#endif
/*
@@ -1360,7 +1347,7 @@ LibAliasInLocked(struct libalias *la, char *ptr, int maxpacketsize)
case IPPROTO_TCP:
iresult = TcpAliasIn(la, pip);
break;
-#ifdef _ALIAS_SCTP
+#ifdef _KERNEL
case IPPROTO_SCTP:
iresult = SctpAlias(la, pip, SN_TO_LOCAL);
break;
@@ -1510,7 +1497,7 @@ LibAliasOutLocked(struct libalias *la, char *ptr, /* valid IP packet */
case IPPROTO_TCP:
iresult = TcpAliasOut(la, pip, maxpacketsize, create);
break;
- #ifdef _ALIAS_SCTP
+#ifdef _KERNEL
case IPPROTO_SCTP:
iresult = SctpAlias(la, pip, SN_TO_GLOBAL);
break;
diff --git a/sys/netinet/libalias/alias.h b/sys/netinet/libalias/alias.h
index f3e57de..2aed829 100644
--- a/sys/netinet/libalias/alias.h
+++ b/sys/netinet/libalias/alias.h
@@ -36,13 +36,6 @@
* distribution.
*/
-/**
- * Modifications to add sctp functionality by David A. Hayes
- * $Id: alias.h 122 2008-06-25 06:50:47Z dhayes $
- * All are inclosed in #ifdef _ALIAS_SCTP
- *
- */
-
#ifndef _ALIAS_H_
#define _ALIAS_H_
@@ -52,11 +45,6 @@
#define LIBALIAS_BUF_SIZE 128
#ifdef _KERNEL
-
-#ifndef _ALIAS_SCTP
-#define _ALIAS_SCTP //if ALIAS_SCTP code is to be included
-#endif
-
/*
* The kernel version of libalias does not support these features.
*/
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index 94dfa51..489933f 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -141,13 +141,6 @@ __FBSDID("$FreeBSD$");
See HISTORY file for additional revisions.
*/
-/**
- * Modifications to add sctp functionality by David A. Hayes
- * $Id: alias_db.c 177 2008-07-14 04:33:47Z dhayes $
- * All are inclosed in #ifdef _ALIAS_SCTP
- *
- */
-
#ifdef _KERNEL
#include <machine/stdarg.h>
@@ -173,9 +166,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
#include <netinet/libalias/alias_mod.h>
-#ifdef _ALIAS_SCTP
-#include <netinet/libalias/alias_sctp.h>
-#endif
#include <net/if.h>
#else
#include "alias.h"
@@ -383,7 +373,6 @@ static moduledata_t alias_mod = {
};
DECLARE_MODULE(alias, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
-
#endif
/* Internal utility routines (used only in alias_db.c)
@@ -421,10 +410,8 @@ static void ClearFWHole(struct alias_link *);
static void ShowAliasStats(struct libalias *);
static int InitPacketAliasLog(struct libalias *);
static void UninitPacketAliasLog(struct libalias *);
-#ifdef _ALIAS_SCTP
-struct in_addr FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm);
+
void SctpShowAliasStats(struct libalias *la);
-#endif
static u_int
StartPointIn(struct in_addr alias_addr,
@@ -504,25 +491,17 @@ ShowAliasStats(struct libalias *la)
/* Used for debugging */
if (la->logDesc) {
int tot = la->icmpLinkCount + la->udpLinkCount +
-#ifdef _ALIAS_SCTP
(la->sctpLinkCount>>1) + /* sctp counts half associations */
-#endif
la->tcpLinkCount + la->pptpLinkCount +
la->protoLinkCount + la->fragmentIdLinkCount +
la->fragmentPtrLinkCount;
AliasLog(la->logDesc,
-#ifdef _ALIAS_SCTP
"icmp=%u, udp=%u, tcp=%u, sctp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u",
-#else
- "icmp=%u, udp=%u, tcp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u",
-#endif
la->icmpLinkCount,
la->udpLinkCount,
la->tcpLinkCount,
-#ifdef _ALIAS_SCTP
la->sctpLinkCount>>1, /* sctp counts half associations */
-#endif
la->pptpLinkCount,
la->protoLinkCount,
la->fragmentIdLinkCount,
@@ -533,12 +512,12 @@ ShowAliasStats(struct libalias *la)
}
}
-#ifdef _ALIAS_SCTP
void SctpShowAliasStats(struct libalias *la)
{
- ShowAliasStats(la);
+
+ ShowAliasStats(la);
}
-#endif
+
/* Internal routines for finding, deleting and adding links
@@ -1003,10 +982,6 @@ AddLink(struct libalias *la, struct in_addr src_addr,
case LINK_TCP:
lnk->expire_time = TCP_EXPIRE_INITIAL;
break;
-#ifdef _ALIAS_SCTP
- case LINK_SCTP: /* treat like LINK_ADDR */
- break;
-#endif
case LINK_PPTP:
lnk->flags |= LINK_PERMANENT; /* no timeout. */
break;
@@ -1067,10 +1042,6 @@ AddLink(struct libalias *la, struct in_addr src_addr,
return (NULL);
}
break;
-#ifdef _ALIAS_SCTP
- case LINK_SCTP: /* treat like LINK_ADDR */
- break;
-#endif
case LINK_PPTP:
la->pptpLinkCount++;
break;
@@ -1317,17 +1288,16 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr,
src_addr = lnk->src_addr;
src_port = lnk->src_port;
}
-#ifdef _ALIAS_SCTP
- if(link_type == LINK_SCTP) {
+
+ if (link_type == LINK_SCTP) {
lnk->src_addr = src_addr;
lnk->src_port = src_port;
return(lnk);
}
-#endif
- lnk = ReLink(lnk,
- src_addr, dst_addr, alias_addr,
- src_port, dst_port, alias_port,
- link_type);
+ lnk = ReLink(lnk,
+ src_addr, dst_addr, alias_addr,
+ src_port, dst_port, alias_port,
+ link_type);
}
return (lnk);
}
@@ -2323,11 +2293,9 @@ LibAliasRedirectPort(struct libalias *la, struct in_addr src_addr, u_short src_p
case IPPROTO_TCP:
link_type = LINK_TCP;
break;
-#ifdef _ALIAS_SCTP
case IPPROTO_SCTP:
link_type = LINK_SCTP;
break;
-#endif
default:
#ifdef LIBALIAS_DEBUG
fprintf(stderr, "PacketAliasRedirectPort(): ");
@@ -2547,8 +2515,8 @@ LibAliasInit(struct libalias *la)
LIST_INIT(&la->linkTableOut[i]);
for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
LIST_INIT(&la->linkTableIn[i]);
-#ifdef _ALIAS_SCTP
- AliasSctpInit(la);//***
+#ifdef _KERNEL
+ AliasSctpInit(la);
#endif
LIBALIAS_LOCK_INIT(la);
LIBALIAS_LOCK(la);
@@ -2557,7 +2525,7 @@ LibAliasInit(struct libalias *la)
la->deleteAllLinks = 1;
CleanupAliasData(la);
la->deleteAllLinks = 0;
-#ifdef _ALIAS_SCTP
+#ifdef _KERNEL
AliasSctpTerm(la);
AliasSctpInit(la);
#endif
@@ -2569,9 +2537,7 @@ LibAliasInit(struct libalias *la)
la->icmpLinkCount = 0;
la->udpLinkCount = 0;
la->tcpLinkCount = 0;
-#ifdef _ALIAS_SCTP
la->sctpLinkCount = 0;
-#endif
la->pptpLinkCount = 0;
la->protoLinkCount = 0;
la->fragmentIdLinkCount = 0;
@@ -2600,7 +2566,7 @@ LibAliasUninit(struct libalias *la)
{
LIBALIAS_LOCK(la);
-#ifdef _ALIAS_SCTP
+#ifdef _KERNEL
AliasSctpTerm(la);
#endif
la->deleteAllLinks = 1;
@@ -2943,39 +2909,30 @@ LibAliasSetSkinnyPort(struct libalias *la, unsigned int port)
la->skinnyPort = port;
LIBALIAS_UNLOCK(la);
}
-#ifdef _ALIAS_SCTP
-/**
- * @brief Find the address to redirect incoming packets
- *
- * The function is located in alias_db.c due to calls to static functions
- *
- *
- * @param la pointer to the libalias instance
- * @param sm pointer to the incoming message
- *
- * @return address to redirect an incoming INIT to
+
+/*
+ * Find the address to redirect incoming packets
*/
struct in_addr
FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm)
{
- struct alias_link *lnk;
- struct in_addr redir;
-
- LIBALIAS_LOCK_ASSERT(la);
- lnk = FindLinkIn(la, sm->ip_hdr->ip_src, sm->ip_hdr->ip_dst,
- sm->sctp_hdr->dest_port,sm->sctp_hdr->dest_port, LINK_SCTP, 1);
- if (lnk != NULL) {
- return(lnk->src_addr); /* port redirect */
- } else {
- redir = FindOriginalAddress(la,sm->ip_hdr->ip_dst);
- if (redir.s_addr == la->aliasAddress.s_addr ||
- redir.s_addr == la->targetAddress.s_addr) { /* No address found */
- lnk = FindLinkIn(la, sm->ip_hdr->ip_src, sm->ip_hdr->ip_dst,
- NO_DEST_PORT, 0, LINK_SCTP, 1);
- if (lnk != NULL)
- return(lnk->src_addr); /* redirect proto */
- }
- return(redir); /* address redirect */
- }
+ struct alias_link *lnk;
+ struct in_addr redir;
+
+ LIBALIAS_LOCK_ASSERT(la);
+ lnk = FindLinkIn(la, sm->ip_hdr->ip_src, sm->ip_hdr->ip_dst,
+ sm->sctp_hdr->dest_port,sm->sctp_hdr->dest_port, LINK_SCTP, 1);
+ if (lnk != NULL) {
+ return(lnk->src_addr); /* port redirect */
+ } else {
+ redir = FindOriginalAddress(la,sm->ip_hdr->ip_dst);
+ if (redir.s_addr == la->aliasAddress.s_addr ||
+ redir.s_addr == la->targetAddress.s_addr) { /* No address found */
+ lnk = FindLinkIn(la, sm->ip_hdr->ip_src, sm->ip_hdr->ip_dst,
+ NO_DEST_PORT, 0, LINK_SCTP, 1);
+ if (lnk != NULL)
+ return(lnk->src_addr); /* redirect proto */
+ }
+ return(redir); /* address redirect */
+ }
}
-#endif
diff --git a/sys/netinet/libalias/alias_ftp.c b/sys/netinet/libalias/alias_ftp.c
index 243dfae..50fa8d0 100644
--- a/sys/netinet/libalias/alias_ftp.c
+++ b/sys/netinet/libalias/alias_ftp.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#else
+#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
diff --git a/sys/netinet/libalias/alias_irc.c b/sys/netinet/libalias/alias_irc.c
index fd76e83..8197fb8 100644
--- a/sys/netinet/libalias/alias_irc.c
+++ b/sys/netinet/libalias/alias_irc.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#else
+#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h
index 4124508..e201394 100644
--- a/sys/netinet/libalias/alias_local.h
+++ b/sys/netinet/libalias/alias_local.h
@@ -42,12 +42,6 @@
*
* <updated several times by original author and Eivind Eklund>
*/
-/**
- * Modifications to add sctp functionality by David A. Hayes
- * $Id: alias_local.h 122 2008-06-25 06:50:47Z dhayes $
- * All are inclosed in #ifdef _ALIAS_SCTP
- *
- */
#ifndef _ALIAS_LOCAL_H_
#define _ALIAS_LOCAL_H_
@@ -56,16 +50,6 @@
#include <sys/sysctl.h>
#ifdef _KERNEL
-/* if alias_sctp is not required, #define _ALIAS_SCTP should be commented out */
-#ifndef _ALIAS_SCTP
-#define _ALIAS_SCTP
-#endif
-#ifdef _ALIAS_SCTP
-#include <netinet/libalias/alias_sctp.h>
-#endif
-#endif
-
-#ifdef _KERNEL
#include <sys/malloc.h>
#include <sys/param.h>
#include <sys/lock.h>
@@ -73,6 +57,10 @@
/* XXX: LibAliasSetTarget() uses this constant. */
#define INADDR_NONE 0xffffffff
+
+#include <netinet/libalias/alias_sctp.h>
+#else
+#include "alias_sctp.h"
#endif
/* Sizes of input and output link tables */
@@ -163,33 +151,29 @@ struct libalias {
struct in_addr true_addr; /* in network byte order. */
u_short true_port; /* in host byte order. */
- /*
- *
- *alias_sctp code
- */
-#ifdef _ALIAS_SCTP
- /*counts associations that have progressed to UP and not yet removed */
- int sctpLinkCount;
- /*Timing queue for keeping track of association timeouts */
- struct sctp_nat_timer sctpNatTimer;
-
- /* Size of hash table used in this instance*/
- u_int sctpNatTableSize;
-/**
- * @brief Local look up table
- *
- * lookup table of sctp_nat_assoc sorted by l_vtag/l_port
- */
- LIST_HEAD(sctpNatTableL, sctp_nat_assoc) *sctpTableLocal;
-/**
- * @brief Global look up table
- *
- * lookup table of sctp_nat_assoc sorted by g_vtag/g_port
- */
- LIST_HEAD(sctpNatTableG, sctp_nat_assoc) *sctpTableGlobal;
-#endif
+ /*
+ * sctp code support
+ */
+
+ /* counts associations that have progressed to UP and not yet removed */
+ int sctpLinkCount;
#ifdef _KERNEL
+ /* timing queue for keeping track of association timeouts */
+ struct sctp_nat_timer sctpNatTimer;
+
+ /* size of hash table used in this instance */
+ u_int sctpNatTableSize;
+
+/*
+ * local look up table sorted by l_vtag/l_port
+ */
+ LIST_HEAD(sctpNatTableL, sctp_nat_assoc) *sctpTableLocal;
+/*
+ * global look up table sorted by g_vtag/g_port
+ */
+ LIST_HEAD(sctpNatTableG, sctp_nat_assoc) *sctpTableGlobal;
+
/*
* avoid races in libalias: every public function has to use it.
*/
@@ -240,21 +224,13 @@ struct libalias {
/* Prototypes */
- /*
- *
- *alias_sctp code
- */
-#ifdef _ALIAS_SCTP
/*
* SctpFunction prototypes
*
*/
void AliasSctpInit(struct libalias *la);
void AliasSctpTerm(struct libalias *la);
-
int SctpAlias(struct libalias *la, struct ip *ip, int direction);
-//int SctpAliasOut(struct libalias *la, struct ip *ip);
-#endif
/*
* We do not calculate TCP checksums when libalias is a kernel
@@ -322,6 +298,8 @@ struct in_addr
FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
struct in_addr
FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
+struct in_addr
+FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm);
/* External data access/modification */
int
diff --git a/sys/netinet/libalias/alias_nbt.c b/sys/netinet/libalias/alias_nbt.c
index 0d17870..924ee6a 100644
--- a/sys/netinet/libalias/alias_nbt.c
+++ b/sys/netinet/libalias/alias_nbt.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
+#include <strings.h>
#endif
#include <netinet/in_systm.h>
diff --git a/sys/netinet/libalias/alias_sctp.c b/sys/netinet/libalias/alias_sctp.c
index 5cb9acc..89dc979 100644
--- a/sys/netinet/libalias/alias_sctp.c
+++ b/sys/netinet/libalias/alias_sctp.c
@@ -1,34 +1,9 @@
-//* $Id$ */
-//#ifndef lint
-//static char vcid[] = "$Id$";
-//#endif /* lint */
/**
* @file alias_sctp.c
* Copyright (c) 2008, Centre for Advanced Internet Architectures
* Swinburne University of Technology, Melbourne, Australia
* (CRICOS number 00111D).
*
- * Alias_sctp forms part of the libalias kernel module to handle
- * Network Address Translation (NAT) for the SCTP protocol.
- *
- * This software was developed by David A. Hayes and Jason But
- *
- * The design is outlined in CAIA technical report number 080618A
- * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW")
- *
- * Development is part of the CAIA SONATA project,
- * proposed by Jason But and Grenville Armitage:
- * http://caia.swin.edu.au/urp/sonata/
- *
- *
- * This project has been made possible in part by a grant from
- * the Cisco University Research Program Fund at Community
- * Foundation Silicon Valley.
- *
- *
- *
- * All rights reserved.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -54,6 +29,23 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Alias_sctp forms part of the libalias kernel module to handle
+ * Network Address Translation (NAT) for the SCTP protocol.
+ *
+ * This software was developed by David A. Hayes and Jason But
+ *
+ * The design is outlined in CAIA technical report number 080618A
+ * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW")
+ *
+ * Development is part of the CAIA SONATA project,
+ * proposed by Jason But and Grenville Armitage:
+ * http://caia.swin.edu.au/urp/sonata/
+ *
+ *
+ * This project has been made possible in part by a grant from
+ * the Cisco University Research Program Fund at Community
+ * Foundation Silicon Valley.
+ *
*/
/** @mainpage
* Alias_sctp is part of the SONATA (http://caia.swin.edu.au/urp/sonata) project
@@ -80,6 +72,8 @@
* - Dynamic control of hash-table size
*/
+/* $FreeBSD$ */
+
#ifdef _KERNEL
#include <machine/stdarg.h>
#include <sys/param.h>
@@ -107,9 +101,9 @@
*/
/* Packet Parsing Functions */
static int sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
- struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc);
+ struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc);
static int GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm,
- uint32_t *l_vtag, uint32_t *g_vtag, int direction);
+ uint32_t *l_vtag, uint32_t *g_vtag, int direction);
static int IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction);
static void AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction);
@@ -119,20 +113,20 @@ static int IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int directio
/* State Machine Functions */
static int ProcessSctpMsg(struct libalias *la, int direction, \
- struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc);
+ struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc);
static int ID_process(struct libalias *la, int direction,\
- struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
+ struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
static int INi_process(struct libalias *la, int direction,\
- struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
+ struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
static int INa_process(struct libalias *la, int direction,\
- struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
+ struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
static int UP_process(struct libalias *la, int direction,\
- struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
+ struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
static int CL_process(struct libalias *la, int direction,\
- struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
+ struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm);
static void TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm,\
- struct sctp_nat_assoc *assoc, int sndrply, int direction);
+ struct sctp_nat_assoc *assoc, int sndrply, int direction);
/* Hash Table Functions */
static struct sctp_nat_assoc*
@@ -189,22 +183,6 @@ static void SctpAliasLog(const char *format, ...);
*/
void SctpShowAliasStats(struct libalias *la);
-/** @ingroup external
- * @brief Find the address to redirect incoming packets
- *
- * This function is defined in alias_db.c, since it calls static functions in
- * this file
- *
- * Given a destination port for incoming packets to the NAT, discover what
- * (if any) internal IP address this packet should be re-directed to
- *
- * @param la Pointer to the libalias instance
- * @param sm Pointer to the incoming message
- *
- * @return Address to redirect an incoming INIT to
- */
-struct in_addr FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm);
-
#ifdef _KERNEL
MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs");
@@ -364,9 +342,9 @@ static u_int sysctl_holddown_timer = 0; /**< Seconds to hold an association in t
static u_int sysctl_hashtable_size = SN_DEFAULT_HASH_SIZE; /**< Sets the hash table size for any NEW NAT instances (existing instances retain their existing Hash Table */
/** @brief net.inet.ip.alias.sctp.error_on_ootb */
static u_int sysctl_error_on_ootb = 1; /**< NAT response to receipt of OOTB packet
- (0 - No response, 1 - NAT will send ErrorM only to local side,
- 2 - NAT will send local ErrorM and global ErrorM if there was a partial association match
- 3 - NAT will send ErrorM to both local and global) */
+ (0 - No response, 1 - NAT will send ErrorM only to local side,
+ 2 - NAT will send local ErrorM and global ErrorM if there was a partial association match
+ 3 - NAT will send ErrorM to both local and global) */
/** @brief net.inet.ip.alias.sctp.accept_global_ootb_addip */
static u_int sysctl_accept_global_ootb_addip = 0; /**<NAT responset to receipt of global OOTB AddIP (0 - No response, 1 - NAT will accept OOTB global AddIP messages for processing (Security risk)) */
/** @brief net.inet.ip.alias.sctp.initialising_chunk_proc_limit */
@@ -377,7 +355,7 @@ static u_int sysctl_chunk_proc_limit = 5; /**< A limit on the number of chunks t
static u_int sysctl_param_proc_limit = 25; /**< A limit on the number of parameters (in chunks) that should be searched (DoS prevention) */
/** @brief net.inet.ip.alias.sctp.track_global_addresses */
static u_int sysctl_track_global_addresses = 0; /**< Configures the global address tracking option within the NAT (0 - Global tracking is disabled, > 0 - enables tracking but limits the number of global IP addresses to this value)
- If set to >=1 the NAT will track that many global IP addresses. This may reduce look up table conflicts, but increases processing */
+ If set to >=1 the NAT will track that many global IP addresses. This may reduce look up table conflicts, but increases processing */
#define SN_NO_ERROR_ON_OOTB 0 /**< Send no errorM on out of the blue packets */
#define SN_LOCAL_ERROR_ON_OOTB 1 /**< Send only local errorM on out of the blue packets */
@@ -393,41 +371,41 @@ SYSCTL_DECL(_net_inet_ip_alias);
SYSCTL_NODE(_net_inet_ip_alias, OID_AUTO, sctp, CTLFLAG_RW, NULL, "SCTP NAT");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, log_level, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_log_level, 0, sysctl_chg_loglevel, "IU",
- "Level of detail (0 - default, 1 - event, 2 - info, 3 - detail, 4 - debug, 5 - max debug)");
+ &sysctl_log_level, 0, sysctl_chg_loglevel, "IU",
+ "Level of detail (0 - default, 1 - event, 2 - info, 3 - detail, 4 - debug, 5 - max debug)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, init_timer, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_init_timer, 0, sysctl_chg_timer, "IU",
- "Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK)");
+ &sysctl_init_timer, 0, sysctl_chg_timer, "IU",
+ "Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, up_timer, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_up_timer, 0, sysctl_chg_timer, "IU",
- "Timeout value (s) to keep an association up with no traffic");
+ &sysctl_up_timer, 0, sysctl_chg_timer, "IU",
+ "Timeout value (s) to keep an association up with no traffic");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, shutdown_timer, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_shutdown_timer, 0, sysctl_chg_timer, "IU",
- "Timeout value (s) while waiting for SHUTDOWN-COMPLETE");
+ &sysctl_shutdown_timer, 0, sysctl_chg_timer, "IU",
+ "Timeout value (s) while waiting for SHUTDOWN-COMPLETE");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, holddown_timer, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_holddown_timer, 0, sysctl_chg_timer, "IU",
- "Hold association in table for this many seconds after receiving a SHUTDOWN-COMPLETE");
+ &sysctl_holddown_timer, 0, sysctl_chg_timer, "IU",
+ "Hold association in table for this many seconds after receiving a SHUTDOWN-COMPLETE");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, hashtable_size, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_hashtable_size, 0, sysctl_chg_hashtable_size, "IU",
- "Size of hash tables used for NAT lookups (100 < prime_number > 1000001)");
+ &sysctl_hashtable_size, 0, sysctl_chg_hashtable_size, "IU",
+ "Size of hash tables used for NAT lookups (100 < prime_number > 1000001)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, error_on_ootb, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_error_on_ootb, 0, sysctl_chg_error_on_ootb, "IU",
- "ErrorM sent on receipt of ootb packet:\n\t0 - none,\n\t1 - to local only,\n\t2 - to local and global if a partial association match,\n\t3 - to local and global (DoS risk)");
+ &sysctl_error_on_ootb, 0, sysctl_chg_error_on_ootb, "IU",
+ "ErrorM sent on receipt of ootb packet:\n\t0 - none,\n\t1 - to local only,\n\t2 - to local and global if a partial association match,\n\t3 - to local and global (DoS risk)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, accept_global_ootb_addip, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_accept_global_ootb_addip, 0, sysctl_chg_accept_global_ootb_addip, "IU",
- "NAT response to receipt of global OOTB AddIP:\n\t0 - No response,\n\t1 - NAT will accept OOTB global AddIP messages for processing (Security risk)");
+ &sysctl_accept_global_ootb_addip, 0, sysctl_chg_accept_global_ootb_addip, "IU",
+ "NAT response to receipt of global OOTB AddIP:\n\t0 - No response,\n\t1 - NAT will accept OOTB global AddIP messages for processing (Security risk)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, initialising_chunk_proc_limit, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_initialising_chunk_proc_limit, 0, sysctl_chg_initialising_chunk_proc_limit, "IU",
- "Number of chunks that should be processed if there is no current association found:\n\t > 0 (A high value is a DoS risk)");
+ &sysctl_initialising_chunk_proc_limit, 0, sysctl_chg_initialising_chunk_proc_limit, "IU",
+ "Number of chunks that should be processed if there is no current association found:\n\t > 0 (A high value is a DoS risk)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, chunk_proc_limit, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_chunk_proc_limit, 0, sysctl_chg_chunk_proc_limit, "IU",
- "Number of chunks that should be processed to find key chunk:\n\t>= initialising_chunk_proc_limit (A high value is a DoS risk)");
+ &sysctl_chunk_proc_limit, 0, sysctl_chg_chunk_proc_limit, "IU",
+ "Number of chunks that should be processed to find key chunk:\n\t>= initialising_chunk_proc_limit (A high value is a DoS risk)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, param_proc_limit, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_param_proc_limit, 0, sysctl_chg_param_proc_limit, "IU",
- "Number of parameters (in a chunk) that should be processed to find key parameters:\n\t> 1 (A high value is a DoS risk)");
+ &sysctl_param_proc_limit, 0, sysctl_chg_param_proc_limit, "IU",
+ "Number of parameters (in a chunk) that should be processed to find key parameters:\n\t> 1 (A high value is a DoS risk)");
SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, track_global_addresses, CTLTYPE_UINT | CTLFLAG_RW,
- &sysctl_track_global_addresses, 0, sysctl_chg_track_global_addresses, "IU",
- "Configures the global address tracking option within the NAT:\n\t0 - Global tracking is disabled,\n\t> 0 - enables tracking but limits the number of global IP addresses to this value");
+ &sysctl_track_global_addresses, 0, sysctl_chg_track_global_addresses, "IU",
+ "Configures the global address tracking option within the NAT:\n\t0 - Global tracking is disabled,\n\t> 0 - enables tracking but limits the number of global IP addresses to this value");
#endif /* SYSCTL_NODE */
@@ -440,16 +418,16 @@ SYSCTL_PROC(_net_inet_ip_alias_sctp, OID_AUTO, track_global_addresses, CTLTYPE_U
*/
int sysctl_chg_loglevel(SYSCTL_HANDLER_ARGS)
{
- u_int level = *(u_int *)arg1;
- int error;
+ u_int level = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &level, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &level, 0, req);
+ if (error) return (error);
- sysctl_log_level = (level > SN_LOG_DEBUG_MAX)?(SN_LOG_DEBUG_MAX):(level);
- sysctl_log_level = (level < SN_LOG_LOW)?(SN_LOG_LOW):(level);
+ sysctl_log_level = (level > SN_LOG_DEBUG_MAX)?(SN_LOG_DEBUG_MAX):(level);
+ sysctl_log_level = (level < SN_LOG_LOW)?(SN_LOG_LOW):(level);
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -461,22 +439,22 @@ int sysctl_chg_loglevel(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_timer(SYSCTL_HANDLER_ARGS)
{
- u_int timer = *(u_int *)arg1;
- int error;
+ u_int timer = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &timer, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &timer, 0, req);
+ if (error) return (error);
- timer = (timer > SN_MAX_TIMER)?(SN_MAX_TIMER):(timer);
+ timer = (timer > SN_MAX_TIMER)?(SN_MAX_TIMER):(timer);
- if (((u_int *)arg1) != &sysctl_holddown_timer)
- {
- timer = (timer < SN_MIN_TIMER)?(SN_MIN_TIMER):(timer);
- }
+ if (((u_int *)arg1) != &sysctl_holddown_timer)
+ {
+ timer = (timer < SN_MIN_TIMER)?(SN_MIN_TIMER):(timer);
+ }
- *(u_int *)arg1 = timer;
+ *(u_int *)arg1 = timer;
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -490,20 +468,20 @@ int sysctl_chg_timer(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS)
{
- u_int size = *(u_int *)arg1;
- int error;
+ u_int size = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &size, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &size, 0, req);
+ if (error) return (error);
- size = (size < SN_MIN_HASH_SIZE)?(SN_MIN_HASH_SIZE):((size > SN_MAX_HASH_SIZE)?(SN_MAX_HASH_SIZE):(size));
+ size = (size < SN_MIN_HASH_SIZE)?(SN_MIN_HASH_SIZE):((size > SN_MAX_HASH_SIZE)?(SN_MAX_HASH_SIZE):(size));
- size |= 0x00000001; /* make odd */
+ size |= 0x00000001; /* make odd */
- for(;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2);
- sysctl_hashtable_size = size;
+ for(;(((size % 3) == 0) || ((size % 5) == 0) || ((size % 7) == 0) || ((size % 11) == 0)); size+=2);
+ sysctl_hashtable_size = size;
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -518,15 +496,15 @@ int sysctl_chg_hashtable_size(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_error_on_ootb(SYSCTL_HANDLER_ARGS)
{
- u_int flag = *(u_int *)arg1;
- int error;
+ u_int flag = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &flag, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &flag, 0, req);
+ if (error) return (error);
- sysctl_error_on_ootb = (flag > SN_ERROR_ON_OOTB) ? SN_ERROR_ON_OOTB: flag;
+ sysctl_error_on_ootb = (flag > SN_ERROR_ON_OOTB) ? SN_ERROR_ON_OOTB: flag;
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -537,15 +515,15 @@ int sysctl_chg_error_on_ootb(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_accept_global_ootb_addip(SYSCTL_HANDLER_ARGS)
{
- u_int flag = *(u_int *)arg1;
- int error;
+ u_int flag = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &flag, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &flag, 0, req);
+ if (error) return (error);
- sysctl_accept_global_ootb_addip = (flag == 1) ? 1: 0;
+ sysctl_accept_global_ootb_addip = (flag == 1) ? 1: 0;
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -557,17 +535,17 @@ int sysctl_chg_accept_global_ootb_addip(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_initialising_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
{
- u_int proclimit = *(u_int *)arg1;
- int error;
+ u_int proclimit = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &proclimit, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &proclimit, 0, req);
+ if (error) return (error);
- sysctl_initialising_chunk_proc_limit = (proclimit < 1) ? 1: proclimit;
- sysctl_chunk_proc_limit =
- (sysctl_chunk_proc_limit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : sysctl_chunk_proc_limit;
+ sysctl_initialising_chunk_proc_limit = (proclimit < 1) ? 1: proclimit;
+ sysctl_chunk_proc_limit =
+ (sysctl_chunk_proc_limit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : sysctl_chunk_proc_limit;
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -579,16 +557,16 @@ int sysctl_chg_initialising_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
{
- u_int proclimit = *(u_int *)arg1;
- int error;
+ u_int proclimit = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &proclimit, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &proclimit, 0, req);
+ if (error) return (error);
- sysctl_chunk_proc_limit =
- (proclimit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : proclimit;
+ sysctl_chunk_proc_limit =
+ (proclimit < sysctl_initialising_chunk_proc_limit) ? sysctl_initialising_chunk_proc_limit : proclimit;
- return (0);
+ return (0);
}
@@ -601,16 +579,16 @@ int sysctl_chg_chunk_proc_limit(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_param_proc_limit(SYSCTL_HANDLER_ARGS)
{
- u_int proclimit = *(u_int *)arg1;
- int error;
+ u_int proclimit = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &proclimit, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &proclimit, 0, req);
+ if (error) return (error);
- sysctl_param_proc_limit =
- (proclimit < 2) ? 2 : proclimit;
+ sysctl_param_proc_limit =
+ (proclimit < 2) ? 2 : proclimit;
- return (0);
+ return (0);
}
/** @ingroup sysctl
@@ -622,15 +600,15 @@ int sysctl_chg_param_proc_limit(SYSCTL_HANDLER_ARGS)
*/
int sysctl_chg_track_global_addresses(SYSCTL_HANDLER_ARGS)
{
- u_int num_to_track = *(u_int *)arg1;
- int error;
+ u_int num_to_track = *(u_int *)arg1;
+ int error;
- error = sysctl_handle_int(oidp, &num_to_track, 0, req);
- if (error) return (error);
+ error = sysctl_handle_int(oidp, &num_to_track, 0, req);
+ if (error) return (error);
- sysctl_track_global_addresses = (num_to_track > SN_MAX_GLOBAL_ADDRESSES) ? SN_MAX_GLOBAL_ADDRESSES : num_to_track;
+ sysctl_track_global_addresses = (num_to_track > SN_MAX_GLOBAL_ADDRESSES) ? SN_MAX_GLOBAL_ADDRESSES : num_to_track;
- return (0);
+ return (0);
}
@@ -648,30 +626,30 @@ int sysctl_chg_track_global_addresses(SYSCTL_HANDLER_ARGS)
*/
void AliasSctpInit(struct libalias *la)
{
- /* Initialise association tables*/
- int i;
- la->sctpNatTableSize = sysctl_hashtable_size;
- SN_LOG(SN_LOG_EVENT,
- SctpAliasLog("Initialising SCTP NAT Instance (hash_table_size:%d)\n", la->sctpNatTableSize));
- la->sctpTableLocal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableL));
- la->sctpTableGlobal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableG));
- la->sctpNatTimer.TimerQ = sn_calloc(SN_TIMER_QUEUE_SIZE, sizeof(struct sctpTimerQ));
- /* Initialise hash table */
- for (i = 0; i < la->sctpNatTableSize; i++) {
- LIST_INIT(&la->sctpTableLocal[i]);
- LIST_INIT(&la->sctpTableGlobal[i]);
- }
-
- /* Initialise circular timer Q*/
- for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++)
- LIST_INIT(&la->sctpNatTimer.TimerQ[i]);
+ /* Initialise association tables*/
+ int i;
+ la->sctpNatTableSize = sysctl_hashtable_size;
+ SN_LOG(SN_LOG_EVENT,
+ SctpAliasLog("Initialising SCTP NAT Instance (hash_table_size:%d)\n", la->sctpNatTableSize));
+ la->sctpTableLocal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableL));
+ la->sctpTableGlobal = sn_calloc(la->sctpNatTableSize, sizeof(struct sctpNatTableG));
+ la->sctpNatTimer.TimerQ = sn_calloc(SN_TIMER_QUEUE_SIZE, sizeof(struct sctpTimerQ));
+ /* Initialise hash table */
+ for (i = 0; i < la->sctpNatTableSize; i++) {
+ LIST_INIT(&la->sctpTableLocal[i]);
+ LIST_INIT(&la->sctpTableGlobal[i]);
+ }
+
+ /* Initialise circular timer Q*/
+ for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++)
+ LIST_INIT(&la->sctpNatTimer.TimerQ[i]);
#ifdef _KERNEL
- la->sctpNatTimer.loc_time=time_uptime; /* la->timeStamp is not set yet */
+ la->sctpNatTimer.loc_time=time_uptime; /* la->timeStamp is not set yet */
#else
- la->sctpNatTimer.loc_time=la->timeStamp;
+ la->sctpNatTimer.loc_time=la->timeStamp;
#endif
- la->sctpNatTimer.cur_loc = 0;
- la->sctpLinkCount = 0;
+ la->sctpNatTimer.cur_loc = 0;
+ la->sctpLinkCount = 0;
}
/**
@@ -688,25 +666,25 @@ void AliasSctpInit(struct libalias *la)
*/
void AliasSctpTerm(struct libalias *la)
{
- struct sctp_nat_assoc *assoc1, *assoc2;
- int i;
-
- LIBALIAS_LOCK_ASSERT(la);
- SN_LOG(SN_LOG_EVENT,
- SctpAliasLog("Removing SCTP NAT Instance\n"));
- for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) {
- assoc1 = LIST_FIRST(&la->sctpNatTimer.TimerQ[i]);
- while (assoc1 != NULL) {
- freeGlobalAddressList(assoc1);
- assoc2 = LIST_NEXT(assoc1, timer_Q);
- sn_free(assoc1);
- assoc1 = assoc2;
- }
- }
-
- sn_free(la->sctpTableLocal);
- sn_free(la->sctpTableGlobal);
- sn_free(la->sctpNatTimer.TimerQ);
+ struct sctp_nat_assoc *assoc1, *assoc2;
+ int i;
+
+ LIBALIAS_LOCK_ASSERT(la);
+ SN_LOG(SN_LOG_EVENT,
+ SctpAliasLog("Removing SCTP NAT Instance\n"));
+ for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) {
+ assoc1 = LIST_FIRST(&la->sctpNatTimer.TimerQ[i]);
+ while (assoc1 != NULL) {
+ freeGlobalAddressList(assoc1);
+ assoc2 = LIST_NEXT(assoc1, timer_Q);
+ sn_free(assoc1);
+ assoc1 = assoc2;
+ }
+ }
+
+ sn_free(la->sctpTableLocal);
+ sn_free(la->sctpTableGlobal);
+ sn_free(la->sctpNatTimer.TimerQ);
}
/**
@@ -735,122 +713,122 @@ void AliasSctpTerm(struct libalias *la)
int
SctpAlias(struct libalias *la, struct ip *pip, int direction)
{
- int rtnval;
- struct sctp_nat_msg msg;
- struct sctp_nat_assoc *assoc = NULL;
-
- if ((direction != SN_TO_LOCAL) && (direction != SN_TO_GLOBAL)) {
- SctpAliasLog("ERROR: Invalid direction\n");
- return(PKT_ALIAS_ERROR);
- }
-
- sctp_CheckTimers(la); /* Check timers */
-
- /* Parse the packet */
- rtnval = sctp_PktParser(la, direction, pip, &msg, &assoc); //using *char (change to mbuf when get code from paolo)
- switch (rtnval) {
- case SN_PARSE_OK:
- break;
- case SN_PARSE_ERROR_CHHL:
- /* Not an error if there is a chunk length parsing error and this is a fragmented packet */
- if (ntohs(pip->ip_off) & IP_MF) {
- rtnval = SN_PARSE_OK;
- break;
- }
- SN_LOG(SN_LOG_EVENT,
- logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- return(PKT_ALIAS_ERROR);
- case SN_PARSE_ERROR_PARTIALLOOKUP:
- if (sysctl_error_on_ootb > SN_LOCALandPARTIAL_ERROR_ON_OOTB) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- return(PKT_ALIAS_ERROR);
- }
- case SN_PARSE_ERROR_LOOKUP:
- if (sysctl_error_on_ootb == SN_ERROR_ON_OOTB ||
- (sysctl_error_on_ootb == SN_LOCALandPARTIAL_ERROR_ON_OOTB && direction == SN_TO_LOCAL) ||
- (sysctl_error_on_ootb == SN_LOCAL_ERROR_ON_OOTB && direction == SN_TO_GLOBAL)) {
- TxAbortErrorM(la, &msg, assoc, SN_REFLECT_ERROR, direction); /*NB assoc=NULL */
- return(PKT_ALIAS_RESPOND);
- }
- default:
- SN_LOG(SN_LOG_EVENT,
- logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- return(PKT_ALIAS_ERROR);
- }
-
- SN_LOG(SN_LOG_DETAIL,
- logsctpassoc(assoc, "*");
- logsctpparse(direction, &msg);
- );
-
- /* Process the SCTP message */
- rtnval = ProcessSctpMsg(la, direction, &msg, assoc);
-
- SN_LOG(SN_LOG_DEBUG_MAX,
- logsctpassoc(assoc, "-");
- logSctpLocal(la);
- logSctpGlobal(la);
- );
- SN_LOG(SN_LOG_DEBUG, logTimerQ(la));
-
- switch(rtnval){
- case SN_NAT_PKT:
- switch(direction) {
- case SN_TO_LOCAL:
- DifferentialChecksum(&(msg.ip_hdr->ip_sum),
- &(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2);
- msg.ip_hdr->ip_dst = assoc->l_addr; /* change dst address to local address*/
- break;
- case SN_TO_GLOBAL:
- DifferentialChecksum(&(msg.ip_hdr->ip_sum),
- &(assoc->a_addr), &(msg.ip_hdr->ip_src), 2);
- msg.ip_hdr->ip_src = assoc->a_addr; /* change src to alias addr*/
- break;
- default:
- rtnval = SN_DROP_PKT; /* shouldn't get here, but if it does drop packet */
- SN_LOG(SN_LOG_LOW, logsctperror("ERROR: Invalid direction", msg.sctp_hdr->v_tag, rtnval, direction));
- break;
- }
- break;
- case SN_DROP_PKT:
- SN_LOG(SN_LOG_DETAIL, logsctperror("SN_DROP_PKT", msg.sctp_hdr->v_tag, rtnval, direction));
- break;
- case SN_REPLY_ABORT:
- case SN_REPLY_ERROR:
- case SN_SEND_ABORT:
- TxAbortErrorM(la, &msg, assoc, rtnval, direction);
- break;
- default:
- // big error, remove association and go to idle and write log messages
- SN_LOG(SN_LOG_LOW, logsctperror("SN_PROCESSING_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
- assoc->state=SN_RM;/* Mark for removal*/
- break;
- }
-
- /* Remove association if tagged for removal */
- if (assoc->state == SN_RM) {
- if (assoc->TableRegister) {
- sctp_RmTimeOut(la, assoc);
- RmSctpAssoc(la, assoc);
- }
- LIBALIAS_LOCK_ASSERT(la);
- freeGlobalAddressList(assoc);
- sn_free(assoc);
- }
- switch(rtnval) {
- case SN_NAT_PKT:
- return(PKT_ALIAS_OK);
- case SN_SEND_ABORT:
- return(PKT_ALIAS_OK);
- case SN_REPLY_ABORT:
- case SN_REPLY_ERROR:
- case SN_REFLECT_ERROR:
- return(PKT_ALIAS_RESPOND);
- case SN_DROP_PKT:
- default:
- return(PKT_ALIAS_ERROR);
- }
+ int rtnval;
+ struct sctp_nat_msg msg;
+ struct sctp_nat_assoc *assoc = NULL;
+
+ if ((direction != SN_TO_LOCAL) && (direction != SN_TO_GLOBAL)) {
+ SctpAliasLog("ERROR: Invalid direction\n");
+ return(PKT_ALIAS_ERROR);
+ }
+
+ sctp_CheckTimers(la); /* Check timers */
+
+ /* Parse the packet */
+ rtnval = sctp_PktParser(la, direction, pip, &msg, &assoc); //using *char (change to mbuf when get code from paolo)
+ switch (rtnval) {
+ case SN_PARSE_OK:
+ break;
+ case SN_PARSE_ERROR_CHHL:
+ /* Not an error if there is a chunk length parsing error and this is a fragmented packet */
+ if (ntohs(pip->ip_off) & IP_MF) {
+ rtnval = SN_PARSE_OK;
+ break;
+ }
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
+ return(PKT_ALIAS_ERROR);
+ case SN_PARSE_ERROR_PARTIALLOOKUP:
+ if (sysctl_error_on_ootb > SN_LOCALandPARTIAL_ERROR_ON_OOTB) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
+ return(PKT_ALIAS_ERROR);
+ }
+ case SN_PARSE_ERROR_LOOKUP:
+ if (sysctl_error_on_ootb == SN_ERROR_ON_OOTB ||
+ (sysctl_error_on_ootb == SN_LOCALandPARTIAL_ERROR_ON_OOTB && direction == SN_TO_LOCAL) ||
+ (sysctl_error_on_ootb == SN_LOCAL_ERROR_ON_OOTB && direction == SN_TO_GLOBAL)) {
+ TxAbortErrorM(la, &msg, assoc, SN_REFLECT_ERROR, direction); /*NB assoc=NULL */
+ return(PKT_ALIAS_RESPOND);
+ }
+ default:
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("SN_PARSE_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
+ return(PKT_ALIAS_ERROR);
+ }
+
+ SN_LOG(SN_LOG_DETAIL,
+ logsctpassoc(assoc, "*");
+ logsctpparse(direction, &msg);
+ );
+
+ /* Process the SCTP message */
+ rtnval = ProcessSctpMsg(la, direction, &msg, assoc);
+
+ SN_LOG(SN_LOG_DEBUG_MAX,
+ logsctpassoc(assoc, "-");
+ logSctpLocal(la);
+ logSctpGlobal(la);
+ );
+ SN_LOG(SN_LOG_DEBUG, logTimerQ(la));
+
+ switch(rtnval){
+ case SN_NAT_PKT:
+ switch(direction) {
+ case SN_TO_LOCAL:
+ DifferentialChecksum(&(msg.ip_hdr->ip_sum),
+ &(assoc->l_addr), &(msg.ip_hdr->ip_dst), 2);
+ msg.ip_hdr->ip_dst = assoc->l_addr; /* change dst address to local address*/
+ break;
+ case SN_TO_GLOBAL:
+ DifferentialChecksum(&(msg.ip_hdr->ip_sum),
+ &(assoc->a_addr), &(msg.ip_hdr->ip_src), 2);
+ msg.ip_hdr->ip_src = assoc->a_addr; /* change src to alias addr*/
+ break;
+ default:
+ rtnval = SN_DROP_PKT; /* shouldn't get here, but if it does drop packet */
+ SN_LOG(SN_LOG_LOW, logsctperror("ERROR: Invalid direction", msg.sctp_hdr->v_tag, rtnval, direction));
+ break;
+ }
+ break;
+ case SN_DROP_PKT:
+ SN_LOG(SN_LOG_DETAIL, logsctperror("SN_DROP_PKT", msg.sctp_hdr->v_tag, rtnval, direction));
+ break;
+ case SN_REPLY_ABORT:
+ case SN_REPLY_ERROR:
+ case SN_SEND_ABORT:
+ TxAbortErrorM(la, &msg, assoc, rtnval, direction);
+ break;
+ default:
+ // big error, remove association and go to idle and write log messages
+ SN_LOG(SN_LOG_LOW, logsctperror("SN_PROCESSING_ERROR", msg.sctp_hdr->v_tag, rtnval, direction));
+ assoc->state=SN_RM;/* Mark for removal*/
+ break;
+ }
+
+ /* Remove association if tagged for removal */
+ if (assoc->state == SN_RM) {
+ if (assoc->TableRegister) {
+ sctp_RmTimeOut(la, assoc);
+ RmSctpAssoc(la, assoc);
+ }
+ LIBALIAS_LOCK_ASSERT(la);
+ freeGlobalAddressList(assoc);
+ sn_free(assoc);
+ }
+ switch(rtnval) {
+ case SN_NAT_PKT:
+ return(PKT_ALIAS_OK);
+ case SN_SEND_ABORT:
+ return(PKT_ALIAS_OK);
+ case SN_REPLY_ABORT:
+ case SN_REPLY_ERROR:
+ case SN_REFLECT_ERROR:
+ return(PKT_ALIAS_RESPOND);
+ case SN_DROP_PKT:
+ default:
+ return(PKT_ALIAS_ERROR);
+ }
}
/**
@@ -889,92 +867,92 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
static void
TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int sndrply, int direction)
{
- int sctp_size = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_error_cause);
- int ip_size = sizeof(struct ip) + sctp_size;
- int include_error_cause = 1;
- char tmp_ip[ip_size];
-
- if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */
- include_error_cause = 0;
- ip_size = ip_size - sizeof(struct sctp_error_cause);
- sctp_size = sctp_size - sizeof(struct sctp_error_cause);
- }
- /* Assign header pointers packet */
- struct ip* ip = (struct ip *) tmp_ip;
- struct sctphdr* sctp_hdr = (struct sctphdr *) ((char *) ip + sizeof(*ip));
- struct sctp_chunkhdr* chunk_hdr = (struct sctp_chunkhdr *) ((char *) sctp_hdr + sizeof(*sctp_hdr));
- struct sctp_error_cause* error_cause = (struct sctp_error_cause *) ((char *) chunk_hdr + sizeof(*chunk_hdr));
-
- /* construct ip header */
- ip->ip_v = sm->ip_hdr->ip_v;
- ip->ip_hl = 5; /* 5*32 bit words */
- ip->ip_tos = 0;
- ip->ip_len = htons(ip_size);
- ip->ip_id = sm->ip_hdr->ip_id;
- ip->ip_off = 0;
- ip->ip_ttl = 255;
- ip->ip_p = IPPROTO_SCTP;
- /*
- The definitions below should be removed when they make it into the SCTP stack
- */
+ int sctp_size = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_error_cause);
+ int ip_size = sizeof(struct ip) + sctp_size;
+ int include_error_cause = 1;
+ char tmp_ip[ip_size];
+
+ if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */
+ include_error_cause = 0;
+ ip_size = ip_size - sizeof(struct sctp_error_cause);
+ sctp_size = sctp_size - sizeof(struct sctp_error_cause);
+ }
+ /* Assign header pointers packet */
+ struct ip* ip = (struct ip *) tmp_ip;
+ struct sctphdr* sctp_hdr = (struct sctphdr *) ((char *) ip + sizeof(*ip));
+ struct sctp_chunkhdr* chunk_hdr = (struct sctp_chunkhdr *) ((char *) sctp_hdr + sizeof(*sctp_hdr));
+ struct sctp_error_cause* error_cause = (struct sctp_error_cause *) ((char *) chunk_hdr + sizeof(*chunk_hdr));
+
+ /* construct ip header */
+ ip->ip_v = sm->ip_hdr->ip_v;
+ ip->ip_hl = 5; /* 5*32 bit words */
+ ip->ip_tos = 0;
+ ip->ip_len = htons(ip_size);
+ ip->ip_id = sm->ip_hdr->ip_id;
+ ip->ip_off = 0;
+ ip->ip_ttl = 255;
+ ip->ip_p = IPPROTO_SCTP;
+ /*
+ The definitions below should be removed when they make it into the SCTP stack
+ */
#define SCTP_MIDDLEBOX_FLAG 0x02
#define SCTP_NAT_TABLE_COLLISION 0x00b0
#define SCTP_MISSING_NAT 0x00b1
- chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR;
- chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG;
- if (include_error_cause) {
- error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION);
- error_cause->length = htons(sizeof(struct sctp_error_cause));
- chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause));
- } else {
- chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr));
- }
-
- /* set specific values */
- switch(sndrply) {
- case SN_REFLECT_ERROR:
- chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */
- sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
- break;
- case SN_REPLY_ERROR:
- sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ;
- break;
- case SN_SEND_ABORT:
- sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
- break;
- case SN_REPLY_ABORT:
- sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag;
- break;
- }
+ chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR;
+ chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG;
+ if (include_error_cause) {
+ error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION);
+ error_cause->length = htons(sizeof(struct sctp_error_cause));
+ chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause));
+ } else {
+ chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr));
+ }
+
+ /* set specific values */
+ switch(sndrply) {
+ case SN_REFLECT_ERROR:
+ chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */
+ sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
+ break;
+ case SN_REPLY_ERROR:
+ sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ;
+ break;
+ case SN_SEND_ABORT:
+ sctp_hdr->v_tag = sm->sctp_hdr->v_tag;
+ break;
+ case SN_REPLY_ABORT:
+ sctp_hdr->v_tag = sm->sctpchnk.Init->initiate_tag;
+ break;
+ }
- /* Set send/reply values */
- if (sndrply == SN_SEND_ABORT) { /*pass through NAT */
- ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr;
- ip->ip_dst = (direction == SN_TO_LOCAL) ? assoc->l_addr : sm->ip_hdr->ip_dst;
- sctp_hdr->src_port = sm->sctp_hdr->src_port;
- sctp_hdr->dest_port = sm->sctp_hdr->dest_port;
- } else { /* reply and reflect */
- ip->ip_src = sm->ip_hdr->ip_dst;
- ip->ip_dst = sm->ip_hdr->ip_src;
- sctp_hdr->src_port = sm->sctp_hdr->dest_port;
- sctp_hdr->dest_port = sm->sctp_hdr->src_port;
- }
+ /* Set send/reply values */
+ if (sndrply == SN_SEND_ABORT) { /*pass through NAT */
+ ip->ip_src = (direction == SN_TO_LOCAL) ? sm->ip_hdr->ip_src : assoc->a_addr;
+ ip->ip_dst = (direction == SN_TO_LOCAL) ? assoc->l_addr : sm->ip_hdr->ip_dst;
+ sctp_hdr->src_port = sm->sctp_hdr->src_port;
+ sctp_hdr->dest_port = sm->sctp_hdr->dest_port;
+ } else { /* reply and reflect */
+ ip->ip_src = sm->ip_hdr->ip_dst;
+ ip->ip_dst = sm->ip_hdr->ip_src;
+ sctp_hdr->src_port = sm->sctp_hdr->dest_port;
+ sctp_hdr->dest_port = sm->sctp_hdr->src_port;
+ }
- /* Calculate IP header checksum */
- ip->ip_sum = in_cksum_hdr(ip);
+ /* Calculate IP header checksum */
+ ip->ip_sum = in_cksum_hdr(ip);
- /* calculate SCTP header CRC32 */
- sctp_hdr->checksum = 0;
- sctp_hdr->checksum = sctp_csum_finalize(update_crc32(0xffffffff, (unsigned char *) sctp_hdr, sctp_size));
-
- memcpy(sm->ip_hdr, ip, ip_size);
-
- SN_LOG(SN_LOG_EVENT,SctpAliasLog("%s %s 0x%x (->%s:%u vtag=0x%x crc=0x%x)\n",
- ((sndrply == SN_SEND_ABORT) ? "Sending" : "Replying"),
- ((sndrply & SN_TX_ERROR) ? "ErrorM" : "AbortM"),
- (include_error_cause ? ntohs(error_cause->code) : 0),
- inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port),
- ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum)));
+ /* calculate SCTP header CRC32 */
+ sctp_hdr->checksum = 0;
+ sctp_hdr->checksum = sctp_finalize_crc32(update_crc32(0xffffffff, (unsigned char *) sctp_hdr, sctp_size));
+
+ memcpy(sm->ip_hdr, ip, ip_size);
+
+ SN_LOG(SN_LOG_EVENT,SctpAliasLog("%s %s 0x%x (->%s:%u vtag=0x%x crc=0x%x)\n",
+ ((sndrply == SN_SEND_ABORT) ? "Sending" : "Replying"),
+ ((sndrply & SN_TX_ERROR) ? "ErrorM" : "AbortM"),
+ (include_error_cause ? ntohs(error_cause->code) : 0),
+ inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port),
+ ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum)));
}
/* ----------------------------------------------------------------------
@@ -1004,209 +982,209 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
*/
static int
sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
- struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc)
+ struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc)
//sctp_PktParser(int direction, struct mbuf *ipak, int ip_hdr_len,struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc)
{
- struct sctphdr *sctp_hdr;
- struct sctp_chunkhdr *chunk_hdr;
- struct sctp_paramhdr *param_hdr;
- struct in_addr ipv4addr;
- int bytes_left; /* bytes left in ip packet */
- int chunk_length;
- int chunk_count;
- int partial_match = 0;
- // mbuf *mp;
- // int mlen;
-
- // mlen = SCTP_HEADER_LEN(i_pak);
- // mp = SCTP_HEADER_TO_CHAIN(i_pak); /* does nothing in bsd since header and chain not separate */
-
- /*
- * Note, that if the VTag is zero, it must be an INIT
- * Also, I am only interested in the content of INIT and ADDIP chunks
- */
-
- // no mbuf stuff from Paolo yet so ...
- sm->ip_hdr = pip;
- /* remove ip header length from the bytes_left */
- bytes_left = ntohs(pip->ip_len) - (pip->ip_hl << 2);
-
- /* Check SCTP header length and move to first chunk */
- if (bytes_left < sizeof(struct sctphdr)) {
- sm->sctp_hdr = NULL;
- return(SN_PARSE_ERROR_IPSHL); /* packet not long enough*/
- }
-
- sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip);
- bytes_left -= sizeof(struct sctphdr);
+ struct sctphdr *sctp_hdr;
+ struct sctp_chunkhdr *chunk_hdr;
+ struct sctp_paramhdr *param_hdr;
+ struct in_addr ipv4addr;
+ int bytes_left; /* bytes left in ip packet */
+ int chunk_length;
+ int chunk_count;
+ int partial_match = 0;
+ // mbuf *mp;
+ // int mlen;
+
+ // mlen = SCTP_HEADER_LEN(i_pak);
+ // mp = SCTP_HEADER_TO_CHAIN(i_pak); /* does nothing in bsd since header and chain not separate */
+
+ /*
+ * Note, that if the VTag is zero, it must be an INIT
+ * Also, I am only interested in the content of INIT and ADDIP chunks
+ */
+
+ // no mbuf stuff from Paolo yet so ...
+ sm->ip_hdr = pip;
+ /* remove ip header length from the bytes_left */
+ bytes_left = ntohs(pip->ip_len) - (pip->ip_hl << 2);
+
+ /* Check SCTP header length and move to first chunk */
+ if (bytes_left < sizeof(struct sctphdr)) {
+ sm->sctp_hdr = NULL;
+ return(SN_PARSE_ERROR_IPSHL); /* packet not long enough*/
+ }
+
+ sm->sctp_hdr = sctp_hdr = (struct sctphdr *) ip_next(pip);
+ bytes_left -= sizeof(struct sctphdr);
- /* Check for valid ports (zero valued ports would find partially initialised associations */
- if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0)
- return(SN_PARSE_ERROR_PORT);
+ /* Check for valid ports (zero valued ports would find partially initialised associations */
+ if (sctp_hdr->src_port == 0 || sctp_hdr->dest_port == 0)
+ return(SN_PARSE_ERROR_PORT);
- /* Check length of first chunk */
- if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/
- return(SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */
+ /* Check length of first chunk */
+ if (bytes_left < SN_MIN_CHUNK_SIZE) /* malformed chunk - could cause endless loop*/
+ return(SN_PARSE_ERROR_CHHL); /* packet not long enough for this chunk */
- /* First chunk */
- chunk_hdr = SN_SCTP_FIRSTCHUNK(sctp_hdr);
+ /* First chunk */
+ chunk_hdr = SN_SCTP_FIRSTCHUNK(sctp_hdr);
- chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length));
- if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could cause endless loop*/
- return(SN_PARSE_ERROR_CHHL);
-
- if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) &&
- ((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) ||
- (chunk_hdr->chunk_type == SCTP_SHUTDOWN_COMPLETE))) {
- /* T-Bit set */
- if (direction == SN_TO_LOCAL)
- *passoc = FindSctpGlobalT(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port);
- else
- *passoc = FindSctpLocalT(la, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port);
- } else {
- /* Proper v_tag settings */
- if (direction == SN_TO_LOCAL)
- *passoc = FindSctpGlobal(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match);
- else
- *passoc = FindSctpLocal(la, pip->ip_src, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port);
- }
-
- chunk_count = 1;
- /* Real packet parsing occurs below */
- sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/
- sm->chunk_length = 0; /* only care about length for key chunks */
- while (IS_SCTP_CONTROL(chunk_hdr)) {
- switch(chunk_hdr->chunk_type) {
- case SCTP_INITIATION:
- if (chunk_length < sizeof(struct sctp_init_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- sm->msg = SN_SCTP_INIT;
- sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr));
- sm->chunk_length = chunk_length;
- /* if no existing association, create a new one */
- if (*passoc == NULL) {
- if (sctp_hdr->v_tag == 0){ //Init requires vtag=0
- *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc));
- if (*passoc == NULL) {/* out of resources */
- return(SN_PARSE_ERROR_AS_MALLOC);
- }
- /* Initialise association - malloc initialises memory to zeros */
- (*passoc)->state = SN_ID;
- LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */
- (*passoc)->TableRegister = SN_NULL_TBL;
- return(SN_PARSE_OK);
- }
- return(SN_PARSE_ERROR_VTAG);
- }
- return(SN_PARSE_ERROR_LOOKUP);
- case SCTP_INITIATION_ACK:
- if (chunk_length < sizeof(struct sctp_init_ack_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- sm->msg = SN_SCTP_INITACK;
- sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr));
- sm->chunk_length = chunk_length;
- return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK));
- case SCTP_ABORT_ASSOCIATION: /* access only minimum sized chunk */
- sm->msg = SN_SCTP_ABORT;
- sm->chunk_length = chunk_length;
- return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP_ABORT):(SN_PARSE_OK));
- case SCTP_SHUTDOWN_ACK:
- if (chunk_length < sizeof(struct sctp_shutdown_ack_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- if (sm->msg > SN_SCTP_SHUTACK) {
- sm->msg = SN_SCTP_SHUTACK;
- sm->chunk_length = chunk_length;
- }
- break;
- case SCTP_SHUTDOWN_COMPLETE: /* minimum sized chunk */
- if (sm->msg > SN_SCTP_SHUTCOMP) {
- sm->msg = SN_SCTP_SHUTCOMP;
- sm->chunk_length = chunk_length;
- }
- return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK));
- case SCTP_ASCONF:
- if (sm->msg > SN_SCTP_ASCONF) {
- if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv4addr_param))) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- //leave parameter searching to later, if required
- param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_chunk)); /*compulsory IP parameter*/
- if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) {
- if ((*passoc == NULL) && (direction == SN_TO_LOCAL)) { /* AddIP with no association */
- /* try look up with the ASCONF packet's alternative address */
- ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr;
- *passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match);
- }
- param_hdr = (struct sctp_paramhdr *)
- ((char *) param_hdr + sizeof(struct sctp_ipv4addr_param)); /*asconf's compulsory address parameter */
- sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr_param); /* rest of chunk */
+ chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length));
+ if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left)) /* malformed chunk - could cause endless loop*/
+ return(SN_PARSE_ERROR_CHHL);
+
+ if ((chunk_hdr->chunk_flags & SCTP_HAD_NO_TCB) &&
+ ((chunk_hdr->chunk_type == SCTP_ABORT_ASSOCIATION) ||
+ (chunk_hdr->chunk_type == SCTP_SHUTDOWN_COMPLETE))) {
+ /* T-Bit set */
+ if (direction == SN_TO_LOCAL)
+ *passoc = FindSctpGlobalT(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port);
+ else
+ *passoc = FindSctpLocalT(la, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->dest_port, sctp_hdr->src_port);
} else {
- if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv6addr_param))) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- param_hdr = (struct sctp_paramhdr *)
- ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */
- sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr_param); /* rest of chunk */
+ /* Proper v_tag settings */
+ if (direction == SN_TO_LOCAL)
+ *passoc = FindSctpGlobal(la, pip->ip_src, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match);
+ else
+ *passoc = FindSctpLocal(la, pip->ip_src, pip->ip_dst, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port);
}
- sm->msg = SN_SCTP_ASCONF;
- sm->sctpchnk.Asconf = param_hdr;
+
+ chunk_count = 1;
+ /* Real packet parsing occurs below */
+ sm->msg = SN_SCTP_OTHER;/* Initialise to largest value*/
+ sm->chunk_length = 0; /* only care about length for key chunks */
+ while (IS_SCTP_CONTROL(chunk_hdr)) {
+ switch(chunk_hdr->chunk_type) {
+ case SCTP_INITIATION:
+ if (chunk_length < sizeof(struct sctp_init_chunk)) /* malformed chunk*/
+ return(SN_PARSE_ERROR_CHHL);
+ sm->msg = SN_SCTP_INIT;
+ sm->sctpchnk.Init = (struct sctp_init *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr));
+ sm->chunk_length = chunk_length;
+ /* if no existing association, create a new one */
+ if (*passoc == NULL) {
+ if (sctp_hdr->v_tag == 0){ //Init requires vtag=0
+ *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc));
+ if (*passoc == NULL) {/* out of resources */
+ return(SN_PARSE_ERROR_AS_MALLOC);
+ }
+ /* Initialise association - malloc initialises memory to zeros */
+ (*passoc)->state = SN_ID;
+ LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */
+ (*passoc)->TableRegister = SN_NULL_TBL;
+ return(SN_PARSE_OK);
+ }
+ return(SN_PARSE_ERROR_VTAG);
+ }
+ return(SN_PARSE_ERROR_LOOKUP);
+ case SCTP_INITIATION_ACK:
+ if (chunk_length < sizeof(struct sctp_init_ack_chunk)) /* malformed chunk*/
+ return(SN_PARSE_ERROR_CHHL);
+ sm->msg = SN_SCTP_INITACK;
+ sm->sctpchnk.InitAck = (struct sctp_init_ack *) ((char *) chunk_hdr + sizeof(struct sctp_chunkhdr));
+ sm->chunk_length = chunk_length;
+ return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK));
+ case SCTP_ABORT_ASSOCIATION: /* access only minimum sized chunk */
+ sm->msg = SN_SCTP_ABORT;
+ sm->chunk_length = chunk_length;
+ return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP_ABORT):(SN_PARSE_OK));
+ case SCTP_SHUTDOWN_ACK:
+ if (chunk_length < sizeof(struct sctp_shutdown_ack_chunk)) /* malformed chunk*/
+ return(SN_PARSE_ERROR_CHHL);
+ if (sm->msg > SN_SCTP_SHUTACK) {
+ sm->msg = SN_SCTP_SHUTACK;
+ sm->chunk_length = chunk_length;
+ }
+ break;
+ case SCTP_SHUTDOWN_COMPLETE: /* minimum sized chunk */
+ if (sm->msg > SN_SCTP_SHUTCOMP) {
+ sm->msg = SN_SCTP_SHUTCOMP;
+ sm->chunk_length = chunk_length;
+ }
+ return ((*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK));
+ case SCTP_ASCONF:
+ if (sm->msg > SN_SCTP_ASCONF) {
+ if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv4addr_param))) /* malformed chunk*/
+ return(SN_PARSE_ERROR_CHHL);
+ //leave parameter searching to later, if required
+ param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr + sizeof(struct sctp_asconf_chunk)); /*compulsory IP parameter*/
+ if (ntohs(param_hdr->param_type) == SCTP_IPV4_ADDRESS) {
+ if ((*passoc == NULL) && (direction == SN_TO_LOCAL)) { /* AddIP with no association */
+ /* try look up with the ASCONF packet's alternative address */
+ ipv4addr.s_addr = ((struct sctp_ipv4addr_param *) param_hdr)->addr;
+ *passoc = FindSctpGlobal(la, ipv4addr, sctp_hdr->v_tag, sctp_hdr->src_port, sctp_hdr->dest_port, &partial_match);
+ }
+ param_hdr = (struct sctp_paramhdr *)
+ ((char *) param_hdr + sizeof(struct sctp_ipv4addr_param)); /*asconf's compulsory address parameter */
+ sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv4addr_param); /* rest of chunk */
+ } else {
+ if (chunk_length < (sizeof(struct sctp_asconf_chunk) + sizeof(struct sctp_ipv6addr_param))) /* malformed chunk*/
+ return(SN_PARSE_ERROR_CHHL);
+ param_hdr = (struct sctp_paramhdr *)
+ ((char *) param_hdr + sizeof(struct sctp_ipv6addr_param)); /*asconf's compulsory address parameter */
+ sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_chunk) - sizeof(struct sctp_ipv6addr_param); /* rest of chunk */
+ }
+ sm->msg = SN_SCTP_ASCONF;
+ sm->sctpchnk.Asconf = param_hdr;
- if (*passoc == NULL) { /* AddIP with no association */
- *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc));
- if (*passoc == NULL) {/* out of resources */
- return(SN_PARSE_ERROR_AS_MALLOC);
- }
- /* Initialise association - malloc initialises memory to zeros */
- (*passoc)->state = SN_ID;
- LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */
- (*passoc)->TableRegister = SN_NULL_TBL;
- return(SN_PARSE_OK);
+ if (*passoc == NULL) { /* AddIP with no association */
+ *passoc = (struct sctp_nat_assoc *) sn_malloc(sizeof(struct sctp_nat_assoc));
+ if (*passoc == NULL) {/* out of resources */
+ return(SN_PARSE_ERROR_AS_MALLOC);
+ }
+ /* Initialise association - malloc initialises memory to zeros */
+ (*passoc)->state = SN_ID;
+ LIST_INIT(&((*passoc)->Gaddr)); /* always initialise to avoid memory problems */
+ (*passoc)->TableRegister = SN_NULL_TBL;
+ return(SN_PARSE_OK);
+ }
+ }
+ break;
+ case SCTP_ASCONF_ACK:
+ if (sm->msg > SN_SCTP_ASCONFACK) {
+ if (chunk_length < sizeof(struct sctp_asconf_ack_chunk)) /* malformed chunk*/
+ return(SN_PARSE_ERROR_CHHL);
+ //leave parameter searching to later, if required
+ param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr
+ + sizeof(struct sctp_asconf_ack_chunk));
+ sm->msg = SN_SCTP_ASCONFACK;
+ sm->sctpchnk.Asconf = param_hdr;
+ sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_ack_chunk);
+ }
+ break;
+ default:
+ break; /* do nothing*/
+ }
+
+ /* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_chunk_proc_limit */
+ if ((*passoc == NULL) && (chunk_count >= sysctl_initialising_chunk_proc_limit))
+ return(SN_PARSE_ERROR_LOOKUP);
+
+ /* finished with this chunk, on to the next chunk*/
+ bytes_left-= chunk_length;
+
+ /* Is this the end of the packet ? */
+ if (bytes_left == 0)
+ return (*passoc == NULL)?(SN_PARSE_ERROR_LOOKUP):(SN_PARSE_OK);
+
+ /* Are there enough bytes in packet to at least retrieve length of next chunk ? */
+ if (bytes_left < SN_MIN_CHUNK_SIZE)
+ return(SN_PARSE_ERROR_CHHL);
+
+ chunk_hdr = SN_SCTP_NEXTCHUNK(chunk_hdr);
+
+ /* Is the chunk long enough to not cause endless look and are there enough bytes in packet to read the chunk ? */
+ chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length));
+ if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left))
+ return(SN_PARSE_ERROR_CHHL);
+ if(++chunk_count > sysctl_chunk_proc_limit)
+ return(SN_PARSE_OK); /* limit for processing chunks, take what we get */
}
- }
- break;
- case SCTP_ASCONF_ACK:
- if (sm->msg > SN_SCTP_ASCONFACK) {
- if (chunk_length < sizeof(struct sctp_asconf_ack_chunk)) /* malformed chunk*/
- return(SN_PARSE_ERROR_CHHL);
- //leave parameter searching to later, if required
- param_hdr = (struct sctp_paramhdr *) ((char *) chunk_hdr
- + sizeof(struct sctp_asconf_ack_chunk));
- sm->msg = SN_SCTP_ASCONFACK;
- sm->sctpchnk.Asconf = param_hdr;
- sm->chunk_length = chunk_length - sizeof(struct sctp_asconf_ack_chunk);
- }
- break;
- default:
- break; /* do nothing*/
- }
-
- /* if no association is found exit - we need to find an Init or AddIP within sysctl_initialising_chunk_proc_limit */
- if ((*passoc == NULL) && (chunk_count >= sysctl_initialising_chunk_proc_limit))
- return(SN_PARSE_ERROR_LOOKUP);
-
- /* finished with this chunk, on to the next chunk*/
- bytes_left-= chunk_length;
-
- /* Is this the end of the packet ? */
- if (bytes_left == 0)
- return(SN_PARSE_OK);
-
- /* Are there enough bytes in packet to at least retrieve length of next chunk ? */
- if (bytes_left < SN_MIN_CHUNK_SIZE)
- return(SN_PARSE_ERROR_CHHL);
-
- chunk_hdr = SN_SCTP_NEXTCHUNK(chunk_hdr);
-
- /* Is the chunk long enough to not cause endless look and are there enough bytes in packet to read the chunk ? */
- chunk_length = SCTP_SIZE32(ntohs(chunk_hdr->chunk_length));
- if ((chunk_length < SN_MIN_CHUNK_SIZE) || (chunk_length > bytes_left))
- return(SN_PARSE_ERROR_CHHL);
- if(++chunk_count > sysctl_chunk_proc_limit)
- return(SN_PARSE_OK); /* limit for processing chunks, take what we get */
- }
-
- if (*passoc == NULL)
- return (partial_match)?(SN_PARSE_ERROR_PARTIALLOOKUP):(SN_PARSE_ERROR_LOOKUP);
- else
- return(SN_PARSE_OK);
+
+ if (*passoc == NULL)
+ return (partial_match)?(SN_PARSE_ERROR_PARTIALLOOKUP):(SN_PARSE_ERROR_LOOKUP);
+ else
+ return(SN_PARSE_OK);
}
/** @ingroup packet_parser
@@ -1229,57 +1207,57 @@ sctp_PktParser(struct libalias *la, int direction, struct ip *pip,
static int
GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, uint32_t *g_vtag, int direction)
{
- /* To be removed when information is in the sctp headers */
+ /* To be removed when information is in the sctp headers */
#define SCTP_VTAG_PARAM 0xC007
- struct sctp_vtag_param {
- struct sctp_paramhdr ph;/* type=SCTP_VTAG_PARAM */
- uint32_t local_vtag;
- uint32_t remote_vtag;
- } __attribute__((packed));
+ struct sctp_vtag_param {
+ struct sctp_paramhdr ph;/* type=SCTP_VTAG_PARAM */
+ uint32_t local_vtag;
+ uint32_t remote_vtag;
+ } __attribute__((packed));
- struct sctp_vtag_param *vtag_param;
- struct sctp_paramhdr *param;
- int bytes_left;
- int param_size;
- int param_count;
-
- param_count = 1;
- param = sm->sctpchnk.Asconf;
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- bytes_left = sm->chunk_length;
- /* step through Asconf parameters */
- while((bytes_left >= param_size) && (bytes_left >= SN_VTAG_PARAM_SIZE)) {
- if (ntohs(param->param_type) == SCTP_VTAG_PARAM) {
- vtag_param = (struct sctp_vtag_param *) param;
- switch(direction) {
- /* The Internet draft is a little ambigious as to order of these vtags.
- We think it is this way around. If we are wrong, the order will need
- to be changed. */
- case SN_TO_GLOBAL:
- *g_vtag = vtag_param->local_vtag;
- *l_vtag = vtag_param->remote_vtag;
- break;
- case SN_TO_LOCAL:
- *g_vtag = vtag_param->remote_vtag;
- *l_vtag = vtag_param->local_vtag;
- break;
- }
- return(1); /* found */
- }
-
- bytes_left -= param_size;
- if (bytes_left < SN_MIN_PARAM_SIZE) return(0);
-
- param = SN_SCTP_NEXTPARAM(param);
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (++param_count > sysctl_param_proc_limit) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded (GetAsconfVtags)",
- sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return(0); /* not found limit exceeded*/
- }
- }
- return(0); /* not found */
+ struct sctp_vtag_param *vtag_param;
+ struct sctp_paramhdr *param;
+ int bytes_left;
+ int param_size;
+ int param_count;
+
+ param_count = 1;
+ param = sm->sctpchnk.Asconf;
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ bytes_left = sm->chunk_length;
+ /* step through Asconf parameters */
+ while((bytes_left >= param_size) && (bytes_left >= SN_VTAG_PARAM_SIZE)) {
+ if (ntohs(param->param_type) == SCTP_VTAG_PARAM) {
+ vtag_param = (struct sctp_vtag_param *) param;
+ switch(direction) {
+ /* The Internet draft is a little ambigious as to order of these vtags.
+ We think it is this way around. If we are wrong, the order will need
+ to be changed. */
+ case SN_TO_GLOBAL:
+ *g_vtag = vtag_param->local_vtag;
+ *l_vtag = vtag_param->remote_vtag;
+ break;
+ case SN_TO_LOCAL:
+ *g_vtag = vtag_param->remote_vtag;
+ *l_vtag = vtag_param->local_vtag;
+ break;
+ }
+ return(1); /* found */
+ }
+
+ bytes_left -= param_size;
+ if (bytes_left < SN_MIN_PARAM_SIZE) return(0);
+
+ param = SN_SCTP_NEXTPARAM(param);
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ if (++param_count > sysctl_param_proc_limit) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("Parameter parse limit exceeded (GetAsconfVtags)",
+ sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
+ return(0); /* not found limit exceeded*/
+ }
+ }
+ return(0); /* not found */
}
/** @ingroup packet_parser
@@ -1296,119 +1274,119 @@ GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, uint32_t *l_vtag, u
static void
AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction)
{
- struct sctp_ipv4addr_param *ipv4_param;
- struct sctp_paramhdr *param = NULL;
- struct sctp_GlobalAddress *G_Addr;
- struct in_addr g_addr = {0};
- int bytes_left = 0;
- int param_size;
- int param_count, addr_param_count = 0;
-
- switch(direction) {
- case SN_TO_GLOBAL: /* does not contain global addresses */
- g_addr = sm->ip_hdr->ip_dst;
- bytes_left = 0; /* force exit */
- break;
- case SN_TO_LOCAL:
- g_addr = sm->ip_hdr->ip_src;
- param_count = 1;
- switch(sm->msg) {
- case SN_SCTP_INIT:
- bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk);
- param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init));
- break;
- case SN_SCTP_INITACK:
- bytes_left = sm->chunk_length - sizeof(struct sctp_init_ack_chunk);
- param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.InitAck + sizeof(struct sctp_init_ack));
- break;
- case SN_SCTP_ASCONF:
- bytes_left = sm->chunk_length;
- param = sm->sctpchnk.Asconf;
- break;
- }
- }
- if (bytes_left >= SN_MIN_PARAM_SIZE)
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- else
- param_size = bytes_left+1; /* force skip loop */
+ struct sctp_ipv4addr_param *ipv4_param;
+ struct sctp_paramhdr *param = NULL;
+ struct sctp_GlobalAddress *G_Addr;
+ struct in_addr g_addr = {0};
+ int bytes_left = 0;
+ int param_size;
+ int param_count, addr_param_count = 0;
+
+ switch(direction) {
+ case SN_TO_GLOBAL: /* does not contain global addresses */
+ g_addr = sm->ip_hdr->ip_dst;
+ bytes_left = 0; /* force exit */
+ break;
+ case SN_TO_LOCAL:
+ g_addr = sm->ip_hdr->ip_src;
+ param_count = 1;
+ switch(sm->msg) {
+ case SN_SCTP_INIT:
+ bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk);
+ param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init));
+ break;
+ case SN_SCTP_INITACK:
+ bytes_left = sm->chunk_length - sizeof(struct sctp_init_ack_chunk);
+ param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.InitAck + sizeof(struct sctp_init_ack));
+ break;
+ case SN_SCTP_ASCONF:
+ bytes_left = sm->chunk_length;
+ param = sm->sctpchnk.Asconf;
+ break;
+ }
+ }
+ if (bytes_left >= SN_MIN_PARAM_SIZE)
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ else
+ param_size = bytes_left+1; /* force skip loop */
- if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */
- G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress));
- if (G_Addr == NULL) {/* out of resources */
- SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
- sm->sctp_hdr->v_tag, 0, direction));
- assoc->num_Gaddr = 0; /* don't track any more for this assoc*/
- sysctl_track_global_addresses=0;
- return;
- }
- G_Addr->g_addr = g_addr;
- if (!Add_Global_Address_to_List(assoc, G_Addr))
- SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Address already in list",
- sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
- }
-
- /* step through parameters */
- while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) {
- if (assoc->num_Gaddr >= sysctl_track_global_addresses) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached",
- sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
- return;
- }
- switch(ntohs(param->param_type)) {
- case SCTP_ADD_IP_ADDRESS:
- /* skip to address parameter - leave param_size so bytes left will be calculated properly*/
- param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp;
- case SCTP_IPV4_ADDRESS:
- ipv4_param = (struct sctp_ipv4addr_param *) param;
- /* add addresses to association */
- G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress));
- if (G_Addr == NULL) {/* out of resources */
- SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
- sm->sctp_hdr->v_tag, 0, direction));
- assoc->num_Gaddr = 0; /* don't track any more for this assoc*/
- sysctl_track_global_addresses=0;
- return;
- }
- /* add address */
- addr_param_count++;
- if ((sm->msg == SN_SCTP_ASCONF) && (ipv4_param->addr == INADDR_ANY)) { /* use packet address */
- G_Addr->g_addr = g_addr;
- if (!Add_Global_Address_to_List(assoc, G_Addr))
- SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Address already in list",
- sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
- return; /*shouldn't be any other addresses if the zero address is given*/
- } else {
- G_Addr->g_addr.s_addr = ipv4_param->addr;
- if (!Add_Global_Address_to_List(assoc, G_Addr))
- SN_LOG(SN_LOG_EVENT,
- logsctperror("AddGlobalIPAddress: Address already in list",
- sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
- }
- }
+ if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */
+ G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress));
+ if (G_Addr == NULL) {/* out of resources */
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
+ sm->sctp_hdr->v_tag, 0, direction));
+ assoc->num_Gaddr = 0; /* don't track any more for this assoc*/
+ sysctl_track_global_addresses=0;
+ return;
+ }
+ G_Addr->g_addr = g_addr;
+ if (!Add_Global_Address_to_List(assoc, G_Addr))
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("AddGlobalIPAddress: Address already in list",
+ sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
+ }
+
+ /* step through parameters */
+ while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) {
+ if (assoc->num_Gaddr >= sysctl_track_global_addresses) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("AddGlobalIPAddress: Maximum Number of addresses reached",
+ sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
+ return;
+ }
+ switch(ntohs(param->param_type)) {
+ case SCTP_ADD_IP_ADDRESS:
+ /* skip to address parameter - leave param_size so bytes left will be calculated properly*/
+ param = (struct sctp_paramhdr *) &((struct sctp_asconf_addrv4_param *) param)->addrp;
+ case SCTP_IPV4_ADDRESS:
+ ipv4_param = (struct sctp_ipv4addr_param *) param;
+ /* add addresses to association */
+ G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress));
+ if (G_Addr == NULL) {/* out of resources */
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking",
+ sm->sctp_hdr->v_tag, 0, direction));
+ assoc->num_Gaddr = 0; /* don't track any more for this assoc*/
+ sysctl_track_global_addresses=0;
+ return;
+ }
+ /* add address */
+ addr_param_count++;
+ if ((sm->msg == SN_SCTP_ASCONF) && (ipv4_param->addr == INADDR_ANY)) { /* use packet address */
+ G_Addr->g_addr = g_addr;
+ if (!Add_Global_Address_to_List(assoc, G_Addr))
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("AddGlobalIPAddress: Address already in list",
+ sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
+ return; /*shouldn't be any other addresses if the zero address is given*/
+ } else {
+ G_Addr->g_addr.s_addr = ipv4_param->addr;
+ if (!Add_Global_Address_to_List(assoc, G_Addr))
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("AddGlobalIPAddress: Address already in list",
+ sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
+ }
+ }
- bytes_left -= param_size;
- if (bytes_left < SN_MIN_PARAM_SIZE)
- break;
+ bytes_left -= param_size;
+ if (bytes_left < SN_MIN_PARAM_SIZE)
+ break;
- param = SN_SCTP_NEXTPARAM(param);
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (++param_count > sysctl_param_proc_limit) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded (AddGlobalIPAddress)",
- sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- break; /* limit exceeded*/
- }
- }
- if (addr_param_count == 0) {
- SN_LOG(SN_LOG_DETAIL,
- logsctperror("AddGlobalIPAddress: no address parameters to add",
+ param = SN_SCTP_NEXTPARAM(param);
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ if (++param_count > sysctl_param_proc_limit) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("Parameter parse limit exceeded (AddGlobalIPAddress)",
+ sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
+ break; /* limit exceeded*/
+ }
+ }
+ if (addr_param_count == 0) {
+ SN_LOG(SN_LOG_DETAIL,
+ logsctperror("AddGlobalIPAddress: no address parameters to add",
sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
- }
+ }
}
/**
@@ -1426,19 +1404,19 @@ AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int
*/
static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr)
{
- struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL;
- first_G_Addr = LIST_FIRST(&(assoc->Gaddr));
- if (first_G_Addr == NULL) {
- LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/
- } else {
- LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr)
- return(0); /* already exists, so don't add */
- }
- LIST_INSERT_AFTER(first_G_Addr, G_addr, list_Gaddr); /* add address to end of list*/
- }
- assoc->num_Gaddr++;
- return(1); /* success */
+ struct sctp_GlobalAddress *iter_G_Addr = NULL, *first_G_Addr = NULL;
+ first_G_Addr = LIST_FIRST(&(assoc->Gaddr));
+ if (first_G_Addr == NULL) {
+ LIST_INSERT_HEAD(&(assoc->Gaddr), G_addr, list_Gaddr); /* add new address to beginning of list*/
+ } else {
+ LIST_FOREACH(iter_G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ if (G_addr->g_addr.s_addr == iter_G_Addr->g_addr.s_addr)
+ return(0); /* already exists, so don't add */
+ }
+ LIST_INSERT_AFTER(first_G_Addr, G_addr, list_Gaddr); /* add address to end of list*/
+ }
+ assoc->num_Gaddr++;
+ return(1); /* success */
}
/** @ingroup packet_parser
@@ -1457,85 +1435,85 @@ static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sct
static void
RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction)
{
- struct sctp_asconf_addrv4_param *asconf_ipv4_param;
- struct sctp_paramhdr *param;
- struct sctp_GlobalAddress *G_Addr, *G_Addr_tmp;
- struct in_addr g_addr;
- int bytes_left;
- int param_size;
- int param_count;
-
- if(direction == SN_TO_GLOBAL)
- g_addr = sm->ip_hdr->ip_dst;
- else
- g_addr = sm->ip_hdr->ip_src;
-
- bytes_left = sm->chunk_length;
- param_count = 1;
- param = sm->sctpchnk.Asconf;
- if (bytes_left >= SN_MIN_PARAM_SIZE) {
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- } else {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses",
+ struct sctp_asconf_addrv4_param *asconf_ipv4_param;
+ struct sctp_paramhdr *param;
+ struct sctp_GlobalAddress *G_Addr, *G_Addr_tmp;
+ struct in_addr g_addr;
+ int bytes_left;
+ int param_size;
+ int param_count;
+
+ if(direction == SN_TO_GLOBAL)
+ g_addr = sm->ip_hdr->ip_dst;
+ else
+ g_addr = sm->ip_hdr->ip_src;
+
+ bytes_left = sm->chunk_length;
+ param_count = 1;
+ param = sm->sctpchnk.Asconf;
+ if (bytes_left >= SN_MIN_PARAM_SIZE) {
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ } else {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses",
sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
- return;
- }
-
- /* step through Asconf parameters */
- while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) {
- if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) {
- asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param;
- if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */
- LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) {
- if(G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) {
- if (assoc->num_Gaddr > 1) { /* only delete if more than one */
- LIST_REMOVE(G_Addr, list_Gaddr);
- sn_free(G_Addr);
- assoc->num_Gaddr--;
- } else {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
- sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
- }
- }
- }
- return; /*shouldn't be any other addresses if the zero address is given*/
- } else {
- LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) {
- if(G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) {
- if (assoc->num_Gaddr > 1) { /* only delete if more than one */
- LIST_REMOVE(G_Addr, list_Gaddr);
- sn_free(G_Addr);
- assoc->num_Gaddr--;
- break; /* Since add only adds new addresses, there should be no double entries */
- } else {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
- sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
- }
- }
+ return;
}
- }
- }
- bytes_left -= param_size;
- if (bytes_left == 0) return;
- else if (bytes_left < SN_MIN_PARAM_SIZE) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses",
- sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
- return;
- }
+
+ /* step through Asconf parameters */
+ while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) {
+ if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) {
+ asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param;
+ if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */
+ LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) {
+ if(G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) {
+ if (assoc->num_Gaddr > 1) { /* only delete if more than one */
+ LIST_REMOVE(G_Addr, list_Gaddr);
+ sn_free(G_Addr);
+ assoc->num_Gaddr--;
+ } else {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
+ sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
+ }
+ }
+ }
+ return; /*shouldn't be any other addresses if the zero address is given*/
+ } else {
+ LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) {
+ if(G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) {
+ if (assoc->num_Gaddr > 1) { /* only delete if more than one */
+ LIST_REMOVE(G_Addr, list_Gaddr);
+ sn_free(G_Addr);
+ assoc->num_Gaddr--;
+ break; /* Since add only adds new addresses, there should be no double entries */
+ } else {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)",
+ sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction));
+ }
+ }
+ }
+ }
+ }
+ bytes_left -= param_size;
+ if (bytes_left == 0) return;
+ else if (bytes_left < SN_MIN_PARAM_SIZE) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("RmGlobalIPAddress: truncated packet - may not have removed all IP addresses",
+ sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction));
+ return;
+ }
- param = SN_SCTP_NEXTPARAM(param);
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (++param_count > sysctl_param_proc_limit) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded (RmGlobalIPAddress)",
- sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return; /* limit exceeded*/
- }
- }
+ param = SN_SCTP_NEXTPARAM(param);
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ if (++param_count > sysctl_param_proc_limit) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("Parameter parse limit exceeded (RmGlobalIPAddress)",
+ sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
+ return; /* limit exceeded*/
+ }
+ }
}
/** @ingroup packet_parser
@@ -1563,42 +1541,42 @@ RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int d
static int
IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction)
{
- struct sctp_paramhdr *param;
- int bytes_left;
- int param_size;
- int param_count;
-
- param_count = 1;
- param = sm->sctpchnk.Asconf;
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (param_size == 8)
- return(1); /*success - default acknowledgement of everything */
-
- bytes_left = sm->chunk_length;
- if (bytes_left < param_size)
- return(0); /* not found */
- /* step through Asconf parameters */
- while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) {
- if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT)
- return(1); /* success - but can't match correlation IDs - should only be one */
- /* check others just in case */
- bytes_left -= param_size;
- if (bytes_left >= SN_MIN_PARAM_SIZE) {
- param = SN_SCTP_NEXTPARAM(param);
- } else {
- return(0);
- }
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (bytes_left < param_size) return(0);
-
- if (++param_count > sysctl_param_proc_limit) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded (IsASCONFack)",
- sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return(0); /* not found limit exceeded*/
- }
- }
- return(0); /* not success */
+ struct sctp_paramhdr *param;
+ int bytes_left;
+ int param_size;
+ int param_count;
+
+ param_count = 1;
+ param = sm->sctpchnk.Asconf;
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ if (param_size == 8)
+ return(1); /*success - default acknowledgement of everything */
+
+ bytes_left = sm->chunk_length;
+ if (bytes_left < param_size)
+ return(0); /* not found */
+ /* step through Asconf parameters */
+ while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) {
+ if (ntohs(param->param_type) == SCTP_SUCCESS_REPORT)
+ return(1); /* success - but can't match correlation IDs - should only be one */
+ /* check others just in case */
+ bytes_left -= param_size;
+ if (bytes_left >= SN_MIN_PARAM_SIZE) {
+ param = SN_SCTP_NEXTPARAM(param);
+ } else {
+ return(0);
+ }
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ if (bytes_left < param_size) return(0);
+
+ if (++param_count > sysctl_param_proc_limit) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("Parameter parse limit exceeded (IsASCONFack)",
+ sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
+ return(0); /* not found limit exceeded*/
+ }
+ }
+ return(0); /* not success */
}
/** @ingroup packet_parser
@@ -1616,42 +1594,42 @@ IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction)
static int
IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction)
{
- struct sctp_paramhdr *param;
- int bytes_left;
- int param_size;
- int param_count;
-
- param_count = 1;
- param = sm->sctpchnk.Asconf;
- param_size = SCTP_SIZE32(ntohs(param->param_length));
-
- bytes_left = sm->chunk_length;
- if (bytes_left < param_size)
- return(0); /* not found */
- /* step through Asconf parameters */
- while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) {
- if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS)
- return(SCTP_ADD_IP_ADDRESS);
- else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS)
- return(SCTP_DEL_IP_ADDRESS);
- /* check others just in case */
- bytes_left -= param_size;
- if (bytes_left >= SN_MIN_PARAM_SIZE) {
- param = SN_SCTP_NEXTPARAM(param);
- } else {
- return(0); /*Neither found */
- }
- param_size = SCTP_SIZE32(ntohs(param->param_length));
- if (bytes_left < param_size) return(0);
-
- if (++param_count > sysctl_param_proc_limit) {
- SN_LOG(SN_LOG_EVENT,
- logsctperror("Parameter parse limit exceeded IsADDorDEL)",
- sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
- return(0); /* not found limit exceeded*/
- }
- }
- return(0); /*Neither found */
+ struct sctp_paramhdr *param;
+ int bytes_left;
+ int param_size;
+ int param_count;
+
+ param_count = 1;
+ param = sm->sctpchnk.Asconf;
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+
+ bytes_left = sm->chunk_length;
+ if (bytes_left < param_size)
+ return(0); /* not found */
+ /* step through Asconf parameters */
+ while(bytes_left >= SN_ASCONFACK_PARAM_SIZE) {
+ if (ntohs(param->param_type) == SCTP_ADD_IP_ADDRESS)
+ return(SCTP_ADD_IP_ADDRESS);
+ else if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS)
+ return(SCTP_DEL_IP_ADDRESS);
+ /* check others just in case */
+ bytes_left -= param_size;
+ if (bytes_left >= SN_MIN_PARAM_SIZE) {
+ param = SN_SCTP_NEXTPARAM(param);
+ } else {
+ return(0); /*Neither found */
+ }
+ param_size = SCTP_SIZE32(ntohs(param->param_length));
+ if (bytes_left < param_size) return(0);
+
+ if (++param_count > sysctl_param_proc_limit) {
+ SN_LOG(SN_LOG_EVENT,
+ logsctperror("Parameter parse limit exceeded IsADDorDEL)",
+ sm->sctp_hdr->v_tag, sysctl_param_proc_limit, direction));
+ return(0); /* not found limit exceeded*/
+ }
+ }
+ return(0); /*Neither found */
}
/* ----------------------------------------------------------------------
@@ -1683,25 +1661,25 @@ IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction)
static int
ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc)
{
- int rtnval;
-
- switch (assoc->state) {
- case SN_ID: /* Idle */
- rtnval = ID_process(la, direction, assoc, sm);
- if (rtnval != SN_NAT_PKT) {
- assoc->state = SN_RM;/* Mark for removal*/
- }
- return(rtnval);
- case SN_INi: /* Initialising - Init */
- return(INi_process(la, direction, assoc, sm));
- case SN_INa: /* Initialising - AddIP */
- return(INa_process(la, direction, assoc, sm));
- case SN_UP: /* Association UP */
- return(UP_process(la, direction, assoc, sm));
- case SN_CL: /* Association Closing */
- return(CL_process(la, direction, assoc, sm));
- }
- return(SN_PROCESSING_ERROR);
+ int rtnval;
+
+ switch (assoc->state) {
+ case SN_ID: /* Idle */
+ rtnval = ID_process(la, direction, assoc, sm);
+ if (rtnval != SN_NAT_PKT) {
+ assoc->state = SN_RM;/* Mark for removal*/
+ }
+ return(rtnval);
+ case SN_INi: /* Initialising - Init */
+ return(INi_process(la, direction, assoc, sm));
+ case SN_INa: /* Initialising - AddIP */
+ return(INa_process(la, direction, assoc, sm));
+ case SN_UP: /* Association UP */
+ return(UP_process(la, direction, assoc, sm));
+ case SN_CL: /* Association Closing */
+ return(CL_process(la, direction, assoc, sm));
+ }
+ return(SN_PROCESSING_ERROR);
}
/** @ingroup state_machine
@@ -1721,56 +1699,56 @@ ProcessSctpMsg(struct libalias *la, int direction, struct sctp_nat_msg *sm, stru
static int
ID_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
- case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk with ADDIP */
- if (!sysctl_accept_global_ootb_addip && (direction == SN_TO_LOCAL))
- return(SN_DROP_PKT);
- /* if this Asconf packet does not contain the Vtag parameters it is of no use in Idle state */
- if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction))
- return(SN_DROP_PKT);
- case SN_SCTP_INIT: /* a packet containing an INIT chunk or an ASCONF AddIP */
- if (sysctl_track_global_addresses)
- AddGlobalIPAddresses(sm, assoc, direction);
- switch(direction){
- case SN_TO_GLOBAL:
- assoc->l_addr = sm->ip_hdr->ip_src;
- assoc->a_addr = FindAliasAddress(la, assoc->l_addr);
- assoc->l_port = sm->sctp_hdr->src_port;
- assoc->g_port = sm->sctp_hdr->dest_port;
- if(sm->msg == SN_SCTP_INIT)
- assoc->g_vtag = sm->sctpchnk.Init->initiate_tag;
- if (AddSctpAssocGlobal(la, assoc)) /* DB clash *///**** need to add dst address
- return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
- if(sm->msg == SN_SCTP_ASCONF) {
- if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */
- return(SN_REPLY_ERROR);
- assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */
- }
- break;
- case SN_TO_LOCAL:
- assoc->l_addr = FindSctpRedirectAddress(la, sm);
- assoc->a_addr = sm->ip_hdr->ip_dst;
- assoc->l_port = sm->sctp_hdr->dest_port;
- assoc->g_port = sm->sctp_hdr->src_port;
- if(sm->msg == SN_SCTP_INIT)
- assoc->l_vtag = sm->sctpchnk.Init->initiate_tag;
- if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */
- return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
- if(sm->msg == SN_SCTP_ASCONF) {
- if (AddSctpAssocGlobal(la, assoc)) /* DB clash */ //**** need to add src address
- return(SN_REPLY_ERROR);
- assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */
- }
- break;
- }
- assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa;
- assoc->exp = SN_I_T(la);
- sctp_AddTimeOut(la,assoc);
- return(SN_NAT_PKT);
- default: /* Any other type of SCTP message is not valid in Idle */
- return(SN_DROP_PKT);
- }
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ switch(sm->msg) {
+ case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk with ADDIP */
+ if (!sysctl_accept_global_ootb_addip && (direction == SN_TO_LOCAL))
+ return(SN_DROP_PKT);
+ /* if this Asconf packet does not contain the Vtag parameters it is of no use in Idle state */
+ if (!GetAsconfVtags(la, sm, &(assoc->l_vtag), &(assoc->g_vtag), direction))
+ return(SN_DROP_PKT);
+ case SN_SCTP_INIT: /* a packet containing an INIT chunk or an ASCONF AddIP */
+ if (sysctl_track_global_addresses)
+ AddGlobalIPAddresses(sm, assoc, direction);
+ switch(direction){
+ case SN_TO_GLOBAL:
+ assoc->l_addr = sm->ip_hdr->ip_src;
+ assoc->a_addr = FindAliasAddress(la, assoc->l_addr);
+ assoc->l_port = sm->sctp_hdr->src_port;
+ assoc->g_port = sm->sctp_hdr->dest_port;
+ if(sm->msg == SN_SCTP_INIT)
+ assoc->g_vtag = sm->sctpchnk.Init->initiate_tag;
+ if (AddSctpAssocGlobal(la, assoc)) /* DB clash *///**** need to add dst address
+ return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
+ if(sm->msg == SN_SCTP_ASCONF) {
+ if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_dst)) /* DB clash */
+ return(SN_REPLY_ERROR);
+ assoc->TableRegister |= SN_WAIT_TOLOCAL; /* wait for tolocal ack */
+ }
+ break;
+ case SN_TO_LOCAL:
+ assoc->l_addr = FindSctpRedirectAddress(la, sm);
+ assoc->a_addr = sm->ip_hdr->ip_dst;
+ assoc->l_port = sm->sctp_hdr->dest_port;
+ assoc->g_port = sm->sctp_hdr->src_port;
+ if(sm->msg == SN_SCTP_INIT)
+ assoc->l_vtag = sm->sctpchnk.Init->initiate_tag;
+ if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) /* DB clash */
+ return((sm->msg == SN_SCTP_INIT) ? SN_REPLY_ABORT : SN_REPLY_ERROR);
+ if(sm->msg == SN_SCTP_ASCONF) {
+ if (AddSctpAssocGlobal(la, assoc)) /* DB clash */ //**** need to add src address
+ return(SN_REPLY_ERROR);
+ assoc->TableRegister |= SN_WAIT_TOGLOBAL; /* wait for toglobal ack */
+ }
+ break;
+ }
+ assoc->state = (sm->msg == SN_SCTP_INIT) ? SN_INi : SN_INa;
+ assoc->exp = SN_I_T(la);
+ sctp_AddTimeOut(la,assoc);
+ return(SN_NAT_PKT);
+ default: /* Any other type of SCTP message is not valid in Idle */
+ return(SN_DROP_PKT);
+ }
+return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
@@ -1789,40 +1767,40 @@ ID_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, str
static int
INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
- case SN_SCTP_INIT: /* a packet containing a retransmitted INIT chunk */
- sctp_ResetTimeOut(la, assoc, SN_I_T(la));
- return(SN_NAT_PKT);
- case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */
- switch(direction){
- case SN_TO_LOCAL:
- if (assoc->num_Gaddr) /*If tracking global addresses for this association */
- AddGlobalIPAddresses(sm, assoc, direction);
- assoc->l_vtag = sm->sctpchnk.Init->initiate_tag;
- if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_SEND_ABORT);
- }
- break;
- case SN_TO_GLOBAL:
- assoc->l_addr = sm->ip_hdr->ip_src; // Only if not set in Init! *
- assoc->g_vtag = sm->sctpchnk.Init->initiate_tag;
- if (AddSctpAssocGlobal(la, assoc)) { /* DB clash */
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_SEND_ABORT);
- }
- break;
- }
- assoc->state = SN_UP;/* association established for NAT */
- sctp_ResetTimeOut(la,assoc, SN_U_T(la));
- return(SN_NAT_PKT);
- case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
- default:
- return(SN_DROP_PKT);
- }
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ switch(sm->msg) {
+ case SN_SCTP_INIT: /* a packet containing a retransmitted INIT chunk */
+ sctp_ResetTimeOut(la, assoc, SN_I_T(la));
+ return(SN_NAT_PKT);
+ case SN_SCTP_INITACK: /* a packet containing an INIT-ACK chunk */
+ switch(direction){
+ case SN_TO_LOCAL:
+ if (assoc->num_Gaddr) /*If tracking global addresses for this association */
+ AddGlobalIPAddresses(sm, assoc, direction);
+ assoc->l_vtag = sm->sctpchnk.Init->initiate_tag;
+ if (AddSctpAssocLocal(la, assoc, sm->ip_hdr->ip_src)) { /* DB clash */
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_SEND_ABORT);
+ }
+ break;
+ case SN_TO_GLOBAL:
+ assoc->l_addr = sm->ip_hdr->ip_src; // Only if not set in Init! *
+ assoc->g_vtag = sm->sctpchnk.Init->initiate_tag;
+ if (AddSctpAssocGlobal(la, assoc)) { /* DB clash */
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_SEND_ABORT);
+ }
+ break;
+ }
+ assoc->state = SN_UP;/* association established for NAT */
+ sctp_ResetTimeOut(la,assoc, SN_U_T(la));
+ return(SN_NAT_PKT);
+ case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_NAT_PKT);
+ default:
+ return(SN_DROP_PKT);
+ }
+ return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
@@ -1841,36 +1819,36 @@ INi_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, st
static int
INa_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
- case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/
- sctp_ResetTimeOut(la,assoc, SN_I_T(la));
- return(SN_NAT_PKT);
- case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */
- switch(direction){
- case SN_TO_LOCAL:
- if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */
- return(SN_DROP_PKT);
- break;
- case SN_TO_GLOBAL:
- if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */
- return(SN_DROP_PKT);
- }
- if (IsASCONFack(la,sm,direction)) {
- assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */
- assoc->state = SN_UP; /* association established for NAT */
- sctp_ResetTimeOut(la,assoc, SN_U_T(la));
- return(SN_NAT_PKT);
- } else {
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
- }
- case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
- default:
- return(SN_DROP_PKT);
- }
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ switch(sm->msg) {
+ case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/
+ sctp_ResetTimeOut(la,assoc, SN_I_T(la));
+ return(SN_NAT_PKT);
+ case SN_SCTP_ASCONFACK: /* a packet containing an ASCONF chunk with a ADDIP-ACK */
+ switch(direction){
+ case SN_TO_LOCAL:
+ if (!(assoc->TableRegister & SN_WAIT_TOLOCAL)) /* wrong direction */
+ return(SN_DROP_PKT);
+ break;
+ case SN_TO_GLOBAL:
+ if (!(assoc->TableRegister & SN_WAIT_TOGLOBAL)) /* wrong direction */
+ return(SN_DROP_PKT);
+ }
+ if (IsASCONFack(la,sm,direction)) {
+ assoc->TableRegister &= SN_BOTH_TBL; /* remove wait flags */
+ assoc->state = SN_UP; /* association established for NAT */
+ sctp_ResetTimeOut(la,assoc, SN_U_T(la));
+ return(SN_NAT_PKT);
+ } else {
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_NAT_PKT);
+ }
+ case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_NAT_PKT);
+ default:
+ return(SN_DROP_PKT);
+ }
+ return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
@@ -1889,29 +1867,29 @@ INa_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, str
static int
UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
- case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */
- assoc->state = SN_CL;
- sctp_ResetTimeOut(la,assoc, SN_C_T(la));
- return(SN_NAT_PKT);
- case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
- case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/
- if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this association & from global side */
- switch(IsADDorDEL(la,sm,direction)) {
- case SCTP_ADD_IP_ADDRESS:
- AddGlobalIPAddresses(sm, assoc, direction);
- break;
- case SCTP_DEL_IP_ADDRESS:
- RmGlobalIPAddresses(sm, assoc, direction);
- break;
- } /* fall through to default */
- default:
- sctp_ResetTimeOut(la,assoc, SN_U_T(la));
- return(SN_NAT_PKT); /* forward packet */
- }
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ switch(sm->msg) {
+ case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */
+ assoc->state = SN_CL;
+ sctp_ResetTimeOut(la,assoc, SN_C_T(la));
+ return(SN_NAT_PKT);
+ case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_NAT_PKT);
+ case SN_SCTP_ASCONF: /* a packet containing an ASCONF chunk*/
+ if ((direction == SN_TO_LOCAL) && assoc->num_Gaddr) /*If tracking global addresses for this association & from global side */
+ switch(IsADDorDEL(la,sm,direction)) {
+ case SCTP_ADD_IP_ADDRESS:
+ AddGlobalIPAddresses(sm, assoc, direction);
+ break;
+ case SCTP_DEL_IP_ADDRESS:
+ RmGlobalIPAddresses(sm, assoc, direction);
+ break;
+ } /* fall through to default */
+ default:
+ sctp_ResetTimeOut(la,assoc, SN_U_T(la));
+ return(SN_NAT_PKT); /* forward packet */
+ }
+ return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/** @ingroup state_machine
@@ -1932,25 +1910,25 @@ UP_process(struct libalias *la, int direction, struct sctp_nat_assoc *assoc, str
static int
CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm)
{
- switch(sm->msg) {
- case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */
- assoc->state = SN_CL; /* Stay in Close state until timeout */
- if (sysctl_holddown_timer > 0)
- sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/
- else
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
- case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */
- assoc->state = SN_CL; /* Stay in Close state until timeout */
- sctp_ResetTimeOut(la, assoc, SN_C_T(la));
- return(SN_NAT_PKT);
- case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
- assoc->state = SN_RM;/* Mark for removal*/
- return(SN_NAT_PKT);
- default:
- return(SN_DROP_PKT);
- }
- return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
+ switch(sm->msg) {
+ case SN_SCTP_SHUTCOMP: /* a packet containing a SHUTDOWN-COMPLETE chunk */
+ assoc->state = SN_CL; /* Stay in Close state until timeout */
+ if (sysctl_holddown_timer > 0)
+ sctp_ResetTimeOut(la, assoc, SN_X_T(la));/* allow to stay open for Tbit packets*/
+ else
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_NAT_PKT);
+ case SN_SCTP_SHUTACK: /* a packet containing a SHUTDOWN-ACK chunk */
+ assoc->state = SN_CL; /* Stay in Close state until timeout */
+ sctp_ResetTimeOut(la, assoc, SN_C_T(la));
+ return(SN_NAT_PKT);
+ case SN_SCTP_ABORT: /* a packet containing an ABORT chunk */
+ assoc->state = SN_RM;/* Mark for removal*/
+ return(SN_NAT_PKT);
+ default:
+ return(SN_DROP_PKT);
+ }
+ return(SN_DROP_PKT);/* shouldn't get here very bad: log, drop and hope for the best */
}
/* ----------------------------------------------------------------------
@@ -1980,27 +1958,27 @@ CL_process(struct libalias *la, int direction,struct sctp_nat_assoc *assoc, stru
static struct sctp_nat_assoc*
FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, uint32_t l_vtag, uint16_t l_port, uint16_t g_port)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
- struct sctp_GlobalAddress *G_Addr = NULL;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
+ struct sctp_GlobalAddress *G_Addr = NULL;
- if (l_vtag != 0) { /* an init packet, vtag==0 */
- i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize);
- LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
- if ((assoc->l_vtag == l_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)\
- && (assoc->l_addr.s_addr == l_addr.s_addr)) {
- if (assoc->num_Gaddr) {
- LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == g_addr.s_addr)
- return(assoc);
- }
- } else {
- return(assoc);
+ if (l_vtag != 0) { /* an init packet, vtag==0 */
+ i = SN_TABLE_HASH(l_vtag, l_port, la->sctpNatTableSize);
+ LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
+ if ((assoc->l_vtag == l_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)\
+ && (assoc->l_addr.s_addr == l_addr.s_addr)) {
+ if (assoc->num_Gaddr) {
+ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ if(G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return(assoc);
+ }
+ } else {
+ return(assoc);
+ }
+ }
+ }
}
- }
- }
- }
- return(NULL);
+ return(NULL);
}
/** @ingroup Hash
@@ -2017,29 +1995,29 @@ FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr,
static struct sctp_nat_assoc*
FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
- struct sctp_GlobalAddress *G_Addr = NULL;
- struct sctp_GlobalAddress *G_AddrC = NULL;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
+ struct sctp_GlobalAddress *G_Addr = NULL;
+ struct sctp_GlobalAddress *G_AddrC = NULL;
- if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */
- i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize);
- LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
- if ((assoc->g_vtag == Cassoc->g_vtag) && (assoc->g_port == Cassoc->g_port) && (assoc->l_port == Cassoc->l_port)) {
- if (assoc->num_Gaddr) {
- LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) {
- LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr)
- return(assoc);
- }
- }
- } else {
- return(assoc);
+ if (Cassoc->g_vtag != 0) { /* an init packet, vtag==0 */
+ i = SN_TABLE_HASH(Cassoc->g_vtag, Cassoc->g_port, la->sctpNatTableSize);
+ LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
+ if ((assoc->g_vtag == Cassoc->g_vtag) && (assoc->g_port == Cassoc->g_port) && (assoc->l_port == Cassoc->l_port)) {
+ if (assoc->num_Gaddr) {
+ LIST_FOREACH(G_AddrC, &(Cassoc->Gaddr), list_Gaddr) {
+ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ if(G_Addr->g_addr.s_addr == G_AddrC->g_addr.s_addr)
+ return(assoc);
+ }
+ }
+ } else {
+ return(assoc);
+ }
+ }
+ }
}
- }
- }
- }
- return(NULL);
+ return(NULL);
}
/** @ingroup Hash
@@ -2064,28 +2042,28 @@ FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc)
static struct sctp_nat_assoc*
FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
- struct sctp_GlobalAddress *G_Addr = NULL;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
+ struct sctp_GlobalAddress *G_Addr = NULL;
- *partial_match = 0;
- if (g_vtag != 0) { /* an init packet, vtag==0 */
- i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize);
- LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
- if ((assoc->g_vtag == g_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) {
- *partial_match = 1;
- if (assoc->num_Gaddr) {
- LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == g_addr.s_addr)
- return(assoc);
- }
- } else {
- return(assoc);
+ *partial_match = 0;
+ if (g_vtag != 0) { /* an init packet, vtag==0 */
+ i = SN_TABLE_HASH(g_vtag, g_port, la->sctpNatTableSize);
+ LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
+ if ((assoc->g_vtag == g_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) {
+ *partial_match = 1;
+ if (assoc->num_Gaddr) {
+ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ if(G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return(assoc);
+ }
+ } else {
+ return(assoc);
+ }
+ }
+ }
}
- }
- }
- }
- return(NULL);
+ return(NULL);
}
/** @ingroup Hash
@@ -2105,29 +2083,29 @@ FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint
static struct sctp_nat_assoc*
FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL, *lastmatch = NULL;
- struct sctp_GlobalAddress *G_Addr = NULL;
- int cnt = 0;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL, *lastmatch = NULL;
+ struct sctp_GlobalAddress *G_Addr = NULL;
+ int cnt = 0;
- if (l_vtag != 0) { /* an init packet, vtag==0 */
- i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize);
- LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
- if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) {
- if (assoc->num_Gaddr) {
- LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == G_Addr->g_addr.s_addr)
- return(assoc); /* full match */
- }
- } else {
- if (++cnt > 1) return(NULL);
- lastmatch = assoc;
+ if (l_vtag != 0) { /* an init packet, vtag==0 */
+ i = SN_TABLE_HASH(l_vtag, g_port, la->sctpNatTableSize);
+ LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
+ if ((assoc->g_vtag == l_vtag) && (assoc->g_port == g_port) && (assoc->l_port == l_port)) {
+ if (assoc->num_Gaddr) {
+ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ if(G_Addr->g_addr.s_addr == G_Addr->g_addr.s_addr)
+ return(assoc); /* full match */
+ }
+ } else {
+ if (++cnt > 1) return(NULL);
+ lastmatch = assoc;
+ }
+ }
+ }
}
- }
- }
- }
- /* If there is more than one match we do not know which local address to send to */
- return( cnt ? lastmatch : NULL );
+ /* If there is more than one match we do not know which local address to send to */
+ return( cnt ? lastmatch : NULL );
}
/** @ingroup Hash
@@ -2147,26 +2125,26 @@ FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uin
static struct sctp_nat_assoc*
FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t l_port, uint16_t g_port)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
- struct sctp_GlobalAddress *G_Addr = NULL;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
+ struct sctp_GlobalAddress *G_Addr = NULL;
- if (g_vtag != 0) { /* an init packet, vtag==0 */
- i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize);
- LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
- if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) {
- if (assoc->num_Gaddr) {
- LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- if(G_Addr->g_addr.s_addr == g_addr.s_addr)
- return(assoc);
- }
- } else {
- return(assoc);
+ if (g_vtag != 0) { /* an init packet, vtag==0 */
+ i = SN_TABLE_HASH(g_vtag, l_port, la->sctpNatTableSize);
+ LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
+ if ((assoc->l_vtag == g_vtag) && (assoc->l_port == l_port) && (assoc->g_port == g_port)) {
+ if (assoc->num_Gaddr) {
+ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ if(G_Addr->g_addr.s_addr == g_addr.s_addr)
+ return(assoc);
+ }
+ } else {
+ return(assoc);
+ }
+ }
+ }
}
- }
- }
- }
- return(NULL);
+ return(NULL);
}
/** @ingroup Hash
@@ -2188,43 +2166,43 @@ FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uin
static int
AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_addr g_addr)
{
- struct sctp_nat_assoc *found;
-
- LIBALIAS_LOCK_ASSERT(la);
- found = FindSctpLocal(la, assoc->l_addr, g_addr, assoc->l_vtag, assoc->l_port, assoc->g_port);
- /*
- * Note that if a different global address initiated this Init,
- * ie it wasn't resent as presumed:
- * - the local receiver if receiving it for the first time will establish
- * an association with the new global host
- * - if receiving an init from a different global address after sending a
- * lost initack it will send an initack to the new global host, the first
- * association attempt will then be blocked if retried.
- */
- if (found != NULL) {
- if ((found->TableRegister == SN_LOCAL_TBL) && (found->g_port == assoc->g_port)) { /* resent message */
- RmSctpAssoc(la, found);
- sctp_RmTimeOut(la, found);
- freeGlobalAddressList(found);
- sn_free(found);
- } else
- return(SN_ADD_CLASH);
- }
+ struct sctp_nat_assoc *found;
+
+ LIBALIAS_LOCK_ASSERT(la);
+ found = FindSctpLocal(la, assoc->l_addr, g_addr, assoc->l_vtag, assoc->l_port, assoc->g_port);
+ /*
+ * Note that if a different global address initiated this Init,
+ * ie it wasn't resent as presumed:
+ * - the local receiver if receiving it for the first time will establish
+ * an association with the new global host
+ * - if receiving an init from a different global address after sending a
+ * lost initack it will send an initack to the new global host, the first
+ * association attempt will then be blocked if retried.
+ */
+ if (found != NULL) {
+ if ((found->TableRegister == SN_LOCAL_TBL) && (found->g_port == assoc->g_port)) { /* resent message */
+ RmSctpAssoc(la, found);
+ sctp_RmTimeOut(la, found);
+ freeGlobalAddressList(found);
+ sn_free(found);
+ } else
+ return(SN_ADD_CLASH);
+ }
- LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableSize)],
- assoc, list_L);
- assoc->TableRegister |= SN_LOCAL_TBL;
- la->sctpLinkCount++; //increment link count
+ LIST_INSERT_HEAD(&la->sctpTableLocal[SN_TABLE_HASH(assoc->l_vtag, assoc->l_port, la->sctpNatTableSize)],
+ assoc, list_L);
+ assoc->TableRegister |= SN_LOCAL_TBL;
+ la->sctpLinkCount++; //increment link count
- if (assoc->TableRegister == SN_BOTH_TBL) {
- /* libalias log -- controlled by libalias */
- if (la->packetAliasMode & PKT_ALIAS_LOG)
- SctpShowAliasStats(la);
+ if (assoc->TableRegister == SN_BOTH_TBL) {
+ /* libalias log -- controlled by libalias */
+ if (la->packetAliasMode & PKT_ALIAS_LOG)
+ SctpShowAliasStats(la);
- SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^"));
- }
+ SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^"));
+ }
- return(SN_ADD_OK);
+ return(SN_ADD_OK);
}
/** @ingroup Hash
@@ -2245,35 +2223,35 @@ AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_a
static int
AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc)
{
- struct sctp_nat_assoc *found;
-
- LIBALIAS_LOCK_ASSERT(la);
- found = FindSctpGlobalClash(la, assoc);
- if (found != NULL) {
- if ((found->TableRegister == SN_GLOBAL_TBL) && \
- (found->l_addr.s_addr == assoc->l_addr.s_addr) && (found->l_port == assoc->l_port)) { /* resent message */
- RmSctpAssoc(la, found);
- sctp_RmTimeOut(la, found);
- freeGlobalAddressList(found);
- sn_free(found);
- } else
- return(SN_ADD_CLASH);
- }
+ struct sctp_nat_assoc *found;
+
+ LIBALIAS_LOCK_ASSERT(la);
+ found = FindSctpGlobalClash(la, assoc);
+ if (found != NULL) {
+ if ((found->TableRegister == SN_GLOBAL_TBL) && \
+ (found->l_addr.s_addr == assoc->l_addr.s_addr) && (found->l_port == assoc->l_port)) { /* resent message */
+ RmSctpAssoc(la, found);
+ sctp_RmTimeOut(la, found);
+ freeGlobalAddressList(found);
+ sn_free(found);
+ } else
+ return(SN_ADD_CLASH);
+ }
- LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTableSize)],
- assoc, list_G);
- assoc->TableRegister |= SN_GLOBAL_TBL;
- la->sctpLinkCount++; //increment link count
+ LIST_INSERT_HEAD(&la->sctpTableGlobal[SN_TABLE_HASH(assoc->g_vtag, assoc->g_port, la->sctpNatTableSize)],
+ assoc, list_G);
+ assoc->TableRegister |= SN_GLOBAL_TBL;
+ la->sctpLinkCount++; //increment link count
- if (assoc->TableRegister == SN_BOTH_TBL) {
- /* libalias log -- controlled by libalias */
- if (la->packetAliasMode & PKT_ALIAS_LOG)
- SctpShowAliasStats(la);
+ if (assoc->TableRegister == SN_BOTH_TBL) {
+ /* libalias log -- controlled by libalias */
+ if (la->packetAliasMode & PKT_ALIAS_LOG)
+ SctpShowAliasStats(la);
- SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^"));
- }
+ SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "^"));
+ }
- return(SN_ADD_OK);
+ return(SN_ADD_OK);
}
/** @ingroup Hash
@@ -2293,33 +2271,33 @@ AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc)
static void
RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc)
{
- // struct sctp_nat_assoc *found;
- if (assoc == NULL) {
- /* very bad, log and die*/
- SN_LOG(SN_LOG_LOW,
- logsctperror("ERROR: alias_sctp:RmSctpAssoc(NULL)\n", 0, 0, SN_TO_NODIR));
- return;
- }
- /* log if association is fully up and now closing */
- if (assoc->TableRegister == SN_BOTH_TBL) {
- SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "$"));
- }
- LIBALIAS_LOCK_ASSERT(la);
- if (assoc->TableRegister & SN_LOCAL_TBL) {
- assoc->TableRegister ^= SN_LOCAL_TBL;
- la->sctpLinkCount--; //decrement link count
- LIST_REMOVE(assoc, list_L);
- }
+ // struct sctp_nat_assoc *found;
+ if (assoc == NULL) {
+ /* very bad, log and die*/
+ SN_LOG(SN_LOG_LOW,
+ logsctperror("ERROR: alias_sctp:RmSctpAssoc(NULL)\n", 0, 0, SN_TO_NODIR));
+ return;
+ }
+ /* log if association is fully up and now closing */
+ if (assoc->TableRegister == SN_BOTH_TBL) {
+ SN_LOG(SN_LOG_INFO, logsctpassoc(assoc, "$"));
+ }
+ LIBALIAS_LOCK_ASSERT(la);
+ if (assoc->TableRegister & SN_LOCAL_TBL) {
+ assoc->TableRegister ^= SN_LOCAL_TBL;
+ la->sctpLinkCount--; //decrement link count
+ LIST_REMOVE(assoc, list_L);
+ }
- if (assoc->TableRegister & SN_GLOBAL_TBL) {
- assoc->TableRegister ^= SN_GLOBAL_TBL;
- la->sctpLinkCount--; //decrement link count
- LIST_REMOVE(assoc, list_G);
- }
- // sn_free(assoc); //Don't remove now, remove if needed later
- /* libalias logging -- controlled by libalias log definition */
- if (la->packetAliasMode & PKT_ALIAS_LOG)
- SctpShowAliasStats(la);
+ if (assoc->TableRegister & SN_GLOBAL_TBL) {
+ assoc->TableRegister ^= SN_GLOBAL_TBL;
+ la->sctpLinkCount--; //decrement link count
+ LIST_REMOVE(assoc, list_G);
+ }
+ // sn_free(assoc); //Don't remove now, remove if needed later
+ /* libalias logging -- controlled by libalias log definition */
+ if (la->packetAliasMode & PKT_ALIAS_LOG)
+ SctpShowAliasStats(la);
}
/**
@@ -2333,14 +2311,14 @@ RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc)
*/
static void freeGlobalAddressList(struct sctp_nat_assoc *assoc)
{
- struct sctp_GlobalAddress *gaddr1=NULL,*gaddr2=NULL;
- /*free global address list*/
- gaddr1 = LIST_FIRST(&(assoc->Gaddr));
- while (gaddr1 != NULL) {
- gaddr2 = LIST_NEXT(gaddr1, list_Gaddr);
- sn_free(gaddr1);
- gaddr1 = gaddr2;
- }
+ struct sctp_GlobalAddress *gaddr1=NULL,*gaddr2=NULL;
+ /*free global address list*/
+ gaddr1 = LIST_FIRST(&(assoc->Gaddr));
+ while (gaddr1 != NULL) {
+ gaddr2 = LIST_NEXT(gaddr1, list_Gaddr);
+ sn_free(gaddr1);
+ gaddr1 = gaddr2;
+ }
}
/* ----------------------------------------------------------------------
* TIMER QUEUE CODE
@@ -2372,13 +2350,13 @@ static void freeGlobalAddressList(struct sctp_nat_assoc *assoc)
static void
sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc)
{
- int add_loc;
- LIBALIAS_LOCK_ASSERT(la);
- add_loc = assoc->exp - la->sctpNatTimer.loc_time + la->sctpNatTimer.cur_loc;
- if (add_loc >= SN_TIMER_QUEUE_SIZE)
- add_loc -= SN_TIMER_QUEUE_SIZE;
- LIST_INSERT_HEAD(&la->sctpNatTimer.TimerQ[add_loc], assoc, timer_Q);
- assoc->exp_loc = add_loc;
+ int add_loc;
+ LIBALIAS_LOCK_ASSERT(la);
+ add_loc = assoc->exp - la->sctpNatTimer.loc_time + la->sctpNatTimer.cur_loc;
+ if (add_loc >= SN_TIMER_QUEUE_SIZE)
+ add_loc -= SN_TIMER_QUEUE_SIZE;
+ LIST_INSERT_HEAD(&la->sctpNatTimer.TimerQ[add_loc], assoc, timer_Q);
+ assoc->exp_loc = add_loc;
}
/** @ingroup Timer
@@ -2393,8 +2371,8 @@ sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc)
static void
sctp_RmTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc)
{
- LIBALIAS_LOCK_ASSERT(la);
- LIST_REMOVE(assoc, timer_Q);/* Note this is O(1) */
+ LIBALIAS_LOCK_ASSERT(la);
+ LIST_REMOVE(assoc, timer_Q);/* Note this is O(1) */
}
@@ -2412,13 +2390,13 @@ sctp_RmTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc)
static void
sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp)
{
- if (newexp < assoc->exp) {
- sctp_RmTimeOut(la, assoc);
- assoc->exp = newexp;
- sctp_AddTimeOut(la, assoc);
- } else {
- assoc->exp = newexp;
- }
+ if (newexp < assoc->exp) {
+ sctp_RmTimeOut(la, assoc);
+ assoc->exp = newexp;
+ sctp_AddTimeOut(la, assoc);
+ } else {
+ assoc->exp = newexp;
+ }
}
/** @ingroup Timer
@@ -2440,29 +2418,29 @@ sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp)
void
sctp_CheckTimers(struct libalias *la)
{
- struct sctp_nat_assoc *assoc;
+ struct sctp_nat_assoc *assoc;
- LIBALIAS_LOCK_ASSERT(la);
- while(la->timeStamp >= la->sctpNatTimer.loc_time) {
- while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) {
- assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]);
- //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q);
- LIST_REMOVE(assoc, timer_Q);
- if (la->timeStamp >= assoc->exp) { /* state expired */
- SN_LOG(((assoc->state == SN_CL)?(SN_LOG_DEBUG):(SN_LOG_INFO)),
- logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR));
- RmSctpAssoc(la, assoc);
- freeGlobalAddressList(assoc);
- sn_free(assoc);
- } else {/* state not expired, reschedule timer*/
- sctp_AddTimeOut(la, assoc);
- }
- }
- /* Goto next location in the timer queue*/
- ++la->sctpNatTimer.loc_time;
- if (++la->sctpNatTimer.cur_loc >= SN_TIMER_QUEUE_SIZE)
- la->sctpNatTimer.cur_loc = 0;
- }
+ LIBALIAS_LOCK_ASSERT(la);
+ while(la->timeStamp >= la->sctpNatTimer.loc_time) {
+ while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) {
+ assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]);
+ //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q);
+ LIST_REMOVE(assoc, timer_Q);
+ if (la->timeStamp >= assoc->exp) { /* state expired */
+ SN_LOG(((assoc->state == SN_CL)?(SN_LOG_DEBUG):(SN_LOG_INFO)),
+ logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR));
+ RmSctpAssoc(la, assoc);
+ freeGlobalAddressList(assoc);
+ sn_free(assoc);
+ } else {/* state not expired, reschedule timer*/
+ sctp_AddTimeOut(la, assoc);
+ }
+ }
+ /* Goto next location in the timer queue*/
+ ++la->sctpNatTimer.loc_time;
+ if (++la->sctpNatTimer.cur_loc >= SN_TIMER_QUEUE_SIZE)
+ la->sctpNatTimer.cur_loc = 0;
+ }
}
/* ----------------------------------------------------------------------
@@ -2486,19 +2464,19 @@ sctp_CheckTimers(struct libalias *la)
static void
logsctperror(char* errormsg, uint32_t vtag, int error, int direction)
{
- char dir;
- switch(direction) {
- case SN_TO_LOCAL:
- dir = 'L';
- break;
- case SN_TO_GLOBAL:
- dir = 'G';
- break;
- default:
- dir = '*';
- break;
- }
- SctpAliasLog("->%c %s (vt=%u) %d\n", dir, errormsg, ntohl(vtag), error);
+ char dir;
+ switch(direction) {
+ case SN_TO_LOCAL:
+ dir = 'L';
+ break;
+ case SN_TO_GLOBAL:
+ dir = 'G';
+ break;
+ default:
+ dir = '*';
+ break;
+ }
+ SctpAliasLog("->%c %s (vt=%u) %d\n", dir, errormsg, ntohl(vtag), error);
}
/** @ingroup Logging
@@ -2510,47 +2488,47 @@ logsctperror(char* errormsg, uint32_t vtag, int error, int direction)
static void
logsctpparse(int direction, struct sctp_nat_msg *sm)
{
- char *ploc, *pstate;
- switch(direction) {
- case SN_TO_LOCAL:
- ploc = "TO_LOCAL -";
- break;
- case SN_TO_GLOBAL:
- ploc = "TO_GLOBAL -";
- break;
- default:
- ploc = "";
- }
- switch(sm->msg) {
- case SN_SCTP_INIT:
- pstate = "Init";
- break;
- case SN_SCTP_INITACK:
- pstate = "InitAck";
- break;
- case SN_SCTP_ABORT:
- pstate = "Abort";
- break;
- case SN_SCTP_SHUTACK:
- pstate = "ShutAck";
- break;
- case SN_SCTP_SHUTCOMP:
- pstate = "ShutComp";
- break;
- case SN_SCTP_ASCONF:
- pstate = "Asconf";
- break;
- case SN_SCTP_ASCONFACK:
- pstate = "AsconfAck";
- break;
- case SN_SCTP_OTHER:
- pstate = "Other";
- break;
- default:
- pstate = "***ERROR***";
- break;
- }
- SctpAliasLog("Parsed: %s %s\n", ploc, pstate);
+ char *ploc, *pstate;
+ switch(direction) {
+ case SN_TO_LOCAL:
+ ploc = "TO_LOCAL -";
+ break;
+ case SN_TO_GLOBAL:
+ ploc = "TO_GLOBAL -";
+ break;
+ default:
+ ploc = "";
+ }
+ switch(sm->msg) {
+ case SN_SCTP_INIT:
+ pstate = "Init";
+ break;
+ case SN_SCTP_INITACK:
+ pstate = "InitAck";
+ break;
+ case SN_SCTP_ABORT:
+ pstate = "Abort";
+ break;
+ case SN_SCTP_SHUTACK:
+ pstate = "ShutAck";
+ break;
+ case SN_SCTP_SHUTCOMP:
+ pstate = "ShutComp";
+ break;
+ case SN_SCTP_ASCONF:
+ pstate = "Asconf";
+ break;
+ case SN_SCTP_ASCONFACK:
+ pstate = "AsconfAck";
+ break;
+ case SN_SCTP_OTHER:
+ pstate = "Other";
+ break;
+ default:
+ pstate = "***ERROR***";
+ break;
+ }
+ SctpAliasLog("Parsed: %s %s\n", ploc, pstate);
}
/** @ingroup Logging
@@ -2561,39 +2539,39 @@ logsctpparse(int direction, struct sctp_nat_msg *sm)
*/
static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s)
{
- struct sctp_GlobalAddress *G_Addr = NULL;
- char *sp;
- switch(assoc->state) {
- case SN_ID:
- sp = "ID ";
- break;
- case SN_INi:
- sp = "INi ";
- break;
- case SN_INa:
- sp = "INa ";
- break;
- case SN_UP:
- sp = "UP ";
- break;
- case SN_CL:
- sp = "CL ";
- break;
- case SN_RM:
- sp = "RM ";
- break;
- default:
- sp = "***ERROR***";
- break;
- }
- SctpAliasLog("%sAssoc: %s exp=%u la=%s lv=%u lp=%u gv=%u gp=%u tbl=%d\n",
- s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag),
- ntohs(assoc->l_port), ntohl(assoc->g_vtag), ntohs(assoc->g_port),
- assoc->TableRegister);
- /* list global addresses */
- LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr));
- }
+ struct sctp_GlobalAddress *G_Addr = NULL;
+ char *sp;
+ switch(assoc->state) {
+ case SN_ID:
+ sp = "ID ";
+ break;
+ case SN_INi:
+ sp = "INi ";
+ break;
+ case SN_INa:
+ sp = "INa ";
+ break;
+ case SN_UP:
+ sp = "UP ";
+ break;
+ case SN_CL:
+ sp = "CL ";
+ break;
+ case SN_RM:
+ sp = "RM ";
+ break;
+ default:
+ sp = "***ERROR***";
+ break;
+ }
+ SctpAliasLog("%sAssoc: %s exp=%u la=%s lv=%u lp=%u gv=%u gp=%u tbl=%d\n",
+ s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag),
+ ntohs(assoc->l_port), ntohl(assoc->g_vtag), ntohs(assoc->g_port),
+ assoc->TableRegister);
+ /* list global addresses */
+ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
+ SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr));
+ }
}
/** @ingroup Logging
@@ -2603,15 +2581,15 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s)
*/
static void logSctpGlobal(struct libalias *la)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
- SctpAliasLog("G->\n");
- for (i=0; i < la->sctpNatTableSize; i++) {
- LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
- logsctpassoc(assoc, " ");
- }
- }
+ SctpAliasLog("G->\n");
+ for (i=0; i < la->sctpNatTableSize; i++) {
+ LIST_FOREACH(assoc, &la->sctpTableGlobal[i], list_G) {
+ logsctpassoc(assoc, " ");
+ }
+ }
}
/** @ingroup Logging
@@ -2621,15 +2599,15 @@ static void logSctpGlobal(struct libalias *la)
*/
static void logSctpLocal(struct libalias *la)
{
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
- SctpAliasLog("L->\n");
- for (i=0; i < la->sctpNatTableSize; i++) {
- LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
- logsctpassoc(assoc, " ");
- }
- }
+ SctpAliasLog("L->\n");
+ for (i=0; i < la->sctpNatTableSize; i++) {
+ LIST_FOREACH(assoc, &la->sctpTableLocal[i], list_L) {
+ logsctpassoc(assoc, " ");
+ }
+ }
}
/** @ingroup Logging
@@ -2639,18 +2617,18 @@ static void logSctpLocal(struct libalias *la)
*/
static void logTimerQ(struct libalias *la)
{
- static char buf[50];
- u_int i;
- struct sctp_nat_assoc *assoc = NULL;
-
- SctpAliasLog("t->\n");
- for (i=0; i < SN_TIMER_QUEUE_SIZE; i++) {
- LIST_FOREACH(assoc, &la->sctpNatTimer.TimerQ[i], timer_Q) {
- snprintf(buf, 50, " l=%u ",i);
- //SctpAliasLog(la->logDesc," l=%d ",i);
- logsctpassoc(assoc, buf);
- }
- }
+ static char buf[50];
+ u_int i;
+ struct sctp_nat_assoc *assoc = NULL;
+
+ SctpAliasLog("t->\n");
+ for (i=0; i < SN_TIMER_QUEUE_SIZE; i++) {
+ LIST_FOREACH(assoc, &la->sctpNatTimer.TimerQ[i], timer_Q) {
+ snprintf(buf, 50, " l=%u ",i);
+ //SctpAliasLog(la->logDesc," l=%d ",i);
+ logsctpassoc(assoc, buf);
+ }
+ }
}
/** @ingroup Logging
@@ -2665,23 +2643,23 @@ static void logTimerQ(struct libalias *la)
static void
SctpAliasLog(const char *format, ...)
{
- char buffer[LIBALIAS_BUF_SIZE];
- va_list ap;
- va_start(ap, format);
- vsnprintf(buffer, LIBALIAS_BUF_SIZE, format, ap);
- va_end(ap);
- log(LOG_SECURITY | LOG_INFO,
- "alias_sctp: %s", buffer);
+ char buffer[LIBALIAS_BUF_SIZE];
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buffer, LIBALIAS_BUF_SIZE, format, ap);
+ va_end(ap);
+ log(LOG_SECURITY | LOG_INFO,
+ "alias_sctp: %s", buffer);
}
#else
static void
SctpAliasLog(FILE *stream, const char *format, ...)
{
- va_list ap;
+ va_list ap;
- va_start(ap, format);
- vfprintf(stream, format, ap);
- va_end(ap);
- fflush(stream);
+ va_start(ap, format);
+ vfprintf(stream, format, ap);
+ va_end(ap);
+ fflush(stream);
}
#endif
diff --git a/sys/netinet/libalias/alias_sctp.h b/sys/netinet/libalias/alias_sctp.h
index f299a6f..7953f43 100644
--- a/sys/netinet/libalias/alias_sctp.h
+++ b/sys/netinet/libalias/alias_sctp.h
@@ -1,34 +1,9 @@
-/*/* $Id$ */
-//#ifndef lint
-//static char vcid[] = "$Id$";
-//#endif /* lint */
/**
* @file alias_sctp.h
* Copyright (c) 2008, Centre for Advanced Internet Architectures
* Swinburne University of Technology, Melbourne, Australia
* (CRICOS number 00111D).
*
- * Alias_sctp forms part of the libalias kernel module to handle
- * Network Address Translation (NAT) for the SCTP protocol.
- *
- * This software was developed by David A. Hayes
- * with leadership and advice from Jason But
- *
- * The design is outlined in CAIA technical report number 080618A
- * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW")
- *
- * Development is part of the CAIA SONATA project,
- * proposed by Jason But and Grenville Armitage:
- * http://caia.swin.edu.au/urp/sonata/
- *
- *
- * This project has been made possible in part by a grant from
- * the Cisco University Research Program Fund at Community
- * Foundation Silicon Valley.
- *
- *
- * All rights reserved.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -54,7 +29,28 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Alias_sctp forms part of the libalias kernel module to handle
+ * Network Address Translation (NAT) for the SCTP protocol.
+ *
+ * This software was developed by David A. Hayes
+ * with leadership and advice from Jason But
+ *
+ * The design is outlined in CAIA technical report number 080618A
+ * (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW")
+ *
+ * Development is part of the CAIA SONATA project,
+ * proposed by Jason But and Grenville Armitage:
+ * http://caia.swin.edu.au/urp/sonata/
+ *
+ *
+ * This project has been made possible in part by a grant from
+ * the Cisco University Research Program Fund at Community
+ * Foundation Silicon Valley.
+ *
*/
+
+/* $FreeBSD$ */
+
#ifndef _ALIAS_SCTP_H_
#define _ALIAS_SCTP_H_
@@ -136,27 +132,27 @@
* Information is stored in network byte order (as is libalias)***
*/
struct sctp_nat_assoc {
- uint32_t l_vtag; /**< local side verification tag */
- uint16_t l_port; /**< local side port number */
- uint32_t g_vtag; /**< global side verification tag */
- uint16_t g_port; /**< global side port number */
- struct in_addr l_addr; /**< local ip address */
- struct in_addr a_addr; /**< alias ip address */
- int state; /**< current state of NAT association */
- int TableRegister; /**< stores which look up tables association is registered in */
- int exp; /**< timer expiration in seconds from uptime */
- int exp_loc; /**< current location in timer_Q */
- int num_Gaddr; /**< number of global IP addresses in the list */
- LIST_HEAD(sctpGlobalAddresshead,sctp_GlobalAddress) Gaddr; /**< List of global addresses */
- LIST_ENTRY (sctp_nat_assoc) list_L; /**< Linked list of pointers for Local table*/
- LIST_ENTRY (sctp_nat_assoc) list_G; /**< Linked list of pointers for Global table */
- LIST_ENTRY (sctp_nat_assoc) timer_Q; /**< Linked list of pointers for timer Q */
+ uint32_t l_vtag; /**< local side verification tag */
+ uint16_t l_port; /**< local side port number */
+ uint32_t g_vtag; /**< global side verification tag */
+ uint16_t g_port; /**< global side port number */
+ struct in_addr l_addr; /**< local ip address */
+ struct in_addr a_addr; /**< alias ip address */
+ int state; /**< current state of NAT association */
+ int TableRegister; /**< stores which look up tables association is registered in */
+ int exp; /**< timer expiration in seconds from uptime */
+ int exp_loc; /**< current location in timer_Q */
+ int num_Gaddr; /**< number of global IP addresses in the list */
+ LIST_HEAD(sctpGlobalAddresshead,sctp_GlobalAddress) Gaddr; /**< List of global addresses */
+ LIST_ENTRY (sctp_nat_assoc) list_L; /**< Linked list of pointers for Local table*/
+ LIST_ENTRY (sctp_nat_assoc) list_G; /**< Linked list of pointers for Global table */
+ LIST_ENTRY (sctp_nat_assoc) timer_Q; /**< Linked list of pointers for timer Q */
//Using libalias locking
};
struct sctp_GlobalAddress {
- struct in_addr g_addr;
- LIST_ENTRY (sctp_GlobalAddress) list_Gaddr; /**< Linked list of pointers for Global table */
+ struct in_addr g_addr;
+ LIST_ENTRY (sctp_GlobalAddress) list_Gaddr; /**< Linked list of pointers for Global table */
};
/**
@@ -165,9 +161,9 @@ struct sctp_GlobalAddress {
* The only chunks whose contents are of any interest are the INIT and ASCONF_AddIP
*/
union sctpChunkOfInt {
- struct sctp_init *Init; /**< Pointer to Init Chunk */
- struct sctp_init_ack *InitAck; /**< Pointer to Init Chunk */
- struct sctp_paramhdr *Asconf; /**< Pointer to ASCONF chunk */
+ struct sctp_init *Init; /**< Pointer to Init Chunk */
+ struct sctp_init_ack *InitAck; /**< Pointer to Init Chunk */
+ struct sctp_paramhdr *Asconf; /**< Pointer to ASCONF chunk */
};
@@ -177,15 +173,15 @@ union sctpChunkOfInt {
* Structure containing the relevant information from the SCTP message
*/
struct sctp_nat_msg {
- uint16_t msg; /**< one of the key messages defined above */
+ uint16_t msg; /**< one of the key messages defined above */
#ifdef INET6
- // struct ip6_hdr *ip_hdr; /**< pointer to ip packet header */ /*no inet6 support yet*/
+ // struct ip6_hdr *ip_hdr; /**< pointer to ip packet header */ /*no inet6 support yet*/
#else
- struct ip *ip_hdr; /**< pointer to ip packet header */
+ struct ip *ip_hdr; /**< pointer to ip packet header */
#endif //#ifdef INET6
- struct sctphdr *sctp_hdr; /**< pointer to sctp common header */
- union sctpChunkOfInt sctpchnk; /**< union of pointers to the chunk of interest */
- int chunk_length; /**< length of chunk of interest */
+ struct sctphdr *sctp_hdr; /**< pointer to sctp common header */
+ union sctpChunkOfInt sctpchnk; /**< union of pointers to the chunk of interest */
+ int chunk_length; /**< length of chunk of interest */
};
@@ -195,9 +191,9 @@ struct sctp_nat_msg {
*/
struct sctp_nat_timer {
- int loc_time; /**< time in seconds for the current location in the queue */
- int cur_loc; /**< index of the current location in the circular queue */
- LIST_HEAD(sctpTimerQ,sctp_nat_assoc) *TimerQ; /**< List of associations at this position in the timer Q */
+ int loc_time; /**< time in seconds for the current location in the queue */
+ int cur_loc; /**< index of the current location in the circular queue */
+ LIST_HEAD(sctpTimerQ,sctp_nat_assoc) *TimerQ; /**< List of associations at this position in the timer Q */
};
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 9fe0eca..27f4b9c 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -276,10 +276,8 @@ rip_input(struct mbuf *m, int off)
continue;
if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
continue;
- if (jailed(inp->inp_cred)) {
- if (!prison_check_ip4(inp->inp_cred, &ip->ip_dst))
- continue;
- }
+ if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
+ continue;
if (last != NULL) {
struct mbuf *n;
@@ -306,10 +304,8 @@ rip_input(struct mbuf *m, int off)
if (inp->inp_faddr.s_addr &&
inp->inp_faddr.s_addr != ip->ip_src.s_addr)
continue;
- if (jailed(inp->inp_cred)) {
- if (!prison_check_ip4(inp->inp_cred, &ip->ip_dst))
- continue;
- }
+ if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
+ continue;
if (last != NULL) {
struct mbuf *n;
@@ -370,14 +366,12 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
ip->ip_off = 0;
ip->ip_p = inp->inp_ip_p;
ip->ip_len = m->m_pkthdr.len;
- if (jailed(inp->inp_cred)) {
- if (prison_getip4(inp->inp_cred, &ip->ip_src)) {
- INP_RUNLOCK(inp);
- m_freem(m);
- return (EPERM);
- }
- } else {
- ip->ip_src = inp->inp_laddr;
+ ip->ip_src = inp->inp_laddr;
+ error = prison_get_ip4(inp->inp_cred, &ip->ip_src);
+ if (error != 0) {
+ INP_RUNLOCK(inp);
+ m_freem(m);
+ return (error);
}
ip->ip_dst.s_addr = dst;
ip->ip_ttl = inp->inp_ip_ttl;
@@ -388,10 +382,11 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
}
INP_RLOCK(inp);
ip = mtod(m, struct ip *);
- if (!prison_check_ip4(inp->inp_cred, &ip->ip_src)) {
+ error = prison_check_ip4(inp->inp_cred, &ip->ip_src);
+ if (error != 0) {
INP_RUNLOCK(inp);
m_freem(m);
- return (EPERM);
+ return (error);
}
/*
@@ -803,12 +798,14 @@ rip_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
INIT_VNET_INET(so->so_vnet);
struct sockaddr_in *addr = (struct sockaddr_in *)nam;
struct inpcb *inp;
+ int error;
if (nam->sa_len != sizeof(*addr))
return (EINVAL);
- if (!prison_check_ip4(td->td_ucred, &addr->sin_addr))
- return (EADDRNOTAVAIL);
+ error = prison_check_ip4(td->td_ucred, &addr->sin_addr);
+ if (error != 0)
+ return (error);
if (TAILQ_EMPTY(&V_ifnet) ||
(addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) ||
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index 71715cc..6da97ec 100644
--- a/sys/netinet/sctp_auth.c
+++ b/sys/netinet/sctp_auth.c
@@ -1645,8 +1645,10 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
bcopy(p_random->random_data, new_key->key, random_len);
}
#else
- keylen = sizeof(*p_random) + random_len + sizeof(*chunks) + num_chunks +
- sizeof(*hmacs) + hmacs_len;
+ keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
+ if (chunks != NULL) {
+ keylen += sizeof(*chunks) + num_chunks;
+ }
new_key = sctp_alloc_key(keylen);
if (new_key != NULL) {
/* copy in the RANDOM */
diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
index cc48d2f..ca9c010 100644
--- a/sys/netinet/sctp_constants.h
+++ b/sys/netinet/sctp_constants.h
@@ -37,8 +37,15 @@ __FBSDID("$FreeBSD$");
#define __sctp_constants_h__
/* IANA assigned port number for SCTP over UDP encapsulation */
-#define SCTP_OVER_UDP_TUNNELING_PORT 9899
-
+/* For freebsd we cannot bind the port at
+ * startup. Otherwise what will happen is
+ * we really won't be bound. The user must
+ * put it into the sysctl... or we need
+ * to build a special timer for this to allow
+ * us to wait 1 second or so after the system
+ * comes up.
+ */
+#define SCTP_OVER_UDP_TUNNELING_PORT 0
/* Number of packets to get before sack sent by default */
#define SCTP_DEFAULT_SACK_FREQ 2
@@ -310,10 +317,6 @@ __FBSDID("$FreeBSD$");
#define SCTP_PARTIAL_DELIVERY_SHIFT 1
-/* Minimum number of bytes read by user before we
- * condsider doing a rwnd update
- */
-
/*
* default HMAC for cookies, etc... use one of the AUTH HMAC id's
* SCTP_HMAC is the HMAC_ID to use
@@ -323,21 +326,6 @@ __FBSDID("$FreeBSD$");
#define SCTP_SIGNATURE_SIZE SCTP_AUTH_DIGEST_LEN_SHA1
#define SCTP_SIGNATURE_ALOC_SIZE SCTP_SIGNATURE_SIZE
-/* DEFINE HERE WHAT CRC YOU WANT TO USE */
-#define SCTP_USECRC_RFC2960 1
-/* #define SCTP_USECRC_FLETCHER 1 */
-/* #define SCTP_USECRC_SSHCRC32 1 */
-/* #define SCTP_USECRC_FASTCRC32 1 */
-/* #define SCTP_USECRC_CRC32 1 */
-/* #define SCTP_USECRC_TCP32 1 */
-/* #define SCTP_USECRC_CRC16SMAL 1 */
-/* #define SCTP_USECRC_CRC16 1 */
-/* #define SCTP_USECRC_MODADLER 1 */
-
-#ifndef SCTP_ADLER32_BASE
-#define SCTP_ADLER32_BASE 65521
-#endif
-
/*
* the SCTP protocol signature this includes the version number encoded in
* the last 4 bits of the signature.
@@ -619,43 +607,16 @@ __FBSDID("$FreeBSD$");
-/*
- * Number of ticks before the soxwakeup() event that is delayed is sent AFTER
- * the accept() call
- */
-
-/*
- * Of course we really don't collect stale cookies, being folks of decerning
- * taste. However we do count them, if we get too many before the association
- * comes up.. we give up. Below is the constant that dictates when we give it
- * up...this is a implemenation dependent treatment. In ours we do not ask
- * for a extension of time, but just retry this many times...
- */
-
/* max number of TSN's dup'd that I will hold */
#define SCTP_MAX_DUP_TSNS 20
/*
* Here we define the types used when setting the retry amounts.
*/
-/* constants for type of set */
-
-/* Maximum TSN's we will summarize in a drop report */
-
/* How many drop re-attempts we make on INIT/COOKIE-ECHO */
#define SCTP_RETRY_DROPPED_THRESH 4
/*
- * And the max we will keep a history of in the tcb which MUST be lower than
- * 256.
- */
-
-/*
- * Here we define the default timers and the default number of attemts we
- * make for each respective side (send/init).
- */
-
-/*
* Maxmium number of chunks a single association can have on it. Note that
* this is a squishy number since the count can run over this if the user
* sends a large message down .. the fragmented chunks don't count until
@@ -763,7 +724,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_DEBUG_INDATA1 0x01000000
#define SCTP_DEBUG_INDATA2 0x02000000 /* unused */
#define SCTP_DEBUG_INDATA3 0x04000000 /* unused */
-#define SCTP_DEBUG_INDATA4 0x08000000 /* unused */
+#define SCTP_DEBUG_CRCOFFLOAD 0x08000000 /* unused */
#define SCTP_DEBUG_USRREQ1 0x10000000 /* unused */
#define SCTP_DEBUG_USRREQ2 0x20000000 /* unused */
#define SCTP_DEBUG_PEEL1 0x40000000
@@ -783,7 +744,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_INITIAL_CWND 4380
-#define SCTP_DEFAULT_MTU 1500 /* emegency default MTU */
+#define SCTP_DEFAULT_MTU 1500 /* emergency default MTU */
/* amount peer is obligated to have in rwnd or I will abort */
#define SCTP_MIN_RWND 1500
@@ -996,13 +957,6 @@ __FBSDID("$FreeBSD$");
*/
#define SCTP_STACK_VTAG_HASH_SIZE 32
-
-/*
- * If we use the per-endpoint model than we do not have a hash table of
- * entries but instead have a single head pointer and we must crawl through
- * the entire list.
- */
-
/*
* Number of seconds of time wait for a vtag.
*/
diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c
index 7f0e742..3fba39e 100644
--- a/sys/netinet/sctp_crc32.c
+++ b/sys/netinet/sctp_crc32.c
@@ -34,12 +34,16 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
#include <netinet/sctp_os.h>
#include <netinet/sctp_crc32.h>
+#include <netinet/sctp_pcb.h>
-#ifndef SCTP_USE_ADLER32
-
-
+#if !defined(SCTP_WITH_NO_CSUM)
/**
*
* Routine Description:
@@ -80,12 +84,14 @@ __FBSDID("$FreeBSD$");
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o32[256] =
@@ -134,12 +140,14 @@ uint32_t sctp_crc_tableil8_o32[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o40[256] =
@@ -188,12 +196,14 @@ uint32_t sctp_crc_tableil8_o40[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o48[256] =
@@ -242,12 +252,14 @@ uint32_t sctp_crc_tableil8_o48[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o56[256] =
@@ -296,12 +308,14 @@ uint32_t sctp_crc_tableil8_o56[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o64[256] =
@@ -350,12 +364,14 @@ uint32_t sctp_crc_tableil8_o64[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o72[256] =
@@ -404,12 +420,14 @@ uint32_t sctp_crc_tableil8_o72[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o80[256] =
@@ -458,12 +476,14 @@ uint32_t sctp_crc_tableil8_o80[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o88[256] =
@@ -506,6 +526,7 @@ uint32_t sctp_crc_tableil8_o88[256] =
* end of the CRC lookup table crc_tableil8_o88
*/
+
static uint32_t
sctp_crc32c_sb8_64_bit(uint32_t crc,
unsigned char *p_buf,
@@ -662,7 +683,7 @@ uint32_t sctp_crc_c[256] = {
#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
-uint32_t
+static uint32_t
old_update_crc32(uint32_t crc32c,
unsigned char *buffer,
unsigned int length)
@@ -677,7 +698,7 @@ old_update_crc32(uint32_t crc32c,
uint32_t
-sctp_csum_finalize(uint32_t crc32c)
+sctp_finalize_crc32(uint32_t crc32c)
{
uint32_t result;
@@ -709,4 +730,88 @@ sctp_csum_finalize(uint32_t crc32c)
return (crc32c);
}
+#endif /* !defined(SCTP_WITH_NO_CSUM) */
+
+#if defined(SCTP_WITH_NO_CSUM)
+uint32_t
+sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
+{
+ return (0);
+}
+
+#else
+uint32_t
+sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
+{
+ /*
+ * given a mbuf chain with a packetheader offset by 'offset'
+ * pointing at a sctphdr (with csum set to 0) go through the chain
+ * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
+ * has a side bonus as it will calculate the total length of the
+ * mbuf chain. Note: if offset is greater than the total mbuf
+ * length, checksum=1, pktlen=0 is returned (ie. no real error code)
+ */
+ uint32_t base = 0xffffffff;
+ struct mbuf *at;
+
+ at = m;
+ /* find the correct mbuf and offset into mbuf */
+ while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
+ offset -= SCTP_BUF_LEN(at); /* update remaining offset
+ * left */
+ at = SCTP_BUF_NEXT(at);
+ }
+ while (at != NULL) {
+ if ((SCTP_BUF_LEN(at) - offset) > 0) {
+ if ((SCTP_BUF_LEN(at) - offset) < 4) {
+ /* Use old method if less than 4 bytes */
+ base = old_update_crc32(base,
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
+ } else {
+ base = update_crc32(base,
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
+ }
+ /* we only offset once into the first mbuf */
+ }
+ if (offset) {
+ if (offset < (uint32_t) SCTP_BUF_LEN(at))
+ offset = 0;
+ else
+ offset -= SCTP_BUF_LEN(at);
+ }
+ at = SCTP_BUF_NEXT(at);
+ }
+ base = sctp_finalize_crc32(base);
+ return (base);
+}
+
#endif
+
+void
+sctp_delayed_cksum(struct mbuf *m)
+{
+ 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);
+ offset += offsetof(struct sctphdr, checksum);
+
+ if (offset + sizeof(uint32_t) > (uint32_t) (m->m_len)) {
+ printf("delayed m_pullup, m->len: %d off: %d p: %d\n",
+ (uint32_t) m->m_len, offset, ip->ip_p);
+ /*
+ * XXX this shouldn't happen, but if it does, the correct
+ * behavior may be to insert the checksum in the appropriate
+ * next mbuf in the chain.
+ */
+ return;
+ }
+ *(uint32_t *) (m->m_data + offset) = checksum;
+}
diff --git a/sys/netinet/sctp_crc32.h b/sys/netinet/sctp_crc32.h
index 88739ed..2c353d2 100644
--- a/sys/netinet/sctp_crc32.h
+++ b/sys/netinet/sctp_crc32.h
@@ -36,16 +36,12 @@ __FBSDID("$FreeBSD$");
#ifndef __crc32c_h__
#define __crc32c_h__
-#ifndef SCTP_USE_ADLER32
-
#if defined(_KERNEL) || defined(__Userspace__)
+uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
+void sctp_delayed_cksum(struct mbuf *);
uint32_t update_crc32(uint32_t, unsigned char *, unsigned int);
-
-uint32_t old_update_crc32(uint32_t, unsigned char *, unsigned int);
-
-uint32_t sctp_csum_finalize(uint32_t);
-
+uint32_t sctp_finalize_crc32(uint32_t);
#endif /* _KERNEL */
-#endif /* !SCTP_USE_ADLER32 */
+
#endif /* __crc32c_h__ */
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index c686fac..2d8a1f2 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_timer.h>
+#include <netinet/sctp_crc32.h>
#include <netinet/udp.h>
@@ -1384,14 +1385,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* FOOBAR */
return (NULL);
}
- /* pre-reserve some space */
-#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
@@ -2504,15 +2497,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
/* FOOBAR */
return (NULL);
}
- /* pre-reserve some space */
-#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
-
/* Set the len */
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
scm = mtod(op_err, struct sctp_stale_cookie_msg *);
@@ -2598,9 +2582,9 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
}
}
}
- if (to == NULL)
+ if (to == NULL) {
return (NULL);
-
+ }
cookie_len -= SCTP_SIGNATURE_SIZE;
if (*stcb == NULL) {
/* this is the "normal" case... get a new TCB */
@@ -5594,7 +5578,6 @@ sctp_input_with_port(i_pak, off, port)
int refcount_up = 0;
int length, mlen, offset;
-
if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
SCTP_RELEASE_PKT(i_pak);
return;
@@ -5642,6 +5625,11 @@ sctp_input_with_port(i_pak, off, port)
}
ip = mtod(m, struct ip *);
}
+ /* validate mbuf chain length with IP payload length */
+ if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
+ SCTP_STAT_INCR(sctps_hdrops);
+ goto bad;
+ }
sh = (struct sctphdr *)((caddr_t)ip + iphlen);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(*sh));
SCTPDBG(SCTP_DEBUG_INPUT1,
@@ -5659,15 +5647,26 @@ sctp_input_with_port(i_pak, off, port)
goto bad;
}
/* validate SCTP checksum */
+ SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+ "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
+ m->m_pkthdr.len,
+ if_name(m->m_pkthdr.rcvif),
+ m->m_pkthdr.csum_flags);
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
+ SCTP_STAT_INCR(sctps_recvhwcrc);
+ goto sctp_skip_csum_4;
+ }
check = sh->checksum; /* save incoming checksum */
if ((check == 0) && (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback)) &&
((ip->ip_src.s_addr == ip->ip_dst.s_addr) ||
(SCTP_IS_IT_LOOPBACK(m)))
) {
+ SCTP_STAT_INCR(sctps_recvnocrc);
goto sctp_skip_csum_4;
}
sh->checksum = 0; /* prepare for calc */
- calc_check = sctp_calculate_sum(m, &mlen, iphlen);
+ calc_check = sctp_calculate_cksum(m, iphlen);
+ SCTP_STAT_INCR(sctps_recvswcrc);
if (calc_check != check) {
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
calc_check, check, m, mlen, iphlen);
@@ -5699,11 +5698,6 @@ sctp_skip_csum_4:
SCTP_STAT_INCR(sctps_hdrops);
goto bad;
}
- /* validate mbuf chain length with IP payload length */
- if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
- SCTP_STAT_INCR(sctps_hdrops);
- goto bad;
- }
/*
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
* IP/SCTP/first chunk header...
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index d0e7a18..fcaf715 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -154,11 +154,8 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
#define MOD_IPSEC ipsec
/* then define the macro(s) that hook into the vimage macros */
-#if defined(__FreeBSD__) && __FreeBSD_version >= 800056
#define MODULE_GLOBAL(__MODULE, __SYMBOL) V_ ## __SYMBOL
-#else
-#define MODULE_GLOBAL(__MODULE, __SYMBOL) (__SYMBOL)
-#endif
+
/*
*
*/
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 9efff50..eac896c 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_indata.h>
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_input.h>
+#include <netinet/sctp_crc32.h>
#include <netinet/udp.h>
#include <machine/in_cksum.h>
@@ -5213,6 +5214,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
int ecn_ok,
struct sctp_tmit_chunk *chk,
int out_of_asoc_ok,
+ uint16_t src_port,
+ uint16_t dest_port,
+ uint32_t v_tag,
uint16_t port,
int so_locked,
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
@@ -5237,7 +5241,6 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
struct mbuf *newm;
struct sctphdr *sctphdr;
int packet_length;
- uint32_t csum;
int ret;
uint32_t vrf_id;
sctp_route_t *ro = NULL;
@@ -5263,51 +5266,27 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
if ((auth != NULL) && (stcb != NULL)) {
sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
}
- /* Calculate the csum and fill in the length of the packet */
- sctphdr = mtod(m, struct sctphdr *);
- if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (stcb) &&
- (to->sa_family == AF_INET) &&
- (stcb->asoc.loopback_scope)) {
- sctphdr->checksum = 0;
- /*
- * This can probably now be taken out since my audit shows
- * no more bad pktlen's coming in. But we will wait a while
- * yet.
- */
- packet_length = sctp_calculate_len(m);
- } else {
- sctphdr->checksum = 0;
- csum = sctp_calculate_sum(m, &packet_length, 0);
- sctphdr->checksum = csum;
- }
-
if (to->sa_family == AF_INET) {
struct ip *ip = NULL;
sctp_route_t iproute;
uint8_t tos_value;
+ int len;
+ len = sizeof(struct ip) + sizeof(struct sctphdr);
if (port) {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
- } else {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1, MT_DATA);
+ len += sizeof(struct udphdr);
}
+ newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
if (newm == NULL) {
sctp_m_freem(m);
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
return (ENOMEM);
}
- if (port) {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip) + sizeof(struct udphdr));
- SCTP_BUF_LEN(newm) = sizeof(struct ip) + sizeof(struct udphdr);
- packet_length += sizeof(struct ip) + sizeof(struct udphdr);
- } else {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip));
- SCTP_BUF_LEN(newm) = sizeof(struct ip);
- packet_length += sizeof(struct ip);
- }
+ SCTP_ALIGN_TO_END(newm, len);
+ SCTP_BUF_LEN(newm) = len;
SCTP_BUF_NEXT(newm) = m;
m = newm;
+ packet_length = sctp_calculate_len(m);
ip = mtod(m, struct ip *);
ip->ip_v = IPVERSION;
ip->ip_hl = (sizeof(struct ip) >> 2);
@@ -5401,12 +5380,21 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
}
}
if (port) {
- udp = (struct udphdr *)(ip + 1);
+ udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip));
udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
udp->uh_dport = port;
udp->uh_ulen = htons(packet_length - sizeof(struct ip));
udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
+ sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+ } else {
+ sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip));
}
+
+ sctphdr->src_port = src_port;
+ sctphdr->dest_port = dest_port;
+ sctphdr->v_tag = v_tag;
+ sctphdr->checksum = 0;
+
/*
* If source address selection fails and we find no route
* then the ip_output should fail as well with a
@@ -5517,7 +5505,25 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
#endif
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
if (port) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
SCTP_ENABLE_UDP_CSUM(o_pak);
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ m->m_pkthdr.csum_flags = CSUM_SCTP;
+ m->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
/* send it out. table id is taken from stcb */
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5591,6 +5597,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
struct sockaddr_in6 lsa6_storage;
int error;
u_short prev_port = 0;
+ int len;
if (net != NULL) {
flowlabel = net->tos_flowlabel;
@@ -5598,27 +5605,21 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
}
+ len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
if (port) {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
- } else {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr), 1, M_DONTWAIT, 1, MT_DATA);
+ len += sizeof(struct udphdr);
}
+ newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
if (newm == NULL) {
sctp_m_freem(m);
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
return (ENOMEM);
}
- if (port) {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
- SCTP_BUF_LEN(newm) = sizeof(struct ip6_hdr) + sizeof(struct udphdr);
- packet_length += sizeof(struct ip6_hdr) + sizeof(struct udphdr);
- } else {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr));
- SCTP_BUF_LEN(newm) = sizeof(struct ip6_hdr);
- packet_length += sizeof(struct ip6_hdr);
- }
+ SCTP_ALIGN_TO_END(newm, len);
+ SCTP_BUF_LEN(newm) = len;
SCTP_BUF_NEXT(newm) = m;
m = newm;
+ packet_length = sctp_calculate_len(m);
ip6h = mtod(m, struct ip6_hdr *);
/*
@@ -5763,12 +5764,21 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
ip6h->ip6_src = lsa6->sin6_addr;
if (port) {
- udp = (struct udphdr *)(ip6h + 1);
+ udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
udp->uh_dport = port;
udp->uh_ulen = htons(packet_length - sizeof(struct ip6_hdr));
udp->uh_sum = 0;
+ sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+ } else {
+ sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
}
+
+ sctphdr->src_port = src_port;
+ sctphdr->dest_port = dest_port;
+ sctphdr->v_tag = v_tag;
+ sctphdr->checksum = 0;
+
/*
* We set the hop limit now since there is a good chance
* that our ro pointer is now filled
@@ -5805,9 +5815,27 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
#endif
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
if (port) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sctphdr->checksum = sctp_calculate_cksum(m, 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), packet_length - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ m->m_pkthdr.csum_flags = CSUM_SCTP;
+ m->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
/* send it out. table id is taken from stcb */
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5905,7 +5933,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
{
struct mbuf *m, *m_at, *mp_last;
struct sctp_nets *net;
- struct sctp_init_msg *initm;
+ struct sctp_init_chunk *init;
struct sctp_supported_addr_param *sup_addr;
struct sctp_adaptation_layer_indication *ali;
struct sctp_ecn_supported_param *ecn;
@@ -5961,7 +5989,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - mbuf?\n");
return;
}
- SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
/*
* assume peer supports asconf in order to be able to queue local
* address changes while an INIT is in flight and before the assoc
@@ -5969,28 +5997,24 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
*/
stcb->asoc.peer_supports_asconf = 1;
/* Now lets put the SCTP header in place */
- initm = mtod(m, struct sctp_init_msg *);
- initm->sh.src_port = inp->sctp_lport;
- initm->sh.dest_port = stcb->rport;
- initm->sh.v_tag = 0;
- initm->sh.checksum = 0; /* calculate later */
+ init = mtod(m, struct sctp_init_chunk *);
/* now the chunk header */
- initm->msg.ch.chunk_type = SCTP_INITIATION;
- initm->msg.ch.chunk_flags = 0;
+ init->ch.chunk_type = SCTP_INITIATION;
+ init->ch.chunk_flags = 0;
/* fill in later from mbuf we build */
- initm->msg.ch.chunk_length = 0;
+ init->ch.chunk_length = 0;
/* place in my tag */
- initm->msg.init.initiate_tag = htonl(stcb->asoc.my_vtag);
+ init->init.initiate_tag = htonl(stcb->asoc.my_vtag);
/* set up some of the credits. */
- initm->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
+ init->init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
SCTP_MINIMAL_RWND));
- initm->msg.init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
- initm->msg.init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
- initm->msg.init.initial_tsn = htonl(stcb->asoc.init_seq_number);
+ init->init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
+ init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
+ init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
/* now the address restriction */
- sup_addr = (struct sctp_supported_addr_param *)((caddr_t)initm +
- sizeof(*initm));
+ sup_addr = (struct sctp_supported_addr_param *)((caddr_t)init +
+ sizeof(*init));
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
#ifdef INET6
/* we support 2 types: IPv6/IPv4 */
@@ -6004,7 +6028,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
sup_addr->addr_type[1] = htons(0); /* this is the padding */
#endif
SCTP_BUF_LEN(m) += sizeof(*sup_addr) + sizeof(uint16_t);
-
/* adaptation layer indication parameter */
ali = (struct sctp_adaptation_layer_indication *)((caddr_t)sup_addr + sizeof(*sup_addr) + sizeof(uint16_t));
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
@@ -6013,6 +6036,16 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
SCTP_BUF_LEN(m) += sizeof(*ali);
ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
+ if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
+ /* Add NAT friendly parameter */
+ struct sctp_paramhdr *ph;
+
+ ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
+ ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
+ ph->param_length = htons(sizeof(struct sctp_paramhdr));
+ SCTP_BUF_LEN(m) += sizeof(struct sctp_paramhdr);
+ ecn = (struct sctp_ecn_supported_param *)((caddr_t)ph + sizeof(*ph));
+ }
/* now any cookie time extensions */
if (stcb->asoc.cookie_preserve_req) {
struct sctp_cookie_perserve_param *cookie_preserve;
@@ -6052,19 +6085,22 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
- if (!SCTP_BASE_SYSCTL(sctp_auth_disable))
+ if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
+ }
/*
* EY if the initiator supports nr_sacks, need to report that to
* responder in INIT chunk
*/
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
+ if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)) {
pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
+ }
p_len = sizeof(*pr_supported) + num_ext;
pr_supported->ph.param_length = htons(p_len);
bzero((caddr_t)pr_supported + p_len, SCTP_SIZE32(p_len) - p_len);
SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
+
/* ECN nonce: And now tell the peer we support ECN nonce */
if (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) {
ecn_nonce = (struct sctp_ecn_nonce_supported_param *)
@@ -6073,15 +6109,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce));
SCTP_BUF_LEN(m) += sizeof(*ecn_nonce);
}
- if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
- /* Add NAT friendly parameter */
- struct sctp_paramhdr *ph;
-
- ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
- ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
- ph->param_length = htons(sizeof(struct sctp_paramhdr));
- SCTP_BUF_LEN(m) += sizeof(sizeof(struct sctp_paramhdr));
- }
/* add authentication parameters */
if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
struct sctp_auth_random *randp;
@@ -6160,7 +6187,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
mp_last = m_at;
p_len += SCTP_BUF_LEN(m_at);
}
- initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr)));
+ init->ch.chunk_length = htons(p_len);
/*
* We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
* here since the timer will drive a retranmission.
@@ -6185,7 +6212,9 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - calls lowlevel_output\n");
ret = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
- m, 0, NULL, 0, 0, 0, NULL, 0, net->port, so_locked, NULL);
+ m, 0, NULL, 0, 0, 0, NULL, 0,
+ inp->sctp_lport, stcb->rport, htonl(0),
+ net->port, so_locked, NULL);
SCTPDBG(SCTP_DEBUG_OUTPUT4, "lowlevel_output - %d\n", ret);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, net);
@@ -6711,7 +6740,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
struct sctp_association *asoc;
struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last;
- struct sctp_init_msg *initackm_out;
+ struct sctp_init_ack_chunk *initack;
struct sctp_adaptation_layer_indication *ali;
struct sctp_ecn_supported_param *ecn;
struct sctp_prsctp_supported_param *prsctp;
@@ -6776,7 +6805,7 @@ do_a_abort:
sctp_m_freem(op_err);
return;
}
- SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
/* the time I built cookie */
(void)SCTP_GETTIME_TIMEVAL(&stc.time_entered);
@@ -7059,29 +7088,25 @@ do_a_abort:
}
}
/* Now lets put the SCTP header in place */
- initackm_out = mtod(m, struct sctp_init_msg *);
- initackm_out->sh.src_port = inp->sctp_lport;
- initackm_out->sh.dest_port = sh->src_port;
- initackm_out->sh.v_tag = init_chk->init.initiate_tag;
+ initack = mtod(m, struct sctp_init_ack_chunk *);
/* Save it off for quick ref */
stc.peers_vtag = init_chk->init.initiate_tag;
- initackm_out->sh.checksum = 0; /* calculate later */
/* who are we */
memcpy(stc.identification, SCTP_VERSION_STRING,
min(strlen(SCTP_VERSION_STRING), sizeof(stc.identification)));
/* now the chunk header */
- initackm_out->msg.ch.chunk_type = SCTP_INITIATION_ACK;
- initackm_out->msg.ch.chunk_flags = 0;
+ initack->ch.chunk_type = SCTP_INITIATION_ACK;
+ initack->ch.chunk_flags = 0;
/* fill in later from mbuf we build */
- initackm_out->msg.ch.chunk_length = 0;
+ initack->ch.chunk_length = 0;
/* place in my tag */
if ((asoc != NULL) &&
((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_INUSE) ||
(SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED))) {
/* re-use the v-tags and init-seq here */
- initackm_out->msg.init.initiate_tag = htonl(asoc->my_vtag);
- initackm_out->msg.init.initial_tsn = htonl(asoc->init_seq_number);
+ initack->init.initiate_tag = htonl(asoc->my_vtag);
+ initack->init.initial_tsn = htonl(asoc->init_seq_number);
} else {
uint32_t vtag, itsn;
@@ -7101,17 +7126,17 @@ do_a_abort:
*/
goto new_tag;
}
- initackm_out->msg.init.initiate_tag = htonl(vtag);
+ initack->init.initiate_tag = htonl(vtag);
/* get a TSN to use too */
itsn = sctp_select_initial_TSN(&inp->sctp_ep);
- initackm_out->msg.init.initial_tsn = htonl(itsn);
+ initack->init.initial_tsn = htonl(itsn);
SCTP_TCB_LOCK(stcb);
atomic_add_int(&asoc->refcnt, -1);
} else {
vtag = sctp_select_a_tag(inp, inp->sctp_lport, sh->src_port, 1);
- initackm_out->msg.init.initiate_tag = htonl(vtag);
+ initack->init.initiate_tag = htonl(vtag);
/* get a TSN to use too */
- initackm_out->msg.init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
+ initack->init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
}
if (hold_inp_lock) {
SCTP_INP_RLOCK(inp);
@@ -7119,7 +7144,7 @@ do_a_abort:
}
}
/* save away my tag to */
- stc.my_vtag = initackm_out->msg.init.initiate_tag;
+ stc.my_vtag = initack->init.initiate_tag;
/* set up some of the credits. */
so = inp->sctp_socket;
@@ -7128,7 +7153,7 @@ do_a_abort:
sctp_m_freem(m);
return;
} else {
- initackm_out->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(so), SCTP_MINIMAL_RWND));
+ initack->init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(so), SCTP_MINIMAL_RWND));
}
/* set what I want */
his_limit = ntohs(init_chk->init.num_inbound_streams);
@@ -7144,17 +7169,17 @@ do_a_abort:
}
if (his_limit < i_want) {
/* I Want more :< */
- initackm_out->msg.init.num_outbound_streams = init_chk->init.num_inbound_streams;
+ initack->init.num_outbound_streams = init_chk->init.num_inbound_streams;
} else {
/* I can have what I want :> */
- initackm_out->msg.init.num_outbound_streams = htons(i_want);
+ initack->init.num_outbound_streams = htons(i_want);
}
/* tell him his limt. */
- initackm_out->msg.init.num_inbound_streams =
+ initack->init.num_inbound_streams =
htons(inp->sctp_ep.max_open_streams_intome);
/* adaptation layer indication parameter */
- ali = (struct sctp_adaptation_layer_indication *)((caddr_t)initackm_out + sizeof(*initackm_out));
+ ali = (struct sctp_adaptation_layer_indication *)((caddr_t)initack + sizeof(*initack));
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(sizeof(*ali));
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
@@ -7183,7 +7208,7 @@ do_a_abort:
ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
- SCTP_BUF_LEN(m) += sizeof(sizeof(struct sctp_paramhdr));
+ SCTP_BUF_LEN(m) += sizeof(struct sctp_paramhdr);
}
/* And now tell the peer we do all the extensions */
pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
@@ -7317,8 +7342,7 @@ do_a_abort:
}
/* Now we must build a cookie */
- m_cookie = sctp_add_cookie(inp, init_pkt, offset, m,
- sizeof(struct sctphdr), &stc, &signature);
+ m_cookie = sctp_add_cookie(inp, init_pkt, offset, m, 0, &stc, &signature);
if (m_cookie == NULL) {
/* memory problem */
sctp_m_freem(m);
@@ -7339,7 +7363,7 @@ do_a_abort:
* Place in the size, but we don't include the last pad (if any) in
* the INIT-ACK.
*/
- initackm_out->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr)));
+ initack->ch.chunk_length = htons(p_len);
/*
* Time to sign the cookie, we don't sign over the cookie signature
@@ -7370,11 +7394,12 @@ do_a_abort:
over_addr = &store1;
} else {
over_addr = NULL;
-
}
(void)sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, NULL, 0, 0,
- 0, NULL, 0, port, SCTP_SO_NOT_LOCKED, over_addr);
+ 0, NULL, 0,
+ inp->sctp_lport, sh->src_port, init_chk->init.initiate_tag,
+ port, SCTP_SO_NOT_LOCKED, over_addr);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
}
@@ -9164,7 +9189,6 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
struct sctp_nets *net;
struct mbuf *outchain, *endoutchain;
struct sctp_tmit_chunk *chk, *nchk;
- struct sctphdr *shdr;
/* temp arrays for unlinking */
struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING];
@@ -9177,7 +9201,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
int tsns_sent = 0;
uint32_t auth_offset = 0;
struct sctp_auth_chunk *auth = NULL;
- uint16_t auth_keyid = 0;
+ uint16_t auth_keyid;
+ int override_ok = 1;
int data_auth_reqd = 0;
/*
@@ -9189,6 +9214,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
*num_out = 0;
cwnd_full_ind = 0;
+ auth_keyid = stcb->asoc.authinfo.active_keyid;
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
(asoc->state & SCTP_STATE_SHUTDOWN_RECEIVED) ||
@@ -9532,24 +9558,14 @@ again_one_more_time:
* it is used to do appropriate
* source address selection.
*/
- SCTP_BUF_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
- if (outchain == NULL) {
- /* no memory */
- SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
- error = ENOBUFS;
- *reason_code = 7;
- continue;
- }
- shdr = mtod(outchain, struct sctphdr *);
- shdr->src_port = inp->sctp_lport;
- shdr->dest_port = stcb->rport;
- shdr->v_tag = htonl(stcb->asoc.peer_vtag);
- shdr->checksum = 0;
- auth_offset += sizeof(struct sctphdr);
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
- outchain, auth_offset, auth, stcb->asoc.authinfo.active_keyid,
- no_fragmentflg, 0, NULL, asconf, net->port, so_locked, NULL))) {
+ outchain, auth_offset, auth,
+ stcb->asoc.authinfo.active_keyid,
+ no_fragmentflg, 0, NULL, asconf,
+ inp->sctp_lport, stcb->rport,
+ htonl(stcb->asoc.peer_vtag),
+ net->port, so_locked, NULL))) {
if (error == ENOBUFS) {
asoc->ifp_had_enobuf = 1;
SCTP_STAT_INCR(sctps_lowlevelerr);
@@ -9773,24 +9789,15 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net);
cookie = 0;
}
- SCTP_BUF_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
- if (outchain == NULL) {
- /* no memory */
- SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
- error = ENOBUFS;
- goto error_out_again;
- }
- shdr = mtod(outchain, struct sctphdr *);
- shdr->src_port = inp->sctp_lport;
- shdr->dest_port = stcb->rport;
- shdr->v_tag = htonl(stcb->asoc.peer_vtag);
- shdr->checksum = 0;
- auth_offset += sizeof(struct sctphdr);
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
outchain,
- auth_offset, auth, stcb->asoc.authinfo.active_keyid,
- no_fragmentflg, 0, NULL, asconf, net->port, so_locked, NULL))) {
+ auth_offset, auth,
+ stcb->asoc.authinfo.active_keyid,
+ no_fragmentflg, 0, NULL, asconf,
+ inp->sctp_lport, stcb->rport,
+ htonl(stcb->asoc.peer_vtag),
+ net->port, so_locked, NULL))) {
if (error == ENOBUFS) {
asoc->ifp_had_enobuf = 1;
SCTP_STAT_INCR(sctps_lowlevelerr);
@@ -9798,7 +9805,6 @@ again_one_more_time:
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- error_out_again:
/* error, could not output */
if (hbflag) {
if (*now_filled == 0) {
@@ -9948,8 +9954,16 @@ again_one_more_time:
&auth_offset,
stcb,
SCTP_DATA);
+ auth_keyid = chk->auth_keyid;
+ override_ok = 0;
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
+ } else if (override_ok) {
+ /*
+ * use this data's
+ * keyid
+ */
auth_keyid = chk->auth_keyid;
+ override_ok = 0;
} else if (auth_keyid != chk->auth_keyid) {
/*
* different keyid,
@@ -10072,25 +10086,6 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
}
/* Now send it, if there is anything to send :> */
- SCTP_BUF_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
- if (outchain == NULL) {
- /* out of mbufs */
- SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
- error = ENOBUFS;
- goto errored_send;
- }
- shdr = mtod(outchain, struct sctphdr *);
- shdr->src_port = inp->sctp_lport;
- shdr->dest_port = stcb->rport;
- shdr->v_tag = htonl(stcb->asoc.peer_vtag);
- shdr->checksum = 0;
- auth_offset += sizeof(struct sctphdr);
- /*
- * if data auth isn't needed, use the assoc active
- * key
- */
- if (!data_auth_reqd)
- auth_keyid = stcb->asoc.authinfo.active_keyid;
if ((error = sctp_lowlevel_chunk_output(inp,
stcb,
net,
@@ -10102,7 +10097,10 @@ again_one_more_time:
no_fragmentflg,
bundle_at,
data_list[0],
- asconf, net->port, so_locked, NULL))) {
+ asconf,
+ inp->sctp_lport, stcb->rport,
+ htonl(stcb->asoc.peer_vtag),
+ net->port, so_locked, NULL))) {
/* error, we could not output */
if (error == ENOBUFS) {
SCTP_STAT_INCR(sctps_lowlevelerr);
@@ -10111,7 +10109,6 @@ again_one_more_time:
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- errored_send:
SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (hbflag) {
if (*now_filled == 0) {
@@ -10727,7 +10724,6 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING];
struct sctp_tmit_chunk *chk, *fwd;
struct mbuf *m, *endofchain;
- struct sctphdr *shdr;
struct sctp_nets *net = NULL;
uint32_t tsns_sent = 0;
int no_fragmentflg, bundle_at, cnt_thru;
@@ -10735,7 +10731,8 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
int error, i, one_chunk, fwd_tsn, ctl_cnt, tmr_started;
struct sctp_auth_chunk *auth = NULL;
uint32_t auth_offset = 0;
- uint16_t auth_keyid = 0;
+ uint16_t auth_keyid;
+ int override_ok = 1;
int data_auth_reqd = 0;
uint32_t dmtu = 0;
@@ -10746,6 +10743,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
*cnt_out = 0;
fwd = NULL;
endofchain = m = NULL;
+ auth_keyid = stcb->asoc.authinfo.active_keyid;
#ifdef SCTP_AUDITING_ENABLED
sctp_audit_log(0xC3, 1);
#endif
@@ -10803,24 +10801,13 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, chk->whoTo);
} else if (chk->rec.chunk_id.id == SCTP_ASCONF)
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, chk->whoTo);
-
- SCTP_BUF_PREPEND(m, sizeof(struct sctphdr), M_DONTWAIT);
- if (m == NULL) {
- SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
- return (ENOBUFS);
- }
- shdr = mtod(m, struct sctphdr *);
- shdr->src_port = inp->sctp_lport;
- shdr->dest_port = stcb->rport;
- shdr->v_tag = htonl(stcb->asoc.peer_vtag);
- shdr->checksum = 0;
- auth_offset += sizeof(struct sctphdr);
chk->snd_count++; /* update our count */
-
if ((error = sctp_lowlevel_chunk_output(inp, stcb, chk->whoTo,
(struct sockaddr *)&chk->whoTo->ro._l_addr, m,
auth_offset, auth, stcb->asoc.authinfo.active_keyid,
- no_fragmentflg, 0, NULL, 0, chk->whoTo->port, so_locked, NULL))) {
+ no_fragmentflg, 0, NULL, 0,
+ inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
+ chk->whoTo->port, so_locked, NULL))) {
SCTP_STAT_INCR(sctps_lowlevelerr);
return (error);
}
@@ -10954,8 +10941,12 @@ one_chunk_around:
&auth_offset,
stcb,
SCTP_DATA);
+ auth_keyid = chk->auth_keyid;
+ override_ok = 0;
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
+ } else if (override_ok) {
auth_keyid = chk->auth_keyid;
+ override_ok = 0;
} else if (chk->auth_keyid != auth_keyid) {
/* different keyid, so done bundling */
break;
@@ -11010,8 +11001,12 @@ one_chunk_around:
&auth_offset,
stcb,
SCTP_DATA);
+ auth_keyid = fwd->auth_keyid;
+ override_ok = 0;
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
+ } else if (override_ok) {
auth_keyid = fwd->auth_keyid;
+ override_ok = 0;
} else if (fwd->auth_keyid != auth_keyid) {
/*
* different keyid,
@@ -11059,28 +11054,13 @@ one_chunk_around:
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
tmr_started = 1;
}
- SCTP_BUF_PREPEND(m, sizeof(struct sctphdr), M_DONTWAIT);
- if (m == NULL) {
- SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOBUFS);
- return (ENOBUFS);
- }
- shdr = mtod(m, struct sctphdr *);
- shdr->src_port = inp->sctp_lport;
- shdr->dest_port = stcb->rport;
- shdr->v_tag = htonl(stcb->asoc.peer_vtag);
- shdr->checksum = 0;
- auth_offset += sizeof(struct sctphdr);
- /*
- * if doing DATA auth, use the data chunk(s) key id,
- * otherwise use the assoc's active key id
- */
- if (!data_auth_reqd)
- auth_keyid = stcb->asoc.authinfo.active_keyid;
/* Now lets send it, if there is anything to send :> */
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr, m,
auth_offset, auth, auth_keyid,
- no_fragmentflg, 0, NULL, 0, net->port, so_locked, NULL))) {
+ no_fragmentflg, 0, NULL, 0,
+ inp->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
+ net->port, so_locked, NULL))) {
/* error, we could not output */
SCTP_STAT_INCR(sctps_lowlevelerr);
return (error);
@@ -12401,7 +12381,6 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
int sz;
uint32_t auth_offset = 0;
struct sctp_auth_chunk *auth = NULL;
- struct sctphdr *shdr;
/*-
* Add an AUTH chunk, if chunk requires it and save the offset into
@@ -12449,23 +12428,12 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
abort->ch.chunk_flags = 0;
abort->ch.chunk_length = htons(sizeof(*abort) + sz);
- /* prepend and fill in the SCTP header */
- SCTP_BUF_PREPEND(m_out, sizeof(struct sctphdr), M_DONTWAIT);
- if (m_out == NULL) {
- /* TSNH: no memory */
- return;
- }
- shdr = mtod(m_out, struct sctphdr *);
- shdr->src_port = stcb->sctp_ep->sctp_lport;
- shdr->dest_port = stcb->rport;
- shdr->v_tag = htonl(stcb->asoc.peer_vtag);
- shdr->checksum = 0;
- auth_offset += sizeof(struct sctphdr);
-
(void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb,
stcb->asoc.primary_destination,
(struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr,
- m_out, auth_offset, auth, stcb->asoc.authinfo.active_keyid, 1, 0, NULL, 0, stcb->asoc.primary_destination->port, so_locked, NULL);
+ m_out, auth_offset, auth, stcb->asoc.authinfo.active_keyid, 1, 0, NULL, 0,
+ stcb->sctp_ep->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
+ stcb->asoc.primary_destination->port, so_locked, NULL);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
}
@@ -12475,26 +12443,24 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
{
/* formulate and SEND a SHUTDOWN-COMPLETE */
struct mbuf *m_shutdown_comp;
- struct sctp_shutdown_complete_msg *comp_cp;
+ struct sctp_shutdown_complete_chunk *shutdown_complete;
- m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_complete_msg), 0, M_DONTWAIT, 1, MT_HEADER);
+ m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_shutdown_comp == NULL) {
/* no mbuf's */
return;
}
- comp_cp = mtod(m_shutdown_comp, struct sctp_shutdown_complete_msg *);
- comp_cp->shut_cmp.ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
- comp_cp->shut_cmp.ch.chunk_flags = 0;
- comp_cp->shut_cmp.ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
- comp_cp->sh.src_port = stcb->sctp_ep->sctp_lport;
- comp_cp->sh.dest_port = stcb->rport;
- comp_cp->sh.v_tag = htonl(stcb->asoc.peer_vtag);
- comp_cp->sh.checksum = 0;
-
- SCTP_BUF_LEN(m_shutdown_comp) = sizeof(struct sctp_shutdown_complete_msg);
+ shutdown_complete = mtod(m_shutdown_comp, struct sctp_shutdown_complete_chunk *);
+ shutdown_complete->ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
+ shutdown_complete->ch.chunk_flags = 0;
+ shutdown_complete->ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
+ SCTP_BUF_LEN(m_shutdown_comp) = sizeof(struct sctp_shutdown_complete_chunk);
(void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
- m_shutdown_comp, 0, NULL, 0, 1, 0, NULL, 0, net->port, SCTP_SO_NOT_LOCKED, NULL);
+ m_shutdown_comp, 0, NULL, 0, 1, 0, NULL, 0,
+ stcb->sctp_ep->sctp_lport, stcb->rport,
+ htonl(stcb->asoc.peer_vtag),
+ net->port, SCTP_SO_NOT_LOCKED, NULL);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
return;
}
@@ -12532,10 +12498,11 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
if (port) {
len += sizeof(struct udphdr);
}
- mout = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
+ mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_DONTWAIT, 1, MT_DATA);
if (mout == NULL) {
return;
}
+ SCTP_BUF_RESV_UF(mout, max_linkhdr);
SCTP_BUF_LEN(mout) = len;
SCTP_BUF_NEXT(mout) = NULL;
iph_out = NULL;
@@ -12596,6 +12563,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
#endif /* INET6 */
default:
/* Currently not supported. */
+ sctp_m_freem(mout);
return;
}
if (port) {
@@ -12621,8 +12589,6 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
comp_cp->shut_cmp.ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
comp_cp->shut_cmp.ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
- /* add checksum */
- comp_cp->sh.checksum = sctp_calculate_sum(mout, NULL, offset_out);
if (iph_out != NULL) {
sctp_route_t ro;
int ret;
@@ -12636,10 +12602,16 @@ 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
- SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
if (port) {
- SCTP_ENABLE_UDP_CSUM(o_pak);
+ comp_cp->sh.checksum = sctp_calculate_cksum(mout, offset_out);
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ SCTP_ENABLE_UDP_CSUM(mout);
+ } else {
+ mout->m_pkthdr.csum_flags = CSUM_SCTP;
+ mout->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
}
+ SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
/* out it goes */
SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
@@ -12660,6 +12632,8 @@ 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),
@@ -13493,17 +13467,22 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
break;
#endif
default:
+ if (err_cause) {
+ sctp_m_freem(err_cause);
+ }
return;
}
if (port) {
len += sizeof(struct udphdr);
}
- mout = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
+ mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_DONTWAIT, 1, MT_DATA);
if (mout == NULL) {
- if (err_cause)
+ if (err_cause) {
sctp_m_freem(err_cause);
+ }
return;
}
+ SCTP_BUF_RESV_UF(mout, max_linkhdr);
SCTP_BUF_LEN(mout) = len;
SCTP_BUF_NEXT(mout) = err_cause;
iph_out = NULL;
@@ -13556,8 +13535,6 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
#endif /* INET6 */
default:
/* Currently not supported */
- if (err_cause)
- sctp_m_freem(err_cause);
sctp_m_freem(mout);
return;
}
@@ -13608,8 +13585,6 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
abm->msg.ch.chunk_length = htons(sizeof(abm->msg.ch));
}
- /* add checksum */
- abm->sh.checksum = sctp_calculate_sum(mout, NULL, iphlen_out);
if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
/* no mbuf's */
sctp_m_freem(mout);
@@ -13637,7 +13612,13 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
#endif
SCTP_ATTACH_CHAIN(o_pak, mout, len);
if (port) {
+ abm->sh.checksum = sctp_calculate_cksum(mout, iphlen_out);
+ SCTP_STAT_INCR(sctps_sendswcrc);
SCTP_ENABLE_UDP_CSUM(o_pak);
+ } else {
+ mout->m_pkthdr.csum_flags = CSUM_SCTP;
+ mout->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
}
SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
@@ -13664,6 +13645,8 @@ 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 ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
@@ -13679,6 +13662,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
#endif
SCTP_STAT_INCR(sctps_sendpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
}
void
@@ -13686,211 +13670,219 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
uint32_t vrf_id, uint16_t port)
{
struct mbuf *o_pak;
- struct sctphdr *ihdr;
- int retcode;
- struct sctphdr *ohdr;
- struct sctp_chunkhdr *ophdr;
- struct ip *iph;
+ struct sctphdr *sh, *sh_out;
+ struct sctp_chunkhdr *ch;
+ struct ip *iph, *iph_out;
struct udphdr *udp = NULL;
struct mbuf *mout;
#ifdef INET6
-#ifdef SCTP_DEBUG
- struct sockaddr_in6 lsa6, fsa6;
+ struct ip6_hdr *ip6, *ip6_out;
#endif
-#endif
- uint32_t val;
- struct mbuf *at;
- int len;
+ int iphlen_out, len;
iph = mtod(m, struct ip *);
- ihdr = (struct sctphdr *)((caddr_t)iph + iphlen);
-
- SCTP_BUF_PREPEND(scm, (sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)), M_DONTWAIT);
- if (scm == NULL) {
- /* can't send because we can't add a mbuf */
+ sh = (struct sctphdr *)((caddr_t)iph + iphlen);
+ switch (iph->ip_v) {
+ case IPVERSION:
+ len = (sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr));
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ len = (sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr));
+ break;
+#endif
+ default:
+ if (scm) {
+ sctp_m_freem(scm);
+ }
return;
}
- ohdr = mtod(scm, struct sctphdr *);
- ohdr->src_port = ihdr->dest_port;
- ohdr->dest_port = ihdr->src_port;
- ohdr->v_tag = vtag;
- ohdr->checksum = 0;
- ophdr = (struct sctp_chunkhdr *)(ohdr + 1);
- ophdr->chunk_type = SCTP_OPERATION_ERROR;
- ophdr->chunk_flags = 0;
- len = 0;
- at = scm;
- while (at) {
- len += SCTP_BUF_LEN(at);
- at = SCTP_BUF_NEXT(at);
+ if (port) {
+ len += sizeof(struct udphdr);
}
- ophdr->chunk_length = htons(len - sizeof(struct sctphdr));
- if (len % 4) {
- /* need padding */
- uint32_t cpthis = 0;
- int padlen;
-
- padlen = 4 - (len % 4);
- m_copyback(scm, len, padlen, (caddr_t)&cpthis);
- len += padlen;
+ mout = sctp_get_mbuf_for_msg(len + max_linkhdr, 1, M_DONTWAIT, 1, MT_DATA);
+ if (mout == NULL) {
+ if (scm) {
+ sctp_m_freem(scm);
+ }
+ return;
}
- val = sctp_calculate_sum(scm, NULL, 0);
+ SCTP_BUF_RESV_UF(mout, max_linkhdr);
+ SCTP_BUF_LEN(mout) = len;
+ SCTP_BUF_NEXT(mout) = scm;
+ iph_out = NULL;
#ifdef INET6
- if (port) {
- mout = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
- } else {
- mout = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr), 1, M_DONTWAIT, 1, MT_DATA);
+ ip6_out = NULL;
+#endif
+ switch (iph->ip_v) {
+ case IPVERSION:
+ iph_out = mtod(mout, struct ip *);
+
+ /* Fill in the IP header for the ABORT */
+ iph_out->ip_v = IPVERSION;
+ iph_out->ip_hl = (sizeof(struct ip) / 4);
+ iph_out->ip_tos = (u_char)0;
+ iph_out->ip_id = 0;
+ iph_out->ip_off = 0;
+ iph_out->ip_ttl = MAXTTL;
+ if (port) {
+ iph_out->ip_p = IPPROTO_UDP;
+ } else {
+ iph_out->ip_p = IPPROTO_SCTP;
+ }
+ iph_out->ip_src.s_addr = iph->ip_dst.s_addr;
+ iph_out->ip_dst.s_addr = iph->ip_src.s_addr;
+ /* let IP layer calculate this */
+ iph_out->ip_sum = 0;
+
+ iphlen_out = sizeof(struct ip);
+ sh_out = (struct sctphdr *)((caddr_t)iph_out + iphlen_out);
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ ip6 = (struct ip6_hdr *)iph;
+ ip6_out = mtod(mout, struct ip6_hdr *);
+
+ /* Fill in the IP6 header for the ABORT */
+ ip6_out->ip6_flow = ip6->ip6_flow;
+ ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
+ if (port) {
+ ip6_out->ip6_nxt = IPPROTO_UDP;
+ } else {
+ ip6_out->ip6_nxt = IPPROTO_SCTP;
+ }
+ ip6_out->ip6_src = ip6->ip6_dst;
+ ip6_out->ip6_dst = ip6->ip6_src;
+
+ iphlen_out = sizeof(struct ip6_hdr);
+ sh_out = (struct sctphdr *)((caddr_t)ip6_out + iphlen_out);
+ break;
+#endif /* INET6 */
+ default:
+ /* Currently not supported */
+ sctp_m_freem(mout);
+ return;
}
-#else
+
+ udp = (struct udphdr *)sh_out;
if (port) {
- mout = sctp_get_mbuf_for_msg(sizeof(struct ip) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
- } else {
- mout = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1, MT_DATA);
+ udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
+ udp->uh_dport = port;
+ /* set udp->uh_ulen later */
+ udp->uh_sum = 0;
+ iphlen_out += sizeof(struct udphdr);
+ sh_out = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
}
-#endif
- if (mout == NULL) {
- sctp_m_freem(scm);
- return;
+ sh_out->src_port = sh->dest_port;
+ sh_out->dest_port = sh->src_port;
+ sh_out->v_tag = vtag;
+ sh_out->checksum = 0;
+
+ ch = (struct sctp_chunkhdr *)((caddr_t)sh_out + sizeof(struct sctphdr));
+ ch->chunk_type = SCTP_OPERATION_ERROR;
+ ch->chunk_flags = 0;
+
+ if (scm) {
+ struct mbuf *m_tmp = scm;
+ int cause_len = 0;
+
+ /* get length of the err_cause chain */
+ while (m_tmp != NULL) {
+ cause_len += SCTP_BUF_LEN(m_tmp);
+ m_tmp = SCTP_BUF_NEXT(m_tmp);
+ }
+ len = SCTP_BUF_LEN(mout) + cause_len;
+ if (cause_len % 4) {
+ /* need pad at end of chunk */
+ uint32_t cpthis = 0;
+ int padlen;
+
+ padlen = 4 - (len % 4);
+ m_copyback(mout, len, padlen, (caddr_t)&cpthis);
+ len += padlen;
+ }
+ ch->chunk_length = htons(sizeof(struct sctp_chunkhdr) + cause_len);
+ } else {
+ len = SCTP_BUF_LEN(mout);
+ ch->chunk_length = htons(sizeof(struct sctp_chunkhdr));
}
- SCTP_BUF_NEXT(mout) = scm;
+
if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
+ /* no mbuf's */
sctp_m_freem(mout);
return;
}
- ohdr->checksum = val;
- switch (iph->ip_v) {
- case IPVERSION:
- {
- /* V4 */
- struct ip *out;
- sctp_route_t ro;
- struct sctp_tcb *stcb = NULL;
-
- SCTP_BUF_LEN(mout) = sizeof(struct ip);
- len += sizeof(struct ip);
- if (port) {
- SCTP_BUF_LEN(mout) += sizeof(struct udphdr);
- len += sizeof(struct udphdr);
- }
- bzero(&ro, sizeof ro);
- out = mtod(mout, struct ip *);
- out->ip_v = iph->ip_v;
- out->ip_hl = (sizeof(struct ip) / 4);
- out->ip_tos = iph->ip_tos;
- out->ip_id = iph->ip_id;
- out->ip_off = 0;
- out->ip_ttl = MAXTTL;
- if (port) {
- out->ip_p = IPPROTO_UDP;
- } else {
- out->ip_p = IPPROTO_SCTP;
- }
- out->ip_sum = 0;
- out->ip_src = iph->ip_dst;
- out->ip_dst = iph->ip_src;
- out->ip_len = len;
- if (port) {
- udp = (struct udphdr *)(out + 1);
- udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
- udp->uh_dport = port;
- udp->uh_ulen = htons(len - sizeof(struct ip));
- udp->uh_sum = in_pseudo(out->ip_src.s_addr, out->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
- }
+ if (iph_out != NULL) {
+ sctp_route_t ro;
+ struct sctp_tcb *stcb = NULL;
+ int ret;
+
+ /* zap the stack pointer to the route */
+ bzero(&ro, sizeof ro);
+ if (port) {
+ udp->uh_ulen = htons(len - sizeof(struct ip));
+ udp->uh_sum = in_pseudo(iph_out->ip_src.s_addr, iph_out->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
+ }
+ /* set IPv4 length */
+ iph_out->ip_len = len;
+ /* out it goes */
#ifdef SCTP_PACKET_LOGGING
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
- sctp_packet_log(mout, len);
+ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
+ sctp_packet_log(mout, len);
#endif
- SCTP_ATTACH_CHAIN(o_pak, mout, len);
- if (port) {
- SCTP_ENABLE_UDP_CSUM(o_pak);
- }
- SCTP_IP_OUTPUT(retcode, o_pak, &ro, stcb, vrf_id);
-
- SCTP_STAT_INCR(sctps_sendpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
- /* Free the route if we got one back */
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
- break;
+ SCTP_ATTACH_CHAIN(o_pak, mout, len);
+ if (port) {
+ sh_out->checksum = sctp_calculate_cksum(mout, iphlen_out);
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ SCTP_ENABLE_UDP_CSUM(o_pak);
+ } else {
+ mout->m_pkthdr.csum_flags = CSUM_SCTP;
+ mout->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
}
+ SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id);
+
+ /* Free the route if we got one back */
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt);
+ }
#ifdef INET6
- case IPV6_VERSION >> 4:
- {
- /* V6 */
- struct route_in6 ro;
- int ret;
- struct sctp_tcb *stcb = NULL;
- struct ifnet *ifp = NULL;
- struct ip6_hdr *out6, *in6;
-
- SCTP_BUF_LEN(mout) = sizeof(struct ip6_hdr);
- len += sizeof(struct ip6_hdr);
- bzero(&ro, sizeof ro);
- if (port) {
- SCTP_BUF_LEN(mout) += sizeof(struct udphdr);
- len += sizeof(struct udphdr);
- }
- in6 = mtod(m, struct ip6_hdr *);
- out6 = mtod(mout, struct ip6_hdr *);
- out6->ip6_flow = in6->ip6_flow;
- out6->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
- if (port) {
- out6->ip6_nxt = IPPROTO_UDP;
- } else {
- out6->ip6_nxt = IPPROTO_SCTP;
- }
- out6->ip6_src = in6->ip6_dst;
- out6->ip6_dst = in6->ip6_src;
- out6->ip6_plen = len - sizeof(struct ip6_hdr);
- if (port) {
- udp = (struct udphdr *)(out6 + 1);
- udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
- udp->uh_dport = port;
- udp->uh_ulen = htons(len - sizeof(struct ip6_hdr));
- udp->uh_sum = 0;
- }
-#ifdef SCTP_DEBUG
- bzero(&lsa6, sizeof(lsa6));
- lsa6.sin6_len = sizeof(lsa6);
- lsa6.sin6_family = AF_INET6;
- lsa6.sin6_addr = out6->ip6_src;
- bzero(&fsa6, sizeof(fsa6));
- fsa6.sin6_len = sizeof(fsa6);
- fsa6.sin6_family = AF_INET6;
- fsa6.sin6_addr = out6->ip6_dst;
-#endif
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "sctp_operr_to calling ipv6 output:\n");
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "src: ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&lsa6);
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "dst ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&fsa6);
+ if (ip6_out != NULL) {
+ struct route_in6 ro;
+ int ret;
+ struct sctp_tcb *stcb = NULL;
+ struct ifnet *ifp = NULL;
+ /* zap the stack pointer to the route */
+ bzero(&ro, sizeof(ro));
+ if (port) {
+ udp->uh_ulen = htons(len - sizeof(struct ip6_hdr));
+ }
+ ip6_out->ip6_plen = len - sizeof(*ip6_out);
#ifdef SCTP_PACKET_LOGGING
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
- sctp_packet_log(mout, len);
+ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
+ sctp_packet_log(mout, len);
#endif
- SCTP_ATTACH_CHAIN(o_pak, mout, len);
- if (port) {
- if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
- udp->uh_sum = 0xffff;
- }
+ sh_out->checksum = sctp_calculate_cksum(mout, iphlen_out);
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ SCTP_ATTACH_CHAIN(o_pak, mout, len);
+ if (port) {
+ if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr))) == 0) {
+ udp->uh_sum = 0xffff;
}
- SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
-
- SCTP_STAT_INCR(sctps_sendpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
- /* Free the route if we got one back */
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
- break;
}
-#endif /* INET6 */
- default:
- /* TSNH */
- break;
+ SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
+
+ /* Free the route if we got one back */
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt);
}
+#endif
+ SCTP_STAT_INCR(sctps_sendpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
}
static struct mbuf *
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 5f05dcd..291509e 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -2504,7 +2504,9 @@ sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
/* Pull the tcb from the old association */
LIST_REMOVE(stcb, sctp_tcbhash);
LIST_REMOVE(stcb, sctp_tcblist);
-
+ if (stcb->asoc.in_asocid_hash) {
+ LIST_REMOVE(stcb, sctp_tcbasocidhash);
+ }
/* Now insert the new_inp into the TCP connected hash */
head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR((lport),
SCTP_BASE_INFO(hashtcpmark))];
@@ -2520,7 +2522,13 @@ sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
* only have one connection? Probably not :> so lets get rid of it
* and not suck up any kernel memory in that.
*/
+ if (stcb->asoc.in_asocid_hash) {
+ struct sctpasochead *lhd;
+ lhd = &new_inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(stcb->asoc.assoc_id,
+ new_inp->hashasocidmark)];
+ LIST_INSERT_HEAD(lhd, stcb, sctp_tcbasocidhash);
+ }
/* Ok. Let's restart timer. */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, new_inp,
@@ -4652,7 +4660,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
/* pull from vtag hash */
LIST_REMOVE(stcb, sctp_asocs);
- sctp_add_vtag_to_timewait(asoc->my_vtag, inp->sctp_lport, stcb->rport, SCTP_TIME_WAIT);
+ sctp_add_vtag_to_timewait(asoc->my_vtag, SCTP_TIME_WAIT, inp->sctp_lport, stcb->rport);
/*
* Now restop the timers to be sure - this is paranoia at is finest!
@@ -4763,7 +4771,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/*
- if(ccnt) {
+ if (ccnt) {
printf("Freed %d from send_queue\n", ccnt);
ccnt = 0;
}
@@ -4788,7 +4796,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/*
- if(ccnt) {
+ if (ccnt) {
printf("Freed %d from sent_queue\n", ccnt);
ccnt = 0;
}
@@ -4813,7 +4821,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/*
- if(ccnt) {
+ if (ccnt) {
printf("Freed %d from ctrl_queue\n", ccnt);
ccnt = 0;
}
@@ -4839,7 +4847,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/*
- if(ccnt) {
+ if (ccnt) {
printf("Freed %d from asconf_queue\n", ccnt);
ccnt = 0;
}
@@ -4863,7 +4871,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/*
- if(ccnt) {
+ if (ccnt) {
printf("Freed %d from reasm_queue\n", ccnt);
ccnt = 0;
}
@@ -5776,7 +5784,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
/* ok get the v4 address and check/add */
phdr = sctp_get_next_param(m, offset,
- (struct sctp_paramhdr *)&p4_buf, sizeof(p4_buf));
+ (struct sctp_paramhdr *)&p4_buf,
+ sizeof(p4_buf));
if (plen != sizeof(struct sctp_ipv4addr_param) ||
phdr == NULL) {
return (-5);
@@ -5858,7 +5867,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
struct sctp_ipv6addr_param *p6, p6_buf;
phdr = sctp_get_next_param(m, offset,
- (struct sctp_paramhdr *)&p6_buf, sizeof(p6_buf));
+ (struct sctp_paramhdr *)&p6_buf,
+ sizeof(p6_buf));
if (plen != sizeof(struct sctp_ipv6addr_param) ||
phdr == NULL) {
return (-14);
@@ -5883,8 +5893,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
local_sa, stcb);
atomic_add_int(&stcb->asoc.refcnt, -1);
- if (stcb_tmp == NULL && (inp == stcb->sctp_ep ||
- inp == NULL)) {
+ if (stcb_tmp == NULL &&
+ (inp == stcb->sctp_ep || inp == NULL)) {
/*
* we must validate the state again
* here
@@ -5965,7 +5975,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
return (-23);
}
phdr = sctp_get_next_param(m, offset,
- (struct sctp_paramhdr *)&lstore, min(plen, sizeof(lstore)));
+ (struct sctp_paramhdr *)&lstore,
+ min(plen, sizeof(lstore)));
if (phdr == NULL) {
return (-24);
}
@@ -6154,6 +6165,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
break;
}
}
+
next_param:
offset += SCTP_SIZE32(plen);
if (offset >= limit) {
@@ -6206,8 +6218,10 @@ next_param:
bcopy(p_random->random_data, new_key->key, random_len);
}
#else
- keylen = sizeof(*p_random) + random_len + sizeof(*chunks) + num_chunks +
- sizeof(*hmacs) + hmacs_len;
+ keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
+ if (chunks != NULL) {
+ keylen += sizeof(*chunks) + num_chunks;
+ }
new_key = sctp_alloc_key(keylen);
if (new_key != NULL) {
/* copy in the RANDOM */
@@ -6343,6 +6357,8 @@ skip_vtag_check:
/* Audit expires this guy */
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
+ twait_block->vtag_block[i].lport = 0;
+ twait_block->vtag_block[i].rport = 0;
} else if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index 66c5f7b..684ed5a 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -144,6 +144,7 @@ struct sctp_tagblock {
struct sctp_epinfo {
+ struct socket *udp_tun_socket;
struct sctpasochead *sctp_asochash;
u_long hashasocmark;
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index 6703daf..bcba5b5 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -120,6 +120,7 @@ sctp_init_sysctls()
#endif
}
+
/* It returns an upper limit. No filtering is done here */
static unsigned int
number_of_addresses(struct sctp_inpcb *inp)
@@ -408,6 +409,8 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
xstcb.primary_addr = stcb->asoc.primary_destination->ro._l_addr;
xstcb.heartbeat_interval = stcb->asoc.heart_beat_delay;
xstcb.state = SCTP_GET_STATE(&stcb->asoc); /* FIXME */
+ /* 7.0 does not support this */
+ xstcb.assoc_id = sctp_get_associd(stcb);
xstcb.in_streams = stcb->asoc.streamincnt;
xstcb.out_streams = stcb->asoc.streamoutcnt;
xstcb.max_nr_retrans = stcb->asoc.overall_error_count;
@@ -506,7 +509,6 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
}
-
#define RANGECHK(var, min, max) \
if ((var) < (min)) { (var) = (min); } \
else if ((var) > (max)) { (var) = (max); }
@@ -517,10 +519,17 @@ sysctl_sctp_udp_tunneling_check(SYSCTL_HANDLER_ARGS)
int error;
uint32_t old_sctp_udp_tunneling_port;
+ SCTP_INP_INFO_RLOCK();
old_sctp_udp_tunneling_port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
+ SCTP_INP_INFO_RUNLOCK();
error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
if (error == 0) {
RANGECHK(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), SCTPCTL_UDP_TUNNELING_PORT_MIN, SCTPCTL_UDP_TUNNELING_PORT_MAX);
+ if (old_sctp_udp_tunneling_port == SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) {
+ error = 0;
+ goto out;
+ }
+ SCTP_INP_INFO_WLOCK();
if (old_sctp_udp_tunneling_port) {
sctp_over_udp_stop();
}
@@ -529,7 +538,9 @@ sysctl_sctp_udp_tunneling_check(SYSCTL_HANDLER_ARGS)
SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = 0;
}
}
+ SCTP_INP_INFO_WUNLOCK();
}
+out:
return (error);
}
@@ -624,14 +635,15 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
static int
sysctl_sctp_cleartrace(SYSCTL_HANDLER_ARGS)
{
+ int error = 0;
+
memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log));
- return (0);
+ return (error);
}
#endif
-
/*
* sysctl definitions
*/
diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
index 46e604f..27597ba 100644
--- a/sys/netinet/sctp_uio.h
+++ b/sys/netinet/sctp_uio.h
@@ -804,6 +804,10 @@ struct sctpstat {
uint32_t sctps_recvexpress; /* total fast path receives all one
* chunk */
uint32_t sctps_recvexpressm; /* total fast path multi-part data */
+ uint32_t sctps_recvnocrc;
+ uint32_t sctps_recvswcrc;
+ uint32_t sctps_recvhwcrc;
+
/* output statistics: */
uint32_t sctps_sendpackets; /* total output packets */
uint32_t sctps_sendsacks; /* total output SACKs */
@@ -820,6 +824,9 @@ struct sctpstat {
uint32_t sctps_sendecne;/* total output ECNE chunks */
uint32_t sctps_sendauth;/* total output AUTH chunks FIXME */
uint32_t sctps_senderrors; /* ip_output error counter */
+ uint32_t sctps_sendnocrc;
+ uint32_t sctps_sendswcrc;
+ uint32_t sctps_sendhwcrc;
/* PCKDROPREP statistics: */
uint32_t sctps_pdrpfmbox; /* Packet drop from middle box */
uint32_t sctps_pdrpfehos; /* P-drop from end host */
@@ -1009,6 +1016,7 @@ struct xsctp_tcb {
uint16_t remote_port; /* sctpAssocEntry 4 */
struct sctp_timeval start_time; /* sctpAssocEntry 16 */
struct sctp_timeval discontinuity_time; /* sctpAssocEntry 17 */
+ sctp_assoc_t assoc_id; /* sctpAssocEntry 1 */
};
struct xsctp_laddr {
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index c642762..9d04f56 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -908,6 +908,7 @@ sctp_disconnect(struct socket *so)
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
}
}
+ soisdisconnecting(so);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_RUNLOCK(inp);
return (0);
@@ -980,6 +981,11 @@ sctp_shutdown(struct socket *so)
struct sctp_tcb *stcb;
struct sctp_association *asoc;
+ if ((so->so_state &
+ (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) {
+ SCTP_INP_RUNLOCK(inp);
+ return (ENOTCONN);
+ }
socantsendmore(so);
stcb = LIST_FIRST(&inp->sctp_asoc_list);
@@ -3515,6 +3521,22 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if (events->sctp_sender_dry_event) {
sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT);
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+ (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
+ stcb = LIST_FIRST(&inp->sctp_asoc_list);
+ if (stcb) {
+ SCTP_TCB_LOCK(stcb);
+ }
+ if (stcb &&
+ TAILQ_EMPTY(&stcb->asoc.send_queue) &&
+ TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
+ (stcb->asoc.stream_queue_cnt == 0)) {
+ sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED);
+ }
+ if (stcb) {
+ SCTP_TCB_UNLOCK(stcb);
+ }
+ }
} else {
sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT);
}
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index ce06853..ac13717 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_output.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_timer.h>
-#include <netinet/sctp_crc32.h>
#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */
#include <netinet/sctp_auth.h>
#include <netinet/sctp_asconf.h>
@@ -53,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,
@@ -2458,48 +2463,6 @@ sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return;
}
-#ifdef SCTP_USE_ADLER32
-static uint32_t
-update_adler32(uint32_t adler, uint8_t * buf, int32_t len)
-{
- uint32_t s1 = adler & 0xffff;
- uint32_t s2 = (adler >> 16) & 0xffff;
- int n;
-
- for (n = 0; n < len; n++, buf++) {
- /* s1 = (s1 + buf[n]) % BASE */
- /* first we add */
- s1 = (s1 + *buf);
- /*
- * now if we need to, we do a mod by subtracting. It seems a
- * bit faster since I really will only ever do one subtract
- * at the MOST, since buf[n] is a max of 255.
- */
- if (s1 >= SCTP_ADLER32_BASE) {
- s1 -= SCTP_ADLER32_BASE;
- }
- /* s2 = (s2 + s1) % BASE */
- /* first we add */
- s2 = (s2 + s1);
- /*
- * again, it is more efficent (it seems) to subtract since
- * the most s2 will ever be is (BASE-1 + BASE-1) in the
- * worse case. This would then be (2 * BASE) - 2, which will
- * still only do one subtract. On Intel this is much better
- * to do this way and avoid the divide. Have not -pg'd on
- * sparc.
- */
- if (s2 >= SCTP_ADLER32_BASE) {
- s2 -= SCTP_ADLER32_BASE;
- }
- }
- /* Return the adler32 of the bytes buf[0..len-1] */
- return ((s2 << 16) + s1);
-}
-
-#endif
-
-
uint32_t
sctp_calculate_len(struct mbuf *m)
{
@@ -2514,132 +2477,6 @@ sctp_calculate_len(struct mbuf *m)
return (tlen);
}
-#if defined(SCTP_WITH_NO_CSUM)
-
-uint32_t
-sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
-{
- /*
- * given a mbuf chain with a packetheader offset by 'offset'
- * pointing at a sctphdr (with csum set to 0) go through the chain
- * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
- * has a side bonus as it will calculate the total length of the
- * mbuf chain. Note: if offset is greater than the total mbuf
- * length, checksum=1, pktlen=0 is returned (ie. no real error code)
- */
- if (pktlen == NULL)
- return (0);
- *pktlen = sctp_calculate_len(m);
- return (0);
-}
-
-#elif defined(SCTP_USE_INCHKSUM)
-
-#include <machine/in_cksum.h>
-
-uint32_t
-sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
-{
- /*
- * given a mbuf chain with a packetheader offset by 'offset'
- * pointing at a sctphdr (with csum set to 0) go through the chain
- * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
- * has a side bonus as it will calculate the total length of the
- * mbuf chain. Note: if offset is greater than the total mbuf
- * length, checksum=1, pktlen=0 is returned (ie. no real error code)
- */
- int32_t tlen = 0;
- struct mbuf *at;
- uint32_t the_sum, retsum;
-
- at = m;
- while (at) {
- tlen += SCTP_BUF_LEN(at);
- at = SCTP_BUF_NEXT(at);
- }
- the_sum = (uint32_t) (in_cksum_skip(m, tlen, offset));
- if (pktlen != NULL)
- *pktlen = (tlen - offset);
- retsum = htons(the_sum);
- return (the_sum);
-}
-
-#else
-
-uint32_t
-sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
-{
- /*
- * given a mbuf chain with a packetheader offset by 'offset'
- * pointing at a sctphdr (with csum set to 0) go through the chain
- * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
- * has a side bonus as it will calculate the total length of the
- * mbuf chain. Note: if offset is greater than the total mbuf
- * length, checksum=1, pktlen=0 is returned (ie. no real error code)
- */
- int32_t tlen = 0;
-
-#ifdef SCTP_USE_ADLER32
- uint32_t base = 1L;
-
-#else
- uint32_t base = 0xffffffff;
-
-#endif
- struct mbuf *at;
-
- at = m;
- /* find the correct mbuf and offset into mbuf */
- while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
- offset -= SCTP_BUF_LEN(at); /* update remaining offset
- * left */
- at = SCTP_BUF_NEXT(at);
- }
- while (at != NULL) {
- if ((SCTP_BUF_LEN(at) - offset) > 0) {
-#ifdef SCTP_USE_ADLER32
- base = update_adler32(base,
- (unsigned char *)(SCTP_BUF_AT(at, offset)),
- (unsigned int)(SCTP_BUF_LEN(at) - offset));
-#else
- if ((SCTP_BUF_LEN(at) - offset) < 4) {
- /* Use old method if less than 4 bytes */
- base = old_update_crc32(base,
- (unsigned char *)(SCTP_BUF_AT(at, offset)),
- (unsigned int)(SCTP_BUF_LEN(at) - offset));
- } else {
- base = update_crc32(base,
- (unsigned char *)(SCTP_BUF_AT(at, offset)),
- (unsigned int)(SCTP_BUF_LEN(at) - offset));
- }
-#endif
- tlen += SCTP_BUF_LEN(at) - offset;
- /* we only offset once into the first mbuf */
- }
- if (offset) {
- if (offset < (uint32_t) SCTP_BUF_LEN(at))
- offset = 0;
- else
- offset -= SCTP_BUF_LEN(at);
- }
- at = SCTP_BUF_NEXT(at);
- }
- if (pktlen != NULL) {
- *pktlen = tlen;
- }
-#ifdef SCTP_USE_ADLER32
- /* Adler32 */
- base = htonl(base);
-#else
- /* CRC-32c */
- base = sctp_csum_finalize(base);
-#endif
- return (base);
-}
-
-
-#endif
-
void
sctp_mtu_size_reset(struct sctp_inpcb *inp,
struct sctp_association *asoc, uint32_t mtu)
@@ -3428,7 +3265,6 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
}
#endif
socantsendmore(stcb->sctp_socket);
- socantrcvmore(stcb->sctp_socket);
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -3596,6 +3432,9 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
/* If the socket is gone we are out of here */
return;
}
+ if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) {
+ return;
+ }
if (stcb && ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) ||
(stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED))) {
if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
@@ -6708,14 +6547,163 @@ sctp_log_trace(uint32_t subsys, const char *str SCTP_UNUSED, uint32_t a, uint32_
* so we can do UDP tunneling. In
* the mean-time, we return error
*/
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <sys/proc.h>
+#include <netinet6/sctp6_var.h>
+
+static void
+sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored)
+{
+ struct ip *iph;
+ struct mbuf *sp, *last;
+ struct udphdr *uhdr;
+ uint16_t port = 0, len;
+ int header_size = sizeof(struct udphdr) + sizeof(struct sctphdr);
+
+ /*
+ * Split out the mbuf chain. Leave the IP header in m, place the
+ * rest in the sp.
+ */
+ if ((m->m_flags & M_PKTHDR) == 0) {
+ /* Can't handle one that is not a pkt hdr */
+ goto out;
+ }
+ /* pull the src port */
+ iph = mtod(m, struct ip *);
+ uhdr = (struct udphdr *)((caddr_t)iph + off);
+
+ port = uhdr->uh_sport;
+ sp = m_split(m, off, M_DONTWAIT);
+ if (sp == NULL) {
+ /* Gak, drop packet, we can't do a split */
+ goto out;
+ }
+ if (sp->m_pkthdr.len < header_size) {
+ /* Gak, packet can't have an SCTP header in it - to small */
+ m_freem(sp);
+ goto out;
+ }
+ /* ok now pull up the UDP header and SCTP header together */
+ sp = m_pullup(sp, header_size);
+ if (sp == NULL) {
+ /* Gak pullup failed */
+ goto out;
+ }
+ /* trim out the UDP header */
+ m_adj(sp, sizeof(struct udphdr));
+
+ /* Now reconstruct the mbuf chain */
+ /* 1) find last one */
+ last = m;
+ while (last->m_next != NULL) {
+ last = last->m_next;
+ }
+ last->m_next = sp;
+ m->m_pkthdr.len += sp->m_pkthdr.len;
+ last = m;
+ while (last != NULL) {
+ last = last->m_next;
+ }
+ /* Now its ready for sctp_input or sctp6_input */
+ iph = mtod(m, struct ip *);
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ len = SCTP_GET_IPV4_LENGTH(iph);
+ len -= sizeof(struct udphdr);
+ SCTP_GET_IPV4_LENGTH(iph) = len;
+ sctp_input_with_port(m, off, port);
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 - NOT supported */
+ goto out;
+ break;
+
+ }
+#endif
+ default:
+ {
+ m_freem(m);
+ break;
+ }
+ }
+ return;
+out:
+ m_freem(m);
+}
void
sctp_over_udp_stop(void)
{
- return;
+ struct socket *sop;
+
+ /*
+ * This function assumes sysctl caller holds sctp_sysctl_info_lock()
+ * for writting!
+ */
+ if (SCTP_BASE_INFO(udp_tun_socket) == NULL) {
+ /* Nothing to do */
+ return;
+ }
+ sop = SCTP_BASE_INFO(udp_tun_socket);
+ soclose(sop);
+ SCTP_BASE_INFO(udp_tun_socket) = NULL;
}
int
sctp_over_udp_start(void)
{
- return (-1);
+ uint16_t port;
+ int ret;
+ struct sockaddr_in sin;
+ struct socket *sop = NULL;
+ struct thread *th;
+ struct ucred *cred;
+
+ /*
+ * This function assumes sysctl caller holds sctp_sysctl_info_lock()
+ * for writting!
+ */
+ port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
+ if (port == 0) {
+ /* Must have a port set */
+ return (EINVAL);
+ }
+ if (SCTP_BASE_INFO(udp_tun_socket) != NULL) {
+ /* Already running -- must stop first */
+ return (EALREADY);
+ }
+ th = curthread;
+ cred = th->td_ucred;
+ if ((ret = socreate(PF_INET, &sop,
+ SOCK_DGRAM, IPPROTO_UDP, cred, th))) {
+ return (ret);
+ }
+ SCTP_BASE_INFO(udp_tun_socket) = sop;
+ /* call the special UDP hook */
+ ret = udp_set_kernel_tunneling(sop, sctp_recv_udp_tunneled_packet);
+ if (ret) {
+ goto exit_stage_left;
+ }
+ /* Ok we have a socket, bind it to the port */
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+ ret = sobind(sop, (struct sockaddr *)&sin, th);
+ if (ret) {
+ /* Close up we cant get the port */
+exit_stage_left:
+ sctp_over_udp_stop();
+ return (ret);
+ }
+ /*
+ * Ok we should now get UDP packets directly to our input routine
+ * sctp_recv_upd_tunneled_packet().
+ */
+ return (0);
}
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index cc940b3..56c6729 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -94,8 +94,6 @@ sctp_timer_stop(int, struct sctp_inpcb *, struct sctp_tcb *,
int
sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id);
-uint32_t sctp_calculate_sum(struct mbuf *, int32_t *, uint32_t);
-
void
sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *, uint32_t);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 30b3fde..d3b91b6 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -117,6 +117,8 @@ int tcp_insecure_rst;
int tcp_do_autorcvbuf;
int tcp_autorcvbuf_inc;
int tcp_autorcvbuf_max;
+int tcp_do_rfc3465;
+int tcp_abc_l_var;
#endif
SYSCTL_V_STRUCT(V_NET, vnet_inet, _net_inet_tcp, TCPCTL_STATS, stats,
@@ -144,6 +146,13 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_RW,
tcp_do_rfc3390, 0,
"Enable RFC 3390 (Increasing TCP's Initial Congestion Window)");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_RW,
+ tcp_do_rfc3465, 0,
+ "Enable RFC 3465 (Appropriate Byte Counting)");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp, OID_AUTO, abc_l_var, CTLFLAG_RW,
+ tcp_abc_l_var, 2,
+ "Cap the max cwnd increment during slow-start to this number of segments");
+
SYSCTL_NODE(_net_inet_tcp, OID_AUTO, ecn, CTLFLAG_RW, 0, "TCP ECN");
SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_tcp_ecn, OID_AUTO, enable,
CTLFLAG_RW, tcp_do_ecn, 0, "TCP ECN support");
@@ -2293,20 +2302,59 @@ process_ACK:
/*
* When new data is acked, open the congestion window.
- * If the window gives us less than ssthresh packets
- * in flight, open exponentially (maxseg per packet).
- * Otherwise open linearly: maxseg per window
- * (maxseg^2 / cwnd per packet).
- * If cwnd > maxseg^2, fix the cwnd increment at 1 byte
- * to avoid capping cwnd (as suggested in RFC2581).
+ * Method depends on which congestion control state we're
+ * in (slow start or cong avoid) and if ABC (RFC 3465) is
+ * enabled.
+ *
+ * slow start: cwnd <= ssthresh
+ * cong avoid: cwnd > ssthresh
+ *
+ * slow start and ABC (RFC 3465):
+ * Grow cwnd exponentially by the amount of data
+ * ACKed capping the max increment per ACK to
+ * (abc_l_var * maxseg) bytes.
+ *
+ * slow start without ABC (RFC 2581):
+ * Grow cwnd exponentially by maxseg per ACK.
+ *
+ * cong avoid and ABC (RFC 3465):
+ * Grow cwnd linearly by maxseg per RTT for each
+ * cwnd worth of ACKed data.
+ *
+ * cong avoid without ABC (RFC 2581):
+ * Grow cwnd linearly by approximately maxseg per RTT using
+ * maxseg^2 / cwnd per ACK as the increment.
+ * If cwnd > maxseg^2, fix the cwnd increment at 1 byte to
+ * avoid capping cwnd.
*/
if ((!V_tcp_do_newreno && !(tp->t_flags & TF_SACK_PERMIT)) ||
!IN_FASTRECOVERY(tp)) {
u_int cw = tp->snd_cwnd;
u_int incr = tp->t_maxseg;
- if (cw > tp->snd_ssthresh)
- incr = max((incr * incr / cw), 1);
- tp->snd_cwnd = min(cw+incr, TCP_MAXWIN<<tp->snd_scale);
+ /* In congestion avoidance? */
+ if (cw > tp->snd_ssthresh) {
+ if (V_tcp_do_rfc3465) {
+ tp->t_bytes_acked += acked;
+ if (tp->t_bytes_acked >= tp->snd_cwnd)
+ tp->t_bytes_acked -= cw;
+ else
+ incr = 0;
+ }
+ else
+ incr = max((incr * incr / cw), 1);
+ /*
+ * In slow-start with ABC enabled and no RTO in sight?
+ * (Must not use abc_l_var > 1 if slow starting after an
+ * RTO. On RTO, snd_nxt = snd_una, so the snd_nxt ==
+ * snd_max check is sufficient to handle this).
+ */
+ } else if (V_tcp_do_rfc3465 &&
+ tp->snd_nxt == tp->snd_max)
+ incr = min(acked,
+ V_tcp_abc_l_var * tp->t_maxseg);
+ /* ABC is on by default, so (incr == 0) frequently. */
+ if (incr > 0)
+ tp->snd_cwnd = min(cw+incr, TCP_MAXWIN<<tp->snd_scale);
}
SOCKBUF_LOCK(&so->so_snd);
if (acked > so->so_snd.sb_cc) {
@@ -2328,8 +2376,10 @@ process_ACK:
tp->snd_recover = th->th_ack - 1;
if ((V_tcp_do_newreno || (tp->t_flags & TF_SACK_PERMIT)) &&
IN_FASTRECOVERY(tp) &&
- SEQ_GEQ(th->th_ack, tp->snd_recover))
+ SEQ_GEQ(th->th_ack, tp->snd_recover)) {
EXIT_FASTRECOVERY(tp);
+ tp->t_bytes_acked = 0;
+ }
tp->snd_una = th->th_ack;
if (tp->t_flags & TF_SACK_PERMIT) {
if (SEQ_GT(tp->snd_una, tp->snd_recover))
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 9cb941a..53fc882 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -316,6 +316,8 @@ tcp_init(void)
V_tcp_do_autorcvbuf = 1;
V_tcp_autorcvbuf_inc = 16*1024;
V_tcp_autorcvbuf_max = 256*1024;
+ V_tcp_do_rfc3465 = 1;
+ V_tcp_abc_l_var = 2;
V_tcp_mssdflt = TCP_MSS;
#ifdef INET6
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 18fab28..9faca96 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1070,8 +1070,6 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
* have an initialized label we can use.
*/
mac_syncache_destroy(&maclabel);
- KASSERT(sc->sc_label != NULL,
- ("%s: label not initialized", __func__));
#endif
/* Retransmit SYN|ACK and reset retransmit count. */
if ((s = tcp_log_addrs(&sc->sc_inc, th, NULL, NULL))) {
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index acce92f..6963d9c 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -587,6 +587,7 @@ tcp_timer_rexmt(void * xtp)
tp->t_dupacks = 0;
}
EXIT_FASTRECOVERY(tp);
+ tp->t_bytes_acked = 0;
(void) tcp_output(tp);
out:
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index f6dcae1..89987c4 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -441,8 +441,8 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
if (sinp->sin_family == AF_INET
&& IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
return (EAFNOSUPPORT);
- if (prison_remote_ip4(td->td_ucred, &sinp->sin_addr) != 0)
- return (EINVAL);
+ if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
+ return (error);
TCPDEBUG0;
INP_INFO_WLOCK(&V_tcbinfo);
@@ -508,10 +508,9 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
in6_sin6_2_sin(&sin, sin6p);
inp->inp_vflag |= INP_IPV4;
inp->inp_vflag &= ~INP_IPV6;
- if (prison_remote_ip4(td->td_ucred, &sin.sin_addr) != 0) {
- error = EINVAL;
+ if ((error = prison_remote_ip4(td->td_ucred,
+ &sin.sin_addr)) != 0)
goto out;
- }
if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
goto out;
error = tcp_output_connect(so, nam);
@@ -520,10 +519,8 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
inp->inp_vflag &= ~INP_IPV4;
inp->inp_vflag |= INP_IPV6;
inp->inp_inc.inc_flags |= INC_ISIPV6;
- if (prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr) != 0) {
- error = EINVAL;
+ if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0)
goto out;
- }
if ((error = tcp6_connect(tp, nam, td)) != 0)
goto out;
error = tcp_output_connect(so, nam);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index a4392cb..c52506e 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -189,6 +189,7 @@ struct tcpcb {
void *t_pspare[3]; /* toe usrreqs / toepcb * / congestion algo / vimage / 1 general use */
struct toe_usrreqs *t_tu; /* offload operations vector */
void *t_toe; /* TOE pcb pointer */
+ int t_bytes_acked; /* # bytes acked during current RTT */
};
/*
@@ -539,6 +540,8 @@ extern int tcp_insecure_rst;
extern int tcp_do_autorcvbuf;
extern int tcp_autorcvbuf_inc;
extern int tcp_autorcvbuf_max;
+extern int tcp_do_rfc3465;
+extern int tcp_abc_l_var;
extern int tcp_do_tso;
extern int tcp_do_autosndbuf;
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index e402297..804f5fe 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -488,10 +488,28 @@ udp_input(struct mbuf *m, int off)
struct mbuf *n;
n = m_copy(m, 0, M_COPYALL);
- if (n != NULL)
- udp_append(last, ip, n, iphlen +
- sizeof(struct udphdr), &udp_in);
- INP_RUNLOCK(last);
+ if (last->inp_ppcb == NULL) {
+ if (n != NULL)
+ udp_append(last,
+ ip, n,
+ iphlen +
+ sizeof(struct udphdr),
+ &udp_in);
+ INP_RUNLOCK(last);
+ } else {
+ /*
+ * Engage the tunneling protocol we
+ * will have to leave the info_lock
+ * up, since we are hunting through
+ * multiple UDP's.
+ *
+ */
+ udp_tun_func_t tunnel_func;
+
+ tunnel_func = (udp_tun_func_t)last->inp_ppcb;
+ tunnel_func(n, iphlen, last);
+ INP_RUNLOCK(last);
+ }
}
last = inp;
/*
@@ -516,10 +534,22 @@ udp_input(struct mbuf *m, int off)
V_udpstat.udps_noportbcast++;
goto badheadlocked;
}
- udp_append(last, ip, m, iphlen + sizeof(struct udphdr),
- &udp_in);
- INP_RUNLOCK(last);
- INP_INFO_RUNLOCK(&V_udbinfo);
+ if (last->inp_ppcb == NULL) {
+ udp_append(last, ip, m, iphlen + sizeof(struct udphdr),
+ &udp_in);
+ INP_RUNLOCK(last);
+ INP_INFO_RUNLOCK(&V_udbinfo);
+ } else {
+ /*
+ * Engage the tunneling protocol.
+ */
+ udp_tun_func_t tunnel_func;
+
+ tunnel_func = (udp_tun_func_t)last->inp_ppcb;
+ tunnel_func(m, iphlen, last);
+ INP_RUNLOCK(last);
+ INP_INFO_RUNLOCK(&V_udbinfo);
+ }
return;
}
@@ -563,6 +593,17 @@ udp_input(struct mbuf *m, int off)
INP_RUNLOCK(inp);
goto badunlocked;
}
+ if (inp->inp_ppcb != NULL) {
+ /*
+ * Engage the tunneling protocol.
+ */
+ udp_tun_func_t tunnel_func;
+
+ tunnel_func = (udp_tun_func_t)inp->inp_ppcb;
+ tunnel_func(m, iphlen, inp);
+ INP_RUNLOCK(inp);
+ return;
+ }
udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in);
INP_RUNLOCK(inp);
return;
@@ -941,10 +982,9 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
* Jail may rewrite the destination address, so let it do
* that before we use it.
*/
- if (prison_remote_ip4(td->td_ucred, &sin->sin_addr) != 0) {
- error = EINVAL;
+ error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
+ if (error)
goto release;
- }
/*
* If a local address or port hasn't yet been selected, or if
@@ -1138,6 +1178,40 @@ udp_attach(struct socket *so, int proto, struct thread *td)
INP_INFO_WUNLOCK(&V_udbinfo);
inp->inp_vflag |= INP_IPV4;
inp->inp_ip_ttl = V_ip_defttl;
+ /*
+ * UDP does not have a per-protocol pcb (inp->inp_ppcb).
+ * We use this pointer for kernel tunneling pointer.
+ * If we ever need to have a protocol block we will
+ * need to move this function pointer there. Null
+ * in this pointer means "do the normal thing".
+ */
+ inp->inp_ppcb = NULL;
+ INP_WUNLOCK(inp);
+ return (0);
+}
+
+int
+udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f)
+{
+ struct inpcb *inp;
+
+ inp = (struct inpcb *)so->so_pcb;
+ 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);
+ }
+ if (inp == NULL) {
+ /* NULL INP? */
+ return (EINVAL);
+ }
+ INP_WLOCK(inp);
+ if (inp->inp_ppcb != NULL) {
+ INP_WUNLOCK(inp);
+ return (EBUSY);
+ }
+ inp->inp_ppcb = f;
INP_WUNLOCK(inp);
return (0);
}
@@ -1196,10 +1270,11 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
return (EISCONN);
}
sin = (struct sockaddr_in *)nam;
- if (prison_remote_ip4(td->td_ucred, &sin->sin_addr) != 0) {
+ error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
+ if (error != 0) {
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_udbinfo);
- return (EAFNOSUPPORT);
+ return (error);
}
error = in_pcbconnect(inp, nam, td->td_ucred);
if (error == 0)
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 39805ed..76a31b8 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -110,6 +110,10 @@ void udp_init(void);
void udp_input(struct mbuf *, int);
struct inpcb *udp_notify(struct inpcb *inp, int errno);
int udp_shutdown(struct socket *so);
+
+
+typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *);
+int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f);
#endif
#endif
diff --git a/sys/netinet/vinet.h b/sys/netinet/vinet.h
index 449334e..618afaa 100644
--- a/sys/netinet/vinet.h
+++ b/sys/netinet/vinet.h
@@ -127,6 +127,8 @@ struct vnet_inet {
int _drop_synfin;
int _tcp_do_rfc3042;
int _tcp_do_rfc3390;
+ int _tcp_do_rfc3465;
+ int _tcp_abc_l_var;
int _tcp_do_ecn;
int _tcp_ecn_maxretries;
int _tcp_insecure_rst;
@@ -291,6 +293,7 @@ extern struct vnet_inet vnet_inet_0;
#define V_subnetsarelocal VNET_INET(subnetsarelocal)
#define V_tcb VNET_INET(tcb)
#define V_tcbinfo VNET_INET(tcbinfo)
+#define V_tcp_abc_l_var VNET_INET(tcp_abc_l_var)
#define V_tcp_autorcvbuf_inc VNET_INET(tcp_autorcvbuf_inc)
#define V_tcp_autorcvbuf_max VNET_INET(tcp_autorcvbuf_max)
#define V_tcp_autosndbuf_inc VNET_INET(tcp_autosndbuf_inc)
@@ -303,6 +306,7 @@ extern struct vnet_inet vnet_inet_0;
#define V_tcp_do_rfc1323 VNET_INET(tcp_do_rfc1323)
#define V_tcp_do_rfc3042 VNET_INET(tcp_do_rfc3042)
#define V_tcp_do_rfc3390 VNET_INET(tcp_do_rfc3390)
+#define V_tcp_do_rfc3465 VNET_INET(tcp_do_rfc3465)
#define V_tcp_do_sack VNET_INET(tcp_do_sack)
#define V_tcp_do_tso VNET_INET(tcp_do_tso)
#define V_tcp_ecn_maxretries VNET_INET(tcp_ecn_maxretries)
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 5c4df75..e2eda6f 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -751,22 +751,6 @@ frag6_slowtimo(void)
}
VNET_LIST_RUNLOCK();
IP6Q_UNLOCK();
-
-#if 0
- /*
- * Routing changes might produce a better route than we last used;
- * make sure we notice eventually, even if forwarding only for one
- * destination and the cache is never replaced.
- */
- if (V_ip6_forward_rt.ro_rt) {
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
- if (ipsrcchk_rt.ro_rt) {
- RTFREE(ipsrcchk_rt.ro_rt);
- ipsrcchk_rt.ro_rt = 0;
- }
-#endif
}
/*
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 0d0c951..81a37f8 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/errno.h>
+#include <sys/jail.h>
#include <sys/malloc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -329,6 +330,9 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
error = in6_setscope(&sa6->sin6_addr, ifp, NULL);
if (error != 0)
return (error);
+ if (td != NULL && (error = prison_check_ip6(td->td_ucred,
+ &sa6->sin6_addr)) != 0)
+ return (error);
ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
} else
ia = NULL;
@@ -1533,52 +1537,29 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
* XXX: the logic below rejects assigning multiple addresses on a p2p
* interface that share the same destination.
*/
-#if 0 /* QL - verify */
plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
- if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 &&
- ia->ia_dstaddr.sin6_family == AF_INET6) {
+ if (!(ia->ia_flags & IFA_ROUTE) && plen == 128) {
+ struct sockaddr *dstaddr;
int rtflags = RTF_UP | RTF_HOST;
- struct rtentry *rt = NULL, **rtp = NULL;
- if (nd6_need_cache(ifp) != 0) {
- rtp = &rt;
- }
+ /*
+ * use the interface address if configuring an
+ * interface address with a /128 prefix len
+ */
+ if (ia->ia_dstaddr.sin6_family == AF_INET6)
+ dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
+ else
+ dstaddr = (struct sockaddr *)&ia->ia_addr;
error = rtrequest(RTM_ADD,
- (struct sockaddr *)&ia->ia_dstaddr,
+ (struct sockaddr *)dstaddr,
(struct sockaddr *)&ia->ia_addr,
(struct sockaddr *)&ia->ia_prefixmask,
- ia->ia_flags | rtflags, rtp);
+ ia->ia_flags | rtflags, NULL);
if (error != 0)
return (error);
- if (rt != NULL) {
- struct llinfo_nd6 *ln;
-
- RT_LOCK(rt);
- ln = (struct llinfo_nd6 *)rt->rt_llinfo;
- if (ln != NULL) {
- /*
- * Set the state to STALE because we don't
- * have to perform address resolution on this
- * link.
- */
- ln->ln_state = ND6_LLINFO_STALE;
- }
- RT_REMREF(rt);
- RT_UNLOCK(rt);
- }
- ia->ia_flags |= IFA_ROUTE;
- }
-#else
- plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
- if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 &&
- ia->ia_dstaddr.sin6_family == AF_INET6) {
- if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
- RTF_UP | RTF_HOST)) != 0)
- return (error);
ia->ia_flags |= IFA_ROUTE;
}
-#endif
/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
if (newhost) {
@@ -2141,16 +2122,16 @@ in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
ifa = ifaof_ifpforaddr(__DECONST(struct sockaddr *, l3addr), ifp);
if (ifa != NULL) {
if (rt != NULL)
- rtfree(rt);
+ RTFREE_LOCKED(rt);
return 0;
}
log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n",
ip6_sprintf(ip6buf, &((const struct sockaddr_in6 *)l3addr)->sin6_addr));
if (rt != NULL)
- rtfree(rt);
+ RTFREE_LOCKED(rt);
return EINVAL;
}
- rtfree(rt);
+ RTFREE_LOCKED(rt);
return 0;
}
@@ -2171,9 +2152,11 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
hashkey = sin6->sin6_addr.s6_addr32[3];
lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
LIST_FOREACH(lle, lleh, lle_next) {
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)L3_ADDR(lle);
if (lle->la_flags & LLE_DELETED)
continue;
- if (bcmp(L3_ADDR(lle), l3addr, l3addr->sa_len) == 0)
+ if (bcmp(&sa6->sin6_addr, &sin6->sin6_addr,
+ sizeof(struct in6_addr)) == 0)
break;
}
@@ -2257,6 +2240,9 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
/* skip deleted or invalid entries */
if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID)
continue;
+ /* Skip if jailed and not a valid IP of the prison. */
+ if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
+ continue;
/*
* produce a msg made of:
* struct rt_msghdr;
@@ -2265,6 +2251,10 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
*/
bzero(&ndpc, sizeof(ndpc));
ndpc.rtm.rtm_msglen = sizeof(ndpc);
+ ndpc.rtm.rtm_version = RTM_VERSION;
+ ndpc.rtm.rtm_type = RTM_GET;
+ ndpc.rtm.rtm_flags = RTF_UP;
+ ndpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
ndpc.sin6.sin6_family = AF_INET6;
ndpc.sin6.sin6_len = sizeof(ndpc.sin6);
bcopy(L3_ADDR(lle), &ndpc.sin6, L3_ADDR_LEN(lle));
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c
index ff0b8d1..bba348f 100644
--- a/sys/netinet6/in6_gif.c
+++ b/sys/netinet6/in6_gif.c
@@ -75,12 +75,15 @@ static int gif_validate6(const struct ip6_hdr *, struct gif_softc *,
struct ifnet *);
extern struct domain inet6domain;
-struct ip6protosw in6_gif_protosw =
-{ SOCK_RAW, &inet6domain, 0/* IPPROTO_IPV[46] */, PR_ATOMIC|PR_ADDR,
- in6_gif_input, rip6_output, 0, rip6_ctloutput,
- 0,
- 0, 0, 0, 0,
- &rip6_usrreqs
+struct ip6protosw in6_gif_protosw = {
+ .pr_type = SOCK_RAW,
+ .pr_domain = &inet6domain,
+ .pr_protocol = 0, /* IPPROTO_IPV[46] */
+ .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_input = in6_gif_input,
+ .pr_output = rip6_output,
+ .pr_ctloutput = rip6_ctloutput,
+ .pr_usrreqs = &rip6_usrreqs
};
int
@@ -375,10 +378,10 @@ gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc,
ip6_sprintf(ip6buf, &sin6.sin6_addr));
#endif
if (rt)
- rtfree(rt);
+ RTFREE_LOCKED(rt);
return 0;
}
- rtfree(rt);
+ RTFREE_LOCKED(rt);
}
return 128 * 2;
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 86d65f6..ca5428d 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -778,7 +778,7 @@ in6_ifdetach(struct ifnet *ifp)
if ((ia->ia_flags & IFA_ROUTE) &&
(rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
rtflags = rt->rt_flags;
- rtfree(rt);
+ RTFREE_LOCKED(rt);
rtrequest(RTM_DELETE, (struct sockaddr *)&ia->ia_addr,
(struct sockaddr *)&ia->ia_addr,
(struct sockaddr *)&ia->ia_prefixmask,
@@ -904,10 +904,6 @@ in6_purgemaddrs(struct ifnet *ifp)
struct in6_multi *in6m;
struct in6_multi *oin6m;
-#ifdef DIAGNOSTIC
- printf("%s: purging ifp %p\n", __func__, ifp);
-#endif
-
IFF_LOCKGIANT(ifp);
LIST_FOREACH_SAFE(in6m, &in6_multihead, in6m_entry, oin6m) {
if (in6m->in6m_ifp == ifp)
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 753f45d..79cb213 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -119,7 +119,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
u_short lport = 0;
- int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
+ int error, wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
INP_INFO_WLOCK_ASSERT(pcbinfo);
INP_WLOCK_ASSERT(inp);
@@ -130,9 +130,11 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
return (EINVAL);
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
wild = INPLOOKUP_WILDCARD;
- if (nam) {
- int error;
-
+ if (nam == NULL) {
+ if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
+ ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
+ return (error);
+ } else {
sin6 = (struct sockaddr_in6 *)nam;
if (nam->sa_len != sizeof(*sin6))
return (EINVAL);
@@ -145,9 +147,9 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
return(error);
- if (prison_local_ip6(cred, &sin6->sin6_addr,
- ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
- return (EINVAL);
+ if ((error = prison_local_ip6(cred, &sin6->sin6_addr,
+ ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
+ return (error);
lport = sin6->sin6_port;
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
@@ -223,9 +225,6 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
return (EADDRINUSE);
}
}
- if (prison_local_ip6(cred, &sin6->sin6_addr,
- ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
- return (EADDRNOTAVAIL);
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
lport, wild, cred);
if (t && (reuseport & ((t->inp_vflag & INP_TIMEWAIT) ?
@@ -258,13 +257,9 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
}
inp->in6p_laddr = sin6->sin6_addr;
}
- if (prison_local_ip6(cred, &inp->in6p_laddr,
- ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
- return (EINVAL);
if (lport == 0) {
- int e;
- if ((e = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
- return (e);
+ if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
+ return (error);
} else {
inp->inp_lport = lport;
if (in_pcbinshash(inp) != 0) {
@@ -320,8 +315,8 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam,
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
sin6->sin6_addr = in6addr_loopback;
}
- if (prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr) != 0)
- return (EADDRNOTAVAIL);
+ if ((error = prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr)) != 0)
+ return (error);
/*
* XXX: in6_selectsrc might replace the bound local address
@@ -885,7 +880,8 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
injail = jailed(inp->inp_cred);
if (injail) {
- if (!prison_check_ip6(inp->inp_cred, laddr))
+ if (prison_check_ip6(inp->inp_cred,
+ laddr) != 0)
continue;
} else {
if (local_exact != NULL)
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index ca65bc9..8030416 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -240,11 +240,10 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
if (*errorp != 0)
return (NULL);
}
- if (cred != NULL && prison_local_ip6(cred, &srcsock.sin6_addr,
- (inp != NULL && (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
- *errorp = EADDRNOTAVAIL;
+ if (cred != NULL && (*errorp = prison_local_ip6(cred,
+ &srcsock.sin6_addr, (inp != NULL &&
+ (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
return (NULL);
- }
ia6 = (struct in6_ifaddr *)ifa_ifwithaddr((struct sockaddr *)(&srcsock));
if (ia6 == NULL ||
@@ -262,11 +261,10 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
* Otherwise, if the socket has already bound the source, just use it.
*/
if (inp != NULL && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
- if (cred != NULL && prison_local_ip6(cred, &inp->in6p_laddr,
- ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
- *errorp = EADDRNOTAVAIL;
+ if (cred != NULL &&
+ (*errorp = prison_local_ip6(cred, &inp->in6p_laddr,
+ ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
return (NULL);
- }
return (&inp->in6p_laddr);
}
@@ -823,15 +821,16 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
INIT_VNET_INET(curvnet);
struct socket *so = inp->inp_socket;
u_int16_t lport = 0, first, last, *lastport;
- int count, error = 0, wild = 0, dorandom;
+ int count, error, wild = 0, dorandom;
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
INP_INFO_WLOCK_ASSERT(pcbinfo);
INP_WLOCK_ASSERT(inp);
- if (prison_local_ip6(cred, laddr,
- ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
- return(EINVAL);
+ error = prison_local_ip6(cred, laddr,
+ ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0));
+ if (error)
+ return(error);
/* XXX: this is redundant when called from in6_pcbbind */
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index db0094c..ca5101f 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -77,10 +77,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6protosw.h>
-#ifdef VIMAGE_GLOBALS
-struct route_in6 ip6_forward_rt;
-#endif
-
/*
* Forward a packet. If some error occurs return the sender
* an icmp packet. Note we can't always generate a meaningful
@@ -100,6 +96,7 @@ ip6_forward(struct mbuf *m, int srcrt)
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct sockaddr_in6 *dst = NULL;
struct rtentry *rt = NULL;
+ struct route_in6 rin6;
int error, type = 0, code = 0;
struct mbuf *mcopy = NULL;
struct ifnet *origifp; /* maybe unnecessary */
@@ -112,8 +109,6 @@ ip6_forward(struct mbuf *m, int srcrt)
#endif
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
- /* GIANT_REQUIRED; */ /* XXX bz: ip6_forward_rt */
-
#ifdef IPSEC
/*
* Check AH/ESP integrity.
@@ -350,64 +345,32 @@ ip6_forward(struct mbuf *m, int srcrt)
if (dst != NULL && rt != NULL)
ipsecrt = 1;
}
- skip_ipsec:
-#endif /* IPSEC */
-
-#ifdef IPSEC
if (ipsecrt)
goto skip_routing;
+skip_ipsec:
#endif
- dst = (struct sockaddr_in6 *)&V_ip6_forward_rt.ro_dst;
- if (!srcrt) {
- /* ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst */
- if (V_ip6_forward_rt.ro_rt == 0 ||
- (V_ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0) {
- if (V_ip6_forward_rt.ro_rt) {
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
-
- /* this probably fails but give it a try again */
- rtalloc((struct route *)&V_ip6_forward_rt);
- }
-
- if (V_ip6_forward_rt.ro_rt == 0) {
- V_ip6stat.ip6s_noroute++;
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
- if (mcopy) {
- icmp6_error(mcopy, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_NOROUTE, 0);
- }
- m_freem(m);
- return;
- }
- } else if ((rt = V_ip6_forward_rt.ro_rt) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) {
- if (V_ip6_forward_rt.ro_rt) {
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
- bzero(dst, sizeof(*dst));
- dst->sin6_len = sizeof(struct sockaddr_in6);
- dst->sin6_family = AF_INET6;
- dst->sin6_addr = ip6->ip6_dst;
-
- rtalloc((struct route *)&V_ip6_forward_rt);
- if (V_ip6_forward_rt.ro_rt == 0) {
- V_ip6stat.ip6s_noroute++;
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
- if (mcopy) {
- icmp6_error(mcopy, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_NOROUTE, 0);
- }
- m_freem(m);
- return;
+ bzero(&rin6, sizeof(struct route_in6));
+ dst = (struct sockaddr_in6 *)&rin6.ro_dst;
+ dst->sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_addr = ip6->ip6_dst;
+
+ rin6.ro_rt = rtalloc1((struct sockaddr *)dst, 0, 0);
+ if (rin6.ro_rt != NULL)
+ RT_UNLOCK(rin6.ro_rt);
+ else {
+ V_ip6stat.ip6s_noroute++;
+ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
+ if (mcopy) {
+ icmp6_error(mcopy, ICMP6_DST_UNREACH,
+ ICMP6_DST_UNREACH_NOROUTE, 0);
}
+ goto bad;
}
- rt = V_ip6_forward_rt.ro_rt;
+ rt = rin6.ro_rt;
#ifdef IPSEC
- skip_routing:;
+skip_routing:
#endif
/*
@@ -424,14 +387,12 @@ ip6_forward(struct mbuf *m, int srcrt)
/* XXX: this should not happen */
V_ip6stat.ip6s_cantforward++;
V_ip6stat.ip6s_badscope++;
- m_freem(m);
- return;
+ goto bad;
}
if (in6_setscope(&src_in6, m->m_pkthdr.rcvif, &inzone)) {
V_ip6stat.ip6s_cantforward++;
V_ip6stat.ip6s_badscope++;
- m_freem(m);
- return;
+ goto bad;
}
if (inzone != outzone
#ifdef IPSEC
@@ -455,8 +416,7 @@ ip6_forward(struct mbuf *m, int srcrt)
if (mcopy)
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_BEYONDSCOPE, 0);
- m_freem(m);
- return;
+ goto bad;
}
/*
@@ -472,8 +432,7 @@ ip6_forward(struct mbuf *m, int srcrt)
inzone != outzone) {
V_ip6stat.ip6s_cantforward++;
V_ip6stat.ip6s_badscope++;
- m_freem(m);
- return;
+ goto bad;
}
if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
@@ -513,8 +472,7 @@ ip6_forward(struct mbuf *m, int srcrt)
#endif /* IPSEC */
icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
}
- m_freem(m);
- return;
+ goto bad;
}
if (rt->rt_flags & RTF_GATEWAY)
@@ -547,8 +505,7 @@ ip6_forward(struct mbuf *m, int srcrt)
*/
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_ADDR, 0);
- m_freem(m);
- return;
+ goto bad;
}
type = ND_REDIRECT;
}
@@ -627,12 +584,12 @@ pass:
senderr:
if (mcopy == NULL)
- return;
+ goto out;
switch (error) {
case 0:
if (type == ND_REDIRECT) {
icmp6_redirect_output(mcopy, rt);
- return;
+ goto out;
}
goto freecopy;
@@ -654,9 +611,18 @@ senderr:
break;
}
icmp6_error(mcopy, type, code, 0);
- return;
+ goto out;
freecopy:
m_freem(mcopy);
- return;
+ goto out;
+bad:
+ m_freem(m);
+out:
+ if (rt != NULL
+#ifdef IPSEC
+ && !ipsecrt
+#endif
+ )
+ RTFREE(rt);
}
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 38ead34..f120ec5 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -143,13 +143,6 @@ extern int icmp6errppslim;
extern int icmp6_nodeinfo;
extern int udp6_sendspace;
extern int udp6_recvspace;
-
-extern struct route_in6 ip6_forward_rt;
-
-int ip6_forward_srcrt; /* XXX */
-int ip6_sourcecheck; /* XXX */
-int ip6_sourcecheck_interval; /* XXX */
-int ip6_ours_check_algorithm;
#endif
struct pfil_head inet6_pfil_hook;
@@ -314,10 +307,12 @@ ip6_input(struct mbuf *m)
int nxt, ours = 0;
struct ifnet *deliverifp = NULL, *ifp = NULL;
struct in6_addr odst;
+ struct route_in6 rin6;
int srcrt = 0;
struct llentry *lle = NULL;
- struct sockaddr_in6 dst6;
+ struct sockaddr_in6 dst6, *dst;
+ bzero(&rin6, sizeof(struct route_in6));
#ifdef IPSEC
/*
* should the inner packet be considered authentic?
@@ -570,29 +565,13 @@ passin:
if (lle != NULL)
LLE_RUNLOCK(lle);
- if (V_ip6_forward_rt.ro_rt != NULL &&
- (V_ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 &&
- IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
- &((struct sockaddr_in6 *)(&V_ip6_forward_rt.ro_dst))->sin6_addr))
- V_ip6stat.ip6s_forward_cachehit++;
- else {
- struct sockaddr_in6 *dst6;
-
- if (V_ip6_forward_rt.ro_rt) {
- /* route is down or destination is different */
- V_ip6stat.ip6s_forward_cachemiss++;
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
-
- bzero(&V_ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
- dst6 = (struct sockaddr_in6 *)&V_ip6_forward_rt.ro_dst;
- dst6->sin6_len = sizeof(struct sockaddr_in6);
- dst6->sin6_family = AF_INET6;
- dst6->sin6_addr = ip6->ip6_dst;
-
- rtalloc((struct route *)&V_ip6_forward_rt);
- }
+ dst = &rin6.ro_dst;
+ dst->sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_addr = ip6->ip6_dst;
+ rin6.ro_rt = rtalloc1((struct sockaddr *)dst, 0, 0);
+ if (rin6.ro_rt)
+ RT_UNLOCK(rin6.ro_rt);
#define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))
@@ -616,14 +595,14 @@ passin:
* while it would be less efficient. Or, should we rather install a
* reject route for such a case?
*/
- if (V_ip6_forward_rt.ro_rt &&
- (V_ip6_forward_rt.ro_rt->rt_flags &
+ if (rin6.ro_rt &&
+ (rin6.ro_rt->rt_flags &
(RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
#ifdef RTF_WASCLONED
- !(V_ip6_forward_rt.ro_rt->rt_flags & RTF_WASCLONED) &&
+ !(rin6.ro_rt->rt_flags & RTF_WASCLONED) &&
#endif
#ifdef RTF_CLONED
- !(V_ip6_forward_rt.ro_rt->rt_flags & RTF_CLONED) &&
+ !(rin6.ro_rt->rt_flags & RTF_CLONED) &&
#endif
#if 0
/*
@@ -632,11 +611,11 @@ passin:
* already done through looking up the routing table.
*/
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
- &rt6_key(V_ip6_forward_rt.ro_rt)->sin6_addr)
+ &rt6_key(rin6.ro_rt)->sin6_addr)
#endif
- V_ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) {
+ rin6.ro_rt->rt_ifp->if_type == IFT_LOOP) {
struct in6_ifaddr *ia6 =
- (struct in6_ifaddr *)V_ip6_forward_rt.ro_rt->rt_ifa;
+ (struct in6_ifaddr *)rin6.ro_rt->rt_ifa;
/*
* record address information into m_tag.
@@ -672,11 +651,11 @@ passin:
* FAITH (Firewall Aided Internet Translator)
*/
if (V_ip6_keepfaith) {
- if (V_ip6_forward_rt.ro_rt && V_ip6_forward_rt.ro_rt->rt_ifp
- && V_ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {
+ if (rin6.ro_rt && rin6.ro_rt->rt_ifp &&
+ rin6.ro_rt->rt_ifp->if_type == IFT_FAITH) {
/* XXX do we need more sanity checks? */
ours = 1;
- deliverifp = V_ip6_forward_rt.ro_rt->rt_ifp; /* faith */
+ deliverifp = rin6.ro_rt->rt_ifp; /* faith */
goto hbhcheck;
}
}
@@ -726,7 +705,7 @@ passin:
#if 0 /*touches NULL pointer*/
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
#endif
- return; /* m have already been freed */
+ goto out; /* m have already been freed */
}
/* adjust pointer */
@@ -749,7 +728,7 @@ passin:
icmp6_error(m, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
- return;
+ goto out;
}
#ifndef PULLDOWN_TEST
/* ip6_hopopts_input() ensures that mbuf is contiguous */
@@ -759,7 +738,7 @@ passin:
sizeof(struct ip6_hbh));
if (hbh == NULL) {
V_ip6stat.ip6s_tooshort++;
- return;
+ goto out;
}
#endif
nxt = hbh->ip6h_nxt;
@@ -821,16 +800,13 @@ passin:
if (ip6_mrouter && ip6_mforward &&
ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
V_ip6stat.ip6s_cantforward++;
- m_freem(m);
- return;
- }
- if (!ours) {
- m_freem(m);
- return;
+ goto bad;
}
+ if (!ours)
+ goto bad;
} else if (!ours) {
ip6_forward(m, srcrt);
- return;
+ goto out;
}
ip6 = mtod(m, struct ip6_hdr *);
@@ -885,9 +861,12 @@ passin:
#endif /* IPSEC */
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
}
- return;
- bad:
+ goto out;
+bad:
m_freem(m);
+out:
+ if (rin6.ro_rt)
+ RTFREE(rin6.ro_rt);
}
/*
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 55bc5db..9e8476c 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -229,9 +229,6 @@ struct ip6stat {
/* number of times that a deprecated address is chosen */
u_quad_t ip6s_sources_deprecated[16];
- u_quad_t ip6s_forward_cachehit;
- u_quad_t ip6s_forward_cachemiss;
-
/* number of times that each rule of source selection is applied. */
u_quad_t ip6s_sources_rule[16];
};
@@ -284,7 +281,6 @@ extern struct ip6stat ip6stat; /* statistics */
extern int ip6_defhlim; /* default hop limit */
extern int ip6_defmcasthlim; /* default multicast hop limit */
extern int ip6_forwarding; /* act as router? */
-extern int ip6_forward_srcrt; /* forward src-routed? */
extern int ip6_gif_hlim; /* Hop limit for gif encap packet */
extern int ip6_use_deprecated; /* allow deprecated addr as source */
extern int ip6_rr_prune; /* router renumbering prefix
@@ -298,8 +294,6 @@ extern struct socket *ip6_mrouter; /* multicast routing daemon */
extern int ip6_sendredirects; /* send IP redirects when forwarding? */
extern int ip6_maxfragpackets; /* Maximum packets in reassembly queue */
extern int ip6_maxfrags; /* Maximum fragments in reassembly queue */
-extern int ip6_sourcecheck; /* Verify source interface */
-extern int ip6_sourcecheck_interval; /* Interval between log messages */
extern int ip6_accept_rtadv; /* Acts as a host not a router */
extern int ip6_keepfaith; /* Firewall Aided Internet Translator */
extern int ip6_log_interval;
diff --git a/sys/netinet6/ip6protosw.h b/sys/netinet6/ip6protosw.h
index 1968959..2a7cea4 100644
--- a/sys/netinet6/ip6protosw.h
+++ b/sys/netinet6/ip6protosw.h
@@ -126,11 +126,6 @@ struct ip6protosw {
int (*pr_ctloutput) /* control output (from above) */
__P((struct socket *, struct sockopt *));
-/* user-protocol hook */
- int (*pr_usrreq) /* user request: see list below */
- __P((struct socket *, int, struct mbuf *,
- struct mbuf *, struct mbuf *, struct thread *));
-
/* utility hooks */
void (*pr_init) /* initialization hook */
__P((void));
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index e2ca9eb..4a38902 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -83,7 +83,6 @@ __FBSDID("$FreeBSD$");
#define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
#define SIN6(s) ((struct sockaddr_in6 *)s)
-#define SDL(s) ((struct sockaddr_dl *)s)
#ifdef VIMAGE_GLOBALS
int nd6_prune;
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 84e415a..1f88fb1 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -259,7 +259,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
need_proxy = (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 &&
rt->rt_gateway->sa_family == AF_LINK);
if (rt)
- rtfree(rt);
+ RTFREE_LOCKED(rt);
if (need_proxy) {
/*
* proxy NDP for single entry
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 7df364e..2bf47d2 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -68,8 +68,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/scope6_var.h>
#include <netinet6/vinet6.h>
-#define SDL(s) ((struct sockaddr_dl *)s)
-
static int rtpref(struct nd_defrouter *);
static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *);
static int prelist_update __P((struct nd_prefixctl *, struct nd_defrouter *,
@@ -653,8 +651,10 @@ defrouter_select(void)
selected_dr = dr;
}
IF_AFDATA_UNLOCK(dr->ifp);
- if (ln != NULL)
+ if (ln != NULL) {
LLE_RUNLOCK(ln);
+ ln = NULL;
+ }
if (dr->installed && installed_dr == NULL)
installed_dr = dr;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index d342bc8..da781a0 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -179,10 +179,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
continue;
- if (jailed(in6p->inp_cred)) {
- if (!prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst))
- continue;
- }
+ if (prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst) != 0)
+ continue;
INP_RLOCK(in6p);
if (in6p->in6p_cksum != -1) {
V_rip6stat.rip6s_isum++;
@@ -411,11 +409,9 @@ rip6_output(m, va_alist)
error = EADDRNOTAVAIL;
goto bad;
}
- if (jailed(in6p->inp_cred))
- if (prison_getip6(in6p->inp_cred, in6a) != 0) {
- error = EPERM;
- goto bad;
- }
+ error = prison_get_ip6(in6p->inp_cred, in6a);
+ if (error != 0)
+ goto bad;
ip6->ip6_src = *in6a;
if (oifp && scope_ambiguous) {
@@ -678,8 +674,8 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
if (nam->sa_len != sizeof(*addr))
return (EINVAL);
- if (!prison_check_ip6(td->td_ucred, &addr->sin6_addr))
- return (EADDRNOTAVAIL);
+ if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0)
+ return (error);
if (TAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6)
return (EADDRNOTAVAIL);
if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0)
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index c6fc3cf..9597528 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_input.h>
#include <netinet/sctp_output.h>
#include <netinet/sctp_bsd_addr.h>
+#include <netinet/sctp_crc32.h>
#include <netinet/udp.h>
#ifdef IPSEC
@@ -75,7 +76,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
uint32_t vrf_id = 0;
struct inpcb *in6p_ip;
struct sctp_chunkhdr *ch;
- int length, mlen, offset, iphlen;
+ int length, offset, iphlen;
uint8_t ecn_bits;
struct sctp_tcb *stcb = NULL;
int pkt_len = 0;
@@ -126,16 +127,28 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
/* destination port of 0 is illegal, based on RFC2960. */
if (sh->dest_port == 0)
goto bad;
+
+ SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+ "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
+ m->m_pkthdr.len,
+ if_name(m->m_pkthdr.rcvif),
+ m->m_pkthdr.csum_flags);
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
+ SCTP_STAT_INCR(sctps_recvhwcrc);
+ goto sctp_skip_csum;
+ }
check = sh->checksum; /* save incoming checksum */
if ((check == 0) && (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback)) &&
(IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &ip6->ip6_dst))) {
+ SCTP_STAT_INCR(sctps_recvnocrc);
goto sctp_skip_csum;
}
sh->checksum = 0; /* prepare for calc */
- calc_check = sctp_calculate_sum(m, &mlen, iphlen);
+ calc_check = sctp_calculate_cksum(m, iphlen);
+ SCTP_STAT_INCR(sctps_recvswcrc);
if (calc_check != check) {
- SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
- calc_check, check, m, mlen, iphlen);
+ SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p phlen:%d\n",
+ calc_check, check, m, iphlen);
stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch),
sh, ch, &in6p, &net, vrf_id);
if ((net) && (port)) {
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index f1634cb..05d48f5 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -287,8 +287,24 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
INP_RLOCK(last);
- udp6_append(last, n, off, &fromsa);
- INP_RUNLOCK(last);
+ if (last->inp_ppcb != NULL) {
+ /*
+ * Engage the tunneling
+ * protocol we will have to
+ * leave the info_lock up,
+ * since we are hunting
+ * through multiple UDP's.
+ *
+ */
+ udp_tun_func_t tunnel_func;
+
+ tunnel_func = (udp_tun_func_t)last->inp_ppcb;
+ tunnel_func(n, off, last);
+ INP_RUNLOCK(last);
+ } else {
+ udp6_append(last, n, off, &fromsa);
+ INP_RUNLOCK(last);
+ }
}
}
last = inp;
@@ -317,6 +333,17 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
}
INP_RLOCK(last);
INP_INFO_RUNLOCK(&V_udbinfo);
+ if (last->inp_ppcb != NULL) {
+ /*
+ * Engage the tunneling protocol.
+ */
+ udp_tun_func_t tunnel_func;
+
+ tunnel_func = (udp_tun_func_t)inp->inp_ppcb;
+ tunnel_func(m, off, last);
+ INP_RUNLOCK(last);
+ return (IPPROTO_DONE);
+ }
udp6_append(last, m, off, &fromsa);
INP_RUNLOCK(last);
return (IPPROTO_DONE);
@@ -354,6 +381,17 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
}
INP_RLOCK(inp);
INP_INFO_RUNLOCK(&V_udbinfo);
+ if (inp->inp_ppcb != NULL) {
+ /*
+ * Engage the tunneling protocol.
+ */
+ udp_tun_func_t tunnel_func;
+
+ tunnel_func = (udp_tun_func_t)inp->inp_ppcb;
+ tunnel_func(m, off, inp);
+ INP_RUNLOCK(inp);
+ return (IPPROTO_DONE);
+ }
udp6_append(inp, m, off, &fromsa);
INP_RUNLOCK(inp);
return (IPPROTO_DONE);
@@ -845,52 +883,43 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
INIT_VNET_INET(so->so_vnet);
struct inpcb *inp;
+ struct sockaddr_in6 *sin6;
int error;
inp = sotoinpcb(so);
+ sin6 = (struct sockaddr_in6 *)nam;
KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
INP_INFO_WLOCK(&V_udbinfo);
INP_WLOCK(inp);
- if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
- struct sockaddr_in6 *sin6_p;
+ if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
+ IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ struct sockaddr_in sin;
- sin6_p = (struct sockaddr_in6 *)nam;
- if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
- struct sockaddr_in sin;
-
- if (inp->inp_faddr.s_addr != INADDR_ANY) {
- error = EISCONN;
- goto out;
- }
- in6_sin6_2_sin(&sin, sin6_p);
- if (td && jailed(td->td_ucred))
- if (prison_remote_ip4(td->td_ucred,
- &sin.sin_addr) != 0) {
- error = EAFNOSUPPORT;
- goto out;
- }
- error = in_pcbconnect(inp, (struct sockaddr *)&sin,
- td->td_ucred);
- if (error == 0) {
- inp->inp_vflag |= INP_IPV4;
- inp->inp_vflag &= ~INP_IPV6;
- soisconnected(so);
- }
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ error = EISCONN;
+ goto out;
+ }
+ in6_sin6_2_sin(&sin, sin6);
+ error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
+ if (error != 0)
goto out;
+ error = in_pcbconnect(inp, (struct sockaddr *)&sin,
+ td->td_ucred);
+ if (error == 0) {
+ inp->inp_vflag |= INP_IPV4;
+ inp->inp_vflag &= ~INP_IPV6;
+ soisconnected(so);
}
+ goto out;
}
if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
error = EISCONN;
goto out;
}
- if (td && jailed(td->td_ucred)) {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
- if (prison_remote_ip6(td->td_ucred, &sin6->sin6_addr) != 0) {
- error = EAFNOSUPPORT;
- goto out;
- }
- }
+ error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
+ if (error != 0)
+ goto out;
error = in6_pcbconnect(inp, nam, td->td_ucred);
if (error == 0) {
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
diff --git a/sys/netinet6/vinet6.h b/sys/netinet6/vinet6.h
index e271d4f..e0a1fa0 100644
--- a/sys/netinet6/vinet6.h
+++ b/sys/netinet6/vinet6.h
@@ -54,7 +54,7 @@ struct vnet_inet6 {
u_int _frag6_nfrags;
struct ip6q _ip6q;
- struct route_in6 _ip6_forward_rt;
+ struct route_in6 _ip6_forward_rt; /* XXX remove */
struct in6_addrpolicy _defaultaddrpolicy;
TAILQ_HEAD(, addrsel_policyent) _addrsel_policytab;
@@ -122,10 +122,10 @@ struct vnet_inet6 {
int _udp6_recvspace;
int _ip6qmaxlen;
int _ip6_prefer_tempaddr;
- int _ip6_forward_srcrt;
- int _ip6_sourcecheck;
- int _ip6_sourcecheck_interval;
- int _ip6_ours_check_algorithm;
+ int _ip6_forward_srcrt; /* XXX remove */
+ int _ip6_sourcecheck; /* XXX remove */
+ int _ip6_sourcecheck_interval; /* XXX remove */
+ int _ip6_ours_check_algorithm; /* XXX remove */
int _nd6_prune;
int _nd6_delay;
@@ -194,8 +194,6 @@ extern struct vnet_inet6 vnet_inet6_0;
#define V_ip6_defhlim VNET_INET6(ip6_defhlim)
#define V_ip6_defmcasthlim VNET_INET6(ip6_defmcasthlim)
#define V_ip6_desync_factor VNET_INET6(ip6_desync_factor)
-#define V_ip6_forward_rt VNET_INET6(ip6_forward_rt)
-#define V_ip6_forward_srcrt VNET_INET6(ip6_forward_srcrt)
#define V_ip6_forwarding VNET_INET6(ip6_forwarding)
#define V_ip6_hdrnestlimit VNET_INET6(ip6_hdrnestlimit)
#define V_ip6_keepfaith VNET_INET6(ip6_keepfaith)
@@ -206,12 +204,9 @@ extern struct vnet_inet6 vnet_inet6_0;
#define V_ip6_mcast_pmtu VNET_INET6(ip6_mcast_pmtu)
#define V_ip6_mrouter_ver VNET_INET6(ip6_mrouter_ver)
#define V_ip6_opts VNET_INET6(ip6_opts)
-#define V_ip6_ours_check_algorithm VNET_INET6(ip6_ours_check_algorithm)
#define V_ip6_prefer_tempaddr VNET_INET6(ip6_prefer_tempaddr)
#define V_ip6_rr_prune VNET_INET6(ip6_rr_prune)
#define V_ip6_sendredirects VNET_INET6(ip6_sendredirects)
-#define V_ip6_sourcecheck VNET_INET6(ip6_sourcecheck)
-#define V_ip6_sourcecheck_interval VNET_INET6(ip6_sourcecheck_interval)
#define V_ip6_temp_preferred_lifetime VNET_INET6(ip6_temp_preferred_lifetime)
#define V_ip6_temp_regen_advance VNET_INET6(ip6_temp_regen_advance)
#define V_ip6_temp_valid_lifetime VNET_INET6(ip6_temp_valid_lifetime)
diff --git a/sys/netipsec/ipsec_mbuf.c b/sys/netipsec/ipsec_mbuf.c
index 322df11..d813c92 100644
--- a/sys/netipsec/ipsec_mbuf.c
+++ b/sys/netipsec/ipsec_mbuf.c
@@ -75,66 +75,67 @@ m_makespace(struct mbuf *m0, int skip, int hlen, int *off)
*/
remain = m->m_len - skip; /* data to move */
if (hlen > M_TRAILINGSPACE(m)) {
- struct mbuf *n;
+ struct mbuf *n0, *n, **np;
+ int todo, len, done, alloc;
+
+ n0 = NULL;
+ np = &n0;
+ alloc = 0;
+ done = 0;
+ todo = remain;
+ while (todo > 0) {
+ if (todo > MHLEN) {
+ n = m_getcl(M_DONTWAIT, m->m_type, 0);
+ len = MCLBYTES;
+ }
+ else {
+ n = m_get(M_DONTWAIT, m->m_type);
+ len = MHLEN;
+ }
+ if (n == NULL) {
+ m_freem(n0);
+ return NULL;
+ }
+ *np = n;
+ np = &n->m_next;
+ alloc++;
+ len = min(todo, len);
+ memcpy(n->m_data, mtod(m, char *) + skip + done, len);
+ n->m_len = len;
+ done += len;
+ todo -= len;
+ }
- /* XXX code doesn't handle clusters XXX */
- IPSEC_ASSERT(remain < MLEN, ("remainder too big: %u", remain));
- /*
- * Not enough space in m, split the contents
- * of m, inserting new mbufs as required.
- *
- * NB: this ignores mbuf types.
- */
- MGET(n, M_DONTWAIT, MT_DATA);
- if (n == NULL)
- return (NULL);
- n->m_next = m->m_next; /* splice new mbuf */
- m->m_next = n;
- V_ipsec4stat.ips_mbinserted++;
if (hlen <= M_TRAILINGSPACE(m) + remain) {
- /*
- * New header fits in the old mbuf if we copy
- * the remainder; just do the copy to the new
- * mbuf and we're good to go.
- */
- memcpy(mtod(n, caddr_t),
- mtod(m, caddr_t) + skip, remain);
- n->m_len = remain;
m->m_len = skip + hlen;
*off = skip;
- } else {
- /*
- * No space in the old mbuf for the new header.
- * Make space in the new mbuf and check the
- * remainder'd data fits too. If not then we
- * must allocate an additional mbuf (yech).
- */
- n->m_len = 0;
- if (remain + hlen > M_TRAILINGSPACE(n)) {
- struct mbuf *n2;
-
- MGET(n2, M_DONTWAIT, MT_DATA);
- /* NB: new mbuf is on chain, let caller free */
- if (n2 == NULL)
- return (NULL);
- n2->m_len = 0;
- memcpy(mtod(n2, caddr_t),
- mtod(m, caddr_t) + skip, remain);
- n2->m_len = remain;
- /* splice in second mbuf */
- n2->m_next = n->m_next;
- n->m_next = n2;
- V_ipsec4stat.ips_mbinserted++;
- } else {
- memcpy(mtod(n, caddr_t) + hlen,
- mtod(m, caddr_t) + skip, remain);
- n->m_len += remain;
+ if (n0 != NULL) {
+ *np = m->m_next;
+ m->m_next = n0;
}
- m->m_len -= remain;
- n->m_len += hlen;
+ }
+ else {
+ n = m_get(M_DONTWAIT, m->m_type);
+ if (n == NULL) {
+ m_freem(n0);
+ return NULL;
+ }
+ alloc++;
+
+ if ((n->m_next = n0) == NULL)
+ np = &n->m_next;
+ n0 = n;
+
+ *np = m->m_next;
+ m->m_next = n0;
+
+ n->m_len = hlen;
+ m->m_len = skip;
+
m = n; /* header is at front ... */
*off = 0; /* ... of new mbuf */
}
+ V_ipsec4stat.ips_mbinserted++;
} else {
/*
* Copy the remainder to the back of the mbuf
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 5728427..ec6b41e 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -791,14 +791,14 @@ ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp, int
RTFREE(state->ro->ro_rt);
state->ro->ro_rt = NULL;
}
- if (state->ro->ro_rt == 0) {
+ if (state->ro->ro_rt == NULL) {
bzero(dst6, sizeof(*dst6));
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(*dst6);
dst6->sin6_addr = ip6->ip6_dst;
rtalloc(state->ro);
}
- if (state->ro->ro_rt == 0) {
+ if (state->ro->ro_rt == NULL) {
V_ip6stat.ip6s_noroute++;
V_ipsec6stat.ips_out_noroute++;
error = EHOSTUNREACH;
diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c
index a9492dc..7b8b92b 100644
--- a/sys/netipsec/xform_ipip.c
+++ b/sys/netipsec/xform_ipip.c
@@ -660,22 +660,24 @@ static struct xformsw ipe4_xformsw = {
};
extern struct domain inetdomain;
-static struct protosw ipe4_protosw =
-{ SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
- ip4_input,
- 0, 0, rip_ctloutput,
- 0,
- 0, 0, 0, 0,
- &rip_usrreqs
+static struct protosw ipe4_protosw = {
+ .pr_type = SOCK_RAW,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_IPV4,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+ .pr_input = ip4_input,
+ .pr_ctloutput = rip_ctloutput,
+ .pr_usrreqs = &rip_usrreqs
};
#ifdef INET6
-static struct ip6protosw ipe6_protosw =
-{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR|PR_LASTHDR,
- ip4_input6,
- 0, 0, rip_ctloutput,
- 0,
- 0, 0, 0, 0,
- &rip_usrreqs
+static struct ip6protosw ipe6_protosw = {
+ .pr_type = SOCK_RAW,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_IPV6,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+ .pr_input = ip4_input6,
+ .pr_ctloutput = rip_ctloutput,
+ .pr_usrreqs = &rip_usrreqs
};
#endif
diff --git a/sys/nfs4client/nfs4_subs.c b/sys/nfs4client/nfs4_subs.c
index a08240a..21c89c9 100644
--- a/sys/nfs4client/nfs4_subs.c
+++ b/sys/nfs4client/nfs4_subs.c
@@ -668,7 +668,7 @@ nfsm_v4build_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c,
nfsm_buildf_xx(mb, bpos, "s", strlen(c->linktext), c->linktext);
else if (c->type == NFCHR || c->type == NFBLK)
nfsm_buildf_xx(mb, bpos, "uu",
- umajor(c->vap->va_rdev), uminor(c->vap->va_rdev));
+ major(c->vap->va_rdev), minor(c->vap->va_rdev));
/* Name */
nfsm_buildf_xx(mb, bpos, "s", c->namelen, c->name);
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 00332f0..9118d30 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -976,39 +976,43 @@ nfs_mount(struct mount *mp, struct thread *td)
}
if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acregmin);
- if (ret != 1 || args.acregmin <= 0) {
+ if (ret != 1 || args.acregmin < 0) {
vfs_mount_error(mp, "illegal acregmin: %s",
opt);
error = EINVAL;
goto out;
}
+ args.flags |= NFSMNT_ACREGMIN;
}
if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acregmax);
- if (ret != 1 || args.acregmax <= 0) {
+ if (ret != 1 || args.acregmax < 0) {
vfs_mount_error(mp, "illegal acregmax: %s",
opt);
error = EINVAL;
goto out;
}
+ args.flags |= NFSMNT_ACREGMAX;
}
if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acdirmin);
- if (ret != 1 || args.acdirmin <= 0) {
+ if (ret != 1 || args.acdirmin < 0) {
vfs_mount_error(mp, "illegal acdirmin: %s",
opt);
error = EINVAL;
goto out;
}
+ args.flags |= NFSMNT_ACDIRMIN;
}
if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.acdirmax);
- if (ret != 1 || args.acdirmax <= 0) {
+ if (ret != 1 || args.acdirmax < 0) {
vfs_mount_error(mp, "illegal acdirmax: %s",
opt);
error = EINVAL;
goto out;
}
+ args.flags |= NFSMNT_ACDIRMAX;
}
if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
ret = sscanf(opt, "%d", &args.deadthresh);
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 7399470..e56e4eb 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -707,9 +707,9 @@ nfs_setattr(struct vop_setattr_args *ap)
#endif
/*
- * Setting of flags and marking of atimes are not supported.
+ * Setting of flags is not supported.
*/
- if (vap->va_flags != VNOVAL || (vap->va_vaflags & VA_MARK_ATIME))
+ if (vap->va_flags != VNOVAL)
return (EOPNOTSUPP);
/*
@@ -1314,8 +1314,8 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
nfsm_v3attrbuild(vap, FALSE);
if (vap->va_type == VCHR || vap->va_type == VBLK) {
tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = txdr_unsigned(umajor(vap->va_rdev));
- *tl = txdr_unsigned(uminor(vap->va_rdev));
+ *tl++ = txdr_unsigned(major(vap->va_rdev));
+ *tl = txdr_unsigned(minor(vap->va_rdev));
}
} else {
sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index 49c6c16..00e5216 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -1057,8 +1057,8 @@ nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap,
fp->fa_mode = vtonfsv3_mode(vap->va_mode);
txdr_hyper(vap->va_size, &fp->fa3_size);
txdr_hyper(vap->va_bytes, &fp->fa3_used);
- fp->fa3_rdev.specdata1 = txdr_unsigned(umajor(vap->va_rdev));
- fp->fa3_rdev.specdata2 = txdr_unsigned(uminor(vap->va_rdev));
+ fp->fa3_rdev.specdata1 = txdr_unsigned(major(vap->va_rdev));
+ fp->fa3_rdev.specdata2 = txdr_unsigned(minor(vap->va_rdev));
fp->fa3_fsid.nfsuquad[0] = 0;
fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(vap->va_fsid);
fp->fa3_fileid.nfsuquad[0] = 0;
diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index 6a802a1..2769be6 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -433,12 +433,17 @@ swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
break;
case CRYPTO_MD5_KPDK:
case CRYPTO_SHA1_KPDK:
+ {
+ /* We need a buffer that can hold an md5 and a sha1 result. */
+ u_char buf[SHA1_RESULTLEN];
+
sw->sw_klen = klen;
bcopy(key, sw->sw_octx, klen);
axf->Init(sw->sw_ictx);
axf->Update(sw->sw_ictx, key, klen);
- axf->Final(NULL, sw->sw_ictx);
+ axf->Final(buf, sw->sw_ictx);
break;
+ }
default:
printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
"doesn't use keys.\n", __func__, axf->type);
@@ -981,7 +986,7 @@ done:
}
static void
-swcr_identify(device_t *dev, device_t parent)
+swcr_identify(driver_t *drv, device_t parent)
{
/* NB: order 10 is so we get attached after h/w devices */
if (device_find_child(parent, "cryptosoft", -1) == NULL &&
@@ -1035,12 +1040,13 @@ swcr_attach(device_t dev)
return 0;
}
-static void
+static int
swcr_detach(device_t dev)
{
crypto_unregister_all(swcr_id);
if (swcr_sessions != NULL)
free(swcr_sessions, M_CRYPTO_DATA);
+ return 0;
}
static device_method_t swcr_methods[] = {
diff --git a/sys/pc98/cbus/scterm-sck.c b/sys/pc98/cbus/scterm-sck.c
index ced4a92..2577f66 100644
--- a/sys/pc98/cbus/scterm-sck.c
+++ b/sys/pc98/cbus/scterm-sck.c
@@ -37,9 +37,7 @@
#include <machine/pc/display.h>
#include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
-
-#ifndef SC_DUMB_TERMINAL
+#include <pc98/cbus/sctermvar.h>
#define MAX_ESC_PAR 5
@@ -1212,5 +1210,3 @@ mask2attr(term_stat *tcp)
return (attr << 8);
}
-
-#endif /* SC_DUMB_TERMINAL */
diff --git a/sys/dev/syscons/sctermvar.h b/sys/pc98/cbus/sctermvar.h
index b1c01af..b1c01af 100644
--- a/sys/dev/syscons/sctermvar.h
+++ b/sys/pc98/cbus/sctermvar.h
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index b8a2ec6..d9dafa6 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -1,8 +1,8 @@
#
# GENERIC -- Generic kernel configuration file for FreeBSD/pc98
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -26,6 +26,12 @@ ident GENERIC
# To statically compile in device wiring instead of /boot/device.hints
#hints "GENERIC.hints" # Default places to look for devices.
+# Use the following to compile in values accessible to the kernel
+# through getenv() (or kenv(1) in userland). The format of the file
+# is 'variable=value', see kenv(1)
+#
+# env "GENERIC.env"
+
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options SCHED_4BSD # 4BSD scheduler
diff --git a/sys/pc98/conf/NOTES b/sys/pc98/conf/NOTES
index e54fc15..4a7b26e 100644
--- a/sys/pc98/conf/NOTES
+++ b/sys/pc98/conf/NOTES
@@ -271,6 +271,9 @@ device isa
# BROKEN_KEYBOARD_RESET disables the use of the keyboard controller to
# reset the CPU for reboot. This is needed on some systems with broken
# keyboard controllers.
+#
+# EPSON_BOUNCEDMA: XXX
+# EPSON_MEMWIN: XXX
options AUTO_EOI_1
@@ -288,6 +291,9 @@ device pci
# AGP GART support
device agp
+# AGP debugging.
+options AGP_DEBUG
+
#####################################################################
# HARDWARE DEVICE CONFIGURATION
@@ -365,7 +371,6 @@ hint.mse.0.irq="13"
# ar: Arnet SYNC/570i hdlc sync 2/4 port V.35/X.21 serial driver
# (requires sppp)
-# ath: Atheros a/b/g WiFi adapters (requires ath_hal and wlan)
# ce: Cronyx Tau-PCI/32 sync single/dual port G.703/E1 serial adaptor
# with 32 HDLC subchannels (requires sppp (default), or NETGRAPH if
# NETGRAPH_CRONYX is configured)
@@ -379,10 +384,13 @@ hint.mse.0.irq="13"
# (requires miibus)
# ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210;
# Intel EtherExpress
+# le: AMD Am7900 LANCE and Am79C9xx ILACC/PCnet Ethernet interface driver
# ral: Ralink Technology IEEE 802.11 wireless adapter
# sbni: Granch SBNI12-xx ISA and PCI adapters
+# snc: National Semiconductor DP8393X SONIC Ethernet adapter driver
# sr: RISCom/N2 hdlc sync 1/2 port V.35/X.21 serial driver (requires sppp)
# ural: Ralink Technology RT2500USB IEEE 802.11 wireless adapter
+# ath: Atheros a/b/g WiFi adapters (requires ath_hal and wlan)
# Order for ISA/EISA devices is important here
@@ -400,6 +408,7 @@ hint.ie.2.at="isa"
hint.ie.2.port="0x300"
hint.ie.2.irq="5"
hint.ie.2.maddr="0xd0000"
+#device le
# Hint for the PC98-only C-NET(98)S C-bus front-end of le(4).
hint.le.0.at="isa"
hint.le.0.port="0x03d0"
@@ -461,8 +470,13 @@ options SAFE_RNDTEST # enable rndtest support
# Miscellaneous hardware:
#
# apm: Laptop Advanced Power Management (experimental)
+# canbus: CanBe I/O Bus
+# canbepm: CanBe Power Management Controller
+# olpt: XXX
+# pmc: Power Management Controller of NEC PC-98Note
# pmtimer: Timer device driver for power management events (APM or ACPI)
-
+# Adjusts system timer at wakeup time
+#
# Notes on APM
# The flags takes the following meaning for apm0:
# 0x0020 Statclock is broken.
@@ -477,7 +491,7 @@ hint.olpt.0.port="0x040"
device pmc
hint.pmc.0.at="isa"
hint.pmc.0.port="0x8f0"
-device pmtimer # Adjust system timer at wakeup time
+device pmtimer
#
# Laptop/Notebook options:
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index b3569e8..d2f55ce 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -154,8 +154,8 @@
/* Known revision codes. */
#define RL_HWREV_8169 0x00000000
-#define RL_HWREV_8110S 0x00800000
-#define RL_HWREV_8169S 0x04000000
+#define RL_HWREV_8169S 0x00800000
+#define RL_HWREV_8110S 0x04000000
#define RL_HWREV_8169_8110SB 0x10000000
#define RL_HWREV_8169_8110SC 0x18000000
#define RL_HWREV_8102EL 0x24800000
@@ -180,6 +180,7 @@
#define RL_HWREV_8101 0x74c00000
#define RL_HWREV_8100 0x78800000
#define RL_HWREV_8169_8110SBL 0x7CC00000
+#define RL_HWREV_8169_8110SCE 0x98000000
#define RL_TXDMA_16BYTES 0x00000000
#define RL_TXDMA_32BYTES 0x00000100
@@ -879,7 +880,6 @@ struct rl_softc {
int rl_txstart;
uint32_t rl_flags;
#define RL_FLAG_MSI 0x0001
-#define RL_FLAG_INVMAR 0x0004
#define RL_FLAG_PHYWAKE 0x0008
#define RL_FLAG_NOJUMBO 0x0010
#define RL_FLAG_PAR 0x0020
@@ -887,8 +887,7 @@ struct rl_softc {
#define RL_FLAG_MACSTAT 0x0080
#define RL_FLAG_FASTETHER 0x0100
#define RL_FLAG_CMDSTOP 0x0200
-#define RL_FLAG_PHY8169 0x0400
-#define RL_FLAG_PHY8110S 0x0800
+#define RL_FLAG_MACRESET 0x0400
#define RL_FLAG_WOLRXENB 0x1000
#define RL_FLAG_MACSLEEP 0x2000
#define RL_FLAG_PCIE 0x4000
@@ -937,6 +936,7 @@ struct rl_softc {
CSR_WRITE_4(sc, offset, CSR_READ_4(sc, offset) & ~(val))
#define RL_TIMEOUT 1000
+#define RL_PHY_TIMEOUT 2000
/*
* General constants that are fun to know.
diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S
index e4df6af..7034c46 100644
--- a/sys/powerpc/booke/locore.S
+++ b/sys/powerpc/booke/locore.S
@@ -400,6 +400,87 @@ ivor_setup:
blr
/*
+ * void tid_flush(tlbtid_t tid);
+ *
+ * Invalidate all TLB0 entries which match the given TID. Note this is
+ * dedicated for cases when invalidation(s) should NOT be propagated to other
+ * CPUs.
+ *
+ * Global vars tlb0_ways, tlb0_entries_per_way are assumed to have been set up
+ * correctly (by tlb0_get_tlbconf()).
+ *
+ */
+ENTRY(tid_flush)
+ cmpwi %r3, TID_KERNEL
+ beq tid_flush_end /* don't evict kernel translations */
+
+ /* Number of TLB0 ways */
+ lis %r4, tlb0_ways@h
+ ori %r4, %r4, tlb0_ways@l
+ lwz %r4, 0(%r4)
+
+ /* Number of entries / way */
+ lis %r5, tlb0_entries_per_way@h
+ ori %r5, %r5, tlb0_entries_per_way@l
+ lwz %r5, 0(%r5)
+
+ /* Disable interrupts */
+ mfmsr %r10
+ wrteei 0
+
+ li %r6, 0 /* ways counter */
+loop_ways:
+ li %r7, 0 /* entries [per way] counter */
+loop_entries:
+ /* Select TLB0 and ESEL (way) */
+ lis %r8, MAS0_TLBSEL0@h
+ rlwimi %r8, %r6, 16, 14, 15
+ mtspr SPR_MAS0, %r8
+ isync
+
+ /* Select EPN (entry within the way) */
+ rlwinm %r8, %r7, 12, 13, 19
+ mtspr SPR_MAS2, %r8
+ isync
+ tlbre
+
+ /* Check if valid entry */
+ mfspr %r8, SPR_MAS1
+ andis. %r9, %r8, MAS1_VALID@h
+ beq next_entry /* invalid entry */
+
+ /* Check if this is our TID */
+ rlwinm %r9, %r8, 16, 24, 31
+
+ cmplw %r9, %r3
+ bne next_entry /* not our TID */
+
+ /* Clear VALID bit */
+ rlwinm %r8, %r8, 0, 1, 31
+ mtspr SPR_MAS1, %r8
+ isync
+ tlbwe
+ isync
+ msync
+
+next_entry:
+ addi %r7, %r7, 1
+ cmpw %r7, %r5
+ bne loop_entries
+
+ /* Next way */
+ addi %r6, %r6, 1
+ cmpw %r6, %r4
+ bne loop_ways
+
+ /* Restore MSR (possibly re-enable interrupts) */
+ mtmsr %r10
+ isync
+
+tid_flush_end:
+ blr
+
+/*
* Cache disable/enable/inval sequences according
* to section 2.16 of E500CORE RM.
*/
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index a48ece1..1803ef2 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -490,6 +490,7 @@ void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
{
+ pcpu->pc_tid_next = TID_MIN;
}
/* Set set up registers on exec. */
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index ce09a83..72964f7 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (C) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * Copyright (C) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
* Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com>
* All rights reserved.
*
@@ -11,8 +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. 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
@@ -38,15 +36,16 @@
*
* Virtual address space layout:
* -----------------------------
- * 0x0000_0000 - 0xbfff_efff : user process
- * 0xc000_0000 - 0xc1ff_ffff : kernel reserved
- * 0xc000_0000 - kernelend : kernel code &data
- * 0xc1ff_c000 - 0xc200_0000 : kstack0
- * 0xc200_0000 - 0xffef_ffff : KVA
- * 0xc200_0000 - 0xc200_3fff : reserved for page zero/copy
- * 0xc200_4000 - ptbl buf end: reserved for ptbl bufs
- * ptbl buf end- 0xffef_ffff : actual free KVA space
- * 0xfff0_0000 - 0xffff_ffff : I/O devices region
+ * 0x0000_0000 - 0xafff_ffff : user process
+ * 0xb000_0000 - 0xbfff_ffff : pmap_mapdev()-ed area (PCI/PCIE etc.)
+ * 0xc000_0000 - 0xc0ff_ffff : kernel reserved
+ * 0xc000_0000 - kernelend : kernel code+data, env, metadata etc.
+ * 0xc100_0000 - 0xfeef_ffff : KVA
+ * 0xc100_0000 - 0xc100_3fff : reserved for page zero/copy
+ * 0xc100_4000 - 0xc200_3fff : reserved for ptbl bufs
+ * 0xc200_4000 - 0xc200_8fff : guard page + kstack0
+ * 0xc200_9000 - 0xfeef_ffff : actual free KVA space
+ * 0xfef0_0000 - 0xffff_ffff : I/O devices region
*/
#include <sys/cdefs.h>
@@ -55,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/malloc.h>
+#include <sys/ktr.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/queue.h>
@@ -118,6 +118,8 @@ int availmem_regions_sz;
static vm_offset_t zero_page_va;
static struct mtx zero_page_mutex;
+static struct mtx tlbivax_mutex;
+
/*
* Reserved KVA space for mmu_booke_zero_page_idle. This is used
* by idle thred only, no lock required.
@@ -148,55 +150,42 @@ static int pagedaemon_waken;
#define PMAP_REMOVE_DONE(pmap) \
((pmap) != kernel_pmap && (pmap)->pm_stats.resident_count == 0)
-extern void load_pid0(tlbtid_t);
+extern void tlb_lock(uint32_t *);
+extern void tlb_unlock(uint32_t *);
+extern void tid_flush(tlbtid_t);
/**************************************************************************/
/* TLB and TID handling */
/**************************************************************************/
/* Translation ID busy table */
-static volatile pmap_t tidbusy[TID_MAX + 1];
+static volatile pmap_t tidbusy[MAXCPU][TID_MAX + 1];
/*
- * Actual maximum number of TLB0 entries.
- * This number differs between e500 core revisions.
+ * TLB0 capabilities (entry, way numbers etc.). These can vary between e500
+ * core revisions and should be read from h/w registers during early config.
*/
-u_int32_t tlb0_size;
-u_int32_t tlb0_nways;
-u_int32_t tlb0_nentries_per_way;
-
-#define TLB0_SIZE (tlb0_size)
-#define TLB0_NWAYS (tlb0_nways)
-#define TLB0_ENTRIES_PER_WAY (tlb0_nentries_per_way)
-
-/* Pointer to kernel tlb0 table, allocated in mmu_booke_bootstrap() */
-tlb_entry_t *tlb0;
+uint32_t tlb0_entries;
+uint32_t tlb0_ways;
+uint32_t tlb0_entries_per_way;
-/*
- * Spinlock to assure proper locking between threads and
- * between tlb miss handler and kernel.
- */
-static struct mtx tlb0_mutex;
+#define TLB0_ENTRIES (tlb0_entries)
+#define TLB0_WAYS (tlb0_ways)
+#define TLB0_ENTRIES_PER_WAY (tlb0_entries_per_way)
-#define TLB1_SIZE 16
+#define TLB1_ENTRIES 16
/* In-ram copy of the TLB1 */
-static tlb_entry_t tlb1[TLB1_SIZE];
+static tlb_entry_t tlb1[TLB1_ENTRIES];
/* Next free entry in the TLB1 */
static unsigned int tlb1_idx;
static tlbtid_t tid_alloc(struct pmap *);
-static void tid_flush(tlbtid_t);
-extern void tlb1_inval_va(vm_offset_t);
-extern void tlb0_inval_va(vm_offset_t);
+static void tlb_print_entry(int, uint32_t, uint32_t, uint32_t, uint32_t);
-static void tlb_print_entry(int, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
-
-static int tlb1_set_entry(vm_offset_t, vm_offset_t, vm_size_t, u_int32_t);
-static void __tlb1_set_entry(unsigned int, vm_offset_t, vm_offset_t,
- vm_size_t, u_int32_t, unsigned int, unsigned int);
+static int tlb1_set_entry(vm_offset_t, vm_offset_t, vm_size_t, uint32_t);
static void tlb1_write_entry(unsigned int);
static int tlb1_iomapped(int, vm_paddr_t, vm_size_t, vm_offset_t *);
static vm_size_t tlb1_mapin_region(vm_offset_t, vm_offset_t, vm_size_t);
@@ -207,11 +196,8 @@ static unsigned int ilog2(unsigned int);
static void set_mas4_defaults(void);
-static void tlb0_inval_entry(vm_offset_t, unsigned int);
+static inline void tlb0_flush_entry(vm_offset_t);
static inline unsigned int tlb0_tableidx(vm_offset_t, unsigned int);
-static void tlb0_write_entry(unsigned int, unsigned int);
-static void tlb0_flush_entry(pmap_t, vm_offset_t);
-static void tlb0_init(void);
/**************************************************************************/
/* Page table management */
@@ -233,17 +219,17 @@ static struct ptbl_buf *ptbl_buf_alloc(void);
static void ptbl_buf_free(struct ptbl_buf *);
static void ptbl_free_pmap_ptbl(pmap_t, pte_t *);
-static void ptbl_alloc(mmu_t, pmap_t, unsigned int);
+static pte_t *ptbl_alloc(mmu_t, pmap_t, unsigned int);
static void ptbl_free(mmu_t, pmap_t, unsigned int);
static void ptbl_hold(mmu_t, pmap_t, unsigned int);
static int ptbl_unhold(mmu_t, pmap_t, unsigned int);
static vm_paddr_t pte_vatopa(mmu_t, pmap_t, vm_offset_t);
static pte_t *pte_find(mmu_t, pmap_t, vm_offset_t);
-void pte_enter(mmu_t, pmap_t, vm_page_t, vm_offset_t, u_int32_t);
-static int pte_remove(mmu_t, pmap_t, vm_offset_t, u_int8_t);
+static void pte_enter(mmu_t, pmap_t, vm_page_t, vm_offset_t, uint32_t);
+static int pte_remove(mmu_t, pmap_t, vm_offset_t, uint8_t);
-pv_entry_t pv_alloc(void);
+static pv_entry_t pv_alloc(void);
static void pv_free(pv_entry_t);
static void pv_insert(pmap_t, vm_offset_t, vm_page_t);
static void pv_remove(pmap_t, vm_offset_t, vm_page_t);
@@ -384,9 +370,9 @@ tlb0_get_tlbconf(void)
uint32_t tlb0_cfg;
tlb0_cfg = mfspr(SPR_TLB0CFG);
- tlb0_size = tlb0_cfg & TLBCFG_NENTRY_MASK;
- tlb0_nways = (tlb0_cfg & TLBCFG_ASSOC_MASK) >> TLBCFG_ASSOC_SHIFT;
- tlb0_nentries_per_way = tlb0_size/tlb0_nways;
+ tlb0_entries = tlb0_cfg & TLBCFG_NENTRY_MASK;
+ tlb0_ways = (tlb0_cfg & TLBCFG_ASSOC_MASK) >> TLBCFG_ASSOC_SHIFT;
+ tlb0_entries_per_way = tlb0_entries / tlb0_ways;
}
/* Initialize pool of kva ptbl buffers. */
@@ -395,10 +381,10 @@ ptbl_init(void)
{
int i;
- //debugf("ptbl_init: s (ptbl_bufs = 0x%08x size 0x%08x)\n",
- // (u_int32_t)ptbl_bufs, sizeof(struct ptbl_buf) * PTBL_BUFS);
- //debugf("ptbl_init: s (ptbl_buf_pool_vabase = 0x%08x size = 0x%08x)\n",
- // ptbl_buf_pool_vabase, PTBL_BUFS * PTBL_PAGES * PAGE_SIZE);
+ CTR3(KTR_PMAP, "%s: s (ptbl_bufs = 0x%08x size 0x%08x)", __func__,
+ (uint32_t)ptbl_bufs, sizeof(struct ptbl_buf) * PTBL_BUFS);
+ CTR3(KTR_PMAP, "%s: s (ptbl_buf_pool_vabase = 0x%08x size = 0x%08x)",
+ __func__, ptbl_buf_pool_vabase, PTBL_BUFS * PTBL_PAGES * PAGE_SIZE);
mtx_init(&ptbl_buf_freelist_lock, "ptbl bufs lock", NULL, MTX_DEF);
TAILQ_INIT(&ptbl_buf_freelist);
@@ -407,8 +393,6 @@ ptbl_init(void)
ptbl_bufs[i].kva = ptbl_buf_pool_vabase + i * PTBL_PAGES * PAGE_SIZE;
TAILQ_INSERT_TAIL(&ptbl_buf_freelist, &ptbl_bufs[i], link);
}
-
- //debugf("ptbl_init: e\n");
}
/* Get a ptbl_buf from the freelist. */
@@ -417,15 +401,14 @@ ptbl_buf_alloc(void)
{
struct ptbl_buf *buf;
- //debugf("ptbl_buf_alloc: s\n");
-
mtx_lock(&ptbl_buf_freelist_lock);
buf = TAILQ_FIRST(&ptbl_buf_freelist);
if (buf != NULL)
TAILQ_REMOVE(&ptbl_buf_freelist, buf, link);
mtx_unlock(&ptbl_buf_freelist_lock);
- //debugf("ptbl_buf_alloc: e (buf = 0x%08x)\n", (u_int32_t)buf);
+ CTR2(KTR_PMAP, "%s: buf = %p", __func__, buf);
+
return (buf);
}
@@ -434,54 +417,49 @@ static void
ptbl_buf_free(struct ptbl_buf *buf)
{
- //debugf("ptbl_buf_free: s (buf = 0x%08x)\n", (u_int32_t)buf);
+ CTR2(KTR_PMAP, "%s: buf = %p", __func__, buf);
mtx_lock(&ptbl_buf_freelist_lock);
TAILQ_INSERT_TAIL(&ptbl_buf_freelist, buf, link);
mtx_unlock(&ptbl_buf_freelist_lock);
-
- //debugf("ptbl_buf_free: e\n");
}
/*
- * Search the list of allocated ptbl bufs and find
- * on list of allocated ptbls
+ * Search the list of allocated ptbl bufs and find on list of allocated ptbls
*/
static void
ptbl_free_pmap_ptbl(pmap_t pmap, pte_t *ptbl)
{
struct ptbl_buf *pbuf;
- //debugf("ptbl_free_pmap_ptbl: s (pmap = 0x%08x ptbl = 0x%08x)\n",
- // (u_int32_t)pmap, (u_int32_t)ptbl);
+ CTR2(KTR_PMAP, "%s: ptbl = %p", __func__, ptbl);
- TAILQ_FOREACH(pbuf, &pmap->ptbl_list, link) {
+ PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+
+ TAILQ_FOREACH(pbuf, &pmap->pm_ptbl_list, link)
if (pbuf->kva == (vm_offset_t)ptbl) {
/* Remove from pmap ptbl buf list. */
- TAILQ_REMOVE(&pmap->ptbl_list, pbuf, link);
+ TAILQ_REMOVE(&pmap->pm_ptbl_list, pbuf, link);
- /* Free correspondig ptbl buf. */
+ /* Free corresponding ptbl buf. */
ptbl_buf_free(pbuf);
-
break;
}
- }
-
- //debugf("ptbl_free_pmap_ptbl: e\n");
}
/* Allocate page table. */
-static void
+static pte_t *
ptbl_alloc(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
{
vm_page_t mtbl[PTBL_PAGES];
vm_page_t m;
struct ptbl_buf *pbuf;
unsigned int pidx;
+ pte_t *ptbl;
int i;
- //int su = (pmap == kernel_pmap);
- //debugf("ptbl_alloc: s (pmap = 0x%08x su = %d pdir_idx = %d)\n", (u_int32_t)pmap, su, pdir_idx);
+ CTR4(KTR_PMAP, "%s: pmap = %p su = %d pdir_idx = %d", __func__, pmap,
+ (pmap == kernel_pmap), pdir_idx);
KASSERT((pdir_idx <= (VM_MAXUSER_ADDRESS / PDIR_SIZE)),
("ptbl_alloc: invalid pdir_idx"));
@@ -491,13 +469,17 @@ ptbl_alloc(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
pbuf = ptbl_buf_alloc();
if (pbuf == NULL)
panic("pte_alloc: couldn't alloc kernel virtual memory");
- pmap->pm_pdir[pdir_idx] = (pte_t *)pbuf->kva;
- //debugf("ptbl_alloc: kva = 0x%08x\n", (u_int32_t)pmap->pm_pdir[pdir_idx]);
+
+ ptbl = (pte_t *)pbuf->kva;
+
+ CTR2(KTR_PMAP, "%s: ptbl kva = %p", __func__, ptbl);
/* Allocate ptbl pages, this will sleep! */
for (i = 0; i < PTBL_PAGES; i++) {
pidx = (PTBL_PAGES * pdir_idx) + i;
- while ((m = vm_page_alloc(NULL, pidx, VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) {
+ while ((m = vm_page_alloc(NULL, pidx,
+ VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) {
+
PMAP_UNLOCK(pmap);
vm_page_unlock_queues();
VM_WAIT;
@@ -507,16 +489,16 @@ ptbl_alloc(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
mtbl[i] = m;
}
- /* Map in allocated pages into kernel_pmap. */
- mmu_booke_qenter(mmu, (vm_offset_t)pmap->pm_pdir[pdir_idx], mtbl, PTBL_PAGES);
+ /* Map allocated pages into kernel_pmap. */
+ mmu_booke_qenter(mmu, (vm_offset_t)ptbl, mtbl, PTBL_PAGES);
/* Zero whole ptbl. */
- bzero((caddr_t)pmap->pm_pdir[pdir_idx], PTBL_PAGES * PAGE_SIZE);
+ bzero((caddr_t)ptbl, PTBL_PAGES * PAGE_SIZE);
/* Add pbuf to the pmap ptbl bufs list. */
- TAILQ_INSERT_TAIL(&pmap->ptbl_list, pbuf, link);
+ TAILQ_INSERT_TAIL(&pmap->pm_ptbl_list, pbuf, link);
- //debugf("ptbl_alloc: e\n");
+ return (ptbl);
}
/* Free ptbl pages and invalidate pdir entry. */
@@ -529,17 +511,28 @@ ptbl_free(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
vm_page_t m;
int i;
- //int su = (pmap == kernel_pmap);
- //debugf("ptbl_free: s (pmap = 0x%08x su = %d pdir_idx = %d)\n", (u_int32_t)pmap, su, pdir_idx);
+ CTR4(KTR_PMAP, "%s: pmap = %p su = %d pdir_idx = %d", __func__, pmap,
+ (pmap == kernel_pmap), pdir_idx);
KASSERT((pdir_idx <= (VM_MAXUSER_ADDRESS / PDIR_SIZE)),
("ptbl_free: invalid pdir_idx"));
ptbl = pmap->pm_pdir[pdir_idx];
- //debugf("ptbl_free: ptbl = 0x%08x\n", (u_int32_t)ptbl);
+ CTR2(KTR_PMAP, "%s: ptbl = %p", __func__, ptbl);
+
KASSERT((ptbl != NULL), ("ptbl_free: null ptbl"));
+ /*
+ * Invalidate the pdir entry as soon as possible, so that other CPUs
+ * don't attempt to look up the page tables we are releasing.
+ */
+ mtx_lock_spin(&tlbivax_mutex);
+
+ pmap->pm_pdir[pdir_idx] = NULL;
+
+ mtx_unlock_spin(&tlbivax_mutex);
+
for (i = 0; i < PTBL_PAGES; i++) {
va = ((vm_offset_t)ptbl + (i * PAGE_SIZE));
pa = pte_vatopa(mmu, kernel_pmap, va);
@@ -550,9 +543,6 @@ ptbl_free(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
}
ptbl_free_pmap_ptbl(pmap, ptbl);
- pmap->pm_pdir[pdir_idx] = NULL;
-
- //debugf("ptbl_free: e\n");
}
/*
@@ -569,9 +559,8 @@ ptbl_unhold(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
vm_page_t m;
int i;
- //int su = (pmap == kernel_pmap);
- //debugf("ptbl_unhold: s (pmap = %08x su = %d pdir_idx = %d)\n",
- // (u_int32_t)pmap, su, pdir_idx);
+ CTR4(KTR_PMAP, "%s: pmap = %p su = %d pdir_idx = %d", __func__, pmap,
+ (pmap == kernel_pmap), pdir_idx);
KASSERT((pdir_idx <= (VM_MAXUSER_ADDRESS / PDIR_SIZE)),
("ptbl_unhold: invalid pdir_idx"));
@@ -586,15 +575,16 @@ ptbl_unhold(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
/* decrement hold count */
for (i = 0; i < PTBL_PAGES; i++) {
- pa = pte_vatopa(mmu, kernel_pmap, (vm_offset_t)ptbl + (i * PAGE_SIZE));
+ pa = pte_vatopa(mmu, kernel_pmap,
+ (vm_offset_t)ptbl + (i * PAGE_SIZE));
m = PHYS_TO_VM_PAGE(pa);
m->wire_count--;
}
/*
* Free ptbl pages if there are no pte etries in this ptbl.
- * wire_count has the same value for all ptbl pages, so check
- * the last page.
+ * wire_count has the same value for all ptbl pages, so check the last
+ * page.
*/
if (m->wire_count == 0) {
ptbl_free(mmu, pmap, pdir_idx);
@@ -603,13 +593,12 @@ ptbl_unhold(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
return (1);
}
- //debugf("ptbl_unhold: e\n");
return (0);
}
/*
- * Increment hold count for ptbl pages. This routine is used when
- * new pte entry is being inserted into ptbl.
+ * Increment hold count for ptbl pages. This routine is used when a new pte
+ * entry is being inserted into the ptbl.
*/
static void
ptbl_hold(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
@@ -619,7 +608,8 @@ ptbl_hold(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
vm_page_t m;
int i;
- //debugf("ptbl_hold: s (pmap = 0x%08x pdir_idx = %d)\n", (u_int32_t)pmap, pdir_idx);
+ CTR3(KTR_PMAP, "%s: pmap = %p pdir_idx = %d", __func__, pmap,
+ pdir_idx);
KASSERT((pdir_idx <= (VM_MAXUSER_ADDRESS / PDIR_SIZE)),
("ptbl_hold: invalid pdir_idx"));
@@ -631,12 +621,11 @@ ptbl_hold(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx)
KASSERT((ptbl != NULL), ("ptbl_hold: null ptbl"));
for (i = 0; i < PTBL_PAGES; i++) {
- pa = pte_vatopa(mmu, kernel_pmap, (vm_offset_t)ptbl + (i * PAGE_SIZE));
+ pa = pte_vatopa(mmu, kernel_pmap,
+ (vm_offset_t)ptbl + (i * PAGE_SIZE));
m = PHYS_TO_VM_PAGE(pa);
m->wire_count++;
}
-
- //debugf("ptbl_hold: e\n");
}
/* Allocate pv_entry structure. */
@@ -645,16 +634,14 @@ pv_alloc(void)
{
pv_entry_t pv;
- debugf("pv_alloc: s\n");
-
pv_entry_count++;
- if ((pv_entry_count > pv_entry_high_water) && (pagedaemon_waken == 0)) {
+ if ((pv_entry_count > pv_entry_high_water) &&
+ (pagedaemon_waken == 0)) {
pagedaemon_waken = 1;
- wakeup (&vm_pages_needed);
+ wakeup(&vm_pages_needed);
}
pv = uma_zalloc(pvzone, M_NOWAIT);
- debugf("pv_alloc: e\n");
return (pv);
}
@@ -662,12 +649,9 @@ pv_alloc(void)
static __inline void
pv_free(pv_entry_t pve)
{
- //debugf("pv_free: s\n");
pv_entry_count--;
uma_zfree(pvzone, pve);
-
- //debugf("pv_free: e\n");
}
@@ -719,7 +703,6 @@ pv_remove(pmap_t pmap, vm_offset_t va, vm_page_t m)
/* free pv entry struct */
pv_free(pve);
-
break;
}
}
@@ -733,7 +716,7 @@ pv_remove(pmap_t pmap, vm_offset_t va, vm_page_t m)
* Return 1 if ptbl pages were freed, otherwise return 0.
*/
static int
-pte_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, u_int8_t flags)
+pte_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, uint8_t flags)
{
unsigned int pdir_idx = PDIR_IDX(va);
unsigned int ptbl_idx = PTBL_IDX(va);
@@ -776,8 +759,14 @@ pte_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, u_int8_t flags)
}
}
+ mtx_lock_spin(&tlbivax_mutex);
+
+ tlb0_flush_entry(va);
pte->flags = 0;
pte->rpn = 0;
+
+ mtx_unlock_spin(&tlbivax_mutex);
+
pmap->pm_stats.resident_count--;
if (flags & PTBL_UNHOLD) {
@@ -792,21 +781,23 @@ pte_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, u_int8_t flags)
/*
* Insert PTE for a given page and virtual address.
*/
-void
-pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offset_t va, u_int32_t flags)
+static void
+pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offset_t va, uint32_t flags)
{
unsigned int pdir_idx = PDIR_IDX(va);
unsigned int ptbl_idx = PTBL_IDX(va);
- pte_t *ptbl;
- pte_t *pte;
+ pte_t *ptbl, *pte;
- //int su = (pmap == kernel_pmap);
- //debugf("pte_enter: s (su = %d pmap = 0x%08x va = 0x%08x)\n", su, (u_int32_t)pmap, va);
+ CTR4(KTR_PMAP, "%s: su = %d pmap = %p va = %p", __func__,
+ pmap == kernel_pmap, pmap, va);
/* Get the page table pointer. */
ptbl = pmap->pm_pdir[pdir_idx];
- if (ptbl) {
+ if (ptbl == NULL) {
+ /* Allocate page table pages. */
+ ptbl = ptbl_alloc(mmu, pmap, pdir_idx);
+ } else {
/*
* Check if there is valid mapping for requested
* va, if there is, remove it.
@@ -822,36 +813,40 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offset_t va, u_int32_t flags)
if (pmap != kernel_pmap)
ptbl_hold(mmu, pmap, pdir_idx);
}
- } else {
- /* Allocate page table pages. */
- ptbl_alloc(mmu, pmap, pdir_idx);
}
- /* Flush entry from TLB. */
- tlb0_flush_entry(pmap, va);
-
- pte = &(pmap->pm_pdir[pdir_idx][ptbl_idx]);
-
/*
- * Insert pv_entry into pv_list for mapped page
- * if part of managed memory.
+ * Insert pv_entry into pv_list for mapped page if part of managed
+ * memory.
*/
if ((m->flags & PG_FICTITIOUS) == 0) {
if ((m->flags & PG_UNMANAGED) == 0) {
- pte->flags |= PTE_MANAGED;
+ flags |= PTE_MANAGED;
/* Create and insert pv entry. */
pv_insert(pmap, va, m);
}
} else {
- pte->flags |= PTE_FAKE;
+ flags |= PTE_FAKE;
}
pmap->pm_stats.resident_count++;
+
+ mtx_lock_spin(&tlbivax_mutex);
+
+ tlb0_flush_entry(va);
+ if (pmap->pm_pdir[pdir_idx] == NULL) {
+ /*
+ * If we just allocated a new page table, hook it in
+ * the pdir.
+ */
+ pmap->pm_pdir[pdir_idx] = ptbl;
+ }
+ pte = &(pmap->pm_pdir[pdir_idx][ptbl_idx]);
pte->rpn = VM_PAGE_TO_PHYS(m) & ~PTE_PA_MASK;
pte->flags |= (PTE_VALID | flags);
- //debugf("pte_enter: e\n");
+ mtx_unlock_spin(&tlbivax_mutex);
}
/* Return the pa for the given pmap/va. */
@@ -903,6 +898,12 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
debugf("mmu_booke_bootstrap: entered\n");
+ /* Initialize invalidation mutex */
+ mtx_init(&tlbivax_mutex, "tlbivax", NULL, MTX_SPIN);
+
+ /* Read TLB0 size and associativity. */
+ tlb0_get_tlbconf();
+
/* Align kernel start and end address (kernel image). */
kernelstart = trunc_page(kernelstart);
kernelend = round_page(kernelend);
@@ -910,23 +911,15 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
/* Allocate space for the message buffer. */
msgbufp = (struct msgbuf *)kernelend;
kernelend += MSGBUF_SIZE;
- debugf(" msgbufp at 0x%08x end = 0x%08x\n", (u_int32_t)msgbufp,
+ debugf(" msgbufp at 0x%08x end = 0x%08x\n", (uint32_t)msgbufp,
kernelend);
kernelend = round_page(kernelend);
- /* Allocate space for tlb0 table. */
- tlb0_get_tlbconf(); /* Read TLB0 size and associativity. */
- tlb0 = (tlb_entry_t *)kernelend;
- kernelend += sizeof(tlb_entry_t) * tlb0_size;
- debugf(" tlb0 at 0x%08x end = 0x%08x\n", (u_int32_t)tlb0, kernelend);
-
- kernelend = round_page(kernelend);
-
/* Allocate space for ptbl_bufs. */
ptbl_bufs = (struct ptbl_buf *)kernelend;
kernelend += sizeof(struct ptbl_buf) * PTBL_BUFS;
- debugf(" ptbl_bufs at 0x%08x end = 0x%08x\n", (u_int32_t)ptbl_bufs,
+ debugf(" ptbl_bufs at 0x%08x end = 0x%08x\n", (uint32_t)ptbl_bufs,
kernelend);
kernelend = round_page(kernelend);
@@ -937,8 +930,9 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
PDIR_SIZE - 1) / PDIR_SIZE;
kernelend += kernel_ptbls * PTBL_PAGES * PAGE_SIZE;
debugf(" kernel ptbls: %d\n", kernel_ptbls);
- debugf(" kernel pdir at 0x%08x\n", kernel_pdir);
+ debugf(" kernel pdir at 0x%08x end = 0x%08x\n", kernel_pdir, kernelend);
+ debugf(" kernelend: 0x%08x\n", kernelend);
if (kernelend - kernelstart > 0x1000000) {
kernelend = (kernelend + 0x3fffff) & ~0x3fffff;
tlb1_mapin_region(kernelstart + 0x1000000,
@@ -946,12 +940,13 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
} else
kernelend = (kernelend + 0xffffff) & ~0xffffff;
+ debugf(" updated kernelend: 0x%08x\n", kernelend);
+
/*
* Clear the structures - note we can only do it safely after the
- * possible additional TLB1 translations are in place so that
+ * possible additional TLB1 translations are in place (above) so that
* all range up to the currently calculated 'kernelend' is covered.
*/
- memset((void *)tlb0, 0, sizeof(tlb_entry_t) * tlb0_size);
memset((void *)ptbl_bufs, 0, sizeof(struct ptbl_buf) * PTBL_SIZE);
memset((void *)kernel_pdir, 0, kernel_ptbls * PTBL_PAGES * PAGE_SIZE);
@@ -970,25 +965,23 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
virtual_avail += PAGE_SIZE;
copy_page_dst_va = virtual_avail;
virtual_avail += PAGE_SIZE;
+ debugf("zero_page_va = 0x%08x\n", zero_page_va);
+ debugf("zero_page_idle_va = 0x%08x\n", zero_page_idle_va);
+ debugf("copy_page_src_va = 0x%08x\n", copy_page_src_va);
+ debugf("copy_page_dst_va = 0x%08x\n", copy_page_dst_va);
/* Initialize page zero/copy mutexes. */
mtx_init(&zero_page_mutex, "mmu_booke_zero_page", NULL, MTX_DEF);
mtx_init(&copy_page_mutex, "mmu_booke_copy_page", NULL, MTX_DEF);
- /* Initialize tlb0 table mutex. */
- mtx_init(&tlb0_mutex, "tlb0", NULL, MTX_SPIN | MTX_RECURSE);
-
/* Allocate KVA space for ptbl bufs. */
ptbl_buf_pool_vabase = virtual_avail;
virtual_avail += PTBL_BUFS * PTBL_PAGES * PAGE_SIZE;
-
- debugf("ptbl_buf_pool_vabase = 0x%08x\n", ptbl_buf_pool_vabase);
- debugf("virtual_avail = %08x\n", virtual_avail);
- debugf("virtual_end = %08x\n", virtual_end);
+ debugf("ptbl_buf_pool_vabase = 0x%08x end = 0x%08x\n",
+ ptbl_buf_pool_vabase, virtual_avail);
/* Calculate corresponding physical addresses for the kernel region. */
phys_kernelend = kernload + (kernelend - kernelstart);
-
debugf("kernel image and allocated data:\n");
debugf(" kernload = 0x%08x\n", kernload);
debugf(" kernelstart = 0x%08x\n", kernelstart);
@@ -999,10 +992,9 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
panic("mmu_booke_bootstrap: phys_avail too small");
/*
- * Removed kernel physical address range from avail
- * regions list. Page align all regions.
- * Non-page aligned memory isn't very interesting to us.
- * Also, sort the entries for ascending addresses.
+ * Remove kernel physical address range from avail regions list. Page
+ * align all regions. Non-page aligned memory isn't very interesting
+ * to us. Also, sort the entries for ascending addresses.
*/
sz = 0;
cnt = availmem_regions_sz;
@@ -1085,7 +1077,8 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
debugf(" region: 0x%08x - 0x%08x (0x%08x)\n",
availmem_regions[i].mr_start,
- availmem_regions[i].mr_start + availmem_regions[i].mr_size,
+ availmem_regions[i].mr_start +
+ availmem_regions[i].mr_size,
availmem_regions[i].mr_size);
if (hwphyssz != 0 &&
@@ -1117,7 +1110,8 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
debugf("Maxmem = 0x%08lx\n", Maxmem);
debugf("phys_avail_count = %d\n", phys_avail_count);
- debugf("physsz = 0x%08x physmem = %ld (0x%08lx)\n", physsz, physmem, physmem);
+ debugf("physsz = 0x%08x physmem = %ld (0x%08lx)\n", physsz, physmem,
+ physmem);
/*******************************************************/
/* Initialize (statically allocated) kernel pmap. */
@@ -1125,8 +1119,8 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
PMAP_LOCK_INIT(kernel_pmap);
kptbl_min = VM_MIN_KERNEL_ADDRESS / PDIR_SIZE;
- debugf("kernel_pmap = 0x%08x\n", (u_int32_t)kernel_pmap);
- debugf("kptbl_min = %d, kernel_kptbls = %d\n", kptbl_min, kernel_ptbls);
+ debugf("kernel_pmap = 0x%08x\n", (uint32_t)kernel_pmap);
+ debugf("kptbl_min = %d, kernel_ptbls = %d\n", kptbl_min, kernel_ptbls);
debugf("kernel pdir range: 0x%08x - 0x%08x\n",
kptbl_min * PDIR_SIZE, (kptbl_min + kernel_ptbls) * PDIR_SIZE - 1);
@@ -1135,15 +1129,19 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
kernel_pmap->pm_pdir[kptbl_min + i] =
(pte_t *)(kernel_pdir + (i * PAGE_SIZE * PTBL_PAGES));
- kernel_pmap->pm_tid = KERNEL_TID;
+ for (i = 0; i < MAXCPU; i++) {
+ kernel_pmap->pm_tid[i] = TID_KERNEL;
+
+ /* Initialize each CPU's tidbusy entry 0 with kernel_pmap */
+ tidbusy[i][0] = kernel_pmap;
+ }
+ /* Mark kernel_pmap active on all CPUs */
kernel_pmap->pm_active = ~0;
- /* Initialize tidbusy with kenel_pmap entry. */
- tidbusy[0] = kernel_pmap;
-
/*******************************************************/
/* Final setup */
/*******************************************************/
+
/* Enter kstack0 into kernel map, provide guard page */
kstack0 = virtual_avail + KSTACK_GUARD_PAGES * PAGE_SIZE;
thread0.td_kstack = kstack0;
@@ -1160,9 +1158,9 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t kernelstart, vm_offset_t kernelend)
kstack0 += PAGE_SIZE;
kstack0_phys += PAGE_SIZE;
}
-
- /* Initialize TLB0 handling. */
- tlb0_init();
+
+ debugf("virtual_avail = %08x\n", virtual_avail);
+ debugf("virtual_end = %08x\n", virtual_end);
debugf("mmu_booke_bootstrap: exit\n");
}
@@ -1203,8 +1201,6 @@ mmu_booke_init(mmu_t mmu)
{
int shpgperproc = PMAP_SHPGPERPROC;
- //debugf("mmu_booke_init: s\n");
-
/*
* Initialize the address space (zone) for the pv entries. Set a
* high water mark so that the system can recover from excessive
@@ -1226,8 +1222,6 @@ mmu_booke_init(mmu_t mmu)
/* Initialize ptbl allocation. */
ptbl_init();
-
- //debugf("mmu_booke_init: e\n");
}
/*
@@ -1240,16 +1234,12 @@ mmu_booke_qenter(mmu_t mmu, vm_offset_t sva, vm_page_t *m, int count)
{
vm_offset_t va;
- //debugf("mmu_booke_qenter: s (sva = 0x%08x count = %d)\n", sva, count);
-
va = sva;
while (count-- > 0) {
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(*m));
va += PAGE_SIZE;
m++;
}
-
- //debugf("mmu_booke_qenter: e\n");
}
/*
@@ -1261,15 +1251,11 @@ mmu_booke_qremove(mmu_t mmu, vm_offset_t sva, int count)
{
vm_offset_t va;
- //debugf("mmu_booke_qremove: s (sva = 0x%08x count = %d)\n", sva, count);
-
va = sva;
while (count-- > 0) {
mmu_booke_kremove(mmu, va);
va += PAGE_SIZE;
}
-
- //debugf("mmu_booke_qremove: e\n");
}
/*
@@ -1280,14 +1266,11 @@ mmu_booke_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
{
unsigned int pdir_idx = PDIR_IDX(va);
unsigned int ptbl_idx = PTBL_IDX(va);
- u_int32_t flags;
+ uint32_t flags;
pte_t *pte;
- //debugf("mmu_booke_kenter: s (pdir_idx = %d ptbl_idx = %d va=0x%08x pa=0x%08x)\n",
- // pdir_idx, ptbl_idx, va, pa);
-
- KASSERT(((va >= VM_MIN_KERNEL_ADDRESS) && (va <= VM_MAX_KERNEL_ADDRESS)),
- ("mmu_booke_kenter: invalid va"));
+ KASSERT(((va >= VM_MIN_KERNEL_ADDRESS) &&
+ (va <= VM_MAX_KERNEL_ADDRESS)), ("mmu_booke_kenter: invalid va"));
#if 0
/* assume IO mapping, set I, G bits */
@@ -1307,14 +1290,18 @@ mmu_booke_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
#endif
flags |= (PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID);
+ flags |= PTE_M;
pte = &(kernel_pmap->pm_pdir[pdir_idx][ptbl_idx]);
+ mtx_lock_spin(&tlbivax_mutex);
+
if (PTE_ISVALID(pte)) {
- //debugf("mmu_booke_kenter: replacing entry!\n");
+
+ CTR1(KTR_PMAP, "%s: replacing entry!", __func__);
/* Flush entry from TLB0 */
- tlb0_flush_entry(kernel_pmap, va);
+ tlb0_flush_entry(va);
}
pte->rpn = pa & ~PTE_PA_MASK;
@@ -1329,7 +1316,7 @@ mmu_booke_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
__syncicache((void *)va, PAGE_SIZE);
}
- //debugf("mmu_booke_kenter: e\n");
+ mtx_unlock_spin(&tlbivax_mutex);
}
/*
@@ -1342,25 +1329,29 @@ mmu_booke_kremove(mmu_t mmu, vm_offset_t va)
unsigned int ptbl_idx = PTBL_IDX(va);
pte_t *pte;
- //debugf("mmu_booke_kremove: s (va = 0x%08x)\n", va);
+// CTR2(KTR_PMAP,("%s: s (va = 0x%08x)\n", __func__, va));
- KASSERT(((va >= VM_MIN_KERNEL_ADDRESS) && (va <= VM_MAX_KERNEL_ADDRESS)),
+ KASSERT(((va >= VM_MIN_KERNEL_ADDRESS) &&
+ (va <= VM_MAX_KERNEL_ADDRESS)),
("mmu_booke_kremove: invalid va"));
pte = &(kernel_pmap->pm_pdir[pdir_idx][ptbl_idx]);
if (!PTE_ISVALID(pte)) {
- //debugf("mmu_booke_kremove: e (invalid pte)\n");
+
+ CTR1(KTR_PMAP, "%s: invalid pte", __func__);
+
return;
}
- /* Invalidate entry in TLB0. */
- tlb0_flush_entry(kernel_pmap, va);
+ mtx_lock_spin(&tlbivax_mutex);
+ /* Invalidate entry in TLB0, update PTE. */
+ tlb0_flush_entry(va);
pte->flags = 0;
pte->rpn = 0;
- //debugf("mmu_booke_kremove: e\n");
+ mtx_unlock_spin(&tlbivax_mutex);
}
/*
@@ -1369,10 +1360,9 @@ mmu_booke_kremove(mmu_t mmu, vm_offset_t va)
static void
mmu_booke_pinit0(mmu_t mmu, pmap_t pmap)
{
- //debugf("mmu_booke_pinit0: s (pmap = 0x%08x)\n", (u_int32_t)pmap);
+
mmu_booke_pinit(mmu, pmap);
PCPU_SET(curpmap, pmap);
- //debugf("mmu_booke_pinit0: e\n");
}
/*
@@ -1382,26 +1372,20 @@ mmu_booke_pinit0(mmu_t mmu, pmap_t pmap)
static void
mmu_booke_pinit(mmu_t mmu, pmap_t pmap)
{
+ int i;
- //struct thread *td;
- //struct proc *p;
-
- //td = PCPU_GET(curthread);
- //p = td->td_proc;
- //debugf("mmu_booke_pinit: s (pmap = 0x%08x)\n", (u_int32_t)pmap);
- //printf("mmu_booke_pinit: proc %d '%s'\n", p->p_pid, p->p_comm);
+ CTR4(KTR_PMAP, "%s: pmap = %p, proc %d '%s'", __func__, pmap,
+ curthread->td_proc->p_pid, curthread->td_proc->p_comm);
- KASSERT((pmap != kernel_pmap), ("mmu_booke_pinit: initializing kernel_pmap"));
+ KASSERT((pmap != kernel_pmap), ("pmap_pinit: initializing kernel_pmap"));
PMAP_LOCK_INIT(pmap);
- pmap->pm_tid = 0;
+ for (i = 0; i < MAXCPU; i++)
+ pmap->pm_tid[i] = TID_NONE;
pmap->pm_active = 0;
bzero(&pmap->pm_stats, sizeof(pmap->pm_stats));
bzero(&pmap->pm_pdir, sizeof(pte_t *) * PDIR_NENTRIES);
-
- TAILQ_INIT(&pmap->ptbl_list);
-
- //debugf("mmu_booke_pinit: e\n");
+ TAILQ_INIT(&pmap->pm_ptbl_list);
}
/*
@@ -1413,11 +1397,13 @@ static void
mmu_booke_release(mmu_t mmu, pmap_t pmap)
{
- //debugf("mmu_booke_release: s\n");
+ printf("mmu_booke_release: s\n");
- PMAP_LOCK_DESTROY(pmap);
+ KASSERT(pmap->pm_stats.resident_count == 0,
+ ("pmap_release: pmap resident count %ld != 0",
+ pmap->pm_stats.resident_count));
- //debugf("mmu_booke_release: e\n");
+ PMAP_LOCK_DESTROY(pmap);
}
#if 0
@@ -1437,6 +1423,7 @@ static void
mmu_booke_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
vm_prot_t prot, boolean_t wired)
{
+
vm_page_lock_queues();
PMAP_LOCK(pmap);
mmu_booke_enter_locked(mmu, pmap, va, m, prot, wired);
@@ -1450,7 +1437,7 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
{
pte_t *pte;
vm_paddr_t pa;
- u_int32_t flags;
+ uint32_t flags;
int su, sync;
pa = VM_PAGE_TO_PHYS(m);
@@ -1463,11 +1450,12 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
// (u_int32_t)m, va, pa, prot, wired);
if (su) {
- KASSERT(((va >= virtual_avail) && (va <= VM_MAX_KERNEL_ADDRESS)),
- ("mmu_booke_enter_locked: kernel pmap, non kernel va"));
+ KASSERT(((va >= virtual_avail) &&
+ (va <= VM_MAX_KERNEL_ADDRESS)),
+ ("mmu_booke_enter_locked: kernel pmap, non kernel va"));
} else {
KASSERT((va <= VM_MAXUSER_ADDRESS),
- ("mmu_booke_enter_locked: user pmap, non user va"));
+ ("mmu_booke_enter_locked: user pmap, non user va"));
}
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
@@ -1478,53 +1466,76 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
*/
if (((pte = pte_find(mmu, pmap, va)) != NULL) &&
(PTE_ISVALID(pte)) && (PTE_PA(pte) == pa)) {
-
- //debugf("mmu_booke_enter_locked: update\n");
+
+ /*
+ * Before actually updating pte->flags we calculate and
+ * prepare its new value in a helper var.
+ */
+ flags = pte->flags;
+ flags &= ~(PTE_UW | PTE_UX | PTE_SW | PTE_SX | PTE_MODIFIED);
/* Wiring change, just update stats. */
if (wired) {
if (!PTE_ISWIRED(pte)) {
- pte->flags |= PTE_WIRED;
+ flags |= PTE_WIRED;
pmap->pm_stats.wired_count++;
}
} else {
if (PTE_ISWIRED(pte)) {
- pte->flags &= ~PTE_WIRED;
+ flags &= ~PTE_WIRED;
pmap->pm_stats.wired_count--;
}
}
- /* Save the old bits and clear the ones we're interested in. */
- flags = pte->flags;
- pte->flags &= ~(PTE_UW | PTE_UX | PTE_SW | PTE_SX | PTE_MODIFIED);
-
if (prot & VM_PROT_WRITE) {
/* Add write permissions. */
- pte->flags |= PTE_SW;
+ flags |= PTE_SW;
if (!su)
- pte->flags |= PTE_UW;
+ flags |= PTE_UW;
} else {
/* Handle modified pages, sense modify status. */
+
+ /*
+ * The PTE_MODIFIED flag could be set by underlying
+ * TLB misses since we last read it (above), possibly
+ * other CPUs could update it so we check in the PTE
+ * directly rather than rely on that saved local flags
+ * copy.
+ */
if (PTE_ISMODIFIED(pte))
vm_page_dirty(m);
}
- /* If we're turning on execute permissions, flush the icache. */
if (prot & VM_PROT_EXECUTE) {
- pte->flags |= PTE_SX;
+ flags |= PTE_SX;
if (!su)
- pte->flags |= PTE_UX;
+ flags |= PTE_UX;
+ /*
+ * Check existing flags for execute permissions: if we
+ * are turning execute permissions on, icache should
+ * be flushed.
+ */
if ((flags & (PTE_UX | PTE_SX)) == 0)
sync++;
}
- /* Flush the old mapping from TLB0. */
- pte->flags &= ~PTE_REFERENCED;
- tlb0_flush_entry(pmap, va);
+ flags &= ~PTE_REFERENCED;
+
+ /*
+ * The new flags value is all calculated -- only now actually
+ * update the PTE.
+ */
+ mtx_lock_spin(&tlbivax_mutex);
+
+ tlb0_flush_entry(va);
+ pte->flags = flags;
+
+ mtx_unlock_spin(&tlbivax_mutex);
+
} else {
/*
- * If there is an existing mapping, but its for a different
+ * If there is an existing mapping, but it's for a different
* physical address, pte_enter() will delete the old mapping.
*/
//if ((pte != NULL) && PTE_ISVALID(pte))
@@ -1534,6 +1545,7 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
/* Now set up the flags and install the new mapping. */
flags = (PTE_SR | PTE_VALID);
+ flags |= PTE_M;
if (!su)
flags |= PTE_UR;
@@ -1576,13 +1588,12 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
pte = pte_find(mmu, pmap, va);
KASSERT(pte == NULL, ("%s:%d", __func__, __LINE__));
- flags = PTE_SR | PTE_VALID | PTE_UR;
+ flags = PTE_SR | PTE_VALID | PTE_UR | PTE_M;
+
pte_enter(mmu, pmap, m, va, flags);
__syncicache((void *)va, PAGE_SIZE);
pte_remove(mmu, pmap, va, PTBL_UNHOLD);
}
-
- //debugf("mmu_booke_enter_locked: e\n");
}
/*
@@ -1608,8 +1619,8 @@ mmu_booke_enter_object(mmu_t mmu, pmap_t pmap, vm_offset_t start,
m = m_start;
PMAP_LOCK(pmap);
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
- mmu_booke_enter_locked(mmu, pmap, start + ptoa(diff), m, prot &
- (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
+ mmu_booke_enter_locked(mmu, pmap, start + ptoa(diff), m,
+ prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
m = TAILQ_NEXT(m, listq);
}
PMAP_UNLOCK(pmap);
@@ -1620,14 +1631,10 @@ mmu_booke_enter_quick(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
vm_prot_t prot)
{
- //debugf("mmu_booke_enter_quick: s\n");
-
PMAP_LOCK(pmap);
mmu_booke_enter_locked(mmu, pmap, va, m,
prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
PMAP_UNLOCK(pmap);
-
- //debugf("mmu_booke_enter_quick e\n");
}
/*
@@ -1639,7 +1646,7 @@ static void
mmu_booke_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t endva)
{
pte_t *pte;
- u_int8_t hold_flag;
+ uint8_t hold_flag;
int su = (pmap == kernel_pmap);
@@ -1647,11 +1654,12 @@ mmu_booke_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t endva)
// su, (u_int32_t)pmap, pmap->pm_tid, va, endva);
if (su) {
- KASSERT(((va >= virtual_avail) && (va <= VM_MAX_KERNEL_ADDRESS)),
- ("mmu_booke_enter: kernel pmap, non kernel va"));
+ KASSERT(((va >= virtual_avail) &&
+ (va <= VM_MAX_KERNEL_ADDRESS)),
+ ("mmu_booke_remove: kernel pmap, non kernel va"));
} else {
KASSERT((va <= VM_MAXUSER_ADDRESS),
- ("mmu_booke_enter: user pmap, non user va"));
+ ("mmu_booke_remove: user pmap, non user va"));
}
if (PMAP_REMOVE_DONE(pmap)) {
@@ -1666,12 +1674,8 @@ mmu_booke_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t endva)
PMAP_LOCK(pmap);
for (; va < endva; va += PAGE_SIZE) {
pte = pte_find(mmu, pmap, va);
- if ((pte != NULL) && PTE_ISVALID(pte)) {
+ if ((pte != NULL) && PTE_ISVALID(pte))
pte_remove(mmu, pmap, va, hold_flag);
-
- /* Flush mapping from TLB0. */
- tlb0_flush_entry(pmap, va);
- }
}
PMAP_UNLOCK(pmap);
vm_page_unlock_queues();
@@ -1686,9 +1690,7 @@ static void
mmu_booke_remove_all(mmu_t mmu, vm_page_t m)
{
pv_entry_t pv, pvn;
- u_int8_t hold_flag;
-
- //debugf("mmu_booke_remove_all: s\n");
+ uint8_t hold_flag;
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
@@ -1698,24 +1700,13 @@ mmu_booke_remove_all(mmu_t mmu, vm_page_t m)
PMAP_LOCK(pv->pv_pmap);
hold_flag = PTBL_HOLD_FLAG(pv->pv_pmap);
pte_remove(mmu, pv->pv_pmap, pv->pv_va, hold_flag);
-
- /* Flush mapping from TLB0. */
- tlb0_flush_entry(pv->pv_pmap, pv->pv_va);
PMAP_UNLOCK(pv->pv_pmap);
}
vm_page_flag_clear(m, PG_WRITEABLE);
-
- //debugf("mmu_booke_remove_all: e\n");
}
/*
* Map a range of physical addresses into kernel virtual address space.
- *
- * The value passed in *virt is a suggested virtual address for the mapping.
- * Architectures which can support a direct-mapped physical to virtual region
- * can return the appropriate address within that region, leaving '*virt'
- * unchanged. We cannot and therefore do not; *virt is updated with the
- * first usable address after the mapped region.
*/
static vm_offset_t
mmu_booke_map(mmu_t mmu, vm_offset_t *virt, vm_offset_t pa_start,
@@ -1749,26 +1740,27 @@ mmu_booke_activate(mmu_t mmu, struct thread *td)
pmap = &td->td_proc->p_vmspace->vm_pmap;
- //debugf("mmu_booke_activate: s (proc = '%s', id = %d, pmap = 0x%08x)\n",
- // td->td_proc->p_comm, td->td_proc->p_pid, pmap);
+ CTR5(KTR_PMAP, "%s: s (td = %p, proc = '%s', id = %d, pmap = 0x%08x)",
+ __func__, td, td->td_proc->p_comm, td->td_proc->p_pid, pmap);
KASSERT((pmap != kernel_pmap), ("mmu_booke_activate: kernel_pmap!"));
mtx_lock_spin(&sched_lock);
- pmap->pm_active |= PCPU_GET(cpumask);
+ atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask));
PCPU_SET(curpmap, pmap);
-
- if (!pmap->pm_tid)
+
+ if (pmap->pm_tid[PCPU_GET(cpuid)] == TID_NONE)
tid_alloc(pmap);
/* Load PID0 register with pmap tid value. */
- load_pid0(pmap->pm_tid);
+ mtspr(SPR_PID0, pmap->pm_tid[PCPU_GET(cpuid)]);
+ __asm __volatile("isync");
mtx_unlock_spin(&sched_lock);
- //debugf("mmu_booke_activate: e (tid = %d for '%s')\n", pmap->pm_tid,
- // td->td_proc->p_comm);
+ CTR3(KTR_PMAP, "%s: e (tid = %d for '%s')", __func__,
+ pmap->pm_tid[PCPU_GET(cpuid)], td->td_proc->p_comm);
}
/*
@@ -1780,7 +1772,11 @@ mmu_booke_deactivate(mmu_t mmu, struct thread *td)
pmap_t pmap;
pmap = &td->td_proc->p_vmspace->vm_pmap;
- pmap->pm_active &= ~(PCPU_GET(cpumask));
+
+ CTR5(KTR_PMAP, "%s: td=%p, proc = '%s', id = %d, pmap = 0x%08x",
+ __func__, td, td->td_proc->p_comm, td->td_proc->p_pid, pmap);
+
+ atomic_clear_int(&pmap->pm_active, PCPU_GET(cpumask));
PCPU_SET(curpmap, NULL);
}
@@ -1824,6 +1820,8 @@ mmu_booke_protect(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
if (PTE_ISVALID(pte)) {
m = PHYS_TO_VM_PAGE(PTE_PA(pte));
+ mtx_lock_spin(&tlbivax_mutex);
+
/* Handle modified pages. */
if (PTE_ISMODIFIED(pte))
vm_page_dirty(m);
@@ -1832,10 +1830,11 @@ mmu_booke_protect(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
if (PTE_ISREFERENCED(pte))
vm_page_flag_set(m, PG_REFERENCED);
- /* Flush mapping from TLB0. */
+ tlb0_flush_entry(va);
pte->flags &= ~(PTE_UW | PTE_SW | PTE_MODIFIED |
PTE_REFERENCED);
- tlb0_flush_entry(pmap, va);
+
+ mtx_unlock_spin(&tlbivax_mutex);
}
}
}
@@ -1863,6 +1862,8 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m)
if (PTE_ISVALID(pte)) {
m = PHYS_TO_VM_PAGE(PTE_PA(pte));
+ mtx_lock_spin(&tlbivax_mutex);
+
/* Handle modified pages. */
if (PTE_ISMODIFIED(pte))
vm_page_dirty(m);
@@ -1874,7 +1875,8 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m)
/* Flush mapping from TLB0. */
pte->flags &= ~(PTE_UW | PTE_SW | PTE_MODIFIED |
PTE_REFERENCED);
- tlb0_flush_entry(pv->pv_pmap, pv->pv_va);
+
+ mtx_unlock_spin(&tlbivax_mutex);
}
}
PMAP_UNLOCK(pv->pv_pmap);
@@ -1914,13 +1916,13 @@ mmu_booke_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va,
{
pte_t *pte;
vm_page_t m;
- u_int32_t pte_wbit;
+ uint32_t pte_wbit;
m = NULL;
vm_page_lock_queues();
PMAP_LOCK(pmap);
- pte = pte_find(mmu, pmap, va);
+ pte = pte_find(mmu, pmap, va);
if ((pte != NULL) && PTE_ISVALID(pte)) {
if (pmap == kernel_pmap)
pte_wbit = PTE_SW;
@@ -1960,7 +1962,7 @@ mmu_booke_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
{
vm_offset_t va;
- //debugf("mmu_booke_zero_page_area: s\n");
+ /* XXX KASSERT off and size are within a single page? */
mtx_lock(&zero_page_mutex);
va = zero_page_va;
@@ -1970,8 +1972,6 @@ mmu_booke_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
mmu_booke_kremove(mmu, va);
mtx_unlock(&zero_page_mutex);
-
- //debugf("mmu_booke_zero_page_area: e\n");
}
/*
@@ -1981,9 +1981,7 @@ static void
mmu_booke_zero_page(mmu_t mmu, vm_page_t m)
{
- //debugf("mmu_booke_zero_page: s\n");
mmu_booke_zero_page_area(mmu, m, 0, PAGE_SIZE);
- //debugf("mmu_booke_zero_page: e\n");
}
/*
@@ -1996,21 +1994,16 @@ mmu_booke_copy_page(mmu_t mmu, vm_page_t sm, vm_page_t dm)
{
vm_offset_t sva, dva;
- //debugf("mmu_booke_copy_page: s\n");
-
- mtx_lock(&copy_page_mutex);
sva = copy_page_src_va;
dva = copy_page_dst_va;
+ mtx_lock(&copy_page_mutex);
mmu_booke_kenter(mmu, sva, VM_PAGE_TO_PHYS(sm));
mmu_booke_kenter(mmu, dva, VM_PAGE_TO_PHYS(dm));
memcpy((caddr_t)dva, (caddr_t)sva, PAGE_SIZE);
mmu_booke_kremove(mmu, dva);
mmu_booke_kremove(mmu, sva);
-
mtx_unlock(&copy_page_mutex);
-
- //debugf("mmu_booke_copy_page: e\n");
}
#if 0
@@ -2036,14 +2029,10 @@ mmu_booke_zero_page_idle(mmu_t mmu, vm_page_t m)
{
vm_offset_t va;
- //debugf("mmu_booke_zero_page_idle: s\n");
-
va = zero_page_idle_va;
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m));
bzero((caddr_t)va, PAGE_SIZE);
mmu_booke_kremove(mmu, va);
-
- //debugf("mmu_booke_zero_page_idle: e\n");
}
/*
@@ -2078,7 +2067,7 @@ make_sure_to_unlock:
}
/*
- * Return whether or not the specified virtual address is elgible
+ * Return whether or not the specified virtual address is eligible
* for prefault.
*/
static boolean_t
@@ -2107,11 +2096,15 @@ mmu_booke_clear_modify(mmu_t mmu, vm_page_t m)
if (!PTE_ISVALID(pte))
goto make_sure_to_unlock;
+ mtx_lock_spin(&tlbivax_mutex);
+
if (pte->flags & (PTE_SW | PTE_UW | PTE_MODIFIED)) {
+ tlb0_flush_entry(pv->pv_va);
pte->flags &= ~(PTE_SW | PTE_UW | PTE_MODIFIED |
PTE_REFERENCED);
- tlb0_flush_entry(pv->pv_pmap, pv->pv_va);
}
+
+ mtx_unlock_spin(&tlbivax_mutex);
}
make_sure_to_unlock:
PMAP_UNLOCK(pv->pv_pmap);
@@ -2147,8 +2140,12 @@ mmu_booke_ts_referenced(mmu_t mmu, vm_page_t m)
goto make_sure_to_unlock;
if (PTE_ISREFERENCED(pte)) {
+ mtx_lock_spin(&tlbivax_mutex);
+
+ tlb0_flush_entry(pv->pv_va);
pte->flags &= ~PTE_REFERENCED;
- tlb0_flush_entry(pv->pv_pmap, pv->pv_va);
+
+ mtx_unlock_spin(&tlbivax_mutex);
if (++count > 4) {
PMAP_UNLOCK(pv->pv_pmap);
@@ -2182,8 +2179,12 @@ mmu_booke_clear_reference(mmu_t mmu, vm_page_t m)
goto make_sure_to_unlock;
if (PTE_ISREFERENCED(pte)) {
+ mtx_lock_spin(&tlbivax_mutex);
+
+ tlb0_flush_entry(pv->pv_va);
pte->flags &= ~PTE_REFERENCED;
- tlb0_flush_entry(pv->pv_pmap, pv->pv_va);
+
+ mtx_unlock_spin(&tlbivax_mutex);
}
}
make_sure_to_unlock:
@@ -2234,7 +2235,6 @@ mmu_booke_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m)
loops = 0;
TAILQ_FOREACH(pv, &m->md.pv_list, pv_link) {
-
if (pv->pv_pmap == pmap)
return (TRUE);
@@ -2325,8 +2325,6 @@ mmu_booke_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
{
vm_offset_t base, offset;
- //debugf("mmu_booke_unmapdev: s (va = 0x%08x)\n", va);
-
/*
* Unmap only if this is inside kernel virtual space.
*/
@@ -2336,19 +2334,18 @@ mmu_booke_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
size = roundup(offset + size, PAGE_SIZE);
kmem_free(kernel_map, base, size);
}
-
- //debugf("mmu_booke_unmapdev: e\n");
}
/*
- * mmu_booke_object_init_pt preloads the ptes for a given object
- * into the specified pmap. This eliminates the blast of soft
- * faults on process startup and immediately after an mmap.
+ * mmu_booke_object_init_pt preloads the ptes for a given object into the
+ * specified pmap. This eliminates the blast of soft faults on process startup
+ * and immediately after an mmap.
*/
static void
mmu_booke_object_init_pt(mmu_t mmu, pmap_t pmap, vm_offset_t addr,
vm_object_t object, vm_pindex_t pindex, vm_size_t size)
{
+
VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
KASSERT(object->type == OBJT_DEVICE,
("mmu_booke_object_init_pt: non-device object"));
@@ -2368,32 +2365,6 @@ mmu_booke_mincore(mmu_t mmu, pmap_t pmap, vm_offset_t addr)
/**************************************************************************/
/* TID handling */
/**************************************************************************/
-/*
- * Flush all entries from TLB0 matching given tid.
- */
-static void
-tid_flush(tlbtid_t tid)
-{
- int i, entryidx, way;
-
- //debugf("tid_flush: s (tid = %d)\n", tid);
-
- mtx_lock_spin(&tlb0_mutex);
-
- for (i = 0; i < TLB0_SIZE; i++) {
- if (MAS1_GETTID(tlb0[i].mas1) == tid) {
- way = i / TLB0_ENTRIES_PER_WAY;
- entryidx = i - (way * TLB0_ENTRIES_PER_WAY);
-
- //debugf("tid_flush: inval tlb0 entry %d\n", i);
- tlb0_inval_entry(entryidx << MAS2_TLB0_ENTRY_IDX_SHIFT, way);
- }
- }
-
- mtx_unlock_spin(&tlb0_mutex);
-
- //debugf("tid_flush: e\n");
-}
/*
* Allocate a TID. If necessary, steal one from someone else.
@@ -2403,110 +2374,47 @@ static tlbtid_t
tid_alloc(pmap_t pmap)
{
tlbtid_t tid;
- static tlbtid_t next_tid = TID_MIN;
-
- //struct thread *td;
- //struct proc *p;
-
- //td = PCPU_GET(curthread);
- //p = td->td_proc;
- //debugf("tid_alloc: s (pmap = 0x%08x)\n", (u_int32_t)pmap);
- //printf("tid_alloc: proc %d '%s'\n", p->p_pid, p->p_comm);
+ int thiscpu;
KASSERT((pmap != kernel_pmap), ("tid_alloc: kernel pmap"));
- /*
- * Find a likely TID, allocate unused if possible,
- * skip reserved entries.
- */
- tid = next_tid;
- while (tidbusy[tid] != NULL) {
- if (tid == next_tid)
- break;
-
- if (tid == TID_MAX)
- tid = TID_MIN;
- else
- tid++;
-
- }
-
- /* Now clean it out */
- tid_flush(tid);
-
- /* If we are stealing pmap then clear its tid */
- if (tidbusy[tid]) {
- //debugf("warning: stealing tid %d\n", tid);
- tidbusy[tid]->pm_tid = 0;
- }
-
- /* Calculate next tid */
- if (tid == TID_MAX)
- next_tid = TID_MIN;
- else
- next_tid = tid + 1;
+ CTR2(KTR_PMAP, "%s: s (pmap = %p)", __func__, pmap);
- tidbusy[tid] = pmap;
- pmap->pm_tid = tid;
+ thiscpu = PCPU_GET(cpuid);
- //debugf("tid_alloc: e (%02d next = %02d)\n", tid, next_tid);
- return (tid);
-}
-
-#if 0
-/*
- * Free this pmap's TID.
- */
-static void
-tid_free(pmap_t pmap)
-{
- tlbtid_t oldtid;
+ tid = PCPU_GET(tid_next);
+ if (tid > TID_MAX)
+ tid = TID_MIN;
+ PCPU_SET(tid_next, tid + 1);
- oldtid = pmap->pm_tid;
+ /* If we are stealing TID then clear the relevant pmap's field */
+ if (tidbusy[thiscpu][tid] != NULL) {
- if (oldtid == 0) {
- panic("tid_free: freeing kernel tid");
- }
+ CTR2(KTR_PMAP, "%s: warning: stealing tid %d", __func__, tid);
+
+ tidbusy[thiscpu][tid]->pm_tid[thiscpu] = TID_NONE;
-#ifdef DEBUG
- if (tidbusy[oldtid] == 0)
- debugf("tid_free: freeing free tid %d\n", oldtid);
- if (tidbusy[oldtid] != pmap) {
- debugf("tid_free: freeing someone esle's tid\n "
- "tidbusy[%d] = 0x%08x pmap = 0x%08x\n",
- oldtid, (u_int32_t)tidbusy[oldtid], (u_int32_t)pmap);
+ /* Flush all entries from TLB0 matching this TID. */
+ tid_flush(tid);
}
-#endif
- tidbusy[oldtid] = NULL;
- tid_flush(oldtid);
-}
-#endif
-
-#if 0
-#if DEBUG
-static void
-tid_print_busy(void)
-{
- int i;
+ tidbusy[thiscpu][tid] = pmap;
+ pmap->pm_tid[thiscpu] = tid;
+ __asm __volatile("msync; isync");
- for (i = 0; i < TID_MAX; i++) {
- debugf("tid %d = pmap 0x%08x", i, (u_int32_t)tidbusy[i]);
- if (tidbusy[i])
- debugf(" pmap->tid = %d", tidbusy[i]->pm_tid);
- debugf("\n");
- }
+ CTR3(KTR_PMAP, "%s: e (%02d next = %02d)", __func__, tid,
+ PCPU_GET(tid_next));
+ return (tid);
}
-#endif /* DEBUG */
-#endif
/**************************************************************************/
/* TLB0 handling */
/**************************************************************************/
static void
-tlb_print_entry(int i, u_int32_t mas1, u_int32_t mas2, u_int32_t mas3, u_int32_t mas7)
+tlb_print_entry(int i, uint32_t mas1, uint32_t mas2, uint32_t mas3,
+ uint32_t mas7)
{
int as;
char desc[3];
@@ -2525,7 +2433,7 @@ tlb_print_entry(int i, u_int32_t mas1, u_int32_t mas2, u_int32_t mas3, u_int32_t
else
desc[1] = ' ';
- as = (mas1 & MAS1_TS) ? 1 : 0;
+ as = (mas1 & MAS1_TS_MASK) ? 1 : 0;
tid = MAS1_GETTID(mas1);
tsize = (mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
@@ -2551,160 +2459,42 @@ tlb0_tableidx(vm_offset_t va, unsigned int way)
}
/*
- * Write given entry to TLB0 hardware.
- * Use 32 bit pa, clear 4 high-order bits of RPN (mas7).
- */
-static void
-tlb0_write_entry(unsigned int idx, unsigned int way)
-{
- u_int32_t mas0, mas7, nv;
-
- /* Clear high order RPN bits. */
- mas7 = 0;
-
- /* Preserve NV. */
- mas0 = mfspr(SPR_MAS0);
- nv = mas0 & (TLB0_NWAYS - 1);
-
- /* Select entry. */
- mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way) | nv;
-
- //debugf("tlb0_write_entry: s (idx=%d way=%d mas0=0x%08x "
- // "mas1=0x%08x mas2=0x%08x mas3=0x%08x)\n",
- // idx, way, mas0, tlb0[idx].mas1,
- // tlb0[idx].mas2, tlb0[idx].mas3);
-
- mtspr(SPR_MAS0, mas0);
- __asm volatile("isync");
- mtspr(SPR_MAS1, tlb0[idx].mas1);
- __asm volatile("isync");
- mtspr(SPR_MAS2, tlb0[idx].mas2);
- __asm volatile("isync");
- mtspr(SPR_MAS3, tlb0[idx].mas3);
- __asm volatile("isync");
- mtspr(SPR_MAS7, mas7);
- __asm volatile("isync; tlbwe; isync; msync");
-
- //debugf("tlb0_write_entry: e\n");
-}
-
-/*
- * Invalidate TLB0 entry, clear correspondig tlb0 table element.
- */
-static void
-tlb0_inval_entry(vm_offset_t va, unsigned int way)
-{
- int idx = tlb0_tableidx(va, way);
-
- //debugf("tlb0_inval_entry: s (va=0x%08x way=%d idx=%d)\n",
- // va, way, idx);
-
- tlb0[idx].mas1 = 1 << MAS1_TSIZE_SHIFT; /* !MAS1_VALID */
- tlb0[idx].mas2 = va & MAS2_EPN;
- tlb0[idx].mas3 = 0;
-
- tlb0_write_entry(idx, way);
-
- //debugf("tlb0_inval_entry: e\n");
-}
-
-/*
- * Invalidate TLB0 entry that corresponds to pmap/va.
+ * Invalidate TLB0 entry.
*/
-static void
-tlb0_flush_entry(pmap_t pmap, vm_offset_t va)
+static inline void
+tlb0_flush_entry(vm_offset_t va)
{
- int idx, way;
-
- //debugf("tlb0_flush_entry: s (pmap=0x%08x va=0x%08x)\n",
- // (u_int32_t)pmap, va);
-
- mtx_lock_spin(&tlb0_mutex);
- /* Check all TLB0 ways. */
- for (way = 0; way < TLB0_NWAYS; way ++) {
- idx = tlb0_tableidx(va, way);
+ CTR2(KTR_PMAP, "%s: s va=0x%08x", __func__, va);
- /* Invalidate only if entry matches va and pmap tid. */
- if (((MAS1_GETTID(tlb0[idx].mas1) == pmap->pm_tid) &&
- ((tlb0[idx].mas2 & MAS2_EPN) == va))) {
- tlb0_inval_entry(va, way);
- }
- }
+ mtx_assert(&tlbivax_mutex, MA_OWNED);
- mtx_unlock_spin(&tlb0_mutex);
+ __asm __volatile("tlbivax 0, %0" :: "r"(va & MAS2_EPN_MASK));
+ __asm __volatile("isync; msync");
+ __asm __volatile("tlbsync; msync");
- //debugf("tlb0_flush_entry: e\n");
-}
-
-/* Clean TLB0 hardware and tlb0[] table. */
-static void
-tlb0_init(void)
-{
- int entryidx, way;
-
- debugf("tlb0_init: TLB0_SIZE = %d TLB0_NWAYS = %d\n",
- TLB0_SIZE, TLB0_NWAYS);
-
- mtx_lock_spin(&tlb0_mutex);
-
- for (way = 0; way < TLB0_NWAYS; way ++) {
- for (entryidx = 0; entryidx < TLB0_ENTRIES_PER_WAY; entryidx++) {
- tlb0_inval_entry(entryidx << MAS2_TLB0_ENTRY_IDX_SHIFT, way);
- }
- }
-
- mtx_unlock_spin(&tlb0_mutex);
-}
-
-#if 0
-#if DEBUG
-/* Print out tlb0 entries for given va. */
-static void
-tlb0_print_tlbentries_va(vm_offset_t va)
-{
- u_int32_t mas0, mas1, mas2, mas3, mas7;
- int way, idx;
-
- debugf("TLB0 entries for va = 0x%08x:\n", va);
- for (way = 0; way < TLB0_NWAYS; way ++) {
- mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way);
- mtspr(SPR_MAS0, mas0);
- __asm volatile("isync");
-
- mas2 = va & MAS2_EPN;
- mtspr(SPR_MAS2, mas2);
- __asm volatile("isync; tlbre");
-
- mas1 = mfspr(SPR_MAS1);
- mas2 = mfspr(SPR_MAS2);
- mas3 = mfspr(SPR_MAS3);
- mas7 = mfspr(SPR_MAS7);
-
- idx = tlb0_tableidx(va, way);
- tlb_print_entry(idx, mas1, mas2, mas3, mas7);
- }
+ CTR1(KTR_PMAP, "%s: e", __func__);
}
/* Print out contents of the MAS registers for each TLB0 entry */
-static void
+void
tlb0_print_tlbentries(void)
{
- u_int32_t mas0, mas1, mas2, mas3, mas7;
+ uint32_t mas0, mas1, mas2, mas3, mas7;
int entryidx, way, idx;
debugf("TLB0 entries:\n");
- for (way = 0; way < TLB0_NWAYS; way ++) {
+ for (way = 0; way < TLB0_WAYS; way ++)
for (entryidx = 0; entryidx < TLB0_ENTRIES_PER_WAY; entryidx++) {
mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way);
mtspr(SPR_MAS0, mas0);
- __asm volatile("isync");
+ __asm __volatile("isync");
mas2 = entryidx << MAS2_TLB0_ENTRY_IDX_SHIFT;
mtspr(SPR_MAS2, mas2);
- __asm volatile("isync; tlbre");
+ __asm __volatile("isync; tlbre");
mas1 = mfspr(SPR_MAS1);
mas2 = mfspr(SPR_MAS2);
@@ -2714,27 +2504,21 @@ tlb0_print_tlbentries(void)
idx = tlb0_tableidx(mas2, way);
tlb_print_entry(idx, mas1, mas2, mas3, mas7);
}
- }
-}
-
-/* Print out kernel tlb0[] table. */
-static void
-tlb0_print_entries(void)
-{
- int i;
-
- debugf("tlb0[] table entries:\n");
- for (i = 0; i < TLB0_SIZE; i++) {
- tlb_print_entry(i, tlb0[i].mas1,
- tlb0[i].mas2, tlb0[i].mas3, 0);
- }
}
-#endif /* DEBUG */
-#endif
/**************************************************************************/
/* TLB1 handling */
/**************************************************************************/
+
+/*
+ * TLB1 mapping notes:
+ *
+ * TLB1[0] CCSRBAR
+ * TLB1[1] Kernel text and data.
+ * TLB1[2-15] Additional kernel text and data mappings (if required), PCI
+ * windows, other devices mappings.
+ */
+
/*
* Write given entry to TLB1 hardware.
* Use 32 bit pa, clear 4 high-order bits of RPN (mas7).
@@ -2742,7 +2526,7 @@ tlb0_print_entries(void)
static void
tlb1_write_entry(unsigned int idx)
{
- u_int32_t mas0, mas7;
+ uint32_t mas0, mas7;
//debugf("tlb1_write_entry: s\n");
@@ -2754,15 +2538,15 @@ tlb1_write_entry(unsigned int idx)
//debugf("tlb1_write_entry: mas0 = 0x%08x\n", mas0);
mtspr(SPR_MAS0, mas0);
- __asm volatile("isync");
+ __asm __volatile("isync");
mtspr(SPR_MAS1, tlb1[idx].mas1);
- __asm volatile("isync");
+ __asm __volatile("isync");
mtspr(SPR_MAS2, tlb1[idx].mas2);
- __asm volatile("isync");
+ __asm __volatile("isync");
mtspr(SPR_MAS3, tlb1[idx].mas3);
- __asm volatile("isync");
+ __asm __volatile("isync");
mtspr(SPR_MAS7, mas7);
- __asm volatile("isync; tlbwe; isync; msync");
+ __asm __volatile("isync; tlbwe; isync; msync");
//debugf("tlb1_write_entry: e\n");;
}
@@ -2801,101 +2585,55 @@ static unsigned int
size2tsize(vm_size_t size)
{
- /*
- * tsize = log2(size) / 2 - 5
- */
-
return (ilog2(size) / 2 - 5);
}
/*
- * Setup entry in a sw tlb1 table, write entry to TLB1 hardware.
- * This routine is used for low level operations on the TLB1,
- * for creating temporaray as well as permanent mappings (tlb_set_entry).
- *
- * We assume kernel mappings only, thus all entries created have supervisor
- * permission bits set nad user permission bits cleared.
+ * Register permanent kernel mapping in TLB1.
*
- * Provided mapping size must be a power of 4.
- * Mapping flags must be a combination of MAS2_[WIMG].
- * Entry TID is set to _tid which must not exceed 8 bit value.
- * Entry TS is set to either 0 or MAS1_TS based on provided _ts.
+ * Entries are created starting from index 0 (current free entry is
+ * kept in tlb1_idx) and are not supposed to be invalidated.
*/
-static void
-__tlb1_set_entry(unsigned int idx, vm_offset_t va, vm_offset_t pa,
- vm_size_t size, u_int32_t flags, unsigned int _tid, unsigned int _ts)
+static int
+tlb1_set_entry(vm_offset_t va, vm_offset_t pa, vm_size_t size,
+ uint32_t flags)
{
+ uint32_t ts, tid;
int tsize;
- u_int32_t ts, tid;
-
- //debugf("__tlb1_set_entry: s (idx = %d va = 0x%08x pa = 0x%08x "
- // "size = 0x%08x flags = 0x%08x _tid = %d _ts = %d\n",
- // idx, va, pa, size, flags, _tid, _ts);
+
+ if (tlb1_idx >= TLB1_ENTRIES) {
+ printf("tlb1_set_entry: TLB1 full!\n");
+ return (-1);
+ }
/* Convert size to TSIZE */
tsize = size2tsize(size);
- //debugf("__tlb1_set_entry: tsize = %d\n", tsize);
- tid = (_tid << MAS1_TID_SHIFT) & MAS1_TID_MASK;
- ts = (_ts) ? MAS1_TS : 0;
- tlb1[idx].mas1 = MAS1_VALID | MAS1_IPROT | ts | tid;
- tlb1[idx].mas1 |= ((tsize << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK);
+ tid = (TID_KERNEL << MAS1_TID_SHIFT) & MAS1_TID_MASK;
+ /* XXX TS is hard coded to 0 for now as we only use single address space */
+ ts = (0 << MAS1_TS_SHIFT) & MAS1_TS_MASK;
- tlb1[idx].mas2 = (va & MAS2_EPN) | flags;
+ /* XXX LOCK tlb1[] */
- /* Set supervisor rwx permission bits */
- tlb1[idx].mas3 = (pa & MAS3_RPN) | MAS3_SR | MAS3_SW | MAS3_SX;
+ tlb1[tlb1_idx].mas1 = MAS1_VALID | MAS1_IPROT | ts | tid;
+ tlb1[tlb1_idx].mas1 |= ((tsize << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK);
+ tlb1[tlb1_idx].mas2 = (va & MAS2_EPN_MASK) | flags;
- //debugf("__tlb1_set_entry: mas1 = %08x mas2 = %08x mas3 = 0x%08x\n",
- // tlb1[idx].mas1, tlb1[idx].mas2, tlb1[idx].mas3);
+ /* Set supervisor RWX permission bits */
+ tlb1[tlb1_idx].mas3 = (pa & MAS3_RPN) | MAS3_SR | MAS3_SW | MAS3_SX;
- tlb1_write_entry(idx);
- //debugf("__tlb1_set_entry: e\n");
-}
-
-/*
- * Register permanent kernel mapping in TLB1.
- *
- * Entries are created starting from index 0 (current free entry is
- * kept in tlb1_idx) and are not supposed to be invalidated.
- */
-static int
-tlb1_set_entry(vm_offset_t va, vm_offset_t pa, vm_size_t size, u_int32_t flags)
-{
- //debugf("tlb1_set_entry: s (tlb1_idx = %d va = 0x%08x pa = 0x%08x "
- // "size = 0x%08x flags = 0x%08x\n",
- // tlb1_idx, va, pa, size, flags);
+ tlb1_write_entry(tlb1_idx++);
- if (tlb1_idx >= TLB1_SIZE) {
- //debugf("tlb1_set_entry: e (tlb1 full!)\n");
- return (-1);
- }
+ /* XXX UNLOCK tlb1[] */
- /* TS = 0, TID = 0 */
- __tlb1_set_entry(tlb1_idx++, va, pa, size, flags, KERNEL_TID, 0);
- //debugf("tlb1_set_entry: e\n");
+ /*
+ * XXX in general TLB1 updates should be propagated between CPUs,
+ * since current design assumes to have the same TLB1 set-up on all
+ * cores.
+ */
return (0);
}
-/*
- * Invalidate TLB1 entry, clear correspondig tlb1 table element.
- * This routine is used to clear temporary entries created
- * early in a locore.S or through the use of __tlb1_set_entry().
- */
-void
-tlb1_inval_entry(unsigned int idx)
-{
- vm_offset_t va;
-
- va = tlb1[idx].mas2 & MAS2_EPN;
-
- tlb1[idx].mas1 = 0; /* !MAS1_VALID */
- tlb1[idx].mas2 = 0;
- tlb1[idx].mas3 = 0;
-
- tlb1_write_entry(idx);
-}
-
static int
tlb1_entry_size_cmp(const void *a, const void *b)
{
@@ -2913,10 +2651,10 @@ tlb1_entry_size_cmp(const void *a, const void *b)
}
/*
- * Mapin contiguous RAM region into the TLB1 using maximum of
+ * Map in contiguous RAM region into the TLB1 using maximum of
* KERNEL_REGION_MAX_TLB_ENTRIES entries.
*
- * If necessarry round up last entry size and return total size
+ * If necessary round up last entry size and return total size
* used by all allocated entries.
*/
vm_size_t
@@ -2927,8 +2665,8 @@ tlb1_mapin_region(vm_offset_t va, vm_offset_t pa, vm_size_t size)
unsigned int log;
int i;
- debugf("tlb1_mapin_region:\n");
- debugf(" region size = 0x%08x va = 0x%08x pa = 0x%08x\n", size, va, pa);
+ CTR4(KTR_PMAP, "%s: region size = 0x%08x va = 0x%08x pa = 0x%08x",
+ __func__, size, va, pa);
mapped_size = 0;
sz = size;
@@ -2938,13 +2676,9 @@ tlb1_mapin_region(vm_offset_t va, vm_offset_t pa, vm_size_t size)
for (i = 0; i < KERNEL_REGION_MAX_TLB_ENTRIES && sz > 0; i++) {
/* Largest region that is power of 4 and fits within size */
- log = ilog2(sz)/2;
+ log = ilog2(sz) / 2;
esz = 1 << (2 * log);
- /* Minimum region size is 4KB */
- if (esz < (1 << 12))
- esz = 1 << 12;
-
/* If this is last entry cover remaining size. */
if (i == KERNEL_REGION_MAX_TLB_ENTRIES - 1) {
while (esz < sz)
@@ -2968,16 +2702,18 @@ tlb1_mapin_region(vm_offset_t va, vm_offset_t pa, vm_size_t size)
esz = entry_size[i];
if (!esz)
break;
- debugf(" entry %d: sz = 0x%08x (va = 0x%08x pa = 0x%08x)\n",
- tlb1_idx, esz, va, pa);
+
+ CTR5(KTR_PMAP, "%s: entry %d: sz = 0x%08x (va = 0x%08x "
+ "pa = 0x%08x)", __func__, tlb1_idx, esz, va, pa);
+
tlb1_set_entry(va, pa, esz, _TLB_ENTRY_MEM);
va += esz;
pa += esz;
}
- debugf(" mapped size 0x%08x (wasted space 0x%08x)\n",
- mapped_size, mapped_size - size);
+ CTR3(KTR_PMAP, "%s: mapped size 0x%08x (wasted space 0x%08x)",
+ __func__, mapped_size, mapped_size - size);
return (mapped_size);
}
@@ -2991,7 +2727,7 @@ tlb1_init(vm_offset_t ccsrbar)
{
uint32_t mas0;
- /* TBL1[1] is used to map the kernel. Save that entry. */
+ /* TLB1[1] is used to map the kernel. Save that entry. */
mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(1);
mtspr(SPR_MAS0, mas0);
__asm __volatile("isync; tlbre");
@@ -3000,15 +2736,18 @@ tlb1_init(vm_offset_t ccsrbar)
tlb1[1].mas2 = mfspr(SPR_MAS2);
tlb1[1].mas3 = mfspr(SPR_MAS3);
- /* Mapin CCSRBAR in TLB1[0] */
- __tlb1_set_entry(0, CCSRBAR_VA, ccsrbar, CCSRBAR_SIZE,
- _TLB_ENTRY_IO, KERNEL_TID, 0);
+ /* Map in CCSRBAR in TLB1[0] */
+ tlb1_idx = 0;
+ tlb1_set_entry(CCSRBAR_VA, ccsrbar, CCSRBAR_SIZE, _TLB_ENTRY_IO);
+ /*
+ * Set the next available TLB1 entry index. Note TLB[1] is reserved
+ * for initial mapping of kernel text+data, which was set early in
+ * locore, we need to skip this [busy] entry.
+ */
+ tlb1_idx = 2;
/* Setup TLB miss defaults */
set_mas4_defaults();
-
- /* Reset next available TLB1 entry index. */
- tlb1_idx = 2;
}
/*
@@ -3018,14 +2757,14 @@ tlb1_init(vm_offset_t ccsrbar)
static void
set_mas4_defaults(void)
{
- u_int32_t mas4;
+ uint32_t mas4;
/* Defaults: TLB0, PID0, TSIZED=4K */
mas4 = MAS4_TLBSELD0;
mas4 |= (TLB_SIZE_4K << MAS4_TSIZED_SHIFT) & MAS4_TSIZED_MASK;
mtspr(SPR_MAS4, mas4);
- __asm volatile("isync");
+ __asm __volatile("isync");
}
/*
@@ -3034,16 +2773,16 @@ set_mas4_defaults(void)
void
tlb1_print_tlbentries(void)
{
- u_int32_t mas0, mas1, mas2, mas3, mas7;
+ uint32_t mas0, mas1, mas2, mas3, mas7;
int i;
debugf("TLB1 entries:\n");
- for (i = 0; i < TLB1_SIZE; i++) {
+ for (i = 0; i < TLB1_ENTRIES; i++) {
mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(i);
mtspr(SPR_MAS0, mas0);
- __asm volatile("isync; tlbre");
+ __asm __volatile("isync; tlbre");
mas1 = mfspr(SPR_MAS1);
mas2 = mfspr(SPR_MAS2);
@@ -3063,7 +2802,7 @@ tlb1_print_entries(void)
int i;
debugf("tlb1[] table entries:\n");
- for (i = 0; i < TLB1_SIZE; i++)
+ for (i = 0; i < TLB1_ENTRIES; i++)
tlb_print_entry(i, tlb1[i].mas1, tlb1[i].mas2, tlb1[i].mas3, 0);
}
@@ -3074,7 +2813,7 @@ tlb1_print_entries(void)
static int
tlb1_iomapped(int i, vm_paddr_t pa, vm_size_t size, vm_offset_t *va)
{
- u_int32_t prot;
+ uint32_t prot;
vm_paddr_t pa_start;
vm_paddr_t pa_end;
unsigned int entry_tsize;
@@ -3110,6 +2849,6 @@ tlb1_iomapped(int i, vm_paddr_t pa, vm_size_t size, vm_offset_t *va)
return (ERANGE);
/* Return virtual address of this mapping. */
- *va = (tlb1[i].mas2 & MAS2_EPN) + (pa - pa_start);
+ *va = (tlb1[i].mas2 & MAS2_EPN_MASK) + (pa - pa_start);
return (0);
}
diff --git a/sys/powerpc/booke/support.S b/sys/powerpc/booke/support.S
deleted file mode 100644
index b21e79c..0000000
--- a/sys/powerpc/booke/support.S
+++ /dev/null
@@ -1,106 +0,0 @@
-/*-
- * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.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:
- * 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 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$
- */
-
-#include "assym.s"
-
-#include <machine/param.h>
-#include <machine/asm.h>
-#include <machine/spr.h>
-#include <machine/psl.h>
-#include <machine/pte.h>
-#include <machine/trap.h>
-#include <machine/vmparam.h>
-#include <machine/tlb.h>
-
- .text
-/*
- * void remap_ccsrbar(vm_offset_t old_ccsrbar_va, vm_offset_t new_ccsrbar_va,
- * vm_offset_t new_ccsrbar_pa)
- *
- * r3 - old_ccsrbar_va
- * r4 - new_ccsrbar_va
- * r5 - new_ccsrbar_pa
- */
-ENTRY(remap_ccsrbar)
- /*
- * CCSRBAR updating sequence according
- * to section 4.3.1.1.1 of MPC8555E RM.
- */
-
- /* Read current value of CCSRBAR */
- lwz %r6, 0(%r3)
- isync
-
- /* Write new value */
- rlwinm %r6, %r5, 20, 12, 23
- stw %r6, 0(%r3)
-
- /*
- * Read from address that is outside of CCSRBAR space.
- * We have RAM locations available at KERNBASE.
- */
- lis %r7, KERNBASE@ha
- addi %r7, %r7, KERNBASE@l
- lwz %r6, 0(%r7)
- isync
-
- /* Read value of CCSRBAR from new location */
- lwz %r6, 0(%r4)
- isync
- blr
-
-/*
- * void switch_to_as0(void)
- */
-ENTRY(switch_to_as0)
- mflr %r5 /* Save LR */
-
- mfmsr %r3
- lis %r6, (PSL_IS | PSL_DS)@ha
- ori %r6, %r6, (PSL_IS | PSL_DS)@l
- not %r6, %r6
- and %r3, %r3, %r6 /* Clear IS/DS bits */
-
- bl 1f
-1: mflr %r4 /* Use current address */
- addi %r4, %r4, 20 /* Increment to instruction after rfi */
- mtspr SPR_SRR0, %r4
- mtspr SPR_SRR1, %r3
- rfi
-
- mtlr %r5 /* Restore LR */
- blr
-
-/*
- * void load_pid0(tlbtid_t)
- */
-ENTRY(load_pid0)
- mtspr SPR_PID0, %r3
- isync
- blr
diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S
index f22a0ce..f7a54a6 100644
--- a/sys/powerpc/booke/trap_subr.S
+++ b/sys/powerpc/booke/trap_subr.S
@@ -1,6 +1,6 @@
/*-
+ * Copyright (C) 2006-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
* Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com>
- * Copyright (C) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
* Copyright (C) 2006 Juniper Networks, Inc.
* All rights reserved.
*
@@ -127,7 +127,7 @@
bf 17, 1f; \
GET_CPUINFO(%r1); /* Per-cpu structure */ \
lwz %r1, PC_CURPCB(%r1); /* Per-thread kernel stack */ \
-1:
+1:
#define STANDARD_CRIT_PROLOG(sprg_sp, savearea, isrr0, isrr1) \
mtspr sprg_sp, %r1; /* Save SP */ \
@@ -213,7 +213,6 @@
stw %r30, FRAME_SRR0+8(1); \
stw %r31, FRAME_SRR1+8(1)
-
/*
*
* isrr0-1 - save restore registers to restore CPU state to (may be
@@ -250,7 +249,7 @@
*
* Notes:
* - potential TLB miss: NO. It is crucial that we do not generate a TLB
- * miss withing the TLB prolog itself!
+ * miss within the TLB prolog itself!
* - TLBSAVE is always translated
*/
#define TLB_PROLOG \
@@ -334,9 +333,9 @@
.align 5
interrupt_vector_base:
-/****************************************
+/*****************************************************************************
* Critical input interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_critical_input)
STANDARD_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_CRIT)
@@ -346,9 +345,9 @@ INTERRUPT(int_critical_input)
rfci
-/****************************************
+/*****************************************************************************
* Machine check interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_machine_check)
STANDARD_PROLOG(SPR_SPRG3, PC_BOOKE_MCHKSAVE, SPR_MCSRR0, SPR_MCSRR1)
FRAME_SETUP(SPR_SPRG3, PC_BOOKE_MCHKSAVE, EXC_MCHK)
@@ -358,27 +357,27 @@ INTERRUPT(int_machine_check)
rfmci
-/****************************************
+/*****************************************************************************
* Data storage interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_data_storage)
STANDARD_PROLOG(SPR_SPRG1, PC_DISISAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_DISISAVE, EXC_DSI)
b trap_common
-/****************************************
+/*****************************************************************************
* Instruction storage interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_instr_storage)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_ISI)
b trap_common
-/****************************************
+/*****************************************************************************
* External input interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_external_input)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_EXI)
@@ -398,18 +397,18 @@ INTERRUPT(int_program)
b trap_common
-/****************************************
+/*****************************************************************************
* System call
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_syscall)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_SC)
b trap_common
-/****************************************
+/*****************************************************************************
* Decrementer interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_decrementer)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_DECR)
@@ -418,36 +417,34 @@ INTERRUPT(int_decrementer)
b trapexit
-/****************************************
+/*****************************************************************************
* Fixed interval timer
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_fixed_interval_timer)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_FIT)
b trap_common
-/****************************************
+/*****************************************************************************
* Watchdog interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_watchdog)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_WDOG)
b trap_common
-/****************************************
+/*****************************************************************************
* Data TLB miss interrupt
*
- * There can be nested TLB misses - while
- * handling a TLB miss we dereference data
- * structures that may be not covered by
- * translations. We support up to
+ * There can be nested TLB misses - while handling a TLB miss we reference
+ * data structures that may be not covered by translations. We support up to
* TLB_NESTED_MAX-1 nested misses.
*
* Registers use:
* r31 - dear
- * r30 - tlb0 entry address
+ * r30 - unused
* r29 - saved mas0
* r28 - saved mas1
* r27 - saved mas2
@@ -455,23 +452,20 @@ INTERRUPT(int_watchdog)
* r25 - pte address
*
* r20:r23 - scratch registers
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_data_tlb_error)
TLB_PROLOG
mfdear %r31
/*
- * Save MAS0-MAS2 registers. There might be another tlb miss during pte
- * lookup overwriting current contents (which was hw filled).
+ * Save MAS0-MAS2 registers. There might be another tlb miss during
+ * pte lookup overwriting current contents (which was hw filled).
*/
mfspr %r29, SPR_MAS0
mfspr %r28, SPR_MAS1
mfspr %r27, SPR_MAS2
- /* return tlb0 entry address in r30 */
- bl get_tlb0table_entry
-
/* Check faulting address. */
lis %r21, VM_MAXUSER_ADDRESS@h
ori %r21, %r21, VM_MAXUSER_ADDRESS@l
@@ -521,11 +515,6 @@ search_failed:
*/
lis %r23, 0xffff0000@h /* revoke all permissions */
- /* Save MAS registers to tlb0[] table. */
- stw %r28, TLB0TABLE_MAS1(%r30) /* write tlb0[idx].mas1 */
- stw %r27, TLB0TABLE_MAS2(%r30) /* write tlb0[idx].mas2 */
- stw %r23, TLB0TABLE_MAS3(%r30) /* write tlb0[idx].mas3 */
-
/* Load MAS registers. */
mtspr SPR_MAS0, %r29
isync
@@ -541,61 +530,18 @@ search_failed:
isync
b tlb_miss_return
-/******************************************************/
-/*
- * Calculate address of tlb0[tlb0table_idx], save it in r30
- *
- * tlb0table_idx = (way * entries_per_way) + entry_number
- * entries_per_way = 128
- * entry_number is defined by EPN[45:51]
+/*****************************************************************************
*
- * input: r31 - faulting address
- * input: r29 - MAS0
- * output: r30 - address of corresponding tlb0[] entry
- *
- * scratch regs used: r21-r23
- */
-/******************************************************/
-get_tlb0table_entry:
- lis %r21, 0 /* keeps tlb0table_idx */
-
- /* Add entry number, use DEAR from r31 (faulting va) */
- rlwinm %r22, %r31, 20, 25, 31 /* get EPN[45:51] */
- add %r21, %r21, %r22
-
- /* Select way */
- rlwinm %r22, %r29, 16, 30, 31 /* get way# = ESEL[0:1] */
-
- /* Get number of entries per tlb0 way. */
- lis %r23, tlb0_nentries_per_way@h
- ori %r23, %r23, tlb0_nentries_per_way@l
- lwz %r23, 0(%r23)
-
- mullw %r22, %r22, %r23 /* multiply by #entries per way */
- add %r21, %r21, %r22
-
- mulli %r21, %r21, TLB0_ENTRY_SIZE /* multipy by tlb0 entry size */
-
- /* Get tlb0[tlb0tble_idx] address, save it in r30 */
- lis %r30, tlb0@h
- ori %r30, %r30, tlb0@l
- lwz %r30, 0(%r30)
- add %r30, %r30, %r21
- blr
-
-
-/******************************************************/
-/*
- * Return pte address that corresponds to given pmap/va.
- * If there is no valid entry return 0.
+ * Return pte address that corresponds to given pmap/va. If there is no valid
+ * entry return 0.
*
* input: r26 - pmap
* input: r31 - dear
* output: r25 - pte address
*
* scratch regs used: r21
- */
-/******************************************************/
+ *
+ ****************************************************************************/
pte_lookup:
cmpwi %r26, 0
beq 1f /* fail quickly if pmap is invalid */
@@ -605,8 +551,11 @@ pte_lookup:
addi %r25, %r26, PM_PDIR /* pmap pm_dir[] address */
add %r25, %r25, %r21 /* offset within pm_pdir[] table */
- lwz %r25, 0(%r25) /* get ptbl address, i.e. pmap->pm_pdir[pdir_idx] */
-
+ /*
+ * Get ptbl address, i.e. pmap->pm_pdir[pdir_idx]
+ * This load may cause a Data TLB miss for non-kernel pmap!
+ */
+ lwz %r25, 0(%r25)
cmpwi %r25, 0
beq 2f
@@ -618,7 +567,11 @@ pte_lookup:
srwi %r21, %r21, (PTBL_SHIFT - PTBL_ENTRY_SHIFT)
add %r25, %r25, %r21 /* address of pte entry */
- lwz %r21, PTE_FLAGS(%r25) /* get pte->flags */
+ /*
+ * Get pte->flags
+ * This load may cause a Data TLB miss for non-kernel pmap!
+ */
+ lwz %r21, PTE_FLAGS(%r25)
andis. %r21, %r21, PTE_VALID@h
bne 2f
1:
@@ -626,32 +579,38 @@ pte_lookup:
2:
blr
-/******************************************************/
-/*
- * Save MAS1-MAS3 registers to tlb0[] table, write TLB entry
+/*****************************************************************************
+ *
+ * Load MAS1-MAS3 registers with data, write TLB entry
*
* input:
* r29 - mas0
* r28 - mas1
* r27 - mas2
* r25 - pte
- * r30 - tlb0 entry address
*
* output: none
*
* scratch regs: r21-r23
- */
-/******************************************************/
+ *
+ ****************************************************************************/
tlb_fill_entry:
- /* Handle pte flags. */
- lwz %r21, PTE_FLAGS(%r25) /* get pte->flags */
+ /*
+ * Update PTE flags: we have to do it atomically, as pmap_protect()
+ * running on other CPUs could attempt to update the flags at the same
+ * time.
+ */
+ li %r23, PTE_FLAGS
+1:
+ lwarx %r21, %r23, %r25 /* get pte->flags */
oris %r21, %r21, PTE_REFERENCED@h /* set referenced bit */
andi. %r22, %r21, (PTE_UW | PTE_UW)@l /* check if writable */
- beq 1f
+ beq 2f
oris %r21, %r21, PTE_MODIFIED@h /* set modified bit */
-1:
- stw %r21, PTE_FLAGS(%r25) /* write it back */
+2:
+ stwcx. %r21, %r23, %r25 /* write it back */
+ bne- 1b
/* Update MAS2. */
rlwimi %r27, %r21, 0, 27, 30 /* insert WIMG bits from pte */
@@ -661,11 +620,6 @@ tlb_fill_entry:
rlwimi %r23, %r21, 24, 26, 31 /* insert protection bits from pte */
- /* Save MAS registers to tlb0[] table. */
- stw %r28, TLB0TABLE_MAS1(%r30) /* write tlb0[idx].mas1 */
- stw %r27, TLB0TABLE_MAS2(%r30) /* write tlb0[idx].mas2 */
- stw %r23, TLB0TABLE_MAS3(%r30) /* write tlb0[idx].mas3 */
-
/* Load MAS registers. */
mtspr SPR_MAS0, %r29
isync
@@ -681,12 +635,11 @@ tlb_fill_entry:
msync
blr
-/****************************************
+/*****************************************************************************
* Instruction TLB miss interrupt
*
* Same notes as for the Data TLB miss
- *
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_inst_tlb_error)
TLB_PROLOG
@@ -700,9 +653,6 @@ INTERRUPT(int_inst_tlb_error)
mfspr %r28, SPR_MAS1
mfspr %r27, SPR_MAS2
- /* return tlb0 entry address in r30 */
- bl get_tlb0table_entry
-
mfsrr1 %r21
mtcr %r21
@@ -714,9 +664,9 @@ INTERRUPT(int_inst_tlb_error)
.globl interrupt_vector_top
interrupt_vector_top:
-/****************************************
+/*****************************************************************************
* Debug interrupt
- ****************************************/
+ ****************************************************************************/
INTERRUPT(int_debug)
STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_DEBUG)
@@ -731,7 +681,7 @@ INTERRUPT(int_debug)
bge 1f
/* Disable single-stepping for the interrupt handlers. */
lwz %r3, FRAME_SRR1+8(%r1);
- rlwinm %r3,%r3,0,23,21
+ rlwinm %r3, %r3, 0, 23, 21
stw %r3, FRAME_SRR1+8(%r1);
/* Restore srr0 and srr1 as they could have been clobbered. */
lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0+8)(%r2);
@@ -752,9 +702,9 @@ INTERRUPT(int_debug)
rfci
-/********************************
+/*****************************************************************************
* Common trap code
- ********************************/
+ ****************************************************************************/
trap_common:
/* Call C trap dispatcher */
addi %r3, %r1, 8
@@ -773,8 +723,8 @@ CNAME(trapexit):
GET_CPUINFO(%r3)
lwz %r4, PC_CURTHREAD(%r3)
lwz %r4, TD_FLAGS(%r4)
- lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
- ori %r5, %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
+ lis %r5, (TDF_ASTPENDING | TDF_NEEDRESCHED)@h
+ ori %r5, %r5, (TDF_ASTPENDING | TDF_NEEDRESCHED)@l
and. %r4, %r4, %r5
beq 1f
@@ -800,12 +750,12 @@ CNAME(breakpoint):
mtsprg1 %r1
mfmsr %r3
mtsrr1 %r3
- andi. %r3,%r3,~(PSL_EE|PSL_ME)@l
+ andi. %r3, %r3, ~(PSL_EE | PSL_ME)@l
mtmsr %r3 /* disable interrupts */
isync
GET_CPUINFO(%r3)
- stw %r30,(PC_DBSAVE+CPUSAVE_R30)(%r3)
- stw %r31,(PC_DBSAVE+CPUSAVE_R31)(%r3)
+ stw %r30, (PC_DBSAVE+CPUSAVE_R30)(%r3)
+ stw %r31, (PC_DBSAVE+CPUSAVE_R31)(%r3)
mflr %r31
mtsrr0 %r31
@@ -829,9 +779,9 @@ CNAME(breakpoint):
dbtrap:
FRAME_SETUP(SPR_SPRG1, PC_DBSAVE, EXC_DEBUG)
/* Call C trap code: */
- addi %r3,%r1,8
+ addi %r3, %r1, 8
bl CNAME(db_trap_glue)
- or. %r3,%r3,%r3
+ or. %r3, %r3, %r3
bne dbleave
/* This wasn't for KDB, so switch to real trap: */
b trap_common
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 2a624ce..50574ab 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -162,6 +162,10 @@ device adb
device cuda
device pmu
+# Powermac I2C support
+device iicbus # I2C bus code
+device kiic # Keywest I2C
+
options KTR
options KTR_COMPILE=0xffffffff
#options KTR_MASK=KTR_SIG
diff --git a/sys/powerpc/conf/NOTES b/sys/powerpc/conf/NOTES
index 189a4e9..e78a042 100644
--- a/sys/powerpc/conf/NOTES
+++ b/sys/powerpc/conf/NOTES
@@ -25,10 +25,13 @@ options SC_OFWFB # OFW frame buffer
device pci
device bm # Apple BMAC (Big Mac Ethernet)
+device kiic # Apple Keywest I2C Controller
device ofwd # Open Firmware disks
device adb # Apple Desktop Bus
device cuda # VIA-CUDA ADB interface
device pmu # Apple Power Management Unit
+device snd_ai2s # Apple I2S Audio
+device snd_davbus # Apple Davbus Audio
#####################################################################
diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h
index fba4c8f..0384902 100644
--- a/sys/powerpc/include/pcpu.h
+++ b/sys/powerpc/include/pcpu.h
@@ -59,7 +59,8 @@ struct pmap;
register_t pc_booke_critsave[BOOKE_CRITSAVE_LEN]; \
register_t pc_booke_mchksave[CPUSAVE_LEN]; \
register_t pc_booke_tlbsave[BOOKE_TLBSAVE_LEN]; \
- register_t pc_booke_tlb_level;
+ register_t pc_booke_tlb_level; \
+ int pc_tid_next;
/* Definitions for register offsets within the exception tmp save areas */
#define CPUSAVE_R28 0 /* where r28 gets saved */
diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h
index d6e3169..2b2d6af 100644
--- a/sys/powerpc/include/pmap.h
+++ b/sys/powerpc/include/pmap.h
@@ -111,17 +111,17 @@ struct md_page {
#else
struct pmap {
- struct mtx pm_mtx; /* pmap mutex */
- tlbtid_t pm_tid; /* TID to identify this pmap entries in TLB */
- u_int pm_active; /* active on cpus */
- int pm_refs; /* ref count */
- struct pmap_statistics pm_stats;/* pmap statistics */
+ struct mtx pm_mtx; /* pmap mutex */
+ tlbtid_t pm_tid[MAXCPU]; /* TID to identify this pmap entries in TLB */
+ u_int pm_active; /* active on cpus */
+ int pm_refs; /* ref count */
+ struct pmap_statistics pm_stats; /* pmap statistics */
/* Page table directory, array of pointers to page tables. */
- pte_t *pm_pdir[PDIR_NENTRIES];
+ pte_t *pm_pdir[PDIR_NENTRIES];
/* List of allocated ptbl bufs (ptbl kva regions). */
- TAILQ_HEAD(, ptbl_buf) ptbl_list;
+ TAILQ_HEAD(, ptbl_buf) pm_ptbl_list;
};
typedef struct pmap *pmap_t;
diff --git a/sys/powerpc/include/pte.h b/sys/powerpc/include/pte.h
index 8664406..af8c453 100644
--- a/sys/powerpc/include/pte.h
+++ b/sys/powerpc/include/pte.h
@@ -211,11 +211,11 @@ extern u_int dsisr(void);
* Page Table Entry definitions and macros.
*/
#ifndef LOCORE
-struct pte_entry {
+struct pte {
vm_offset_t rpn;
- u_int32_t flags;
+ uint32_t flags;
};
-typedef struct pte_entry pte_t;
+typedef struct pte pte_t;
#endif
/* RPN mask, TLB0 4K pages */
diff --git a/sys/powerpc/include/tlb.h b/sys/powerpc/include/tlb.h
index a6859fc..b8913c5 100644
--- a/sys/powerpc/include/tlb.h
+++ b/sys/powerpc/include/tlb.h
@@ -46,7 +46,8 @@
#define MAS1_IPROT 0x40000000
#define MAS1_TID_MASK 0x00FF0000
#define MAS1_TID_SHIFT 16
-#define MAS1_TS 0x00001000
+#define MAS1_TS_MASK 0x00001000
+#define MAS1_TS_SHIFT 12
#define MAS1_TSIZE_MASK 0x00000F00
#define MAS1_TSIZE_SHIFT 8
@@ -62,7 +63,7 @@
#define TLB_SIZE_1G 10
#define TLB_SIZE_4G 11
-#define MAS2_EPN 0xFFFFF000
+#define MAS2_EPN_MASK 0xFFFFF000
#define MAS2_EPN_SHIFT 12
#define MAS2_X0 0x00000040
#define MAS2_X1 0x00000020
@@ -109,31 +110,37 @@
#define MAS2_TLB0_ENTRY_IDX_SHIFT 12
/*
- * Maximum number of TLB1 entries used for a permanat
- * mapping of kernel region (kernel image plus statically
- * allocated data.
+ * Maximum number of TLB1 entries used for a permanent mapping of kernel
+ * region (kernel image plus statically allocated data).
*/
#define KERNEL_REGION_MAX_TLB_ENTRIES 4
#define _TLB_ENTRY_IO (MAS2_I | MAS2_G)
+#ifdef SMP
+#define _TLB_ENTRY_MEM (MAS2_M)
+#else
#define _TLB_ENTRY_MEM (0)
+#endif
-#define KERNEL_TID 0 /* TLB TID to use for kernel translations */
+#define TID_KERNEL 0 /* TLB TID to use for kernel (shared) translations */
#define TID_KRESERVED 1 /* Number of TIDs reserved for kernel */
-#define TID_URESERVED 0 /* Number of TIDs reserve for user */
+#define TID_URESERVED 0 /* Number of TIDs reserved for user */
#define TID_MIN (TID_KRESERVED + TID_URESERVED)
#define TID_MAX 255
+#define TID_NONE -1
#if !defined(LOCORE)
typedef struct tlb_entry {
- u_int32_t mas1;
- u_int32_t mas2;
- u_int32_t mas3;
+ uint32_t mas1;
+ uint32_t mas2;
+ uint32_t mas3;
} tlb_entry_t;
-typedef u_int8_t tlbtid_t;
+typedef int tlbtid_t;
struct pmap;
+void tlb0_print_tlbentries(void);
+
void tlb1_inval_entry(unsigned int);
void tlb1_init(vm_offset_t);
void tlb1_print_entries(void);
diff --git a/sys/powerpc/powermac/ata_macio.c b/sys/powerpc/powermac/ata_macio.c
index 5d1e211..482f76e 100644
--- a/sys/powerpc/powermac/ata_macio.c
+++ b/sys/powerpc/powermac/ata_macio.c
@@ -164,9 +164,11 @@ ata_macio_probe(device_t dev)
ch = &sc->sc_ch.sc_ch;
if (strcmp(name,"ata-4") == 0) {
+ device_set_desc(dev,"Apple MacIO Ultra ATA Controller");
sc->rev = 4;
sc->max_mode = ATA_UDMA4;
} else {
+ device_set_desc(dev,"Apple MacIO ATA Controller");
sc->rev = 3;
sc->max_mode = ATA_WDMA2;
}
diff --git a/sys/powerpc/powermac/grackle.c b/sys/powerpc/powermac/grackle.c
index 9dd796d..fc323bf 100644
--- a/sys/powerpc/powermac/grackle.c
+++ b/sys/powerpc/powermac/grackle.c
@@ -165,7 +165,7 @@ static int
grackle_attach(device_t dev)
{
struct grackle_softc *sc;
- phandle_t node, iparent;
+ phandle_t node;
u_int32_t busrange[2];
struct grackle_range *rp, *io, *mem[2];
int nmem, i, error;
@@ -254,14 +254,6 @@ grackle_attach(device_t dev)
ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
- /* We need the number of interrupt cells to read the imap */
- if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) <= 0)
- iparent = node;
-
- if (OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells,
- sizeof(sc->sc_icells)) <= 0)
- sc->sc_icells = 1;
-
device_add_child(dev, "pci", device_get_unit(dev));
return (bus_generic_attach(dev));
}
@@ -348,15 +340,14 @@ grackle_route_interrupt(device_t bus, device_t dev, int pin)
{
struct grackle_softc *sc;
struct ofw_pci_register reg;
- uint32_t pintr, mintr[2];
+ uint32_t pintr, mintr;
uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bus);
pintr = pin;
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
- sizeof(reg), &pintr, sizeof(pintr), &mintr,
- sizeof(mintr[0])*sc->sc_icells, maskbuf))
- return (mintr[0]);
+ sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
+ return (mintr);
/* Maybe it's a real interrupt, not an intpin */
if (pin > 4)
diff --git a/sys/powerpc/powermac/gracklevar.h b/sys/powerpc/powermac/gracklevar.h
index 78461d8..8d58c0a 100644
--- a/sys/powerpc/powermac/gracklevar.h
+++ b/sys/powerpc/powermac/gracklevar.h
@@ -52,7 +52,6 @@ struct grackle_softc {
struct rman sc_mem_rman;
bus_space_tag_t sc_memt;
bus_dma_tag_t sc_dmat;
- int sc_icells;
struct ofw_bus_iinfo sc_pci_iinfo;
};
diff --git a/sys/powerpc/powermac/kiic.c b/sys/powerpc/powermac/kiic.c
new file mode 100644
index 0000000..1f246e7
--- /dev/null
+++ b/sys/powerpc/powermac/kiic.c
@@ -0,0 +1,390 @@
+/*-
+ * Copyright (c) 2001 Tsubai Masanari. 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. 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$
+ * NetBSD: ki2c.c,v 1.11 2007/12/06 17:00:33 ad Exp
+ * Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai Exp
+ */
+
+/*
+ * Support routines for the Keywest I2C controller.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/ofw/ofw_bus.h>
+#include "iicbus_if.h"
+
+/* Keywest I2C Register offsets */
+#define MODE 0
+#define CONTROL 1
+#define STATUS 2
+#define ISR 3
+#define IER 4
+#define ADDR 5
+#define SUBADDR 6
+#define DATA 7
+
+/* MODE */
+#define I2C_SPEED 0x03 /* Speed mask */
+#define I2C_100kHz 0x00
+#define I2C_50kHz 0x01
+#define I2C_25kHz 0x02
+#define I2C_MODE 0x0c /* Mode mask */
+#define I2C_DUMBMODE 0x00 /* Dumb mode */
+#define I2C_STDMODE 0x04 /* Standard mode */
+#define I2C_STDSUBMODE 0x08 /* Standard mode + sub address */
+#define I2C_COMBMODE 0x0c /* Combined mode */
+#define I2C_PORT 0xf0 /* Port mask */
+
+/* CONTROL */
+#define I2C_CT_AAK 0x01 /* Send AAK */
+#define I2C_CT_ADDR 0x02 /* Send address(es) */
+#define I2C_CT_STOP 0x04 /* Send STOP */
+#define I2C_CT_START 0x08 /* Send START */
+
+/* STATUS */
+#define I2C_ST_BUSY 0x01 /* Busy */
+#define I2C_ST_LASTAAK 0x02 /* Last AAK */
+#define I2C_ST_LASTRW 0x04 /* Last R/W */
+#define I2C_ST_SDA 0x08 /* SDA */
+#define I2C_ST_SCL 0x10 /* SCL */
+
+/* ISR/IER */
+#define I2C_INT_DATA 0x01 /* Data byte sent/received */
+#define I2C_INT_ADDR 0x02 /* Address sent */
+#define I2C_INT_STOP 0x04 /* STOP condition sent */
+#define I2C_INT_START 0x08 /* START condition sent */
+
+/* I2C flags */
+#define I2C_BUSY 0x01
+#define I2C_READING 0x02
+#define I2C_ERROR 0x04
+#define I2C_SELECTED 0x08
+
+struct kiic_softc {
+ device_t sc_dev;
+ phandle_t sc_node;
+ struct mtx sc_mutex;
+ struct resource *sc_reg;
+ int sc_irqrid;
+ struct resource *sc_irq;
+ void *sc_ih;
+ u_int sc_regstep;
+ u_int sc_flags;
+ u_char *sc_data;
+ int sc_resid;
+ device_t sc_iicbus;
+};
+
+static int kiic_probe(device_t dev);
+static int kiic_attach(device_t dev);
+static void kiic_writereg(struct kiic_softc *sc, u_int, u_int);
+static u_int kiic_readreg(struct kiic_softc *, u_int);
+static void kiic_setmode(struct kiic_softc *, u_int);
+static void kiic_setspeed(struct kiic_softc *, u_int);
+static void kiic_intr(void *xsc);
+static int kiic_transfer(device_t dev, struct iic_msg *msgs,
+ uint32_t nmsgs);
+static phandle_t kiic_get_node(device_t bus, device_t dev);
+
+static device_method_t kiic_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, kiic_probe),
+ DEVMETHOD(device_attach, kiic_attach),
+
+ /* iicbus interface */
+ DEVMETHOD(iicbus_callback, iicbus_null_callback),
+ DEVMETHOD(iicbus_transfer, kiic_transfer),
+
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_node, kiic_get_node),
+
+ { 0, 0 }
+};
+
+static driver_t kiic_driver = {
+ "iichb",
+ kiic_methods,
+ sizeof(struct kiic_softc)
+};
+static devclass_t kiic_devclass;
+
+DRIVER_MODULE(kiic, macio, kiic_driver, kiic_devclass, 0, 0);
+
+static int
+kiic_probe(device_t self)
+{
+ const char *name;
+
+ name = ofw_bus_get_name(self);
+ if (name && strcmp(name, "i2c") == 0) {
+ device_set_desc(self, "Keywest I2C controller");
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+static int
+kiic_attach(device_t self)
+{
+ struct kiic_softc *sc = device_get_softc(self);
+ int rid, rate;
+ phandle_t node;
+ char name[64];
+
+ bzero(sc, sizeof(*sc));
+ sc->sc_dev = self;
+
+ node = ofw_bus_get_node(self);
+ if (node == 0 || node == -1) {
+ return (EINVAL);
+ }
+
+ rid = 0;
+ sc->sc_reg = bus_alloc_resource_any(self, SYS_RES_MEMORY,
+ &rid, RF_ACTIVE);
+ if (sc->sc_reg == NULL) {
+ return (ENOMEM);
+ }
+
+ if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
+ device_printf(self, "cannot get i2c-rate\n");
+ return (ENXIO);
+ }
+ if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
+ device_printf(self, "unable to find i2c address step\n");
+ return (ENXIO);
+ }
+
+ /*
+ * Some Keywest I2C devices have their children attached directly
+ * underneath them. Some have a single 'iicbus' child with the
+ * devices underneath that. Sort this out, and make sure that the
+ * OFW I2C layer has the correct node.
+ */
+
+ sc->sc_node = OF_child(node);
+ if (OF_getprop(sc->sc_node,"name",name,sizeof(name)) > 0) {
+ if (strcmp(name,"i2c-bus") != 0)
+ sc->sc_node = node;
+ }
+
+ mtx_init(&sc->sc_mutex, "kiic", NULL, MTX_DEF);
+
+ sc->sc_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &sc->sc_irqrid,
+ RF_ACTIVE);
+ bus_setup_intr(self, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL,
+ kiic_intr, sc, &sc->sc_ih);
+
+ kiic_writereg(sc, STATUS, 0);
+ kiic_writereg(sc, ISR, 0);
+ kiic_writereg(sc, IER, 0);
+
+ kiic_setmode(sc, I2C_STDMODE);
+ kiic_setspeed(sc, I2C_100kHz); /* XXX rate */
+
+ kiic_writereg(sc, IER, I2C_INT_DATA | I2C_INT_ADDR | I2C_INT_STOP);
+
+ /* Add the IIC bus layer */
+ sc->sc_iicbus = device_add_child(self, "iicbus", -1);
+
+ return (bus_generic_attach(self));
+}
+
+static void
+kiic_writereg(struct kiic_softc *sc, u_int reg, u_int val)
+{
+ bus_write_1(sc->sc_reg, sc->sc_regstep * reg, val);
+ DELAY(10); /* register access delay */
+}
+
+static u_int
+kiic_readreg(struct kiic_softc *sc, u_int reg)
+{
+ return bus_read_1(sc->sc_reg, sc->sc_regstep * reg);
+}
+
+static void
+kiic_setmode(struct kiic_softc *sc, u_int mode)
+{
+ u_int x;
+
+ KASSERT((mode & ~I2C_MODE) == 0, ("bad mode"));
+ x = kiic_readreg(sc, MODE);
+ x &= ~I2C_MODE;
+ x |= mode;
+ kiic_writereg(sc, MODE, x);
+}
+
+static void
+kiic_setspeed(struct kiic_softc *sc, u_int speed)
+{
+ u_int x;
+
+ KASSERT((speed & ~I2C_SPEED) == 0, ("bad speed"));
+ x = kiic_readreg(sc, MODE);
+ x &= ~I2C_SPEED;
+ x |= speed;
+ kiic_writereg(sc, MODE, x);
+}
+
+static void
+kiic_intr(void *xsc)
+{
+ struct kiic_softc *sc = xsc;
+ u_int isr;
+ uint32_t x;
+
+ mtx_lock(&sc->sc_mutex);
+ isr = kiic_readreg(sc, ISR);
+
+ if (isr & I2C_INT_ADDR) {
+ sc->sc_flags |= I2C_SELECTED;
+
+ if (sc->sc_flags & I2C_READING) {
+ if (sc->sc_resid > 1) {
+ x = kiic_readreg(sc, CONTROL);
+ x |= I2C_CT_AAK;
+ kiic_writereg(sc, CONTROL, x);
+ }
+ } else {
+ kiic_writereg(sc, DATA, *sc->sc_data++);
+ sc->sc_resid--;
+ }
+ }
+
+ if (isr & I2C_INT_DATA) {
+ if (sc->sc_flags & I2C_READING) {
+ if (sc->sc_resid > 0) {
+ *sc->sc_data++ = kiic_readreg(sc, DATA);
+ sc->sc_resid--;
+ }
+
+ } else {
+ if (sc->sc_resid == 0) {
+ x = kiic_readreg(sc, CONTROL);
+ x |= I2C_CT_STOP;
+ kiic_writereg(sc, CONTROL, x);
+ } else {
+ kiic_writereg(sc, DATA, *sc->sc_data++);
+ sc->sc_resid--;
+ }
+ }
+ }
+
+ if (isr & I2C_INT_STOP) {
+ kiic_writereg(sc, CONTROL, 0);
+ sc->sc_flags &= ~I2C_SELECTED;
+ wakeup(sc->sc_dev);
+ }
+
+ kiic_writereg(sc, ISR, isr);
+ mtx_unlock(&sc->sc_mutex);
+}
+
+static int
+kiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ struct kiic_softc *sc;
+ int i, x, timo, err;
+ uint8_t addr;
+
+ sc = device_get_softc(dev);
+ timo = 100;
+
+ mtx_lock(&sc->sc_mutex);
+
+ if (sc->sc_flags & I2C_BUSY)
+ mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
+
+ if (sc->sc_flags & I2C_BUSY) {
+ mtx_unlock(&sc->sc_mutex);
+ return (ETIMEDOUT);
+ }
+
+ sc->sc_flags = I2C_BUSY;
+
+ for (i = 0; i < nmsgs; i++) {
+ sc->sc_data = msgs[i].buf;
+ sc->sc_resid = msgs[i].len;
+ sc->sc_flags = I2C_BUSY;
+ addr = msgs[i].slave;
+ timo = 1000 + sc->sc_resid * 200;
+ timo += 100000;
+
+ if (msgs[i].flags & IIC_M_RD) {
+ sc->sc_flags |= I2C_READING;
+ addr |= 1;
+ }
+
+ kiic_writereg(sc, ADDR, addr);
+ kiic_writereg(sc, SUBADDR, 0x04);
+
+ x = kiic_readreg(sc, CONTROL) | I2C_CT_ADDR;
+ kiic_writereg(sc, CONTROL, x);
+
+ err = mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
+
+ msgs[i].len -= sc->sc_resid;
+
+ if ((sc->sc_flags & I2C_ERROR) || err == EWOULDBLOCK) {
+ device_printf(sc->sc_dev, "I2C error\n");
+ sc->sc_flags = 0;
+ mtx_unlock(&sc->sc_mutex);
+ return (-1);
+ }
+ }
+
+ sc->sc_flags = 0;
+
+ mtx_unlock(&sc->sc_mutex);
+
+ return (0);
+}
+
+static phandle_t
+kiic_get_node(device_t bus, device_t dev)
+{
+ struct kiic_softc *sc;
+
+ sc = device_get_softc(bus);
+ /* We only have one child, the I2C bus, which needs our own node. */
+
+ return sc->sc_node;
+}
+
diff --git a/sys/powerpc/powermac/macgpio.c b/sys/powerpc/powermac/macgpio.c
index 7dd58a9..0d4065f 100644
--- a/sys/powerpc/powermac/macgpio.c
+++ b/sys/powerpc/powermac/macgpio.c
@@ -172,8 +172,14 @@ macgpio_attach(device_t dev)
if (OF_getprop(child,"reg",&dinfo->gpio_num,
sizeof(dinfo->gpio_num)) != sizeof(dinfo->gpio_num)) {
- free(dinfo, M_MACGPIO);
- continue;
+ /*
+ * Some early GPIO controllers don't provide GPIO
+ * numbers for GPIOs designed only to provide
+ * interrupt resources. We should still allow these
+ * to attach, but with caution.
+ */
+
+ dinfo->gpio_num = -1;
}
resource_list_init(&dinfo->mdi_resources);
@@ -217,7 +223,7 @@ macgpio_print_child(device_t dev, device_t child)
printf(" gpio %d", dinfo->gpio_num - GPIO_BASE);
else if (dinfo->gpio_num >= GPIO_EXTINT_BASE)
printf(" extint-gpio %d", dinfo->gpio_num - GPIO_EXTINT_BASE);
- else
+ else if (dinfo->gpio_num >= 0)
printf(" addr 0x%02x", dinfo->gpio_num); /* should not happen */
resource_list_print_type(&dinfo->mdi_resources, "irq", SYS_RES_IRQ,
@@ -240,7 +246,8 @@ macgpio_probe_nomatch(device_t dev, device_t child)
if ((type = ofw_bus_get_type(child)) == NULL)
type = "(unknown)";
device_printf(dev, "<%s, %s>", type, ofw_bus_get_name(child));
- printf(" gpio %d",dinfo->gpio_num);
+ if (dinfo->gpio_num >= 0)
+ printf(" gpio %d",dinfo->gpio_num);
resource_list_print_type(&dinfo->mdi_resources, "irq",
SYS_RES_IRQ, "%ld");
printf(" (no driver attached)\n");
@@ -279,9 +286,11 @@ macgpio_activate_resource(device_t bus, device_t child, int type, int rid,
if (type != SYS_RES_IRQ)
return ENXIO;
- val = bus_read_1(sc->sc_gpios,dinfo->gpio_num);
- val |= 0x80;
- bus_write_1(sc->sc_gpios,dinfo->gpio_num,val);
+ if (dinfo->gpio_num >= 0) {
+ val = bus_read_1(sc->sc_gpios,dinfo->gpio_num);
+ val |= 0x80;
+ bus_write_1(sc->sc_gpios,dinfo->gpio_num,val);
+ }
return (bus_activate_resource(bus, type, rid, res));
}
@@ -301,9 +310,11 @@ macgpio_deactivate_resource(device_t bus, device_t child, int type, int rid,
if (type != SYS_RES_IRQ)
return ENXIO;
- val = bus_read_1(sc->sc_gpios,dinfo->gpio_num);
- val &= ~0x80;
- bus_write_1(sc->sc_gpios,dinfo->gpio_num,val);
+ if (dinfo->gpio_num >= 0) {
+ val = bus_read_1(sc->sc_gpios,dinfo->gpio_num);
+ val &= ~0x80;
+ bus_write_1(sc->sc_gpios,dinfo->gpio_num,val);
+ }
return (bus_deactivate_resource(bus, type, rid, res));
}
@@ -317,6 +328,9 @@ macgpio_read(device_t dev)
sc = device_get_softc(device_get_parent(dev));
dinfo = device_get_ivars(dev);
+ if (dinfo->gpio_num < 0)
+ return (0);
+
return (bus_read_1(sc->sc_gpios,dinfo->gpio_num));
}
@@ -329,6 +343,9 @@ macgpio_write(device_t dev, uint8_t val)
sc = device_get_softc(device_get_parent(dev));
dinfo = device_get_ivars(dev);
+ if (dinfo->gpio_num < 0)
+ return;
+
bus_write_1(sc->sc_gpios,dinfo->gpio_num,val);
}
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c
index 71be113..eab1011 100644
--- a/sys/powerpc/powermac/macio.c
+++ b/sys/powerpc/powermac/macio.c
@@ -152,6 +152,7 @@ static struct macio_pci_dev {
*/
#define MACIO_QUIRK_IGNORE 0x00000001
#define MACIO_QUIRK_CHILD_HAS_INTR 0x00000002
+#define MACIO_QUIRK_USE_CHILD_REG 0x00000004
struct macio_quirk_entry {
const char *mq_name;
@@ -162,7 +163,9 @@ static struct macio_quirk_entry macio_quirks[] = {
{ "escc-legacy", MACIO_QUIRK_IGNORE },
{ "timer", MACIO_QUIRK_IGNORE },
{ "escc", MACIO_QUIRK_CHILD_HAS_INTR },
- { NULL, 0 }
+ { "i2s", MACIO_QUIRK_CHILD_HAS_INTR |
+ MACIO_QUIRK_USE_CHILD_REG },
+ { NULL, 0 }
};
static int
@@ -185,7 +188,6 @@ macio_add_intr(phandle_t devnode, struct macio_devinfo *dinfo)
{
int *intr;
int i, nintr;
- phandle_t iparent;
int icells;
if (dinfo->mdi_ninterrupts >= 6) {
@@ -193,10 +195,9 @@ macio_add_intr(phandle_t devnode, struct macio_devinfo *dinfo)
return;
}
- icells = 1;
-
- if (OF_getprop(devnode, "interrupt-parent", &iparent, sizeof(iparent)) == sizeof(iparent))
- OF_getprop(iparent, "#interrupt-cells", &icells, sizeof(icells));
+ if (OF_searchprop(devnode, "#interrupt-cells", &icells, sizeof(icells))
+ <= 0)
+ icells = 1;
nintr = OF_getprop_alloc(devnode, "interrupts", sizeof(*intr),
(void **)&intr);
@@ -320,7 +321,10 @@ macio_attach(device_t dev)
resource_list_init(&dinfo->mdi_resources);
dinfo->mdi_ninterrupts = 0;
macio_add_intr(child, dinfo);
- macio_add_reg(child, dinfo);
+ if ((quirks & MACIO_QUIRK_USE_CHILD_REG) != 0)
+ macio_add_reg(OF_child(child), dinfo);
+ else
+ macio_add_reg(child, dinfo);
if ((quirks & MACIO_QUIRK_CHILD_HAS_INTR) != 0)
for (subchild = OF_child(child); subchild != 0;
subchild = OF_peer(subchild))
diff --git a/sys/powerpc/powermac/uninorth.c b/sys/powerpc/powermac/uninorth.c
index b0b55a4..d9de1af 100644
--- a/sys/powerpc/powermac/uninorth.c
+++ b/sys/powerpc/powermac/uninorth.c
@@ -164,7 +164,7 @@ uninorth_attach(device_t dev)
{
struct uninorth_softc *sc;
const char *compatible;
- phandle_t node, child, iparent;
+ phandle_t node, child;
u_int32_t reg[2], busrange[2];
struct uninorth_range *rp, *io, *mem[2];
int nmem, i, error;
@@ -296,12 +296,6 @@ uninorth_attach(device_t dev)
ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
- /* We need the number of interrupt cells to read the imap */
- sc->sc_icells = 2;
- if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0)
- OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells,
- sizeof(sc->sc_icells));
-
device_add_child(dev, "pci", device_get_unit(dev));
return (bus_generic_attach(dev));
}
@@ -370,15 +364,14 @@ uninorth_route_interrupt(device_t bus, device_t dev, int pin)
{
struct uninorth_softc *sc;
struct ofw_pci_register reg;
- uint32_t pintr, mintr[2];
+ uint32_t pintr, mintr;
uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bus);
pintr = pin;
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
- sizeof(reg), &pintr, sizeof(pintr), mintr,
- sizeof(mintr[0])*sc->sc_icells, maskbuf))
- return (mintr[0]);
+ sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
+ return (mintr);
/* Maybe it's a real interrupt, not an intpin */
if (pin > 4)
diff --git a/sys/powerpc/powermac/uninorthvar.h b/sys/powerpc/powermac/uninorthvar.h
index 6bb4024..4480eb8 100644
--- a/sys/powerpc/powermac/uninorthvar.h
+++ b/sys/powerpc/powermac/uninorthvar.h
@@ -64,7 +64,6 @@ struct uninorth_softc {
struct ofw_bus_iinfo sc_pci_iinfo;
int sc_u3;
- int sc_icells;
};
struct unin_chip_softc {
diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c
index f563c26..1c4f4fb 100644
--- a/sys/powerpc/powerpc/genassym.c
+++ b/sys/powerpc/powerpc/genassym.c
@@ -108,11 +108,8 @@ ASSYM(PM_PDIR, offsetof(struct pmap, pm_pdir));
#endif
#if defined(E500)
-ASSYM(PTE_RPN, offsetof(struct pte_entry, rpn));
-ASSYM(PTE_FLAGS, offsetof(struct pte_entry, flags));
-ASSYM(TLB0TABLE_MAS1, offsetof(struct tlb_entry, mas1));
-ASSYM(TLB0TABLE_MAS2, offsetof(struct tlb_entry, mas2));
-ASSYM(TLB0TABLE_MAS3, offsetof(struct tlb_entry, mas3));
+ASSYM(PTE_RPN, offsetof(struct pte, rpn));
+ASSYM(PTE_FLAGS, offsetof(struct pte, flags));
ASSYM(TLB0_ENTRY_SIZE, sizeof(struct tlb_entry));
#endif
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
index 3e07348..99b3c2d 100644
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -243,7 +243,7 @@ powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep)
{
struct powerpc_intr *i;
- int error;
+ int error, enable = 0;
i = intr_lookup(irq);
if (i == NULL)
@@ -258,13 +258,16 @@ powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
i->cntp = &intrcnt[i->vector];
- if (!cold)
- PIC_ENABLE(pic, i->irq, i->vector);
+ enable = 1;
}
error = intr_event_add_handler(i->event, name, filter, handler, arg,
intr_priority(flags), flags, cookiep);
intrcnt_setname(i->event->ie_fullname, i->vector);
+
+ if (!cold && enable)
+ PIC_ENABLE(pic, i->irq, i->vector);
+
return (error);
}
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c
index 8d7bfd6..48d9495 100644
--- a/sys/rpc/clnt_rc.c
+++ b/sys/rpc/clnt_rc.c
@@ -181,11 +181,12 @@ again:
rpc_createerr.cf_error.re_errno = 0;
goto out;
}
- if (rc->rc_privport)
- bindresvport(so, NULL);
oldcred = td->td_ucred;
td->td_ucred = rc->rc_ucred;
+ if (rc->rc_privport)
+ bindresvport(so, NULL);
+
if (rc->rc_nconf->nc_semantics == NC_TPI_CLTS)
rc->rc_client = clnt_dg_create(so,
(struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers,
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index 14dbcfd..227d2dc 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -198,11 +198,11 @@ void audit_thread_free(struct thread *td);
/*
* Wrap the audit_syscall_exit() function so that it is called only when
- * auditing is enabled, or we have a audit record on the thread. It is
- * possible that an audit record was begun before auditing was turned off.
+ * we have a audit record on the thread. Audit records can persist after
+ * auditing is disabled, so we don't just check audit_enabled here.
*/
#define AUDIT_SYSCALL_EXIT(error, td) do { \
- if (audit_enabled || (td->td_ar != NULL)) \
+ if (td->td_ar != NULL) \
audit_syscall_exit(error, td); \
} while (0)
diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c
index 1ddb8be..c1e0494 100644
--- a/sys/security/audit/audit_bsm.c
+++ b/sys/security/audit/audit_bsm.c
@@ -1462,7 +1462,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
}
kau_write(rec, subj_tok);
- tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
+ tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval);
kau_write(rec, tok); /* Every record gets a return token */
kau_close(rec, &ar->ar_endtime, ar->ar_event);
diff --git a/sys/security/audit/audit_bsm_domain.c b/sys/security/audit/audit_bsm_domain.c
new file mode 100644
index 0000000..6f43a77
--- /dev/null
+++ b/sys/security/audit/audit_bsm_domain.c
@@ -0,0 +1,502 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_domain.c#2
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <security/audit/audit.h>
+
+#include <bsm/audit_domain.h>
+#include <bsm/audit_record.h>
+
+struct bsm_domain {
+ u_short bd_bsm_domain;
+ int bd_local_domain;
+};
+
+#define PF_NO_LOCAL_MAPPING -600
+
+static const struct bsm_domain bsm_domains[] = {
+ { BSM_PF_UNSPEC, PF_UNSPEC },
+ { BSM_PF_LOCAL, PF_LOCAL },
+ { BSM_PF_INET, PF_INET },
+ { BSM_PF_IMPLINK,
+#ifdef PF_IMPLINK
+ PF_IMPLINK
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PUP,
+#ifdef PF_PUP
+ PF_PUP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CHAOS,
+#ifdef PF_CHAOS
+ PF_CHAOS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NS,
+#ifdef PF_NS
+ PF_NS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NBS,
+#ifdef PF_NBS
+ PF_NBS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ECMA,
+#ifdef PF_ECMA
+ PF_ECMA
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_DATAKIT,
+#ifdef PF_DATAKIT
+ PF_DATAKIT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CCITT,
+#ifdef PF_CCITT
+ PF_CCITT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SNA, PF_SNA },
+ { BSM_PF_DECnet, PF_DECnet },
+ { BSM_PF_DLI,
+#ifdef PF_DLI
+ PF_DLI
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_LAT,
+#ifdef PF_LAT
+ PF_LAT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_HYLINK,
+#ifdef PF_HYLINK
+ PF_HYLINK
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_APPLETALK, PF_APPLETALK },
+ { BSM_PF_NIT,
+#ifdef PF_NIT
+ PF_NIT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_802,
+#ifdef PF_802
+ PF_802
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_OSI,
+#ifdef PF_OSI
+ PF_OSI
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_X25,
+#ifdef PF_X25
+ PF_X25
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_OSINET,
+#ifdef PF_OSINET
+ PF_OSINET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_GOSIP,
+#ifdef PF_GOSIP
+ PF_GOSIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IPX, PF_IPX },
+ { BSM_PF_ROUTE, PF_ROUTE },
+ { BSM_PF_LINK,
+#ifdef PF_LINK
+ PF_LINK
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_INET6, PF_INET6 },
+ { BSM_PF_KEY, PF_KEY },
+ { BSM_PF_NCA,
+#ifdef PF_NCA
+ PF_NCA
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_POLICY,
+#ifdef PF_POLICY
+ PF_POLICY
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_INET_OFFLOAD,
+#ifdef PF_INET_OFFLOAD
+ PF_INET_OFFLOAD
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NETBIOS,
+#ifdef PF_NETBIOS
+ PF_NETBIOS
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ISO,
+#ifdef PF_ISO
+ PF_ISO
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_XTP,
+#ifdef PF_XTP
+ PF_XTP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_COIP,
+#ifdef PF_COIP
+ PF_COIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CNT,
+#ifdef PF_CNT
+ PF_CNT
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_RTIP,
+#ifdef PF_RTIP
+ PF_RTIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SIP,
+#ifdef PF_SIP
+ PF_SIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PIP,
+#ifdef PF_PIP
+ PF_PIP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ISDN,
+#ifdef PF_ISDN
+ PF_ISDN
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_E164,
+#ifdef PF_E164
+ PF_E164
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NATM,
+#ifdef PF_NATM
+ PF_NATM
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ATM,
+#ifdef PF_ATM
+ PF_ATM
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NETGRAPH,
+#ifdef PF_NETGRAPH
+ PF_NETGRAPH
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SLOW,
+#ifdef PF_SLOW
+ PF_SLOW
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SCLUSTER,
+#ifdef PF_SCLUSTER
+ PF_SCLUSTER
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ARP,
+#ifdef PF_ARP
+ PF_ARP
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_BLUETOOTH,
+#ifdef PF_BLUETOOTH
+ PF_BLUETOOTH
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IEEE80211,
+#ifdef PF_IEEE80211
+ PF_IEEE80211
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_AX25,
+#ifdef PF_AX25
+ PF_AX25
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ROSE,
+#ifdef PF_ROSE
+ PF_ROSE
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_NETBEUI,
+#ifdef PF_NETBEUI
+ PF_NETBEUI
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_SECURITY,
+#ifdef PF_SECURITY
+ PF_SECURITY
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PACKET,
+#ifdef PF_PACKET
+ PF_PACKET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ASH,
+#ifdef PF_ASH
+ PF_ASH
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ECONET,
+#ifdef PF_ECONET
+ PF_ECONET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_ATMSVC,
+#ifdef PF_ATMSVC
+ PF_ATMSVC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IRDA,
+#ifdef PF_IRDA
+ PF_IRDA
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PPPOX,
+#ifdef PF_PPPOX
+ PF_PPPOX
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_WANPIPE,
+#ifdef PF_WANPIPE
+ PF_WANPIPE
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_LLC,
+#ifdef PF_LLC
+ PF_LLC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_CAN,
+#ifdef PF_CAN
+ PF_CAN
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_TIPC,
+#ifdef PF_TIPC
+ PF_TIPC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_IUCV,
+#ifdef PF_IUCV
+ PF_IUCV
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_RXRPC,
+#ifdef PF_RXRPC
+ PF_RXRPC
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+ { BSM_PF_PHONET,
+#ifdef PF_PHONET
+ PF_PHONET
+#else
+ PF_NO_LOCAL_MAPPING
+#endif
+ },
+};
+static const int bsm_domains_count = sizeof(bsm_domains) /
+ sizeof(bsm_domains[0]);
+
+static const struct bsm_domain *
+bsm_lookup_local_domain(int local_domain)
+{
+ int i;
+
+ for (i = 0; i < bsm_domains_count; i++) {
+ if (bsm_domains[i].bd_local_domain == local_domain)
+ return (&bsm_domains[i]);
+ }
+ return (NULL);
+}
+
+u_short
+au_domain_to_bsm(int local_domain)
+{
+ const struct bsm_domain *bstp;
+
+ bstp = bsm_lookup_local_domain(local_domain);
+ if (bstp == NULL)
+ return (BSM_PF_UNKNOWN);
+ return (bstp->bd_bsm_domain);
+}
+
+static const struct bsm_domain *
+bsm_lookup_bsm_domain(u_short bsm_domain)
+{
+ int i;
+
+ for (i = 0; i < bsm_domains_count; i++) {
+ if (bsm_domains[i].bd_bsm_domain == bsm_domain)
+ return (&bsm_domains[i]);
+ }
+ return (NULL);
+}
+
+int
+au_bsm_to_domain(u_short bsm_domain, int *local_domainp)
+{
+ const struct bsm_domain *bstp;
+
+ bstp = bsm_lookup_bsm_domain(bsm_domain);
+ if (bstp == NULL || bstp->bd_local_domain)
+ return (-1);
+ *local_domainp = bstp->bd_local_domain;
+ return (0);
+}
diff --git a/sys/security/audit/audit_bsm_errno.c b/sys/security/audit/audit_bsm_errno.c
new file mode 100644
index 0000000..782ce62
--- /dev/null
+++ b/sys/security/audit/audit_bsm_errno.c
@@ -0,0 +1,663 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_errno.c#12
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <security/audit/audit.h>
+
+#include <bsm/audit_errno.h>
+#include <bsm/audit_record.h>
+
+#include <sys/errno.h>
+
+/*
+ * Different operating systems use different numeric constants for different
+ * error numbers, and sometimes error numbers don't exist in more than one
+ * operating system. These routines convert between BSM and local error
+ * number spaces, subject to the above realities. BSM error numbers are
+ * stored in a single 8-bit character, so don't have a byte order.
+ *
+ * Don't include string definitions when this code is compiled into a kernel.
+ */
+struct bsm_errno {
+ int be_bsm_errno;
+ int be_local_errno;
+#if !defined(KERNEL) && !defined(_KERNEL)
+ const char *be_strerror;
+#endif
+};
+
+#define ERRNO_NO_LOCAL_MAPPING -600
+
+#if !defined(KERNEL) && !defined(_KERNEL)
+#define ES(x) x
+#else
+#define ES(x)
+#endif
+
+/*
+ * Mapping table -- please maintain in numeric sorted order with respect to
+ * the BSM constant. Today we do a linear lookup, but could switch to a
+ * binary search if it makes sense. We only ifdef errors that aren't
+ * generally available, but it does make the table a lot more ugly.
+ *
+ * XXXRW: It would be nice to have a similar ordered table mapping to BSM
+ * constant from local constant, but the order of local constants varies by
+ * OS. Really we need to build that table at compile-time but don't do that
+ * yet.
+ *
+ * XXXRW: We currently embed English-language error strings here, but should
+ * support catalogues; these are only used if the OS doesn't have an error
+ * string using strerror(3).
+ */
+static const struct bsm_errno bsm_errnos[] = {
+ { BSM_ERRNO_ESUCCESS, 0, ES("Success") },
+ { BSM_ERRNO_EPERM, EPERM, ES("Operation not permitted") },
+ { BSM_ERRNO_ENOENT, ENOENT, ES("No such file or directory") },
+ { BSM_ERRNO_ESRCH, ESRCH, ES("No such process") },
+ { BSM_ERRNO_EINTR, EINTR, ES("Interrupted system call") },
+ { BSM_ERRNO_EIO, EIO, ES("Input/output error") },
+ { BSM_ERRNO_ENXIO, ENXIO, ES("Device not configured") },
+ { BSM_ERRNO_E2BIG, E2BIG, ES("Argument list too long") },
+ { BSM_ERRNO_ENOEXEC, ENOEXEC, ES("Exec format error") },
+ { BSM_ERRNO_EBADF, EBADF, ES("Bad file descriptor") },
+ { BSM_ERRNO_ECHILD, ECHILD, ES("No child processes") },
+ { BSM_ERRNO_EAGAIN, EAGAIN, ES("Resource temporarily unavailable") },
+ { BSM_ERRNO_ENOMEM, ENOMEM, ES("Cannot allocate memory") },
+ { BSM_ERRNO_EACCES, EACCES, ES("Permission denied") },
+ { BSM_ERRNO_EFAULT, EFAULT, ES("Bad address") },
+ { BSM_ERRNO_ENOTBLK, ENOTBLK, ES("Block device required") },
+ { BSM_ERRNO_EBUSY, EBUSY, ES("Device busy") },
+ { BSM_ERRNO_EEXIST, EEXIST, ES("File exists") },
+ { BSM_ERRNO_EXDEV, EXDEV, ES("Cross-device link") },
+ { BSM_ERRNO_ENODEV, ENODEV, ES("Operation not supported by device") },
+ { BSM_ERRNO_ENOTDIR, ENOTDIR, ES("Not a directory") },
+ { BSM_ERRNO_EISDIR, EISDIR, ES("Is a directory") },
+ { BSM_ERRNO_EINVAL, EINVAL, ES("Invalid argument") },
+ { BSM_ERRNO_ENFILE, ENFILE, ES("Too many open files in system") },
+ { BSM_ERRNO_EMFILE, EMFILE, ES("Too many open files") },
+ { BSM_ERRNO_ENOTTY, ENOTTY, ES("Inappropriate ioctl for device") },
+ { BSM_ERRNO_ETXTBSY, ETXTBSY, ES("Text file busy") },
+ { BSM_ERRNO_EFBIG, EFBIG, ES("File too large") },
+ { BSM_ERRNO_ENOSPC, ENOSPC, ES("No space left on device") },
+ { BSM_ERRNO_ESPIPE, ESPIPE, ES("Illegal seek") },
+ { BSM_ERRNO_EROFS, EROFS, ES("Read-only file system") },
+ { BSM_ERRNO_EMLINK, EMLINK, ES("Too many links") },
+ { BSM_ERRNO_EPIPE, EPIPE, ES("Broken pipe") },
+ { BSM_ERRNO_EDOM, EDOM, ES("Numerical argument out of domain") },
+ { BSM_ERRNO_ERANGE, ERANGE, ES("Result too large") },
+ { BSM_ERRNO_ENOMSG, ENOMSG, ES("No message of desired type") },
+ { BSM_ERRNO_EIDRM, EIDRM, ES("Identifier removed") },
+ { BSM_ERRNO_ECHRNG,
+#ifdef ECHRNG
+ ECHRNG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Channel number out of range") },
+ { BSM_ERRNO_EL2NSYNC,
+#ifdef EL2NSYNC
+ EL2NSYNC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 2 not synchronized") },
+ { BSM_ERRNO_EL3HLT,
+#ifdef EL3HLT
+ EL3HLT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 3 halted") },
+ { BSM_ERRNO_EL3RST,
+#ifdef EL3RST
+ EL3RST,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 3 reset") },
+ { BSM_ERRNO_ELNRNG,
+#ifdef ELNRNG
+ ELNRNG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Link number out of range") },
+ { BSM_ERRNO_EUNATCH,
+#ifdef EUNATCH
+ EUNATCH,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Protocol driver not attached") },
+ { BSM_ERRNO_ENOCSI,
+#ifdef ENOCSI
+ ENOCSI,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No CSI structure available") },
+ { BSM_ERRNO_EL2HLT,
+#ifdef EL2HLT
+ EL2HLT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Level 2 halted") },
+ { BSM_ERRNO_EDEADLK, EDEADLK, ES("Resource deadlock avoided") },
+ { BSM_ERRNO_ENOLCK, ENOLCK, ES("No locks available") },
+ { BSM_ERRNO_ECANCELED, ECANCELED, ES("Operation canceled") },
+ { BSM_ERRNO_ENOTSUP, ENOTSUP, ES("Operation not supported") },
+ { BSM_ERRNO_EDQUOT, EDQUOT, ES("Disc quota exceeded") },
+ { BSM_ERRNO_EBADE,
+#ifdef EBADE
+ EBADE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid exchange") },
+ { BSM_ERRNO_EBADR,
+#ifdef EBADR
+ EBADR,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid request descriptor") },
+ { BSM_ERRNO_EXFULL,
+#ifdef EXFULL
+ EXFULL,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Exchange full") },
+ { BSM_ERRNO_ENOANO,
+#ifdef ENOANO
+ ENOANO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No anode") },
+ { BSM_ERRNO_EBADRQC,
+#ifdef EBADRQC
+ EBADRQC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid request descriptor") },
+ { BSM_ERRNO_EBADSLT,
+#ifdef EBADSLT
+ EBADSLT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Invalid slot") },
+ { BSM_ERRNO_EDEADLOCK,
+#ifdef EDEADLOCK
+ EDEADLOCK,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Resource deadlock avoided") },
+ { BSM_ERRNO_EBFONT,
+#ifdef EBFONT
+ EBFONT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad font file format") },
+ { BSM_ERRNO_EOWNERDEAD,
+#ifdef EOWNERDEAD
+ EOWNERDEAD,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Process died with the lock") },
+ { BSM_ERRNO_ENOTRECOVERABLE,
+#ifdef ENOTRECOVERABLE
+ ENOTRECOVERABLE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Lock is not recoverable") },
+ { BSM_ERRNO_ENOSTR,
+#ifdef ENOSTR
+ ENOSTR,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Device not a stream") },
+ { BSM_ERRNO_ENONET,
+#ifdef ENONET
+ ENONET,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Machine is not on the network") },
+ { BSM_ERRNO_ENOPKG,
+#ifdef ENOPKG
+ ENOPKG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Package not installed") },
+ { BSM_ERRNO_EREMOTE, EREMOTE,
+ ES("Too many levels of remote in path") },
+ { BSM_ERRNO_ENOLINK,
+#ifdef ENOLINK
+ ENOLINK,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Link has been severed") },
+ { BSM_ERRNO_EADV,
+#ifdef EADV
+ EADV,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Advertise error") },
+ { BSM_ERRNO_ESRMNT,
+#ifdef ESRMNT
+ ESRMNT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("srmount error") },
+ { BSM_ERRNO_ECOMM,
+#ifdef ECOMM
+ ECOMM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Communication error on send") },
+ { BSM_ERRNO_EPROTO,
+#ifdef EPROTO
+ EPROTO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Protocol error") },
+ { BSM_ERRNO_ELOCKUNMAPPED,
+#ifdef ELOCKUNMAPPED
+ ELOCKUNMAPPED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Locked lock was unmapped") },
+ { BSM_ERRNO_ENOTACTIVE,
+#ifdef ENOTACTIVE
+ ENOTACTIVE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Facility is not active") },
+ { BSM_ERRNO_EMULTIHOP,
+#ifdef EMULTIHOP
+ EMULTIHOP,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Multihop attempted") },
+ { BSM_ERRNO_EBADMSG,
+#ifdef EBADMSG
+ EBADMSG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad message") },
+ { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, ES("File name too long") },
+ { BSM_ERRNO_EOVERFLOW, EOVERFLOW,
+ ES("Value too large to be stored in data type") },
+ { BSM_ERRNO_ENOTUNIQ,
+#ifdef ENOTUNIQ
+ ENOTUNIQ,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Given log name not unique") },
+ { BSM_ERRNO_EBADFD,
+#ifdef EBADFD
+ EBADFD,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Given f.d. invalid for this operation") },
+ { BSM_ERRNO_EREMCHG,
+#ifdef EREMCHG
+ EREMCHG,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Remote address changed") },
+ { BSM_ERRNO_ELIBACC,
+#ifdef ELIBACC
+ ELIBACC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Can't access a needed shared lib") },
+ { BSM_ERRNO_ELIBBAD,
+#ifdef ELIBBAD
+ ELIBBAD,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Accessing a corrupted shared lib") },
+ { BSM_ERRNO_ELIBSCN,
+#ifdef ELIBSCN
+ ELIBSCN,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES(".lib section in a.out corrupted") },
+ { BSM_ERRNO_ELIBMAX,
+#ifdef ELIBMAX
+ ELIBMAX,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Attempting to link in too many libs") },
+ { BSM_ERRNO_ELIBEXEC,
+#ifdef ELIBEXEC
+ ELIBEXEC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Attempting to exec a shared library") },
+ { BSM_ERRNO_EILSEQ, EILSEQ, ES("Illegal byte sequence") },
+ { BSM_ERRNO_ENOSYS, ENOSYS, ES("Function not implemented") },
+ { BSM_ERRNO_ELOOP, ELOOP, ES("Too many levels of symbolic links") },
+ { BSM_ERRNO_ERESTART,
+#ifdef ERESTART
+ ERESTART,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Restart syscall") },
+ { BSM_ERRNO_ESTRPIPE,
+#ifdef ESTRPIPE
+ ESTRPIPE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("If pipe/FIFO, don't sleep in stream head") },
+ { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, ES("Directory not empty") },
+ { BSM_ERRNO_EUSERS, EUSERS, ES("Too many users") },
+ { BSM_ERRNO_ENOTSOCK, ENOTSOCK,
+ ES("Socket operation on non-socket") },
+ { BSM_ERRNO_EDESTADDRREQ, EDESTADDRREQ,
+ ES("Destination address required") },
+ { BSM_ERRNO_EMSGSIZE, EMSGSIZE, ES("Message too long") },
+ { BSM_ERRNO_EPROTOTYPE, EPROTOTYPE,
+ ES("Protocol wrong type for socket") },
+ { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, ES("Protocol not available") },
+ { BSM_ERRNO_EPROTONOSUPPORT, EPROTONOSUPPORT,
+ ES("Protocol not supported") },
+ { BSM_ERRNO_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT,
+ ES("Socket type not supported") },
+ { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, ES("Operation not supported") },
+ { BSM_ERRNO_EPFNOSUPPORT, EPFNOSUPPORT,
+ ES("Protocol family not supported") },
+ { BSM_ERRNO_EAFNOSUPPORT, EAFNOSUPPORT,
+ ES("Address family not supported by protocol family") },
+ { BSM_ERRNO_EADDRINUSE, EADDRINUSE, ES("Address already in use") },
+ { BSM_ERRNO_EADDRNOTAVAIL, EADDRNOTAVAIL,
+ ES("Can't assign requested address") },
+ { BSM_ERRNO_ENETDOWN, ENETDOWN, ES("Network is down") },
+ { BSM_ERRNO_ENETRESET, ENETRESET,
+ ES("Network dropped connection on reset") },
+ { BSM_ERRNO_ECONNABORTED, ECONNABORTED,
+ ES("Software caused connection abort") },
+ { BSM_ERRNO_ECONNRESET, ECONNRESET, ES("Connection reset by peer") },
+ { BSM_ERRNO_ENOBUFS, ENOBUFS, ES("No buffer space available") },
+ { BSM_ERRNO_EISCONN, EISCONN, ES("Socket is already connected") },
+ { BSM_ERRNO_ENOTCONN, ENOTCONN, ES("Socket is not connected") },
+ { BSM_ERRNO_ESHUTDOWN, ESHUTDOWN,
+ ES("Can't send after socket shutdown") },
+ { BSM_ERRNO_ETOOMANYREFS, ETOOMANYREFS,
+ ES("Too many references: can't splice") },
+ { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, ES("Operation timed out") },
+ { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, ES("Connection refused") },
+ { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, ES("Host is down") },
+ { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, ES("No route to host") },
+ { BSM_ERRNO_EALREADY, EALREADY, ES("Operation already in progress") },
+ { BSM_ERRNO_EINPROGRESS, EINPROGRESS,
+ ES("Operation now in progress") },
+ { BSM_ERRNO_ESTALE, ESTALE, ES("Stale NFS file handle") },
+ { BSM_ERRNO_EPWROFF,
+#ifdef EPWROFF
+ EPWROFF,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Device power is off") },
+ { BSM_ERRNO_EDEVERR,
+#ifdef EDEVERR
+ EDEVERR,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Device error") },
+ { BSM_ERRNO_EBADEXEC,
+#ifdef EBADEXEC
+ EBADEXEC,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad executable") },
+ { BSM_ERRNO_EBADARCH,
+#ifdef EBADARCH
+ EBADARCH,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Bad CPU type in executable") },
+ { BSM_ERRNO_ESHLIBVERS,
+#ifdef ESHLIBVERS
+ ESHLIBVERS,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Shared library version mismatch") },
+ { BSM_ERRNO_EBADMACHO,
+#ifdef EBADMACHO
+ EBADMACHO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Malfored Macho file") },
+ { BSM_ERRNO_EPOLICY,
+#ifdef EPOLICY
+ EPOLICY,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Operation failed by policy") },
+ { BSM_ERRNO_EDOTDOT,
+#ifdef EDOTDOT
+ EDOTDOT,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("RFS specific error") },
+ { BSM_ERRNO_EUCLEAN,
+#ifdef EUCLEAN
+ EUCLEAN,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Structure needs cleaning") },
+ { BSM_ERRNO_ENOTNAM,
+#ifdef ENOTNAM
+ ENOTNAM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Not a XENIX named type file") },
+ { BSM_ERRNO_ENAVAIL,
+#ifdef ENAVAIL
+ ENAVAIL,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No XENIX semaphores available") },
+ { BSM_ERRNO_EISNAM,
+#ifdef EISNAM
+ EISNAM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Is a named type file") },
+ { BSM_ERRNO_EREMOTEIO,
+#ifdef EREMOTEIO
+ EREMOTEIO,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Remote I/O error") },
+ { BSM_ERRNO_ENOMEDIUM,
+#ifdef ENOMEDIUM
+ ENOMEDIUM,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("No medium found") },
+ { BSM_ERRNO_EMEDIUMTYPE,
+#ifdef EMEDIUMTYPE
+ EMEDIUMTYPE,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Wrong medium type") },
+ { BSM_ERRNO_ENOKEY,
+#ifdef ENOKEY
+ ENOKEY,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Required key not available") },
+ { BSM_ERRNO_EKEYEXPIRED,
+#ifdef EKEEXPIRED
+ EKEYEXPIRED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Key has expired") },
+ { BSM_ERRNO_EKEYREVOKED,
+#ifdef EKEYREVOKED
+ EKEYREVOKED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Key has been revoked") },
+ { BSM_ERRNO_EKEYREJECTED,
+#ifdef EKEREJECTED
+ EKEYREJECTED,
+#else
+ ERRNO_NO_LOCAL_MAPPING,
+#endif
+ ES("Key was rejected by service") },
+};
+static const int bsm_errnos_count = sizeof(bsm_errnos) / sizeof(bsm_errnos[0]);
+
+static const struct bsm_errno *
+bsm_lookup_errno_local(int local_errno)
+{
+ int i;
+
+ for (i = 0; i < bsm_errnos_count; i++) {
+ if (bsm_errnos[i].be_local_errno == local_errno)
+ return (&bsm_errnos[i]);
+ }
+ return (NULL);
+}
+
+/*
+ * Conversion to the BSM errno space isn't allowed to fail; we simply map to
+ * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it.
+ */
+u_char
+au_errno_to_bsm(int local_errno)
+{
+ const struct bsm_errno *bsme;
+
+ bsme = bsm_lookup_errno_local(local_errno);
+ if (bsme == NULL)
+ return (BSM_ERRNO_UNKNOWN);
+ return (bsme->be_bsm_errno);
+}
+
+static const struct bsm_errno *
+bsm_lookup_errno_bsm(u_char bsm_errno)
+{
+ int i;
+
+ for (i = 0; i < bsm_errnos_count; i++) {
+ if (bsm_errnos[i].be_bsm_errno == bsm_errno)
+ return (&bsm_errnos[i]);
+ }
+ return (NULL);
+}
+
+/*
+ * Converstion from a BSM error to a local error number may fail if either
+ * OpenBSM doesn't recognize the error on the wire, or because there is no
+ * appropriate local mapping.
+ */
+int
+au_bsm_to_errno(u_char bsm_errno, int *errorp)
+{
+ const struct bsm_errno *bsme;
+
+ bsme = bsm_lookup_errno_bsm(bsm_errno);
+ if (bsme == NULL || bsme->be_local_errno == ERRNO_NO_LOCAL_MAPPING)
+ return (-1);
+ *errorp = bsme->be_local_errno;
+ return (0);
+}
+
+#if !defined(KERNEL) && !defined(_KERNEL)
+const char *
+au_strerror(u_char bsm_errno)
+{
+ const struct bsm_errno *bsme;
+
+ bsme = bsm_lookup_errno_bsm(bsm_errno);
+ if (bsme == NULL)
+ return ("Unrecognized BSM error");
+ if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING)
+ return (strerror(bsme->be_local_errno));
+ return (bsme->be_strerror);
+}
+#endif
diff --git a/sys/security/audit/audit_bsm_socket_type.c b/sys/security/audit/audit_bsm_socket_type.c
new file mode 100644
index 0000000..c049179
--- /dev/null
+++ b/sys/security/audit/audit_bsm_socket_type.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2008 Apple Inc.
+ * 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 Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE 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.
+ *
+ * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_socket_type.c#1
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <security/audit/audit.h>
+
+#include <bsm/audit_record.h>
+#include <bsm/audit_socket_type.h>
+
+struct bsm_socket_type {
+ u_short bst_bsm_socket_type;
+ int bst_local_socket_type;
+};
+
+#define ST_NO_LOCAL_MAPPING -600
+
+static const struct bsm_socket_type bsm_socket_types[] = {
+ { BSM_SOCK_DGRAM, SOCK_DGRAM },
+ { BSM_SOCK_STREAM, SOCK_STREAM },
+ { BSM_SOCK_RAW, SOCK_RAW },
+ { BSM_SOCK_RDM, SOCK_RDM },
+ { BSM_SOCK_SEQPACKET, SOCK_SEQPACKET },
+};
+static const int bsm_socket_types_count = sizeof(bsm_socket_types) /
+ sizeof(bsm_socket_types[0]);
+
+static const struct bsm_socket_type *
+bsm_lookup_local_socket_type(int local_socket_type)
+{
+ int i;
+
+ for (i = 0; i < bsm_socket_types_count; i++) {
+ if (bsm_socket_types[i].bst_local_socket_type ==
+ local_socket_type)
+ return (&bsm_socket_types[i]);
+ }
+ return (NULL);
+}
+
+u_short
+au_socket_type_to_bsm(int local_socket_type)
+{
+ const struct bsm_socket_type *bstp;
+
+ bstp = bsm_lookup_local_socket_type(local_socket_type);
+ if (bstp == NULL)
+ return (BSM_SOCK_UNKNOWN);
+ return (bstp->bst_bsm_socket_type);
+}
+
+static const struct bsm_socket_type *
+bsm_lookup_bsm_socket_type(u_short bsm_socket_type)
+{
+ int i;
+
+ for (i = 0; i < bsm_socket_types_count; i++) {
+ if (bsm_socket_types[i].bst_bsm_socket_type ==
+ bsm_socket_type)
+ return (&bsm_socket_types[i]);
+ }
+ return (NULL);
+}
+
+int
+au_bsm_to_socket_type(u_short bsm_socket_type, int *local_socket_typep)
+{
+ const struct bsm_socket_type *bstp;
+
+ bstp = bsm_lookup_bsm_socket_type(bsm_socket_type);
+ if (bstp == NULL || bstp->bst_local_socket_type)
+ return (-1);
+ *local_socket_typep = bstp->bst_local_socket_type;
+ return (0);
+}
diff --git a/sys/security/audit/audit_bsm_token.c b/sys/security/audit/audit_bsm_token.c
index b1d977d..a30fa53 100644
--- a/sys/security/audit/audit_bsm_token.c
+++ b/sys/security/audit/audit_bsm_token.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004-2008 Apple Inc.
+ * Copyright (c) 2004-2009 Apple Inc.
* Copyright (c) 2005 SPARTA, Inc.
* All rights reserved.
*
@@ -30,7 +30,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#72
+ * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#86
*/
#include <sys/cdefs.h>
@@ -147,8 +147,12 @@ au_to_attr32(struct vnode_au_info *vni)
ADD_U_CHAR(dptr, AUT_ATTR32);
/*
- * Darwin defines the size for the file mode as 2 bytes; BSM defines
- * 4 so pad with 0.
+ * BSD defines the size for the file mode as 2 bytes; BSM defines 4
+ * so pad with 0.
+ *
+ * XXXRW: Possibly should be conditionally compiled.
+ *
+ * XXXRW: Should any conversions take place on the mode?
*/
ADD_U_INT16(dptr, pad0_16);
ADD_U_INT16(dptr, vni->vn_mode);
@@ -190,8 +194,12 @@ au_to_attr64(struct vnode_au_info *vni)
ADD_U_CHAR(dptr, AUT_ATTR64);
/*
- * Darwin defines the size for the file mode as 2 bytes; BSM defines
- * 4 so pad with 0.
+ * BSD defines the size for the file mode as 2 bytes; BSM defines 4
+ * so pad with 0.
+ *
+ * XXXRW: Possibly should be conditionally compiled.
+ *
+ * XXXRW: Should any conversions take place on the mode?
*/
ADD_U_INT16(dptr, pad0_16);
ADD_U_INT16(dptr, vni->vn_mode);
@@ -269,6 +277,10 @@ au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
+ /*
+ * XXXRW: We should be byte-swapping each data item for multi-byte
+ * types.
+ */
ADD_U_CHAR(dptr, AUT_DATA);
ADD_U_CHAR(dptr, unit_print);
ADD_U_CHAR(dptr, unit_type);
@@ -432,25 +444,36 @@ au_to_ipc_perm(struct ipc_perm *perm)
ADD_U_CHAR(dptr, AUT_IPC_PERM);
/*
- * Darwin defines the sizes for ipc_perm members as 2 bytes; BSM
- * defines 4 so pad with 0.
+ * Systems vary significantly in what types they use in struct
+ * ipc_perm; at least a few still use 16-bit uid's and gid's, so
+ * allow for that, as BSM define 32-bit values here.
+ * Some systems define the sizes for ipc_perm members as 2 bytes;
+ * BSM defines 4 so pad with 0.
+ *
+ * XXXRW: Possibly shoulid be conditionally compiled, and more cases
+ * need to be handled.
*/
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->uid);
-
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->gid);
-
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->cuid);
-
- ADD_U_INT16(dptr, pad0);
- ADD_U_INT16(dptr, perm->cgid);
+ if (sizeof(perm->uid) != sizeof(u_int32_t)) {
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->uid);
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->gid);
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->cuid);
+ ADD_U_INT16(dptr, pad0);
+ ADD_U_INT16(dptr, perm->cgid);
+ } else {
+ ADD_U_INT32(dptr, perm->uid);
+ ADD_U_INT32(dptr, perm->gid);
+ ADD_U_INT32(dptr, perm->cuid);
+ ADD_U_INT32(dptr, perm->cgid);
+ }
ADD_U_INT16(dptr, pad0);
ADD_U_INT16(dptr, perm->mode);
ADD_U_INT16(dptr, pad0);
+
ADD_U_INT16(dptr, perm->seq);
ADD_U_INT32(dptr, perm->key);
@@ -543,6 +566,8 @@ au_to_text(const char *text)
textlen = strlen(text);
textlen += 1;
+ /* XXXRW: Should validate length against token size limit. */
+
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
ADD_U_CHAR(dptr, AUT_TEXT);
@@ -607,6 +632,13 @@ au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
ADD_U_INT32(dptr, pid);
ADD_U_INT32(dptr, sid);
ADD_U_INT32(dptr, tid->port);
+
+ /*
+ * Note: Solaris will write out IPv6 addresses here as a 32-bit
+ * address type and 16 bytes of address, but for IPv4 addresses it
+ * simply writes the 4-byte address directly. We support only IPv4
+ * addresses for process32 tokens.
+ */
ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
return (t);
@@ -631,6 +663,13 @@ au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
ADD_U_INT32(dptr, pid);
ADD_U_INT32(dptr, sid);
ADD_U_INT64(dptr, tid->port);
+
+ /*
+ * Note: Solaris will write out IPv6 addresses here as a 32-bit
+ * address type and 16 bytes of address, but for IPv4 addresses it
+ * simply writes the 4-byte address directly. We support only IPv4
+ * addresses for process64 tokens.
+ */
ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
return (t);
@@ -805,22 +844,63 @@ au_to_seq(long audit_count)
/*
* token ID 1 byte
+ * socket domain 2 bytes
* socket type 2 bytes
+ * address type 2 byte
* local port 2 bytes
- * local Internet address 4 bytes
+ * local address 4 bytes/16 bytes (IPv4/IPv6 address)
* remote port 2 bytes
- * remote Internet address 4 bytes
+ * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
+ *
+ * Domain and type arguments to this routine are assumed to already have been
+ * converted to the BSM constant space, so we don't do that here.
*/
token_t *
-au_to_socket(struct socket *so)
+au_to_socket_ex(u_short so_domain, u_short so_type,
+ struct sockaddr *sa_local, struct sockaddr *sa_remote)
{
+ token_t *t;
+ u_char *dptr = NULL;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ if (so_domain == AF_INET)
+ GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
+ 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
+ else if (so_domain == AF_INET6)
+ GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
+ 5 * sizeof(u_int16_t) + 16 * sizeof(u_int32_t));
+ else
+ return (NULL);
+
+ ADD_U_CHAR(dptr, AUT_SOCKET_EX);
+ ADD_U_INT16(dptr, so_domain); /* XXXRW: explicitly convert? */
+ ADD_U_INT16(dptr, so_type); /* XXXRW: explicitly convert? */
+ if (so_domain == AF_INET) {
+ ADD_U_INT16(dptr, AU_IPv4);
+ sin = (struct sockaddr_in *)sa_local;
+ ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
+ sin = (struct sockaddr_in *)sa_remote;
+ ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
+ } else {
+ ADD_U_INT16(dptr, AU_IPv6);
+ sin6 = (struct sockaddr_in6 *)sa_local;
+ ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
+ sin6 = (struct sockaddr_in6 *)sa_remote;
+ ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
+ ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
+ }
- /* XXXRW ... */
- return (NULL);
+ return (t);
}
/*
* Kernel-specific version of the above function.
+ *
+ * XXXRW: Should now use au_to_socket_ex() here.
*/
#ifdef _KERNEL
token_t *
@@ -832,7 +912,7 @@ kau_to_socket(struct socket_au_info *soi)
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
-
+
ADD_U_CHAR(dptr, AUT_SOCKET);
/* Coerce the socket type into a short value */
so_type = soi->so_type;
@@ -848,32 +928,6 @@ kau_to_socket(struct socket_au_info *soi)
/*
* token ID 1 byte
- * socket type 2 bytes
- * local port 2 bytes
- * address type/length 4 bytes
- * local Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
- * remote port 4 bytes
- * address type/length 4 bytes
- * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
- */
-token_t *
-au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
- struct sockaddr *ra)
-{
-
- return (NULL);
-}
-
-token_t *
-au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
- struct sockaddr *ra)
-{
-
- return (NULL);
-}
-
-/*
- * token ID 1 byte
* socket family 2 bytes
* path 104 bytes
*/
@@ -940,8 +994,9 @@ au_to_sock_inet128(struct sockaddr_in6 *so)
ADD_U_CHAR(dptr, AUT_SOCKINET128);
/*
- * In Darwin, sin6_family is one octet, but BSM defines the token
- * to store two. So we copy in a 0 first.
+ * In BSD, sin6_family is one octet, but BSM defines the token to
+ * store two. So we copy in a 0 first. XXXRW: Possibly should be
+ * conditionally compiled.
*/
ADD_U_CHAR(dptr, 0);
ADD_U_CHAR(dptr, so->sin6_family);
@@ -1215,7 +1270,6 @@ au_to_exec_args(char **argv)
nextarg = *(argv + count);
}
- totlen += count * sizeof(char); /* nul terminations. */
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
@@ -1228,30 +1282,7 @@ au_to_exec_args(char **argv)
return (t);
}
-#endif
-
-/*
- * token ID 1 byte
- * zonename length 2 bytes
- * zonename N bytes + 1 terminating NULL byte
- */
-token_t *
-au_to_zonename(const char *zonename)
-{
- u_char *dptr = NULL;
- u_int16_t textlen;
- token_t *t;
-
- textlen = strlen(zonename);
- textlen += 1;
- GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
- ADD_U_CHAR(dptr, AUT_ZONENAME);
- ADD_U_INT16(dptr, textlen);
- ADD_STRING(dptr, zonename, textlen);
- return (t);
-}
-#if !defined(_KERNEL) && !defined(KERNEL)
/*
* token ID 1 byte
* count 4 bytes
@@ -1277,7 +1308,6 @@ au_to_exec_env(char **envp)
nextenv = *(envp + count);
}
- totlen += sizeof(char) * count;
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
ADD_U_CHAR(dptr, AUT_EXEC_ENV);
@@ -1294,6 +1324,27 @@ au_to_exec_env(char **envp)
/*
* token ID 1 byte
+ * zonename length 2 bytes
+ * zonename N bytes + 1 terminating NULL byte
+ */
+token_t *
+au_to_zonename(const char *zonename)
+{
+ u_char *dptr = NULL;
+ u_int16_t textlen;
+ token_t *t;
+
+ textlen = strlen(zonename) + 1;
+ GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
+
+ ADD_U_CHAR(dptr, AUT_ZONENAME);
+ ADD_U_INT16(dptr, textlen);
+ ADD_STRING(dptr, zonename, textlen);
+ return (t);
+}
+
+/*
+ * token ID 1 byte
* record byte count 4 bytes
* version # 1 byte [2]
* event type 2 bytes
@@ -1465,7 +1516,7 @@ au_to_trailer(int rec_size)
{
token_t *t;
u_char *dptr = NULL;
- u_int16_t magic = TRAILER_PAD_MAGIC;
+ u_int16_t magic = AUT_TRAILER_MAGIC;
GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
sizeof(u_int32_t));
diff --git a/sys/security/audit/audit_pipe.c b/sys/security/audit/audit_pipe.c
index f12a2b1..318f41d 100644
--- a/sys/security/audit/audit_pipe.c
+++ b/sys/security/audit/audit_pipe.c
@@ -169,7 +169,8 @@ struct audit_pipe {
/*
* Current pending record list. Protected by a combination of ap_mtx
* and ap_sx. Note particularly that *both* locks are required to
- * remove a record from the head of the queue, as an in-progress read * may sleep while copying and therefore cannot hold ap_mtx.
+ * remove a record from the head of the queue, as an in-progress read
+ * may sleep while copying and therefore cannot hold ap_mtx.
*/
TAILQ_HEAD(, audit_pipe_entry) ap_queue;
@@ -435,6 +436,10 @@ audit_pipe_preselect(au_id_t auid, au_event_t event, au_class_t class,
{
struct audit_pipe *ap;
+ /* Lockless read to avoid acquiring the global lock if not needed. */
+ if (TAILQ_EMPTY(&audit_pipe_list))
+ return (0);
+
AUDIT_PIPE_LIST_RLOCK();
TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) {
AUDIT_PIPE_LOCK(ap);
@@ -1072,18 +1077,13 @@ audit_pipe_kqfilter(struct cdev *dev, struct knote *kn)
static int
audit_pipe_kqread(struct knote *kn, long hint)
{
- struct audit_pipe_entry *ape;
struct audit_pipe *ap;
ap = (struct audit_pipe *)kn->kn_hook;
KASSERT(ap != NULL, ("audit_pipe_kqread: ap == NULL"));
-
AUDIT_PIPE_LOCK_ASSERT(ap);
if (ap->ap_qlen != 0) {
- ape = TAILQ_FIRST(&ap->ap_queue);
- KASSERT(ape != NULL, ("audit_pipe_kqread: ape == NULL"));
-
kn->kn_data = ap->ap_qbyteslen - ap->ap_qoffset;
return (1);
} else {
diff --git a/sys/security/mac/mac_audit.c b/sys/security/mac/mac_audit.c
index d8cd8e6..f3fc639 100644
--- a/sys/security/mac/mac_audit.c
+++ b/sys/security/mac/mac_audit.c
@@ -35,10 +35,11 @@
* 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/module.h>
#include <sys/vnode.h>
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index 0a7b085..26d391c 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -1,9 +1,9 @@
/*-
- * Copyright (c) 1999-2002, 2006 Robert N. M. Watson
+ * Copyright (c) 1999-2002, 2006, 2009 Robert N. M. Watson
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
- * Copyright (c) 2008 Apple Inc.
+ * Copyright (c) 2008-2009 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@@ -63,6 +63,7 @@
* src/sys/security/mac_*.
*/
+#include "opt_kdtrace.h"
#include "opt_mac.h"
#include <sys/cdefs.h>
@@ -75,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/mac.h>
#include <sys/module.h>
+#include <sys/sdt.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
@@ -83,6 +85,24 @@ __FBSDID("$FreeBSD$");
#include <security/mac/mac_policy.h>
/*
+ * DTrace SDT provider for MAC.
+ */
+SDT_PROVIDER_DEFINE(mac);
+
+SDT_PROBE_DEFINE(mac, kernel, policy, modevent);
+SDT_PROBE_ARGTYPE(mac, kernel, policy, modevent, 0, "int");
+SDT_PROBE_ARGTYPE(mac, kernel, policy, modevent, 1,
+ "struct mac_policy_conf *mpc");
+
+SDT_PROBE_DEFINE(mac, kernel, policy, register);
+SDT_PROBE_ARGTYPE(mac, kernel, policy, register, 0,
+ "struct mac_policy_conf *");
+
+SDT_PROBE_DEFINE(mac, kernel, policy, unregister);
+SDT_PROBE_ARGTYPE(mac, kernel, policy, unregister, 0,
+ "struct mac_policy_conf *");
+
+/*
* Root sysctl node for all MAC and MAC policy controls.
*/
SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
@@ -329,10 +349,48 @@ mac_late_init(void)
}
/*
- * After the policy list has changed, walk the list to update any global
- * flags. Currently, we support only one flag, and it's conditionally
- * defined; as a result, the entire function is conditional. Eventually, the
- * #else case might also iterate across the policies.
+ * Given a policy, derive from its set of non-NULL label init methods what
+ * object types the policy is interested in.
+ */
+static uint64_t
+mac_policy_getlabeled(struct mac_policy_conf *mpc)
+{
+ uint64_t labeled;
+
+#define MPC_FLAG(method, flag) \
+ if (mpc->mpc_ops->mpo_ ## method != NULL) \
+ labeled |= (flag); \
+
+ labeled = 0;
+ MPC_FLAG(cred_init_label, MPC_OBJECT_CRED);
+ MPC_FLAG(proc_init_label, MPC_OBJECT_PROC);
+ MPC_FLAG(vnode_init_label, MPC_OBJECT_VNODE);
+ MPC_FLAG(inpcb_init_label, MPC_OBJECT_INPCB);
+ MPC_FLAG(socket_init_label, MPC_OBJECT_SOCKET);
+ MPC_FLAG(devfs_init_label, MPC_OBJECT_DEVFS);
+ MPC_FLAG(mbuf_init_label, MPC_OBJECT_MBUF);
+ MPC_FLAG(ipq_init_label, MPC_OBJECT_IPQ);
+ MPC_FLAG(ifnet_init_label, MPC_OBJECT_IFNET);
+ MPC_FLAG(bpfdesc_init_label, MPC_OBJECT_BPFDESC);
+ MPC_FLAG(pipe_init_label, MPC_OBJECT_PIPE);
+ MPC_FLAG(mount_init_label, MPC_OBJECT_MOUNT);
+ MPC_FLAG(posixsem_init_label, MPC_OBJECT_POSIXSEM);
+ MPC_FLAG(posixshm_init_label, MPC_OBJECT_POSIXSHM);
+ MPC_FLAG(sysvmsg_init_label, MPC_OBJECT_SYSVMSG);
+ MPC_FLAG(sysvmsq_init_label, MPC_OBJECT_SYSVMSQ);
+ MPC_FLAG(sysvsem_init_label, MPC_OBJECT_SYSVSEM);
+ MPC_FLAG(sysvshm_init_label, MPC_OBJECT_SYSVSHM);
+ MPC_FLAG(syncache_init_label, MPC_OBJECT_SYNCACHE);
+ MPC_FLAG(ip6q_init_label, MPC_OBJECT_IP6Q);
+
+#undef MPC_FLAG
+ return (labeled);
+}
+
+/*
+ * When policies are loaded or unloaded, walk the list of registered policies
+ * and built mac_labeled, a bitmask representing the union of all objects
+ * requiring labels across all policies.
*/
static void
mac_policy_updateflags(void)
@@ -343,9 +401,9 @@ mac_policy_updateflags(void)
mac_labeled = 0;
LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list)
- mac_labeled |= mpc->mpc_labeled;
+ mac_labeled |= mac_policy_getlabeled(mpc);
LIST_FOREACH(mpc, &mac_policy_list, mpc_list)
- mac_labeled |= mpc->mpc_labeled;
+ mac_labeled |= mac_policy_getlabeled(mpc);
}
static int
@@ -420,6 +478,7 @@ mac_policy_register(struct mac_policy_conf *mpc)
(*(mpc->mpc_ops->mpo_init))(mpc);
mac_policy_updateflags();
+ SDT_PROBE(mac, kernel, policy, register, mpc, 0, 0, 0, 0);
printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
mpc->mpc_name);
@@ -467,6 +526,7 @@ mac_policy_unregister(struct mac_policy_conf *mpc)
mac_policy_release_exclusive();
+ SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0);
printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
mpc->mpc_name);
@@ -492,6 +552,7 @@ mac_policy_modevent(module_t mod, int type, void *data)
}
#endif
+ SDT_PROBE(mac, kernel, policy, modevent, type, mpc, 0, 0, 0);
switch (type) {
case MOD_LOAD:
if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
diff --git a/sys/security/mac/mac_inet6.c b/sys/security/mac/mac_inet6.c
index 068455b..9201b36 100644
--- a/sys/security/mac/mac_inet6.c
+++ b/sys/security/mac/mac_inet6.c
@@ -80,7 +80,7 @@ int
mac_ip6q_init(struct ip6q *q6, int flag)
{
- if (mac_labeled & MPC_OBJECT_IPQ) {
+ if (mac_labeled & MPC_OBJECT_IP6Q) {
q6->ip6q_label = mac_ip6q_label_alloc(flag);
if (q6->ip6q_label == NULL)
return (ENOMEM);
diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h
index 23da90a..79544c3 100644
--- a/sys/security/mac/mac_internal.h
+++ b/sys/security/mac/mac_internal.h
@@ -4,6 +4,7 @@
* Copyright (c) 2001-2004 Networks Associates Technology, Inc.
* Copyright (c) 2006 nCircle Network Security, Inc.
* Copyright (c) 2006 SPARTA, Inc.
+ * Copyright (c) 2009 Apple, Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@@ -83,6 +84,34 @@ struct label {
intptr_t l_perpolicy[MAC_MAX_SLOTS];
};
+
+/*
+ * Flags for mac_labeled, a bitmask of object types need across the union of
+ * all policies currently registered with the MAC Framework, used to key
+ * whether or not labels are allocated and constructors for the type are
+ * invoked.
+ */
+#define MPC_OBJECT_CRED 0x0000000000000001
+#define MPC_OBJECT_PROC 0x0000000000000002
+#define MPC_OBJECT_VNODE 0x0000000000000004
+#define MPC_OBJECT_INPCB 0x0000000000000008
+#define MPC_OBJECT_SOCKET 0x0000000000000010
+#define MPC_OBJECT_DEVFS 0x0000000000000020
+#define MPC_OBJECT_MBUF 0x0000000000000040
+#define MPC_OBJECT_IPQ 0x0000000000000080
+#define MPC_OBJECT_IFNET 0x0000000000000100
+#define MPC_OBJECT_BPFDESC 0x0000000000000200
+#define MPC_OBJECT_PIPE 0x0000000000000400
+#define MPC_OBJECT_MOUNT 0x0000000000000800
+#define MPC_OBJECT_POSIXSEM 0x0000000000001000
+#define MPC_OBJECT_POSIXSHM 0x0000000000002000
+#define MPC_OBJECT_SYSVMSG 0x0000000000004000
+#define MPC_OBJECT_SYSVMSQ 0x0000000000008000
+#define MPC_OBJECT_SYSVSEM 0x0000000000010000
+#define MPC_OBJECT_SYSVSHM 0x0000000000020000
+#define MPC_OBJECT_SYNCACHE 0x0000000000040000
+#define MPC_OBJECT_IP6Q 0x0000000000080000
+
/*
* MAC Framework global variables.
*/
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
index ecf68a6..e333409 100644
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -956,9 +956,9 @@ struct mac_policy_conf {
int *mpc_field_off; /* security field */
int mpc_runtime_flags; /* flags */
int _mpc_spare1; /* Spare. */
- uint64_t mpc_labeled; /* Labeled objects. */
uint64_t _mpc_spare2; /* Spare. */
- void *_mpc_spare3; /* Spare. */
+ uint64_t _mpc_spare3; /* Spare. */
+ void *_mpc_spare4; /* Spare. */
LIST_ENTRY(mac_policy_conf) mpc_list; /* global list */
};
@@ -969,31 +969,6 @@ struct mac_policy_conf {
/* Flags for the mpc_runtime_flags field. */
#define MPC_RUNTIME_FLAG_REGISTERED 0x00000001
-/*
- * Flags for mpc_labeled declaring which objects should have labels allocated
- * for them by the MAC Framework.
- */
-#define MPC_OBJECT_CRED 0x0000000000000001
-#define MPC_OBJECT_PROC 0x0000000000000002
-#define MPC_OBJECT_VNODE 0x0000000000000004
-#define MPC_OBJECT_INPCB 0x0000000000000008
-#define MPC_OBJECT_SOCKET 0x0000000000000010
-#define MPC_OBJECT_DEVFS 0x0000000000000020
-#define MPC_OBJECT_MBUF 0x0000000000000040
-#define MPC_OBJECT_IPQ 0x0000000000000080
-#define MPC_OBJECT_IFNET 0x0000000000000100
-#define MPC_OBJECT_BPFDESC 0x0000000000000200
-#define MPC_OBJECT_PIPE 0x0000000000000400
-#define MPC_OBJECT_MOUNT 0x0000000000000800
-#define MPC_OBJECT_POSIXSEM 0x0000000000001000
-#define MPC_OBJECT_POSIXSHM 0x0000000000002000
-#define MPC_OBJECT_SYSVMSG 0x0000000000004000
-#define MPC_OBJECT_SYSVMSQ 0x0000000000008000
-#define MPC_OBJECT_SYSVSEM 0x0000000000010000
-#define MPC_OBJECT_SYSVSHM 0x0000000000020000
-#define MPC_OBJECT_SYNCACHE 0x0000000000040000
-#define MPC_OBJECT_IP6Q 0x0000000000080000
-
/*-
* The TrustedBSD MAC Framework has a major version number, MAC_VERSION,
* which defines the ABI of the Framework present in the kernel (and depended
@@ -1009,15 +984,13 @@ struct mac_policy_conf {
*/
#define MAC_VERSION 4
-#define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted, \
- labeled) \
+#define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted) \
static struct mac_policy_conf mpname##_mac_policy_conf = { \
.mpc_name = #mpname, \
.mpc_fullname = mpfullname, \
.mpc_ops = mpops, \
.mpc_loadtime_flags = mpflags, \
.mpc_field_off = privdata_wanted, \
- .mpc_labeled = labeled, \
}; \
static moduledata_t mpname##_mod = { \
#mpname, \
diff --git a/sys/security/mac/mac_priv.c b/sys/security/mac/mac_priv.c
index 45a8c81..745695c 100644
--- a/sys/security/mac/mac_priv.c
+++ b/sys/security/mac/mac_priv.c
@@ -25,14 +25,15 @@
* 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$
*/
/*
* MAC checks for system privileges.
*/
+#include "sys/cdefs.h"
+__FBSDID("$FreeBSD$");
+
#include "opt_mac.h"
#include <sys/param.h>
diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c
index 4e10f27..26366e3 100644
--- a/sys/security/mac_biba/mac_biba.c
+++ b/sys/security/mac_biba/mac_biba.c
@@ -3545,25 +3545,5 @@ static struct mac_policy_ops mac_biba_ops =
.mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
};
-#define BIBA_OBJECTS (MPC_OBJECT_CRED | \
- /* MPC_OBJECT_PROC | */ \
- MPC_OBJECT_VNODE | \
- MPC_OBJECT_INPCB | \
- MPC_OBJECT_SOCKET | \
- MPC_OBJECT_DEVFS | \
- MPC_OBJECT_MBUF | \
- MPC_OBJECT_IPQ | \
- MPC_OBJECT_IFNET | \
- MPC_OBJECT_BPFDESC | \
- MPC_OBJECT_PIPE | \
- MPC_OBJECT_MOUNT | \
- MPC_OBJECT_POSIXSEM | \
- /* MPC_OBJECT_POSIXSHM | */ \
- MPC_OBJECT_SYSVMSG | \
- MPC_OBJECT_SYSVMSQ | \
- MPC_OBJECT_SYSVSEM | \
- MPC_OBJECT_SYSVSHM | \
- MPC_OBJECT_SYNCACHE)
-
MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
- MPC_LOADTIME_FLAG_NOTLATE, &biba_slot, BIBA_OBJECTS);
+ MPC_LOADTIME_FLAG_NOTLATE, &biba_slot);
diff --git a/sys/security/mac_bsdextended/mac_bsdextended.c b/sys/security/mac_bsdextended/mac_bsdextended.c
index b30b214..fa64011 100644
--- a/sys/security/mac_bsdextended/mac_bsdextended.c
+++ b/sys/security/mac_bsdextended/mac_bsdextended.c
@@ -523,4 +523,4 @@ static struct mac_policy_ops ugidfw_ops =
};
MAC_POLICY_SET(&ugidfw_ops, mac_bsdextended, "TrustedBSD MAC/BSD Extended",
- MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/sys/security/mac_ifoff/mac_ifoff.c b/sys/security/mac_ifoff/mac_ifoff.c
index 8543d2b..e49e3ad 100644
--- a/sys/security/mac_ifoff/mac_ifoff.c
+++ b/sys/security/mac_ifoff/mac_ifoff.c
@@ -170,4 +170,4 @@ static struct mac_policy_ops ifoff_ops =
};
MAC_POLICY_SET(&ifoff_ops, mac_ifoff, "TrustedBSD MAC/ifoff",
- MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c
index 9eb2701..da3aa30 100644
--- a/sys/security/mac_lomac/mac_lomac.c
+++ b/sys/security/mac_lomac/mac_lomac.c
@@ -3052,25 +3052,5 @@ static struct mac_policy_ops lomac_ops =
.mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr,
};
-#define LOMAC_OBJECTS (MPC_OBJECT_CRED | \
- /* MPC_OBJECT_PROC | */ \
- MPC_OBJECT_VNODE | \
- MPC_OBJECT_INPCB | \
- MPC_OBJECT_SOCKET | \
- MPC_OBJECT_DEVFS | \
- MPC_OBJECT_MBUF | \
- MPC_OBJECT_IPQ | \
- MPC_OBJECT_IFNET | \
- MPC_OBJECT_BPFDESC | \
- MPC_OBJECT_PIPE | \
- MPC_OBJECT_MOUNT | \
- /* MPC_OBJECT_POSIXSEM | */ \
- /* MPC_OBJECT_POSIXSHM | */ \
- /* MPC_OBJECT_SYSVMSG | */ \
- /* MPC_OBJECT_SYSVMSQ | */ \
- /* MPC_OBJECT_SYSVSEM | */ \
- /* MPC_OBJECT_SYSVSHM | */ \
- MPC_OBJECT_SYNCACHE)
-
MAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
- MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot, LOMAC_OBJECTS);
+ MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot);
diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c
index 217fa5f..0ca6bf3 100644
--- a/sys/security/mac_mls/mac_mls.c
+++ b/sys/security/mac_mls/mac_mls.c
@@ -3162,25 +3162,5 @@ static struct mac_policy_ops mls_ops =
.mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr,
};
-#define MLS_OBJECTS (MPC_OBJECT_CRED | \
- /* MPC_OBJECT_PROC | */ \
- MPC_OBJECT_VNODE | \
- MPC_OBJECT_INPCB | \
- MPC_OBJECT_SOCKET | \
- MPC_OBJECT_DEVFS | \
- MPC_OBJECT_MBUF | \
- MPC_OBJECT_IPQ | \
- MPC_OBJECT_IFNET | \
- MPC_OBJECT_BPFDESC | \
- MPC_OBJECT_PIPE | \
- MPC_OBJECT_MOUNT | \
- MPC_OBJECT_POSIXSEM | \
- /* MPC_OBJECT_POSIXSHM | */ \
- MPC_OBJECT_SYSVMSG | \
- MPC_OBJECT_SYSVMSQ | \
- MPC_OBJECT_SYSVSEM | \
- MPC_OBJECT_SYSVSHM | \
- MPC_OBJECT_SYNCACHE)
-
MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS",
- MPC_LOADTIME_FLAG_NOTLATE, &mls_slot, MLS_OBJECTS);
+ MPC_LOADTIME_FLAG_NOTLATE, &mls_slot);
diff --git a/sys/security/mac_none/mac_none.c b/sys/security/mac_none/mac_none.c
index d57c309..8577c73 100644
--- a/sys/security/mac_none/mac_none.c
+++ b/sys/security/mac_none/mac_none.c
@@ -53,4 +53,4 @@ static struct mac_policy_ops none_ops =
};
MAC_POLICY_SET(&none_ops, mac_none, "TrustedBSD MAC/None",
- MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/sys/security/mac_partition/mac_partition.c b/sys/security/mac_partition/mac_partition.c
index 7eca1f9..2fecb27 100644
--- a/sys/security/mac_partition/mac_partition.c
+++ b/sys/security/mac_partition/mac_partition.c
@@ -316,4 +316,4 @@ static struct mac_policy_ops partition_ops =
};
MAC_POLICY_SET(&partition_ops, mac_partition, "TrustedBSD MAC/Partition",
- MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot, MPC_OBJECT_CRED);
+ MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot);
diff --git a/sys/security/mac_portacl/mac_portacl.c b/sys/security/mac_portacl/mac_portacl.c
index eb388cc..aceda69 100644
--- a/sys/security/mac_portacl/mac_portacl.c
+++ b/sys/security/mac_portacl/mac_portacl.c
@@ -490,4 +490,4 @@ static struct mac_policy_ops portacl_ops =
};
MAC_POLICY_SET(&portacl_ops, mac_portacl, "TrustedBSD MAC/portacl",
- MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/sys/security/mac_seeotheruids/mac_seeotheruids.c b/sys/security/mac_seeotheruids/mac_seeotheruids.c
index ddbdaec..e1b73e0 100644
--- a/sys/security/mac_seeotheruids/mac_seeotheruids.c
+++ b/sys/security/mac_seeotheruids/mac_seeotheruids.c
@@ -186,4 +186,4 @@ static struct mac_policy_ops seeotheruids_ops =
};
MAC_POLICY_SET(&seeotheruids_ops, mac_seeotheruids,
- "TrustedBSD MAC/seeotheruids", MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);
+ "TrustedBSD MAC/seeotheruids", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c
index 02cb541..23228a7 100644
--- a/sys/security/mac_stub/mac_stub.c
+++ b/sys/security/mac_stub/mac_stub.c
@@ -1800,25 +1800,5 @@ static struct mac_policy_ops stub_ops =
.mpo_vnode_setlabel_extattr = stub_vnode_setlabel_extattr,
};
-#define STUB_OBJECTS (MPC_OBJECT_CRED | \
- /* XXX: MPC_OBJECT_PROC | */ \
- MPC_OBJECT_VNODE | \
- MPC_OBJECT_INPCB | \
- MPC_OBJECT_SOCKET | \
- MPC_OBJECT_DEVFS | \
- MPC_OBJECT_MBUF | \
- MPC_OBJECT_IPQ | \
- MPC_OBJECT_IFNET | \
- MPC_OBJECT_BPFDESC | \
- MPC_OBJECT_PIPE | \
- MPC_OBJECT_MOUNT | \
- MPC_OBJECT_POSIXSEM | \
- MPC_OBJECT_POSIXSHM | \
- MPC_OBJECT_SYSVMSG | \
- MPC_OBJECT_SYSVMSQ | \
- MPC_OBJECT_SYSVSEM | \
- MPC_OBJECT_SYSVSHM | \
- MPC_OBJECT_SYNCACHE)
-
MAC_POLICY_SET(&stub_ops, mac_stub, "TrustedBSD MAC/Stub",
- MPC_LOADTIME_FLAG_UNLOADOK, NULL, STUB_OBJECTS);
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c
index 08f8dd8..13086f2 100644
--- a/sys/security/mac_test/mac_test.c
+++ b/sys/security/mac_test/mac_test.c
@@ -3139,25 +3139,5 @@ static struct mac_policy_ops test_ops =
.mpo_vnode_setlabel_extattr = test_vnode_setlabel_extattr,
};
-#define TEST_OBJECTS (MPC_OBJECT_CRED | \
- MPC_OBJECT_PROC | \
- MPC_OBJECT_VNODE | \
- MPC_OBJECT_INPCB | \
- MPC_OBJECT_SOCKET | \
- MPC_OBJECT_DEVFS | \
- MPC_OBJECT_MBUF | \
- MPC_OBJECT_IPQ | \
- MPC_OBJECT_IFNET | \
- MPC_OBJECT_BPFDESC | \
- MPC_OBJECT_PIPE | \
- MPC_OBJECT_MOUNT | \
- MPC_OBJECT_POSIXSEM | \
- MPC_OBJECT_POSIXSHM | \
- MPC_OBJECT_SYSVMSG | \
- MPC_OBJECT_SYSVMSQ | \
- MPC_OBJECT_SYSVSEM | \
- MPC_OBJECT_SYSVSHM | \
- MPC_OBJECT_SYNCACHE)
-
MAC_POLICY_SET(&test_ops, mac_test, "TrustedBSD MAC/Test",
- MPC_LOADTIME_FLAG_UNLOADOK, &test_slot, TEST_OBJECTS);
+ MPC_LOADTIME_FLAG_UNLOADOK, &test_slot);
diff --git a/sys/sparc64/include/tlb.h b/sys/sparc64/include/tlb.h
index 06a8296..f0a4a7b 100644
--- a/sys/sparc64/include/tlb.h
+++ b/sys/sparc64/include/tlb.h
@@ -129,6 +129,8 @@ typedef void tlb_flush_user_t(void);
struct pmap;
struct tlb_entry;
+extern int dtlb_slots;
+extern int itlb_slots;
extern int kernel_tlb_slots;
extern struct tlb_entry *kernel_tlbs;
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 4e1e300..4eb8d9c 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -115,6 +115,8 @@ typedef int ofw_vec_t(void *);
extern vm_offset_t ksym_start, ksym_end;
#endif
+int dtlb_slots;
+int itlb_slots;
struct tlb_entry *kernel_tlbs;
int kernel_tlb_slots;
@@ -276,7 +278,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
tick_stop();
/*
- * Set up Open Firmware entry points
+ * Set up Open Firmware entry points.
*/
ofw_tba = rdpr(tba);
ofw_vec = (u_long)vec;
@@ -380,6 +382,19 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
end = (vm_offset_t)_end;
}
+ /*
+ * Determine the TLB slot maxima, which are expected to be
+ * equal across all CPUs.
+ * NB: for Cheetah-class CPUs, these properties only refer
+ * to the t16s.
+ */
+ if (OF_getprop(pc->pc_node, "#dtlb-entries", &dtlb_slots,
+ sizeof(dtlb_slots)) == -1)
+ panic("sparc64_init: cannot determine number of dTLB slots");
+ if (OF_getprop(pc->pc_node, "#itlb-entries", &itlb_slots,
+ sizeof(itlb_slots)) == -1)
+ panic("sparc64_init: cannot determine number of iTLB slots");
+
cache_init(pc);
cache_enable();
uma_set_align(pc->pc_cache.dc_linesize - 1);
diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c
index c083bbb..08c9ac2 100644
--- a/sys/sparc64/sparc64/pmap.c
+++ b/sys/sparc64/sparc64/pmap.c
@@ -334,13 +334,23 @@ pmap_bootstrap(vm_offset_t ekva)
/*
* Calculate the size of kernel virtual memory, and the size and mask
- * for the kernel TSB.
+ * 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.
*/
virtsz = roundup(physsz, PAGE_SIZE_4M << (PAGE_SHIFT - TTE_SHIFT));
+ virtsz = MIN(virtsz,
+ (dtlb_slots / 2 * 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.
*/
diff --git a/sys/sun4v/include/pcpu.h b/sys/sun4v/include/pcpu.h
index b88ddbb..434f1cd 100644
--- a/sys/sun4v/include/pcpu.h
+++ b/sys/sun4v/include/pcpu.h
@@ -38,6 +38,12 @@
struct pmap;
+#ifdef KTR
+#define PCPU_MD_FIELDS_PAD (4 - (PCPU_NAME_LEN + 7) / 8)
+#else
+#define PCPU_MD_FIELDS_PAD 4
+#endif
+
/*
* Inside the kernel, the globally reserved register g7 is used to
* point at the globaldata structure.
@@ -72,7 +78,7 @@ struct pmap;
u_int pc_kwbuf_full; \
struct rwindow pc_tsbwbuf[2]; \
uint16_t pc_cpulist[MAXCPU]; \
- uint64_t pad[4];
+ uint64_t pad[PCPU_MD_FIELDS_PAD];
/* XXX SUN4V_FIXME - as we access the *_ra and *_size fields in quick
* succession we _really_ want them to be L1 cache line size aligned
diff --git a/sys/sys/_null.h b/sys/sys/_null.h
index 9e965f1..caae781 100644
--- a/sys/sys/_null.h
+++ b/sys/sys/_null.h
@@ -31,11 +31,15 @@
#if defined(_KERNEL) || !defined(__cplusplus)
#define NULL ((void *)0)
#else
+#if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
+#define NULL __null
+#else
#if defined(__LP64__)
#define NULL (0L)
#else
#define NULL 0
#endif /* __LP64__ */
+#endif /* __GNUG__ */
#endif /* _KERNEL || !__cplusplus */
#endif
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index e796908..a850950 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -221,8 +221,10 @@
#endif
#if __GNUC_PREREQ__(2, 96)
+#define __malloc_like __attribute__((__malloc__))
#define __pure __attribute__((__pure__))
#else
+#define __malloc_like
#define __pure
#endif
diff --git a/sys/sys/cfictl.h b/sys/sys/cfictl.h
index ef6d5d1..a5439e0 100644
--- a/sys/sys/cfictl.h
+++ b/sys/sys/cfictl.h
@@ -44,4 +44,10 @@ struct cfiocqry {
#define CFIOCQRY _IOWR('q', 0, struct cfiocqry)
+/* Intel StrataFlash Protection Register support */
+#define CFIOCGFACTORYPR _IOR('q', 1, uint64_t) /* get factory protection reg */
+#define CFIOCGOEMPR _IOR('q', 2, uint64_t) /* get oem protection reg */
+#define CFIOCSOEMPR _IOW('q', 3, uint64_t) /* set oem protection reg */
+#define CFIOCGPLR _IOR('q', 4, uint32_t) /* get protection lock reg */
+#define CFIOCSPLR _IO('q', 5) /* set protection log reg */
#endif /* _SYS_CFICTL_H_ */
diff --git a/sys/sys/clist.h b/sys/sys/clist.h
index 9f865c8..d497022 100644
--- a/sys/sys/clist.h
+++ b/sys/sys/clist.h
@@ -54,8 +54,6 @@ struct cblock {
};
#ifdef _KERNEL
-extern int cfreecount;
-
int b_to_q(char *cp, int cc, struct clist *q);
void clist_alloc_cblocks(struct clist *q, int ccmax, int ccres);
void clist_free_cblocks(struct clist *q);
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 3fc0777..285376b 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -219,8 +219,6 @@ struct cdevsw {
#define d_gianttrick __d_giant.gianttrick
#define d_postfree_list __d_giant.postfree_list
-#define NUMCDEVSW 256
-
struct module;
struct devsw_module_data {
@@ -274,10 +272,7 @@ void dev_lock(void);
void dev_unlock(void);
void setconf(void);
-#define dev2unit(d) ((d) ? (d)->si_drv0 : NODEV)
-#define minor(d) ((d) ? (d)->si_drv0 : NODEV)
-#define unit2minor(u) (u)
-#define minor2unit(m) (m)
+#define dev2unit(d) ((d)->si_drv0)
typedef void (*cdevpriv_dtr_t)(void *data);
int devfs_get_cdevpriv(void **datap);
diff --git a/sys/sys/copyright.h b/sys/sys/copyright.h
index 0f2805b..1b0b96a 100644
--- a/sys/sys/copyright.h
+++ b/sys/sys/copyright.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (C) 1992-2008 The FreeBSD Project. All rights reserved.
+ * Copyright (C) 1992-2009 The FreeBSD Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
/* FreeBSD */
#define COPYRIGHT_FreeBSD \
- "Copyright (c) 1992-2008 The FreeBSD Project.\n"
+ "Copyright (c) 1992-2009 The FreeBSD Project.\n"
/* Foundation */
#define TRADEMARK_Foundation \
diff --git a/sys/sys/elf64.h b/sys/sys/elf64.h
index 0fbb8ee..4ec7d34 100644
--- a/sys/sys/elf64.h
+++ b/sys/sys/elf64.h
@@ -141,16 +141,16 @@ typedef struct {
} Elf64_Rela;
/* Macros for accessing the fields of r_info. */
-#define ELF64_R_SYM(info) ((info) >> 32)
-#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
+#define ELF64_R_SYM(info) ((info) >> 32)
+#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
/* Macro for constructing r_info from field values. */
-#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
+#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
#define ELF64_R_TYPE_INFO(data, type) \
- (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
+ (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
/*
* Note entry header
@@ -197,14 +197,14 @@ typedef struct {
} Elf64_Sym;
/* Macros for accessing the fields of st_info. */
-#define ELF64_ST_BIND(info) ((info) >> 4)
-#define ELF64_ST_TYPE(info) ((info) & 0xf)
+#define ELF64_ST_BIND(info) ((info) >> 4)
+#define ELF64_ST_TYPE(info) ((info) & 0xf)
/* Macro for constructing st_info from field values. */
-#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Macro for accessing the fields of st_other. */
-#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
+#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
/* Structures used by Sun & GNU-style symbol versioning. */
typedef struct {
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
index 688fab2..34c0b3a 100644
--- a/sys/sys/elf_common.h
+++ b/sys/sys/elf_common.h
@@ -27,7 +27,7 @@
*/
#ifndef _SYS_ELF_COMMON_H_
-#define _SYS_ELF_COMMON_H_ 1
+#define _SYS_ELF_COMMON_H_ 1
/*
* ELF definitions that are independent of architecture or word size.
@@ -48,269 +48,281 @@ typedef struct {
u_int32_t n_type; /* Type of this note. */
} Elf_Note;
+/*
+ * The header for GNU-style hash sections.
+ */
+
+typedef struct {
+ u_int32_t gh_nbuckets; /* Number of hash buckets. */
+ u_int32_t gh_symndx; /* First visible symbol in .dynsym. */
+ u_int32_t gh_maskwords; /* #maskwords used in bloom filter. */
+ u_int32_t gh_shift2; /* Bloom filter shift count. */
+} Elf_GNU_Hash_Header;
+
/* Indexes into the e_ident array. Keep synced with
http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
-#define EI_MAG0 0 /* Magic number, byte 0. */
-#define EI_MAG1 1 /* Magic number, byte 1. */
-#define EI_MAG2 2 /* Magic number, byte 2. */
-#define EI_MAG3 3 /* Magic number, byte 3. */
-#define EI_CLASS 4 /* Class of machine. */
-#define EI_DATA 5 /* Data format. */
-#define EI_VERSION 6 /* ELF format version. */
-#define EI_OSABI 7 /* Operating system / ABI identification */
-#define EI_ABIVERSION 8 /* ABI version */
-#define OLD_EI_BRAND 8 /* Start of architecture identification. */
-#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
-#define EI_NIDENT 16 /* Size of e_ident array. */
+#define EI_MAG0 0 /* Magic number, byte 0. */
+#define EI_MAG1 1 /* Magic number, byte 1. */
+#define EI_MAG2 2 /* Magic number, byte 2. */
+#define EI_MAG3 3 /* Magic number, byte 3. */
+#define EI_CLASS 4 /* Class of machine. */
+#define EI_DATA 5 /* Data format. */
+#define EI_VERSION 6 /* ELF format version. */
+#define EI_OSABI 7 /* Operating system / ABI identification */
+#define EI_ABIVERSION 8 /* ABI version */
+#define OLD_EI_BRAND 8 /* Start of architecture identification. */
+#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
+#define EI_NIDENT 16 /* Size of e_ident array. */
/* Values for the magic number bytes. */
-#define ELFMAG0 0x7f
-#define ELFMAG1 'E'
-#define ELFMAG2 'L'
-#define ELFMAG3 'F'
-#define ELFMAG "\177ELF" /* magic string */
-#define SELFMAG 4 /* magic string size */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF" /* magic string */
+#define SELFMAG 4 /* magic string size */
/* Values for e_ident[EI_VERSION] and e_version. */
-#define EV_NONE 0
-#define EV_CURRENT 1
+#define EV_NONE 0
+#define EV_CURRENT 1
/* Values for e_ident[EI_CLASS]. */
-#define ELFCLASSNONE 0 /* Unknown class. */
-#define ELFCLASS32 1 /* 32-bit architecture. */
-#define ELFCLASS64 2 /* 64-bit architecture. */
+#define ELFCLASSNONE 0 /* Unknown class. */
+#define ELFCLASS32 1 /* 32-bit architecture. */
+#define ELFCLASS64 2 /* 64-bit architecture. */
/* Values for e_ident[EI_DATA]. */
-#define ELFDATANONE 0 /* Unknown data format. */
-#define ELFDATA2LSB 1 /* 2's complement little-endian. */
-#define ELFDATA2MSB 2 /* 2's complement big-endian. */
+#define ELFDATANONE 0 /* Unknown data format. */
+#define ELFDATA2LSB 1 /* 2's complement little-endian. */
+#define ELFDATA2MSB 2 /* 2's complement big-endian. */
/* Values for e_ident[EI_OSABI]. */
-#define ELFOSABI_NONE 0 /* UNIX System V ABI */
-#define ELFOSABI_HPUX 1 /* HP-UX operating system */
-#define ELFOSABI_NETBSD 2 /* NetBSD */
-#define ELFOSABI_LINUX 3 /* GNU/Linux */
-#define ELFOSABI_HURD 4 /* GNU/Hurd */
-#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
-#define ELFOSABI_SOLARIS 6 /* Solaris */
-#define ELFOSABI_AIX 7 /* AIX */
-#define ELFOSABI_IRIX 8 /* IRIX */
-#define ELFOSABI_FREEBSD 9 /* FreeBSD */
-#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
-#define ELFOSABI_MODESTO 11 /* Novell Modesto */
-#define ELFOSABI_OPENBSD 12 /* OpenBSD */
-#define ELFOSABI_OPENVMS 13 /* Open VMS */
-#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
-#define ELFOSABI_AROS 15 /* Amiga Research OS */
-#define ELFOSABI_ARM 97 /* ARM */
-#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
-
-#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
-#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX 1 /* HP-UX operating system */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* GNU/Linux */
+#define ELFOSABI_HURD 4 /* GNU/Hurd */
+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS 6 /* Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
+#define ELFOSABI_AROS 15 /* Amiga Research OS */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
+#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
/* e_ident */
-#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* Values for e_type. */
-#define ET_NONE 0 /* Unknown type. */
-#define ET_REL 1 /* Relocatable. */
-#define ET_EXEC 2 /* Executable. */
-#define ET_DYN 3 /* Shared object. */
-#define ET_CORE 4 /* Core file. */
-#define ET_LOOS 0xfe00 /* First operating system specific. */
-#define ET_HIOS 0xfeff /* Last operating system-specific. */
-#define ET_LOPROC 0xff00 /* First processor-specific. */
-#define ET_HIPROC 0xffff /* Last processor-specific. */
+#define ET_NONE 0 /* Unknown type. */
+#define ET_REL 1 /* Relocatable. */
+#define ET_EXEC 2 /* Executable. */
+#define ET_DYN 3 /* Shared object. */
+#define ET_CORE 4 /* Core file. */
+#define ET_LOOS 0xfe00 /* First operating system specific. */
+#define ET_HIOS 0xfeff /* Last operating system-specific. */
+#define ET_LOPROC 0xff00 /* First processor-specific. */
+#define ET_HIPROC 0xffff /* Last processor-specific. */
/* Values for e_machine. */
-#define EM_NONE 0 /* Unknown machine. */
-#define EM_M32 1 /* AT&T WE32100. */
-#define EM_SPARC 2 /* Sun SPARC. */
-#define EM_386 3 /* Intel i386. */
-#define EM_68K 4 /* Motorola 68000. */
-#define EM_88K 5 /* Motorola 88000. */
-#define EM_860 7 /* Intel i860. */
-#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
-#define EM_S370 9 /* IBM System/370. */
-#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
-#define EM_PARISC 15 /* HP PA-RISC. */
-#define EM_VPP500 17 /* Fujitsu VPP500. */
-#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
-#define EM_960 19 /* Intel 80960. */
-#define EM_PPC 20 /* PowerPC 32-bit. */
-#define EM_PPC64 21 /* PowerPC 64-bit. */
-#define EM_S390 22 /* IBM System/390. */
-#define EM_V800 36 /* NEC V800. */
-#define EM_FR20 37 /* Fujitsu FR20. */
-#define EM_RH32 38 /* TRW RH-32. */
-#define EM_RCE 39 /* Motorola RCE. */
-#define EM_ARM 40 /* ARM. */
-#define EM_SH 42 /* Hitachi SH. */
-#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
-#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
-#define EM_ARC 45 /* Argonaut RISC Core. */
-#define EM_H8_300 46 /* Hitachi H8/300. */
-#define EM_H8_300H 47 /* Hitachi H8/300H. */
-#define EM_H8S 48 /* Hitachi H8S. */
-#define EM_H8_500 49 /* Hitachi H8/500. */
-#define EM_IA_64 50 /* Intel IA-64 Processor. */
-#define EM_MIPS_X 51 /* Stanford MIPS-X. */
-#define EM_COLDFIRE 52 /* Motorola ColdFire. */
-#define EM_68HC12 53 /* Motorola M68HC12. */
-#define EM_MMA 54 /* Fujitsu MMA. */
-#define EM_PCP 55 /* Siemens PCP. */
-#define EM_NCPU 56 /* Sony nCPU. */
-#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
-#define EM_STARCORE 58 /* Motorola Star*Core processor. */
-#define EM_ME16 59 /* Toyota ME16 processor. */
-#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
-#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
-#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
+#define EM_NONE 0 /* Unknown machine. */
+#define EM_M32 1 /* AT&T WE32100. */
+#define EM_SPARC 2 /* Sun SPARC. */
+#define EM_386 3 /* Intel i386. */
+#define EM_68K 4 /* Motorola 68000. */
+#define EM_88K 5 /* Motorola 88000. */
+#define EM_860 7 /* Intel i860. */
+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
+#define EM_S370 9 /* IBM System/370. */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
+#define EM_PARISC 15 /* HP PA-RISC. */
+#define EM_VPP500 17 /* Fujitsu VPP500. */
+#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
+#define EM_960 19 /* Intel 80960. */
+#define EM_PPC 20 /* PowerPC 32-bit. */
+#define EM_PPC64 21 /* PowerPC 64-bit. */
+#define EM_S390 22 /* IBM System/390. */
+#define EM_V800 36 /* NEC V800. */
+#define EM_FR20 37 /* Fujitsu FR20. */
+#define EM_RH32 38 /* TRW RH-32. */
+#define EM_RCE 39 /* Motorola RCE. */
+#define EM_ARM 40 /* ARM. */
+#define EM_SH 42 /* Hitachi SH. */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
+#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
+#define EM_ARC 45 /* Argonaut RISC Core. */
+#define EM_H8_300 46 /* Hitachi H8/300. */
+#define EM_H8_300H 47 /* Hitachi H8/300H. */
+#define EM_H8S 48 /* Hitachi H8S. */
+#define EM_H8_500 49 /* Hitachi H8/500. */
+#define EM_IA_64 50 /* Intel IA-64 Processor. */
+#define EM_MIPS_X 51 /* Stanford MIPS-X. */
+#define EM_COLDFIRE 52 /* Motorola ColdFire. */
+#define EM_68HC12 53 /* Motorola M68HC12. */
+#define EM_MMA 54 /* Fujitsu MMA. */
+#define EM_PCP 55 /* Siemens PCP. */
+#define EM_NCPU 56 /* Sony nCPU. */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
+#define EM_STARCORE 58 /* Motorola Star*Core processor. */
+#define EM_ME16 59 /* Toyota ME16 processor. */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
+#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
-#define EM_PDSP 63 /* Sony DSP Processor. */
-#define EM_FX66 66 /* Siemens FX66 microcontroller. */
-#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16
+#define EM_PDSP 63 /* Sony DSP Processor. */
+#define EM_FX66 66 /* Siemens FX66 microcontroller. */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16
microcontroller. */
-#define EM_ST7 68 /* STmicroelectronics ST7 8-bit
+#define EM_ST7 68 /* STmicroelectronics ST7 8-bit
microcontroller. */
-#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */
-#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */
-#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */
-#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */
-#define EM_SVX 73 /* Silicon Graphics SVx. */
-#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */
-#define EM_VAX 75 /* Digital VAX. */
-#define EM_CRIS 76 /* Axis Communications 32-bit embedded
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */
+#define EM_SVX 73 /* Silicon Graphics SVx. */
+#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */
+#define EM_VAX 75 /* Digital VAX. */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded
processor. */
-#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
processor. */
-#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */
-#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */
-#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */
-#define EM_HUANY 81 /* Harvard University machine-independent
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */
+#define EM_HUANY 81 /* Harvard University machine-independent
object files. */
-#define EM_PRISM 82 /* SiTera Prism. */
-#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */
-#define EM_FR30 84 /* Fujitsu FR30. */
-#define EM_D10V 85 /* Mitsubishi D10V. */
-#define EM_D30V 86 /* Mitsubishi D30V. */
-#define EM_V850 87 /* NEC v850. */
-#define EM_M32R 88 /* Mitsubishi M32R. */
-#define EM_MN10300 89 /* Matsushita MN10300. */
-#define EM_MN10200 90 /* Matsushita MN10200. */
-#define EM_PJ 91 /* picoJava. */
-#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */
-#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */
-#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */
-#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */
-#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose
+#define EM_PRISM 82 /* SiTera Prism. */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */
+#define EM_FR30 84 /* Fujitsu FR30. */
+#define EM_D10V 85 /* Mitsubishi D10V. */
+#define EM_D30V 86 /* Mitsubishi D30V. */
+#define EM_V850 87 /* NEC v850. */
+#define EM_M32R 88 /* Mitsubishi M32R. */
+#define EM_MN10300 89 /* Matsushita MN10300. */
+#define EM_MN10200 90 /* Matsushita MN10200. */
+#define EM_PJ 91 /* picoJava. */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose
Processor. */
-#define EM_NS32K 97 /* National Semiconductor 32000 series. */
-#define EM_TPC 98 /* Tenor Network TPC processor. */
-#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */
-#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */
-#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */
-#define EM_MAX 102 /* MAX Processor. */
-#define EM_CR 103 /* National Semiconductor CompactRISC
+#define EM_NS32K 97 /* National Semiconductor 32000 series. */
+#define EM_TPC 98 /* Tenor Network TPC processor. */
+#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */
+#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */
+#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */
+#define EM_MAX 102 /* MAX Processor. */
+#define EM_CR 103 /* National Semiconductor CompactRISC
microprocessor. */
-#define EM_F2MC16 104 /* Fujitsu F2MC16. */
-#define EM_MSP430 105 /* Texas Instruments embedded microcontroller
+#define EM_F2MC16 104 /* Fujitsu F2MC16. */
+#define EM_MSP430 105 /* Texas Instruments embedded microcontroller
msp430. */
-#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */
-#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */
-#define EM_SEP 108 /* Sharp embedded microprocessor. */
-#define EM_ARCA 109 /* Arca RISC Microprocessor. */
-#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd.
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */
+#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */
+#define EM_SEP 108 /* Sharp embedded microprocessor. */
+#define EM_ARCA 109 /* Arca RISC Microprocessor. */
+#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd.
and MPRC of Peking University */
/* Non-standard or deprecated. */
-#define EM_486 6 /* Intel i486. */
-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
-#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
-#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
+#define EM_486 6 /* Intel i486. */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
+#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
+#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
/* Special section indexes. */
-#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
-#define SHN_LORESERVE 0xff00 /* First of reserved range. */
-#define SHN_LOPROC 0xff00 /* First processor-specific. */
-#define SHN_HIPROC 0xff1f /* Last processor-specific. */
-#define SHN_LOOS 0xff20 /* First operating system-specific. */
-#define SHN_HIOS 0xff3f /* Last operating system-specific. */
-#define SHN_ABS 0xfff1 /* Absolute values. */
-#define SHN_COMMON 0xfff2 /* Common data. */
-#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
-#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE 0xff00 /* First of reserved range. */
+#define SHN_LOPROC 0xff00 /* First processor-specific. */
+#define SHN_HIPROC 0xff1f /* Last processor-specific. */
+#define SHN_LOOS 0xff20 /* First operating system-specific. */
+#define SHN_HIOS 0xff3f /* Last operating system-specific. */
+#define SHN_ABS 0xfff1 /* Absolute values. */
+#define SHN_COMMON 0xfff2 /* Common data. */
+#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
/* sh_type */
-#define SHT_NULL 0 /* inactive */
-#define SHT_PROGBITS 1 /* program defined information */
-#define SHT_SYMTAB 2 /* symbol table section */
-#define SHT_STRTAB 3 /* string table section */
-#define SHT_RELA 4 /* relocation section with addends */
-#define SHT_HASH 5 /* symbol hash table section */
-#define SHT_DYNAMIC 6 /* dynamic section */
-#define SHT_NOTE 7 /* note section */
-#define SHT_NOBITS 8 /* no space section */
-#define SHT_REL 9 /* relocation section - no addends */
-#define SHT_SHLIB 10 /* reserved - purpose unknown */
-#define SHT_DYNSYM 11 /* dynamic symbol table section */
-#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
-#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
-#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
-#define SHT_GROUP 17 /* Section group. */
-#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
-#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
-#define SHT_LOSUNW 0x6ffffff4
-#define SHT_SUNW_dof 0x6ffffff4
-#define SHT_SUNW_cap 0x6ffffff5
-#define SHT_SUNW_SIGNATURE 0x6ffffff6
-#define SHT_SUNW_ANNOTATE 0x6ffffff7
-#define SHT_SUNW_DEBUGSTR 0x6ffffff8
-#define SHT_SUNW_DEBUG 0x6ffffff9
-#define SHT_SUNW_move 0x6ffffffa
-#define SHT_SUNW_COMDAT 0x6ffffffb
-#define SHT_SUNW_syminfo 0x6ffffffc
-#define SHT_SUNW_verdef 0x6ffffffd
-#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
-#define SHT_SUNW_verneed 0x6ffffffe
-#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
-#define SHT_SUNW_versym 0x6fffffff
-#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
-#define SHT_HISUNW 0x6fffffff
-#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
-#define SHT_LOPROC 0x70000000 /* reserved range for processor */
-#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
-#define SHT_HIPROC 0x7fffffff /* specific section header types */
-#define SHT_LOUSER 0x80000000 /* reserved range for application */
-#define SHT_HIUSER 0xffffffff /* specific indexes */
+#define SHT_NULL 0 /* inactive */
+#define SHT_PROGBITS 1 /* program defined information */
+#define SHT_SYMTAB 2 /* symbol table section */
+#define SHT_STRTAB 3 /* string table section */
+#define SHT_RELA 4 /* relocation section with addends */
+#define SHT_HASH 5 /* symbol hash table section */
+#define SHT_DYNAMIC 6 /* dynamic section */
+#define SHT_NOTE 7 /* note section */
+#define SHT_NOBITS 8 /* no space section */
+#define SHT_REL 9 /* relocation section - no addends */
+#define SHT_SHLIB 10 /* reserved - purpose unknown */
+#define SHT_DYNSYM 11 /* dynamic symbol table section */
+#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
+#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
+#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
+#define SHT_GROUP 17 /* Section group. */
+#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
+#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
+#define SHT_LOSUNW 0x6ffffff4
+#define SHT_SUNW_dof 0x6ffffff4
+#define SHT_SUNW_cap 0x6ffffff5
+#define SHT_SUNW_SIGNATURE 0x6ffffff6
+#define SHT_GNU_HASH 0x6ffffff6
+#define SHT_SUNW_ANNOTATE 0x6ffffff7
+#define SHT_SUNW_DEBUGSTR 0x6ffffff8
+#define SHT_SUNW_DEBUG 0x6ffffff9
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef 0x6ffffffd
+#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
+#define SHT_SUNW_verneed 0x6ffffffe
+#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
+#define SHT_SUNW_versym 0x6fffffff
+#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
+#define SHT_LOPROC 0x70000000 /* reserved range for processor */
+#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
+#define SHT_HIPROC 0x7fffffff /* specific section header types */
+#define SHT_LOUSER 0x80000000 /* reserved range for application */
+#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Flags for sh_flags. */
-#define SHF_WRITE 0x1 /* Section contains writable data. */
-#define SHF_ALLOC 0x2 /* Section occupies memory. */
-#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
-#define SHF_MERGE 0x10 /* Section may be merged. */
-#define SHF_STRINGS 0x20 /* Section contains strings. */
-#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
-#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
-#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
-#define SHF_GROUP 0x200 /* Member of section group. */
-#define SHF_TLS 0x400 /* Section contains TLS data. */
-#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
-#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
+#define SHF_WRITE 0x1 /* Section contains writable data. */
+#define SHF_ALLOC 0x2 /* Section occupies memory. */
+#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
+#define SHF_MERGE 0x10 /* Section may be merged. */
+#define SHF_STRINGS 0x20 /* Section contains strings. */
+#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
+#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
+#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
+#define SHF_GROUP 0x200 /* Member of section group. */
+#define SHF_TLS 0x400 /* Section contains TLS data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
/* Values for p_type. */
-#define PT_NULL 0 /* Unused entry. */
-#define PT_LOAD 1 /* Loadable segment. */
-#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
-#define PT_INTERP 3 /* Pathname of interpreter. */
-#define PT_NOTE 4 /* Auxiliary information. */
-#define PT_SHLIB 5 /* Reserved (not used). */
-#define PT_PHDR 6 /* Location of program header itself. */
+#define PT_NULL 0 /* Unused entry. */
+#define PT_LOAD 1 /* Loadable segment. */
+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
+#define PT_INTERP 3 /* Pathname of interpreter. */
+#define PT_NOTE 4 /* Auxiliary information. */
+#define PT_SHLIB 5 /* Reserved (not used). */
+#define PT_PHDR 6 /* Location of program header itself. */
#define PT_TLS 7 /* Thread local storage segment */
-#define PT_LOOS 0x60000000 /* First OS-specific. */
+#define PT_LOOS 0x60000000 /* First OS-specific. */
#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
#define PT_GNU_EH_FRAME 0x6474e550
#define PT_LOSUNW 0x6ffffffa
@@ -319,48 +331,48 @@ typedef struct {
#define PT_SUNWDTRACE 0x6ffffffc /* private */
#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
#define PT_HISUNW 0x6fffffff
-#define PT_HIOS 0x6fffffff /* Last OS-specific. */
-#define PT_LOPROC 0x70000000 /* First processor-specific type. */
-#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
+#define PT_HIOS 0x6fffffff /* Last OS-specific. */
+#define PT_LOPROC 0x70000000 /* First processor-specific type. */
+#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
/* Values for p_flags. */
-#define PF_X 0x1 /* Executable. */
-#define PF_W 0x2 /* Writable. */
-#define PF_R 0x4 /* Readable. */
-#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
-#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
+#define PF_X 0x1 /* Executable. */
+#define PF_W 0x2 /* Writable. */
+#define PF_R 0x4 /* Readable. */
+#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
/* Extended program header index. */
#define PN_XNUM 0xffff
/* Values for d_tag. */
-#define DT_NULL 0 /* Terminating entry. */
-#define DT_NEEDED 1 /* String table offset of a needed shared
+#define DT_NULL 0 /* Terminating entry. */
+#define DT_NEEDED 1 /* String table offset of a needed shared
library. */
-#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
-#define DT_PLTGOT 3 /* Processor-dependent address. */
-#define DT_HASH 4 /* Address of symbol hash table. */
-#define DT_STRTAB 5 /* Address of string table. */
-#define DT_SYMTAB 6 /* Address of symbol table. */
-#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
-#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
-#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
-#define DT_STRSZ 10 /* Size of string table. */
-#define DT_SYMENT 11 /* Size of each symbol table entry. */
-#define DT_INIT 12 /* Address of initialization function. */
-#define DT_FINI 13 /* Address of finalization function. */
-#define DT_SONAME 14 /* String table offset of shared object
+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT 3 /* Processor-dependent address. */
+#define DT_HASH 4 /* Address of symbol hash table. */
+#define DT_STRTAB 5 /* Address of string table. */
+#define DT_SYMTAB 6 /* Address of symbol table. */
+#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
+#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
+#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
+#define DT_STRSZ 10 /* Size of string table. */
+#define DT_SYMENT 11 /* Size of each symbol table entry. */
+#define DT_INIT 12 /* Address of initialization function. */
+#define DT_FINI 13 /* Address of finalization function. */
+#define DT_SONAME 14 /* String table offset of shared object
name. */
-#define DT_RPATH 15 /* String table offset of library path. [sup] */
-#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
-#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
-#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
-#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
-#define DT_PLTREL 20 /* Type of relocation used for PLT. */
-#define DT_DEBUG 21 /* Reserved (not used). */
-#define DT_TEXTREL 22 /* Indicates there may be relocations in
+#define DT_RPATH 15 /* String table offset of library path. [sup] */
+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
+#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
+#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
+#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
+#define DT_PLTREL 20 /* Type of relocation used for PLT. */
+#define DT_DEBUG 21 /* Reserved (not used). */
+#define DT_TEXTREL 22 /* Indicates there may be relocations in
non-writable segments. [sup] */
-#define DT_JMPREL 23 /* Address of PLT relocations. */
+#define DT_JMPREL 23 /* Address of PLT relocations. */
#define DT_BIND_NOW 24 /* [sup] */
#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
initialization functions */
@@ -455,63 +467,63 @@ typedef struct {
thread-local storage scheme. */
/* Values for n_type. Used in core files. */
-#define NT_PRSTATUS 1 /* Process status. */
-#define NT_FPREGSET 2 /* Floating point registers. */
-#define NT_PRPSINFO 3 /* Process state info. */
+#define NT_PRSTATUS 1 /* Process status. */
+#define NT_FPREGSET 2 /* Floating point registers. */
+#define NT_PRPSINFO 3 /* Process state info. */
/* Symbol Binding - ELFNN_ST_BIND - st_info */
-#define STB_LOCAL 0 /* Local symbol */
-#define STB_GLOBAL 1 /* Global symbol */
-#define STB_WEAK 2 /* like global - lower precedence */
-#define STB_LOOS 10 /* Reserved range for operating system */
-#define STB_HIOS 12 /* specific semantics. */
-#define STB_LOPROC 13 /* reserved range for processor */
-#define STB_HIPROC 15 /* specific semantics. */
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* like global - lower precedence */
+#define STB_LOOS 10 /* Reserved range for operating system */
+#define STB_HIOS 12 /* specific semantics. */
+#define STB_LOPROC 13 /* reserved range for processor */
+#define STB_HIPROC 15 /* specific semantics. */
/* Symbol type - ELFNN_ST_TYPE - st_info */
-#define STT_NOTYPE 0 /* Unspecified type. */
-#define STT_OBJECT 1 /* Data object. */
-#define STT_FUNC 2 /* Function. */
-#define STT_SECTION 3 /* Section. */
-#define STT_FILE 4 /* Source file. */
-#define STT_COMMON 5 /* Uninitialized common block. */
-#define STT_TLS 6 /* TLS object. */
-#define STT_NUM 7
-#define STT_LOOS 10 /* Reserved range for operating system */
-#define STT_HIOS 12 /* specific semantics. */
-#define STT_LOPROC 13 /* reserved range for processor */
-#define STT_HIPROC 15 /* specific semantics. */
+#define STT_NOTYPE 0 /* Unspecified type. */
+#define STT_OBJECT 1 /* Data object. */
+#define STT_FUNC 2 /* Function. */
+#define STT_SECTION 3 /* Section. */
+#define STT_FILE 4 /* Source file. */
+#define STT_COMMON 5 /* Uninitialized common block. */
+#define STT_TLS 6 /* TLS object. */
+#define STT_NUM 7
+#define STT_LOOS 10 /* Reserved range for operating system */
+#define STT_HIOS 12 /* specific semantics. */
+#define STT_LOPROC 13 /* reserved range for processor */
+#define STT_HIPROC 15 /* specific semantics. */
/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
-#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
-#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
-#define STV_HIDDEN 0x2 /* Not visible. */
-#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
-#define STV_EXPORTED 0x4
-#define STV_SINGLETON 0x5
-#define STV_ELIMINATE 0x6
+#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
+#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
+#define STV_HIDDEN 0x2 /* Not visible. */
+#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
+#define STV_EXPORTED 0x4
+#define STV_SINGLETON 0x5
+#define STV_ELIMINATE 0x6
/* Special symbol table indexes. */
-#define STN_UNDEF 0 /* Undefined symbol index. */
+#define STN_UNDEF 0 /* Undefined symbol index. */
/* Symbol versioning flags. */
#define VER_DEF_CURRENT 1
-#define VER_DEF_IDX(x) VER_NDX(x)
+#define VER_DEF_IDX(x) VER_NDX(x)
#define VER_FLG_BASE 0x01
#define VER_FLG_WEAK 0x02
#define VER_NEED_CURRENT 1
-#define VER_NEED_WEAK (1u << 15)
-#define VER_NEED_HIDDEN VER_NDX_HIDDEN
-#define VER_NEED_IDX(x) VER_NDX(x)
+#define VER_NEED_WEAK (1u << 15)
+#define VER_NEED_HIDDEN VER_NDX_HIDDEN
+#define VER_NEED_IDX(x) VER_NDX(x)
#define VER_NDX_LOCAL 0
#define VER_NDX_GLOBAL 1
-#define VER_NDX_GIVEN 2
+#define VER_NDX_GIVEN 2
-#define VER_NDX_HIDDEN (1u << 15)
-#define VER_NDX(x) ((x) & ~(1u << 15))
+#define VER_NDX_HIDDEN (1u << 15)
+#define VER_NDX(x) ((x) & ~(1u << 15))
#define CA_SUNW_NULL 0
#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
@@ -763,30 +775,30 @@ typedef struct {
/*
* TLS relocations
*/
-#define R_PPC_TLS 67
-#define R_PPC_DTPMOD32 68
-#define R_PPC_TPREL16 69
-#define R_PPC_TPREL16_LO 70
-#define R_PPC_TPREL16_HI 71
-#define R_PPC_TPREL16_HA 72
-#define R_PPC_TPREL32 73
-#define R_PPC_DTPREL16 74
-#define R_PPC_DTPREL16_LO 75
-#define R_PPC_DTPREL16_HI 76
-#define R_PPC_DTPREL16_HA 77
-#define R_PPC_DTPREL32 78
-#define R_PPC_GOT_TLSGD16 79
-#define R_PPC_GOT_TLSGD16_LO 80
-#define R_PPC_GOT_TLSGD16_HI 81
-#define R_PPC_GOT_TLSGD16_HA 82
-#define R_PPC_GOT_TLSLD16 83
-#define R_PPC_GOT_TLSLD16_LO 84
-#define R_PPC_GOT_TLSLD16_HI 85
-#define R_PPC_GOT_TLSLD16_HA 86
-#define R_PPC_GOT_TPREL16 87
-#define R_PPC_GOT_TPREL16_LO 88
-#define R_PPC_GOT_TPREL16_HI 89
-#define R_PPC_GOT_TPREL16_HA 90
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
/*
* The remaining relocs are from the Embedded ELF ABI, and are not in the
diff --git a/sys/sys/elf_generic.h b/sys/sys/elf_generic.h
index ff1b6f7..95a682f 100644
--- a/sys/sys/elf_generic.h
+++ b/sys/sys/elf_generic.h
@@ -27,7 +27,7 @@
*/
#ifndef _SYS_ELF_GENERIC_H_
-#define _SYS_ELF_GENERIC_H_ 1
+#define _SYS_ELF_GENERIC_H_ 1
#include <sys/cdefs.h>
@@ -40,20 +40,20 @@
#error "__ELF_WORD_SIZE must be defined as 32 or 64"
#endif
-#define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE)
+#define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE)
#if BYTE_ORDER == LITTLE_ENDIAN
-#define ELF_DATA ELFDATA2LSB
+#define ELF_DATA ELFDATA2LSB
#elif BYTE_ORDER == BIG_ENDIAN
-#define ELF_DATA ELFDATA2MSB
+#define ELF_DATA ELFDATA2MSB
#else
#error "Unknown byte order"
#endif
-#define __elfN(x) __CONCAT(__CONCAT(__CONCAT(elf,__ELF_WORD_SIZE),_),x)
-#define __ElfN(x) __CONCAT(__CONCAT(__CONCAT(Elf,__ELF_WORD_SIZE),_),x)
-#define __ELFN(x) __CONCAT(__CONCAT(__CONCAT(ELF,__ELF_WORD_SIZE),_),x)
-#define __ElfType(x) typedef __ElfN(x) __CONCAT(Elf_,x)
+#define __elfN(x) __CONCAT(__CONCAT(__CONCAT(elf,__ELF_WORD_SIZE),_),x)
+#define __ElfN(x) __CONCAT(__CONCAT(__CONCAT(Elf,__ELF_WORD_SIZE),_),x)
+#define __ELFN(x) __CONCAT(__CONCAT(__CONCAT(ELF,__ELF_WORD_SIZE),_),x)
+#define __ElfType(x) typedef __ElfN(x) __CONCAT(Elf_,x)
__ElfType(Addr);
__ElfType(Half);
@@ -78,11 +78,11 @@ __ElfType(Hashelt);
__ElfType(Size);
__ElfType(Ssize);
-#define ELF_R_SYM __ELFN(R_SYM)
-#define ELF_R_TYPE __ELFN(R_TYPE)
-#define ELF_R_INFO __ELFN(R_INFO)
-#define ELF_ST_BIND __ELFN(ST_BIND)
-#define ELF_ST_TYPE __ELFN(ST_TYPE)
-#define ELF_ST_INFO __ELFN(ST_INFO)
+#define ELF_R_SYM __ELFN(R_SYM)
+#define ELF_R_TYPE __ELFN(R_TYPE)
+#define ELF_R_INFO __ELFN(R_INFO)
+#define ELF_ST_BIND __ELFN(ST_BIND)
+#define ELF_ST_TYPE __ELFN(ST_TYPE)
+#define ELF_ST_INFO __ELFN(ST_INFO)
#endif /* !_SYS_ELF_GENERIC_H_ */
diff --git a/sys/sys/file.h b/sys/sys/file.h
index 461b7e8..5c58e82 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -119,7 +119,7 @@ struct file {
struct ucred *f_cred; /* associated credentials. */
struct vnode *f_vnode; /* NULL or applicable vnode */
short f_type; /* descriptor type */
- short f_vnread_flags; /* (f) Sleep lock for f_offset */
+ short f_vnread_flags; /* (f) Sleep lock for f_offset */
volatile u_int f_flag; /* see fcntl.h */
volatile u_int f_count; /* reference count */
/*
diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h
index ec1d638..deb5b10 100644
--- a/sys/sys/imgact_elf.h
+++ b/sys/sys/imgact_elf.h
@@ -29,13 +29,13 @@
*/
#ifndef _SYS_IMGACT_ELF_H_
-#define _SYS_IMGACT_ELF_H_
+#define _SYS_IMGACT_ELF_H_
#include <machine/elf.h>
#ifdef _KERNEL
-#define AUXARGS_ENTRY(pos, id, val) {suword(pos++, id); suword(pos++, val);}
+#define AUXARGS_ENTRY(pos, id, val) {suword(pos++, id); suword(pos++, val);}
struct thread;
@@ -62,14 +62,14 @@ typedef struct {
const char *interp_path;
struct sysentvec *sysvec;
const char *interp_newpath;
- int flags;
-#define BI_CAN_EXEC_DYN 0x0001
+ int flags;
+#define BI_CAN_EXEC_DYN 0x0001
} __ElfN(Brandinfo);
__ElfType(Auxargs);
__ElfType(Brandinfo);
-#define MAX_BRANDS 8
+#define MAX_BRANDS 8
int __elfN(brand_inuse)(Elf_Brandinfo *entry);
int __elfN(insert_brand_entry)(Elf_Brandinfo *entry);
@@ -80,7 +80,7 @@ int __elfN(coredump)(struct thread *, struct vnode *, off_t);
/* Machine specific function to dump per-thread information. */
void __elfN(dump_thread)(struct thread *, void *, size_t *);
-extern int __elfN(fallback_brand);
+extern int __elfN(fallback_brand);
#endif /* _KERNEL */
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
index 5fab37a..74c7a6a 100644
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -181,16 +181,17 @@ void prison_hold(struct prison *pr);
void prison_hold_locked(struct prison *pr);
void prison_proc_hold(struct prison *);
void prison_proc_free(struct prison *);
-int prison_getip4(struct ucred *cred, struct in_addr *ia);
+int prison_get_ip4(struct ucred *cred, struct in_addr *ia);
int prison_local_ip4(struct ucred *cred, struct in_addr *ia);
int prison_remote_ip4(struct ucred *cred, struct in_addr *ia);
int prison_check_ip4(struct ucred *cred, struct in_addr *ia);
#ifdef INET6
-int prison_getip6(struct ucred *, struct in6_addr *);
+int prison_get_ip6(struct ucred *, struct in6_addr *);
int prison_local_ip6(struct ucred *, struct in6_addr *, int);
int prison_remote_ip6(struct ucred *, struct in6_addr *);
int prison_check_ip6(struct ucred *, struct in6_addr *);
#endif
+int prison_check_af(struct ucred *cred, int af);
int prison_if(struct ucred *cred, struct sockaddr *sa);
int prison_priv_check(struct ucred *cred, int priv);
diff --git a/sys/sys/kobj.h b/sys/sys/kobj.h
index 64a666a..9272e49 100644
--- a/sys/sys/kobj.h
+++ b/sys/sys/kobj.h
@@ -114,7 +114,7 @@ DEFINE_CLASS_0(name, name ## _class, methods, size)
#define DEFINE_CLASS_0(name, classvar, methods, size) \
\
struct kobj_class classvar = { \
- #name, methods, size, 0 \
+ #name, methods, size, NULL \
}
/*
@@ -127,7 +127,7 @@ struct kobj_class classvar = { \
base1) \
\
static kobj_class_t name ## _baseclasses[] = \
- { &base1, 0 }; \
+ { &base1, NULL }; \
struct kobj_class classvar = { \
#name, methods, size, name ## _baseclasses \
}
@@ -143,7 +143,7 @@ struct kobj_class classvar = { \
\
static kobj_class_t name ## _baseclasses[] = \
{ &base1, \
- &base2, 0 }; \
+ &base2, NULL }; \
struct kobj_class name ## _class = { \
#name, methods, size, name ## _baseclasses \
}
@@ -160,7 +160,7 @@ struct kobj_class name ## _class = { \
static kobj_class_t name ## _baseclasses[] = \
{ &base1, \
&base2, \
- &base3, 0 }; \
+ &base3, NULL }; \
struct kobj_class name ## _class = { \
#name, methods, size, name ## _baseclasses \
}
diff --git a/sys/sys/ktr.h b/sys/sys/ktr.h
index 5a262db..220d3fe 100644
--- a/sys/sys/ktr.h
+++ b/sys/sys/ktr.h
@@ -165,6 +165,95 @@ void ktr_tracepoint(u_int mask, const char *file, int line,
#define TR6(d, p1, p2, p3, p4, p5, p6) CTR6(KTR_GEN, d, p1, p2, p3, p4, p5, p6)
/*
+ * The event macros implement KTR graphic plotting facilities provided
+ * by src/tools/sched/schedgraph.py. Three generic types of events are
+ * supported: states, counters, and points.
+ *
+ * m is the ktr class for ktr_mask.
+ * ident is the string identifier that owns the event (ie: "thread 10001")
+ * etype is the type of event to plot (state, counter, point)
+ * edat is the event specific data (state name, counter value, point name)
+ * up to four attributes may be supplied as a name, value pair of arguments.
+ *
+ * etype and attribute names must be string constants. This minimizes the
+ * number of ktr slots required by construction the final format strings
+ * at compile time. Both must also include a colon and format specifier
+ * (ie. "prio:%d", prio). It is recommended that string arguments be
+ * contained within escaped quotes if they may contain ',' or ':' characters.
+ *
+ * The special attribute (KTR_ATTR_LINKED, ident) creates a reference to another
+ * id on the graph for easy traversal of related graph elements.
+ */
+
+#define KTR_ATTR_LINKED "linkedto:\"%s\""
+#define KTR_EFMT(egroup, ident, etype) \
+ "KTRGRAPH group:\"" egroup "\", id:\"%s\", " etype ", attributes: "
+
+#define KTR_EVENT0(m, egroup, ident, etype, edat) \
+ CTR2(m, KTR_EFMT(egroup, ident, etype) "none", ident, edat)
+#define KTR_EVENT1(m, egroup, ident, etype, edat, a0, v0) \
+ CTR3(m, KTR_EFMT(egroup, ident, etype) a0, ident, edat, (v0))
+#define KTR_EVENT2(m, egroup, ident, etype, edat, a0, v0, a1, v1) \
+ CTR4(m, KTR_EFMT(egroup, ident, etype) a0 ", " a1, \
+ ident, edat, (v0), (v1))
+#define KTR_EVENT3(m, egroup, ident, etype, edat, a0, v0, a1, v1, a2, v2)\
+ CTR5(m,KTR_EFMT(egroup, ident, etype) a0 ", " a1 ", " a2, \
+ ident, edat, (v0), (v1), (v2))
+#define KTR_EVENT4(m, egroup, ident, etype, edat, \
+ a0, v0, a1, v1, a2, v2, a3, v3) \
+ CTR6(m,KTR_EFMT(egroup, ident, etype) a0 ", " a1 ", " a2, ", ", a3,\
+ ident, edat, (v0), (v1), (v2), (v3))
+
+/*
+ * State functions graph state changes on an ident.
+ */
+#define KTR_STATE0(m, egroup, ident, state) \
+ KTR_EVENT0(m, egroup, ident, "state:\"%s\"", state)
+#define KTR_STATE1(m, egroup, ident, state, a0, v0) \
+ KTR_EVENT1(m, egroup, ident, "state:\"%s\"", state, a0, (v0))
+#define KTR_STATE2(m, egroup, ident, state, a0, v0, a1, v1) \
+ KTR_EVENT2(m, egroup, ident, "state:\"%s\"", state, a0, (v0), a1, (v1))
+#define KTR_STATE3(m, egroup, ident, state, a0, v0, a1, v1, a2, v2) \
+ KTR_EVENT3(m, egroup, ident, "state:\"%s\"", \
+ state, a0, (v0), a1, (v1), a2, (v2))
+#define KTR_STATE4(m, egroup, ident, state, a0, v0, a1, v1, a2, v2, a3, v3)\
+ KTR_EVENT4(m, egroup, ident, "state:\"%s\"", \
+ state, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
+
+/*
+ * Counter functions graph counter values. The counter id
+ * must not be intermixed with a state id.
+ */
+#define KTR_COUNTER0(m, egroup, ident, counter) \
+ KTR_EVENT0(m, egroup, ident, "counter:%d", counter)
+#define KTR_COUNTER1(m, egroup, ident, edat, a0, v0) \
+ KTR_EVENT1(m, egroup, ident, "counter:%d", counter, a0, (v0))
+#define KTR_COUNTER2(m, egroup, ident, counter, a0, v0, a1, v1) \
+ KTR_EVENT2(m, egroup, ident, "counter:%d", counter, a0, (v0), a1, (v1))
+#define KTR_COUNTER3(m, egroup, ident, counter, a0, v0, a1, v1, a2, v2) \
+ KTR_EVENT3(m, egroup, ident, "counter:%d", \
+ counter, a0, (v0), a1, (v1), a2, (v2))
+#define KTR_COUNTER4(m, egroup, ident, counter, a0, v0, a1, v1, a2, v2, a3, v3)\
+ KTR_EVENT4(m, egroup, ident, "counter:%d", \
+ counter, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
+
+/*
+ * Point functions plot points of interest on counter or state graphs.
+ */
+#define KTR_POINT0(m, egroup, ident, point) \
+ KTR_EVENT0(m, egroup, ident, "point:\"%s\"", point)
+#define KTR_POINT1(m, egroup, ident, point, a0, v0) \
+ KTR_EVENT1(m, egroup, ident, "point:\"%s\"", point, a0, (v0))
+#define KTR_POINT2(m, egroup, ident, point, a0, v0, a1, v1) \
+ KTR_EVENT2(m, egroup, ident, "point:\"%s\"", point, a0, (v0), a1, (v1))
+#define KTR_POINT3(m, egroup, ident, point, a0, v0, a1, v1, a2, v2) \
+ KTR_EVENT3(m, egroup, ident, "point:\"%s\"", point, \
+ a0, (v0), a1, (v1), a2, (v2))
+#define KTR_POINT4(m, egroup, ident, point, a0, v0, a1, v1, a2, v2, a3, v3)\
+ KTR_EVENT4(m, egroup, ident, "point:\"%s\"", \
+ point, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
+
+/*
* Trace initialization events, similar to CTR with KTR_INIT, but
* completely ifdef'ed out if KTR_INIT isn't in KTR_COMPILE (to
* save string space, the compiler doesn't optimize out strings
diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h
index 6e6660f..98840a5 100644
--- a/sys/sys/link_elf.h
+++ b/sys/sys/link_elf.h
@@ -39,7 +39,7 @@
*/
#ifndef _SYS_LINK_ELF_H_
-#define _SYS_LINK_ELF_H_
+#define _SYS_LINK_ELF_H_
#include <sys/elf.h>
@@ -70,9 +70,9 @@ struct r_debug {
void (*r_brk)(struct r_debug *, struct link_map *);
/* pointer to break point */
enum {
- RT_CONSISTENT, /* things are stable */
- RT_ADD, /* adding a shared library */
- RT_DELETE /* removing a shared library */
+ RT_CONSISTENT, /* things are stable */
+ RT_ADD, /* adding a shared library */
+ RT_DELETE /* removing a shared library */
} r_state;
};
@@ -90,8 +90,7 @@ struct dl_phdr_info
__BEGIN_DECLS
-typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t,
- void *);
+typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *);
extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
__END_DECLS
diff --git a/sys/sys/lock.h b/sys/sys/lock.h
index b2f7782..8eb85a3 100644
--- a/sys/sys/lock.h
+++ b/sys/sys/lock.h
@@ -216,6 +216,8 @@ int witness_warn(int, struct lock_object *, const char *, ...);
void witness_assert(struct lock_object *, int, const char *, int);
void witness_display_spinlock(struct lock_object *, struct thread *);
int witness_line(struct lock_object *);
+void witness_norelease(struct lock_object *);
+void witness_releaseok(struct lock_object *);
const char *witness_file(struct lock_object *);
void witness_thread_exit(struct thread *);
@@ -267,6 +269,12 @@ void witness_thread_exit(struct thread *);
#define WITNESS_RESTORE(lock, n) \
witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl))
+#define WITNESS_NORELEASE(lock) \
+ witness_norelease(&(lock)->lock_object)
+
+#define WITNESS_RELEASEOK(lock) \
+ witness_releaseok(&(lock)->lock_object)
+
#define WITNESS_FILE(lock) \
witness_file(lock)
@@ -287,6 +295,8 @@ void witness_thread_exit(struct thread *);
#define WITNESS_SAVE_DECL(n)
#define WITNESS_SAVE(lock, n)
#define WITNESS_RESTORE(lock, n)
+#define WITNESS_NORELEASE(lock)
+#define WITNESS_RELEASEOK(lock)
#define WITNESS_FILE(lock) ("?")
#define WITNESS_LINE(lock) (0)
#endif /* WITNESS */
diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h
index 2183144..8be7fb8 100644
--- a/sys/sys/lockmgr.h
+++ b/sys/sys/lockmgr.h
@@ -183,8 +183,6 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
#define KA_UNLOCKED LA_UNLOCKED
#define KA_RECURSED LA_RECURSED
#define KA_NOTRECURSED LA_NOTRECURSED
-#define KA_HELD
-#define KA_UNHELD
#endif
#endif /* _KERNEL */
diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
index 33b287f..24a044c 100644
--- a/sys/sys/malloc.h
+++ b/sys/sys/malloc.h
@@ -190,9 +190,9 @@ typedef void malloc_type_list_func_t(struct malloc_type *, void *);
void contigfree(void *addr, unsigned long size, struct malloc_type *type);
void *contigmalloc(unsigned long size, struct malloc_type *type, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
- unsigned long boundary);
+ unsigned long boundary) __malloc_like;
void free(void *addr, struct malloc_type *type);
-void *malloc(unsigned long size, struct malloc_type *type, int flags);
+void *malloc(unsigned long size, struct malloc_type *type, int flags) __malloc_like;
void malloc_init(void *);
int malloc_last_fail(void);
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 197618e..4d7e641 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -241,11 +241,13 @@ struct mbuf {
#define CSUM_IP_FRAGS 0x0008 /* will csum IP fragments */
#define CSUM_FRAGMENT 0x0010 /* will do IP fragmentation */
#define CSUM_TSO 0x0020 /* will do TSO */
+#define CSUM_SCTP 0x0040 /* will csum SCTP */
#define CSUM_IP_CHECKED 0x0100 /* did csum IP */
#define CSUM_IP_VALID 0x0200 /* ... the csum is valid */
#define CSUM_DATA_VALID 0x0400 /* csum_data field is valid */
#define CSUM_PSEUDO_HDR 0x0800 /* csum_data has pseudo hdr */
+#define CSUM_SCTP_VALID 0x1000 /* SCTP checksum is valid */
#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
#define CSUM_DELAY_IP (CSUM_IP) /* XXX add ipv6 here too? */
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 60086c6..5dd7b74 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -206,6 +206,7 @@ void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
#define MNT_MTX(mp) (&(mp)->mnt_mtx)
#define MNT_REF(mp) (mp)->mnt_ref++
#define MNT_REL(mp) do { \
+ KASSERT((mp)->mnt_ref > 0, ("negative mnt_ref")); \
(mp)->mnt_ref--; \
if ((mp)->mnt_ref == 0) \
wakeup((mp)); \
diff --git a/sys/sys/param.h b/sys/sys/param.h
index fad4d51..6a8e4b0 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 800060 /* Master, propagated to newvers */
+#define __FreeBSD_version 800062 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
diff --git a/sys/sys/pciio.h b/sys/sys/pciio.h
index 29771e4..a0c4560 100644
--- a/sys/sys/pciio.h
+++ b/sys/sys/pciio.h
@@ -108,9 +108,18 @@ struct pci_io {
u_int32_t pi_data; /* data to write or result of read */
};
+struct pci_bar_io {
+ struct pcisel pbi_sel; /* device to operate on */
+ int pbi_reg; /* starting address of BAR */
+ int pbi_enabled; /* decoding enabled */
+ uint64_t pbi_base; /* current value of BAR */
+ uint64_t pbi_length; /* length of BAR */
+};
+
#define PCIOCGETCONF _IOWR('p', 5, struct pci_conf_io)
#define PCIOCREAD _IOWR('p', 2, struct pci_io)
#define PCIOCWRITE _IOWR('p', 3, struct pci_io)
#define PCIOCATTACHED _IOWR('p', 4, struct pci_io)
+#define PCIOCGETBAR _IOWR('p', 6, struct pci_bar_io)
#endif /* !_SYS_PCIIO_H_ */
diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index 5633bf0..a1052e6 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -54,6 +54,9 @@ struct rm_queue {
struct rm_queue* volatile rmq_prev;
};
+#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
@@ -77,6 +80,9 @@ struct pcpu {
int pc_ktr_idx; /* Index into trace table */
char *pc_ktr_buf;
#endif
+#ifdef 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;
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index 92fb3e5..2be03d1 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -83,7 +83,8 @@
__PMC_CPU(INTEL_CORE, 0x87, "Intel Core Solo/Duo") \
__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_ATOM, 0x8A, "Intel Atom") \
+ __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7")
enum pmc_cputype {
#undef __PMC_CPU
@@ -92,7 +93,7 @@ enum pmc_cputype {
};
#define PMC_CPU_FIRST PMC_CPU_AMD_K7
-#define PMC_CPU_LAST PMC_CPU_INTEL_ATOM
+#define PMC_CPU_LAST PMC_CPU_INTEL_COREI7
/*
* Classes of PMCs
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 30f1a4d..9f064c5 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -66,9 +66,7 @@ struct sockopt;
/* USE THESE FOR YOUR PROTOTYPES ! */
typedef void pr_input_t (struct mbuf *, int);
typedef int pr_input6_t (struct mbuf **, int*, int); /* XXX FIX THIS */
-typedef void pr_in_input_t (struct mbuf *, int, int); /* XXX FIX THIS */
typedef int pr_output_t (struct mbuf *, struct socket *);
-typedef int pr_in_output_t (struct mbuf *, struct socket *, struct sockaddr *);
typedef void pr_ctlinput_t (int, struct sockaddr *, void *);
typedef int pr_ctloutput_t (struct socket *, struct sockopt *);
typedef void pr_init_t (void);
@@ -76,9 +74,6 @@ typedef void pr_fasttimo_t (void);
typedef void pr_slowtimo_t (void);
typedef void pr_drain_t (void);
-typedef int pr_usrreq_t(struct socket *, int, struct mbuf *,
- struct mbuf *, struct mbuf *, struct thread *);
-
struct protosw {
short pr_type; /* socket type used for */
struct domain *pr_domain; /* domain protocol a member of */
@@ -89,15 +84,13 @@ struct protosw {
pr_output_t *pr_output; /* output to protocol (from above) */
pr_ctlinput_t *pr_ctlinput; /* control input (from below) */
pr_ctloutput_t *pr_ctloutput; /* control output (from above) */
-/* user-protocol hook */
- pr_usrreq_t *pr_ousrreq;
/* utility hooks */
pr_init_t *pr_init;
pr_fasttimo_t *pr_fasttimo; /* fast timeout (200ms) */
pr_slowtimo_t *pr_slowtimo; /* slow timeout (500ms) */
pr_drain_t *pr_drain; /* flush any excess space possible */
- struct pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */
+ struct pr_usrreqs *pr_usrreqs; /* user-protocol hook */
};
/*#endif*/
@@ -133,17 +126,6 @@ struct protosw {
* We now provide individual function pointers which protocols can implement,
* which offers a number of benefits (such as type checking for arguments).
* These older constants are still present in order to support TCP debugging.
- *
- * The arguments to usrreq were:
- * (*protosw[].pr_usrreq)(up, req, m, nam, opt);
- * where up is a (struct socket *), req is one of these requests,
- * m is an optional mbuf chain containing a message,
- * nam is an optional mbuf chain containing an address,
- * and opt is a pointer to a socketopt structure or nil.
- * The protocol is responsible for disposal of the mbuf chain m,
- * the caller is responsible for any space held by nam and opt.
- * A non-zero return from usrreq gives an
- * UNIX error number which should be passed to higher level software.
*/
#define PRU_ATTACH 0 /* attach protocol to up */
#define PRU_DETACH 1 /* detach protocol from up */
@@ -172,7 +154,8 @@ struct protosw {
#define PRU_SEND_EOF 22 /* send and close */
#define PRU_SOSETLABEL 23 /* MAC label change */
#define PRU_CLOSE 24 /* socket close */
-#define PRU_NREQ 24
+#define PRU_FLUSH 25 /* flush the socket */
+#define PRU_NREQ 25
#ifdef PRUREQUESTS
const char *prurequests[] = {
@@ -182,7 +165,7 @@ const char *prurequests[] = {
"SENSE", "RCVOOB", "SENDOOB", "SOCKADDR",
"PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO",
"PROTORCV", "PROTOSEND", "SEND_EOF", "SOSETLABEL",
- "CLOSE",
+ "CLOSE", "FLUSH",
};
#endif
@@ -328,7 +311,7 @@ char *prcrequests[] = {
* The protocol is responsible for disposal of the mbuf chain *optval
* if supplied,
* the caller is responsible for any space held by *optval, when returned.
- * A non-zero return from usrreq gives an
+ * A non-zero return from ctloutput gives an
* UNIX error number which should be passed to higher level software.
*/
#define PRCO_GETOPT 0
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index bbd2199..198d96e 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -134,6 +134,12 @@ void sched_affinity(struct thread *td);
int sched_sizeof_proc(void);
int sched_sizeof_thread(void);
+/*
+ * This routine provides a consistent thread name for use with KTR graphing
+ * functions.
+ */
+char *sched_tdname(struct thread *td);
+
static __inline void
sched_pin(void)
{
diff --git a/sys/sys/soundcard.h b/sys/sys/soundcard.h
index 0ae5969..e5401f3 100644
--- a/sys/sys/soundcard.h
+++ b/sys/sys/soundcard.h
@@ -801,18 +801,91 @@ typedef struct audio_buf_info {
#define SNDCTL_DSP_NONBLOCK _IO ('P',14)
#define SNDCTL_DSP_GETCAPS _IOR ('P',15, int)
-#define DSP_CAP_REVISION 0x000000ff /* revision level (0 to 255) */
-#define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */
-#define DSP_CAP_REALTIME 0x00000200 /* Real time capability */
-#define DSP_CAP_BATCH 0x00000400
- /*
- * Device has some kind of internal buffers which may
- * cause some delays and decrease precision of timing
- */
-#define DSP_CAP_COPROC 0x00000800
- /* Has a coprocessor, sometimes it's a DSP but usually not */
-#define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
-#define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */
+# define PCM_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */
+# define PCM_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */
+# define PCM_CAP_REALTIME 0x00000200 /* Not in use */
+# define PCM_CAP_BATCH 0x00000400 /* Device has some kind of */
+ /* internal buffers which may */
+ /* cause some delays and */
+ /* decrease precision of timing */
+# define PCM_CAP_COPROC 0x00000800 /* Has a coprocessor */
+ /* Sometimes it's a DSP */
+ /* but usually not */
+# define PCM_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
+# define PCM_CAP_MMAP 0x00002000 /* Supports mmap() */
+# define PCM_CAP_MULTI 0x00004000 /* Supports multiple open */
+# define PCM_CAP_BIND 0x00008000 /* Supports binding to front/rear/center/lfe */
+# define PCM_CAP_INPUT 0x00010000 /* Supports recording */
+# define PCM_CAP_OUTPUT 0x00020000 /* Supports playback */
+# define PCM_CAP_VIRTUAL 0x00040000 /* Virtual device */
+/* 0x00040000 and 0x00080000 reserved for future use */
+
+/* Analog/digital control capabilities */
+# define PCM_CAP_ANALOGOUT 0x00100000
+# define PCM_CAP_ANALOGIN 0x00200000
+# define PCM_CAP_DIGITALOUT 0x00400000
+# define PCM_CAP_DIGITALIN 0x00800000
+# define PCM_CAP_ADMASK 0x00f00000
+/*
+ * NOTE! (capabilities & PCM_CAP_ADMASK)==0 means just that the
+ * digital/analog interface control features are not supported by the
+ * device/driver. However the device still supports analog, digital or
+ * both inputs/outputs (depending on the device). See the OSS Programmer's
+ * Guide for full details.
+ */
+# define PCM_CAP_SPECIAL 0x01000000 /* Not for ordinary "multimedia" use */
+# define PCM_CAP_SHADOW 0x00000000 /* OBSOLETE */
+
+/*
+ * Preferred channel usage. These bits can be used to
+ * give recommendations to the application. Used by few drivers.
+ * For example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that
+ * the device works best in mono mode. However it doesn't necessarily mean
+ * that the device cannot be used in stereo. These bits should only be used
+ * by special applications such as multi track hard disk recorders to find
+ * out the initial setup. However the user should be able to override this
+ * selection.
+ *
+ * To find out which modes are actually supported the application should
+ * try to select them using SNDCTL_DSP_CHANNELS.
+ */
+# define DSP_CH_MASK 0x06000000 /* Mask */
+# define DSP_CH_ANY 0x00000000 /* No preferred mode */
+# define DSP_CH_MONO 0x02000000
+# define DSP_CH_STEREO 0x04000000
+# define DSP_CH_MULTI 0x06000000 /* More than two channels */
+
+# define PCM_CAP_HIDDEN 0x08000000 /* Hidden device */
+# define PCM_CAP_FREERATE 0x10000000
+# define PCM_CAP_MODEM 0x20000000 /* Modem device */
+# define PCM_CAP_DEFAULT 0x40000000 /* "Default" device */
+
+/*
+ * The PCM_CAP_* capability names were known as DSP_CAP_* prior OSS 4.0
+ * so it's necessary to define the older names too.
+ */
+#define DSP_CAP_ADMASK PCM_CAP_ADMASK
+#define DSP_CAP_ANALOGIN PCM_CAP_ANALOGIN
+#define DSP_CAP_ANALOGOUT PCM_CAP_ANALOGOUT
+#define DSP_CAP_BATCH PCM_CAP_BATCH
+#define DSP_CAP_BIND PCM_CAP_BIND
+#define DSP_CAP_COPROC PCM_CAP_COPROC
+#define DSP_CAP_DEFAULT PCM_CAP_DEFAULT
+#define DSP_CAP_DIGITALIN PCM_CAP_DIGITALIN
+#define DSP_CAP_DIGITALOUT PCM_CAP_DIGITALOUT
+#define DSP_CAP_DUPLEX PCM_CAP_DUPLEX
+#define DSP_CAP_FREERATE PCM_CAP_FREERATE
+#define DSP_CAP_HIDDEN PCM_CAP_HIDDEN
+#define DSP_CAP_INPUT PCM_CAP_INPUT
+#define DSP_CAP_MMAP PCM_CAP_MMAP
+#define DSP_CAP_MODEM PCM_CAP_MODEM
+#define DSP_CAP_MULTI PCM_CAP_MULTI
+#define DSP_CAP_OUTPUT PCM_CAP_OUTPUT
+#define DSP_CAP_REALTIME PCM_CAP_REALTIME
+#define DSP_CAP_REVISION PCM_CAP_REVISION
+#define DSP_CAP_SHADOW PCM_CAP_SHADOW
+#define DSP_CAP_TRIGGER PCM_CAP_TRIGGER
+#define DSP_CAP_VIRTUAL PCM_CAP_VIRTUAL
/*
* What do these function do ?
@@ -1639,7 +1712,10 @@ typedef struct oss_sysinfo
int openedmidi[8]; /* Bit mask telling which midi devices
are busy */
int numcards; /* Number of sound cards in the system */
- int filler[241]; /* For future expansion (set to -1) */
+ int numaudioengines; /* Number of audio engines in the system */
+ char license[16]; /* For example "GPL" or "CDDL" */
+ char revision_info[256]; /* For internal use */
+ int filler[172]; /* For future expansion (set to -1) */
} oss_sysinfo;
typedef struct oss_mixext
@@ -1782,7 +1858,9 @@ typedef struct oss_audioinfo
int latency; /* In usecs, -1=unknown */
oss_devnode_t devnode; /* Device special file name (inside
/dev) */
- int filler[186];
+ int next_play_engine;
+ int next_rec_engine;
+ int filler[184];
} oss_audioinfo;
typedef struct oss_mixerinfo
@@ -1848,7 +1926,9 @@ typedef struct oss_card_info
char shortname[16];
char longname[128];
int flags;
- int filler[256];
+ char hw_info[400];
+ int intr_count, ack_count;
+ int filler[154];
} oss_card_info;
#define SNDCTL_SYSINFO _IOR ('X', 1, oss_sysinfo)
@@ -1865,6 +1945,8 @@ typedef struct oss_card_info
#define SNDCTL_MIDIINFO _IOWR('X', 9, oss_midi_info)
#define SNDCTL_MIXERINFO _IOWR('X',10, oss_mixerinfo)
#define SNDCTL_CARDINFO _IOWR('X',11, oss_card_info)
+#define SNDCTL_ENGINEINFO _IOWR('X',12, oss_audioinfo)
+#define SNDCTL_AUDIOINFO_EX _IOWR('X',13, oss_audioinfo)
/*
* Few more "globally" available ioctl calls.
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index a92f190..ea76c09 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -84,6 +84,7 @@ struct ctlname {
#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */
#define CTLMASK_SECURE 0x00F00000 /* Secure level */
#define CTLFLAG_TUN 0x00080000 /* Tunable variable */
+#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */
#define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN)
/*
@@ -221,7 +222,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
/* This constructs a "raw" MIB oid. */
#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
static struct sysctl_oid sysctl__##parent##_##name = { \
- &sysctl_##parent##_children, { 0 }, nbr, kind, \
+ &sysctl_##parent##_children, { NULL }, nbr, kind, \
a1, a2, #name, handler, fmt, 0, __DESCR(descr) }; \
DATA_SET(sysctl_set, sysctl__##parent##_##name)
@@ -257,7 +258,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \
- 0, 0, handler, "N", __DESCR(descr))
+ NULL, 0, handler, "N", __DESCR(descr))
/* Oid for a string. len can be 0 to indicate '\0' termination. */
#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \
@@ -286,7 +287,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
/* Oid for an int. If ptr is NULL, val is returned. */
#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_int, "I", descr)
#ifdef VIMAGE
@@ -296,22 +297,22 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#else
#ifdef VIMAGE_GLOBALS
#define SYSCTL_V_INT(subs, mod, parent, nbr, name, access, sym, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
&sym, val, sysctl_handle_int, "I", descr)
#else
#define SYSCTL_V_INT(subs, mod, parent, nbr, name, access, sym, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
& mod ## _0._ ## sym, val, sysctl_handle_int, "I", descr)
#endif
#endif
#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_int, "I", __DESCR(descr))
/* Oid for an unsigned int. If ptr is NULL, val is returned. */
#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_int, "IU", descr)
#ifdef VIMAGE
@@ -321,60 +322,60 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#else
#ifdef VIMAGE_GLOBALS
#define SYSCTL_V_UINT(subs, mod, parent, nbr, name, access, sym, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
&sym, val, sysctl_handle_int, "IU", descr)
#else
#define SYSCTL_V_UINT(subs, mod, parent, nbr, name, access, sym, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
& mod ## _0._ ## sym, val, sysctl_handle_int, "IU", descr)
#endif
#endif
#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_int, "IU", __DESCR(descr))
#define SYSCTL_XINT(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_int, "IX", descr)
#define SYSCTL_ADD_XINT(ctx, parent, nbr, name, access, ptr, val, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_int, "IX", __DESCR(descr))
/* Oid for a long. The pointer must be non NULL. */
#define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_LONG|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_LONG|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_long, "L", descr)
#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|CTLFLAG_MPSAFE|(access), \
ptr, 0, sysctl_handle_long, "L", __DESCR(descr))
/* Oid for an unsigned long. The pointer must be non NULL. */
#define SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_long, "LU", __DESCR(descr))
#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access), \
ptr, 0, sysctl_handle_long, "LU", __DESCR(descr))
#define SYSCTL_XLONG(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_long, "LX", __DESCR(descr))
#define SYSCTL_ADD_XLONG(ctx, parent, nbr, name, access, ptr, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access), \
ptr, 0, sysctl_handle_long, "LX", __DESCR(descr))
/* Oid for a quad. The pointer must be non NULL. */
#define SYSCTL_QUAD(parent, nbr, name, access, ptr, val, descr) \
- SYSCTL_OID(parent, nbr, name, CTLTYPE_QUAD|(access), \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_QUAD|CTLFLAG_MPSAFE|(access), \
ptr, val, sysctl_handle_quad, "Q", __DESCR(descr))
#define SYSCTL_ADD_QUAD(ctx, parent, nbr, name, access, ptr, descr) \
- sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_QUAD|(access), \
+ sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_QUAD|CTLFLAG_MPSAFE|(access), \
ptr, 0, sysctl_handle_quad, "Q", __DESCR(descr))
/* Oid for an opaque object. Specified by a pointer and a length. */
@@ -798,6 +799,8 @@ int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *retval, int flags);
int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
int *nindx, struct sysctl_req *req);
+void sysctl_lock(void);
+void sysctl_unlock(void);
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
#else /* !_KERNEL */
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index 7505562..218fd21 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -64,24 +64,25 @@ struct tty {
TAILQ_ENTRY(tty) t_list; /* (l) TTY list entry. */
unsigned int t_flags; /* (t) Terminal option flags. */
/* Keep flags in sync with db_show_tty and pstat(8). */
-#define TF_NOPREFIX 0x0001 /* Don't prepend "tty" to device name. */
-#define TF_INITLOCK 0x0002 /* Create init/lock state devices. */
-#define TF_CALLOUT 0x0004 /* Create "cua" devices. */
-#define TF_OPENED_IN 0x0008 /* "tty" node is in use. */
-#define TF_OPENED_OUT 0x0010 /* "cua" node is in use. */
-#define TF_OPENED (TF_OPENED_IN|TF_OPENED_OUT)
-#define TF_GONE 0x0020 /* Device node is gone. */
-#define TF_OPENCLOSE 0x0040 /* Device is in open()/close(). */
-#define TF_ASYNC 0x0080 /* Asynchronous I/O enabled. */
-#define TF_LITERAL 0x0100 /* Accept the next character literally. */
-#define TF_HIWAT_IN 0x0200 /* We've reached the input watermark. */
-#define TF_HIWAT_OUT 0x0400 /* We've reached the output watermark. */
+#define TF_NOPREFIX 0x00001 /* Don't prepend "tty" to device name. */
+#define TF_INITLOCK 0x00002 /* Create init/lock state devices. */
+#define TF_CALLOUT 0x00004 /* Create "cua" devices. */
+#define TF_OPENED_IN 0x00008 /* "tty" node is in use. */
+#define TF_OPENED_OUT 0x00010 /* "cua" node is in use. */
+#define TF_OPENED_CONS 0x00020 /* Device in use as console. */
+#define TF_OPENED (TF_OPENED_IN|TF_OPENED_OUT|TF_OPENED_CONS)
+#define TF_GONE 0x00040 /* Device node is gone. */
+#define TF_OPENCLOSE 0x00080 /* Device is in open()/close(). */
+#define TF_ASYNC 0x00100 /* Asynchronous I/O enabled. */
+#define TF_LITERAL 0x00200 /* Accept the next character literally. */
+#define TF_HIWAT_IN 0x00400 /* We've reached the input watermark. */
+#define TF_HIWAT_OUT 0x00800 /* We've reached the output watermark. */
#define TF_HIWAT (TF_HIWAT_IN|TF_HIWAT_OUT)
-#define TF_STOPPED 0x0800 /* Output flow control - stopped. */
-#define TF_EXCLUDE 0x1000 /* Exclusive access. */
-#define TF_BYPASS 0x2000 /* Optimized input path. */
-#define TF_ZOMBIE 0x4000 /* Modem disconnect received. */
-#define TF_HOOK 0x8000 /* TTY has hook attached. */
+#define TF_STOPPED 0x01000 /* Output flow control - stopped. */
+#define TF_EXCLUDE 0x02000 /* Exclusive access. */
+#define TF_BYPASS 0x04000 /* Optimized input path. */
+#define TF_ZOMBIE 0x08000 /* Modem disconnect received. */
+#define TF_HOOK 0x10000 /* TTY has hook attached. */
unsigned int t_revokecnt; /* (t) revoke() count. */
/* Buffering mechanisms. */
diff --git a/sys/sys/ttyqueue.h b/sys/sys/ttyqueue.h
index 2bb0be1..aac6b3c 100644
--- a/sys/sys/ttyqueue.h
+++ b/sys/sys/ttyqueue.h
@@ -43,29 +43,29 @@ struct uio;
/* Data input queue. */
struct ttyinq {
- TAILQ_HEAD(ttyinq_bhead, ttyinq_block) ti_list;
- struct ttyinq_block *ti_startblock;
- struct ttyinq_block *ti_reprintblock;
- struct ttyinq_block *ti_lastblock;
- unsigned int ti_begin;
- unsigned int ti_linestart;
- unsigned int ti_reprint;
- unsigned int ti_end;
- unsigned int ti_nblocks;
- unsigned int ti_quota;
+ struct ttyinq_block *ti_firstblock;
+ struct ttyinq_block *ti_startblock;
+ struct ttyinq_block *ti_reprintblock;
+ struct ttyinq_block *ti_lastblock;
+ unsigned int ti_begin;
+ unsigned int ti_linestart;
+ unsigned int ti_reprint;
+ unsigned int ti_end;
+ unsigned int ti_nblocks;
+ unsigned int ti_quota;
};
#define TTYINQ_DATASIZE 128
/* Data output queue. */
struct ttyoutq {
- STAILQ_HEAD(, ttyoutq_block) to_list;
- struct ttyoutq_block *to_lastblock;
- unsigned int to_begin;
- unsigned int to_end;
- unsigned int to_nblocks;
- unsigned int to_quota;
+ struct ttyoutq_block *to_firstblock;
+ struct ttyoutq_block *to_lastblock;
+ unsigned int to_begin;
+ unsigned int to_end;
+ unsigned int to_nblocks;
+ unsigned int to_quota;
};
-#define TTYOUTQ_DATASIZE (256 - sizeof(STAILQ_ENTRY(ttyoutq_block)))
+#define TTYOUTQ_DATASIZE (256 - sizeof(struct ttyoutq_block *))
#ifdef _KERNEL
/* Input queue handling routines. */
@@ -86,13 +86,6 @@ void ttyinq_unputchar(struct ttyinq *ti);
void ttyinq_reprintpos_set(struct ttyinq *ti);
void ttyinq_reprintpos_reset(struct ttyinq *ti);
-static __inline void
-ttyinq_init(struct ttyinq *ti)
-{
-
- TAILQ_INIT(&ti->ti_list);
-}
-
static __inline size_t
ttyinq_getsize(struct ttyinq *ti)
{
@@ -143,13 +136,6 @@ int ttyoutq_read_uio(struct ttyoutq *to, struct tty *tp, struct uio *uio);
size_t ttyoutq_write(struct ttyoutq *to, const void *buf, size_t len);
int ttyoutq_write_nofrag(struct ttyoutq *to, const void *buf, size_t len);
-static __inline void
-ttyoutq_init(struct ttyoutq *to)
-{
-
- STAILQ_INIT(&to->to_list);
-}
-
static __inline size_t
ttyoutq_getsize(struct ttyoutq *to)
{
diff --git a/sys/sys/types.h b/sys/sys/types.h
index cf9264a..66be699 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -317,17 +317,9 @@ typedef struct vm_page *vm_page_t;
* minor() gives a cookie instead of an index since we don't want to
* change the meanings of bits 0-15 or waste time and space shifting
* bits 16-31 for devices that don't use them.
- *
- * XXX: In the kernel we must name it umajor() and uminor(), because
- * minor() is still in use by <sys/conf.h>.
*/
-#ifdef _KERNEL
-#define umajor(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */
-#define uminor(x) ((int)((x)&0xffff00ff)) /* minor number */
-#else /* !_KERNEL */
-#define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */
+#define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */
#define minor(x) ((int)((x)&0xffff00ff)) /* minor number */
-#endif /* _KERNEL */
#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) /* create dev_t */
/*
diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h
index f65a198..6db586b 100644
--- a/sys/sys/unistd.h
+++ b/sys/sys/unistd.h
@@ -178,7 +178,7 @@
#define RFSIGSHARE (1<<14) /* share signal handlers */
#define RFLINUXTHPN (1<<16) /* do linux clone exit parent notification */
#define RFSTOPPED (1<<17) /* leave child in a stopped state */
-#define RFHIGHPID (1<<18) /* use a pid higher then 10 (idleproc) */
+#define RFHIGHPID (1<<18) /* use a pid higher than 10 (idleproc) */
#define RFPPWAIT (1<<31) /* parent sleeps until child exits (vfork) */
#define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPPWAIT)
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index de64090..8e96a1d 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -285,7 +285,6 @@ struct vattr {
*/
#define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
#define VA_EXCLUSIVE 0x02 /* exclusive create request */
-#define VA_MARK_ATIME 0x04 /* setting atime for execve/mmap */
/*
* Flags for ioflag. (high 16 bits used to ask for read-ahead and
@@ -636,6 +635,9 @@ int vn_extattr_set(struct vnode *vp, int ioflg, int attrnamespace,
const char *attrname, int buflen, char *buf, struct thread *td);
int vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace,
const char *attrname, struct thread *td);
+int vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags,
+ struct vnode **rvp);
+
int vfs_cache_lookup(struct vop_lookup_args *ap);
void vfs_timestamp(struct timespec *);
void vfs_write_resume(struct mount *mp);
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index a72137e..4748f68 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -130,10 +130,10 @@ static int ffs_reallocblks_ufs2(struct vop_reallocblks_args *);
* available block is located.
*/
int
-ffs_alloc(ip, lbn, bpref, size, cred, bnp)
+ffs_alloc(ip, lbn, bpref, size, flags, cred, bnp)
struct inode *ip;
ufs2_daddr_t lbn, bpref;
- int size;
+ int size, flags;
struct ucred *cred;
ufs2_daddr_t *bnp;
{
@@ -191,7 +191,10 @@ retry:
UFS_UNLOCK(ump);
}
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ if (flags & IO_EXT)
+ ip->i_flag |= IN_CHANGE;
+ else
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
*bnp = bno;
return (0);
}
@@ -227,12 +230,12 @@ nospace:
* invoked to get an appropriate block.
*/
int
-ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, cred, bpp)
+ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp)
struct inode *ip;
ufs2_daddr_t lbprev;
ufs2_daddr_t bprev;
ufs2_daddr_t bpref;
- int osize, nsize;
+ int osize, nsize, flags;
struct ucred *cred;
struct buf **bpp;
{
@@ -317,7 +320,10 @@ retry:
UFS_UNLOCK(ump);
}
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ if (flags & IO_EXT)
+ ip->i_flag |= IN_CHANGE;
+ else
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
allocbuf(bp, nsize);
bp->b_flags |= B_DONE;
if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO)
@@ -392,7 +398,10 @@ retry:
UFS_UNLOCK(ump);
}
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ if (flags & IO_EXT)
+ ip->i_flag |= IN_CHANGE;
+ else
+ ip->i_flag |= IN_CHANGE | IN_UPDATE;
allocbuf(bp, nsize);
bp->b_flags |= B_DONE;
if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO)
@@ -1849,7 +1858,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
struct cdev *dev;
cg = dtog(fs, bno);
- if (devvp->v_type != VCHR) {
+ if (devvp->v_type == VREG) {
/* devvp is a snapshot */
dev = VTOI(devvp)->i_devvp->v_rdev;
cgblkno = fragstoblks(fs, cgtod(fs, cg));
@@ -1894,7 +1903,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum)
if (size == fs->fs_bsize) {
fragno = fragstoblks(fs, cgbno);
if (!ffs_isfreeblock(fs, blksfree, fragno)) {
- if (devvp->v_type != VCHR) {
+ if (devvp->v_type == VREG) {
UFS_UNLOCK(ump);
/* devvp is a snapshot */
brelse(bp);
@@ -2047,7 +2056,7 @@ ffs_freefile(ump, fs, devvp, ino, mode)
struct cdev *dev;
cg = ino_to_cg(fs, ino);
- if (devvp->v_type != VCHR) {
+ if (devvp->v_type == VREG) {
/* devvp is a snapshot */
dev = VTOI(devvp)->i_devvp->v_rdev;
cgbno = fragstoblks(fs, cgtod(fs, cg));
@@ -2113,7 +2122,7 @@ ffs_checkfreefile(fs, devvp, ino)
u_int8_t *inosused;
cg = ino_to_cg(fs, ino);
- if (devvp->v_type != VCHR) {
+ if (devvp->v_type == VREG) {
/* devvp is a snapshot */
cgbno = fragstoblks(fs, cgtod(fs, cg));
} else {
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index 0bd895f..a12f96e 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -133,7 +133,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_realloccg(ip, nb, dp->di_db[nb],
ffs_blkpref_ufs1(ip, lastlbn, (int)nb,
- &dp->di_db[0]), osize, (int)fs->fs_bsize, cred, &bp);
+ &dp->di_db[0]), osize, (int)fs->fs_bsize, flags,
+ cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -184,7 +185,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
ffs_blkpref_ufs1(ip, lbn, (int)lbn,
- &dp->di_db[0]), osize, nsize, cred, &bp);
+ &dp->di_db[0]), osize, nsize, flags,
+ cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -200,7 +202,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_alloc(ip, lbn,
ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]),
- nsize, cred, &newb);
+ nsize, flags, cred, &newb);
if (error)
return (error);
bp = getblk(vp, lbn, nsize, 0, 0, 0);
@@ -241,7 +243,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
- cred, &newb)) != 0) {
+ flags, cred, &newb)) != 0) {
curthread->td_pflags &= saved_inbdflush;
return (error);
}
@@ -291,8 +293,8 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
if (pref == 0)
pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
- if ((error =
- ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) != 0) {
+ if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
+ flags, cred, &newb)) != 0) {
brelse(bp);
goto fail;
}
@@ -346,7 +348,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, &bap[0]);
error = ffs_alloc(ip,
- lbn, pref, (int)fs->fs_bsize, cred, &newb);
+ lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
if (error) {
brelse(bp);
goto fail;
@@ -534,7 +536,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
dp->di_extb[nb],
ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
&dp->di_extb[0]), osize,
- (int)fs->fs_bsize, cred, &bp);
+ (int)fs->fs_bsize, flags, cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -545,7 +547,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
dp->di_extsize = smalllblktosize(fs, nb + 1);
dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
bp->b_xflags |= BX_ALTDATA;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
if (flags & IO_SYNC)
bwrite(bp);
else
@@ -588,7 +590,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
error = ffs_realloccg(ip, -1 - lbn,
dp->di_extb[lbn],
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
- &dp->di_extb[0]), osize, nsize, cred, &bp);
+ &dp->di_extb[0]), osize, nsize, flags,
+ cred, &bp);
if (error)
return (error);
bp->b_xflags |= BX_ALTDATA;
@@ -605,7 +608,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_alloc(ip, lbn,
ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
- nsize, cred, &newb);
+ nsize, flags, cred, &newb);
if (error)
return (error);
bp = getblk(vp, -1 - lbn, nsize, 0, 0, 0);
@@ -618,7 +621,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
nsize, 0, bp);
}
dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
*bpp = bp;
return (0);
}
@@ -636,7 +639,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
error = ffs_realloccg(ip, nb, dp->di_db[nb],
ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
&dp->di_db[0]), osize, (int)fs->fs_bsize,
- cred, &bp);
+ flags, cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -688,7 +691,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
- &dp->di_db[0]), osize, nsize, cred, &bp);
+ &dp->di_db[0]), osize, nsize, flags,
+ cred, &bp);
if (error)
return (error);
if (DOINGSOFTDEP(vp))
@@ -704,7 +708,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
error = ffs_alloc(ip, lbn,
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
- &dp->di_db[0]), nsize, cred, &newb);
+ &dp->di_db[0]), nsize, flags, cred, &newb);
if (error)
return (error);
bp = getblk(vp, lbn, nsize, 0, 0, 0);
@@ -745,7 +749,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
- cred, &newb)) != 0) {
+ flags, cred, &newb)) != 0) {
curthread->td_pflags &= saved_inbdflush;
return (error);
}
@@ -795,8 +799,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
if (pref == 0)
pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
- if ((error =
- ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) != 0) {
+ if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
+ flags, cred, &newb)) != 0) {
brelse(bp);
goto fail;
}
@@ -850,7 +854,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
UFS_LOCK(ump);
pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, &bap[0]);
error = ffs_alloc(ip,
- lbn, pref, (int)fs->fs_bsize, cred, &newb);
+ lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
if (error) {
brelse(bp);
goto fail;
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 4a2f3a2..7e32ced 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -48,8 +48,8 @@ struct vnode;
struct vop_fsync_args;
struct vop_reallocblks_args;
-int ffs_alloc(struct inode *,
- ufs2_daddr_t, ufs2_daddr_t, int, struct ucred *, ufs2_daddr_t *);
+int ffs_alloc(struct inode *, ufs2_daddr_t, ufs2_daddr_t, int, int,
+ struct ucred *, ufs2_daddr_t *);
int ffs_balloc_ufs1(struct vnode *a_vp, off_t a_startoffset, int a_size,
struct ucred *a_cred, int a_flags, struct buf **a_bpp);
int ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size,
@@ -72,7 +72,7 @@ void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
int ffs_mountroot(void);
int ffs_reallocblks(struct vop_reallocblks_args *);
int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t,
- ufs2_daddr_t, int, int, struct ucred *, struct buf **);
+ ufs2_daddr_t, int, int, int, struct ucred *, struct buf **);
int ffs_sbupdate(struct ufsmount *, int, int);
void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_snapblkfree(struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t);
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index fa679ef..b2f9067 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
#include <ufs/ufs/extattr.h>
#include <ufs/ufs/quota.h>
@@ -128,6 +129,18 @@ ffs_update(vp, waitfor)
}
}
+static void
+ffs_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end)
+{
+ vm_object_t object;
+
+ if ((object = vp->v_object) == NULL)
+ return;
+ VM_OBJECT_LOCK(object);
+ vm_object_page_remove(object, start, end, FALSE);
+ VM_OBJECT_UNLOCK(object);
+}
+
#define SINGLE 0 /* index of single indirect block */
#define DOUBLE 1 /* index of double indirect block */
#define TRIPLE 2 /* index of triple indirect block */
@@ -205,12 +218,14 @@ ffs_truncate(vp, length, flags, cred, td)
(void) chkdq(ip, -extblocks, NOCRED, 0);
#endif
vinvalbuf(vp, V_ALT, 0, 0);
+ ffs_pages_remove(vp,
+ OFF_TO_IDX(lblktosize(fs, -extblocks)), 0);
ip->i_din2->di_extsize = 0;
for (i = 0; i < NXADDR; i++) {
oldblks[i] = ip->i_din2->di_extb[i];
ip->i_din2->di_extb[i] = 0;
}
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
if ((error = ffs_update(vp, 1)))
return (error);
for (i = 0; i < NXADDR; i++) {
@@ -281,6 +296,9 @@ ffs_truncate(vp, length, flags, cred, td)
IO_EXT | IO_NORMAL : IO_NORMAL);
ASSERT_VOP_LOCKED(vp, "ffs_truncate1");
vinvalbuf(vp, needextclean ? 0 : V_NORMAL, 0, 0);
+ if (!needextclean)
+ ffs_pages_remove(vp, 0,
+ OFF_TO_IDX(lblktosize(fs, -extblocks)));
vnode_pager_setsize(vp, 0);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
return (ffs_update(vp, 0));
@@ -296,8 +314,10 @@ ffs_truncate(vp, length, flags, cred, td)
vnode_pager_setsize(vp, length);
flags |= BA_CLRBUF;
error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp);
- if (error)
+ if (error) {
+ vnode_pager_setsize(vp, osize);
return (error);
+ }
ip->i_size = length;
DIP_SET(ip, i_size, length);
if (bp->b_bufsize == fs->fs_bsize)
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 563473c..b9ad090 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -641,6 +641,7 @@ ffs_mountfs(devvp, mp, td)
VOP_UNLOCK(devvp, 0);
if (error)
return (error);
+ dev_ref(dev);
if (devvp->v_rdev->si_iosize_max != 0)
mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
if (mp->mnt_iosize_max > MAXPHYS)
@@ -921,6 +922,7 @@ out:
free(ump, M_UFSMNT);
mp->mnt_data = NULL;
}
+ dev_rel(dev);
return (error);
}
@@ -1030,6 +1032,9 @@ ffs_unmount(mp, mntflags, td)
struct ufsmount *ump = VFSTOUFS(mp);
struct fs *fs;
int error, flags, susp;
+#ifdef UFS_EXTATTR
+ int e_restart;
+#endif
flags = 0;
fs = ump->um_fs;
@@ -1043,8 +1048,10 @@ ffs_unmount(mp, mntflags, td)
if (error != EOPNOTSUPP)
printf("ffs_unmount: ufs_extattr_stop returned %d\n",
error);
+ e_restart = 0;
} else {
ufs_extattr_uepm_destroy(&ump->um_extattr);
+ e_restart = 1;
}
#endif
if (susp) {
@@ -1102,6 +1109,7 @@ ffs_unmount(mp, mntflags, td)
g_topology_unlock();
PICKUP_GIANT();
vrele(ump->um_devvp);
+ dev_rel(ump->um_dev);
mtx_destroy(UFS_MTX(ump));
if (mp->mnt_gjprovider != NULL) {
free(mp->mnt_gjprovider, M_UFSMNT);
@@ -1121,6 +1129,15 @@ fail:
vfs_write_resume(mp);
vn_start_write(NULL, &mp, V_WAIT);
}
+#ifdef UFS_EXTATTR
+ if (e_restart) {
+ ufs_extattr_uepm_init(&ump->um_extattr);
+#ifdef UFS_EXTATTR_AUTOSTART
+ (void) ufs_extattr_autostart(mp, td);
+#endif
+ }
+#endif
+
return (error);
}
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 38dc2b6..ca2efa6 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -723,8 +723,10 @@ ffs_write(ap)
/* XXX is uio->uio_offset the right thing here? */
error = UFS_BALLOC(vp, uio->uio_offset, xfersize,
ap->a_cred, flags, &bp);
- if (error != 0)
+ if (error != 0) {
+ vnode_pager_setsize(vp, ip->i_size);
break;
+ }
/*
* If the buffer is not valid we have to clear out any
* garbage data from the pages instantiated for the buffer.
@@ -1004,14 +1006,6 @@ ffs_extread(struct vnode *vp, struct uio *uio, int ioflag)
bqrelse(bp);
}
}
-
- if ((error == 0 || uio->uio_resid != orig_resid) &&
- (vp->v_mount->mnt_flag & MNT_NOATIME) == 0 &&
- (ip->i_flag & IN_ACCESS) == 0) {
- VI_LOCK(vp);
- ip->i_flag |= IN_ACCESS;
- VI_UNLOCK(vp);
- }
return (error);
}
@@ -1117,7 +1111,7 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred)
bdwrite(bp);
if (error || xfersize == 0)
break;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
+ ip->i_flag |= IN_CHANGE;
}
/*
* If we successfully wrote any data, and we are not the superuser
diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c
index 0eacb58..3b6d5e1 100644
--- a/sys/ufs/ufs/ufs_dirhash.c
+++ b/sys/ufs/ufs/ufs_dirhash.c
@@ -126,6 +126,18 @@ static struct mtx ufsdirhash_mtx;
* free a dirhash structure that was recycled by ufsdirhash_recycle().
*
* The dirhash lock may be held across io operations.
+ *
+ * WITNESS reports a lock order reversal between the "bufwait" lock
+ * and the "dirhash" lock. However, this specific reversal will not
+ * cause a deadlock. To get a deadlock, one would have to lock a
+ * buffer followed by the dirhash while a second thread locked a
+ * buffer while holding the dirhash lock. The second order can happen
+ * under a shared or exclusive vnode lock for the associated directory
+ * in lookup(). The first order, however, can only happen under an
+ * exclusive vnode lock (e.g. unlink(), rename(), etc.). Thus, for
+ * a thread to be doing a "bufwait" -> "dirhash" order, it has to hold
+ * an exclusive vnode lock. That exclusive vnode lock will prevent
+ * any other threads from doing a "dirhash" -> "bufwait" order.
*/
static void
diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c
index b991920..d034bee 100644
--- a/sys/ufs/ufs/ufs_extattr.c
+++ b/sys/ufs/ufs/ufs_extattr.c
@@ -93,6 +93,10 @@ static int ufs_extattr_set(struct vnode *vp, int attrnamespace,
struct thread *td);
static int ufs_extattr_rm(struct vnode *vp, int attrnamespace,
const char *name, struct ucred *cred, struct thread *td);
+static int ufs_extattr_autostart_locked(struct mount *mp,
+ struct thread *td);
+static int ufs_extattr_start_locked(struct ufsmount *ump,
+ struct thread *td);
/*
* Per-FS attribute lock protecting attribute operations.
@@ -208,24 +212,22 @@ ufs_extattr_start(struct mount *mp, struct thread *td)
ump = VFSTOUFS(mp);
ufs_extattr_uepm_lock(ump, td);
+ error = ufs_extattr_start_locked(ump, td);
+ ufs_extattr_uepm_unlock(ump, td);
+ return (error);
+}
- if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_INITIALIZED)) {
- error = EOPNOTSUPP;
- goto unlock;
- }
- if (ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED) {
- error = EBUSY;
- goto unlock;
- }
+static int
+ufs_extattr_start_locked(struct ufsmount *ump, struct thread *td)
+{
+ if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_INITIALIZED))
+ return (EOPNOTSUPP);
+ if (ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)
+ return (EBUSY);
ump->um_extattr.uepm_flags |= UFS_EXTATTR_UEPM_STARTED;
-
ump->um_extattr.uepm_ucred = crhold(td->td_ucred);
-
-unlock:
- ufs_extattr_uepm_unlock(ump, td);
-
- return (error);
+ return (0);
}
#ifdef UFS_EXTATTR_AUTOSTART
@@ -448,6 +450,19 @@ ufs_extattr_iterate_directory(struct ufsmount *ump, struct vnode *dvp,
int
ufs_extattr_autostart(struct mount *mp, struct thread *td)
{
+ struct ufsmount *ump;
+ int error;
+
+ ump = VFSTOUFS(mp);
+ ufs_extattr_uepm_lock(ump, td);
+ error = ufs_extattr_autostart_locked(mp, td);
+ ufs_extattr_uepm_unlock(ump, td);
+ return (error);
+}
+
+static int
+ufs_extattr_autostart_locked(struct mount *mp, struct thread *td)
+{
struct vnode *rvp, *attr_dvp, *attr_system_dvp, *attr_user_dvp;
struct ufsmount *ump = VFSTOUFS(mp);
int error;
@@ -491,7 +506,7 @@ ufs_extattr_autostart(struct mount *mp, struct thread *td)
goto return_vput_attr_dvp;
}
- error = ufs_extattr_start(mp, td);
+ error = ufs_extattr_start_locked(ump, td);
if (error) {
printf("ufs_extattr_autostart: ufs_extattr_start failed (%d)\n",
error);
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 65ab0da..bc11a6a 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -157,7 +157,6 @@ ufs_lookup(ap)
int nameiop = cnp->cn_nameiop;
ino_t ino;
int ltype;
- struct mount *mp;
bp = NULL;
slotoffset = -1;
@@ -578,27 +577,7 @@ found:
*/
pdp = vdp;
if (flags & ISDOTDOT) {
- ltype = VOP_ISLOCKED(pdp);
- mp = pdp->v_mount;
- for (;;) {
- error = vfs_busy(mp, MBF_NOWAIT);
- if (error == 0)
- break;
- VOP_UNLOCK(pdp, 0);
- pause("ufs_dd", 1);
- vn_lock(pdp, ltype | LK_RETRY);
- if (pdp->v_iflag & VI_DOOMED)
- return (ENOENT);
- }
- VOP_UNLOCK(pdp, 0); /* race to get the inode */
- error = VFS_VGET(mp, ino, cnp->cn_lkflags, &tdp);
- vfs_unbusy(mp);
- vn_lock(pdp, ltype | LK_RETRY);
- if (pdp->v_iflag & VI_DOOMED) {
- if (error == 0)
- vput(tdp);
- error = ENOENT;
- }
+ error = vn_vget_ino(pdp, ino, cnp->cn_lkflags, &tdp);
if (error)
return (error);
*vpp = tdp;
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 7b639e8..675c55c 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -98,6 +98,7 @@ static vop_create_t ufs_create;
static vop_getattr_t ufs_getattr;
static vop_link_t ufs_link;
static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *);
+static vop_markatime_t ufs_markatime;
static vop_mkdir_t ufs_mkdir;
static vop_mknod_t ufs_mknod;
static vop_open_t ufs_open;
@@ -491,17 +492,6 @@ ufs_setattr(ap)
((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
return (EINVAL);
}
- /*
- * Mark for update the file's access time for vfs_mark_atime().
- * We are doing this here to avoid some of the checks done
- * below -- this operation is done by request of the kernel and
- * should bypass some security checks. Things like read-only
- * checks get handled by other levels (e.g., ffs_update()).
- */
- if (vap->va_vaflags & VA_MARK_ATIME) {
- ip->i_flag |= IN_ACCESS;
- return (0);
- }
if (vap->va_flags != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
@@ -663,6 +653,25 @@ ufs_setattr(ap)
}
/*
+ * Mark this file's access time for update for vfs_mark_atime(). This
+ * is called from execve() and mmap().
+ */
+static int
+ufs_markatime(ap)
+ struct vop_markatime_args /* {
+ struct vnode *a_vp;
+ } */ *ap;
+{
+ struct vnode *vp = ap->a_vp;
+ struct inode *ip = VTOI(vp);
+
+ VI_LOCK(vp);
+ ip->i_flag |= IN_ACCESS;
+ VI_UNLOCK(vp);
+ return (0);
+}
+
+/*
* Change the mode on a file.
* Inode must be locked before calling.
*/
@@ -2468,6 +2477,7 @@ struct vop_vector ufs_vnodeops = {
.vop_inactive = ufs_inactive,
.vop_link = ufs_link,
.vop_lookup = vfs_cache_lookup,
+ .vop_markatime = ufs_markatime,
.vop_mkdir = ufs_mkdir,
.vop_mknod = ufs_mknod,
.vop_open = ufs_open,
@@ -2507,6 +2517,7 @@ struct vop_vector ufs_fifoops = {
.vop_getattr = ufs_getattr,
.vop_inactive = ufs_inactive,
.vop_kqfilter = ufsfifo_kqfilter,
+ .vop_markatime = ufs_markatime,
.vop_print = ufs_print,
.vop_read = VOP_PANIC,
.vop_reclaim = ufs_reclaim,
diff --git a/sys/vm/uma.h b/sys/vm/uma.h
index 81f08d8..c044824 100644
--- a/sys/vm/uma.h
+++ b/sys/vm/uma.h
@@ -205,6 +205,17 @@ uma_zone_t uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor,
uma_init zinit, uma_fini zfini, uma_zone_t master);
/*
+ * Add a second master to a secondary zone. This provides multiple data
+ * backends for objects with the same size. Both masters must have
+ * compatible allocation flags. Presently, UMA_ZONE_MALLOC type zones are
+ * the only supported.
+ *
+ * Returns:
+ * Error on failure, 0 on success.
+ */
+int uma_zsecond_add(uma_zone_t zone, uma_zone_t master);
+
+/*
* Definitions for uma_zcreate flags
*
* These flags share space with UMA_ZFLAGs in uma_int.h. Be careful not to
@@ -230,6 +241,22 @@ uma_zone_t uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor,
#define UMA_ZONE_SECONDARY 0x0200 /* Zone is a Secondary Zone */
#define UMA_ZONE_REFCNT 0x0400 /* Allocate refcnts in slabs */
#define UMA_ZONE_MAXBUCKET 0x0800 /* Use largest buckets */
+#define UMA_ZONE_CACHESPREAD 0x1000 /*
+ * Spread memory start locations across
+ * all possible cache lines. May
+ * require many virtually contiguous
+ * backend pages and can fail early.
+ */
+#define UMA_ZONE_VTOSLAB 0x2000 /* Zone uses vtoslab for lookup. */
+
+/*
+ * These flags are shared between the keg and zone. In zones wishing to add
+ * new kegs these flags must be compatible. Some are determined based on
+ * physical parameters of the request and may not be provided by the consumer.
+ */
+#define UMA_ZONE_INHERIT \
+ (UMA_ZONE_OFFPAGE | UMA_ZONE_MALLOC | UMA_ZONE_HASH | \
+ UMA_ZONE_REFCNT | UMA_ZONE_VTOSLAB)
/* Definitions for align */
#define UMA_ALIGN_PTR (sizeof(void *) - 1) /* Alignment fit for ptr */
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index d9e1d8c..9841a64 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003, 2004, 2005 Jeffrey Roberson <jeff@FreeBSD.org>
+ * Copyright (c) 2002-2005, 2009 Jeffrey Roberson <jeff@FreeBSD.org>
* Copyright (c) 2004, 2005 Bosko Milekic <bmilekic@FreeBSD.org>
* Copyright (c) 2004-2006 Robert N. M. Watson
* All rights reserved.
@@ -112,7 +112,7 @@ static uma_zone_t slabrefzone; /* With refcounters (for UMA_ZONE_REFCNT) */
static uma_zone_t hashzone;
/* The boot-time adjusted value for cache line alignment. */
-static int uma_align_cache = 16 - 1;
+static int uma_align_cache = 64 - 1;
static MALLOC_DEFINE(M_UMAHASH, "UMAHash", "UMA Hash Buckets");
@@ -212,7 +212,7 @@ static void *obj_alloc(uma_zone_t, int, u_int8_t *, int);
static void *page_alloc(uma_zone_t, int, u_int8_t *, int);
static void *startup_alloc(uma_zone_t, int, u_int8_t *, int);
static void page_free(void *, int, u_int8_t);
-static uma_slab_t slab_zalloc(uma_zone_t, int);
+static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int);
static void cache_drain(uma_zone_t);
static void bucket_drain(uma_zone_t, uma_bucket_t);
static void bucket_cache_drain(uma_zone_t zone);
@@ -221,8 +221,8 @@ static void keg_dtor(void *, int, void *);
static int zone_ctor(void *, int, void *, int);
static void zone_dtor(void *, int, void *);
static int zero_init(void *, int, int);
-static void zone_small_init(uma_zone_t zone);
-static void zone_large_init(uma_zone_t zone);
+static void keg_small_init(uma_keg_t keg);
+static void keg_large_init(uma_keg_t keg);
static void zone_foreach(void (*zfunc)(uma_zone_t));
static void zone_timeout(uma_zone_t zone);
static int hash_alloc(struct uma_hash *);
@@ -230,19 +230,22 @@ static int hash_expand(struct uma_hash *, struct uma_hash *);
static void hash_free(struct uma_hash *hash);
static void uma_timeout(void *);
static void uma_startup3(void);
-static void *uma_zalloc_internal(uma_zone_t, void *, int);
-static void uma_zfree_internal(uma_zone_t, void *, void *, enum zfreeskip,
+static void *zone_alloc_item(uma_zone_t, void *, int);
+static void zone_free_item(uma_zone_t, void *, void *, enum zfreeskip,
int);
static void bucket_enable(void);
static void bucket_init(void);
static uma_bucket_t bucket_alloc(int, int);
static void bucket_free(uma_bucket_t);
static void bucket_zone_drain(void);
-static int uma_zalloc_bucket(uma_zone_t zone, int flags);
-static uma_slab_t uma_zone_slab(uma_zone_t zone, int flags);
-static void *uma_slab_alloc(uma_zone_t zone, uma_slab_t slab);
-static uma_zone_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit,
+static int zone_alloc_bucket(uma_zone_t zone, int flags);
+static uma_slab_t zone_fetch_slab(uma_zone_t zone, uma_keg_t last, int flags);
+static uma_slab_t zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int flags);
+static void *slab_alloc_item(uma_zone_t zone, uma_slab_t slab);
+static uma_keg_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit,
uma_fini fini, int align, u_int32_t flags);
+static inline void zone_relock(uma_zone_t zone, uma_keg_t keg);
+static inline void keg_relock(uma_keg_t keg, uma_zone_t zone);
void uma_print_zone(uma_zone_t);
void uma_print_stats(void);
@@ -291,7 +294,8 @@ bucket_init(void)
size = roundup(sizeof(struct uma_bucket), sizeof(void *));
size += sizeof(void *) * ubz->ubz_entries;
ubz->ubz_zone = uma_zcreate(ubz->ubz_name, size,
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
+ UMA_ZFLAG_INTERNAL | UMA_ZFLAG_BUCKET);
for (; i <= ubz->ubz_entries; i += (1 << BUCKET_SHIFT))
bucket_size[i >> BUCKET_SHIFT] = j;
}
@@ -326,7 +330,7 @@ bucket_alloc(int entries, int bflags)
return (NULL);
ubz = bucket_zone_lookup(entries);
- bucket = uma_zalloc_internal(ubz->ubz_zone, NULL, bflags);
+ bucket = zone_alloc_item(ubz->ubz_zone, NULL, bflags);
if (bucket) {
#ifdef INVARIANTS
bzero(bucket->ub_bucket, sizeof(void *) * ubz->ubz_entries);
@@ -344,7 +348,7 @@ bucket_free(uma_bucket_t bucket)
struct uma_bucket_zone *ubz;
ubz = bucket_zone_lookup(bucket->ub_entries);
- uma_zfree_internal(ubz->ubz_zone, bucket, NULL, SKIP_NONE,
+ zone_free_item(ubz->ubz_zone, bucket, NULL, SKIP_NONE,
ZFREE_STATFREE);
}
@@ -357,6 +361,21 @@ bucket_zone_drain(void)
zone_drain(ubz->ubz_zone);
}
+static inline uma_keg_t
+zone_first_keg(uma_zone_t zone)
+{
+
+ return (LIST_FIRST(&zone->uz_kegs)->kl_keg);
+}
+
+static void
+zone_foreach_keg(uma_zone_t zone, void (*kegfn)(uma_keg_t))
+{
+ uma_klink_t klink;
+
+ LIST_FOREACH(klink, &zone->uz_kegs, kl_link)
+ kegfn(klink->kl_keg);
+}
/*
* Routine called by timeout which is used to fire off some time interval
@@ -382,29 +401,20 @@ uma_timeout(void *unused)
* Routine to perform timeout driven calculations. This expands the
* hashes and does per cpu statistics aggregation.
*
- * Arguments:
- * zone The zone to operate on
- *
- * Returns:
- * Nothing
+ * Returns nothing.
*/
static void
-zone_timeout(uma_zone_t zone)
+keg_timeout(uma_keg_t keg)
{
- uma_keg_t keg;
- u_int64_t alloc;
-
- keg = zone->uz_keg;
- alloc = 0;
+ KEG_LOCK(keg);
/*
- * Expand the zone hash table.
+ * Expand the keg hash table.
*
* This is done if the number of slabs is larger than the hash size.
* What I'm trying to do here is completely reduce collisions. This
* may be a little aggressive. Should I allow for two collisions max?
*/
- ZONE_LOCK(zone);
if (keg->uk_flags & UMA_ZONE_HASH &&
keg->uk_pages / keg->uk_ppera >= keg->uk_hash.uh_hashsize) {
struct uma_hash newhash;
@@ -413,14 +423,14 @@ zone_timeout(uma_zone_t zone)
/*
* This is so involved because allocating and freeing
- * while the zone lock is held will lead to deadlock.
+ * while the keg lock is held will lead to deadlock.
* I have to do everything in stages and check for
* races.
*/
newhash = keg->uk_hash;
- ZONE_UNLOCK(zone);
+ KEG_UNLOCK(keg);
ret = hash_alloc(&newhash);
- ZONE_LOCK(zone);
+ KEG_LOCK(keg);
if (ret) {
if (hash_expand(&keg->uk_hash, &newhash)) {
oldhash = keg->uk_hash;
@@ -428,12 +438,19 @@ zone_timeout(uma_zone_t zone)
} else
oldhash = newhash;
- ZONE_UNLOCK(zone);
+ KEG_UNLOCK(keg);
hash_free(&oldhash);
- ZONE_LOCK(zone);
+ KEG_LOCK(keg);
}
}
- ZONE_UNLOCK(zone);
+ KEG_UNLOCK(keg);
+}
+
+static void
+zone_timeout(uma_zone_t zone)
+{
+
+ zone_foreach_keg(zone, &keg_timeout);
}
/*
@@ -462,7 +479,7 @@ hash_alloc(struct uma_hash *hash)
M_UMAHASH, M_NOWAIT);
} else {
alloc = sizeof(hash->uh_slab_hash[0]) * UMA_HASH_SIZE_INIT;
- hash->uh_slab_hash = uma_zalloc_internal(hashzone, NULL,
+ hash->uh_slab_hash = zone_alloc_item(hashzone, NULL,
M_WAITOK);
hash->uh_hashsize = UMA_HASH_SIZE_INIT;
}
@@ -535,7 +552,7 @@ hash_free(struct uma_hash *hash)
if (hash->uh_slab_hash == NULL)
return;
if (hash->uh_hashsize == UMA_HASH_SIZE_INIT)
- uma_zfree_internal(hashzone,
+ zone_free_item(hashzone,
hash->uh_slab_hash, NULL, SKIP_NONE, ZFREE_STATFREE);
else
free(hash->uh_slab_hash, M_UMAHASH);
@@ -555,20 +572,11 @@ hash_free(struct uma_hash *hash)
static void
bucket_drain(uma_zone_t zone, uma_bucket_t bucket)
{
- uma_slab_t slab;
- int mzone;
void *item;
if (bucket == NULL)
return;
- slab = NULL;
- mzone = 0;
-
- /* We have to lookup the slab again for malloc.. */
- if (zone->uz_keg->uk_flags & UMA_ZONE_MALLOC)
- mzone = 1;
-
while (bucket->ub_cnt > 0) {
bucket->ub_cnt--;
item = bucket->ub_bucket[bucket->ub_cnt];
@@ -577,15 +585,7 @@ bucket_drain(uma_zone_t zone, uma_bucket_t bucket)
KASSERT(item != NULL,
("bucket_drain: botched ptr, item is NULL"));
#endif
- /*
- * This is extremely inefficient. The slab pointer was passed
- * to uma_zfree_arg, but we lost it because the buckets don't
- * hold them. This will go away when free() gets a size passed
- * to it.
- */
- if (mzone)
- slab = vtoslab((vm_offset_t)item & (~UMA_SLAB_MASK));
- uma_zfree_internal(zone, item, slab, SKIP_DTOR, 0);
+ zone_free_item(zone, item, NULL, SKIP_DTOR, 0);
}
}
@@ -665,42 +665,32 @@ bucket_cache_drain(uma_zone_t zone)
}
/*
- * Frees pages from a zone back to the system. This is done on demand from
+ * Frees pages from a keg back to the system. This is done on demand from
* the pageout daemon.
*
- * Arguments:
- * zone The zone to free pages from
- * all Should we drain all items?
- *
- * Returns:
- * Nothing.
+ * Returns nothing.
*/
-void
-zone_drain(uma_zone_t zone)
+static void
+keg_drain(uma_keg_t keg)
{
struct slabhead freeslabs = { 0 };
- uma_keg_t keg;
uma_slab_t slab;
uma_slab_t n;
u_int8_t flags;
u_int8_t *mem;
int i;
- keg = zone->uz_keg;
-
/*
- * We don't want to take pages from statically allocated zones at this
+ * We don't want to take pages from statically allocated kegs at this
* time
*/
if (keg->uk_flags & UMA_ZONE_NOFREE || keg->uk_freef == NULL)
return;
- ZONE_LOCK(zone);
-
#ifdef UMA_DEBUG
- printf("%s free items: %u\n", zone->uz_name, keg->uk_free);
+ printf("%s free items: %u\n", keg->uk_name, keg->uk_free);
#endif
- bucket_cache_drain(zone);
+ KEG_LOCK(keg);
if (keg->uk_free == 0)
goto finished;
@@ -726,7 +716,7 @@ zone_drain(uma_zone_t zone)
slab = n;
}
finished:
- ZONE_UNLOCK(zone);
+ KEG_UNLOCK(keg);
while ((slab = SLIST_FIRST(&freeslabs)) != NULL) {
SLIST_REMOVE(&freeslabs, slab, uma_slab, us_hlink);
@@ -738,8 +728,7 @@ finished:
flags = slab->us_flags;
mem = slab->us_data;
- if ((keg->uk_flags & UMA_ZONE_MALLOC) ||
- (keg->uk_flags & UMA_ZONE_REFCNT)) {
+ if (keg->uk_flags & UMA_ZONE_VTOSLAB) {
vm_object_t obj;
if (flags & UMA_SLAB_KMEM)
@@ -753,21 +742,61 @@ finished:
obj);
}
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
- uma_zfree_internal(keg->uk_slabzone, slab, NULL,
+ zone_free_item(keg->uk_slabzone, slab, NULL,
SKIP_NONE, ZFREE_STATFREE);
#ifdef UMA_DEBUG
printf("%s: Returning %d bytes.\n",
- zone->uz_name, UMA_SLAB_SIZE * keg->uk_ppera);
+ keg->uk_name, UMA_SLAB_SIZE * keg->uk_ppera);
#endif
keg->uk_freef(mem, UMA_SLAB_SIZE * keg->uk_ppera, flags);
}
}
+static void
+zone_drain_wait(uma_zone_t zone, int waitok)
+{
+
+ /*
+ * Set draining to interlock with zone_dtor() so we can release our
+ * locks as we go. Only dtor() should do a WAITOK call since it
+ * is the only call that knows the structure will still be available
+ * when it wakes up.
+ */
+ ZONE_LOCK(zone);
+ while (zone->uz_flags & UMA_ZFLAG_DRAINING) {
+ if (waitok == M_NOWAIT)
+ goto out;
+ mtx_unlock(&uma_mtx);
+ msleep(zone, zone->uz_lock, PVM, "zonedrain", 1);
+ mtx_lock(&uma_mtx);
+ }
+ zone->uz_flags |= UMA_ZFLAG_DRAINING;
+ bucket_cache_drain(zone);
+ ZONE_UNLOCK(zone);
+ /*
+ * The DRAINING flag protects us from being freed while
+ * we're running. Normally the uma_mtx would protect us but we
+ * must be able to release and acquire the right lock for each keg.
+ */
+ zone_foreach_keg(zone, &keg_drain);
+ ZONE_LOCK(zone);
+ zone->uz_flags &= ~UMA_ZFLAG_DRAINING;
+ wakeup(zone);
+out:
+ ZONE_UNLOCK(zone);
+}
+
+void
+zone_drain(uma_zone_t zone)
+{
+
+ zone_drain_wait(zone, M_NOWAIT);
+}
+
/*
- * Allocate a new slab for a zone. This does not insert the slab onto a list.
+ * Allocate a new slab for a keg. This does not insert the slab onto a list.
*
* Arguments:
- * zone The zone to allocate slabs for
* wait Shall we wait?
*
* Returns:
@@ -775,27 +804,28 @@ finished:
* caller specified M_NOWAIT.
*/
static uma_slab_t
-slab_zalloc(uma_zone_t zone, int wait)
+keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
{
uma_slabrefcnt_t slabref;
+ uma_alloc allocf;
uma_slab_t slab;
- uma_keg_t keg;
u_int8_t *mem;
u_int8_t flags;
int i;
+ mtx_assert(&keg->uk_lock, MA_OWNED);
slab = NULL;
- keg = zone->uz_keg;
#ifdef UMA_DEBUG
- printf("slab_zalloc: Allocating a new slab for %s\n", zone->uz_name);
+ printf("slab_zalloc: Allocating a new slab for %s\n", keg->uk_name);
#endif
- ZONE_UNLOCK(zone);
+ allocf = keg->uk_allocf;
+ KEG_UNLOCK(keg);
if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
- slab = uma_zalloc_internal(keg->uk_slabzone, NULL, wait);
+ slab = zone_alloc_item(keg->uk_slabzone, NULL, wait);
if (slab == NULL) {
- ZONE_LOCK(zone);
+ KEG_LOCK(keg);
return NULL;
}
}
@@ -812,13 +842,13 @@ slab_zalloc(uma_zone_t zone, int wait)
else
wait &= ~M_ZERO;
- mem = keg->uk_allocf(zone, keg->uk_ppera * UMA_SLAB_SIZE,
- &flags, wait);
+ /* zone is passed for legacy reasons. */
+ mem = allocf(zone, keg->uk_ppera * UMA_SLAB_SIZE, &flags, wait);
if (mem == NULL) {
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
- uma_zfree_internal(keg->uk_slabzone, slab, NULL,
+ zone_free_item(keg->uk_slabzone, slab, NULL,
SKIP_NONE, ZFREE_STATFREE);
- ZONE_LOCK(zone);
+ KEG_LOCK(keg);
return (NULL);
}
@@ -826,8 +856,7 @@ slab_zalloc(uma_zone_t zone, int wait)
if (!(keg->uk_flags & UMA_ZONE_OFFPAGE))
slab = (uma_slab_t )(mem + keg->uk_pgoff);
- if ((keg->uk_flags & UMA_ZONE_MALLOC) ||
- (keg->uk_flags & UMA_ZONE_REFCNT))
+ if (keg->uk_flags & UMA_ZONE_VTOSLAB)
for (i = 0; i < keg->uk_ppera; i++)
vsetslab((vm_offset_t)mem + (i * PAGE_SIZE), slab);
@@ -860,8 +889,7 @@ slab_zalloc(uma_zone_t zone, int wait)
(keg->uk_rsize * i),
keg->uk_size);
}
- if ((keg->uk_flags & UMA_ZONE_MALLOC) ||
- (keg->uk_flags & UMA_ZONE_REFCNT)) {
+ if (keg->uk_flags & UMA_ZONE_VTOSLAB) {
vm_object_t obj;
if (flags & UMA_SLAB_KMEM)
@@ -875,15 +903,15 @@ slab_zalloc(uma_zone_t zone, int wait)
(i * PAGE_SIZE), obj);
}
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
- uma_zfree_internal(keg->uk_slabzone, slab,
+ zone_free_item(keg->uk_slabzone, slab,
NULL, SKIP_NONE, ZFREE_STATFREE);
keg->uk_freef(mem, UMA_SLAB_SIZE * keg->uk_ppera,
flags);
- ZONE_LOCK(zone);
+ KEG_LOCK(keg);
return (NULL);
}
}
- ZONE_LOCK(zone);
+ KEG_LOCK(keg);
if (keg->uk_flags & UMA_ZONE_HASH)
UMA_HASH_INSERT(&keg->uk_hash, slab, mem);
@@ -905,7 +933,7 @@ startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
uma_keg_t keg;
uma_slab_t tmps;
- keg = zone->uz_keg;
+ keg = zone_first_keg(zone);
/*
* Check our small startup cache to see if it has pages remaining.
@@ -935,7 +963,6 @@ startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
* Allocates a number of pages from the system
*
* Arguments:
- * zone Unused
* bytes The number of bytes requested
* wait Shall we wait?
*
@@ -958,7 +985,6 @@ page_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
* Allocates a number of pages from within an object
*
* Arguments:
- * zone Unused
* bytes The number of bytes requested
* wait Shall we wait?
*
@@ -973,8 +999,10 @@ obj_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
vm_offset_t retkva, zkva;
vm_page_t p;
int pages, startpages;
+ uma_keg_t keg;
- object = zone->uz_keg->uk_obj;
+ keg = zone_first_keg(zone);
+ object = keg->uk_obj;
retkva = 0;
/*
@@ -984,7 +1012,7 @@ obj_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
p = TAILQ_LAST(&object->memq, pglist);
pages = p != NULL ? p->pindex + 1 : 0;
startpages = pages;
- zkva = zone->uz_keg->uk_kva + pages * PAGE_SIZE;
+ zkva = keg->uk_kva + pages * PAGE_SIZE;
for (; bytes > 0; bytes -= PAGE_SIZE) {
p = vm_page_alloc(object, pages,
VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED);
@@ -1052,25 +1080,23 @@ zero_init(void *mem, int size, int flags)
}
/*
- * Finish creating a small uma zone. This calculates ipers, and the zone size.
+ * Finish creating a small uma keg. This calculates ipers, and the keg size.
*
* Arguments
- * zone The zone we should initialize
+ * keg The zone we should initialize
*
* Returns
* Nothing
*/
static void
-zone_small_init(uma_zone_t zone)
+keg_small_init(uma_keg_t keg)
{
- uma_keg_t keg;
u_int rsize;
u_int memused;
u_int wastedspace;
u_int shsize;
- keg = zone->uz_keg;
- KASSERT(keg != NULL, ("Keg is null in zone_small_init"));
+ KASSERT(keg != NULL, ("Keg is null in keg_small_init"));
rsize = keg->uk_size;
if (rsize < UMA_SMALLEST_UNIT)
@@ -1090,7 +1116,7 @@ zone_small_init(uma_zone_t zone)
}
keg->uk_ipers = (UMA_SLAB_SIZE - shsize) / rsize;
- KASSERT(keg->uk_ipers != 0, ("zone_small_init: ipers is 0"));
+ KASSERT(keg->uk_ipers != 0, ("keg_small_init: ipers is 0"));
memused = keg->uk_ipers * rsize + shsize;
wastedspace = UMA_SLAB_SIZE - memused;
@@ -1109,44 +1135,41 @@ zone_small_init(uma_zone_t zone)
(keg->uk_ipers < (UMA_SLAB_SIZE / keg->uk_rsize))) {
keg->uk_ipers = UMA_SLAB_SIZE / keg->uk_rsize;
KASSERT(keg->uk_ipers <= 255,
- ("zone_small_init: keg->uk_ipers too high!"));
+ ("keg_small_init: keg->uk_ipers too high!"));
#ifdef UMA_DEBUG
printf("UMA decided we need offpage slab headers for "
- "zone: %s, calculated wastedspace = %d, "
+ "keg: %s, calculated wastedspace = %d, "
"maximum wasted space allowed = %d, "
"calculated ipers = %d, "
- "new wasted space = %d\n", zone->uz_name, wastedspace,
+ "new wasted space = %d\n", keg->uk_name, wastedspace,
UMA_MAX_WASTE, keg->uk_ipers,
UMA_SLAB_SIZE - keg->uk_ipers * keg->uk_rsize);
#endif
keg->uk_flags |= UMA_ZONE_OFFPAGE;
- if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0)
+ if ((keg->uk_flags & UMA_ZONE_VTOSLAB) == 0)
keg->uk_flags |= UMA_ZONE_HASH;
}
}
/*
- * Finish creating a large (> UMA_SLAB_SIZE) uma zone. Just give in and do
+ * Finish creating a large (> UMA_SLAB_SIZE) uma kegs. Just give in and do
* OFFPAGE for now. When I can allow for more dynamic slab sizes this will be
* more complicated.
*
* Arguments
- * zone The zone we should initialize
+ * keg The keg we should initialize
*
* Returns
* Nothing
*/
static void
-zone_large_init(uma_zone_t zone)
+keg_large_init(uma_keg_t keg)
{
- uma_keg_t keg;
int pages;
- keg = zone->uz_keg;
-
- KASSERT(keg != NULL, ("Keg is null in zone_large_init"));
+ KASSERT(keg != NULL, ("Keg is null in keg_large_init"));
KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0,
- ("zone_large_init: Cannot large-init a UMA_ZFLAG_CACHEONLY zone"));
+ ("keg_large_init: Cannot large-init a UMA_ZFLAG_CACHEONLY keg"));
pages = keg->uk_size / UMA_SLAB_SIZE;
@@ -1158,12 +1181,44 @@ zone_large_init(uma_zone_t zone)
keg->uk_ipers = 1;
keg->uk_flags |= UMA_ZONE_OFFPAGE;
- if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0)
+ if ((keg->uk_flags & UMA_ZONE_VTOSLAB) == 0)
keg->uk_flags |= UMA_ZONE_HASH;
keg->uk_rsize = keg->uk_size;
}
+static void
+keg_cachespread_init(uma_keg_t keg)
+{
+ int alignsize;
+ int trailer;
+ int pages;
+ int rsize;
+
+ alignsize = keg->uk_align + 1;
+ rsize = keg->uk_size;
+ /*
+ * We want one item to start on every align boundary in a page. To
+ * do this we will span pages. We will also extend the item by the
+ * size of align if it is an even multiple of align. Otherwise, it
+ * would fall on the same boundary every time.
+ */
+ if (rsize & keg->uk_align)
+ rsize = (rsize & ~keg->uk_align) + alignsize;
+ if ((rsize & alignsize) == 0)
+ rsize += alignsize;
+ trailer = rsize - keg->uk_size;
+ pages = (rsize * (PAGE_SIZE / alignsize)) / PAGE_SIZE;
+ pages = MIN(pages, (128 * 1024) / PAGE_SIZE);
+ keg->uk_rsize = rsize;
+ keg->uk_ppera = pages;
+ keg->uk_ipers = ((pages * PAGE_SIZE) + trailer) / rsize;
+ keg->uk_flags |= UMA_ZONE_OFFPAGE | UMA_ZONE_VTOSLAB;
+ KASSERT(keg->uk_ipers <= uma_max_ipers,
+ ("keg_small_init: keg->uk_ipers too high(%d) increase max_ipers",
+ keg->uk_ipers));
+}
+
/*
* Keg header ctor. This initializes all fields, locks, etc. And inserts
* the keg onto the global keg list.
@@ -1195,7 +1250,7 @@ keg_ctor(void *mem, int size, void *udata, int flags)
* The master zone is passed to us at keg-creation time.
*/
zone = arg->zone;
- zone->uz_keg = keg;
+ keg->uk_name = zone->uz_name;
if (arg->flags & UMA_ZONE_VM)
keg->uk_flags |= UMA_ZFLAG_CACHEONLY;
@@ -1203,24 +1258,31 @@ keg_ctor(void *mem, int size, void *udata, int flags)
if (arg->flags & UMA_ZONE_ZINIT)
keg->uk_init = zero_init;
+ if (arg->flags & UMA_ZONE_REFCNT || arg->flags & UMA_ZONE_MALLOC)
+ keg->uk_flags |= UMA_ZONE_VTOSLAB;
+
/*
* The +UMA_FRITM_SZ added to uk_size is to account for the
- * linkage that is added to the size in zone_small_init(). If
+ * linkage that is added to the size in keg_small_init(). If
* we don't account for this here then we may end up in
- * zone_small_init() with a calculated 'ipers' of 0.
+ * keg_small_init() with a calculated 'ipers' of 0.
*/
if (keg->uk_flags & UMA_ZONE_REFCNT) {
- if ((keg->uk_size+UMA_FRITMREF_SZ) >
+ if (keg->uk_flags & UMA_ZONE_CACHESPREAD)
+ keg_cachespread_init(keg);
+ else if ((keg->uk_size+UMA_FRITMREF_SZ) >
(UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt)))
- zone_large_init(zone);
+ keg_large_init(keg);
else
- zone_small_init(zone);
+ keg_small_init(keg);
} else {
- if ((keg->uk_size+UMA_FRITM_SZ) >
+ if (keg->uk_flags & UMA_ZONE_CACHESPREAD)
+ keg_cachespread_init(keg);
+ else if ((keg->uk_size+UMA_FRITM_SZ) >
(UMA_SLAB_SIZE - sizeof(struct uma_slab)))
- zone_large_init(zone);
+ keg_large_init(keg);
else
- zone_small_init(zone);
+ keg_small_init(keg);
}
if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
@@ -1244,14 +1306,12 @@ keg_ctor(void *mem, int size, void *udata, int flags)
}
/*
- * Initialize keg's lock (shared among zones) through
- * Master zone
+ * Initialize keg's lock (shared among zones).
*/
- zone->uz_lock = &keg->uk_lock;
if (arg->flags & UMA_ZONE_MTXCLASS)
- ZONE_LOCK_INIT(zone, 1);
+ KEG_LOCK_INIT(keg, 1);
else
- ZONE_LOCK_INIT(zone, 0);
+ KEG_LOCK_INIT(keg, 0);
/*
* If we're putting the slab header in the actual page we need to
@@ -1300,10 +1360,10 @@ keg_ctor(void *mem, int size, void *udata, int flags)
hash_alloc(&keg->uk_hash);
#ifdef UMA_DEBUG
- printf("%s(%p) size = %d ipers = %d ppera = %d pgoff = %d\n",
- zone->uz_name, zone,
- keg->uk_size, keg->uk_ipers,
- keg->uk_ppera, keg->uk_pgoff);
+ printf("UMA: %s(%p) size %d(%d) flags %d ipers %d ppera %d out %d free %d\n",
+ zone->uz_name, zone, keg->uk_size, keg->uk_rsize, keg->uk_flags,
+ keg->uk_ipers, keg->uk_ppera,
+ (keg->uk_ipers * keg->uk_pages) - keg->uk_free, keg->uk_free);
#endif
LIST_INSERT_HEAD(&keg->uk_zones, zone, uz_link);
@@ -1320,7 +1380,6 @@ keg_ctor(void *mem, int size, void *udata, int flags)
* Arguments/Returns follow uma_ctor specifications
* udata Actually uma_zctor_args
*/
-
static int
zone_ctor(void *mem, int size, void *udata, int flags)
{
@@ -1333,23 +1392,24 @@ zone_ctor(void *mem, int size, void *udata, int flags)
zone->uz_name = arg->name;
zone->uz_ctor = arg->ctor;
zone->uz_dtor = arg->dtor;
+ zone->uz_slab = zone_fetch_slab;
zone->uz_init = NULL;
zone->uz_fini = NULL;
zone->uz_allocs = 0;
zone->uz_frees = 0;
zone->uz_fails = 0;
zone->uz_fills = zone->uz_count = 0;
+ zone->uz_flags = 0;
+ keg = arg->keg;
if (arg->flags & UMA_ZONE_SECONDARY) {
KASSERT(arg->keg != NULL, ("Secondary zone on zero'd keg"));
- keg = arg->keg;
- zone->uz_keg = keg;
zone->uz_init = arg->uminit;
zone->uz_fini = arg->fini;
zone->uz_lock = &keg->uk_lock;
+ zone->uz_flags |= UMA_ZONE_SECONDARY;
mtx_lock(&uma_mtx);
ZONE_LOCK(zone);
- keg->uk_flags |= UMA_ZONE_SECONDARY;
LIST_FOREACH(z, &keg->uk_zones, uz_link) {
if (LIST_NEXT(z, uz_link) == NULL) {
LIST_INSERT_AFTER(z, zone, uz_link);
@@ -1358,9 +1418,9 @@ zone_ctor(void *mem, int size, void *udata, int flags)
}
ZONE_UNLOCK(zone);
mtx_unlock(&uma_mtx);
- } else if (arg->keg == NULL) {
- if (uma_kcreate(zone, arg->size, arg->uminit, arg->fini,
- arg->align, arg->flags) == NULL)
+ } else if (keg == NULL) {
+ if ((keg = uma_kcreate(zone, arg->size, arg->uminit, arg->fini,
+ arg->align, arg->flags)) == NULL)
return (ENOMEM);
} else {
struct uma_kctor_args karg;
@@ -1378,15 +1438,22 @@ zone_ctor(void *mem, int size, void *udata, int flags)
if (error)
return (error);
}
- keg = zone->uz_keg;
+ /*
+ * Link in the first keg.
+ */
+ zone->uz_klink.kl_keg = keg;
+ LIST_INSERT_HEAD(&zone->uz_kegs, &zone->uz_klink, kl_link);
zone->uz_lock = &keg->uk_lock;
+ zone->uz_size = keg->uk_size;
+ zone->uz_flags |= (keg->uk_flags &
+ (UMA_ZONE_INHERIT | UMA_ZFLAG_INHERIT));
/*
* Some internal zones don't have room allocated for the per cpu
* caches. If we're internal, bail out here.
*/
if (keg->uk_flags & UMA_ZFLAG_INTERNAL) {
- KASSERT((keg->uk_flags & UMA_ZONE_SECONDARY) == 0,
+ KASSERT((zone->uz_flags & UMA_ZONE_SECONDARY) == 0,
("Secondary zone requested UMA_ZFLAG_INTERNAL"));
return (0);
}
@@ -1413,18 +1480,17 @@ keg_dtor(void *arg, int size, void *udata)
uma_keg_t keg;
keg = (uma_keg_t)arg;
- mtx_lock(&keg->uk_lock);
+ KEG_LOCK(keg);
if (keg->uk_free != 0) {
printf("Freed UMA keg was not empty (%d items). "
" Lost %d pages of memory.\n",
keg->uk_free, keg->uk_pages);
}
- mtx_unlock(&keg->uk_lock);
+ KEG_UNLOCK(keg);
- if (keg->uk_flags & UMA_ZONE_HASH)
- hash_free(&keg->uk_hash);
+ hash_free(&keg->uk_hash);
- mtx_destroy(&keg->uk_lock);
+ KEG_LOCK_FINI(keg);
}
/*
@@ -1436,38 +1502,46 @@ keg_dtor(void *arg, int size, void *udata)
static void
zone_dtor(void *arg, int size, void *udata)
{
+ uma_klink_t klink;
uma_zone_t zone;
uma_keg_t keg;
zone = (uma_zone_t)arg;
- keg = zone->uz_keg;
+ keg = zone_first_keg(zone);
- if (!(keg->uk_flags & UMA_ZFLAG_INTERNAL))
+ if (!(zone->uz_flags & UMA_ZFLAG_INTERNAL))
cache_drain(zone);
mtx_lock(&uma_mtx);
- zone_drain(zone);
- if (keg->uk_flags & UMA_ZONE_SECONDARY) {
- LIST_REMOVE(zone, uz_link);
- /*
- * XXX there are some races here where
- * the zone can be drained but zone lock
- * released and then refilled before we
- * remove it... we dont care for now
- */
- ZONE_LOCK(zone);
- if (LIST_EMPTY(&keg->uk_zones))
- keg->uk_flags &= ~UMA_ZONE_SECONDARY;
- ZONE_UNLOCK(zone);
- mtx_unlock(&uma_mtx);
- } else {
+ LIST_REMOVE(zone, uz_link);
+ mtx_unlock(&uma_mtx);
+ /*
+ * XXX there are some races here where
+ * the zone can be drained but zone lock
+ * released and then refilled before we
+ * remove it... we dont care for now
+ */
+ zone_drain_wait(zone, M_WAITOK);
+ /*
+ * Unlink all of our kegs.
+ */
+ while ((klink = LIST_FIRST(&zone->uz_kegs)) != NULL) {
+ klink->kl_keg = NULL;
+ LIST_REMOVE(klink, kl_link);
+ if (klink == &zone->uz_klink)
+ continue;
+ free(klink, M_TEMP);
+ }
+ /*
+ * We only destroy kegs from non secondary zones.
+ */
+ if ((zone->uz_flags & UMA_ZONE_SECONDARY) == 0) {
+ mtx_lock(&uma_mtx);
LIST_REMOVE(keg, uk_link);
- LIST_REMOVE(zone, uz_link);
mtx_unlock(&uma_mtx);
- uma_zfree_internal(kegs, keg, NULL, SKIP_NONE,
+ zone_free_item(kegs, keg, NULL, SKIP_NONE,
ZFREE_STATFREE);
}
- zone->uz_keg = NULL;
}
/*
@@ -1517,7 +1591,7 @@ uma_startup(void *bootmem, int boot_pages)
* (UMA_MAX_WASTE).
*
* We iterate until we find an object size for
- * which the calculated wastage in zone_small_init() will be
+ * which the calculated wastage in keg_small_init() will be
* enough to warrant OFFPAGE. Since wastedspace versus objsize
* is an overall increasing see-saw function, we find the smallest
* objsize such that the wastage is always acceptable for objects
@@ -1525,7 +1599,7 @@ uma_startup(void *bootmem, int boot_pages)
* generates a larger possible uma_max_ipers, we use this computed
* objsize to calculate the largest ipers possible. Since the
* ipers calculated for OFFPAGE slab headers is always larger than
- * the ipers initially calculated in zone_small_init(), we use
+ * the ipers initially calculated in keg_small_init(), we use
* the former's equation (UMA_SLAB_SIZE / keg->uk_rsize) to
* obtain the maximum ipers possible for offpage slab headers.
*
@@ -1557,7 +1631,7 @@ uma_startup(void *bootmem, int boot_pages)
}
if (objsize > UMA_SMALLEST_UNIT)
objsize--;
- uma_max_ipers = UMA_SLAB_SIZE / objsize;
+ uma_max_ipers = MAX(UMA_SLAB_SIZE / objsize, 64);
wsize = UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt) - UMA_MAX_WASTE;
totsize = wsize;
@@ -1570,7 +1644,7 @@ uma_startup(void *bootmem, int boot_pages)
}
if (objsize > UMA_SMALLEST_UNIT)
objsize--;
- uma_max_ipers_ref = UMA_SLAB_SIZE / objsize;
+ uma_max_ipers_ref = MAX(UMA_SLAB_SIZE / objsize, 64);
KASSERT((uma_max_ipers_ref <= 255) && (uma_max_ipers <= 255),
("uma_startup: calculated uma_max_ipers values too large!"));
@@ -1698,7 +1772,7 @@ uma_startup3(void)
#endif
}
-static uma_zone_t
+static uma_keg_t
uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
int align, u_int32_t flags)
{
@@ -1710,7 +1784,7 @@ uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
args.align = (align == UMA_ALIGN_CACHE) ? uma_align_cache : align;
args.flags = flags;
args.zone = zone;
- return (uma_zalloc_internal(kegs, &args, M_WAITOK));
+ return (zone_alloc_item(kegs, &args, M_WAITOK));
}
/* See uma.h */
@@ -1741,7 +1815,7 @@ uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor,
args.flags = flags;
args.keg = NULL;
- return (uma_zalloc_internal(zones, &args, M_WAITOK));
+ return (zone_alloc_item(zones, &args, M_WAITOK));
}
/* See uma.h */
@@ -1750,26 +1824,115 @@ uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor,
uma_init zinit, uma_fini zfini, uma_zone_t master)
{
struct uma_zctor_args args;
+ uma_keg_t keg;
+ keg = zone_first_keg(master);
args.name = name;
- args.size = master->uz_keg->uk_size;
+ args.size = keg->uk_size;
args.ctor = ctor;
args.dtor = dtor;
args.uminit = zinit;
args.fini = zfini;
- args.align = master->uz_keg->uk_align;
- args.flags = master->uz_keg->uk_flags | UMA_ZONE_SECONDARY;
- args.keg = master->uz_keg;
+ args.align = keg->uk_align;
+ args.flags = keg->uk_flags | UMA_ZONE_SECONDARY;
+ args.keg = keg;
+
+ /* XXX Attaches only one keg of potentially many. */
+ return (zone_alloc_item(zones, &args, M_WAITOK));
+}
+
+static void
+zone_lock_pair(uma_zone_t a, uma_zone_t b)
+{
+ if (a < b) {
+ ZONE_LOCK(a);
+ mtx_lock_flags(b->uz_lock, MTX_DUPOK);
+ } else {
+ ZONE_LOCK(b);
+ mtx_lock_flags(a->uz_lock, MTX_DUPOK);
+ }
+}
+
+static void
+zone_unlock_pair(uma_zone_t a, uma_zone_t b)
+{
+
+ ZONE_UNLOCK(a);
+ ZONE_UNLOCK(b);
+}
+
+int
+uma_zsecond_add(uma_zone_t zone, uma_zone_t master)
+{
+ uma_klink_t klink;
+ uma_klink_t kl;
+ int error;
+
+ error = 0;
+ klink = malloc(sizeof(*klink), M_TEMP, M_WAITOK | M_ZERO);
+
+ zone_lock_pair(zone, master);
+ /*
+ * zone must use vtoslab() to resolve objects and must already be
+ * a secondary.
+ */
+ if ((zone->uz_flags & (UMA_ZONE_VTOSLAB | UMA_ZONE_SECONDARY))
+ != (UMA_ZONE_VTOSLAB | UMA_ZONE_SECONDARY)) {
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * The new master must also use vtoslab().
+ */
+ if ((zone->uz_flags & UMA_ZONE_VTOSLAB) != UMA_ZONE_VTOSLAB) {
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * Both must either be refcnt, or not be refcnt.
+ */
+ if ((zone->uz_flags & UMA_ZONE_REFCNT) !=
+ (master->uz_flags & UMA_ZONE_REFCNT)) {
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * The underlying object must be the same size. rsize
+ * may be different.
+ */
+ if (master->uz_size != zone->uz_size) {
+ error = E2BIG;
+ goto out;
+ }
+ /*
+ * Put it at the end of the list.
+ */
+ klink->kl_keg = zone_first_keg(master);
+ LIST_FOREACH(kl, &zone->uz_kegs, kl_link) {
+ if (LIST_NEXT(kl, kl_link) == NULL) {
+ LIST_INSERT_AFTER(kl, klink, kl_link);
+ break;
+ }
+ }
+ klink = NULL;
+ zone->uz_flags |= UMA_ZFLAG_MULTI;
+ zone->uz_slab = zone_fetch_slab_multi;
+
+out:
+ zone_unlock_pair(zone, master);
+ if (klink != NULL)
+ free(klink, M_TEMP);
- return (uma_zalloc_internal(zones, &args, M_WAITOK));
+ return (error);
}
+
/* See uma.h */
void
uma_zdestroy(uma_zone_t zone)
{
- uma_zfree_internal(zones, zone, NULL, SKIP_NONE, ZFREE_STATFREE);
+ zone_free_item(zones, zone, NULL, SKIP_NONE, ZFREE_STATFREE);
}
/* See uma.h */
@@ -1829,16 +1992,16 @@ zalloc_start:
ZONE_UNLOCK(zone);
#endif
if (zone->uz_ctor != NULL) {
- if (zone->uz_ctor(item, zone->uz_keg->uk_size,
+ if (zone->uz_ctor(item, zone->uz_size,
udata, flags) != 0) {
- uma_zfree_internal(zone, item, udata,
+ zone_free_item(zone, item, udata,
SKIP_DTOR, ZFREE_STATFAIL |
ZFREE_STATFREE);
return (NULL);
}
}
if (flags & M_ZERO)
- bzero(item, zone->uz_keg->uk_size);
+ bzero(item, zone->uz_size);
return (item);
} else if (cache->uc_freebucket) {
/*
@@ -1921,7 +2084,7 @@ zalloc_start:
* Now lets just fill a bucket and put it on the free list. If that
* works we'll restart the allocation from the begining.
*/
- if (uma_zalloc_bucket(zone, flags)) {
+ if (zone_alloc_bucket(zone, flags)) {
ZONE_UNLOCK(zone);
goto zalloc_restart;
}
@@ -1933,39 +2096,16 @@ zalloc_start:
printf("uma_zalloc_arg: Bucketzone returned NULL\n");
#endif
- return (uma_zalloc_internal(zone, udata, flags));
+ item = zone_alloc_item(zone, udata, flags);
+ return (item);
}
static uma_slab_t
-uma_zone_slab(uma_zone_t zone, int flags)
+keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int flags)
{
uma_slab_t slab;
- uma_keg_t keg;
-
- keg = zone->uz_keg;
-
- /*
- * This is to prevent us from recursively trying to allocate
- * buckets. The problem is that if an allocation forces us to
- * grab a new bucket we will call page_alloc, which will go off
- * and cause the vm to allocate vm_map_entries. If we need new
- * buckets there too we will recurse in kmem_alloc and bad
- * things happen. So instead we return a NULL bucket, and make
- * the code that allocates buckets smart enough to deal with it
- *
- * XXX: While we want this protection for the bucket zones so that
- * recursion from the VM is handled (and the calling code that
- * allocates buckets knows how to deal with it), we do not want
- * to prevent allocation from the slab header zones (slabzone
- * and slabrefzone) if uk_recurse is not zero for them. The
- * reason is that it could lead to NULL being returned for
- * slab header allocations even in the M_WAITOK case, and the
- * caller can't handle that.
- */
- if (keg->uk_flags & UMA_ZFLAG_INTERNAL && keg->uk_recurse != 0)
- if (zone != slabzone && zone != slabrefzone && zone != zones)
- return (NULL);
+ mtx_assert(&keg->uk_lock, MA_OWNED);
slab = NULL;
for (;;) {
@@ -1983,6 +2123,7 @@ uma_zone_slab(uma_zone_t zone, int flags)
LIST_INSERT_HEAD(&keg->uk_part_slab, slab,
us_link);
}
+ MPASS(slab->us_keg == keg);
return (slab);
}
@@ -1992,27 +2133,29 @@ uma_zone_slab(uma_zone_t zone, int flags)
if (flags & M_NOVM)
break;
- if (keg->uk_maxpages &&
- keg->uk_pages >= keg->uk_maxpages) {
+ if (keg->uk_maxpages && keg->uk_pages >= keg->uk_maxpages) {
keg->uk_flags |= UMA_ZFLAG_FULL;
-
+ /*
+ * If this is not a multi-zone, set the FULL bit.
+ * Otherwise slab_multi() takes care of it.
+ */
+ if ((zone->uz_flags & UMA_ZFLAG_MULTI) == 0)
+ zone->uz_flags |= UMA_ZFLAG_FULL;
if (flags & M_NOWAIT)
break;
- else
- msleep(keg, &keg->uk_lock, PVM,
- "zonelimit", 0);
+ msleep(keg, &keg->uk_lock, PVM, "keglimit", 0);
continue;
}
keg->uk_recurse++;
- slab = slab_zalloc(zone, flags);
+ slab = keg_alloc_slab(keg, zone, flags);
keg->uk_recurse--;
-
/*
* If we got a slab here it's safe to mark it partially used
* and return. We assume that the caller is going to remove
* at least one item.
*/
if (slab) {
+ MPASS(slab->us_keg == keg);
LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link);
return (slab);
}
@@ -2021,21 +2164,145 @@ uma_zone_slab(uma_zone_t zone, int flags)
* could have while we were unlocked. Check again before we
* fail.
*/
- if (flags & M_NOWAIT)
- flags |= M_NOVM;
+ flags |= M_NOVM;
}
return (slab);
}
+static inline void
+zone_relock(uma_zone_t zone, uma_keg_t keg)
+{
+ if (zone->uz_lock != &keg->uk_lock) {
+ KEG_UNLOCK(keg);
+ ZONE_LOCK(zone);
+ }
+}
+
+static inline void
+keg_relock(uma_keg_t keg, uma_zone_t zone)
+{
+ if (zone->uz_lock != &keg->uk_lock) {
+ ZONE_UNLOCK(zone);
+ KEG_LOCK(keg);
+ }
+}
+
+static uma_slab_t
+zone_fetch_slab(uma_zone_t zone, uma_keg_t keg, int flags)
+{
+ uma_slab_t slab;
+
+ if (keg == NULL)
+ keg = zone_first_keg(zone);
+ /*
+ * This is to prevent us from recursively trying to allocate
+ * buckets. The problem is that if an allocation forces us to
+ * grab a new bucket we will call page_alloc, which will go off
+ * and cause the vm to allocate vm_map_entries. If we need new
+ * buckets there too we will recurse in kmem_alloc and bad
+ * things happen. So instead we return a NULL bucket, and make
+ * the code that allocates buckets smart enough to deal with it
+ */
+ if (keg->uk_flags & UMA_ZFLAG_BUCKET && keg->uk_recurse != 0)
+ return (NULL);
+
+ for (;;) {
+ slab = keg_fetch_slab(keg, zone, flags);
+ if (slab)
+ return (slab);
+ if (flags & (M_NOWAIT | M_NOVM))
+ break;
+ }
+ return (NULL);
+}
+
+/*
+ * uma_zone_fetch_slab_multi: Fetches a slab from one available keg. Returns
+ * with the keg locked. Caller must call zone_relock() afterwards if the
+ * zone lock is required. On NULL the zone lock is held.
+ *
+ * The last pointer is used to seed the search. It is not required.
+ */
+static uma_slab_t
+zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int rflags)
+{
+ uma_klink_t klink;
+ uma_slab_t slab;
+ uma_keg_t keg;
+ int flags;
+ int empty;
+ int full;
+
+ /*
+ * Don't wait on the first pass. This will skip limit tests
+ * as well. We don't want to block if we can find a provider
+ * without blocking.
+ */
+ flags = (rflags & ~M_WAITOK) | M_NOWAIT;
+ /*
+ * Use the last slab allocated as a hint for where to start
+ * the search.
+ */
+ if (last) {
+ slab = keg_fetch_slab(last, zone, flags);
+ if (slab)
+ return (slab);
+ zone_relock(zone, last);
+ last = NULL;
+ }
+ /*
+ * Loop until we have a slab incase of transient failures
+ * while M_WAITOK is specified. I'm not sure this is 100%
+ * required but we've done it for so long now.
+ */
+ for (;;) {
+ empty = 0;
+ full = 0;
+ /*
+ * Search the available kegs for slabs. Be careful to hold the
+ * correct lock while calling into the keg layer.
+ */
+ LIST_FOREACH(klink, &zone->uz_kegs, kl_link) {
+ keg = klink->kl_keg;
+ keg_relock(keg, zone);
+ if ((keg->uk_flags & UMA_ZFLAG_FULL) == 0) {
+ slab = keg_fetch_slab(keg, zone, flags);
+ if (slab)
+ return (slab);
+ }
+ if (keg->uk_flags & UMA_ZFLAG_FULL)
+ full++;
+ else
+ empty++;
+ zone_relock(zone, keg);
+ }
+ if (rflags & (M_NOWAIT | M_NOVM))
+ break;
+ flags = rflags;
+ /*
+ * All kegs are full. XXX We can't atomically check all kegs
+ * and sleep so just sleep for a short period and retry.
+ */
+ if (full && !empty) {
+ zone->uz_flags |= UMA_ZFLAG_FULL;
+ msleep(zone, zone->uz_lock, PVM, "zonelimit", hz/100);
+ zone->uz_flags &= ~UMA_ZFLAG_FULL;
+ continue;
+ }
+ }
+ return (NULL);
+}
+
static void *
-uma_slab_alloc(uma_zone_t zone, uma_slab_t slab)
+slab_alloc_item(uma_zone_t zone, uma_slab_t slab)
{
uma_keg_t keg;
uma_slabrefcnt_t slabref;
void *item;
u_int8_t freei;
- keg = zone->uz_keg;
+ keg = slab->us_keg;
+ mtx_assert(&keg->uk_lock, MA_OWNED);
freei = slab->us_firstfree;
if (keg->uk_flags & UMA_ZONE_REFCNT) {
@@ -2061,10 +2328,11 @@ uma_slab_alloc(uma_zone_t zone, uma_slab_t slab)
}
static int
-uma_zalloc_bucket(uma_zone_t zone, int flags)
+zone_alloc_bucket(uma_zone_t zone, int flags)
{
uma_bucket_t bucket;
uma_slab_t slab;
+ uma_keg_t keg;
int16_t saved;
int max, origflags = flags;
@@ -2073,13 +2341,13 @@ uma_zalloc_bucket(uma_zone_t zone, int flags)
*/
if ((bucket = LIST_FIRST(&zone->uz_free_bucket)) != NULL) {
KASSERT(bucket->ub_cnt == 0,
- ("uma_zalloc_bucket: Bucket on free list is not empty."));
+ ("zone_alloc_bucket: Bucket on free list is not empty."));
LIST_REMOVE(bucket, ub_link);
} else {
int bflags;
bflags = (flags & ~M_ZERO);
- if (zone->uz_keg->uk_flags & UMA_ZFLAG_CACHEONLY)
+ if (zone->uz_flags & UMA_ZFLAG_CACHEONLY)
bflags |= M_NOVM;
ZONE_UNLOCK(zone);
@@ -2087,8 +2355,9 @@ uma_zalloc_bucket(uma_zone_t zone, int flags)
ZONE_LOCK(zone);
}
- if (bucket == NULL)
+ if (bucket == NULL) {
return (0);
+ }
#ifdef SMP
/*
@@ -2105,16 +2374,21 @@ uma_zalloc_bucket(uma_zone_t zone, int flags)
max = MIN(bucket->ub_entries, zone->uz_count);
/* Try to keep the buckets totally full */
saved = bucket->ub_cnt;
+ slab = NULL;
+ keg = NULL;
while (bucket->ub_cnt < max &&
- (slab = uma_zone_slab(zone, flags)) != NULL) {
+ (slab = zone->uz_slab(zone, keg, flags)) != NULL) {
+ keg = slab->us_keg;
while (slab->us_freecount && bucket->ub_cnt < max) {
bucket->ub_bucket[bucket->ub_cnt++] =
- uma_slab_alloc(zone, slab);
+ slab_alloc_item(zone, slab);
}
/* Don't block on the next fill */
flags |= M_NOWAIT;
}
+ if (slab)
+ zone_relock(zone, keg);
/*
* We unlock here because we need to call the zone's init.
@@ -2128,8 +2402,8 @@ uma_zalloc_bucket(uma_zone_t zone, int flags)
ZONE_UNLOCK(zone);
for (i = saved; i < bucket->ub_cnt; i++)
- if (zone->uz_init(bucket->ub_bucket[i],
- zone->uz_keg->uk_size, origflags) != 0)
+ if (zone->uz_init(bucket->ub_bucket[i], zone->uz_size,
+ origflags) != 0)
break;
/*
* If we couldn't initialize the whole bucket, put the
@@ -2139,7 +2413,7 @@ uma_zalloc_bucket(uma_zone_t zone, int flags)
int j;
for (j = i; j < bucket->ub_cnt; j++) {
- uma_zfree_internal(zone, bucket->ub_bucket[j],
+ zone_free_item(zone, bucket->ub_bucket[j],
NULL, SKIP_FINI, 0);
#ifdef INVARIANTS
bucket->ub_bucket[j] = NULL;
@@ -2177,31 +2451,29 @@ done:
*/
static void *
-uma_zalloc_internal(uma_zone_t zone, void *udata, int flags)
+zone_alloc_item(uma_zone_t zone, void *udata, int flags)
{
- uma_keg_t keg;
uma_slab_t slab;
void *item;
item = NULL;
- keg = zone->uz_keg;
#ifdef UMA_DEBUG_ALLOC
printf("INTERNAL: Allocating one item from %s(%p)\n", zone->uz_name, zone);
#endif
ZONE_LOCK(zone);
- slab = uma_zone_slab(zone, flags);
+ slab = zone->uz_slab(zone, NULL, flags);
if (slab == NULL) {
zone->uz_fails++;
ZONE_UNLOCK(zone);
return (NULL);
}
- item = uma_slab_alloc(zone, slab);
+ item = slab_alloc_item(zone, slab);
+ zone_relock(zone, slab->us_keg);
zone->uz_allocs++;
-
ZONE_UNLOCK(zone);
/*
@@ -2211,21 +2483,21 @@ uma_zalloc_internal(uma_zone_t zone, void *udata, int flags)
* to be both zone-init'd as well as zone-ctor'd.
*/
if (zone->uz_init != NULL) {
- if (zone->uz_init(item, keg->uk_size, flags) != 0) {
- uma_zfree_internal(zone, item, udata, SKIP_FINI,
+ if (zone->uz_init(item, zone->uz_size, flags) != 0) {
+ zone_free_item(zone, item, udata, SKIP_FINI,
ZFREE_STATFAIL | ZFREE_STATFREE);
return (NULL);
}
}
if (zone->uz_ctor != NULL) {
- if (zone->uz_ctor(item, keg->uk_size, udata, flags) != 0) {
- uma_zfree_internal(zone, item, udata, SKIP_DTOR,
+ if (zone->uz_ctor(item, zone->uz_size, udata, flags) != 0) {
+ zone_free_item(zone, item, udata, SKIP_DTOR,
ZFREE_STATFAIL | ZFREE_STATFREE);
return (NULL);
}
}
if (flags & M_ZERO)
- bzero(item, keg->uk_size);
+ bzero(item, zone->uz_size);
return (item);
}
@@ -2234,14 +2506,11 @@ uma_zalloc_internal(uma_zone_t zone, void *udata, int flags)
void
uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
{
- uma_keg_t keg;
uma_cache_t cache;
uma_bucket_t bucket;
int bflags;
int cpu;
- keg = zone->uz_keg;
-
#ifdef UMA_DEBUG_ALLOC_1
printf("Freeing item %p to %s(%p)\n", item, zone->uz_name, zone);
#endif
@@ -2249,10 +2518,11 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
zone->uz_name);
if (zone->uz_dtor)
- zone->uz_dtor(item, keg->uk_size, udata);
+ zone->uz_dtor(item, zone->uz_size, udata);
+
#ifdef INVARIANTS
ZONE_LOCK(zone);
- if (keg->uk_flags & UMA_ZONE_MALLOC)
+ if (zone->uz_flags & UMA_ZONE_MALLOC)
uma_dbg_free(zone, udata, item);
else
uma_dbg_free(zone, NULL, item);
@@ -2262,7 +2532,7 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
* The race here is acceptable. If we miss it we'll just have to wait
* a little longer for the limits to be reset.
*/
- if (keg->uk_flags & UMA_ZFLAG_FULL)
+ if (zone->uz_flags & UMA_ZFLAG_FULL)
goto zfree_internal;
/*
@@ -2384,7 +2654,7 @@ zfree_start:
#endif
bflags = M_NOWAIT;
- if (keg->uk_flags & UMA_ZFLAG_CACHEONLY)
+ if (zone->uz_flags & UMA_ZFLAG_CACHEONLY)
bflags |= M_NOVM;
bucket = bucket_alloc(zone->uz_count, bflags);
if (bucket) {
@@ -2399,7 +2669,7 @@ zfree_start:
* If nothing else caught this, we'll just do an internal free.
*/
zfree_internal:
- uma_zfree_internal(zone, item, udata, SKIP_DTOR, ZFREE_STATFREE);
+ zone_free_item(zone, item, udata, SKIP_DTOR, ZFREE_STATFREE);
return;
}
@@ -2414,7 +2684,7 @@ zfree_internal:
* skip Skip dtors and finis
*/
static void
-uma_zfree_internal(uma_zone_t zone, void *item, void *udata,
+zone_free_item(uma_zone_t zone, void *item, void *udata,
enum zfreeskip skip, int flags)
{
uma_slab_t slab;
@@ -2422,13 +2692,13 @@ uma_zfree_internal(uma_zone_t zone, void *item, void *udata,
uma_keg_t keg;
u_int8_t *mem;
u_int8_t freei;
-
- keg = zone->uz_keg;
+ int clearfull;
if (skip < SKIP_DTOR && zone->uz_dtor)
- zone->uz_dtor(item, keg->uk_size, udata);
+ zone->uz_dtor(item, zone->uz_size, udata);
+
if (skip < SKIP_FINI && zone->uz_fini)
- zone->uz_fini(item, keg->uk_size);
+ zone->uz_fini(item, zone->uz_size);
ZONE_LOCK(zone);
@@ -2437,17 +2707,25 @@ uma_zfree_internal(uma_zone_t zone, void *item, void *udata,
if (flags & ZFREE_STATFREE)
zone->uz_frees++;
- if (!(keg->uk_flags & UMA_ZONE_MALLOC)) {
+ if (!(zone->uz_flags & UMA_ZONE_VTOSLAB)) {
mem = (u_int8_t *)((unsigned long)item & (~UMA_SLAB_MASK));
- if (keg->uk_flags & UMA_ZONE_HASH)
+ keg = zone_first_keg(zone); /* Must only be one. */
+ if (zone->uz_flags & UMA_ZONE_HASH) {
slab = hash_sfind(&keg->uk_hash, mem);
- else {
+ } else {
mem += keg->uk_pgoff;
slab = (uma_slab_t)mem;
}
} else {
- slab = (uma_slab_t)udata;
+ /* This prevents redundant lookups via free(). */
+ if ((zone->uz_flags & UMA_ZONE_MALLOC) && udata != NULL)
+ slab = (uma_slab_t)udata;
+ else
+ slab = vtoslab((vm_offset_t)item);
+ keg = slab->us_keg;
+ keg_relock(keg, zone);
}
+ MPASS(keg == slab->us_keg);
/* Do we need to remove from any lists? */
if (slab->us_freecount+1 == keg->uk_ipers) {
@@ -2479,9 +2757,12 @@ uma_zfree_internal(uma_zone_t zone, void *item, void *udata,
/* Zone statistics */
keg->uk_free++;
+ clearfull = 0;
if (keg->uk_flags & UMA_ZFLAG_FULL) {
- if (keg->uk_pages < keg->uk_maxpages)
+ if (keg->uk_pages < keg->uk_maxpages) {
keg->uk_flags &= ~UMA_ZFLAG_FULL;
+ clearfull = 1;
+ }
/*
* We can handle one more allocation. Since we're clearing ZFLAG_FULL,
@@ -2491,8 +2772,13 @@ uma_zfree_internal(uma_zone_t zone, void *item, void *udata,
*/
wakeup(keg);
}
-
- ZONE_UNLOCK(zone);
+ if (clearfull) {
+ zone_relock(zone, keg);
+ zone->uz_flags &= ~UMA_ZFLAG_FULL;
+ wakeup(zone);
+ ZONE_UNLOCK(zone);
+ } else
+ KEG_UNLOCK(keg);
}
/* See uma.h */
@@ -2501,15 +2787,11 @@ uma_zone_set_max(uma_zone_t zone, int nitems)
{
uma_keg_t keg;
- keg = zone->uz_keg;
ZONE_LOCK(zone);
- if (keg->uk_ppera > 1)
- keg->uk_maxpages = nitems * keg->uk_ppera;
- else
- keg->uk_maxpages = nitems / keg->uk_ipers;
-
+ keg = zone_first_keg(zone);
+ keg->uk_maxpages = (nitems / keg->uk_ipers) * keg->uk_ppera;
if (keg->uk_maxpages * keg->uk_ipers < nitems)
- keg->uk_maxpages++;
+ keg->uk_maxpages += keg->uk_ppera;
ZONE_UNLOCK(zone);
}
@@ -2518,10 +2800,13 @@ uma_zone_set_max(uma_zone_t zone, int nitems)
void
uma_zone_set_init(uma_zone_t zone, uma_init uminit)
{
+ uma_keg_t keg;
+
ZONE_LOCK(zone);
- KASSERT(zone->uz_keg->uk_pages == 0,
+ keg = zone_first_keg(zone);
+ KASSERT(keg->uk_pages == 0,
("uma_zone_set_init on non-empty keg"));
- zone->uz_keg->uk_init = uminit;
+ keg->uk_init = uminit;
ZONE_UNLOCK(zone);
}
@@ -2529,10 +2814,13 @@ uma_zone_set_init(uma_zone_t zone, uma_init uminit)
void
uma_zone_set_fini(uma_zone_t zone, uma_fini fini)
{
+ uma_keg_t keg;
+
ZONE_LOCK(zone);
- KASSERT(zone->uz_keg->uk_pages == 0,
+ keg = zone_first_keg(zone);
+ KASSERT(keg->uk_pages == 0,
("uma_zone_set_fini on non-empty keg"));
- zone->uz_keg->uk_fini = fini;
+ keg->uk_fini = fini;
ZONE_UNLOCK(zone);
}
@@ -2541,7 +2829,7 @@ void
uma_zone_set_zinit(uma_zone_t zone, uma_init zinit)
{
ZONE_LOCK(zone);
- KASSERT(zone->uz_keg->uk_pages == 0,
+ KASSERT(zone_first_keg(zone)->uk_pages == 0,
("uma_zone_set_zinit on non-empty keg"));
zone->uz_init = zinit;
ZONE_UNLOCK(zone);
@@ -2552,7 +2840,7 @@ void
uma_zone_set_zfini(uma_zone_t zone, uma_fini zfini)
{
ZONE_LOCK(zone);
- KASSERT(zone->uz_keg->uk_pages == 0,
+ KASSERT(zone_first_keg(zone)->uk_pages == 0,
("uma_zone_set_zfini on non-empty keg"));
zone->uz_fini = zfini;
ZONE_UNLOCK(zone);
@@ -2563,8 +2851,9 @@ uma_zone_set_zfini(uma_zone_t zone, uma_fini zfini)
void
uma_zone_set_freef(uma_zone_t zone, uma_free freef)
{
+
ZONE_LOCK(zone);
- zone->uz_keg->uk_freef = freef;
+ zone_first_keg(zone)->uk_freef = freef;
ZONE_UNLOCK(zone);
}
@@ -2573,9 +2862,12 @@ uma_zone_set_freef(uma_zone_t zone, uma_free freef)
void
uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf)
{
+ uma_keg_t keg;
+
ZONE_LOCK(zone);
- zone->uz_keg->uk_flags |= UMA_ZFLAG_PRIVALLOC;
- zone->uz_keg->uk_allocf = allocf;
+ keg = zone_first_keg(zone);
+ keg->uk_flags |= UMA_ZFLAG_PRIVALLOC;
+ keg->uk_allocf = allocf;
ZONE_UNLOCK(zone);
}
@@ -2587,7 +2879,7 @@ uma_zone_set_obj(uma_zone_t zone, struct vm_object *obj, int count)
vm_offset_t kva;
int pages;
- keg = zone->uz_keg;
+ keg = zone_first_keg(zone);
pages = count / keg->uk_ipers;
if (pages * keg->uk_ipers < count)
@@ -2623,13 +2915,16 @@ uma_prealloc(uma_zone_t zone, int items)
uma_slab_t slab;
uma_keg_t keg;
- keg = zone->uz_keg;
+ keg = zone_first_keg(zone);
ZONE_LOCK(zone);
slabs = items / keg->uk_ipers;
if (slabs * keg->uk_ipers < items)
slabs++;
while (slabs > 0) {
- slab = slab_zalloc(zone, M_WAITOK);
+ slab = keg_alloc_slab(keg, zone, M_WAITOK);
+ if (slab == NULL)
+ break;
+ MPASS(slab->us_keg == keg);
LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
slabs--;
}
@@ -2645,9 +2940,9 @@ uma_find_refcnt(uma_zone_t zone, void *item)
u_int32_t *refcnt;
int idx;
- keg = zone->uz_keg;
slabref = (uma_slabrefcnt_t)vtoslab((vm_offset_t)item &
(~UMA_SLAB_MASK));
+ keg = slabref->us_keg;
KASSERT(slabref != NULL && slabref->us_keg->uk_flags & UMA_ZONE_REFCNT,
("uma_find_refcnt(): zone possibly not UMA_ZONE_REFCNT"));
idx = ((unsigned long)item - (unsigned long)slabref->us_data)
@@ -2682,7 +2977,7 @@ uma_zone_exhausted(uma_zone_t zone)
int full;
ZONE_LOCK(zone);
- full = (zone->uz_keg->uk_flags & UMA_ZFLAG_FULL);
+ full = (zone->uz_flags & UMA_ZFLAG_FULL);
ZONE_UNLOCK(zone);
return (full);
}
@@ -2690,7 +2985,7 @@ uma_zone_exhausted(uma_zone_t zone)
int
uma_zone_exhausted_nolock(uma_zone_t zone)
{
- return (zone->uz_keg->uk_flags & UMA_ZFLAG_FULL);
+ return (zone->uz_flags & UMA_ZFLAG_FULL);
}
void *
@@ -2700,7 +2995,7 @@ uma_large_malloc(int size, int wait)
uma_slab_t slab;
u_int8_t flags;
- slab = uma_zalloc_internal(slabzone, NULL, wait);
+ slab = zone_alloc_item(slabzone, NULL, wait);
if (slab == NULL)
return (NULL);
mem = page_alloc(NULL, size, &flags, wait);
@@ -2710,7 +3005,7 @@ uma_large_malloc(int size, int wait)
slab->us_flags = flags | UMA_SLAB_MALLOC;
slab->us_size = size;
} else {
- uma_zfree_internal(slabzone, slab, NULL, SKIP_NONE,
+ zone_free_item(slabzone, slab, NULL, SKIP_NONE,
ZFREE_STATFAIL | ZFREE_STATFREE);
}
@@ -2722,7 +3017,7 @@ uma_large_free(uma_slab_t slab)
{
vsetobj((vm_offset_t)slab->us_data, kmem_object);
page_free(slab->us_data, slab->us_size, slab->us_flags);
- uma_zfree_internal(slabzone, slab, NULL, SKIP_NONE, ZFREE_STATFREE);
+ zone_free_item(slabzone, slab, NULL, SKIP_NONE, ZFREE_STATFREE);
}
void
@@ -2749,19 +3044,17 @@ cache_print(uma_cache_t cache)
cache->uc_freebucket?cache->uc_freebucket->ub_cnt:0);
}
-void
-uma_print_zone(uma_zone_t zone)
+static void
+uma_print_keg(uma_keg_t keg)
{
- uma_cache_t cache;
- uma_keg_t keg;
uma_slab_t slab;
- int i;
- keg = zone->uz_keg;
- printf("%s(%p) size %d(%d) flags %d ipers %d ppera %d out %d free %d\n",
- zone->uz_name, zone, keg->uk_size, keg->uk_rsize, keg->uk_flags,
+ printf("keg: %s(%p) size %d(%d) flags %d ipers %d ppera %d "
+ "out %d free %d limit %d\n",
+ keg->uk_name, keg, keg->uk_size, keg->uk_rsize, keg->uk_flags,
keg->uk_ipers, keg->uk_ppera,
- (keg->uk_ipers * keg->uk_pages) - keg->uk_free, keg->uk_free);
+ (keg->uk_ipers * keg->uk_pages) - keg->uk_free, keg->uk_free,
+ (keg->uk_maxpages / keg->uk_ppera) * keg->uk_ipers);
printf("Part slabs:\n");
LIST_FOREACH(slab, &keg->uk_part_slab, us_link)
slab_print(slab);
@@ -2771,6 +3064,19 @@ uma_print_zone(uma_zone_t zone)
printf("Full slabs:\n");
LIST_FOREACH(slab, &keg->uk_full_slab, us_link)
slab_print(slab);
+}
+
+void
+uma_print_zone(uma_zone_t zone)
+{
+ uma_cache_t cache;
+ uma_klink_t kl;
+ int i;
+
+ printf("zone: %s(%p) size %d flags %d\n",
+ zone->uz_name, zone, zone->uz_size, zone->uz_flags);
+ LIST_FOREACH(kl, &zone->uz_kegs, kl_link)
+ uma_print_keg(kl->kl_keg);
for (i = 0; i <= mp_maxid; i++) {
if (CPU_ABSENT(i))
continue;
@@ -2850,8 +3156,10 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
uma_bucket_t bucket;
struct sbuf sbuf;
uma_cache_t cache;
+ uma_klink_t kl;
uma_keg_t kz;
uma_zone_t z;
+ uma_keg_t k;
char *buffer;
int buflen, count, error, i;
@@ -2902,23 +3210,22 @@ restart:
ZONE_LOCK(z);
strlcpy(uth.uth_name, z->uz_name, UTH_MAX_NAME);
uth.uth_align = kz->uk_align;
- uth.uth_pages = kz->uk_pages;
- uth.uth_keg_free = kz->uk_free;
uth.uth_size = kz->uk_size;
uth.uth_rsize = kz->uk_rsize;
- uth.uth_maxpages = kz->uk_maxpages;
- if (kz->uk_ppera > 1)
- uth.uth_limit = kz->uk_maxpages /
- kz->uk_ppera;
- else
- uth.uth_limit = kz->uk_maxpages *
- kz->uk_ipers;
+ LIST_FOREACH(kl, &z->uz_kegs, kl_link) {
+ k = kl->kl_keg;
+ uth.uth_maxpages += k->uk_maxpages;
+ uth.uth_pages += k->uk_pages;
+ uth.uth_keg_free += k->uk_free;
+ uth.uth_limit = (k->uk_maxpages / k->uk_ppera)
+ * k->uk_ipers;
+ }
/*
* A zone is secondary is it is not the first entry
* on the keg's zone list.
*/
- if ((kz->uk_flags & UMA_ZONE_SECONDARY) &&
+ if ((z->uz_flags & UMA_ZONE_SECONDARY) &&
(LIST_FIRST(&kz->uk_zones) != z))
uth.uth_zone_flags = UTH_ZONE_SECONDARY;
@@ -2995,7 +3302,7 @@ DB_SHOW_COMMAND(uma, db_show_uma)
} else
uma_zone_sumstat(z, &cachefree, &allocs,
&frees);
- if (!((kz->uk_flags & UMA_ZONE_SECONDARY) &&
+ if (!((z->uz_flags & UMA_ZONE_SECONDARY) &&
(LIST_FIRST(&kz->uk_zones) != z)))
cachefree += kz->uk_free;
LIST_FOREACH(bucket, &z->uz_full_bucket, ub_link)
diff --git a/sys/vm/uma_dbg.c b/sys/vm/uma_dbg.c
index 9075bf9..ade5fb5 100644
--- a/sys/vm/uma_dbg.c
+++ b/sys/vm/uma_dbg.c
@@ -198,15 +198,15 @@ uma_dbg_getslab(uma_zone_t zone, void *item)
uma_keg_t keg;
u_int8_t *mem;
- keg = zone->uz_keg;
mem = (u_int8_t *)((unsigned long)item & (~UMA_SLAB_MASK));
- if (keg->uk_flags & UMA_ZONE_MALLOC) {
+ if (zone->uz_flags & UMA_ZONE_VTOSLAB) {
slab = vtoslab((vm_offset_t)mem);
- } else if (keg->uk_flags & UMA_ZONE_HASH) {
- slab = hash_sfind(&keg->uk_hash, mem);
} else {
- mem += keg->uk_pgoff;
- slab = (uma_slab_t)mem;
+ keg = LIST_FIRST(&zone->uz_kegs)->kl_keg;
+ if (keg->uk_flags & UMA_ZONE_HASH)
+ slab = hash_sfind(&keg->uk_hash, mem);
+ else
+ slab = (uma_slab_t)(mem + keg->uk_pgoff);
}
return (slab);
@@ -224,13 +224,13 @@ uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item)
uma_slabrefcnt_t slabref;
int freei;
- keg = zone->uz_keg;
if (slab == NULL) {
slab = uma_dbg_getslab(zone, item);
if (slab == NULL)
panic("uma: item %p did not belong to zone %s\n",
item, zone->uz_name);
}
+ keg = slab->us_keg;
freei = ((unsigned long)item - (unsigned long)slab->us_data)
/ keg->uk_rsize;
@@ -258,13 +258,13 @@ uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item)
uma_slabrefcnt_t slabref;
int freei;
- keg = zone->uz_keg;
if (slab == NULL) {
slab = uma_dbg_getslab(zone, item);
if (slab == NULL)
panic("uma: Freed item %p did not belong to zone %s\n",
item, zone->uz_name);
}
+ keg = slab->us_keg;
freei = ((unsigned long)item - (unsigned long)slab->us_data)
/ keg->uk_rsize;
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index c4ea69c..c2ed06d 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003, 2004, 2005 Jeffrey Roberson <jeff@FreeBSD.org>
+ * Copyright (c) 2002-2005, 2009 Jeffrey Roberson <jeff@FreeBSD.org>
* Copyright (c) 2004, 2005 Bosko Milekic <bmilekic@FreeBSD.org>
* All rights reserved.
*
@@ -193,6 +193,7 @@ struct uma_keg {
struct mtx uk_lock; /* Lock for the keg */
struct uma_hash uk_hash;
+ char *uk_name; /* Name of creating zone. */
LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */
LIST_HEAD(,uma_slab) uk_part_slab; /* partially allocated slabs */
LIST_HEAD(,uma_slab) uk_free_slab; /* empty slab list */
@@ -220,9 +221,7 @@ struct uma_keg {
u_int16_t uk_ipers; /* Items per slab */
u_int32_t uk_flags; /* Internal flags */
};
-
-/* Simpler reference to uma_keg for internal use. */
-typedef struct uma_keg * uma_keg_t;
+typedef struct uma_keg * uma_keg_t;
/* Page management structure */
@@ -271,6 +270,8 @@ struct uma_slab_refcnt {
typedef struct uma_slab * uma_slab_t;
typedef struct uma_slab_refcnt * uma_slabrefcnt_t;
+typedef uma_slab_t (*uma_slaballoc)(uma_zone_t, uma_keg_t, int);
+
/*
* These give us the size of one free item reference within our corresponding
@@ -282,6 +283,12 @@ typedef struct uma_slab_refcnt * uma_slabrefcnt_t;
#define UMA_FRITMREF_SZ (sizeof(struct uma_slab_refcnt) - \
sizeof(struct uma_slab_head))
+struct uma_klink {
+ LIST_ENTRY(uma_klink) kl_link;
+ uma_keg_t kl_keg;
+};
+typedef struct uma_klink *uma_klink_t;
+
/*
* Zone management structure
*
@@ -291,12 +298,15 @@ typedef struct uma_slab_refcnt * uma_slabrefcnt_t;
struct uma_zone {
char *uz_name; /* Text name of the zone */
struct mtx *uz_lock; /* Lock for the zone (keg's lock) */
- uma_keg_t uz_keg; /* Our underlying Keg */
LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */
LIST_HEAD(,uma_bucket) uz_full_bucket; /* full buckets */
LIST_HEAD(,uma_bucket) uz_free_bucket; /* Buckets for frees */
+ LIST_HEAD(,uma_klink) uz_kegs; /* List of kegs. */
+ struct uma_klink uz_klink; /* klink for first keg. */
+
+ uma_slaballoc uz_slab; /* Allocate a slab from the backend. */
uma_ctor uz_ctor; /* Constructor for each allocation */
uma_dtor uz_dtor; /* Destructor */
uma_init uz_init; /* Initializer for each item */
@@ -305,6 +315,8 @@ struct uma_zone {
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 */
uint16_t uz_fills; /* Outstanding bucket fills */
uint16_t uz_count; /* Highest value ub_ptr can have */
@@ -318,11 +330,17 @@ struct uma_zone {
/*
* These flags must not overlap with the UMA_ZONE flags specified in uma.h.
*/
+#define UMA_ZFLAG_BUCKET 0x02000000 /* Bucket zone. */
+#define UMA_ZFLAG_MULTI 0x04000000 /* Multiple kegs in the zone. */
+#define UMA_ZFLAG_DRAINING 0x08000000 /* Running zone_drain. */
#define UMA_ZFLAG_PRIVALLOC 0x10000000 /* Use uz_allocf. */
#define UMA_ZFLAG_INTERNAL 0x20000000 /* No offpage no PCPU. */
#define UMA_ZFLAG_FULL 0x40000000 /* Reached uz_maxpages */
#define UMA_ZFLAG_CACHEONLY 0x80000000 /* Don't ask VM for buckets. */
+#define UMA_ZFLAG_INHERIT (UMA_ZFLAG_INTERNAL | UMA_ZFLAG_CACHEONLY | \
+ UMA_ZFLAG_BUCKET)
+
#ifdef _KERNEL
/* Internal prototypes */
static __inline uma_slab_t hash_sfind(struct uma_hash *hash, u_int8_t *data);
@@ -331,17 +349,19 @@ void uma_large_free(uma_slab_t slab);
/* Lock Macros */
-#define ZONE_LOCK_INIT(z, lc) \
+#define KEG_LOCK_INIT(k, lc) \
do { \
if ((lc)) \
- mtx_init((z)->uz_lock, (z)->uz_name, \
- (z)->uz_name, MTX_DEF | MTX_DUPOK); \
+ mtx_init(&(k)->uk_lock, (k)->uk_name, \
+ (k)->uk_name, MTX_DEF | MTX_DUPOK); \
else \
- mtx_init((z)->uz_lock, (z)->uz_name, \
+ mtx_init(&(k)->uk_lock, (k)->uk_name, \
"UMA zone", MTX_DEF | MTX_DUPOK); \
} while (0)
-#define ZONE_LOCK_FINI(z) mtx_destroy((z)->uz_lock)
+#define KEG_LOCK_FINI(k) mtx_destroy(&(k)->uk_lock)
+#define KEG_LOCK(k) mtx_lock(&(k)->uk_lock)
+#define KEG_UNLOCK(k) mtx_unlock(&(k)->uk_lock)
#define ZONE_LOCK(z) mtx_lock((z)->uz_lock)
#define ZONE_UNLOCK(z) mtx_unlock((z)->uz_lock)
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index a1f0ef3..18ba489 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -100,7 +100,8 @@ __FBSDID("$FreeBSD$");
* Synchronization is required prior to most operations.
*
* Maps consist of an ordered doubly-linked list of simple
- * entries; a single hint is used to speed up lookups.
+ * entries; a self-adjusting binary search tree of these
+ * entries is used to speed up lookups.
*
* Since portions of maps are specified by start/end addresses,
* which may not align with existing map entries, all
@@ -469,7 +470,7 @@ _vm_map_lock_read(vm_map_t map, const char *file, int line)
if (map->system_map)
_mtx_lock_flags(&map->system_mtx, 0, file, line);
else
- (void)_sx_xlock(&map->lock, 0, file, line);
+ (void)_sx_slock(&map->lock, 0, file, line);
}
void
@@ -479,7 +480,7 @@ _vm_map_unlock_read(vm_map_t map, const char *file, int line)
if (map->system_map)
_mtx_unlock_flags(&map->system_mtx, 0, file, line);
else
- _sx_xunlock(&map->lock, file, line);
+ _sx_sunlock(&map->lock, file, line);
}
int
@@ -502,20 +503,44 @@ _vm_map_trylock_read(vm_map_t map, const char *file, int line)
error = map->system_map ?
!_mtx_trylock(&map->system_mtx, 0, file, line) :
- !_sx_try_xlock(&map->lock, file, line);
+ !_sx_try_slock(&map->lock, file, line);
return (error == 0);
}
+/*
+ * _vm_map_lock_upgrade: [ internal use only ]
+ *
+ * Tries to upgrade a read (shared) lock on the specified map to a write
+ * (exclusive) lock. Returns the value "0" if the upgrade succeeds and a
+ * non-zero value if the upgrade fails. If the upgrade fails, the map is
+ * returned without a read or write lock held.
+ *
+ * Requires that the map be read locked.
+ */
int
_vm_map_lock_upgrade(vm_map_t map, const char *file, int line)
{
+ unsigned int last_timestamp;
-#ifdef INVARIANTS
if (map->system_map) {
+#ifdef INVARIANTS
_mtx_assert(&map->system_mtx, MA_OWNED, file, line);
- } else
- _sx_assert(&map->lock, SX_XLOCKED, file, line);
#endif
+ } else {
+ if (!_sx_try_upgrade(&map->lock, file, line)) {
+ last_timestamp = map->timestamp;
+ _sx_sunlock(&map->lock, file, line);
+ /*
+ * If the map's timestamp does not change while the
+ * map is unlocked, then the upgrade succeeds.
+ */
+ (void)_sx_xlock(&map->lock, 0, file, line);
+ if (last_timestamp != map->timestamp) {
+ _sx_xunlock(&map->lock, file, line);
+ return (1);
+ }
+ }
+ }
map->timestamp++;
return (0);
}
@@ -524,12 +549,28 @@ void
_vm_map_lock_downgrade(vm_map_t map, const char *file, int line)
{
-#ifdef INVARIANTS
if (map->system_map) {
+#ifdef INVARIANTS
_mtx_assert(&map->system_mtx, MA_OWNED, file, line);
- } else
- _sx_assert(&map->lock, SX_XLOCKED, file, line);
#endif
+ } else
+ _sx_downgrade(&map->lock, file, line);
+}
+
+/*
+ * vm_map_locked:
+ *
+ * Returns a non-zero value if the caller holds a write (exclusive) lock
+ * on the specified map and the value "0" otherwise.
+ */
+int
+vm_map_locked(vm_map_t map)
+{
+
+ if (map->system_map)
+ return (mtx_owned(&map->system_mtx));
+ else
+ return (sx_xlocked(&map->lock));
}
/*
@@ -737,9 +778,9 @@ vm_map_entry_splay(vm_offset_t addr, vm_map_entry_t root)
rlist = root;
root = y;
}
- } else {
+ } else if (addr >= root->end) {
y = root->right;
- if (addr < root->end || y == NULL)
+ if (y == NULL)
break;
if (addr >= y->end && y->right != NULL) {
/* Rotate left and put y on llist. */
@@ -755,7 +796,8 @@ vm_map_entry_splay(vm_offset_t addr, vm_map_entry_t root)
llist = root;
root = y;
}
- }
+ } else
+ break;
}
/*
@@ -900,20 +942,64 @@ vm_map_lookup_entry(
vm_map_entry_t *entry) /* OUT */
{
vm_map_entry_t cur;
+ boolean_t locked;
- cur = vm_map_entry_splay(address, map->root);
+ /*
+ * If the map is empty, then the map entry immediately preceding
+ * "address" is the map's header.
+ */
+ cur = map->root;
if (cur == NULL)
*entry = &map->header;
- else {
- map->root = cur;
+ else if (address >= cur->start && cur->end > address) {
+ *entry = cur;
+ return (TRUE);
+ } else if ((locked = vm_map_locked(map)) ||
+ sx_try_upgrade(&map->lock)) {
+ /*
+ * Splay requires a write lock on the map. However, it only
+ * restructures the binary search tree; it does not otherwise
+ * change the map. Thus, the map's timestamp need not change
+ * on a temporary upgrade.
+ */
+ map->root = cur = vm_map_entry_splay(address, cur);
+ if (!locked)
+ sx_downgrade(&map->lock);
+ /*
+ * If "address" is contained within a map entry, the new root
+ * is that map entry. Otherwise, the new root is a map entry
+ * immediately before or after "address".
+ */
if (address >= cur->start) {
*entry = cur;
if (cur->end > address)
return (TRUE);
} else
*entry = cur->prev;
- }
+ } else
+ /*
+ * Since the map is only locked for read access, perform a
+ * standard binary search tree lookup for "address".
+ */
+ for (;;) {
+ if (address < cur->start) {
+ if (cur->left == NULL) {
+ *entry = cur->prev;
+ break;
+ }
+ cur = cur->left;
+ } else if (cur->end > address) {
+ *entry = cur;
+ return (TRUE);
+ } else {
+ if (cur->right == NULL) {
+ *entry = cur;
+ break;
+ }
+ cur = cur->right;
+ }
+ }
return (FALSE);
}
@@ -1616,7 +1702,7 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
/*
* Update physical map if necessary. Worry about copy-on-write
- * here -- CHECK THIS XXX
+ * here.
*/
if (current->protection != old_prot) {
#define MASK(entry) (((entry)->eflags & MAP_ENTRY_COW) ? ~VM_PROT_WRITE : \
@@ -1793,7 +1879,7 @@ vm_map_madvise(
* Sets the inheritance of the specified address
* range in the target map. Inheritance
* affects how the map will be shared with
- * child maps at the time of vm_map_fork.
+ * child maps at the time of vmspace_fork.
*/
int
vm_map_inherit(vm_map_t map, vm_offset_t start, vm_offset_t end,
@@ -3108,35 +3194,19 @@ vm_map_lookup(vm_map_t *var_map, /* IN/OUT */
vm_prot_t fault_type = fault_typea;
RetryLookup:;
- /*
- * Lookup the faulting address.
- */
vm_map_lock_read(map);
-#define RETURN(why) \
- { \
- vm_map_unlock_read(map); \
- return (why); \
- }
/*
- * If the map has an interesting hint, try it before calling full
- * blown lookup routine.
+ * Lookup the faulting address.
*/
- entry = map->root;
- *out_entry = entry;
- if (entry == NULL ||
- (vaddr < entry->start) || (vaddr >= entry->end)) {
- /*
- * Entry was either not a valid hint, or the vaddr was not
- * contained in the entry, so do a full lookup.
- */
- if (!vm_map_lookup_entry(map, vaddr, out_entry))
- RETURN(KERN_INVALID_ADDRESS);
-
- entry = *out_entry;
+ if (!vm_map_lookup_entry(map, vaddr, out_entry)) {
+ vm_map_unlock_read(map);
+ return (KERN_INVALID_ADDRESS);
}
+ entry = *out_entry;
+
/*
* Handle submaps.
*/
@@ -3160,13 +3230,15 @@ RetryLookup:;
prot = entry->protection;
fault_type &= (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
if ((fault_type & prot) != fault_type) {
- RETURN(KERN_PROTECTION_FAILURE);
+ vm_map_unlock_read(map);
+ return (KERN_PROTECTION_FAILURE);
}
if ((entry->eflags & MAP_ENTRY_USER_WIRED) &&
(entry->eflags & MAP_ENTRY_COW) &&
(fault_type & VM_PROT_WRITE) &&
(fault_typea & VM_PROT_OVERRIDE_WRITE) == 0) {
- RETURN(KERN_PROTECTION_FAILURE);
+ vm_map_unlock_read(map);
+ return (KERN_PROTECTION_FAILURE);
}
/*
@@ -3236,8 +3308,6 @@ RetryLookup:;
*out_prot = prot;
return (KERN_SUCCESS);
-
-#undef RETURN
}
/*
@@ -3262,22 +3332,12 @@ vm_map_lookup_locked(vm_map_t *var_map, /* IN/OUT */
vm_prot_t fault_type = fault_typea;
/*
- * If the map has an interesting hint, try it before calling full
- * blown lookup routine.
+ * Lookup the faulting address.
*/
- entry = map->root;
- *out_entry = entry;
- if (entry == NULL ||
- (vaddr < entry->start) || (vaddr >= entry->end)) {
- /*
- * Entry was either not a valid hint, or the vaddr was not
- * contained in the entry, so do a full lookup.
- */
- if (!vm_map_lookup_entry(map, vaddr, out_entry))
- return (KERN_INVALID_ADDRESS);
+ if (!vm_map_lookup_entry(map, vaddr, out_entry))
+ return (KERN_INVALID_ADDRESS);
- entry = *out_entry;
- }
+ entry = *out_entry;
/*
* Fail if the entry refers to a submap.
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index bc2ae43..0c3ddc8 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -109,7 +109,6 @@ struct vm_map_entry {
union vm_map_object object; /* object I point to */
vm_ooffset_t offset; /* offset into object */
vm_eflags_t eflags; /* map entry flags */
- /* Only in task maps: */
vm_prot_t protection; /* protection code */
vm_prot_t max_protection; /* maximum protection */
vm_inherit_t inheritance; /* inheritance */
@@ -168,13 +167,6 @@ vm_map_entry_system_wired_count(vm_map_entry_t entry)
* Tarjan's top-down splay algorithm is employed to control
* height imbalance in the binary search tree.
*
- * Note: the lock structure cannot be the first element of vm_map
- * because this can result in a running lockup between two or more
- * system processes trying to kmem_alloc_wait() due to kmem_alloc_wait()
- * and free tsleep/waking up 'map' and the underlying lockmgr also
- * sleeping and waking up on 'map'. The lockup occurs when the map fills
- * up. The 'exec' map, for example.
- *
* List of locks
* (c) const until freed
*/
@@ -186,7 +178,7 @@ struct vm_map {
vm_size_t size; /* virtual size */
u_int timestamp; /* Version number */
u_char needs_wakeup;
- u_char system_map; /* Am I a system map? */
+ u_char system_map; /* (c) Am I a system map? */
vm_flags_t flags; /* flags for this vm_map */
vm_map_entry_t root; /* Root of a binary search tree */
pmap_t pmap; /* (c) Physical map */
@@ -277,6 +269,7 @@ int _vm_map_trylock(vm_map_t map, const char *file, int line);
int _vm_map_trylock_read(vm_map_t map, const char *file, int line);
int _vm_map_lock_upgrade(vm_map_t map, const char *file, int line);
void _vm_map_lock_downgrade(vm_map_t map, const char *file, int line);
+int vm_map_locked(vm_map_t map);
int vm_map_unlock_and_wait(vm_map_t map, int timo);
void vm_map_wakeup(vm_map_t map);
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index be9ee1e..07d1bd6 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -90,8 +90,9 @@ sysctl_vm_loadavg(SYSCTL_HANDLER_ARGS)
#endif
return SYSCTL_OUT(req, &averunnable, sizeof(averunnable));
}
-SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT|CTLFLAG_RD,
- NULL, 0, sysctl_vm_loadavg, "S,loadavg", "Machine loadaverage history");
+SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT | CTLFLAG_RD |
+ CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_loadavg, "S,loadavg",
+ "Machine loadaverage history");
static int
vmtotal(SYSCTL_HANDLER_ARGS)
@@ -109,7 +110,6 @@ vmtotal(SYSCTL_HANDLER_ARGS)
/*
* Mark all objects as inactive.
*/
- GIANT_REQUIRED;
mtx_lock(&vm_object_list_mtx);
TAILQ_FOREACH(object, &vm_object_list, object_list) {
if (!VM_OBJECT_TRYLOCK(object)) {
@@ -269,7 +269,7 @@ vcnt(SYSCTL_HANDLER_ARGS)
return (SYSCTL_OUT(req, &count, sizeof(int)));
}
-SYSCTL_PROC(_vm, VM_TOTAL, vmtotal, CTLTYPE_OPAQUE|CTLFLAG_RD,
+SYSCTL_PROC(_vm, VM_TOTAL, vmtotal, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE,
0, sizeof(struct vmtotal), vmtotal, "S,vmtotal",
"System virtual memory statistics");
SYSCTL_NODE(_vm, OID_AUTO, stats, CTLFLAG_RW, 0, "VM meter stats");
@@ -279,103 +279,103 @@ static SYSCTL_NODE(_vm_stats, OID_AUTO, vm, CTLFLAG_RW, 0,
"VM meter vm stats");
SYSCTL_NODE(_vm_stats, OID_AUTO, misc, CTLFLAG_RW, 0, "VM meter misc stats");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_swtch, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_swtch, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_swtch, 0, vcnt, "IU", "Context switches");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_trap, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_trap, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_trap, 0, vcnt, "IU", "Traps");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_syscall, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_syscall, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_syscall, 0, vcnt, "IU", "Syscalls");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_intr, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_intr, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_intr, 0, vcnt, "IU", "Hardware interrupts");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_soft, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_soft, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_soft, 0, vcnt, "IU", "Software interrupts");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vm_faults, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vm_faults, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vm_faults, 0, vcnt, "IU", "VM faults");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_faults, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_faults, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_cow_faults, 0, vcnt, "IU", "COW faults");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_optim, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_optim, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_cow_optim, 0, vcnt, "IU", "Optimized COW faults");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_zfod, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_zfod, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_zfod, 0, vcnt, "IU", "Zero fill");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_ozfod, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_ozfod, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_ozfod, 0, vcnt, "IU", "Optimized zero fill");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapin, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapin, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_swapin, 0, vcnt, "IU", "Swapin operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapout, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapout, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_swapout, 0, vcnt, "IU", "Swapout operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsin, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsin, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_swappgsin, 0, vcnt, "IU", "Swapin pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsout, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsout, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_swappgsout, 0, vcnt, "IU", "Swapout pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodein, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodein, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vnodein, 0, vcnt, "IU", "Vnodein operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodeout, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodeout, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vnodeout, 0, vcnt, "IU", "Vnodeout operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsin, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsin, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vnodepgsin, 0, vcnt, "IU", "Vnodein pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsout, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsout, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vnodepgsout, 0, vcnt, "IU", "Vnodeout pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_intrans, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_intrans, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_intrans, 0, vcnt, "IU", "In transit page blocking");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_reactivated, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_reactivated, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_reactivated, 0, vcnt, "IU", "Reactivated pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdwakeups, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdwakeups, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_pdwakeups, 0, vcnt, "IU", "Pagedaemon wakeups");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdpages, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdpages, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_pdpages, 0, vcnt, "IU", "Pagedaemon page scans");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_tcached, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_tcached, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_tcached, 0, vcnt, "IU", "Total pages cached");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_dfree, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_dfree, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_dfree, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pfree, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pfree, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_pfree, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_tfree, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_tfree, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_tfree, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_page_size, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_page_size, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_page_size, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_page_count, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_page_count, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_page_count, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_reserved, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_reserved, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_free_reserved, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_target, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_target, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_free_target, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_min, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_min, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_free_min, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_count, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_free_count, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_free_count, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_wire_count, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_wire_count, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_wire_count, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_active_count, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_active_count, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_active_count, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_inactive_target, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_inactive_target, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_inactive_target, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_inactive_count, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_inactive_count, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_inactive_count, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cache_count, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cache_count, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_cache_count, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cache_min, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cache_min, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_cache_min, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cache_max, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cache_max, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_cache_max, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pageout_free_min, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pageout_free_min, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_pageout_free_min, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_interrupt_free_min, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_interrupt_free_min, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_interrupt_free_min, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forks, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forks, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_forks, 0, vcnt, "IU", "Number of fork() calls");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforks, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforks, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vforks, 0, vcnt, "IU", "Number of vfork() calls");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforks, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforks, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_rforks, 0, vcnt, "IU", "Number of rfork() calls");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreads, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreads, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_kthreads, 0, vcnt, "IU", "Number of fork() calls by kernel");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forkpages, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forkpages, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_forkpages, 0, vcnt, "IU", "VM pages affected by fork()");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforkpages, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforkpages, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_vforkpages, 0, vcnt, "IU", "VM pages affected by vfork()");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforkpages, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforkpages, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_rforkpages, 0, vcnt, "IU", "VM pages affected by rfork()");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreadpages, CTLTYPE_UINT|CTLFLAG_RD,
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreadpages, CTLTYPE_UINT|CTLFLAG_RD|CTLFLAG_MPSAFE,
&cnt.v_kthreadpages, 0, vcnt, "IU", "VM pages affected by fork() by kernel");
SYSCTL_INT(_vm_stats_misc, OID_AUTO,
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 3f1d43d..2d668c4 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -1160,7 +1160,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
mp = vp->v_mount;
cred = td->td_ucred;
vfslocked = VFS_LOCK_GIANT(mp);
- if ((error = vget(vp, LK_EXCLUSIVE, td)) != 0) {
+ if ((error = vget(vp, LK_SHARED, td)) != 0) {
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
@@ -1177,7 +1177,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
if (obj->handle != vp) {
vput(vp);
vp = (struct vnode*)obj->handle;
- vget(vp, LK_EXCLUSIVE, td);
+ vget(vp, LK_SHARED, td);
}
type = OBJT_VNODE;
handle = vp;
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index a4ac79b..8befdd5 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -106,6 +106,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
@@ -2112,13 +2113,16 @@ vm_page_cowclear(vm_page_t m)
*/
}
-void
+int
vm_page_cowsetup(vm_page_t m)
{
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ if (m->cow == USHRT_MAX - 1)
+ return (EBUSY);
m->cow++;
pmap_remove_write(m);
+ return (0);
}
#include "opt_ddb.h"
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index f609a21..7f996ea 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -111,12 +111,12 @@ struct vm_page {
vm_paddr_t phys_addr; /* physical address of page */
struct md_page md; /* machine dependant stuff */
uint8_t queue; /* page queue index */
- int8_t segind;
+ int8_t segind;
u_short flags; /* see below */
uint8_t order; /* index of the buddy queue */
uint8_t pool;
- u_short wire_count; /* wired down maps refs (P) */
- u_int cow; /* page cow mapping count */
+ u_short cow; /* page cow mapping count */
+ u_int wire_count; /* wired down maps refs (P) */
short hold_count; /* page hold count */
u_short oflags; /* page flags (O) */
u_char act_count; /* page usage count */
@@ -336,7 +336,7 @@ void vm_page_zero_invalid(vm_page_t m, boolean_t setvalid);
void vm_page_free_toq(vm_page_t m);
void vm_page_zero_idle_wakeup(void);
void vm_page_cowfault (vm_page_t);
-void vm_page_cowsetup (vm_page_t);
+int vm_page_cowsetup(vm_page_t);
void vm_page_cowclear (vm_page_t);
/*
diff --git a/sys/i386/include/xen/evtchn.h b/sys/xen/evtchn.h
index f86a8ab..721742f 100644
--- a/sys/i386/include/xen/evtchn.h
+++ b/sys/xen/evtchn.h
@@ -12,7 +12,7 @@
#ifndef __ASM_EVTCHN_H__
#define __ASM_EVTCHN_H__
#include <machine/pcpu.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/synch_bitops.h>
#include <machine/frame.h>
diff --git a/sys/xen/evtchn/evtchn.c b/sys/xen/evtchn/evtchn.c
index b28315c..884270c 100644
--- a/sys/xen/evtchn/evtchn.c
+++ b/sys/xen/evtchn/evtchn.c
@@ -23,10 +23,10 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
#include <machine/xen/synch_bitops.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/hypervisor.h>
#include <sys/smp.h>
@@ -76,6 +76,7 @@ static struct mtx irq_mapping_update_lock;
static struct xenpic *xp;
struct xenpic_intsrc {
struct intsrc xp_intsrc;
+ void *xp_cookie;
uint8_t xp_vector;
boolean_t xp_masked;
};
@@ -295,6 +296,7 @@ bind_caller_port_to_irq(unsigned int caller_port)
}
irq_bindcount[irq]++;
+ unmask_evtchn(caller_port);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -320,6 +322,7 @@ bind_local_port_to_irq(unsigned int local_port)
evtchn_to_irq[local_port] = irq;
irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
irq_bindcount[irq]++;
+ unmask_evtchn(local_port);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -361,7 +364,7 @@ static int
bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
- int evtchn, irq;
+ int evtchn = 0, irq;
mtx_lock_spin(&irq_mapping_update_lock);
@@ -385,6 +388,7 @@ bind_virq_to_irq(unsigned int virq, unsigned int cpu)
}
irq_bindcount[irq]++;
+ unmask_evtchn(evtchn);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -398,8 +402,9 @@ int
bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
struct evtchn_bind_ipi bind_ipi;
- int evtchn, irq;
-
+ int irq;
+ int evtchn = 0;
+
mtx_lock_spin(&irq_mapping_update_lock);
if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
@@ -418,6 +423,7 @@ bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
bind_evtchn_to_cpu(evtchn, cpu);
}
irq_bindcount[irq]++;
+ unmask_evtchn(evtchn);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -465,20 +471,25 @@ bind_caller_port_to_irqhandler(unsigned int caller_port,
driver_intr_t handler,
void *arg,
unsigned long irqflags,
- void **cookiep)
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_caller_port_to_irq(caller_port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, NULL, handler, arg, irqflags, cookiep);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
+ &xp->xp_pins[irq].xp_cookie);
+
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+
+ return (0);
}
int
@@ -488,43 +499,50 @@ bind_listening_port_to_irqhandler(
driver_intr_t handler,
void *arg,
unsigned long irqflags,
- void **cookiep)
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_listening_port_to_irq(remote_domain);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, NULL, handler, arg, irqflags, cookiep);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
+ &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
-
- return irq;
+ if (irqp)
+ *irqp = irq;
+
+ return (0);
}
int
bind_interdomain_evtchn_to_irqhandler(
- unsigned int remote_domain,
- unsigned int remote_port,
- const char *devname,
- driver_filter_t filter,
- driver_intr_t handler,
- unsigned long irqflags)
+ unsigned int remote_domain,
+ unsigned int remote_port,
+ const char *devname,
+ driver_filter_t filter,
+ driver_intr_t handler,
+ unsigned long irqflags,
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, filter, handler, NULL, irqflags, NULL);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, filter, handler, NULL,
+ irqflags, &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+ return (0);
}
int
@@ -533,20 +551,25 @@ bind_virq_to_irqhandler(unsigned int virq,
const char *devname,
driver_filter_t filter,
driver_intr_t handler,
- unsigned long irqflags)
+ void *arg,
+ unsigned long irqflags,
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_virq_to_irq(virq, cpu);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, filter, handler, NULL, irqflags, NULL);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, filter, handler,
+ arg, irqflags, &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+ return (0);
}
int
@@ -554,27 +577,30 @@ bind_ipi_to_irqhandler(unsigned int ipi,
unsigned int cpu,
const char *devname,
driver_filter_t filter,
- unsigned long irqflags)
+ unsigned long irqflags,
+ unsigned int *irqp)
{
- int irq, retval;
+ unsigned int irq;
+ int error;
irq = bind_ipi_to_irq(ipi, cpu);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, filter, NULL,
- NULL, irqflags, NULL);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, filter, NULL,
+ NULL, irqflags, &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+ return (0);
}
void
-unbind_from_irqhandler(unsigned int irq, void *dev_id)
+unbind_from_irqhandler(unsigned int irq)
{
- if (dev_id)
- intr_remove_handler(dev_id); /* XXX */
+ intr_remove_handler(xp->xp_pins[irq].xp_cookie);
unbind_from_irq(irq);
}
diff --git a/sys/xen/evtchn/evtchn_dev.c b/sys/xen/evtchn/evtchn_dev.c
index 111b066..ea12860 100644
--- a/sys/xen/evtchn/evtchn_dev.c
+++ b/sys/xen/evtchn/evtchn_dev.c
@@ -26,13 +26,13 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/xen/synch_bitops.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <xen/evtchn.h>
typedef struct evtchn_sotfc {
diff --git a/sys/xen/features.c b/sys/xen/features.c
index 51d6899..876a7d1 100644
--- a/sys/xen/features.c
+++ b/sys/xen/features.c
@@ -3,7 +3,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/features.h>
uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32] /* __read_mostly */;
diff --git a/sys/xen/gnttab.c b/sys/xen/gnttab.c
index fdd3d1b..9675655 100644
--- a/sys/xen/gnttab.c
+++ b/sys/xen/gnttab.c
@@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/synch_bitops.h>
#include <xen/gnttab.h>
@@ -70,14 +70,14 @@ static int gnttab_expand(unsigned int req_entries);
#define gnttab_entry(entry) (gnttab_list[(entry) / RPP][(entry) % RPP])
static int
-get_free_entries(int count)
+get_free_entries(int count, int *entries)
{
int ref, rc;
grant_ref_t head;
mtx_lock(&gnttab_list_lock);
if ((gnttab_free_count < count) &&
- ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) {
+ ((rc = gnttab_expand(count - gnttab_free_count)) != 0)) {
mtx_unlock(&gnttab_list_lock);
return (rc);
}
@@ -88,10 +88,10 @@ get_free_entries(int count)
gnttab_free_head = gnttab_entry(head);
gnttab_entry(head) = GNTTAB_LIST_END;
mtx_unlock(&gnttab_list_lock);
- return (ref);
-}
-#define get_free_entry() get_free_entries(1)
+ *entries = ref;
+ return (0);
+}
static void
do_free_callbacks(void)
@@ -138,19 +138,25 @@ put_free_entry(grant_ref_t ref)
*/
int
-gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
+gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly,
+ grant_ref_t *result)
{
- int ref;
+ int error, ref;
- if (unlikely((ref = get_free_entry()) == -1))
- return -ENOSPC;
+ error = get_free_entries(1, &ref);
+
+ if (unlikely(error))
+ return (error);
shared[ref].frame = frame;
shared[ref].domid = domid;
wmb();
shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
- return ref;
+ if (result)
+ *result = ref;
+
+ return (0);
}
void
@@ -209,10 +215,11 @@ gnttab_end_foreign_access(grant_ref_t ref, void *page)
int
gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
{
- int ref;
-
- if (unlikely((ref = get_free_entry()) == -1))
- return -ENOSPC;
+ int error, ref;
+
+ error = get_free_entries(1, &ref);
+ if (unlikely(error))
+ return (error);
gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
@@ -300,14 +307,14 @@ gnttab_free_grant_references(grant_ref_t head)
int
gnttab_alloc_grant_references(uint16_t count, grant_ref_t *head)
{
- int h = get_free_entries(count);
+ int ref, error;
- if (h == -1)
- return -ENOSPC;
+ error = get_free_entries(count, &ref);
+ if (unlikely(error))
+ return (error);
- *head = h;
-
- return 0;
+ *head = ref;
+ return (0);
}
int
@@ -322,7 +329,7 @@ gnttab_claim_grant_reference(grant_ref_t *private_head)
grant_ref_t g = *private_head;
if (unlikely(g == GNTTAB_LIST_END))
- return -ENOSPC;
+ return (ENOSPC);
*private_head = gnttab_entry(g);
return (g);
@@ -468,7 +475,7 @@ gnttab_map(unsigned int start_idx, unsigned int end_idx)
frames = malloc(nr_gframes * sizeof(unsigned long), M_DEVBUF, M_NOWAIT);
if (!frames)
- return -ENOMEM;
+ return (ENOMEM);
setup.dom = DOMID_SELF;
setup.nr_frames = nr_gframes;
@@ -477,7 +484,7 @@ gnttab_map(unsigned int start_idx, unsigned int end_idx)
rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
if (rc == -ENOSYS) {
free(frames, M_DEVBUF);
- return -ENOSYS;
+ return (ENOSYS);
}
PANIC_IF(rc || setup.status);
@@ -529,7 +536,7 @@ gnttab_expand(unsigned int req_entries)
extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
GREFS_PER_GRANT_FRAME);
if (cur + extra > max_nr_grant_frames())
- return -ENOSPC;
+ return (ENOSPC);
if ((rc = gnttab_map(cur, cur + extra - 1)) == 0)
rc = grow_gnttab_list(extra);
@@ -561,7 +568,7 @@ gnttab_init()
M_DEVBUF, M_NOWAIT);
if (gnttab_list == NULL)
- return -ENOMEM;
+ return (ENOMEM);
for (i = 0; i < nr_grant_frames; i++) {
gnttab_list[i] = (grant_ref_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
@@ -569,8 +576,8 @@ gnttab_init()
goto ini_nomem;
}
- if (gnttab_resume() < 0)
- return -ENODEV;
+ if (gnttab_resume())
+ return (ENODEV);
nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
@@ -588,7 +595,7 @@ ini_nomem:
for (i--; i >= 0; i--)
free(gnttab_list[i], M_DEVBUF);
free(gnttab_list, M_DEVBUF);
- return -ENOMEM;
+ return (ENOMEM);
}
diff --git a/sys/xen/gnttab.h b/sys/xen/gnttab.h
index d1abe14..bcefbbc 100644
--- a/sys/xen/gnttab.h
+++ b/sys/xen/gnttab.h
@@ -36,10 +36,9 @@
#ifndef __ASM_GNTTAB_H__
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <xen/interface/grant_table.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
#include <machine/xen/features.h>
struct gnttab_free_callback {
@@ -52,7 +51,7 @@ struct gnttab_free_callback {
int gnttab_init(void);
int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
- int flags);
+ int flags, grant_ref_t *result);
/*
* End access through the given grant reference, iff the grant entry is no
diff --git a/sys/i386/include/xen/hypervisor.h b/sys/xen/hypervisor.h
index 7f7ca20..369b0c4 100644
--- a/sys/i386/include/xen/hypervisor.h
+++ b/sys/xen/hypervisor.h
@@ -4,6 +4,8 @@
* Linux-specific hypervisor handling.
*
* Copyright (c) 2002, K A Fraser
+ *
+ * $FreeBSD$
*/
#ifndef __HYPERVISOR_H__
diff --git a/sys/i386/include/xen/xen_intr.h b/sys/xen/xen_intr.h
index a0e6c88..528fa7f 100644
--- a/sys/i386/include/xen/xen_intr.h
+++ b/sys/xen/xen_intr.h
@@ -34,28 +34,31 @@ extern void unbind_from_irq(int irq);
extern int bind_caller_port_to_irqhandler(unsigned int caller_port,
const char *devname, driver_intr_t handler, void *arg,
- unsigned long irqflags, void **cookiep);
+ unsigned long irqflags, unsigned int *irqp);
extern int bind_listening_port_to_irqhandler(unsigned int remote_domain,
const char *devname, driver_intr_t handler, void *arg, unsigned long irqflags,
- void **cookiep);
-extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, const char *devname,
- driver_filter_t filter, driver_intr_t handler, unsigned long irqflags);
+ unsigned int *irqp);
+extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
+ const char *devname, driver_filter_t filter, driver_intr_t handler,
+ void *arg, unsigned long irqflags, unsigned int *irqp);
extern int bind_ipi_to_irqhandler(unsigned int ipi,
unsigned int cpu,
const char *devname,
driver_filter_t handler,
- unsigned long irqflags);
+ unsigned long irqflags,
+ unsigned int *irqp);
extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
unsigned int remote_port,
const char *devname,
driver_filter_t filter,
driver_intr_t handler,
- unsigned long irqflags);
+ unsigned long irqflags,
+ unsigned int *irqp);
-extern void unbind_from_irqhandler(unsigned int evtchn, void *dev_id);
+extern void unbind_from_irqhandler(unsigned int evtchn);
static __inline__ int irq_cannonicalize(int irq)
{
return (irq == 2) ? 9 : irq;
diff --git a/sys/xen/xenbus/xenbus_client.c b/sys/xen/xenbus/xenbus_client.c
index d8a1a3f..740d664 100644
--- a/sys/xen/xenbus/xenbus_client.c
+++ b/sys/xen/xenbus/xenbus_client.c
@@ -44,19 +44,14 @@ __FBSDID("$FreeBSD$");
#include <sys/libkern.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <xen/evtchn.h>
#include <xen/gnttab.h>
#include <xen/xenbus/xenbusvar.h>
#include <machine/stdarg.h>
-
-#define EXPORT_SYMBOL(x)
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define kfree(ptr) free(ptr, M_DEVBUF)
-#define BUG_ON PANIC_IF
-
-
-const char *xenbus_strstate(XenbusState state)
+const char *
+xenbus_strstate(XenbusState state)
{
static const char *const name[] = {
[ XenbusStateUnknown ] = "Unknown",
@@ -67,121 +62,108 @@ const char *xenbus_strstate(XenbusState state)
[ XenbusStateClosing ] = "Closing",
[ XenbusStateClosed ] = "Closed",
};
- return (state < (XenbusStateClosed + 1)) ? name[state] : "INVALID";
+
+ return ((state < (XenbusStateClosed + 1)) ? name[state] : "INVALID");
}
int
-xenbus_watch_path(device_t dev, char *path,
- struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int))
+xenbus_watch_path(device_t dev, char *path, struct xenbus_watch *watch,
+ void (*callback)(struct xenbus_watch *, const char **, unsigned int))
{
- int err;
+ int error;
watch->node = path;
watch->callback = callback;
- err = register_xenbus_watch(watch);
+ error = register_xenbus_watch(watch);
- if (err) {
+ if (error) {
watch->node = NULL;
watch->callback = NULL;
- xenbus_dev_fatal(dev, err, "adding watch on %s", path);
+ xenbus_dev_fatal(dev, error, "adding watch on %s", path);
}
- return err;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_watch_path);
-
-int xenbus_watch_path2(device_t dev, const char *path,
- const char *path2, struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int))
+int
+xenbus_watch_path2(device_t dev, const char *path,
+ const char *path2, struct xenbus_watch *watch,
+ void (*callback)(struct xenbus_watch *, const char **, unsigned int))
{
- int err;
- char *state =
- kmalloc(strlen(path) + 1 + strlen(path2) + 1, GFP_KERNEL);
- if (!state) {
- xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
- return -ENOMEM;
- }
+ int error;
+ char *state = malloc(strlen(path) + 1 + strlen(path2) + 1,
+ M_DEVBUF, M_WAITOK);
+
strcpy(state, path);
strcat(state, "/");
strcat(state, path2);
- err = xenbus_watch_path(dev, state, watch, callback);
-
- if (err) {
- kfree(state);
+ error = xenbus_watch_path(dev, state, watch, callback);
+ if (error) {
+ free(state, M_DEVBUF);
}
- return err;
+
+ return (error);
}
-EXPORT_SYMBOL(xenbus_watch_path2);
/**
* Return the path to the error node for the given device, or NULL on failure.
* If the value returned is non-NULL, then it is the caller's to kfree.
*/
-static char *error_path(device_t dev)
+static char *
+error_path(device_t dev)
{
- char *path_buffer = kmalloc(strlen("error/")
- + strlen(xenbus_get_node(dev)) +
- 1, GFP_KERNEL);
- if (path_buffer == NULL) {
- return NULL;
- }
+ char *path_buffer = malloc(strlen("error/")
+ + strlen(xenbus_get_node(dev)) + 1, M_DEVBUF, M_WAITOK);
strcpy(path_buffer, "error/");
strcpy(path_buffer + strlen("error/"), xenbus_get_node(dev));
- return path_buffer;
+ return (path_buffer);
}
-static void _dev_error(device_t dev, int err, const char *fmt,
- va_list ap)
+static void
+_dev_error(device_t dev, int err, const char *fmt, va_list ap)
{
int ret;
unsigned int len;
char *printf_buffer = NULL, *path_buffer = NULL;
#define PRINTF_BUFFER_SIZE 4096
- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
- if (printf_buffer == NULL)
- goto fail;
+ printf_buffer = malloc(PRINTF_BUFFER_SIZE, M_DEVBUF, M_WAITOK);
- len = sprintf(printf_buffer, "%i ", -err);
+ len = sprintf(printf_buffer, "%i ", err);
ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
- BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
+ KASSERT(len + ret <= PRINTF_BUFFER_SIZE-1, ("xenbus error message too big"));
#if 0
dev_err(&dev->dev, "%s\n", printf_buffer);
#endif
path_buffer = error_path(dev);
if (path_buffer == NULL) {
- printk("xenbus: failed to write error node for %s (%s)\n",
+ printf("xenbus: failed to write error node for %s (%s)\n",
xenbus_get_node(dev), printf_buffer);
goto fail;
}
if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
- printk("xenbus: failed to write error node for %s (%s)\n",
+ printf("xenbus: failed to write error node for %s (%s)\n",
xenbus_get_node(dev), printf_buffer);
goto fail;
}
fail:
if (printf_buffer)
- kfree(printf_buffer);
+ free(printf_buffer, M_DEVBUF);
if (path_buffer)
- kfree(path_buffer);
+ free(path_buffer, M_DEVBUF);
}
-
-void xenbus_dev_error(device_t dev, int err, const char *fmt,
- ...)
+void
+xenbus_dev_error(device_t dev, int err, const char *fmt, ...)
{
va_list ap;
@@ -189,11 +171,9 @@ void xenbus_dev_error(device_t dev, int err, const char *fmt,
_dev_error(dev, err, fmt, ap);
va_end(ap);
}
-EXPORT_SYMBOL(xenbus_dev_error);
-
-void xenbus_dev_fatal(device_t dev, int err, const char *fmt,
- ...)
+void
+xenbus_dev_fatal(device_t dev, int err, const char *fmt, ...)
{
va_list ap;
@@ -203,21 +183,26 @@ void xenbus_dev_fatal(device_t dev, int err, const char *fmt,
xenbus_set_state(dev, XenbusStateClosing);
}
-EXPORT_SYMBOL(xenbus_dev_fatal);
-
-int xenbus_grant_ring(device_t dev, unsigned long ring_mfn)
+int
+xenbus_grant_ring(device_t dev, unsigned long ring_mfn, int *refp)
{
- int err = gnttab_grant_foreign_access(
- xenbus_get_otherend_id(dev), ring_mfn, 0);
- if (err < 0)
- xenbus_dev_fatal(dev, err, "granting access to ring page");
- return err;
-}
-EXPORT_SYMBOL(xenbus_grant_ring);
+ int error;
+ grant_ref_t ref;
+
+ error = gnttab_grant_foreign_access(
+ xenbus_get_otherend_id(dev), ring_mfn, 0, &ref);
+ if (error) {
+ xenbus_dev_fatal(dev, error, "granting access to ring page");
+ return (error);
+ }
+ *refp = ref;
+ return (0);
+}
-int xenbus_alloc_evtchn(device_t dev, int *port)
+int
+xenbus_alloc_evtchn(device_t dev, int *port)
{
struct evtchn_alloc_unbound alloc_unbound;
int err;
@@ -228,16 +213,16 @@ int xenbus_alloc_evtchn(device_t dev, int *port)
err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
&alloc_unbound);
- if (err)
- xenbus_dev_fatal(dev, err, "allocating event channel");
- else
- *port = alloc_unbound.port;
- return err;
+ if (err) {
+ xenbus_dev_fatal(dev, -err, "allocating event channel");
+ return (-err);
+ }
+ *port = alloc_unbound.port;
+ return (0);
}
-EXPORT_SYMBOL(xenbus_alloc_evtchn);
-
-int xenbus_free_evtchn(device_t dev, int port)
+int
+xenbus_free_evtchn(device_t dev, int port)
{
struct evtchn_close close;
int err;
@@ -245,32 +230,22 @@ int xenbus_free_evtchn(device_t dev, int port)
close.port = port;
err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
- if (err)
- xenbus_dev_error(dev, err, "freeing event channel %d", port);
- return err;
+ if (err) {
+ xenbus_dev_error(dev, -err, "freeing event channel %d", port);
+ return (-err);
+ }
+ return (0);
}
-EXPORT_SYMBOL(xenbus_free_evtchn);
-
-XenbusState xenbus_read_driver_state(const char *path)
+XenbusState
+xenbus_read_driver_state(const char *path)
{
XenbusState result;
+ int error;
- int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
- if (err)
+ error = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
+ if (error)
result = XenbusStateClosed;
- return result;
+ return (result);
}
-EXPORT_SYMBOL(xenbus_read_driver_state);
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_comms.c b/sys/xen/xenbus/xenbus_comms.c
index 90f0ea9..2f03955 100644
--- a/sys/xen/xenbus/xenbus_comms.c
+++ b/sys/xen/xenbus/xenbus_comms.c
@@ -33,217 +33,194 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
-#include <sys/time.h>
-#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/xen_intr.h>
-#include <xen/xenbus/xenbus_comms.h>
-#include <xen/interface/io/xs_wire.h>
+#include <xen/hypervisor.h>
-static int xenbus_irq;
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
+#include <xen/interface/io/xs_wire.h>
+#include <xen/xenbus/xenbus_comms.h>
-extern void xenbus_probe(void *);
-extern int xenstored_ready;
-#if 0
-static DECLARE_WORK(probe_work, xenbus_probe, NULL);
-#endif
-int xb_wait;
-extern char *xen_store;
-#define wake_up wakeup
-#define xb_waitq xb_wait
-#define pr_debug(a,b,c)
+static unsigned int xenstore_irq;
-static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
+static inline struct xenstore_domain_interface *
+xenstore_domain_interface(void)
{
- return (struct xenstore_domain_interface *)xen_store;
+
+ return (struct xenstore_domain_interface *)xen_store;
}
static void
-wake_waiting(void * arg __attribute__((unused)))
+xb_intr(void * arg __attribute__((unused)))
{
-#if 0
- if (unlikely(xenstored_ready == 0)) {
- xenstored_ready = 1;
- schedule_work(&probe_work);
- }
-#endif
- wakeup(&xb_wait);
-}
-static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-{
- return ((prod - cons) <= XENSTORE_RING_SIZE);
+ wakeup(xen_store);
}
-static void *get_output_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- char *buf, uint32_t *len)
+static int
+xb_check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
- if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
- *len = XENSTORE_RING_SIZE - (prod - cons);
- return buf + MASK_XENSTORE_IDX(prod);
-}
-static const void *get_input_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- const char *buf, uint32_t *len)
-{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
- if ((prod - cons) < *len)
- *len = prod - cons;
- return buf + MASK_XENSTORE_IDX(cons);
+ return ((prod - cons) <= XENSTORE_RING_SIZE);
}
-int xb_write(const void *tdata, unsigned len)
+static void *
+xb_get_output_chunk(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod,
+ char *buf, uint32_t *len)
{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
- const char *data = (const char *)tdata;
-
- while (len != 0) {
- void *dst;
- unsigned int avail;
-
- wait_event_interruptible(&xb_waitq,
- (intf->req_prod - intf->req_cons) !=
- XENSTORE_RING_SIZE);
-
- /* Read indexes, then verify. */
- cons = intf->req_cons;
- prod = intf->req_prod;
- mb();
- if (!check_indexes(cons, prod)) {
- intf->req_cons = intf->req_prod = 0;
- return -EIO;
- }
-
- dst = get_output_chunk(cons, prod, intf->req, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
- mb();
-
- memcpy(dst, data, avail);
- data += avail;
- len -= avail;
-
- /* Other side must not see new header until data is there. */
- wmb();
- intf->req_prod += avail;
- /* This implies mb() before other side sees interrupt. */
- notify_remote_via_evtchn(xen_start_info->store_evtchn);
- }
-
- return 0;
+ *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
+ if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
+ *len = XENSTORE_RING_SIZE - (prod - cons);
+ return (buf + MASK_XENSTORE_IDX(prod));
}
-#ifdef notyet
-int xb_data_to_read(void)
+static const void *
+xb_get_input_chunk(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod,
+ const char *buf, uint32_t *len)
{
- struct xenstore_domain_interface *intf = xen_store_interface;
- return (intf->rsp_cons != intf->rsp_prod);
-}
-int xb_wait_for_data_to_read(void)
-{
- return wait_event_interruptible(xb_waitq, xb_data_to_read());
+ *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
+ if ((prod - cons) < *len)
+ *len = prod - cons;
+ return (buf + MASK_XENSTORE_IDX(cons));
}
-#endif
-
-int xb_read(void *tdata, unsigned len)
+int
+xb_write(const void *tdata, unsigned len, struct lock_object *lock)
{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
- char *data = (char *)tdata;
-
- while (len != 0) {
- unsigned int avail;
- const char *src;
-
- wait_event_interruptible(&xb_waitq,
- intf->rsp_cons != intf->rsp_prod);
-
- /* Read indexes, then verify. */
- cons = intf->rsp_cons;
- prod = intf->rsp_prod;
- if (!check_indexes(cons, prod)) {
- intf->rsp_cons = intf->rsp_prod = 0;
- return -EIO;
- }
-
- src = get_input_chunk(cons, prod, intf->rsp, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
-
- /* We must read header before we read data. */
- rmb();
+ struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ XENSTORE_RING_IDX cons, prod;
+ const char *data = (const char *)tdata;
+ int error;
+
+ while (len != 0) {
+ void *dst;
+ unsigned int avail;
+
+ while ((intf->req_prod - intf->req_cons)
+ == XENSTORE_RING_SIZE) {
+ error = _sleep(intf,
+ lock,
+ PCATCH, "xbwrite", hz/10);
+ if (error && error != EWOULDBLOCK)
+ return (error);
+ }
- memcpy(data, src, avail);
- data += avail;
- len -= avail;
+ /* Read indexes, then verify. */
+ cons = intf->req_cons;
+ prod = intf->req_prod;
+ mb();
+ if (!xb_check_indexes(cons, prod)) {
+ intf->req_cons = intf->req_prod = 0;
+ return (EIO);
+ }
- /* Other side must not see free space until we've copied out */
- mb();
- intf->rsp_cons += avail;
+ dst = xb_get_output_chunk(cons, prod, intf->req, &avail);
+ if (avail == 0)
+ continue;
+ if (avail > len)
+ avail = len;
+ mb();
+
+ memcpy(dst, data, avail);
+ data += avail;
+ len -= avail;
- pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
+ /* Other side must not see new header until data is there. */
+ wmb();
+ intf->req_prod += avail;
- /* Implies mb(): they will see new header. */
- notify_remote_via_evtchn(xen_start_info->store_evtchn);
- }
+ /* This implies mb() before other side sees interrupt. */
+ notify_remote_via_evtchn(xen_store_evtchn);
+ }
- return 0;
+ return (0);
}
-/* Set up interrupt handler off store event channel. */
-int xb_init_comms(void)
+int
+xb_read(void *tdata, unsigned len, struct lock_object *lock)
{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- int err;
-
- if (intf->rsp_prod != intf->rsp_cons) {
- log(LOG_WARNING, "XENBUS response ring is not quiescent "
- "(%08x:%08x): fixing up\n",
- intf->rsp_cons, intf->rsp_prod);
- intf->rsp_cons = intf->rsp_prod;
+ struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ XENSTORE_RING_IDX cons, prod;
+ char *data = (char *)tdata;
+ int error;
+
+ while (len != 0) {
+ unsigned int avail;
+ const char *src;
+
+ while (intf->rsp_cons == intf->rsp_prod) {
+ error = _sleep(intf, lock,
+ PCATCH, "xbread", hz/10);
+ if (error && error != EWOULDBLOCK)
+ return (error);
}
+
+ /* Read indexes, then verify. */
+ cons = intf->rsp_cons;
+ prod = intf->rsp_prod;
+ if (!xb_check_indexes(cons, prod)) {
+ intf->rsp_cons = intf->rsp_prod = 0;
+ return (EIO);
+ }
+
+ src = xb_get_input_chunk(cons, prod, intf->rsp, &avail);
+ if (avail == 0)
+ continue;
+ if (avail > len)
+ avail = len;
- if (xenbus_irq)
- unbind_from_irqhandler(xenbus_irq, &xb_waitq);
+ /* We must read header before we read data. */
+ rmb();
- err = bind_caller_port_to_irqhandler(
- xen_start_info->store_evtchn,
- "xenbus", wake_waiting, NULL, INTR_TYPE_NET, NULL);
- if (err <= 0) {
- log(LOG_WARNING, "XENBUS request irq failed %i\n", err);
- return err;
- }
+ memcpy(data, src, avail);
+ data += avail;
+ len -= avail;
+
+ /* Other side must not see free space until we've copied out */
+ mb();
+ intf->rsp_cons += avail;
- xenbus_irq = err;
+ /* Implies mb(): they will see new header. */
+ notify_remote_via_evtchn(xen_store_evtchn);
+ }
- return 0;
+ return (0);
}
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
+/* Set up interrupt handler off store event channel. */
+int
+xb_init_comms(void)
+{
+ struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ int error;
+
+ if (intf->rsp_prod != intf->rsp_cons) {
+ log(LOG_WARNING, "XENBUS response ring is not quiescent "
+ "(%08x:%08x): fixing up\n",
+ intf->rsp_cons, intf->rsp_prod);
+ intf->rsp_cons = intf->rsp_prod;
+ }
+
+ if (xenstore_irq)
+ unbind_from_irqhandler(xenstore_irq);
+
+ error = bind_caller_port_to_irqhandler(
+ xen_store_evtchn, "xenbus",
+ xb_intr, NULL, INTR_TYPE_NET, &xenstore_irq);
+ if (error) {
+ log(LOG_WARNING, "XENBUS request irq failed %i\n", error);
+ return (error);
+ }
+
+ return (0);
+}
diff --git a/sys/xen/xenbus/xenbus_comms.h b/sys/xen/xenbus/xenbus_comms.h
index 94a57dc..fa47331 100644
--- a/sys/xen/xenbus/xenbus_comms.h
+++ b/sys/xen/xenbus/xenbus_comms.h
@@ -30,123 +30,19 @@
#ifndef _XENBUS_COMMS_H
#define _XENBUS_COMMS_H
+struct sx;
+extern int xen_store_evtchn;
+extern char *xen_store;
+
int xs_init(void);
int xb_init_comms(void);
/* Low level routines. */
-int xb_write(const void *data, unsigned len);
-int xb_read(void *data, unsigned len);
-int xs_input_avail(void);
-extern int xb_waitq;
+int xb_write(const void *data, unsigned len, struct lock_object *);
+int xb_read(void *data, unsigned len, struct lock_object *);
extern int xenbus_running;
-#define __wait_event_interruptible(wchan, condition, ret) \
-do { \
- for (;;) { \
- if (xenbus_running == 0) { \
- break; \
- } \
- if (condition) \
- break; \
- if ((ret = !tsleep(wchan, PWAIT | PCATCH, "waitev", hz/10))) \
- break; \
- } \
-} while (0)
-
-
-#define wait_event_interruptible(wchan, condition) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_event_interruptible(wchan, condition, __ret); \
- __ret; \
-})
-
-
-
-#define DECLARE_MUTEX(lock) struct sema lock
-#define semaphore sema
-#define rw_semaphore sema
-
-#define down sema_wait
-#define up sema_post
-#define down_read sema_wait
-#define up_read sema_post
-#define down_write sema_wait
-#define up_write sema_post
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-/*
- * XXX
- *
- */
-
-#define GFP_KERNEL 1
-#define EXPORT_SYMBOL(x)
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define kfree(ptr) free((void *)(uintptr_t)ptr, M_DEVBUF)
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
-#define wake_up wakeup
-#define BUS_ID_SIZE 128
-
-struct xen_bus_type
-{
- char *root;
- unsigned int levels;
- int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
- int (*probe)(const char *type, const char *dir);
- struct xendev_list_head *bus;
- int error;
-#if 0
- struct bus_type bus;
- struct device dev;
-#endif
-};
-
-
-#if 0
-
-void dev_changed(const char *node, struct xen_bus_type *bus);
-
-int
-read_otherend_details(struct xenbus_device *xendev, char *id_node,
- char *path_node);
-#endif
-
char *kasprintf(const char *fmt, ...);
-
-
#endif /* _XENBUS_COMMS_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_dev.c b/sys/xen/xenbus/xenbus_dev.c
index 52e0b67..ac3f103 100644
--- a/sys/xen/xenbus/xenbus_dev.c
+++ b/sys/xen/xenbus/xenbus_dev.c
@@ -45,19 +45,10 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <xen/xenbus/xenbusvar.h>
#include <xen/xenbus/xenbus_comms.h>
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define simple_strtoul strtoul
-
struct xenbus_dev_transaction {
LIST_ENTRY(xenbus_dev_transaction) list;
struct xenbus_transaction handle;
@@ -78,62 +69,65 @@ struct xenbus_dev_data {
#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
char read_buffer[PAGE_SIZE];
unsigned int read_cons, read_prod;
- int read_waitq;
};
-#if 0
-static struct proc_dir_entry *xenbus_dev_intf;
-#endif
+
static int
xenbus_dev_read(struct cdev *dev, struct uio *uio, int ioflag)
{
- int i = 0;
+ int error;
struct xenbus_dev_data *u = dev->si_drv1;
- if (wait_event_interruptible(&u->read_waitq,
- u->read_prod != u->read_cons))
- return EINTR;
+ while (u->read_prod == u->read_cons) {
+ error = tsleep(u, PCATCH, "xbdread", hz/10);
+ if (error && error != EWOULDBLOCK)
+ return (error);
+ }
- for (i = 0; i < uio->uio_iov[0].iov_len; i++) {
+ while (uio->uio_resid > 0) {
if (u->read_cons == u->read_prod)
break;
- copyout(&u->read_buffer[MASK_READ_IDX(u->read_cons)], (char *)uio->uio_iov[0].iov_base+i, 1);
+ error = uiomove(&u->read_buffer[MASK_READ_IDX(u->read_cons)],
+ 1, uio);
+ if (error)
+ return (error);
u->read_cons++;
- uio->uio_resid--;
}
- return 0;
+ return (0);
}
-static void queue_reply(struct xenbus_dev_data *u,
- char *data, unsigned int len)
+static void
+queue_reply(struct xenbus_dev_data *u, char *data, unsigned int len)
{
int i;
for (i = 0; i < len; i++, u->read_prod++)
u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
- BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
+ KASSERT((u->read_prod - u->read_cons) <= sizeof(u->read_buffer),
+ ("xenstore reply too big"));
- wakeup(&u->read_waitq);
+ wakeup(u);
}
static int
xenbus_dev_write(struct cdev *dev, struct uio *uio, int ioflag)
{
- int err = 0;
+ int error;
struct xenbus_dev_data *u = dev->si_drv1;
struct xenbus_dev_transaction *trans;
void *reply;
- int len = uio->uio_iov[0].iov_len;
+ int len = uio->uio_resid;
if ((len + u->len) > sizeof(u->u.buffer))
- return EINVAL;
+ return (EINVAL);
- if (copyin(u->u.buffer + u->len, uio->uio_iov[0].iov_base, len) != 0)
- return EFAULT;
+ error = uiomove(u->u.buffer + u->len, len, uio);
+ if (error)
+ return (error);
u->len += len;
if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
- return len;
+ return (0);
switch (u->u.msg.type) {
case XS_TRANSACTION_START:
@@ -147,67 +141,59 @@ xenbus_dev_write(struct cdev *dev, struct uio *uio, int ioflag)
case XS_MKDIR:
case XS_RM:
case XS_SET_PERMS:
- reply = xenbus_dev_request_and_reply(&u->u.msg);
- if (IS_ERR(reply)) {
- err = PTR_ERR(reply);
- } else {
+ error = xenbus_dev_request_and_reply(&u->u.msg, &reply);
+ if (!error) {
if (u->u.msg.type == XS_TRANSACTION_START) {
- trans = kmalloc(sizeof(*trans), GFP_KERNEL);
- trans->handle.id = simple_strtoul(reply, NULL, 0);
+ trans = malloc(sizeof(*trans), M_DEVBUF,
+ M_WAITOK);
+ trans->handle.id = strtoul(reply, NULL, 0);
LIST_INSERT_HEAD(&u->transactions, trans, list);
} else if (u->u.msg.type == XS_TRANSACTION_END) {
- LIST_FOREACH(trans, &u->transactions,
- list)
- if (trans->handle.id ==
- u->u.msg.tx_id)
+ LIST_FOREACH(trans, &u->transactions, list)
+ if (trans->handle.id == u->u.msg.tx_id)
break;
#if 0 /* XXX does this mean the list is empty? */
BUG_ON(&trans->list == &u->transactions);
#endif
LIST_REMOVE(trans, list);
- kfree(trans);
+ free(trans, M_DEVBUF);
}
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
queue_reply(u, (char *)reply, u->u.msg.len);
- kfree(reply);
+ free(reply, M_DEVBUF);
}
break;
default:
- err = EINVAL;
+ error = EINVAL;
break;
}
- if (err == 0) {
+ if (error == 0)
u->len = 0;
- err = len;
- }
- return err;
+ return (error);
}
-static int xenbus_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+static int
+xenbus_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
struct xenbus_dev_data *u;
- if (xen_start_info->store_evtchn == 0)
- return ENOENT;
+ if (xen_store_evtchn == 0)
+ return (ENOENT);
#if 0 /* XXX figure out if equiv needed */
nonseekable_open(inode, filp);
#endif
- u = kmalloc(sizeof(*u), GFP_KERNEL);
- if (u == NULL)
- return ENOMEM;
-
- memset(u, 0, sizeof(*u));
+ u = malloc(sizeof(*u), M_DEVBUF, M_WAITOK|M_ZERO);
LIST_INIT(&u->transactions);
-
dev->si_drv1 = u;
- return 0;
+ return (0);
}
-static int xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+static int
+xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
{
struct xenbus_dev_data *u = dev->si_drv1;
struct xenbus_dev_transaction *trans, *tmp;
@@ -215,11 +201,11 @@ static int xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thr
LIST_FOREACH_SAFE(trans, &u->transactions, list, tmp) {
xenbus_transaction_end(trans->handle, 1);
LIST_REMOVE(trans, list);
- kfree(trans);
+ free(trans, M_DEVBUF);
}
- kfree(u);
- return 0;
+ free(u, M_DEVBUF);
+ return (0);
}
static struct cdevsw xenbus_dev_cdevsw = {
@@ -234,21 +220,10 @@ static struct cdevsw xenbus_dev_cdevsw = {
static int
xenbus_dev_sysinit(void)
{
- make_dev(&xenbus_dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0400, "xenbus");
+ make_dev(&xenbus_dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0400,
+ "xen/xenbus");
- return 0;
+ return (0);
}
-SYSINIT(xenbus_dev_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, xenbus_dev_sysinit, NULL);
-/* SYSINIT NEEDED XXX */
-
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
+SYSINIT(xenbus_dev_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE,
+ xenbus_dev_sysinit, NULL);
diff --git a/sys/xen/xenbus/xenbus_probe.c b/sys/xen/xenbus/xenbus_probe.c
index e57e6e3..3d2cb4b 100644
--- a/sys/xen/xenbus/xenbus_probe.c
+++ b/sys/xen/xenbus/xenbus_probe.c
@@ -88,9 +88,7 @@ kasprintf(const char *fmt, ...)
len = vsnprintf(dummy, 0, fmt, ap);
va_end(ap);
- p = kmalloc(len + 1, GFP_KERNEL);
- if (!p)
- return NULL;
+ p = malloc(len + 1, M_DEVBUF, M_WAITOK);
va_start(ap, fmt);
vsprintf(p, fmt, ap);
va_end(ap);
@@ -187,6 +185,7 @@ xenbus_add_device(device_t dev, const char *bus,
struct xenbus_device_ivars *ivars;
enum xenbus_state state;
char *statepath;
+ int error;
ivars = malloc(sizeof(struct xenbus_device_ivars),
M_DEVBUF, M_ZERO|M_WAITOK);
@@ -217,17 +216,19 @@ xenbus_add_device(device_t dev, const char *bus,
/*
* Find the backend details
*/
- xenbus_gather(XBT_NIL, ivars->xd_node,
+ error = xenbus_gather(XBT_NIL, ivars->xd_node,
"backend-id", "%i", &ivars->xd_otherend_id,
"backend", NULL, &ivars->xd_otherend_path,
NULL);
+ if (error)
+ return (error);
sx_init(&ivars->xd_lock, "xdlock");
ivars->xd_type = strdup(type, M_DEVBUF);
ivars->xd_state = XenbusStateInitialising;
statepath = malloc(strlen(ivars->xd_otherend_path)
- + strlen("/state") + 1, M_DEVBUF, M_NOWAIT);
+ + strlen("/state") + 1, M_DEVBUF, M_WAITOK);
sprintf(statepath, "%s/state", ivars->xd_otherend_path);
ivars->xd_otherend_watch.node = statepath;
@@ -245,10 +246,11 @@ xenbus_enumerate_type(device_t dev, const char *bus, const char *type)
{
char **dir;
unsigned int i, count;
+ int error;
- dir = xenbus_directory(XBT_NIL, bus, type, &count);
- if (IS_ERR(dir))
- return (EINVAL);
+ error = xenbus_directory(XBT_NIL, bus, type, &count, &dir);
+ if (error)
+ return (error);
for (i = 0; i < count; i++)
xenbus_add_device(dev, bus, type, dir[i]);
@@ -262,10 +264,11 @@ xenbus_enumerate_bus(device_t dev, const char *bus)
{
char **dir;
unsigned int i, count;
+ int error;
- dir = xenbus_directory(XBT_NIL, bus, "", &count);
- if (IS_ERR(dir))
- return (EINVAL);
+ error = xenbus_directory(XBT_NIL, bus, "", &count, &dir);
+ if (error)
+ return (error);
for (i = 0; i < count; i++) {
xenbus_enumerate_type(dev, bus, dir[i]);
}
@@ -386,28 +389,90 @@ xenbus_attach(device_t dev)
return (0);
}
-static void
+static int
xenbus_suspend(device_t dev)
{
+ int error;
+
DPRINTK("");
- panic("implement me");
-#if 0
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
-#endif
+
+ error = bus_generic_suspend(dev);
+ if (error)
+ return (error);
+
xs_suspend();
+
+ return (0);
}
-static void
+static int
xenbus_resume(device_t dev)
{
+ device_t *kids;
+ struct xenbus_device_ivars *ivars;
+ int i, count, error;
+ char *statepath;
+
xb_init_comms();
xs_resume();
- panic("implement me");
+
+ /*
+ * We must re-examine each device and find the new path for
+ * its backend.
+ */
+ if (device_get_children(dev, &kids, &count) == 0) {
+ for (i = 0; i < count; i++) {
+ if (device_get_state(kids[i]) == DS_NOTPRESENT)
+ continue;
+
+ ivars = device_get_ivars(kids[i]);
+
+ unregister_xenbus_watch(
+ &ivars->xd_otherend_watch);
+ ivars->xd_state = XenbusStateInitialising;
+
+ /*
+ * Find the new backend details and
+ * re-register our watch.
+ */
+ free(ivars->xd_otherend_path, M_DEVBUF);
+ error = xenbus_gather(XBT_NIL, ivars->xd_node,
+ "backend-id", "%i", &ivars->xd_otherend_id,
+ "backend", NULL, &ivars->xd_otherend_path,
+ NULL);
+ if (error)
+ return (error);
+
+ DEVICE_RESUME(kids[i]);
+
+ statepath = malloc(strlen(ivars->xd_otherend_path)
+ + strlen("/state") + 1, M_DEVBUF, M_WAITOK);
+ sprintf(statepath, "%s/state", ivars->xd_otherend_path);
+
+ free(ivars->xd_otherend_watch.node, M_DEVBUF);
+ ivars->xd_otherend_watch.node = statepath;
+ register_xenbus_watch(
+ &ivars->xd_otherend_watch);
+
#if 0
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
-#endif
+ /*
+ * Can't do this yet since we are running in
+ * the xenwatch thread and if we sleep here,
+ * we will stop delivering watch notifications
+ * and the device will never come back online.
+ */
+ sx_xlock(&ivars->xd_lock);
+ while (ivars->xd_state != XenbusStateClosed
+ && ivars->xd_state != XenbusStateConnected)
+ sx_sleep(&ivars->xd_state, &ivars->xd_lock,
+ 0, "xdresume", 0);
+ sx_xunlock(&ivars->xd_lock);
+#endif
+ }
+ free(kids, M_TEMP);
+ }
+
+ return (0);
}
static int
@@ -433,9 +498,11 @@ xenbus_read_ivar(device_t dev, device_t child, int index,
case XENBUS_IVAR_NODE:
*result = (uintptr_t) ivars->xd_node;
return (0);
+
case XENBUS_IVAR_TYPE:
*result = (uintptr_t) ivars->xd_type;
return (0);
+
case XENBUS_IVAR_STATE:
*result = (uintptr_t) ivars->xd_state;
return (0);
@@ -468,8 +535,8 @@ xenbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
goto out;
error = xenbus_scanf(XBT_NIL, ivars->xd_node, "state",
- "%d", &currstate);
- if (error < 0)
+ NULL, "%d", &currstate);
+ if (error)
goto out;
error = xenbus_printf(XBT_NIL, ivars->xd_node, "state",
@@ -494,15 +561,14 @@ xenbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
*/
return (EINVAL);
}
+
return (ENOENT);
}
SYSCTL_DECL(_dev);
SYSCTL_NODE(_dev, OID_AUTO, xen, CTLFLAG_RD, NULL, "Xen");
-#if 0
SYSCTL_INT(_dev_xen, OID_AUTO, xsd_port, CTLFLAG_RD, &xen_store_evtchn, 0, "");
SYSCTL_ULONG(_dev_xen, OID_AUTO, xsd_kva, CTLFLAG_RD, (u_long *) &xen_store, 0, "");
-#endif
static device_method_t xenbus_methods[] = {
/* Device interface */
diff --git a/sys/xen/xenbus/xenbus_probe_backend.c b/sys/xen/xenbus/xenbus_probe_backend.c
index af83fe6..20cc49f 100644
--- a/sys/xen/xenbus/xenbus_probe_backend.c
+++ b/sys/xen/xenbus/xenbus_probe_backend.c
@@ -57,10 +57,11 @@ __FBSDID("$FreeBSD$");
#include <sys/sx.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <machine/xen/xenbus.h>
#include <machine/stdarg.h>
+#include <xen/evtchn.h>
#include <xen/xenbus/xenbus_comms.h>
#define BUG_ON PANIC_IF
diff --git a/sys/xen/xenbus/xenbus_xs.c b/sys/xen/xenbus/xenbus_xs.c
index 332a509..9e0f779 100644
--- a/sys/xen/xenbus/xenbus_xs.c
+++ b/sys/xen/xenbus/xenbus_xs.c
@@ -33,91 +33,77 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/unistd.h>
-#include <sys/errno.h>
#include <sys/uio.h>
#include <sys/kernel.h>
-#include <sys/time.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sx.h>
-#include <sys/sema.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
-#include <sys/libkern.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/kthread.h>
+#include <sys/unistd.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/stdarg.h>
#include <xen/xenbus/xenbusvar.h>
#include <xen/xenbus/xenbus_comms.h>
-static int xs_process_msg(enum xsd_sockmsg_type *type);
+#include <xen/interface/hvm/params.h>
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define BUG_ON PANIC_IF
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+static int xs_process_msg(enum xsd_sockmsg_type *type);
-#define streq(a, b) (strcmp((a), (b)) == 0)
int xenwatch_running = 0;
int xenbus_running = 0;
-
-struct kvec {
- const void *iov_base;
- size_t iov_len;
-};
+int xen_store_evtchn;
struct xs_stored_msg {
- TAILQ_ENTRY(xs_stored_msg) list;
-
- struct xsd_sockmsg hdr;
-
- union {
- /* Queued replies. */
- struct {
- char *body;
- } reply;
-
- /* Queued watch events. */
- struct {
- struct xenbus_watch *handle;
- char **vec;
- unsigned int vec_size;
- } watch;
- } u;
+ TAILQ_ENTRY(xs_stored_msg) list;
+
+ struct xsd_sockmsg hdr;
+
+ union {
+ /* Queued replies. */
+ struct {
+ char *body;
+ } reply;
+
+ /* Queued watch events. */
+ struct {
+ struct xenbus_watch *handle;
+ char **vec;
+ unsigned int vec_size;
+ } watch;
+ } u;
};
struct xs_handle {
- /* A list of replies. Currently only one will ever be outstanding. */
- TAILQ_HEAD(xs_handle_list, xs_stored_msg) reply_list;
- struct mtx reply_lock;
- int reply_waitq;
+ /* A list of replies. Currently only one will ever be outstanding. */
+ TAILQ_HEAD(xs_handle_list, xs_stored_msg) reply_list;
+ struct mtx reply_lock;
+ int reply_waitq;
- /* One request at a time. */
- struct sx request_mutex;
+ /* One request at a time. */
+ struct sx request_mutex;
- /* Protect transactions against save/restore. */
- struct sx suspend_mutex;
+ /* Protect transactions against save/restore. */
+ struct sx suspend_mutex;
};
static struct xs_handle xs_state;
/* List of registered watches, and a lock to protect it. */
static LIST_HEAD(watch_list_head, xenbus_watch) watches;
-static DEFINE_SPINLOCK(watches_lock);
+static struct mtx watches_lock;
/* List of pending watch callback events, and a lock to protect it. */
static TAILQ_HEAD(event_list_head, xs_stored_msg) watch_events;
-static DEFINE_SPINLOCK(watch_events_lock);
+static struct mtx watch_events_lock;
+
/*
* Details of the xenwatch callback kernel thread. The thread waits on the
* watch_events_waitq for work to do (queued on watch_events list). When it
@@ -128,831 +114,814 @@ static pid_t xenwatch_pid;
struct sx xenwatch_mutex;
static int watch_events_waitq;
-static int get_error(const char *errorstring)
+#define xsd_error_count (sizeof(xsd_errors) / sizeof(xsd_errors[0]))
+
+static int
+xs_get_error(const char *errorstring)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
- if (i == ARRAY_SIZE(xsd_errors) - 1) {
- log(LOG_WARNING, "XENBUS xen store gave: unknown error %s",
- errorstring);
- return EINVAL;
- }
- }
- return xsd_errors[i].errnum;
+ for (i = 0; i < xsd_error_count; i++) {
+ if (!strcmp(errorstring, xsd_errors[i].errstring))
+ return (xsd_errors[i].errnum);
+ }
+ log(LOG_WARNING, "XENBUS xen store gave: unknown error %s",
+ errorstring);
+ return (EINVAL);
}
-extern void idle_block(void);
extern void kdb_backtrace(void);
-static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
+static int
+xs_read_reply(enum xsd_sockmsg_type *type, unsigned int *len, void **result)
{
- struct xs_stored_msg *msg;
- char *body;
- int i, err;
- enum xsd_sockmsg_type itype = *type;
-
- printf("read_reply ");
- if (xenbus_running == 0) {
- /*
- * Give other domain time to run :-/
- */
- for (i = 0; i < 1000000 && (xenbus_running == 0); i++) {
- err = xs_process_msg(type);
-
- if ((err == 0)
- && (*type != XS_WATCH_EVENT))
- break;
-
- HYPERVISOR_yield();
+ struct xs_stored_msg *msg;
+ char *body;
+ int error;
+
+ mtx_lock(&xs_state.reply_lock);
+
+ while (TAILQ_EMPTY(&xs_state.reply_list)) {
+ while (TAILQ_EMPTY(&xs_state.reply_list)) {
+ error = mtx_sleep(&xs_state.reply_waitq,
+ &xs_state.reply_lock,
+ PCATCH, "xswait", hz/10);
+ if (error && error != EWOULDBLOCK) {
+ mtx_unlock(&xs_state.reply_lock);
+ return (error);
}
- if (list_empty(&xs_state.reply_list)) {
- printf("giving up and returning an error type=%d\n",
- *type);
- kdb_backtrace();
- return (ERR_PTR(-1));
- }
+ }
+
}
- mtx_lock(&xs_state.reply_lock);
- if (xenbus_running) {
- while (list_empty(&xs_state.reply_list)) {
- mtx_unlock(&xs_state.reply_lock);
- wait_event_interruptible(&xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list));
-
- mtx_lock(&xs_state.reply_lock);
- }
- }
- msg = TAILQ_FIRST(&xs_state.reply_list);
- list_del(&xs_state.reply_list, msg);
+ msg = TAILQ_FIRST(&xs_state.reply_list);
+ TAILQ_REMOVE(&xs_state.reply_list, msg, list);
- mtx_unlock(&xs_state.reply_lock);
+ mtx_unlock(&xs_state.reply_lock);
- printf("itype=%d htype=%d ", itype, msg->hdr.type);
- *type = msg->hdr.type;
- if (len)
- *len = msg->hdr.len;
- body = msg->u.reply.body;
+ *type = msg->hdr.type;
+ if (len)
+ *len = msg->hdr.len;
+ body = msg->u.reply.body;
- kfree(msg);
- if (len)
- printf("len=%d\n", *len);
- else
- printf("len=NULL\n");
- return body;
+ free(msg, M_DEVBUF);
+ *result = body;
+ return (0);
}
#if 0
/* Emergency write. UNUSED*/
void xenbus_debug_write(const char *str, unsigned int count)
{
- struct xsd_sockmsg msg = { 0 };
+ struct xsd_sockmsg msg = { 0 };
- msg.type = XS_DEBUG;
- msg.len = sizeof("print") + count + 1;
+ msg.type = XS_DEBUG;
+ msg.len = sizeof("print") + count + 1;
- sx_xlock(&xs_state.request_mutex);
- xb_write(&msg, sizeof(msg));
- xb_write("print", sizeof("print"));
- xb_write(str, count);
- xb_write("", 1);
- sx_xunlock(&xs_state.request_mutex);
+ sx_xlock(&xs_state.request_mutex);
+ xb_write(&msg, sizeof(msg));
+ xb_write("print", sizeof("print"));
+ xb_write(str, count);
+ xb_write("", 1);
+ sx_xunlock(&xs_state.request_mutex);
}
#endif
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
+
+int
+xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void **result)
{
- void *ret;
- struct xsd_sockmsg req_msg = *msg;
- int err;
+ struct xsd_sockmsg req_msg = *msg;
+ int error;
- if (req_msg.type == XS_TRANSACTION_START)
- sx_slock(&xs_state.suspend_mutex);
+ if (req_msg.type == XS_TRANSACTION_START)
+ sx_slock(&xs_state.suspend_mutex);
- sx_xlock(&xs_state.request_mutex);
+ sx_xlock(&xs_state.request_mutex);
- err = xb_write(msg, sizeof(*msg) + msg->len);
- if (err) {
- msg->type = XS_ERROR;
- ret = ERR_PTR(err);
- } else {
- ret = read_reply(&msg->type, &msg->len);
- }
+ error = xb_write(msg, sizeof(*msg) + msg->len, &xs_state.request_mutex.lock_object);
+ if (error) {
+ msg->type = XS_ERROR;
+ } else {
+ error = xs_read_reply(&msg->type, &msg->len, result);
+ }
- sx_xunlock(&xs_state.request_mutex);
+ sx_xunlock(&xs_state.request_mutex);
- if ((msg->type == XS_TRANSACTION_END) ||
- ((req_msg.type == XS_TRANSACTION_START) &&
- (msg->type == XS_ERROR)))
- sx_sunlock(&xs_state.suspend_mutex);
+ if ((msg->type == XS_TRANSACTION_END) ||
+ ((req_msg.type == XS_TRANSACTION_START) &&
+ (msg->type == XS_ERROR)))
+ sx_sunlock(&xs_state.suspend_mutex);
- return ret;
+ return (error);
}
-static int xenwatch_inline;
-
-/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction t,
- enum xsd_sockmsg_type type,
- const struct kvec *iovec,
- unsigned int num_vecs,
- unsigned int *len)
+/*
+ * Send message to xs. The reply is returned in *result and should be
+ * fred with free(*result, M_DEVBUF). Return zero on success or an
+ * error code on failure.
+ */
+static int
+xs_talkv(struct xenbus_transaction t, enum xsd_sockmsg_type type,
+ const struct iovec *iovec, unsigned int num_vecs,
+ unsigned int *len, void **result)
{
- struct xsd_sockmsg msg;
- void *ret = NULL;
- unsigned int i;
- int err;
-
- msg.tx_id = t.id;
- msg.req_id = 0;
- msg.type = type;
- msg.len = 0;
- for (i = 0; i < num_vecs; i++)
- msg.len += iovec[i].iov_len;
-
- printf("xs_talkv ");
-
- sx_xlock(&xs_state.request_mutex);
-
- err = xb_write(&msg, sizeof(msg));
- if (err) {
- sx_xunlock(&xs_state.request_mutex);
- printf("xs_talkv failed %d\n", err);
- return ERR_PTR(err);
- }
-
- for (i = 0; i < num_vecs; i++) {
- err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
- if (err) {
- sx_xunlock(&xs_state.request_mutex);
- printf("xs_talkv failed %d\n", err);
- return ERR_PTR(err);
- }
+ struct xsd_sockmsg msg;
+ void *ret = NULL;
+ unsigned int i;
+ int error;
+
+ msg.tx_id = t.id;
+ msg.req_id = 0;
+ msg.type = type;
+ msg.len = 0;
+ for (i = 0; i < num_vecs; i++)
+ msg.len += iovec[i].iov_len;
+
+ sx_xlock(&xs_state.request_mutex);
+
+ error = xb_write(&msg, sizeof(msg), &xs_state.request_mutex.lock_object);
+ if (error) {
+ sx_xunlock(&xs_state.request_mutex);
+ printf("xs_talkv failed %d\n", error);
+ return (error);
+ }
+
+ for (i = 0; i < num_vecs; i++) {
+ error = xb_write(iovec[i].iov_base, iovec[i].iov_len, &xs_state.request_mutex.lock_object);
+ if (error) {
+ sx_xunlock(&xs_state.request_mutex);
+ printf("xs_talkv failed %d\n", error);
+ return (error);
}
+ }
- ret = read_reply(&msg.type, len);
+ error = xs_read_reply(&msg.type, len, &ret);
- sx_xunlock(&xs_state.request_mutex);
+ sx_xunlock(&xs_state.request_mutex);
- if (IS_ERR(ret))
- return ret;
+ if (error)
+ return (error);
- if (msg.type == XS_ERROR) {
- err = get_error(ret);
- kfree(ret);
- return ERR_PTR(-err);
- }
+ if (msg.type == XS_ERROR) {
+ error = xs_get_error(ret);
+ free(ret, M_DEVBUF);
+ return (error);
+ }
- if ((xenwatch_running == 0) && (xenwatch_inline == 0)) {
- xenwatch_inline = 1;
- while (!TAILQ_EMPTY(&watch_events)
- && xenwatch_running == 0) {
+#if 0
+ if ((xenwatch_running == 0) && (xenwatch_inline == 0)) {
+ xenwatch_inline = 1;
+ while (!TAILQ_EMPTY(&watch_events)
+ && xenwatch_running == 0) {
- struct xs_stored_msg *wmsg = TAILQ_FIRST(&watch_events);
- list_del(&watch_events, wmsg);
- printf("handling %p ...", wmsg->u.watch.handle->callback);
+ struct xs_stored_msg *wmsg = TAILQ_FIRST(&watch_events);
+ TAILQ_REMOVE(&watch_events, wmsg, list);
- wmsg->u.watch.handle->callback(
- wmsg->u.watch.handle,
- (const char **)wmsg->u.watch.vec,
- wmsg->u.watch.vec_size);
- printf("... %p done\n", wmsg->u.watch.handle->callback);
- kfree(wmsg->u.watch.vec);
- kfree(wmsg);
- }
- xenwatch_inline = 0;
+ wmsg->u.watch.handle->callback(
+ wmsg->u.watch.handle,
+ (const char **)wmsg->u.watch.vec,
+ wmsg->u.watch.vec_size);
+ free(wmsg->u.watch.vec, M_DEVBUF);
+ free(wmsg, M_DEVBUF);
}
- BUG_ON(msg.type != type);
+ xenwatch_inline = 0;
+ }
+#endif
+ KASSERT(msg.type == type, ("bad xenstore message type"));
- return ret;
+ if (result)
+ *result = ret;
+ else
+ free(ret, M_DEVBUF);
+
+ return (0);
}
/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction t,
- enum xsd_sockmsg_type type,
- const char *string,
- unsigned int *len)
+static int
+xs_single(struct xenbus_transaction t, enum xsd_sockmsg_type type,
+ const char *string, unsigned int *len, void **result)
{
- struct kvec iovec;
+ struct iovec iovec;
- printf("xs_single %s ", string);
- iovec.iov_base = (const void *)string;
- iovec.iov_len = strlen(string) + 1;
- return xs_talkv(t, type, &iovec, 1, len);
-}
+ iovec.iov_base = (void *)(uintptr_t) string;
+ iovec.iov_len = strlen(string) + 1;
-/* Many commands only need an ack, don't care what it says. */
-static int xs_error(char *reply)
-{
- if (IS_ERR(reply))
- return PTR_ERR(reply);
- kfree(reply);
- return 0;
+ return (xs_talkv(t, type, &iovec, 1, len, result));
}
-static unsigned int count_strings(const char *strings, unsigned int len)
+static unsigned int
+count_strings(const char *strings, unsigned int len)
{
- unsigned int num;
- const char *p;
+ unsigned int num;
+ const char *p;
- for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
- num++;
+ for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
+ num++;
- return num;
+ return num;
}
/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
-static char *join(const char *dir, const char *name)
+static char *
+join(const char *dir, const char *name)
{
- char *buffer;
+ char *buffer;
- buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1,
- GFP_KERNEL);
- if (buffer == NULL)
- return ERR_PTR(-ENOMEM);
+ buffer = malloc(strlen(dir) + strlen("/") + strlen(name) + 1,
+ M_DEVBUF, M_WAITOK);
- strcpy(buffer, dir);
- if (!streq(name, "")) {
- strcat(buffer, "/");
- strcat(buffer, name);
- }
+ strcpy(buffer, dir);
+ if (strcmp(name, "")) {
+ strcat(buffer, "/");
+ strcat(buffer, name);
+ }
- return buffer;
+ return (buffer);
}
-static char **split(char *strings, unsigned int len, unsigned int *num)
+static char **
+split(char *strings, unsigned int len, unsigned int *num)
{
- char *p, **ret;
+ char *p, **ret;
- /* Count the strings. */
- *num = count_strings(strings, len) + 1;
+ /* Count the strings. */
+ *num = count_strings(strings, len) + 1;
- /* Transfer to one big alloc for easy freeing. */
- ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL);
- if (!ret) {
- kfree(strings);
- return ERR_PTR(-ENOMEM);
- }
- memcpy(&ret[*num], strings, len);
- kfree(strings);
+ /* Transfer to one big alloc for easy freeing. */
+ ret = malloc(*num * sizeof(char *) + len, M_DEVBUF, M_WAITOK);
+ memcpy(&ret[*num], strings, len);
+ free(strings, M_DEVBUF);
- strings = (char *)&ret[*num];
- for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
- ret[(*num)++] = p;
+ strings = (char *)&ret[*num];
+ for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
+ ret[(*num)++] = p;
- ret[*num] = strings + len;
+ ret[*num] = strings + len;
- return ret;
+ return ret;
}
-char **xenbus_directory(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *num)
+/*
+ * Return the contents of a directory in *result which should be freed
+ * with free(*result, M_DEVBUF).
+ */
+int
+xenbus_directory(struct xenbus_transaction t, const char *dir,
+ const char *node, unsigned int *num, char ***result)
{
- char *strings, *path;
- unsigned int len = 0;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (char **)path;
+ char *strings, *path;
+ unsigned int len = 0;
+ int error;
- strings = xs_single(t, XS_DIRECTORY, path, &len);
- kfree(path);
- if (IS_ERR(strings))
- return (char **)strings;
+ path = join(dir, node);
+ error = xs_single(t, XS_DIRECTORY, path, &len, (void **) &strings);
+ free(path, M_DEVBUF);
+ if (error)
+ return (error);
- return split(strings, len, num);
+ *result = split(strings, len, num);
+ return (0);
}
-EXPORT_SYMBOL(xenbus_directory);
-/* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction t,
- const char *dir, const char *node)
+/*
+ * Check if a path exists. Return 1 if it does.
+ */
+int
+xenbus_exists(struct xenbus_transaction t, const char *dir, const char *node)
{
- char **d;
- int dir_n;
+ char **d;
+ int error, dir_n;
- d = xenbus_directory(t, dir, node, &dir_n);
- if (IS_ERR(d))
- return 0;
- kfree(d);
- return 1;
+ error = xenbus_directory(t, dir, node, &dir_n, &d);
+ if (error)
+ return (0);
+ free(d, M_DEVBUF);
+ return (1);
}
-EXPORT_SYMBOL(xenbus_exists);
-/* Get the value of a single file.
- * Returns a kmalloced value: call free() on it after use.
- * len indicates length in bytes.
+/*
+ * Get the value of a single file. Returns the contents in *result
+ * which should be freed with free(*result, M_DEVBUF) after use.
+ * The length of the value in bytes is returned in *len.
*/
-void *xenbus_read(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *len)
+int
+xenbus_read(struct xenbus_transaction t, const char *dir, const char *node,
+ unsigned int *len, void **result)
{
- char *path;
- void *ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (void *)path;
+ char *path;
+ void *ret;
+ int error;
- printf("xs_read ");
- ret = xs_single(t, XS_READ, path, len);
- kfree(path);
- return ret;
+ path = join(dir, node);
+ error = xs_single(t, XS_READ, path, len, &ret);
+ free(path, M_DEVBUF);
+ if (error)
+ return (error);
+ *result = ret;
+ return (0);
}
-EXPORT_SYMBOL(xenbus_read);
-/* Write the value of a single file.
- * Returns -err on failure.
+/*
+ * Write the value of a single file. Returns error on failure.
*/
-int xenbus_write(struct xenbus_transaction t,
- const char *dir, const char *node, const char *string)
+int
+xenbus_write(struct xenbus_transaction t, const char *dir, const char *node,
+ const char *string)
{
- char *path;
- struct kvec iovec[2];
- int ret;
+ char *path;
+ struct iovec iovec[2];
+ int error;
+
+ path = join(dir, node);
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
+ iovec[0].iov_base = (void *)(uintptr_t) path;
+ iovec[0].iov_len = strlen(path) + 1;
+ iovec[1].iov_base = (void *)(uintptr_t) string;
+ iovec[1].iov_len = strlen(string);
- iovec[0].iov_base = path;
- iovec[0].iov_len = strlen(path) + 1;
- iovec[1].iov_base = string;
- iovec[1].iov_len = strlen(string);
+ error = xs_talkv(t, XS_WRITE, iovec, 2, NULL, NULL);
+ free(path, M_DEVBUF);
- printf("xenbus_write dir=%s val=%s ", dir, string);
- ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
- kfree(path);
- return ret;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_write);
-/* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction t,
- const char *dir, const char *node)
+/*
+ * Create a new directory.
+ */
+int
+xenbus_mkdir(struct xenbus_transaction t, const char *dir, const char *node)
{
- char *path;
- int ret;
+ char *path;
+ int ret;
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
+ path = join(dir, node);
+ ret = xs_single(t, XS_MKDIR, path, NULL, NULL);
+ free(path, M_DEVBUF);
- ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
- kfree(path);
- return ret;
+ return (ret);
}
-EXPORT_SYMBOL(xenbus_mkdir);
-/* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
+/*
+ * Destroy a file or directory (directories must be empty).
+ */
+int
+xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
{
- char *path;
- int ret;
+ char *path;
+ int ret;
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
+ path = join(dir, node);
+ ret = xs_single(t, XS_RM, path, NULL, NULL);
+ free(path, M_DEVBUF);
- ret = xs_error(xs_single(t, XS_RM, path, NULL));
- kfree(path);
- return ret;
+ return (ret);
}
-EXPORT_SYMBOL(xenbus_rm);
-/* Start a transaction: changes by others will not be seen during this
+/*
+ * Start a transaction: changes by others will not be seen during this
* transaction, and changes will not be visible to others until end.
*/
-int xenbus_transaction_start(struct xenbus_transaction *t)
+int
+xenbus_transaction_start(struct xenbus_transaction *t)
{
- char *id_str;
+ char *id_str;
+ int error;
- sx_slock(&xs_state.suspend_mutex);
- id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
- if (IS_ERR(id_str)) {
- sx_sunlock(&xs_state.suspend_mutex);
- return PTR_ERR(id_str);
- }
+ sx_slock(&xs_state.suspend_mutex);
+ error = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL,
+ (void **) &id_str);
+ if (error) {
+ sx_sunlock(&xs_state.suspend_mutex);
+ return (error);
+ }
- t->id = simple_strtoul(id_str, NULL, 0);
- kfree(id_str);
+ t->id = strtoul(id_str, NULL, 0);
+ free(id_str, M_DEVBUF);
- return 0;
+ return (0);
}
-EXPORT_SYMBOL(xenbus_transaction_start);
-/* End a transaction.
- * If abandon is true, transaction is discarded instead of committed.
+/*
+ * End a transaction. If abandon is true, transaction is discarded
+ * instead of committed.
*/
int xenbus_transaction_end(struct xenbus_transaction t, int abort)
{
- char abortstr[2];
- int err;
+ char abortstr[2];
+ int error;
- if (abort)
- strcpy(abortstr, "F");
- else
- strcpy(abortstr, "T");
+ if (abort)
+ strcpy(abortstr, "F");
+ else
+ strcpy(abortstr, "T");
- printf("xenbus_transaction_end ");
- err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
+ error = xs_single(t, XS_TRANSACTION_END, abortstr, NULL, NULL);
- sx_sunlock(&xs_state.suspend_mutex);
+ sx_sunlock(&xs_state.suspend_mutex);
- return err;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_transaction_end);
-/* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
+/* Single read and scanf: returns zero or errno. */
+int
+xenbus_scanf(struct xenbus_transaction t,
+ const char *dir, const char *node, int *scancountp, const char *fmt, ...)
{
- va_list ap;
- int ret;
- char *val;
-
- val = xenbus_read(t, dir, node, NULL);
- if (IS_ERR(val))
- return PTR_ERR(val);
-
- va_start(ap, fmt);
- ret = vsscanf(val, fmt, ap);
- va_end(ap);
- kfree(val);
- /* Distinctive errno. */
- if (ret == 0)
- return -ERANGE;
- return ret;
-}
-EXPORT_SYMBOL(xenbus_scanf);
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
+ va_list ap;
+ int error, ns;
+ char *val;
+
+ error = xenbus_read(t, dir, node, NULL, (void **) &val);
+ if (error)
+ return (error);
+
+ va_start(ap, fmt);
+ ns = vsscanf(val, fmt, ap);
+ va_end(ap);
+ free(val, M_DEVBUF);
+ /* Distinctive errno. */
+ if (ns == 0)
+ return (ERANGE);
+ if (scancountp)
+ *scancountp = ns;
+ return (0);
+}
+
+/* Single printf and write: returns zero or errno. */
+int
+xenbus_printf(struct xenbus_transaction t,
+ const char *dir, const char *node, const char *fmt, ...)
{
- va_list ap;
- int ret;
+ va_list ap;
+ int error, ret;
#define PRINTF_BUFFER_SIZE 4096
- char *printf_buffer;
+ char *printf_buffer;
- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
- if (printf_buffer == NULL)
- return -ENOMEM;
+ printf_buffer = malloc(PRINTF_BUFFER_SIZE, M_DEVBUF, M_WAITOK);
- va_start(ap, fmt);
- ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
- va_end(ap);
+ va_start(ap, fmt);
+ ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
+ va_end(ap);
- BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
- ret = xenbus_write(t, dir, node, printf_buffer);
+ KASSERT(ret <= PRINTF_BUFFER_SIZE-1, ("xenbus_printf: message too large"));
+ error = xenbus_write(t, dir, node, printf_buffer);
- kfree(printf_buffer);
+ free(printf_buffer, M_DEVBUF);
- return ret;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_printf);
/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
+int
+xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
{
- va_list ap;
- const char *name;
- int i, ret = 0;
+ va_list ap;
+ const char *name;
+ int error, i;
- for (i = 0; i < 10000; i++)
- HYPERVISOR_yield();
+ for (i = 0; i < 10000; i++)
+ HYPERVISOR_yield();
- printf("gather ");
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- p = xenbus_read(t, dir, name, NULL);
- if (IS_ERR(p)) {
- ret = PTR_ERR(p);
- break;
- }
- printf(" %s ", p);
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
- ret = -EINVAL;
- kfree(p);
- } else
- *(char **)result = p;
- }
- va_end(ap);
- printf("\n");
- return ret;
-}
-EXPORT_SYMBOL(xenbus_gather);
-
-static int xs_watch(const char *path, const char *token)
+ va_start(ap, dir);
+ error = 0;
+ while (error == 0 && (name = va_arg(ap, char *)) != NULL) {
+ const char *fmt = va_arg(ap, char *);
+ void *result = va_arg(ap, void *);
+ char *p;
+
+ error = xenbus_read(t, dir, name, NULL, (void **) &p);
+ if (error)
+ break;
+
+ if (fmt) {
+ if (sscanf(p, fmt, result) == 0)
+ error = EINVAL;
+ free(p, M_DEVBUF);
+ } else
+ *(char **)result = p;
+ }
+ va_end(ap);
+
+ return (error);
+}
+
+static int
+xs_watch(const char *path, const char *token)
{
- struct kvec iov[2];
+ struct iovec iov[2];
- iov[0].iov_base = path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = token;
- iov[1].iov_len = strlen(token) + 1;
+ iov[0].iov_base = (void *)(uintptr_t) path;
+ iov[0].iov_len = strlen(path) + 1;
+ iov[1].iov_base = (void *)(uintptr_t) token;
+ iov[1].iov_len = strlen(token) + 1;
- return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov,
- ARRAY_SIZE(iov), NULL));
+ return (xs_talkv(XBT_NIL, XS_WATCH, iov, 2, NULL, NULL));
}
-static int xs_unwatch(const char *path, const char *token)
+static int
+xs_unwatch(const char *path, const char *token)
{
- struct kvec iov[2];
+ struct iovec iov[2];
- iov[0].iov_base = path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = token;
- iov[1].iov_len = strlen(token) + 1;
+ iov[0].iov_base = (void *)(uintptr_t) path;
+ iov[0].iov_len = strlen(path) + 1;
+ iov[1].iov_base = (void *)(uintptr_t) token;
+ iov[1].iov_len = strlen(token) + 1;
- return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov,
- ARRAY_SIZE(iov), NULL));
+ return (xs_talkv(XBT_NIL, XS_UNWATCH, iov, 2, NULL, NULL));
}
-static struct xenbus_watch *find_watch(const char *token)
+static struct xenbus_watch *
+find_watch(const char *token)
{
- struct xenbus_watch *i, *cmp;
+ struct xenbus_watch *i, *cmp;
- cmp = (void *)simple_strtoul(token, NULL, 16);
+ cmp = (void *)strtoul(token, NULL, 16);
- LIST_FOREACH(i, &watches, list)
- if (i == cmp)
- return i;
+ LIST_FOREACH(i, &watches, list)
+ if (i == cmp)
+ return (i);
- return NULL;
+ return (NULL);
}
/* Register callback to watch this node. */
-int register_xenbus_watch(struct xenbus_watch *watch)
+int
+register_xenbus_watch(struct xenbus_watch *watch)
{
- /* Pointer in ascii is the token. */
- char token[sizeof(watch) * 2 + 1];
- int err;
+ /* Pointer in ascii is the token. */
+ char token[sizeof(watch) * 2 + 1];
+ int error;
- sprintf(token, "%lX", (long)watch);
+ sprintf(token, "%lX", (long)watch);
- sx_slock(&xs_state.suspend_mutex);
+ sx_slock(&xs_state.suspend_mutex);
- mtx_lock(&watches_lock);
- BUG_ON(find_watch(token) != NULL);
- LIST_INSERT_HEAD(&watches, watch, list);
- mtx_unlock(&watches_lock);
+ mtx_lock(&watches_lock);
+ KASSERT(find_watch(token) == NULL, ("watch already registered"));
+ LIST_INSERT_HEAD(&watches, watch, list);
+ mtx_unlock(&watches_lock);
- err = xs_watch(watch->node, token);
+ error = xs_watch(watch->node, token);
- /* Ignore errors due to multiple registration. */
- if ((err != 0) && (err != -EEXIST)) {
- mtx_lock(&watches_lock);
- LIST_REMOVE(watch, list);
- mtx_unlock(&watches_lock);
- }
+ /* Ignore errors due to multiple registration. */
+ if (error == EEXIST) {
+ mtx_lock(&watches_lock);
+ LIST_REMOVE(watch, list);
+ mtx_unlock(&watches_lock);
+ }
- sx_sunlock(&xs_state.suspend_mutex);
+ sx_sunlock(&xs_state.suspend_mutex);
- return err;
+ return (error);
}
-EXPORT_SYMBOL(register_xenbus_watch);
-void unregister_xenbus_watch(struct xenbus_watch *watch)
+void
+unregister_xenbus_watch(struct xenbus_watch *watch)
{
- struct xs_stored_msg *msg, *tmp;
- char token[sizeof(watch) * 2 + 1];
- int err;
+ struct xs_stored_msg *msg, *tmp;
+ char token[sizeof(watch) * 2 + 1];
+ int error;
- sprintf(token, "%lX", (long)watch);
+ sprintf(token, "%lX", (long)watch);
- sx_slock(&xs_state.suspend_mutex);
-
- mtx_lock(&watches_lock);
- BUG_ON(!find_watch(token));
- LIST_REMOVE(watch, list);
- mtx_unlock(&watches_lock);
+ sx_slock(&xs_state.suspend_mutex);
+
+ mtx_lock(&watches_lock);
+ KASSERT(find_watch(token), ("watch not registered"));
+ LIST_REMOVE(watch, list);
+ mtx_unlock(&watches_lock);
+
+ error = xs_unwatch(watch->node, token);
+ if (error)
+ log(LOG_WARNING, "XENBUS Failed to release watch %s: %i\n",
+ watch->node, error);
+
+ sx_sunlock(&xs_state.suspend_mutex);
+
+ /* Cancel pending watch events. */
+ mtx_lock(&watch_events_lock);
+ TAILQ_FOREACH_SAFE(msg, &watch_events, list, tmp) {
+ if (msg->u.watch.handle != watch)
+ continue;
+ TAILQ_REMOVE(&watch_events, msg, list);
+ free(msg->u.watch.vec, M_DEVBUF);
+ free(msg, M_DEVBUF);
+ }
+ mtx_unlock(&watch_events_lock);
+
+ /* Flush any currently-executing callback, unless we are it. :-) */
+ if (curproc->p_pid != xenwatch_pid) {
+ sx_xlock(&xenwatch_mutex);
+ sx_xunlock(&xenwatch_mutex);
+ }
+}
+
+void
+xs_suspend(void)
+{
- err = xs_unwatch(watch->node, token);
- if (err)
- log(LOG_WARNING, "XENBUS Failed to release watch %s: %i\n",
- watch->node, err);
+ sx_xlock(&xs_state.suspend_mutex);
+ sx_xlock(&xs_state.request_mutex);
+}
- sx_sunlock(&xs_state.suspend_mutex);
+void
+xs_resume(void)
+{
+ struct xenbus_watch *watch;
+ char token[sizeof(watch) * 2 + 1];
- /* Cancel pending watch events. */
- mtx_lock(&watch_events_lock);
- TAILQ_FOREACH_SAFE(msg, &watch_events, list, tmp) {
- if (msg->u.watch.handle != watch)
- continue;
- list_del(&watch_events, msg);
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- mtx_unlock(&watch_events_lock);
+ sx_xunlock(&xs_state.request_mutex);
- /* Flush any currently-executing callback, unless we are it. :-) */
- if (curproc->p_pid != xenwatch_pid) {
- sx_xlock(&xenwatch_mutex);
- sx_xunlock(&xenwatch_mutex);
- }
-}
-EXPORT_SYMBOL(unregister_xenbus_watch);
+ /* No need for watches_lock: the suspend_mutex is sufficient. */
+ LIST_FOREACH(watch, &watches, list) {
+ sprintf(token, "%lX", (long)watch);
+ xs_watch(watch->node, token);
+ }
-void xs_suspend(void)
-{
- sx_xlock(&xs_state.suspend_mutex);
- sx_xlock(&xs_state.request_mutex);
+ sx_xunlock(&xs_state.suspend_mutex);
}
-void xs_resume(void)
+static void
+xenwatch_thread(void *unused)
{
- struct xenbus_watch *watch;
- char token[sizeof(watch) * 2 + 1];
+ struct xs_stored_msg *msg;
- sx_xunlock(&xs_state.request_mutex);
+ for (;;) {
- /* No need for watches_lock: the suspend_mutex is sufficient. */
- LIST_FOREACH(watch, &watches, list) {
- sprintf(token, "%lX", (long)watch);
- xs_watch(watch->node, token);
- }
+ mtx_lock(&watch_events_lock);
+ while (TAILQ_EMPTY(&watch_events))
+ mtx_sleep(&watch_events_waitq,
+ &watch_events_lock,
+ PWAIT | PCATCH, "waitev", hz/10);
- sx_xunlock(&xs_state.suspend_mutex);
-}
+ mtx_unlock(&watch_events_lock);
+ sx_xlock(&xenwatch_mutex);
-static void xenwatch_thread(void *unused)
-{
- struct xs_stored_msg *msg;
+ mtx_lock(&watch_events_lock);
+ msg = TAILQ_FIRST(&watch_events);
+ if (msg)
+ TAILQ_REMOVE(&watch_events, msg, list);
+ mtx_unlock(&watch_events_lock);
- DELAY(100000);
- while (xenwatch_inline) {
- printf("xenwatch inline still running\n");
- DELAY(100000);
+ if (msg != NULL) {
+ msg->u.watch.handle->callback(
+ msg->u.watch.handle,
+ (const char **)msg->u.watch.vec,
+ msg->u.watch.vec_size);
+ free(msg->u.watch.vec, M_DEVBUF);
+ free(msg, M_DEVBUF);
}
-
-
- for (;;) {
-
- while (list_empty(&watch_events))
- tsleep(&watch_events_waitq,
- PWAIT | PCATCH, "waitev", hz/10);
-
- sx_xlock(&xenwatch_mutex);
-
- mtx_lock(&watch_events_lock);
- msg = TAILQ_FIRST(&watch_events);
- if (msg)
- list_del(&watch_events, msg);
- mtx_unlock(&watch_events_lock);
-
- if (msg != NULL) {
- msg->u.watch.handle->callback(
- msg->u.watch.handle,
- (const char **)msg->u.watch.vec,
- msg->u.watch.vec_size);
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- sx_xunlock(&xenwatch_mutex);
- }
+ sx_xunlock(&xenwatch_mutex);
+ }
}
-static int xs_process_msg(enum xsd_sockmsg_type *type)
+static int
+xs_process_msg(enum xsd_sockmsg_type *type)
{
- struct xs_stored_msg *msg;
- char *body;
- int err;
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (msg == NULL)
- return -ENOMEM;
-
- err = xb_read(&msg->hdr, sizeof(msg->hdr));
- if (err) {
- kfree(msg);
- return err;
- }
-
- body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
- if (body == NULL) {
- kfree(msg);
- return -ENOMEM;
- }
+ struct xs_stored_msg *msg;
+ char *body;
+ int error;
- err = xb_read(body, msg->hdr.len);
- if (err) {
- kfree(body);
- kfree(msg);
- return err;
- }
- body[msg->hdr.len] = '\0';
-
- *type = msg->hdr.type;
- if (msg->hdr.type == XS_WATCH_EVENT) {
- msg->u.watch.vec = split(body, msg->hdr.len,
- &msg->u.watch.vec_size);
- if (IS_ERR(msg->u.watch.vec)) {
- kfree(msg);
- return PTR_ERR(msg->u.watch.vec);
- }
+ msg = malloc(sizeof(*msg), M_DEVBUF, M_WAITOK);
+ mtx_lock(&xs_state.reply_lock);
+ error = xb_read(&msg->hdr, sizeof(msg->hdr), &xs_state.reply_lock.lock_object);
+ mtx_unlock(&xs_state.reply_lock);
+ if (error) {
+ free(msg, M_DEVBUF);
+ return (error);
+ }
+
+ body = malloc(msg->hdr.len + 1, M_DEVBUF, M_WAITOK);
+ mtx_lock(&xs_state.reply_lock);
+ error = xb_read(body, msg->hdr.len, &xs_state.reply_lock.lock_object);
+ mtx_unlock(&xs_state.reply_lock);
+ if (error) {
+ free(body, M_DEVBUF);
+ free(msg, M_DEVBUF);
+ return (error);
+ }
+ body[msg->hdr.len] = '\0';
+
+ *type = msg->hdr.type;
+ if (msg->hdr.type == XS_WATCH_EVENT) {
+ msg->u.watch.vec = split(body, msg->hdr.len,
+ &msg->u.watch.vec_size);
- mtx_lock(&watches_lock);
- msg->u.watch.handle = find_watch(
- msg->u.watch.vec[XS_WATCH_TOKEN]);
- if (msg->u.watch.handle != NULL) {
- mtx_lock(&watch_events_lock);
- TAILQ_INSERT_TAIL(&watch_events, msg, list);
- wakeup(&watch_events_waitq);
- mtx_unlock(&watch_events_lock);
- } else {
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- mtx_unlock(&watches_lock);
+ mtx_lock(&watches_lock);
+ msg->u.watch.handle = find_watch(
+ msg->u.watch.vec[XS_WATCH_TOKEN]);
+ if (msg->u.watch.handle != NULL) {
+ mtx_lock(&watch_events_lock);
+ TAILQ_INSERT_TAIL(&watch_events, msg, list);
+ wakeup(&watch_events_waitq);
+ mtx_unlock(&watch_events_lock);
} else {
- printf("event=%d ", *type);
- msg->u.reply.body = body;
- mtx_lock(&xs_state.reply_lock);
- TAILQ_INSERT_TAIL(&xs_state.reply_list, msg, list);
- wakeup(&xs_state.reply_waitq);
- mtx_unlock(&xs_state.reply_lock);
+ free(msg->u.watch.vec, M_DEVBUF);
+ free(msg, M_DEVBUF);
}
- if (*type == XS_WATCH_EVENT)
- printf("\n");
+ mtx_unlock(&watches_lock);
+ } else {
+ msg->u.reply.body = body;
+ mtx_lock(&xs_state.reply_lock);
+ TAILQ_INSERT_TAIL(&xs_state.reply_list, msg, list);
+ wakeup(&xs_state.reply_waitq);
+ mtx_unlock(&xs_state.reply_lock);
+ }
- return 0;
+ return 0;
}
-static void xenbus_thread(void *unused)
+static void
+xenbus_thread(void *unused)
{
- int err;
- enum xsd_sockmsg_type type;
+ int error;
+ enum xsd_sockmsg_type type;
+ xenbus_running = 1;
- DELAY(10000);
- xenbus_running = 1;
- pause("xenbus", hz/10);
+ for (;;) {
+ error = xs_process_msg(&type);
+ if (error)
+ printf("XENBUS error %d while reading message\n",
+ error);
+ }
+}
- for (;;) {
- err = xs_process_msg(&type);
- if (err)
- printf("XENBUS error %d while reading "
- "message\n", err);
+#ifdef XENHVM
+static unsigned long xen_store_mfn;
+char *xen_store;
- }
+static inline unsigned long
+hvm_get_parameter(int index)
+{
+ struct xen_hvm_param xhv;
+ int error;
+
+ xhv.domid = DOMID_SELF;
+ xhv.index = index;
+ error = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
+ if (error) {
+ printf("hvm_get_parameter: failed to get %d, error %d\n",
+ index, error);
+ return (0);
+ }
+ return (xhv.value);
}
-int xs_init(void)
+#endif
+
+int
+xs_init(void)
{
- int err;
- struct proc *p;
+ int error;
+ struct proc *p;
+
+#ifdef XENHVM
+ xen_store_evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN);
+ xen_store_mfn = hvm_get_parameter(HVM_PARAM_STORE_PFN);
+ xen_store = pmap_mapdev(xen_store_mfn * PAGE_SIZE, PAGE_SIZE);
+#else
+ xen_store_evtchn = xen_start_info->store_evtchn;
+#endif
- TAILQ_INIT(&xs_state.reply_list);
- TAILQ_INIT(&watch_events);
- sx_init(&xenwatch_mutex, "xenwatch");
+ TAILQ_INIT(&xs_state.reply_list);
+ TAILQ_INIT(&watch_events);
+ sx_init(&xenwatch_mutex, "xenwatch");
- mtx_init(&xs_state.reply_lock, "state reply", NULL, MTX_DEF);
- sx_init(&xs_state.request_mutex, "xenstore request");
- sx_init(&xs_state.suspend_mutex, "xenstore suspend");
+ mtx_init(&xs_state.reply_lock, "state reply", NULL, MTX_DEF);
+ sx_init(&xs_state.request_mutex, "xenstore request");
+ sx_init(&xs_state.suspend_mutex, "xenstore suspend");
#if 0
- mtx_init(&xs_state.suspend_mutex, "xenstore suspend", NULL, MTX_DEF);
- sema_init(&xs_state.request_mutex, 1, "xenstore request");
- sema_init(&xenwatch_mutex, 1, "xenwatch");
+ mtx_init(&xs_state.suspend_mutex, "xenstore suspend", NULL, MTX_DEF);
+ sema_init(&xs_state.request_mutex, 1, "xenstore request");
+ sema_init(&xenwatch_mutex, 1, "xenwatch");
#endif
- mtx_init(&watches_lock, "watches", NULL, MTX_DEF);
- mtx_init(&watch_events_lock, "watch events", NULL, MTX_DEF);
+ mtx_init(&watches_lock, "watches", NULL, MTX_DEF);
+ mtx_init(&watch_events_lock, "watch events", NULL, MTX_DEF);
- /* Initialize the shared memory rings to talk to xenstored */
- err = xb_init_comms();
- if (err)
- return err;
-
- err = kproc_create(xenwatch_thread, NULL, &p,
- RFHIGHPID, 0, "xenwatch");
- if (err)
- return err;
- xenwatch_pid = p->p_pid;
-
- err = kproc_create(xenbus_thread, NULL, NULL,
- RFHIGHPID, 0, "xenbus");
+ /* Initialize the shared memory rings to talk to xenstored */
+ error = xb_init_comms();
+ if (error)
+ return (error);
+
+ xenwatch_running = 1;
+ error = kproc_create(xenwatch_thread, NULL, &p,
+ RFHIGHPID, 0, "xenwatch");
+ if (error)
+ return (error);
+ xenwatch_pid = p->p_pid;
+
+ error = kproc_create(xenbus_thread, NULL, NULL,
+ RFHIGHPID, 0, "xenbus");
- return err;
+ return (error);
}
-
-
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
diff --git a/sys/xen/xenbus/xenbusvar.h b/sys/xen/xenbus/xenbusvar.h
index 1331c43..6511664 100644
--- a/sys/xen/xenbus/xenbusvar.h
+++ b/sys/xen/xenbus/xenbusvar.h
@@ -103,32 +103,37 @@ struct xenbus_transaction
#define XBT_NIL ((struct xenbus_transaction) { 0 })
-char **xenbus_directory(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction t,
- const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction t,
- const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction t,
- const char *dir, const char *node);
+int xenbus_directory(struct xenbus_transaction t, const char *dir,
+ const char *node, unsigned int *num, char ***result);
+int xenbus_read(struct xenbus_transaction t, const char *dir,
+ const char *node, unsigned int *len, void **result);
+int xenbus_write(struct xenbus_transaction t, const char *dir,
+ const char *node, const char *string);
+int xenbus_mkdir(struct xenbus_transaction t, const char *dir,
+ const char *node);
+int xenbus_exists(struct xenbus_transaction t, const char *dir,
+ const char *node);
int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
int xenbus_transaction_start(struct xenbus_transaction *t);
int xenbus_transaction_end(struct xenbus_transaction t, int abort);
-/* Single read and scanf: returns -errno or num scanned if > 0. */
+/*
+ * Single read and scanf: returns errno or zero. If scancountp is
+ * non-null, then number of items scanned is returned in *scanncountp.
+ */
int xenbus_scanf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
- __attribute__((format(scanf, 4, 5)));
+ const char *dir, const char *node, int *scancountp, const char *fmt, ...)
+ __attribute__((format(scanf, 5, 6)));
-/* Single printf and write: returns -errno or 0. */
+/* Single printf and write: returns errno or 0. */
int xenbus_printf(struct xenbus_transaction t,
const char *dir, const char *node, const char *fmt, ...)
__attribute__((format(printf, 4, 5)));
-/* Generic read function: NULL-terminated triples of name,
- * sprintf-style type string, and pointer. Returns 0 or errno.*/
+/*
+ * Generic read function: NULL-terminated triples of name,
+ * sprintf-style type string, and pointer. Returns 0 or errno.
+ */
int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
/* notifer routines for when the xenstore comes up */
@@ -142,7 +147,9 @@ void xs_suspend(void);
void xs_resume(void);
/* Used by xenbus_dev to borrow kernel's store connection. */
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
+int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void **result);
+
+#if 0
#define XENBUS_IS_ERR_READ(str) ({ \
if (!IS_ERR(str) && strlen(str) == 0) { \
@@ -152,12 +159,15 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
IS_ERR(str); \
})
-#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
+#endif
+
+#define XENBUS_EXIST_ERR(err) ((err) == ENOENT || (err) == ERANGE)
+
/**
* Register a watch on the given path, using the given xenbus_watch structure
* for storage, and the given callback function as the callback. Return 0 on
- * success, or -errno on error. On success, the given path will be saved as
+ * success, or errno on error. On success, the given path will be saved as
* watch->node, and remains the caller's to free. On error, watch->node will
* be NULL, the device will switch to XenbusStateClosing, and the error will
* be saved in the store.
@@ -171,7 +181,7 @@ int xenbus_watch_path(device_t dev, char *path,
/**
* Register a watch on the given path/path2, using the given xenbus_watch
* structure for storage, and the given callback function as the callback.
- * Return 0 on success, or -errno on error. On success, the watched path
+ * Return 0 on success, or errno on error. On success, the watched path
* (path/path2) will be saved as watch->node, and becomes the caller's to
* kfree(). On error, watch->node will be NULL, so the caller has nothing to
* free, the device will switch to XenbusStateClosing, and the error will be
@@ -186,7 +196,7 @@ int xenbus_watch_path2(device_t dev, const char *path,
/**
* Advertise in the store a change of the given driver to the given new_state.
* which case this is performed inside its own transaction. Return 0 on
- * success, or -errno on error. On error, the device will switch to
+ * success, or errno on error. On error, the device will switch to
* XenbusStateClosing, and the error will be saved in the store.
*/
int xenbus_switch_state(device_t dev,
@@ -194,16 +204,17 @@ int xenbus_switch_state(device_t dev,
/**
- * Grant access to the given ring_mfn to the peer of the given device. Return
- * 0 on success, or -errno on error. On error, the device will switch to
- * XenbusStateClosing, and the error will be saved in the store.
+ * Grant access to the given ring_mfn to the peer of the given device.
+ * Return 0 on success, or errno on error. On error, the device will
+ * switch to XenbusStateClosing, and the error will be saved in the
+ * store. The grant ring reference is returned in *refp.
*/
-int xenbus_grant_ring(device_t dev, unsigned long ring_mfn);
+int xenbus_grant_ring(device_t dev, unsigned long ring_mfn, int *refp);
/**
* Allocate an event channel for the given xenbus_device, assigning the newly
- * created local port to *port. Return 0 on success, or -errno on error. On
+ * created local port to *port. Return 0 on success, or errno on error. On
* error, the device will switch to XenbusStateClosing, and the error will be
* saved in the store.
*/
@@ -211,7 +222,7 @@ int xenbus_alloc_evtchn(device_t dev, int *port);
/**
- * Free an existing event channel. Returns 0 on success or -errno on error.
+ * Free an existing event channel. Returns 0 on success or errno on error.
*/
int xenbus_free_evtchn(device_t dev, int port);
diff --git a/tools/regression/fstest/tests/conf b/tools/regression/fstest/tests/conf
index 73496e3..33e68f8 100644
--- a/tools/regression/fstest/tests/conf
+++ b/tools/regression/fstest/tests/conf
@@ -6,15 +6,19 @@ os=`uname`
case "${os}" in
FreeBSD|Darwin)
+ GREP=grep
#fs=`df -T . | tail -1 | awk '{print $2}'`
pattern="`df . | tail -1 | awk '{printf("%s on %s \n", $1, $6)}'`"
fs=`mount | egrep "^${pattern}" | awk -F '[(,]' '{print $2}'`
;;
-Solaris)
- pattern="`df -k . | tail -1 | awk '{printf("%s on %s \n", $1, $6)}'`"
- fs=`mount -v | egrep "^${pattern}" | awk '{print $5}'`
+Solaris|SunOS)
+ GREP=ggrep
+ pattern=`df -k . | tail -1 | awk '{printf("%s on %s \n", $1, $6)}'`
+ fs=`mount -v | egrep "^${pattern}" | awk '{print $5}' | \
+ tr -s '[:lower:]' '[:upper:]'`
;;
Linux)
+ GREP=grep
fs=`df -PT . | tail -1 | awk '{print $2}'`
;;
*)
diff --git a/tools/regression/fstest/tests/misc.sh b/tools/regression/fstest/tests/misc.sh
index 60764a9..97fe07c 100644
--- a/tools/regression/fstest/tests/misc.sh
+++ b/tools/regression/fstest/tests/misc.sh
@@ -87,7 +87,7 @@ test_check()
todo()
{
- echo "${os}" | grep -iq "${1}"
+ echo "${os}" | $GREP -iq "${1}"
if [ $? -eq 0 ]; then
todomsg="${2}"
fi
diff --git a/tools/regression/lib/libc/stdio/test-printfloat.c b/tools/regression/lib/libc/stdio/test-printfloat.c
index e7740b4..97bb1a8 100644
--- a/tools/regression/lib/libc/stdio/test-printfloat.c
+++ b/tools/regression/lib/libc/stdio/test-printfloat.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2005 David Schultz <das@FreeBSD.org>
+ * Copyright (c) 2002-2009 David Schultz <das@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
#define testfmt(result, fmt, ...) \
_testfmt((result), __LINE__, #__VA_ARGS__, fmt, __VA_ARGS__)
@@ -326,10 +327,13 @@ smash_stack(void)
void
_testfmt(const char *result, int line, const char *argstr, const char *fmt,...)
{
- char s[100];
- va_list ap;
+#define BUF 100
+ wchar_t ws[BUF], wfmt[BUF], wresult[BUF];
+ char s[BUF];
+ va_list ap, ap2;
va_start(ap, fmt);
+ va_copy(ap2, ap);
smash_stack();
vsnprintf(s, sizeof(s), fmt, ap);
if (strcmp(result, s) != 0) {
@@ -338,4 +342,16 @@ _testfmt(const char *result, int line, const char *argstr, const char *fmt,...)
line, fmt, argstr, s, result);
abort();
}
+
+ smash_stack();
+ mbstowcs(ws, s, BUF - 1);
+ mbstowcs(wfmt, fmt, BUF - 1);
+ mbstowcs(wresult, result, BUF - 1);
+ vswprintf(ws, sizeof(ws) / sizeof(ws[0]), wfmt, ap2);
+ if (wcscmp(wresult, ws) != 0) {
+ fprintf(stderr,
+ "%d: wprintf(\"%ls\", %s) ==> [%ls], expected [%ls]\n",
+ line, wfmt, argstr, ws, wresult);
+ abort();
+ }
}
diff --git a/tools/regression/lib/msun/Makefile b/tools/regression/lib/msun/Makefile
index 89ccd21..4a19dc2 100644
--- a/tools/regression/lib/msun/Makefile
+++ b/tools/regression/lib/msun/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-TESTS= test-csqrt test-exponential test-fenv test-fma \
+TESTS= test-conj test-csqrt test-exponential test-fenv test-fma \
test-fmaxmin test-ilogb test-invtrig test-lrint \
test-lround test-nan test-next test-rem test-trig
CFLAGS+= -O0 -lm
diff --git a/tools/regression/lib/msun/test-conj.c b/tools/regression/lib/msun/test-conj.c
new file mode 100644
index 0000000..909e810
--- /dev/null
+++ b/tools/regression/lib/msun/test-conj.c
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2008 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for conj{,f,l}()
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <complex.h>
+#include <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#pragma STDC CX_LIMITED_RANGE off
+
+/* Make sure gcc doesn't use builtin versions of these or honor __pure2. */
+static float complex (*libconjf)(float complex) = conjf;
+static double complex (*libconj)(double complex) = conj;
+static long double complex (*libconjl)(long double complex) = conjl;
+static float (*libcrealf)(float complex) = crealf;
+static double (*libcreal)(double complex) = creal;
+static long double (*libcreall)(long double complex) = creall;
+static float (*libcimagf)(float complex) = cimagf;
+static double (*libcimag)(double complex) = cimag;
+static long double (*libcimagl)(long double complex) = cimagl;
+
+/*
+ * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
+ * Fail an assertion if they differ.
+ */
+static int
+fpequal(long double d1, long double d2)
+{
+
+ if (d1 != d2)
+ return (isnan(d1) && isnan(d2));
+ return (copysignl(1.0, d1) == copysignl(1.0, d2));
+}
+
+static int
+cfpequal(long double complex d1, long double complex d2)
+{
+
+ return (fpequal(creall(d1), creall(d2)) &&
+ fpequal(cimagl(d1), cimagl(d2)));
+}
+
+static const double tests[] = {
+ /* a + bI */
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ -1.0, 0.0,
+ 1.0, -0.0,
+ 0.0, -1.0,
+ 2.0, 4.0,
+ 0.0, INFINITY,
+ 0.0, -INFINITY,
+ INFINITY, 0.0,
+ NAN, 1.0,
+ 1.0, NAN,
+ NAN, NAN,
+ -INFINITY, INFINITY,
+};
+
+int
+main(int argc, char *argv[])
+{
+ static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2;
+ complex float in;
+ complex long double expected;
+ int i;
+
+ printf("1..%d\n", ntests * 3);
+
+ for (i = 0; i < ntests; i++) {
+ __real__ expected = __real__ in = tests[2 * i];
+ __imag__ in = tests[2 * i + 1];
+ __imag__ expected = -cimag(in);
+
+ assert(fpequal(libcrealf(in), __real__ in));
+ assert(fpequal(libcreal(in), __real__ in));
+ assert(fpequal(libcreall(in), __real__ in));
+ assert(fpequal(libcimagf(in), __imag__ in));
+ assert(fpequal(libcimag(in), __imag__ in));
+ assert(fpequal(libcimagl(in), __imag__ in));
+
+ feclearexcept(FE_ALL_EXCEPT);
+ if (!cfpequal(libconjf(in), expected)) {
+ printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
+ "wrong value\n",
+ 3 * i + 1, creal(in), cimag(in));
+ } else if (fetestexcept(FE_ALL_EXCEPT)) {
+ printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
+ "threw an exception\n",
+ 3 * i + 1, creal(in), cimag(in));
+ } else {
+ printf("ok %d\t\t# conjf(%#.2g + %#.2gI)\n",
+ 3 * i + 1, creal(in), cimag(in));
+ }
+
+ feclearexcept(FE_ALL_EXCEPT);
+ if (!cfpequal(libconj(in), expected)) {
+ printf("not ok %d\t# conj(%#.2g + %#.2gI): "
+ "wrong value\n",
+ 3 * i + 2, creal(in), cimag(in));
+ } else if (fetestexcept(FE_ALL_EXCEPT)) {
+ printf("not ok %d\t# conj(%#.2g + %#.2gI): "
+ "threw an exception\n",
+ 3 * i + 2, creal(in), cimag(in));
+ } else {
+ printf("ok %d\t\t# conj(%#.2g + %#.2gI)\n",
+ 3 * i + 2, creal(in), cimag(in));
+ }
+
+ feclearexcept(FE_ALL_EXCEPT);
+ if (!cfpequal(libconjl(in), expected)) {
+ printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
+ "wrong value\n",
+ 3 * i + 3, creal(in), cimag(in));
+ } else if (fetestexcept(FE_ALL_EXCEPT)) {
+ printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
+ "threw an exception\n",
+ 3 * i + 3, creal(in), cimag(in));
+ } else {
+ printf("ok %d\t\t# conjl(%#.2g + %#.2gI)\n",
+ 3 * i + 3, creal(in), cimag(in));
+ }
+ }
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/test-conj.t b/tools/regression/lib/msun/test-conj.t
new file mode 100644
index 0000000..8bdfd03
--- /dev/null
+++ b/tools/regression/lib/msun/test-conj.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable
diff --git a/tools/regression/usr.bin/jot/regress.sh b/tools/regression/usr.bin/jot/regress.sh
index c71ade8..15d6208 100644
--- a/tools/regression/usr.bin/jot/regress.sh
+++ b/tools/regression/usr.bin/jot/regress.sh
@@ -49,7 +49,7 @@ REGRESSION_TEST(`wgd', `jot -w "a%gb" 10 .2')
REGRESSION_TEST(`wu', `jot -w "a%ub" 10')
REGRESSION_TEST(`wo', `jot -w "a%ob" 10')
REGRESSION_TEST(`wx', `jot -w "a%xb" 10')
-REGRESSION_TEST(`wX', `jot -w "a%Xb" 10')
+REGRESSION_TEST(`wX1', `jot -w "a%Xb" 10')
REGRESSION_TEST(`wXl', `jot -w "a%Xb" 10 2147483648')
REGRESSION_TEST(`wdl', `jot -w "a%db" 10 2147483648')
REGRESSION_TEST(`wxn', `jot -w "a%xb" 10 -5')
diff --git a/tools/regression/usr.bin/jot/regress.wX.out b/tools/regression/usr.bin/jot/regress.wX1.out
index dc7f5e9..dc7f5e9 100644
--- a/tools/regression/usr.bin/jot/regress.wX.out
+++ b/tools/regression/usr.bin/jot/regress.wX1.out
diff --git a/tools/sched/schedgraph.py b/tools/sched/schedgraph.py
index c0eafe2..4335574 100644
--- a/tools/sched/schedgraph.py
+++ b/tools/sched/schedgraph.py
@@ -1,6 +1,6 @@
#!/usr/local/bin/python
-# Copyright (c) 2002-2003, Jeffrey Roberson <jeff@freebsd.org>
+# Copyright (c) 2002-2003, 2009, Jeffrey Roberson <jeff@freebsd.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,7 @@
import sys
import re
+import random
from Tkinter import *
# To use:
@@ -53,53 +54,124 @@ from Tkinter import *
# while the workload is still running is to avoid wasting log entries on
# "idle" time at the end.
# - Dump the trace to a file: 'ktrdump -ct > ktr.out'
-# - Run the python script: 'python schedgraph.py ktr.out'
+# - Run the python script: 'python schedgraph.py ktr.out' optionally provide
+# your cpu frequency in ghz: 'python schedgraph.py ktr.out 2.4'
#
# To do:
-# 1) Add a per-thread summary display
-# 2) Add bounding box style zoom.
-# 3) Click to center.
-# 4) Implement some sorting mechanism.
-# 5) Widget to display variable-range data (e.g. q length)
-# 6) Reorder rows, hide rows, etc.
-# 7) "Vertical rule" to help relate data in different rows
-# 8) Mouse-over popup of full thread/event/row lable (currently truncated)
-# 9) More visible anchors for popup event windows
+# Add a per-source summary display
+# "Vertical rule" to help relate data in different rows
+# Mouse-over popup of full thread/event/row label (currently truncated)
+# More visible anchors for popup event windows
#
# BUGS: 1) Only 8 CPUs are supported, more CPUs require more choices of
# colours to represent them ;-)
-# 2) Extremely short traces may cause a crash because the code
-# assumes there is always at least one stathz entry logged, and
-# the number of such events is used as a denominator
+
+eventcolors = [
+ ("count", "red"),
+ ("running", "green"),
+ ("idle", "grey"),
+ ("yielding", "yellow"),
+ ("swapped", "violet"),
+ ("suspended", "purple"),
+ ("iwait", "grey"),
+ ("sleep", "blue"),
+ ("blocked", "dark red"),
+ ("runq add", "yellow"),
+ ("runq rem", "yellow"),
+ ("thread exit", "grey"),
+ ("proc exit", "grey"),
+ ("callwheel idle", "grey"),
+ ("callout running", "green"),
+ ("lock acquire", "blue"),
+ ("lock contest", "purple"),
+ ("failed lock try", "red"),
+ ("lock release", "grey"),
+ ("statclock", "black"),
+ ("prio", "black"),
+ ("lend prio", "black"),
+ ("wokeup", "black")
+]
+
+cpucolors = [
+ ("CPU 0", "light grey"),
+ ("CPU 1", "dark grey"),
+ ("CPU 2", "light blue"),
+ ("CPU 3", "light pink"),
+ ("CPU 4", "blanched almond"),
+ ("CPU 5", "slate grey"),
+ ("CPU 6", "tan"),
+ ("CPU 7", "thistle"),
+ ("CPU 8", "white")
+]
+
+colors = [
+ "white", "thistle", "blanched almond", "tan", "chartreuse",
+ "dark red", "red", "pale violet red", "pink", "light pink",
+ "dark orange", "orange", "coral", "light coral",
+ "goldenrod", "gold", "yellow", "light yellow",
+ "dark green", "green", "light green", "light sea green",
+ "dark blue", "blue", "light blue", "steel blue", "light slate blue",
+ "dark violet", "violet", "purple", "blue violet",
+ "dark grey", "slate grey", "light grey",
+ "black",
+]
+colors.sort()
ticksps = None
status = None
-configtypes = []
+colormap = None
+ktrfile = None
+clockfreq = None
+sources = []
lineno = -1
+Y_BORDER = 10
+X_BORDER = 10
+Y_COUNTER = 80
+Y_EVENTSOURCE = 10
+XY_POINT = 4
+
+class Colormap:
+ def __init__(self, table):
+ self.table = table
+ self.map = {}
+ for entry in table:
+ self.map[entry[0]] = entry[1]
+
+ def lookup(self, name):
+ try:
+ color = self.map[name]
+ except:
+ color = colors[random.randrange(0, len(colors))]
+ print "Picking random color", color, "for", name
+ self.map[name] = color
+ self.table.append((name, color))
+ return (color)
+
def ticks2sec(ticks):
- us = ticksps / 1000000
- ticks /= us
+ ticks = float(ticks)
+ ns = float(ticksps) / 1000000000
+ ticks /= ns
+ if (ticks < 1000):
+ return ("%.2fns" % ticks)
+ ticks /= 1000
if (ticks < 1000):
- return (str(ticks) + "us")
+ return ("%.2fus" % ticks)
ticks /= 1000
if (ticks < 1000):
- return (str(ticks) + "ms")
+ return ("%.2fms" % ticks)
ticks /= 1000
- return (str(ticks) + "s")
+ return ("%.2fs" % ticks)
class Scaler(Frame):
def __init__(self, master, target):
Frame.__init__(self, master)
- self.scale = Scale(self, command=self.scaleset,
- from_=1000, to_=10000000, orient=HORIZONTAL,
- resolution=1000)
+ self.scale = None
+ self.target = target
self.label = Label(self, text="Ticks per pixel")
self.label.pack(side=LEFT)
- self.scale.pack(fill="both", expand=1)
- self.target = target
- self.scale.set(target.scaleget())
- self.initialized = 1
+ self.resolution = 100
+ self.setmax(10000)
def scaleset(self, value):
self.target.scaleset(int(value))
@@ -107,6 +179,20 @@ class Scaler(Frame):
def set(self, value):
self.scale.set(value)
+ def setmax(self, value):
+ #
+ # We can't reconfigure the to_ value so we delete the old
+ # window and make a new one when we resize.
+ #
+ if (self.scale != None):
+ self.scale.pack_forget()
+ self.scale.destroy()
+ self.scale = Scale(self, command=self.scaleset,
+ from_=100, to_=value, orient=HORIZONTAL,
+ resolution=self.resolution)
+ self.scale.pack(fill="both", expand=1)
+ self.scale.set(self.target.scaleget())
+
class Status(Frame):
def __init__(self, master):
Frame.__init__(self, master)
@@ -124,9 +210,13 @@ class Status(Frame):
self.set(str)
root.update()
-class EventConf(Frame):
- def __init__(self, master, name, color, enabled):
+class ColorConf(Frame):
+ def __init__(self, master, name, color):
Frame.__init__(self, master)
+ if (graph.getstate(name) == "hidden"):
+ enabled = 0
+ else:
+ enabled = 1
self.name = name
self.color = StringVar()
self.color_default = color
@@ -144,16 +234,8 @@ class EventConf(Frame):
bg='grey')
self.rect = self.sample.create_rectangle(0, 0, 24, 24,
fill=self.color.get())
- self.list = OptionMenu(self, self.color,
- "dark red", "red", "pink",
- "dark orange", "orange",
- "yellow", "light yellow",
- "dark green", "green", "light green",
- "dark blue", "blue", "light blue",
- "dark violet", "violet", "purple",
- "dark grey", "light grey",
- "white", "black",
- command=self.setcolor)
+ self.list = OptionMenu(self, self.color, command=self.setcolor,
+ *colors)
self.checkbox = Checkbutton(self, text="enabled",
variable=self.enabled)
self.label.grid(row=0, column=0, sticky=E+W)
@@ -161,7 +243,7 @@ class EventConf(Frame):
self.list.grid(row=0, column=2, sticky=E+W)
self.checkbox.grid(row=0, column=3)
self.columnconfigure(0, weight=1)
- self.columnconfigure(2, minsize=110)
+ self.columnconfigure(2, minsize=150)
def setcolor(self, color):
self.color.set(color)
@@ -186,19 +268,15 @@ class EventConf(Frame):
graph.setcolor(self.name, self.color_current)
def revert(self):
- self.setcolor(self.color_current)
- self.enabled.set(self.enabled_current)
-
- def default(self):
self.setcolor(self.color_default)
self.enabled.set(self.enabled_default)
-class EventConfigure(Toplevel):
- def __init__(self):
+class ColorConfigure(Toplevel):
+ def __init__(self, table, name):
Toplevel.__init__(self)
self.resizable(0, 0)
- self.title("Event Configuration")
- self.items = LabelFrame(self, text="Event Type")
+ self.title(name)
+ self.items = LabelFrame(self, text="Item Type")
self.buttons = Frame(self)
self.drawbuttons()
self.items.grid(row=0, column=0, sticky=E+W)
@@ -206,11 +284,13 @@ class EventConfigure(Toplevel):
self.buttons.grid(row=1, column=0, sticky=E+W)
self.types = []
self.irow = 0
- for type in configtypes:
- self.additem(type.name, type.color, type.enabled)
+ for type in table:
+ color = graph.getcolor(type[0])
+ if (color != ""):
+ self.additem(type[0], color)
- def additem(self, name, color, enabled=1):
- item = EventConf(self.items, name, color, enabled)
+ def additem(self, name, color):
+ item = ColorConf(self.items, name, color)
self.types.append(item)
item.grid(row=self.irow, column=0, sticky=E+W)
self.irow += 1
@@ -218,16 +298,12 @@ class EventConfigure(Toplevel):
def drawbuttons(self):
self.apply = Button(self.buttons, text="Apply",
command=self.apress)
- self.revert = Button(self.buttons, text="Revert",
+ self.default = Button(self.buttons, text="Revert",
command=self.rpress)
- self.default = Button(self.buttons, text="Default",
- command=self.dpress)
self.apply.grid(row=0, column=0, sticky=E+W)
- self.revert.grid(row=0, column=1, sticky=E+W)
- self.default.grid(row=0, column=2, sticky=E+W)
+ self.default.grid(row=0, column=1, sticky=E+W)
self.buttons.columnconfigure(0, weight=1)
self.buttons.columnconfigure(1, weight=1)
- self.buttons.columnconfigure(2, weight=1)
def apress(self):
for item in self.types:
@@ -237,9 +313,206 @@ class EventConfigure(Toplevel):
for item in self.types:
item.revert()
- def dpress(self):
- for item in self.types:
- item.default()
+class SourceConf(Frame):
+ def __init__(self, master, source):
+ Frame.__init__(self, master)
+ if (source.hidden == 1):
+ enabled = 0
+ else:
+ enabled = 1
+ self.source = source
+ self.name = source.name
+ self.enabled = IntVar()
+ self.enabled_default = enabled
+ self.enabled_current = enabled
+ self.enabled.set(enabled)
+ self.draw()
+
+ def draw(self):
+ self.label = Label(self, text=self.name, anchor=W)
+ self.checkbox = Checkbutton(self, text="enabled",
+ variable=self.enabled)
+ self.label.grid(row=0, column=0, sticky=E+W)
+ self.checkbox.grid(row=0, column=1)
+ self.columnconfigure(0, weight=1)
+
+ def changed(self):
+ if (self.enabled_current != self.enabled.get()):
+ return 1
+ return 0
+
+ def apply(self):
+ self.enabled_current = self.enabled.get()
+
+ def revert(self):
+ self.enabled.set(self.enabled_default)
+
+ def check(self):
+ self.enabled.set(1)
+
+ def uncheck(self):
+ self.enabled.set(0)
+
+class SourceConfigure(Toplevel):
+ def __init__(self):
+ Toplevel.__init__(self)
+ self.resizable(0, 0)
+ self.title("Source Configuration")
+ self.items = []
+ self.iframe = Frame(self)
+ self.iframe.grid(row=0, column=0, sticky=E+W)
+ f = LabelFrame(self.iframe, bd=4, text="Sources")
+ self.items.append(f)
+ self.buttons = Frame(self)
+ self.items[0].grid(row=0, column=0, sticky=E+W)
+ self.columnconfigure(0, weight=1)
+ self.sconfig = []
+ self.irow = 0
+ self.icol = 0
+ for source in sources:
+ self.addsource(source)
+ self.drawbuttons()
+ self.buttons.grid(row=1, column=0, sticky=W)
+
+ def addsource(self, source):
+ if (self.irow > 30):
+ self.icol += 1
+ self.irow = 0
+ c = self.icol
+ f = LabelFrame(self.iframe, bd=4, text="Sources")
+ f.grid(row=0, column=c, sticky=N+E+W)
+ self.items.append(f)
+ item = SourceConf(self.items[self.icol], source)
+ self.sconfig.append(item)
+ item.grid(row=self.irow, column=0, sticky=E+W)
+ self.irow += 1
+
+ def drawbuttons(self):
+ self.apply = Button(self.buttons, text="Apply",
+ command=self.apress)
+ self.default = Button(self.buttons, text="Revert",
+ command=self.rpress)
+ self.checkall = Button(self.buttons, text="Check All",
+ command=self.cpress)
+ self.uncheckall = Button(self.buttons, text="Uncheck All",
+ command=self.upress)
+ self.checkall.grid(row=0, column=0, sticky=W)
+ self.uncheckall.grid(row=0, column=1, sticky=W)
+ self.apply.grid(row=0, column=2, sticky=W)
+ self.default.grid(row=0, column=3, sticky=W)
+ self.buttons.columnconfigure(0, weight=1)
+ self.buttons.columnconfigure(1, weight=1)
+ self.buttons.columnconfigure(2, weight=1)
+ self.buttons.columnconfigure(3, weight=1)
+
+ def apress(self):
+ disable_sources = []
+ enable_sources = []
+ for item in self.sconfig:
+ if (item.changed() == 0):
+ continue
+ if (item.enabled.get() == 1):
+ enable_sources.append(item.source)
+ else:
+ disable_sources.append(item.source)
+
+ if (len(disable_sources)):
+ graph.sourcehidelist(disable_sources)
+ if (len(enable_sources)):
+ graph.sourceshowlist(enable_sources)
+
+ for item in self.sconfig:
+ item.apply()
+
+ def rpress(self):
+ for item in self.sconfig:
+ item.revert()
+
+ def cpress(self):
+ for item in self.sconfig:
+ item.check()
+
+ def upress(self):
+ for item in self.sconfig:
+ item.uncheck()
+
+# Reverse compare of second member of the tuple
+def cmp_counts(x, y):
+ return y[1] - x[1]
+
+class SourceStats(Toplevel):
+ def __init__(self, source):
+ self.source = source
+ Toplevel.__init__(self)
+ self.resizable(0, 0)
+ self.title(source.name + " statistics")
+ self.evframe = LabelFrame(self,
+ text="Event Count, Duration, Avg Duration")
+ self.evframe.grid(row=0, column=0, sticky=E+W)
+ eventtypes={}
+ for event in self.source.events:
+ if (event.type == "pad"):
+ continue
+ duration = event.duration
+ if (eventtypes.has_key(event.name)):
+ (c, d) = eventtypes[event.name]
+ c += 1
+ d += duration
+ eventtypes[event.name] = (c, d)
+ else:
+ eventtypes[event.name] = (1, duration)
+ events = []
+ for k, v in eventtypes.iteritems():
+ (c, d) = v
+ events.append((k, c, d))
+ events.sort(cmp=cmp_counts)
+
+ ypos = 0
+ for event in events:
+ (name, c, d) = event
+ Label(self.evframe, text=name, bd=1,
+ relief=SUNKEN, anchor=W, width=30).grid(
+ row=ypos, column=0, sticky=W+E)
+ Label(self.evframe, text=str(c), bd=1,
+ relief=SUNKEN, anchor=W, width=10).grid(
+ row=ypos, column=1, sticky=W+E)
+ Label(self.evframe, text=ticks2sec(d),
+ bd=1, relief=SUNKEN, width=10).grid(
+ row=ypos, column=2, sticky=W+E)
+ if (d and c):
+ d /= c
+ else:
+ d = 0
+ Label(self.evframe, text=ticks2sec(d),
+ bd=1, relief=SUNKEN, width=10).grid(
+ row=ypos, column=3, sticky=W+E)
+ ypos += 1
+
+
+class SourceContext(Menu):
+ def __init__(self, event, source):
+ self.source = source
+ Menu.__init__(self, tearoff=0, takefocus=0)
+ self.add_command(label="hide", command=self.hide)
+ self.add_command(label="hide group", command=self.hidegroup)
+ self.add_command(label="stats", command=self.stats)
+ self.tk_popup(event.x_root-3, event.y_root+3)
+
+ def hide(self):
+ graph.sourcehide(self.source)
+
+ def hidegroup(self):
+ grouplist = []
+ for source in sources:
+ if (source.group == self.source.group):
+ grouplist.append(source)
+ graph.sourcehidelist(grouplist)
+
+ def show(self):
+ graph.sourceshow(self.source)
+
+ def stats(self):
+ SourceStats(self.source)
class EventView(Toplevel):
def __init__(self, event, canvas):
@@ -247,10 +520,10 @@ class EventView(Toplevel):
self.resizable(0, 0)
self.title("Event")
self.event = event
- self.frame = Frame(self)
- self.frame.grid(row=0, column=0, sticky=N+S+E+W)
self.buttons = Frame(self)
- self.buttons.grid(row=1, column=0, sticky=E+W)
+ self.buttons.grid(row=0, column=0, sticky=E+W)
+ self.frame = Frame(self)
+ self.frame.grid(row=1, column=0, sticky=N+S+E+W)
self.canvas = canvas
self.drawlabels()
self.drawbuttons()
@@ -272,9 +545,12 @@ class EventView(Toplevel):
ypos = 0
labels = self.event.labels()
while (len(labels) < 7):
- labels.append(("", "", 0))
+ labels.append(("", ""))
for label in labels:
- name, value, linked = label
+ name, value = label
+ linked = 0
+ if (name == "linkedto"):
+ linked = 1
l = Label(self.frame, text=name, bd=1, width=15,
relief=SUNKEN, anchor=W)
if (linked):
@@ -313,7 +589,7 @@ class EventView(Toplevel):
prev = self.event.prev()
if (prev == None):
return
- while (prev.real == 0):
+ while (prev.type == "pad"):
prev = prev.prev()
if (prev == None):
return
@@ -323,7 +599,7 @@ class EventView(Toplevel):
next = self.event.next()
if (next == None):
return
- while (next.real == 0):
+ while (next.type == "pad"):
next = next.next()
if (next == None):
return
@@ -335,60 +611,68 @@ class EventView(Toplevel):
self.newevent(event)
class Event:
- name = "none"
- color = "grey"
- def __init__(self, source, cpu, timestamp, last=0):
+ def __init__(self, source, name, cpu, timestamp, attrs):
self.source = source
+ self.name = name
self.cpu = cpu
self.timestamp = int(timestamp)
- self.entries = []
- self.real = 1
+ self.attrs = attrs
self.idx = None
- self.state = 0
self.item = None
self.dispcnt = 0
- self.linked = None
+ self.duration = 0
self.recno = lineno
- if (last):
- source.lastevent(self)
- else:
- source.event(self)
def status(self):
statstr = self.name + " " + self.source.name
statstr += " on: cpu" + str(self.cpu)
statstr += " at: " + str(self.timestamp)
- statstr += self.stattxt()
+ statstr += " attributes: "
+ for i in range(0, len(self.attrs)):
+ attr = self.attrs[i]
+ statstr += attr[0] + ": " + str(attr[1])
+ if (i != len(self.attrs) - 1):
+ statstr += ", "
status.set(statstr)
- def stattxt(self):
- return ""
-
- def textadd(self, tuple):
- pass
- self.entries.append(tuple)
-
def labels(self):
- return [("Source:", self.source.name, 0),
- ("Event:", self.name, 0),
- ("CPU:", self.cpu, 0),
- ("Timestamp:", self.timestamp, 0),
- ("Record: ", self.recno, 0)
- ] + self.entries
- def mouseenter(self, canvas, item):
+ return [("Source", self.source.name),
+ ("Event", self.name),
+ ("CPU", self.cpu),
+ ("Timestamp", self.timestamp),
+ ("KTR Line ", self.recno)
+ ] + self.attrs
+
+ def mouseenter(self, canvas):
self.displayref(canvas)
self.status()
- def mouseexit(self, canvas, item):
+ def mouseexit(self, canvas):
self.displayunref(canvas)
status.clear()
- def mousepress(self, canvas, item):
+ def mousepress(self, canvas):
EventView(self, canvas)
+ def draw(self, canvas, xpos, ypos, item):
+ self.item = item
+ if (item != None):
+ canvas.items[item] = self
+
+ def move(self, canvas, x, y):
+ if (self.item == None):
+ return;
+ canvas.move(self.item, x, y);
+
def next(self):
return self.source.eventat(self.idx + 1)
+ def nexttype(self, type):
+ next = self.next()
+ while (next != None and next.type != type):
+ next = next.next()
+ return (next)
+
def prev(self):
return self.source.eventat(self.idx - 1)
@@ -404,405 +688,172 @@ class Event:
canvas.tag_raise("point", "state")
def getlinked(self):
- return self.linked.findevent(self.timestamp)
+ for attr in self.attrs:
+ if (attr[0] != "linkedto"):
+ continue
+ source = ktrfile.findid(attr[1])
+ return source.findevent(self.timestamp)
+ return None
class PointEvent(Event):
- def __init__(self, thread, cpu, timestamp, last=0):
- Event.__init__(self, thread, cpu, timestamp, last)
+ type = "point"
+ def __init__(self, source, name, cpu, timestamp, attrs):
+ Event.__init__(self, source, name, cpu, timestamp, attrs)
def draw(self, canvas, xpos, ypos):
- l = canvas.create_oval(xpos - 6, ypos + 1, xpos + 6, ypos - 11,
- fill=self.color, tags=("all", "point", "event")
- + (self.name,), width=0)
- canvas.events[l] = self
- self.item = l
- if (self.enabled == 0):
- canvas.itemconfigure(l, state="hidden")
+ color = colormap.lookup(self.name)
+ l = canvas.create_oval(xpos - XY_POINT, ypos,
+ xpos + XY_POINT, ypos - (XY_POINT * 2),
+ fill=color, width=0,
+ tags=("event", self.type, self.name, self.source.tag))
+ Event.draw(self, canvas, xpos, ypos, l)
- return (xpos)
+ return xpos
class StateEvent(Event):
- def __init__(self, thread, cpu, timestamp, last=0):
- Event.__init__(self, thread, cpu, timestamp, last)
- self.duration = 0
- self.skipnext = 0
- self.skipself = 0
- self.state = 1
+ type = "state"
+ def __init__(self, source, name, cpu, timestamp, attrs):
+ Event.__init__(self, source, name, cpu, timestamp, attrs)
def draw(self, canvas, xpos, ypos):
- next = self.nextstate()
- if (self.skipself == 1 or next == None):
+ next = self.nexttype("state")
+ if (next == None):
return (xpos)
- while (self.skipnext):
- skipped = next
- next.skipself = 1
- next.real = 0
- next = next.nextstate()
- if (next == None):
- next = skipped
- self.skipnext -= 1
- self.duration = next.timestamp - self.timestamp
- if (self.duration < 0):
- self.duration = 0
+ self.duration = duration = next.timestamp - self.timestamp
+ self.attrs.insert(0, ("duration", ticks2sec(duration)))
+ color = colormap.lookup(self.name)
+ if (duration < 0):
+ duration = 0
print "Unsynchronized timestamp"
print self.cpu, self.timestamp
print next.cpu, next.timestamp
- delta = self.duration / canvas.ratio
+ delta = duration / canvas.ratio
l = canvas.create_rectangle(xpos, ypos,
- xpos + delta, ypos - 10, fill=self.color, width=0,
- tags=("all", "state", "event") + (self.name,))
- canvas.events[l] = self
- self.item = l
- if (self.enabled == 0):
- canvas.itemconfigure(l, state="hidden")
+ xpos + delta, ypos - 10, fill=color, width=0,
+ tags=("event", self.type, self.name, self.source.tag))
+ Event.draw(self, canvas, xpos, ypos, l)
return (xpos + delta)
- def stattxt(self):
- return " duration: " + ticks2sec(self.duration)
-
- def nextstate(self):
- next = self.next()
- while (next != None and next.state == 0):
- next = next.next()
- return (next)
-
- def labels(self):
- return [("Source:", self.source.name, 0),
- ("Event:", self.name, 0),
- ("Timestamp:", self.timestamp, 0),
- ("CPU:", self.cpu, 0),
- ("Record:", self.recno, 0),
- ("Duration:", ticks2sec(self.duration), 0)
- ] + self.entries
-
-class Count(Event):
- name = "Count"
- color = "red"
- enabled = 1
- def __init__(self, source, cpu, timestamp, count):
- self.count = int(count)
- Event.__init__(self, source, cpu, timestamp)
- self.duration = 0
- self.textadd(("count:", self.count, 0))
+class CountEvent(Event):
+ type = "count"
+ def __init__(self, source, count, cpu, timestamp, attrs):
+ count = int(count)
+ self.count = count
+ Event.__init__(self, source, "count", cpu, timestamp, attrs)
def draw(self, canvas, xpos, ypos):
- next = self.next()
- self.duration = next.timestamp - self.timestamp
- delta = self.duration / canvas.ratio
+ next = self.nexttype("count")
+ if (next == None):
+ return (xpos)
+ color = colormap.lookup("count")
+ self.duration = duration = next.timestamp - self.timestamp
+ if (duration < 0):
+ duration = 0
+ print "Unsynchronized timestamp"
+ print self.cpu, self.timestamp
+ print next.cpu, next.timestamp
+ self.attrs.insert(0, ("count", self.count))
+ self.attrs.insert(1, ("duration", ticks2sec(duration)))
+ delta = duration / canvas.ratio
yhight = self.source.yscale() * self.count
l = canvas.create_rectangle(xpos, ypos - yhight,
- xpos + delta, ypos, fill=self.color, width=0,
- tags=("all", "count", "event") + (self.name,))
- canvas.events[l] = self
- self.item = l
- if (self.enabled == 0):
- canvas.itemconfigure(l, state="hidden")
+ xpos + delta, ypos, fill=color, width=0,
+ tags=("event", self.type, self.name, self.source.tag))
+ Event.draw(self, canvas, xpos, ypos, l)
return (xpos + delta)
- def stattxt(self):
- return " count: " + str(self.count)
-
-configtypes.append(Count)
-
-class Running(StateEvent):
- name = "running"
- color = "green"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Running)
-
-class Idle(StateEvent):
- name = "idle"
- color = "grey"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Idle)
-
-class Yielding(StateEvent):
- name = "yielding"
- color = "yellow"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.skipnext = 0
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Yielding)
-
-class Swapped(StateEvent):
- name = "swapped"
- color = "violet"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Swapped)
-
-class Suspended(StateEvent):
- name = "suspended"
- color = "purple"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Suspended)
-
-class Iwait(StateEvent):
- name = "iwait"
- color = "grey"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Iwait)
-
-class Preempted(StateEvent):
- name = "preempted"
- color = "red"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio, bythread):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.skipnext = 1
- self.prio = prio
- self.linked = bythread
- self.textadd(("prio:", self.prio, 0))
- self.textadd(("by thread:", self.linked.name, 1))
-
-configtypes.append(Preempted)
-
-class Sleep(StateEvent):
- name = "sleep"
- color = "blue"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio, wmesg):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.wmesg = wmesg
- self.textadd(("prio:", self.prio, 0))
- self.textadd(("wmesg:", self.wmesg, 0))
-
- def stattxt(self):
- statstr = StateEvent.stattxt(self)
- statstr += " sleeping on: " + self.wmesg
- return (statstr)
-
-configtypes.append(Sleep)
-
-class Blocked(StateEvent):
- name = "blocked"
- color = "dark red"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio, lock):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.lock = lock
- self.textadd(("prio:", self.prio, 0))
- self.textadd(("lock:", self.lock, 0))
-
- def stattxt(self):
- statstr = StateEvent.stattxt(self)
- statstr += " blocked on: " + self.lock
- return (statstr)
-
-configtypes.append(Blocked)
-
-class KsegrpRunq(StateEvent):
- name = "KsegrpRunq"
- color = "orange"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio, bythread):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.linked = bythread
- self.textadd(("prio:", self.prio, 0))
- self.textadd(("by thread:", self.linked.name, 1))
-
-configtypes.append(KsegrpRunq)
-
-class Runq(StateEvent):
- name = "Runq"
- color = "yellow"
- enabled = 1
- def __init__(self, thread, cpu, timestamp, prio, bythread):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.linked = bythread
- self.textadd(("prio:", self.prio, 0))
- self.textadd(("by thread:", self.linked.name, 1))
-
-configtypes.append(Runq)
-
-class Sched_exit_thread(StateEvent):
- name = "exit_thread"
- color = "grey"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.name = "sched_exit_thread"
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Sched_exit_thread)
-
-class Sched_exit(StateEvent):
- name = "exit"
- color = "grey"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio):
- StateEvent.__init__(self, thread, cpu, timestamp)
- self.name = "sched_exit"
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Sched_exit)
-
-class Padevent(StateEvent):
- def __init__(self, thread, cpu, timestamp, last=0):
- StateEvent.__init__(self, thread, cpu, timestamp, last)
- self.name = "pad"
- self.real = 0
-
+class PadEvent(StateEvent):
+ type = "pad"
+ def __init__(self, source, cpu, timestamp, last=0):
+ if (last):
+ cpu = source.events[len(source.events) -1].cpu
+ else:
+ cpu = source.events[0].cpu
+ StateEvent.__init__(self, source, "pad", cpu, timestamp, [])
def draw(self, canvas, xpos, ypos):
next = self.next()
if (next == None):
return (xpos)
- self.duration = next.timestamp - self.timestamp
- delta = self.duration / canvas.ratio
+ duration = next.timestamp - self.timestamp
+ delta = duration / canvas.ratio
+ Event.draw(self, canvas, xpos, ypos, None)
return (xpos + delta)
-class Tick(PointEvent):
- name = "tick"
- color = "black"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio, stathz):
- PointEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.textadd(("prio:", self.prio, 0))
-
-configtypes.append(Tick)
-
-class Prio(PointEvent):
- name = "prio"
- color = "black"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio, newprio, bythread):
- PointEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.newprio = newprio
- self.linked = bythread
- self.textadd(("new prio:", self.newprio, 0))
- self.textadd(("prio:", self.prio, 0))
- if (self.linked != self.source):
- self.textadd(("by thread:", self.linked.name, 1))
- else:
- self.textadd(("by thread:", self.linked.name, 0))
-
-configtypes.append(Prio)
-
-class Lend(PointEvent):
- name = "lend"
- color = "black"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, prio, tothread):
- PointEvent.__init__(self, thread, cpu, timestamp)
- self.prio = prio
- self.linked = tothread
- self.textadd(("prio:", self.prio, 0))
- self.textadd(("to thread:", self.linked.name, 1))
-
-configtypes.append(Lend)
-
-class Wokeup(PointEvent):
- name = "wokeup"
- color = "black"
- enabled = 0
- def __init__(self, thread, cpu, timestamp, ranthread):
- PointEvent.__init__(self, thread, cpu, timestamp)
- self.linked = ranthread
- self.textadd(("ran thread:", self.linked.name, 1))
-
-configtypes.append(Wokeup)
+# Sort function for start y address
+def source_cmp_start(x, y):
+ return x.y - y.y
class EventSource:
- def __init__(self, name):
- self.name = name
+ def __init__(self, group, id):
+ self.name = id
self.events = []
- self.cpu = 0
- self.cpux = 0
-
+ self.cpuitems = []
+ self.group = group
+ self.y = 0
+ self.item = None
+ self.hidden = 0
+ self.tag = group + id
+
+ def __cmp__(self, other):
+ if (other == None):
+ return -1
+ if (self.group == other.group):
+ return cmp(self.name, other.name)
+ return cmp(self.group, other.group)
+
+ # It is much faster to append items to a list then to insert them
+ # at the beginning. As a result, we add events in reverse order
+ # and then swap the list during fixup.
def fixup(self):
- pass
+ self.events.reverse()
- def event(self, event):
- self.events.insert(0, event)
-
- def remove(self, event):
- self.events.remove(event)
-
- def lastevent(self, event):
+ def addevent(self, event):
self.events.append(event)
+ def addlastevent(self, event):
+ self.events.insert(0, event)
+
def draw(self, canvas, ypos):
xpos = 10
- self.cpux = 10
- self.cpu = self.events[1].cpu
+ cpux = 10
+ cpu = self.events[1].cpu
for i in range(0, len(self.events)):
self.events[i].idx = i
for event in self.events:
- if (event.cpu != self.cpu and event.cpu != -1):
- self.drawcpu(canvas, xpos, ypos)
- self.cpux = xpos
- self.cpu = event.cpu
+ if (event.cpu != cpu and event.cpu != -1):
+ self.drawcpu(canvas, cpu, cpux, xpos, ypos)
+ cpux = xpos
+ cpu = event.cpu
xpos = event.draw(canvas, xpos, ypos)
- self.drawcpu(canvas, xpos, ypos)
+ self.drawcpu(canvas, cpu, cpux, xpos, ypos)
def drawname(self, canvas, ypos):
+ self.y = ypos
ypos = ypos - (self.ysize() / 2)
- canvas.create_text(10, ypos, anchor="w", text=self.name)
-
- def drawcpu(self, canvas, xpos, ypos):
- cpu = int(self.cpu)
- if (cpu == 0):
- color = 'light grey'
- elif (cpu == 1):
- color = 'dark grey'
- elif (cpu == 2):
- color = 'light blue'
- elif (cpu == 3):
- color = 'light green'
- elif (cpu == 4):
- color = 'blanched almond'
- elif (cpu == 5):
- color = 'slate grey'
- elif (cpu == 6):
- color = 'light slate blue'
- elif (cpu == 7):
- color = 'thistle'
- else:
- color = "white"
- l = canvas.create_rectangle(self.cpux,
+ self.item = canvas.create_text(X_BORDER, ypos, anchor="w",
+ text=self.name)
+ return (self.item)
+
+ def drawcpu(self, canvas, cpu, fromx, tox, ypos):
+ cpu = "CPU " + str(cpu)
+ color = cpucolormap.lookup(cpu)
+ # Create the cpu background colors default to hidden
+ l = canvas.create_rectangle(fromx,
ypos - self.ysize() - canvas.bdheight,
- xpos, ypos + canvas.bdheight, fill=color, width=0,
- tags=("all", "cpuinfo"))
+ tox, ypos + canvas.bdheight, fill=color, width=0,
+ tags=("cpubg", cpu, self.tag), state="hidden")
+ self.cpuitems.append(l)
+
+ def move(self, canvas, xpos, ypos):
+ canvas.move(self.tag, xpos, ypos)
+
+ def movename(self, canvas, xpos, ypos):
+ self.y += ypos
+ canvas.move(self.item, xpos, ypos)
def ysize(self):
- return (None)
+ return (Y_EVENTSOURCE)
def eventat(self, i):
if (i >= len(self.events)):
@@ -812,77 +863,68 @@ class EventSource:
def findevent(self, timestamp):
for event in self.events:
- if (event.timestamp >= timestamp and event.real):
+ if (event.timestamp >= timestamp and event.type != "pad"):
return (event)
return (None)
-class Thread(EventSource):
- names = {}
- def __init__(self, td, pcomm):
- EventSource.__init__(self, pcomm)
- self.str = td
+class Counter(EventSource):
+ #
+ # Store a hash of counter groups that keeps the max value
+ # for a counter in this group for scaling purposes.
+ #
+ groups = {}
+ def __init__(self, group, id):
try:
- cnt = Thread.names[pcomm]
+ Counter.cnt = Counter.groups[group]
except:
- Thread.names[pcomm] = 0
- return
- Thread.names[pcomm] = cnt + 1
+ Counter.groups[group] = 0
+ EventSource.__init__(self, group, id)
def fixup(self):
- cnt = Thread.names[self.name]
- if (cnt == 0):
- return
- cnt -= 1
- Thread.names[self.name] = cnt
- self.name += " td" + str(cnt)
-
- def ysize(self):
- return (10)
-
-class Counter(EventSource):
- max = 0
- def __init__(self, name):
- EventSource.__init__(self, name)
-
- def event(self, event):
- EventSource.event(self, event)
- try:
- count = event.count
- except:
- return
- count = int(count)
- if (count > Counter.max):
- Counter.max = count
+ for event in self.events:
+ if (event.type != "count"):
+ continue;
+ count = int(event.count)
+ if (count > Counter.groups[self.group]):
+ Counter.groups[self.group] = count
+ EventSource.fixup(self)
def ymax(self):
- return (Counter.max)
+ return (Counter.groups[self.group])
def ysize(self):
- return (80)
+ return (Y_COUNTER)
def yscale(self):
- return (self.ysize() / Counter.max)
-
+ return (self.ysize() / self.ymax())
class KTRFile:
def __init__(self, file):
self.timestamp_f = None
self.timestamp_l = None
- self.threads = []
- self.sources = []
+ self.locks = {}
+ self.callwheels = {}
self.ticks = {}
self.load = {}
self.crit = {}
self.stathz = 0
+ self.eventcnt = 0
+ self.taghash = {}
self.parse(file)
self.fixup()
global ticksps
- print "first", self.timestamp_f, "last", self.timestamp_l
- print "time span", self.timespan()
- print "stathz", self.stathz
ticksps = self.ticksps()
- print "Ticks per second", ticksps
+ span = self.timespan()
+ ghz = float(ticksps) / 1000000000.0
+ #
+ # Update the title with some stats from the file
+ #
+ titlestr = "SchedGraph: "
+ titlestr += ticks2sec(span) + " at %.3f ghz, " % ghz
+ titlestr += str(len(sources)) + " event sources, "
+ titlestr += str(self.eventcnt) + " events"
+ root.title(titlestr)
def parse(self, file):
try:
@@ -891,369 +933,340 @@ class KTRFile:
print "Can't open", file
sys.exit(1)
- ktrhdr = "\s*\d+\s+(\d+)\s+(\d+)\s+"
- tdname = "(\S+)\(([^)]*)\)"
- crittdname = "(\S+)\s+\(\d+,\s+([^)]*)\)"
-
-# XXX doesn't handle:
-# 371 0 61628682318 mi_switch: 0xc075c070(swapper) prio 180 inhibit 2 wmesg ATA request done lock (null)
- ktrstr = "mi_switch: " + tdname
- ktrstr += " prio (\d+) inhibit (\d+) wmesg (\S+) lock (\S+)"
- switchout_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "mi_switch: " + tdname + " prio (\d+) idle"
- idled_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "mi_switch: " + tdname + " prio (\d+) preempted by "
- ktrstr += tdname
- preempted_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "mi_switch: running " + tdname + " prio (\d+)"
- switchin_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "sched_add: " + tdname + " prio (\d+) by " + tdname
- sched_add_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "setrunqueue: " + tdname + " prio (\d+) by " + tdname
- setrunqueue_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "sched_rem: " + tdname + " prio (\d+) by " + tdname
- sched_rem_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "sched_exit_thread: " + tdname + " prio (\d+)"
- sched_exit_thread_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "sched_exit: " + tdname + " prio (\d+)"
- sched_exit_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "statclock: " + tdname + " prio (\d+)"
- ktrstr += " stathz (\d+)"
- sched_clock_re = re.compile(ktrhdr + ktrstr)
-
- ktrstr = "sched_prio: " + tdname + " prio (\d+)"
- ktrstr += " newprio (\d+) by " + tdname
- sched_prio_re = re.compile(ktrhdr + ktrstr)
-
- cpuload_re = re.compile(ktrhdr + "load: (\d+)")
- cpuload2_re = re.compile(ktrhdr + "cpu (\d+) load: (\d+)")
- loadglobal_re = re.compile(ktrhdr + "global load: (\d+)")
-
- ktrstr = "critical_\S+ by thread " + crittdname + " to (\d+)"
- critsec_re = re.compile(ktrhdr + ktrstr)
-
- parsers = [[cpuload_re, self.cpuload],
- [cpuload2_re, self.cpuload2],
- [loadglobal_re, self.loadglobal],
- [switchin_re, self.switchin],
- [switchout_re, self.switchout],
- [sched_add_re, self.sched_add],
- [setrunqueue_re, self.sched_rem],
- [sched_prio_re, self.sched_prio],
- [preempted_re, self.preempted],
- [sched_rem_re, self.sched_rem],
- [sched_exit_thread_re, self.sched_exit_thread],
- [sched_exit_re, self.sched_exit],
- [sched_clock_re, self.sched_clock],
- [critsec_re, self.critsec],
- [idled_re, self.idled]]
+ # quoteexp matches a quoted string, no escaping
+ quoteexp = "\"([^\"]*)\""
+
+ #
+ # commaexp matches a quoted string OR the string up
+ # to the first ','
+ #
+ commaexp = "(?:" + quoteexp + "|([^,]+))"
+
+ #
+ # colonstr matches a quoted string OR the string up
+ # to the first ':'
+ #
+ colonexp = "(?:" + quoteexp + "|([^:]+))"
+
+ #
+ # Match various manditory parts of the KTR string this is
+ # fairly inflexible until you get to attributes to make
+ # parsing faster.
+ #
+ hdrexp = "\s*(\d+)\s+(\d+)\s+(\d+)\s+"
+ groupexp = "KTRGRAPH group:" + quoteexp + ", "
+ idexp = "id:" + quoteexp + ", "
+ typeexp = "([^:]+):" + commaexp + ", "
+ attribexp = "attributes: (.*)"
+
+ #
+ # Matches optional attributes in the KTR string. This
+ # tolerates more variance as the users supply these values.
+ #
+ attrexp = colonexp + "\s*:\s*(?:" + commaexp + ", (.*)|"
+ attrexp += quoteexp +"|(.*))"
+
+ # Precompile regexp
+ ktrre = re.compile(hdrexp + groupexp + idexp + typeexp + attribexp)
+ attrre = re.compile(attrexp)
global lineno
lineno = 0
for line in ifp.readlines():
lineno += 1
- if ((lineno % 1024) == 0):
+ if ((lineno % 2048) == 0):
status.startup("Parsing line " + str(lineno))
- for p in parsers:
- m = p[0].match(line)
- if (m != None):
- p[1](*m.groups())
- break
+ m = ktrre.match(line);
if (m == None):
- print line,
+ print "Can't parse", lineno, line,
+ continue;
+ (index, cpu, timestamp, group, id, type, dat, dat1, attrstring) = m.groups();
+ if (dat == None):
+ dat = dat1
+ if (self.checkstamp(timestamp) == 0):
+ print "Bad timestamp at", lineno, ":",
+ print cpu, timestamp
+ continue
+ #
+ # Build the table of optional attributes
+ #
+ attrs = []
+ while (attrstring != None):
+ m = attrre.match(attrstring.strip())
+ if (m == None):
+ break;
+ #
+ # Name may or may not be quoted.
+ #
+ # For val we have four cases:
+ # 1) quotes followed by comma and more
+ # attributes.
+ # 2) no quotes followed by comma and more
+ # attributes.
+ # 3) no more attributes or comma with quotes.
+ # 4) no more attributes or comma without quotes.
+ #
+ (name, name1, val, val1, attrstring, end, end1) = m.groups();
+ if (name == None):
+ name = name1
+ if (end == None):
+ end = end1
+ if (val == None):
+ val = val1
+ if (val == None):
+ val = end
+ if (name == "stathz"):
+ self.setstathz(val, cpu)
+ attrs.append((name, val))
+ args = (dat, cpu, timestamp, attrs)
+ e = self.makeevent(group, id, type, args)
+ if (e == None):
+ print "Unknown type", type, lineno, line,
+
+ def makeevent(self, group, id, type, args):
+ e = None
+ source = self.makeid(group, id, type)
+ if (type == "state"):
+ e = StateEvent(source, *args)
+ elif (type == "counter"):
+ e = CountEvent(source, *args)
+ elif (type == "point"):
+ e = PointEvent(source, *args)
+ if (e != None):
+ self.eventcnt += 1
+ source.addevent(e);
+ return e
+
+ def setstathz(self, val, cpu):
+ self.stathz = int(val)
+ cpu = int(cpu)
+ try:
+ ticks = self.ticks[cpu]
+ except:
+ self.ticks[cpu] = 0
+ self.ticks[cpu] += 1
- def checkstamp(self, cpu, timestamp):
+ def checkstamp(self, timestamp):
timestamp = int(timestamp)
if (self.timestamp_f == None):
self.timestamp_f = timestamp;
- if (self.timestamp_l != None and timestamp > self.timestamp_l):
+ if (self.timestamp_l != None and
+ timestamp -2048> self.timestamp_l):
return (0)
self.timestamp_l = timestamp;
- return (timestamp)
+ return (1)
+
+ def makeid(self, group, id, type):
+ tag = group + id
+ if (self.taghash.has_key(tag)):
+ return self.taghash[tag]
+ if (type == "counter"):
+ source = Counter(group, id)
+ else:
+ source = EventSource(group, id)
+ sources.append(source)
+ self.taghash[tag] = source
+ return (source)
+
+ def findid(self, id):
+ for source in sources:
+ if (source.name == id):
+ return source
+ return (None)
def timespan(self):
return (self.timestamp_f - self.timestamp_l);
def ticksps(self):
- return (self.timespan() / self.ticks[0]) * int(self.stathz)
-
- def switchout(self, cpu, timestamp, td, pcomm, prio, inhibit, wmesg, lock):
- TDI_SUSPENDED = 0x0001
- TDI_SLEEPING = 0x0002
- TDI_SWAPPED = 0x0004
- TDI_LOCK = 0x0008
- TDI_IWAIT = 0x0010
+ oneghz = 1000000000
+ # Use user supplied clock first
+ if (clockfreq != None):
+ return int(clockfreq * oneghz)
+
+ # Check for a discovered clock
+ if (self.stathz != 0):
+ return (self.timespan() / self.ticks[0]) * int(self.stathz)
+ # Pretend we have a 1ns clock
+ print "WARNING: No clock discovered and no frequency ",
+ print "specified via the command line."
+ print "Using fake 1ghz clock"
+ return (oneghz);
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- inhibit = int(inhibit)
- thread = self.findtd(td, pcomm)
- if (inhibit & TDI_SWAPPED):
- Swapped(thread, cpu, timestamp, prio)
- elif (inhibit & TDI_SLEEPING):
- Sleep(thread, cpu, timestamp, prio, wmesg)
- elif (inhibit & TDI_LOCK):
- Blocked(thread, cpu, timestamp, prio, lock)
- elif (inhibit & TDI_IWAIT):
- Iwait(thread, cpu, timestamp, prio)
- elif (inhibit & TDI_SUSPENDED):
- Suspended(thread, cpu, timestamp, prio)
- elif (inhibit == 0):
- Yielding(thread, cpu, timestamp, prio)
- else:
- print "Unknown event", inhibit
- sys.exit(1)
-
- def idled(self, cpu, timestamp, td, pcomm, prio):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- Idle(thread, cpu, timestamp, prio)
-
- def preempted(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- Preempted(thread, cpu, timestamp, prio,
- self.findtd(bytd, bypcomm))
-
- def switchin(self, cpu, timestamp, td, pcomm, prio):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- Running(thread, cpu, timestamp, prio)
-
- def sched_add(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- bythread = self.findtd(bytd, bypcomm)
- Runq(thread, cpu, timestamp, prio, bythread)
- Wokeup(bythread, cpu, timestamp, thread)
-
- def sched_rem(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- KsegrpRunq(thread, cpu, timestamp, prio,
- self.findtd(bytd, bypcomm))
-
- def sched_exit_thread(self, cpu, timestamp, td, pcomm, prio):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- Sched_exit_thread(thread, cpu, timestamp, prio)
-
- def sched_exit(self, cpu, timestamp, td, pcomm, prio):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
+ def fixup(self):
+ for source in sources:
+ e = PadEvent(source, -1, self.timestamp_l)
+ source.addevent(e)
+ e = PadEvent(source, -1, self.timestamp_f, last=1)
+ source.addlastevent(e)
+ source.fixup()
+ sources.sort()
+
+class SchedNames(Canvas):
+ def __init__(self, master, display):
+ self.display = display
+ self.parent = master
+ self.bdheight = master.bdheight
+ self.items = {}
+ self.ysize = 0
+ self.lines = []
+ Canvas.__init__(self, master, width=120,
+ height=display["height"], bg='grey',
+ scrollregion=(0, 0, 50, 100))
+
+ def moveline(self, cur_y, y):
+ for line in self.lines:
+ (x0, y0, x1, y1) = self.coords(line)
+ if (cur_y != y0):
+ continue
+ self.move(line, 0, y)
return
- thread = self.findtd(td, pcomm)
- Sched_exit(thread, cpu, timestamp, prio)
- def sched_clock(self, cpu, timestamp, td, pcomm, prio, stathz):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- self.stathz = stathz
- cpu = int(cpu)
- try:
- ticks = self.ticks[cpu]
- except:
- self.ticks[cpu] = 0
- self.ticks[cpu] += 1
- thread = self.findtd(td, pcomm)
- Tick(thread, cpu, timestamp, prio, stathz)
+ def draw(self):
+ status.startup("Drawing names")
+ ypos = 0
+ self.configure(scrollregion=(0, 0,
+ self["width"], self.display.ysize()))
+ for source in sources:
+ l = self.create_line(0, ypos, self["width"], ypos,
+ width=1, fill="black", tags=("all","sources"))
+ self.lines.append(l)
+ ypos += self.bdheight
+ ypos += source.ysize()
+ t = source.drawname(self, ypos)
+ self.items[t] = source
+ ypos += self.bdheight
+ self.ysize = ypos
+ self.create_line(0, ypos, self["width"], ypos,
+ width=1, fill="black", tags=("all",))
+ self.bind("<Button-1>", self.master.mousepress);
+ self.bind("<Button-3>", self.master.mousepressright);
+ self.bind("<ButtonRelease-1>", self.master.mouserelease);
+ self.bind("<B1-Motion>", self.master.mousemotion);
- def sched_prio(self, cpu, timestamp, td, pcomm, prio, newprio, bytd, bypcomm):
- if (prio == newprio):
- return
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- thread = self.findtd(td, pcomm)
- bythread = self.findtd(bytd, bypcomm)
- Prio(thread, cpu, timestamp, prio, newprio, bythread)
- Lend(bythread, cpu, timestamp, newprio, thread)
-
- def cpuload(self, cpu, timestamp, count):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- cpu = int(cpu)
- try:
- load = self.load[cpu]
- except:
- load = Counter("cpu" + str(cpu) + " load")
- self.load[cpu] = load
- self.sources.insert(0, load)
- Count(load, cpu, timestamp, count)
-
- def cpuload2(self, cpu, timestamp, ncpu, count):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- cpu = int(ncpu)
- try:
- load = self.load[cpu]
- except:
- load = Counter("cpu" + str(cpu) + " load")
- self.load[cpu] = load
- self.sources.insert(0, load)
- Count(load, cpu, timestamp, count)
-
- def loadglobal(self, cpu, timestamp, count):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- cpu = 0
- try:
- load = self.load[cpu]
- except:
- load = Counter("CPU load")
- self.load[cpu] = load
- self.sources.insert(0, load)
- Count(load, cpu, timestamp, count)
-
- def critsec(self, cpu, timestamp, td, pcomm, to):
- timestamp = self.checkstamp(cpu, timestamp)
- if (timestamp == 0):
- return
- cpu = int(cpu)
- try:
- crit = self.crit[cpu]
- except:
- crit = Counter("Critical Section")
- self.crit[cpu] = crit
- self.sources.insert(0, crit)
- Count(crit, cpu, timestamp, to)
-
- def findtd(self, td, pcomm):
- for thread in self.threads:
- if (thread.str == td and thread.name == pcomm):
- return thread
- thread = Thread(td, pcomm)
- self.threads.append(thread)
- self.sources.append(thread)
- return (thread)
+ def updatescroll(self):
+ self.configure(scrollregion=(0, 0,
+ self["width"], self.display.ysize()))
- def fixup(self):
- for source in self.sources:
- Padevent(source, -1, self.timestamp_l)
- Padevent(source, -1, self.timestamp_f, last=1)
- source.fixup()
class SchedDisplay(Canvas):
def __init__(self, master):
- self.ratio = 10
- self.ktrfile = None
- self.sources = None
- self.bdheight = 10
- self.events = {}
-
+ self.ratio = 1
+ self.parent = master
+ self.bdheight = master.bdheight
+ self.items = {}
+ self.lines = []
Canvas.__init__(self, master, width=800, height=500, bg='grey',
scrollregion=(0, 0, 800, 500))
- def setfile(self, ktrfile):
- self.ktrfile = ktrfile
- self.sources = ktrfile.sources
+ def prepare(self):
+ #
+ # Compute a ratio to ensure that the file's timespan fits into
+ # 2^31. Although python may handle larger values for X
+ # values, the Tk internals do not.
+ #
+ self.ratio = (ktrfile.timespan() - 1) / 2**31 + 1
def draw(self):
ypos = 0
xsize = self.xsize()
- for source in self.sources:
+ for source in sources:
status.startup("Drawing " + source.name)
- self.create_line(0, ypos, xsize, ypos,
+ l = self.create_line(0, ypos, xsize, ypos,
width=1, fill="black", tags=("all",))
+ self.lines.append(l)
ypos += self.bdheight
ypos += source.ysize()
source.draw(self, ypos)
ypos += self.bdheight
- try:
- self.tag_raise("point", "state")
- self.tag_lower("cpuinfo", "all")
- except:
- pass
+ self.tag_raise("point", "state")
+ self.tag_lower("cpubg", ALL)
self.create_line(0, ypos, xsize, ypos,
- width=1, fill="black", tags=("all",))
+ width=1, fill="black", tags=("lines",))
self.tag_bind("event", "<Enter>", self.mouseenter)
self.tag_bind("event", "<Leave>", self.mouseexit)
- self.tag_bind("event", "<Button-1>", self.mousepress)
+ self.bind("<Button-1>", self.mousepress)
+ self.bind("<Button-3>", self.master.mousepressright);
+ self.bind("<Button-4>", self.wheelup)
+ self.bind("<Button-5>", self.wheeldown)
+ self.bind("<ButtonRelease-1>", self.master.mouserelease);
+ self.bind("<B1-Motion>", self.master.mousemotion);
+
+ def moveline(self, cur_y, y):
+ for line in self.lines:
+ (x0, y0, x1, y1) = self.coords(line)
+ if (cur_y != y0):
+ continue
+ self.move(line, 0, y)
+ return
def mouseenter(self, event):
item, = self.find_withtag(CURRENT)
- event = self.events[item]
- event.mouseenter(self, item)
+ self.items[item].mouseenter(self)
def mouseexit(self, event):
item, = self.find_withtag(CURRENT)
- event = self.events[item]
- event.mouseexit(self, item)
+ self.items[item].mouseexit(self)
def mousepress(self, event):
- item, = self.find_withtag(CURRENT)
- event = self.events[item]
- event.mousepress(self, item)
+ # Find out what's beneath us
+ items = self.find_withtag(CURRENT)
+ if (len(items) == 0):
+ self.master.mousepress(event)
+ return
+ # Only grab mouse presses for things with event tags.
+ item = items[0]
+ tags = self.gettags(item)
+ for tag in tags:
+ if (tag == "event"):
+ self.items[item].mousepress(self)
+ return
+ # Leave the rest to the master window
+ self.master.mousepress(event)
- def drawnames(self, canvas):
- status.startup("Drawing names")
- ypos = 0
- canvas.configure(scrollregion=(0, 0,
- canvas["width"], self.ysize()))
- for source in self.sources:
- canvas.create_line(0, ypos, canvas["width"], ypos,
- width=1, fill="black", tags=("all",))
- ypos += self.bdheight
- ypos += source.ysize()
- source.drawname(canvas, ypos)
- ypos += self.bdheight
- canvas.create_line(0, ypos, canvas["width"], ypos,
- width=1, fill="black", tags=("all",))
+ def wheeldown(self, event):
+ self.parent.display_yview("scroll", 1, "units")
+
+ def wheelup(self, event):
+ self.parent.display_yview("scroll", -1, "units")
def xsize(self):
- return ((self.ktrfile.timespan() / self.ratio) + 20)
+ return ((ktrfile.timespan() / self.ratio) + (X_BORDER * 2))
def ysize(self):
ysize = 0
- for source in self.sources:
- ysize += source.ysize() + (self.bdheight * 2)
- return (ysize)
+ for source in sources:
+ if (source.hidden == 1):
+ continue
+ ysize += self.parent.sourcesize(source)
+ return ysize
def scaleset(self, ratio):
- if (self.ktrfile == None):
+ if (ktrfile == None):
return
oldratio = self.ratio
- xstart, ystart = self.xview()
- length = (float(self["width"]) / self.xsize())
- middle = xstart + (length / 2)
+ xstart, xend = self.xview()
+ midpoint = xstart + ((xend - xstart) / 2)
self.ratio = ratio
- self.configure(scrollregion=(0, 0, self.xsize(), self.ysize()))
- self.scale("all", 0, 0, float(oldratio) / ratio, 1)
+ self.updatescroll()
+ self.scale(ALL, 0, 0, float(oldratio) / ratio, 1)
+
+ xstart, xend = self.xview()
+ xsize = (xend - xstart) / 2
+ self.xview_moveto(midpoint - xsize)
- length = (float(self["width"]) / self.xsize())
- xstart = middle - (length / 2)
- self.xview_moveto(xstart)
+ def updatescroll(self):
+ self.configure(scrollregion=(0, 0, self.xsize(), self.ysize()))
def scaleget(self):
return self.ratio
+ def getcolor(self, tag):
+ return self.itemcget(tag, "fill")
+
+ def getstate(self, tag):
+ return self.itemcget(tag, "state")
+
def setcolor(self, tag, color):
self.itemconfigure(tag, state="normal", fill=color)
@@ -1263,16 +1276,25 @@ class SchedDisplay(Canvas):
class GraphMenu(Frame):
def __init__(self, master):
Frame.__init__(self, master, bd=2, relief=RAISED)
- self.view = Menubutton(self, text="Configure")
- self.viewmenu = Menu(self.view, tearoff=0)
- self.viewmenu.add_command(label="Events",
+ self.conf = Menubutton(self, text="Configure")
+ self.confmenu = Menu(self.conf, tearoff=0)
+ self.confmenu.add_command(label="Event Colors",
command=self.econf)
- self.view["menu"] = self.viewmenu
- self.view.pack(side=LEFT)
+ self.confmenu.add_command(label="CPU Colors",
+ command=self.cconf)
+ self.confmenu.add_command(label="Source Configure",
+ command=self.sconf)
+ self.conf["menu"] = self.confmenu
+ self.conf.pack(side=LEFT)
def econf(self):
- EventConfigure()
+ ColorConfigure(eventcolors, "Event Display Configuration")
+
+ def cconf(self):
+ ColorConfigure(cpucolors, "CPU Background Colors")
+ def sconf(self):
+ SourceConfigure()
class SchedGraph(Frame):
def __init__(self, master):
@@ -1282,18 +1304,18 @@ class SchedGraph(Frame):
self.display = None
self.scale = None
self.status = None
+ self.bdheight = Y_BORDER
+ self.clicksource = None
+ self.lastsource = None
self.pack(expand=1, fill="both")
self.buildwidgets()
self.layout()
- self.draw(sys.argv[1])
def buildwidgets(self):
global status
self.menu = GraphMenu(self)
self.display = SchedDisplay(self)
- self.names = Canvas(self,
- width=100, height=self.display["height"],
- bg='grey', scrollregion=(0, 0, 50, 100))
+ self.names = SchedNames(self, self.display)
self.scale = Scaler(self, self.display)
status = self.status = Status(self)
self.scrollY = Scrollbar(self, orient="vertical",
@@ -1316,30 +1338,288 @@ class SchedGraph(Frame):
self.scale.grid(row=3, column=0, columnspan=3, sticky=E+W)
self.status.grid(row=4, column=0, columnspan=3, sticky=E+W)
- def draw(self, file):
+ def draw(self):
self.master.update()
- ktrfile = KTRFile(file)
- self.display.setfile(ktrfile)
- self.display.drawnames(self.names)
+ self.display.prepare()
+ self.names.draw()
self.display.draw()
- self.scale.set(250000)
+ self.status.startup("")
+ #
+ # Configure scale related values
+ #
+ scalemax = ktrfile.timespan() / int(self.display["width"])
+ width = int(root.geometry().split('x')[0])
+ self.constwidth = width - int(self.display["width"])
+ self.scale.setmax(scalemax)
+ self.scale.set(scalemax)
self.display.xview_moveto(0)
+ self.bind("<Configure>", self.resize)
+
+ def mousepress(self, event):
+ self.clicksource = self.sourceat(event.y)
+
+ def mousepressright(self, event):
+ source = self.sourceat(event.y)
+ if (source == None):
+ return
+ SourceContext(event, source)
+
+ def mouserelease(self, event):
+ if (self.clicksource == None):
+ return
+ newsource = self.sourceat(event.y)
+ if (self.clicksource != newsource):
+ self.sourceswap(self.clicksource, newsource)
+ self.clicksource = None
+ self.lastsource = None
+
+ def mousemotion(self, event):
+ if (self.clicksource == None):
+ return
+ newsource = self.sourceat(event.y)
+ #
+ # If we get a None source they moved off the page.
+ # swapsource() can't handle moving multiple items so just
+ # pretend we never clicked on anything to begin with so the
+ # user can't mouseover a non-contiguous area.
+ #
+ if (newsource == None):
+ self.clicksource = None
+ self.lastsource = None
+ return
+ if (newsource == self.lastsource):
+ return;
+ self.lastsource = newsource
+ if (newsource != self.clicksource):
+ self.sourceswap(self.clicksource, newsource)
+
+ # These are here because this object controls layout
+ def sourcestart(self, source):
+ return source.y - self.bdheight - source.ysize()
+
+ def sourceend(self, source):
+ return source.y + self.bdheight
+
+ def sourcesize(self, source):
+ return (self.bdheight * 2) + source.ysize()
+
+ def sourceswap(self, source1, source2):
+ # Sort so we always know which one is on top.
+ if (source2.y < source1.y):
+ swap = source1
+ source1 = source2
+ source2 = swap
+ # Only swap adjacent sources
+ if (self.sourceend(source1) != self.sourcestart(source2)):
+ return
+ # Compute start coordinates and target coordinates
+ y1 = self.sourcestart(source1)
+ y2 = self.sourcestart(source2)
+ y1targ = y1 + self.sourcesize(source2)
+ y2targ = y1
+ #
+ # If the sizes are not equal, adjust the start of the lower
+ # source to account for the lost/gained space.
+ #
+ if (source1.ysize() != source2.ysize()):
+ diff = source2.ysize() - source1.ysize()
+ self.names.moveline(y2, diff);
+ self.display.moveline(y2, diff)
+ source1.move(self.display, 0, y1targ - y1)
+ source2.move(self.display, 0, y2targ - y2)
+ source1.movename(self.names, 0, y1targ - y1)
+ source2.movename(self.names, 0, y2targ - y2)
+
+ def sourcepicky(self, source):
+ if (source.hidden == 0):
+ return self.sourcestart(source)
+ # Revert to group based sort
+ sources.sort()
+ prev = None
+ for s in sources:
+ if (s == source):
+ break
+ if (s.hidden == 0):
+ prev = s
+ if (prev == None):
+ newy = 0
+ else:
+ newy = self.sourcestart(prev) + self.sourcesize(prev)
+ return newy
+
+ def sourceshow(self, source):
+ if (source.hidden == 0):
+ return;
+ newy = self.sourcepicky(source)
+ off = newy - self.sourcestart(source)
+ self.sourceshiftall(newy-1, self.sourcesize(source))
+ self.sourceshift(source, off)
+ source.hidden = 0
+
+ #
+ # Optimized source show of multiple entries that only moves each
+ # existing entry once. Doing sourceshow() iteratively is too
+ # expensive due to python's canvas.move().
+ #
+ def sourceshowlist(self, srclist):
+ srclist.sort(cmp=source_cmp_start)
+ startsize = []
+ for source in srclist:
+ if (source.hidden == 0):
+ srclist.remove(source)
+ startsize.append((self.sourcepicky(source),
+ self.sourcesize(source)))
+
+ sources.sort(cmp=source_cmp_start, reverse=True)
+ self.status.startup("Updating display...");
+ for source in sources:
+ if (source.hidden == 1):
+ continue
+ nstart = self.sourcestart(source)
+ size = 0
+ for hidden in startsize:
+ (start, sz) = hidden
+ if (start <= nstart or start+sz <= nstart):
+ size += sz
+ self.sourceshift(source, size)
+ idx = 0
+ size = 0
+ for source in srclist:
+ (newy, sz) = startsize[idx]
+ off = (newy + size) - self.sourcestart(source)
+ self.sourceshift(source, off)
+ source.hidden = 0
+ size += sz
+ idx += 1
+ self.updatescroll()
+ self.status.set("")
+
+ #
+ # Optimized source hide of multiple entries that only moves each
+ # remaining entry once. Doing sourcehide() iteratively is too
+ # expensive due to python's canvas.move().
+ #
+ def sourcehidelist(self, srclist):
+ srclist.sort(cmp=source_cmp_start)
+ sources.sort(cmp=source_cmp_start)
+ startsize = []
+ off = len(sources) * 100
+ self.status.startup("Updating display...");
+ for source in srclist:
+ if (source.hidden == 1):
+ srclist.remove(source)
+ #
+ # Remember our old position so we can sort things
+ # below us when we're done.
+ #
+ startsize.append((self.sourcestart(source),
+ self.sourcesize(source)))
+ self.sourceshift(source, off)
+ source.hidden = 1
+
+ idx = 0
+ size = 0
+ for hidden in startsize:
+ (start, sz) = hidden
+ size += sz
+ if (idx + 1 < len(startsize)):
+ (stop, sz) = startsize[idx+1]
+ else:
+ stop = self.display.ysize()
+ idx += 1
+ for source in sources:
+ nstart = self.sourcestart(source)
+ if (nstart < start or source.hidden == 1):
+ continue
+ if (nstart >= stop):
+ break;
+ self.sourceshift(source, -size)
+ self.updatescroll()
+ self.status.set("")
+
+ def sourcehide(self, source):
+ if (source.hidden == 1):
+ return;
+ # Move it out of the visible area
+ off = len(sources) * 100
+ start = self.sourcestart(source)
+ self.sourceshift(source, off)
+ self.sourceshiftall(start, -self.sourcesize(source))
+ source.hidden = 1
+
+ def sourceshift(self, source, off):
+ start = self.sourcestart(source)
+ source.move(self.display, 0, off)
+ source.movename(self.names, 0, off)
+ self.names.moveline(start, off);
+ self.display.moveline(start, off)
+ #
+ # We update the idle tasks to shrink the dirtied area so
+ # it does not always include the entire screen.
+ #
+ self.names.update_idletasks()
+ self.display.update_idletasks()
+
+ def sourceshiftall(self, start, off):
+ self.status.startup("Updating display...");
+ for source in sources:
+ nstart = self.sourcestart(source)
+ if (nstart < start):
+ continue;
+ self.sourceshift(source, off)
+ self.updatescroll()
+ self.status.set("")
+
+ def sourceat(self, ypos):
+ (start, end) = self.names.yview()
+ starty = start * float(self.names.ysize)
+ ypos += starty
+ for source in sources:
+ if (source.hidden == 1):
+ continue;
+ yend = self.sourceend(source)
+ ystart = self.sourcestart(source)
+ if (ypos >= ystart and ypos <= yend):
+ return source
+ return None
def display_yview(self, *args):
self.names.yview(*args)
self.display.yview(*args)
+ def resize(self, *args):
+ width = int(root.geometry().split('x')[0])
+ scalemax = ktrfile.timespan() / (width - self.constwidth)
+ self.scale.setmax(scalemax)
+
+ def updatescroll(self):
+ self.names.updatescroll()
+ self.display.updatescroll()
+
def setcolor(self, tag, color):
self.display.setcolor(tag, color)
def hide(self, tag):
self.display.hide(tag)
-if (len(sys.argv) != 2):
- print "usage:", sys.argv[0], "<ktr file>"
+ def getcolor(self, tag):
+ return self.display.getcolor(tag)
+
+ def getstate(self, tag):
+ return self.display.getstate(tag)
+
+if (len(sys.argv) != 2 and len(sys.argv) != 3):
+ print "usage:", sys.argv[0], "<ktr file> [clock freq in ghz]"
sys.exit(1)
+if (len(sys.argv) > 2):
+ clockfreq = float(sys.argv[2])
+
root = Tk()
-root.title("Scheduler Graph")
+root.title("SchedGraph")
+colormap = Colormap(eventcolors)
+cpucolormap = Colormap(cpucolors)
graph = SchedGraph(root)
+ktrfile = KTRFile(sys.argv[1])
+graph.draw()
root.mainloop()
diff --git a/tools/tools/README b/tools/tools/README
index c00cf2a..9190f6b 100644
--- a/tools/tools/README
+++ b/tools/tools/README
@@ -12,6 +12,7 @@ ansify Convert K&R-style function definitions to ANSI style
ath Tools specific to the Atheros 802.11 support
backout_commit A tool for reading in a commit message and generating
a script that will backout the commit.
+cfi Common Flash Interface (CFI) tool
commitsdb A tool for reconstructing commit history using md5
checksums of the commit logs.
crypto Test and exercise tools related to the crypto framework
diff --git a/tools/tools/ath/Makefile b/tools/tools/ath/Makefile
index 16a87ae..ed421bc 100644
--- a/tools/tools/ath/Makefile
+++ b/tools/tools/ath/Makefile
@@ -1,5 +1,5 @@
# $FreeBSD$
-SUBDIR= athdebug athkey athprom athregs athstats
+SUBDIR= athdebug athkey athprom athrd athregs athstats
.include <bsd.subdir.mk>
diff --git a/tools/tools/ath/Makefile.inc b/tools/tools/ath/Makefile.inc
index 68ea6a9..81f0a80 100644
--- a/tools/tools/ath/Makefile.inc
+++ b/tools/tools/ath/Makefile.inc
@@ -6,6 +6,7 @@ NO_MAN=
ATH_DEFAULT= ath0
CFLAGS+=-DATH_DEFAULT='"${ATH_DEFAULT}"'
-CFLAGS+=-I../common
-CFLAGS+=-I../../../../sys/dev/ath
-CFLAGS+=-I../../../../sys/dev/ath/ath_hal
+CFLAGS+=-I${.CURDIR}
+CFLAGS+=-I${.CURDIR}/../common
+CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath
+CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath/ath_hal
diff --git a/tools/tools/ath/athdebug/athdebug.c b/tools/tools/ath/athdebug/athdebug.c
index 76d5932..a219aae 100644
--- a/tools/tools/ath/athdebug/athdebug.c
+++ b/tools/tools/ath/athdebug/athdebug.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,7 @@ enum {
ATH_DEBUG_FF = 0x00200000, /* fast frames */
ATH_DEBUG_DFS = 0x00400000, /* DFS processing */
ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */
+ ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */
ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
ATH_DEBUG_ANY = 0xffffffff
@@ -99,6 +100,7 @@ static struct {
{ "ff", ATH_DEBUG_FF },
{ "dfs", ATH_DEBUG_DFS },
{ "tdma", ATH_DEBUG_TDMA },
+ { "tdma_timer", ATH_DEBUG_TDMA_TIMER },
{ "regdomain", ATH_DEBUG_REGDOMAIN },
{ "fatal", ATH_DEBUG_FATAL },
};
diff --git a/tools/tools/ath/athrd/Makefile b/tools/tools/ath/athrd/Makefile
new file mode 100644
index 0000000..352d712
--- /dev/null
+++ b/tools/tools/ath/athrd/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= athrd
+
+SRCS= athrd.c ah_regdomain.c opt_ah.h
+
+CLEANFILES+= opt_ah.h
+
+CFLAGS+= -fno-inline
+
+.include <../Makefile.inc>
+
+MAN= athrd.1
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athrd/athrd.1 b/tools/tools/ath/athrd/athrd.1
new file mode 100644
index 0000000..ef9f007
--- /dev/null
+++ b/tools/tools/ath/athrd/athrd.1
@@ -0,0 +1,172 @@
+.\"-
+.\" Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+.\" 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,
+.\" without modification.
+.\" 2. Redistributions in binary form must reproduce at minimum a disclaimer
+.\" similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+.\" redistribution must be conditioned upon including a substantially
+.\" similar Disclaimer requirement for further binary redistribution.
+.\"
+.\" NO WARRANTY
+.\" 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 NONINFRINGEMENT, MERCHANTIBILITY
+.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+.\" THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+.\"
+.\" $FreeBSD$
+.\"/
+.Dd January 27, 2009
+.Dt ATHRD 1
+.Os
+.Sh NAME
+.Nm athrd
+.Nd list channels and transmit power for a country/regulatory domain
+.Sh SYNOPSIS
+.Nm
+.Op Fl aedlpcfr4ABGT
+.Op Fl m Ar mode
+.Bk
+.Op Ar country
+.Ek
+.Sh DESCRIPTION
+.Nm
+displays the list of frequencies and the associated maximum transmit
+power permitted within a regulatory domain and/or country.
+.Pp
+If no command line options are given, a default country (\c
+.Ql US )
+is used.
+Country and regulatory names are case insensitive.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl a
+By default
+.Nm
+will display B channels only if they are not also marked as available for
+use as G channels and similary for A and T channels.
+With this option
+.Nm
+will list all channels.
+.It Fl e
+Calculate channels not assuming extended channel mode.
+.It Fl d
+Enabling debugging in the HAL code that calculates the available channels
+and transmit power values.
+.It Fl l
+Provide a list of all known country and regulatory domain names.
+.It Fl m Ar mode
+Calculate channels and transmit power for operation in
+.Ql mode ;
+one of
+.Ql station ,
+.Ql ibss ,
+.Ql monitor ,
+and
+.Ql ap
+(or the first two letters).
+.It Fl p
+Mark passive scan channels with lower case letters and active
+scan channels with upper case letters.
+.It Fl r
+Mark channels that require DFS with a
+.Ql * .
+.It Fl 4
+Mark channels that have a 4ms packet limit with a
+.Ql 4 .
+.It Fl c
+Display IEEE channel numbers instead of frequencies.
+.It Fl f
+Display frequencies (default).
+.It Fl A
+Display only 11A channels.
+.It Fl B
+Display only 11B channels.
+.It Fl G
+Display only 11G channels.
+.It Fl T
+Display only Turbo channels.
+.El
+.Sh EXAMPLES
+The following demonstrates how to list the permissible frequencies
+and maximum transport power per channel for use in Spain:
+.Pp
+.nf
+tubby% athrd es
+\&
+SPAIN (ES, 0x2d4, 724) NULL1_WORLD (0x3, 3)
+2412G 14.0 2417G 14.0 2422G 14.0 2427G 17.0 2432G 14.0 2437G 17.0
+2442G 14.0 2447G 17.0 2452G 17.0 2457G 14.0 2462G 17.0
+.fi
+.Pp
+Each frequency has a suffix that is one of:
+.Ql G ,
+.Ql B ,
+.Ql A ,
+or
+.Ql T
+according to whether the channel is usable with 802.11g, 802.11b,
+802.11a, or Atheros Turbo mode.
+All channels listed as
+.Ql G
+are also usable in
+.Ql B .
+Likewise, all channels listed as
+.Ql A
+are usable in
+.Ql T .
+Channels listed as
+.Ql B
+or
+.Ql T
+are only usable in those modes.
+(Note that when the
+.Fl p
+option is specified passive scan channels are marked with a lower case
+.Ql g ,
+.Ql b ,
+.Ql a ,
+or
+.Ql t .)
+The transmit power is given in units of dbM.
+.Sh DIAGNOSTICS
+Various diagnostics about unknown regulatory domains and/or country
+codes may be encountered.
+Use the
+.Fl l
+option for a list of valid names.
+.Sh SEE ALSO
+.Xr ath 4 ,
+.Xr ath_hal 4
+.Sh STANDARDS
+Lots belong here.
+.Sh NOTES
+.Nm
+use the HAL to calculate the set of channels.
+The transmit power calculations are done by emulating
+how the HAL works.
+Because
+.Nm
+does not
+read the actual EEPROM contents from a device this emulation may lag
+behind current practice.
+.Sh BUGS
+The HAL reset logic should be used to calculate the transmit power
+for each channel instead of using a separate copy of the code.
+The data presented by
+.Nm
+are the expected values; for compliance testing one must measure the actual
+operation of the driver and the HAL.
diff --git a/tools/tools/ath/athrd/athrd.c b/tools/tools/ath/athrd/athrd.c
new file mode 100644
index 0000000..4cacddf
--- /dev/null
+++ b/tools/tools/ath/athrd/athrd.c
@@ -0,0 +1,1674 @@
+/*-
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * 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 NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+
+#include <net80211/_ieee80211.h>
+#include <net80211/ieee80211_regdomain.h>
+
+#include "ah_internal.h"
+#include "ah_eeprom_v3.h" /* XXX */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+int ath_hal_debug = 0;
+HAL_CTRY_CODE cc = CTRY_DEFAULT;
+HAL_REG_DOMAIN rd = 169; /* FCC */
+HAL_BOOL Amode = 1;
+HAL_BOOL Bmode = 1;
+HAL_BOOL Gmode = 1;
+HAL_BOOL HT20mode = 1;
+HAL_BOOL HT40mode = 1;
+HAL_BOOL turbo5Disable = AH_FALSE;
+HAL_BOOL turbo2Disable = AH_FALSE;
+
+u_int16_t _numCtls = 8;
+u_int16_t _ctl[32] =
+ { 0x10, 0x13, 0x40, 0x30, 0x11, 0x31, 0x12, 0x32 };
+RD_EDGES_POWER _rdEdgesPower[NUM_EDGES*NUM_CTLS] = {
+ { 5180, 28, 0 }, /* 0x10 */
+ { 5240, 60, 0 },
+ { 5260, 36, 0 },
+ { 5320, 27, 0 },
+ { 5745, 36, 0 },
+ { 5765, 36, 0 },
+ { 5805, 36, 0 },
+ { 5825, 36, 0 },
+
+ { 5210, 28, 0 }, /* 0x13 */
+ { 5250, 28, 0 },
+ { 5290, 30, 0 },
+ { 5760, 36, 0 },
+ { 5800, 36, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+
+ { 5170, 60, 0 }, /* 0x40 */
+ { 5230, 60, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+
+ { 5180, 33, 0 }, /* 0x30 */
+ { 5320, 33, 0 },
+ { 5500, 34, 0 },
+ { 5700, 34, 0 },
+ { 5745, 35, 0 },
+ { 5765, 35, 0 },
+ { 5785, 35, 0 },
+ { 5825, 35, 0 },
+
+ { 2412, 36, 0 }, /* 0x11 */
+ { 2417, 36, 0 },
+ { 2422, 36, 0 },
+ { 2432, 36, 0 },
+ { 2442, 36, 0 },
+ { 2457, 36, 0 },
+ { 2467, 36, 0 },
+ { 2472, 36, 0 },
+
+ { 2412, 36, 0 }, /* 0x31 */
+ { 2417, 36, 0 },
+ { 2422, 36, 0 },
+ { 2432, 36, 0 },
+ { 2442, 36, 0 },
+ { 2457, 36, 0 },
+ { 2467, 36, 0 },
+ { 2472, 36, 0 },
+
+ { 2412, 36, 0 }, /* 0x12 */
+ { 2417, 36, 0 },
+ { 2422, 36, 0 },
+ { 2432, 36, 0 },
+ { 2442, 36, 0 },
+ { 2457, 36, 0 },
+ { 2467, 36, 0 },
+ { 2472, 36, 0 },
+
+ { 2412, 28, 0 }, /* 0x32 */
+ { 2417, 28, 0 },
+ { 2422, 28, 0 },
+ { 2432, 28, 0 },
+ { 2442, 28, 0 },
+ { 2457, 28, 0 },
+ { 2467, 28, 0 },
+ { 2472, 28, 0 },
+};
+
+u_int16_t turbo2WMaxPower5 = 32;
+u_int16_t turbo2WMaxPower2;
+int8_t antennaGainMax[2] = { 0, 0 }; /* XXX */
+int eeversion = AR_EEPROM_VER3_1;
+TRGT_POWER_ALL_MODES tpow = {
+ 8, {
+ { 22, 24, 28, 32, 5180 },
+ { 22, 24, 28, 32, 5200 },
+ { 22, 24, 28, 32, 5320 },
+ { 26, 30, 34, 34, 5500 },
+ { 26, 30, 34, 34, 5700 },
+ { 20, 30, 34, 36, 5745 },
+ { 20, 30, 34, 36, 5825 },
+ { 20, 30, 34, 36, 5850 },
+ },
+ 2, {
+ { 23, 27, 31, 34, 2412 },
+ { 23, 27, 31, 34, 2447 },
+ },
+ 2, {
+ { 36, 36, 36, 36, 2412 },
+ { 36, 36, 36, 36, 2484 },
+ }
+};
+#define numTargetPwr_11a tpow.numTargetPwr_11a
+#define trgtPwr_11a tpow.trgtPwr_11a
+#define numTargetPwr_11g tpow.numTargetPwr_11g
+#define trgtPwr_11g tpow.trgtPwr_11g
+#define numTargetPwr_11b tpow.numTargetPwr_11b
+#define trgtPwr_11b tpow.trgtPwr_11b
+
+static HAL_BOOL
+getChannelEdges(struct ath_hal *ah, u_int16_t flags, u_int16_t *low, u_int16_t *high)
+{
+ struct ath_hal_private *ahp = AH_PRIVATE(ah);
+ HAL_CAPABILITIES *pCap = &ahp->ah_caps;
+
+ if (flags & IEEE80211_CHAN_5GHZ) {
+ *low = pCap->halLow5GhzChan;
+ *high = pCap->halHigh5GhzChan;
+ return AH_TRUE;
+ }
+ if (flags & IEEE80211_CHAN_2GHZ) {
+ *low = pCap->halLow2GhzChan;
+ *high = pCap->halHigh2GhzChan;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+}
+
+static u_int
+getWirelessModes(struct ath_hal *ah)
+{
+ u_int mode = 0;
+
+ if (Amode) {
+ mode = HAL_MODE_11A;
+ if (!turbo5Disable)
+ mode |= HAL_MODE_TURBO;
+ }
+ if (Bmode)
+ mode |= HAL_MODE_11B;
+ if (Gmode) {
+ mode |= HAL_MODE_11G;
+ if (!turbo2Disable)
+ mode |= HAL_MODE_108G;
+ }
+ if (HT20mode)
+ mode |= HAL_MODE_11NG_HT20|HAL_MODE_11NA_HT20;
+ if (HT40mode)
+ mode |= HAL_MODE_11NG_HT40PLUS|HAL_MODE_11NA_HT40PLUS
+ | HAL_MODE_11NG_HT40MINUS|HAL_MODE_11NA_HT40MINUS
+ ;
+ return mode;
+}
+
+/* Enumerated Regulatory Domain Information 8 bit values indicate that
+ * the regdomain is really a pair of unitary regdomains. 12 bit values
+ * are the real unitary regdomains and are the only ones which have the
+ * frequency bitmasks and flags set.
+ */
+
+enum EnumRd {
+ /*
+ * The following regulatory domain definitions are
+ * found in the EEPROM. Each regulatory domain
+ * can operate in either a 5GHz or 2.4GHz wireless mode or
+ * both 5GHz and 2.4GHz wireless modes.
+ * In general, the value holds no special
+ * meaning and is used to decode into either specific
+ * 2.4GHz or 5GHz wireless mode for that particular
+ * regulatory domain.
+ */
+ NO_ENUMRD = 0x00,
+ NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
+ NULL1_ETSIB = 0x07, /* Israel */
+ NULL1_ETSIC = 0x08,
+ FCC1_FCCA = 0x10, /* USA */
+ FCC1_WORLD = 0x11, /* Hong Kong */
+ FCC4_FCCA = 0x12, /* USA - Public Safety */
+
+ FCC2_FCCA = 0x20, /* Canada */
+ FCC2_WORLD = 0x21, /* Australia & HK */
+ FCC2_ETSIC = 0x22,
+ FRANCE_RES = 0x31, /* Legacy France for OEM */
+ FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
+ FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
+
+ ETSI1_WORLD = 0x37,
+ ETSI3_ETSIA = 0x32, /* France (optional) */
+ ETSI2_WORLD = 0x35, /* Hungary & others */
+ ETSI3_WORLD = 0x36, /* France & others */
+ ETSI4_WORLD = 0x30,
+ ETSI4_ETSIC = 0x38,
+ ETSI5_WORLD = 0x39,
+ ETSI6_WORLD = 0x34, /* Bulgaria */
+ ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
+
+ MKK1_MKKA = 0x40, /* Japan (JP1) */
+ MKK1_MKKB = 0x41, /* Japan (JP0) */
+ APL4_WORLD = 0x42, /* Singapore */
+ MKK2_MKKA = 0x43, /* Japan with 4.9G channels */
+ APL_RESERVED = 0x44, /* Reserved (Do not used) */
+ APL2_WORLD = 0x45, /* Korea */
+ APL2_APLC = 0x46,
+ APL3_WORLD = 0x47,
+ MKK1_FCCA = 0x48, /* Japan (JP1-1) */
+ APL2_APLD = 0x49, /* Korea with 2.3G channels */
+ MKK1_MKKA1 = 0x4A, /* Japan (JE1) */
+ MKK1_MKKA2 = 0x4B, /* Japan (JE2) */
+ MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */
+
+ APL3_FCCA = 0x50,
+ APL1_WORLD = 0x52, /* Latin America */
+ APL1_FCCA = 0x53,
+ APL1_APLA = 0x54,
+ APL1_ETSIC = 0x55,
+ APL2_ETSIC = 0x56, /* Venezuela */
+ APL5_WORLD = 0x58, /* Chile */
+ APL6_WORLD = 0x5B, /* Singapore */
+ APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
+ APL8_WORLD = 0x5D, /* Malaysia 5GHz */
+ APL9_WORLD = 0x5E, /* Korea 5GHz */
+
+ /*
+ * World mode SKUs
+ */
+ WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
+ WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
+ WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
+ WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
+ WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
+ WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
+
+ WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
+ WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
+ EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
+
+ WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
+ WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
+
+ MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */
+ MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */
+ MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */
+
+ MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */
+ MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */
+ MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */
+
+ MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
+ MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
+ MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
+
+ MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */
+ MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
+ MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */
+
+ MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
+ MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
+ MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
+
+ MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
+ MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
+ MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
+
+ /* Following definitions are used only by s/w to map old
+ * Japan SKUs.
+ */
+ MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */
+ MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */
+ MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */
+ MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */
+ MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */
+ MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */
+ MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */
+ MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */
+
+ /*
+ * Regulator domains ending in a number (e.g. APL1,
+ * MK1, ETSI4, etc) apply to 5GHz channel and power
+ * information. Regulator domains ending in a letter
+ * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
+ * power information.
+ */
+ APL1 = 0x0150, /* LAT & Asia */
+ APL2 = 0x0250, /* LAT & Asia */
+ APL3 = 0x0350, /* Taiwan */
+ APL4 = 0x0450, /* Jordan */
+ APL5 = 0x0550, /* Chile */
+ APL6 = 0x0650, /* Singapore */
+ APL8 = 0x0850, /* Malaysia */
+ APL9 = 0x0950, /* Korea (South) ROC 3 */
+
+ ETSI1 = 0x0130, /* Europe & others */
+ ETSI2 = 0x0230, /* Europe & others */
+ ETSI3 = 0x0330, /* Europe & others */
+ ETSI4 = 0x0430, /* Europe & others */
+ ETSI5 = 0x0530, /* Europe & others */
+ ETSI6 = 0x0630, /* Europe & others */
+ ETSIA = 0x0A30, /* France */
+ ETSIB = 0x0B30, /* Israel */
+ ETSIC = 0x0C30, /* Latin America */
+
+ FCC1 = 0x0110, /* US & others */
+ FCC2 = 0x0120, /* Canada, Australia & New Zealand */
+ FCC3 = 0x0160, /* US w/new middle band & DFS */
+ FCC4 = 0x0165, /* US Public Safety */
+ FCCA = 0x0A10,
+
+ APLD = 0x0D50, /* South Korea */
+
+ MKK1 = 0x0140, /* Japan (UNI-1 odd)*/
+ MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */
+ MKK3 = 0x0340, /* Japan (UNI-1 even) */
+ MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */
+ MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */
+ MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */
+ MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
+ MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
+ MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */
+ MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
+ MKKA = 0x0A40, /* Japan */
+ MKKC = 0x0A50,
+
+ NULL1 = 0x0198,
+ WORLD = 0x0199,
+ DEBUG_REG_DMN = 0x01ff,
+};
+#define DEF_REGDMN FCC1_FCCA
+
+static struct {
+ const char *name;
+ HAL_REG_DOMAIN rd;
+} domains[] = {
+#define D(_x) { #_x, _x }
+ D(NO_ENUMRD),
+ D(NULL1_WORLD), /* For 11b-only countries (no 11a allowed) */
+ D(NULL1_ETSIB), /* Israel */
+ D(NULL1_ETSIC),
+ D(FCC1_FCCA), /* USA */
+ D(FCC1_WORLD), /* Hong Kong */
+ D(FCC4_FCCA), /* USA - Public Safety */
+
+ D(FCC2_FCCA), /* Canada */
+ D(FCC2_WORLD), /* Australia & HK */
+ D(FCC2_ETSIC),
+ D(FRANCE_RES), /* Legacy France for OEM */
+ D(FCC3_FCCA),
+ D(FCC3_WORLD),
+
+ D(ETSI1_WORLD),
+ D(ETSI3_ETSIA), /* France (optional) */
+ D(ETSI2_WORLD), /* Hungary & others */
+ D(ETSI3_WORLD), /* France & others */
+ D(ETSI4_WORLD),
+ D(ETSI4_ETSIC),
+ D(ETSI5_WORLD),
+ D(ETSI6_WORLD), /* Bulgaria */
+ D(ETSI_RESERVED), /* Reserved (Do not used) */
+
+ D(MKK1_MKKA), /* Japan (JP1) */
+ D(MKK1_MKKB), /* Japan (JP0) */
+ D(APL4_WORLD), /* Singapore */
+ D(MKK2_MKKA), /* Japan with 4.9G channels */
+ D(APL_RESERVED), /* Reserved (Do not used) */
+ D(APL2_WORLD), /* Korea */
+ D(APL2_APLC),
+ D(APL3_WORLD),
+ D(MKK1_FCCA), /* Japan (JP1-1) */
+ D(APL2_APLD), /* Korea with 2.3G channels */
+ D(MKK1_MKKA1), /* Japan (JE1) */
+ D(MKK1_MKKA2), /* Japan (JE2) */
+ D(MKK1_MKKC),
+
+ D(APL3_FCCA),
+ D(APL1_WORLD), /* Latin America */
+ D(APL1_FCCA),
+ D(APL1_APLA),
+ D(APL1_ETSIC),
+ D(APL2_ETSIC), /* Venezuela */
+ D(APL5_WORLD), /* Chile */
+ D(APL6_WORLD), /* Singapore */
+ D(APL7_FCCA), /* Taiwan 5.47 Band */
+ D(APL8_WORLD), /* Malaysia 5GHz */
+ D(APL9_WORLD), /* Korea 5GHz */
+
+ D(WOR0_WORLD), /* World0 (WO0 SKU) */
+ D(WOR1_WORLD), /* World1 (WO1 SKU) */
+ D(WOR2_WORLD), /* World2 (WO2 SKU) */
+ D(WOR3_WORLD), /* World3 (WO3 SKU) */
+ D(WOR4_WORLD), /* World4 (WO4 SKU) */
+ D(WOR5_ETSIC), /* World5 (WO5 SKU) */
+
+ D(WOR01_WORLD), /* World0-1 (WW0-1 SKU) */
+ D(WOR02_WORLD), /* World0-2 (WW0-2 SKU) */
+ D(EU1_WORLD),
+
+ D(WOR9_WORLD), /* World9 (WO9 SKU) */
+ D(WORA_WORLD), /* WorldA (WOA SKU) */
+
+ D(MKK3_MKKB), /* Japan UNI-1 even + MKKB */
+ D(MKK3_MKKA2), /* Japan UNI-1 even + MKKA2 */
+ D(MKK3_MKKC), /* Japan UNI-1 even + MKKC */
+
+ D(MKK4_MKKB), /* Japan UNI-1 even + UNI-2 + MKKB */
+ D(MKK4_MKKA2), /* Japan UNI-1 even + UNI-2 + MKKA2 */
+ D(MKK4_MKKC), /* Japan UNI-1 even + UNI-2 + MKKC */
+
+ D(MKK5_MKKB), /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
+ D(MKK5_MKKA2), /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
+ D(MKK5_MKKC), /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
+
+ D(MKK6_MKKB), /* Japan UNI-1 even + UNI-1 odd MKKB */
+ D(MKK6_MKKA2), /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
+ D(MKK6_MKKC), /* Japan UNI-1 even + UNI-1 odd + MKKC */
+
+ D(MKK7_MKKB), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
+ D(MKK7_MKKA2), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
+ D(MKK7_MKKC), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
+
+ D(MKK8_MKKB), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
+ D(MKK8_MKKA2), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
+ D(MKK8_MKKC), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
+
+ D(MKK3_MKKA), /* Japan UNI-1 even + MKKA */
+ D(MKK3_MKKA1), /* Japan UNI-1 even + MKKA1 */
+ D(MKK3_FCCA), /* Japan UNI-1 even + FCCA */
+ D(MKK4_MKKA), /* Japan UNI-1 even + UNI-2 + MKKA */
+ D(MKK4_MKKA1), /* Japan UNI-1 even + UNI-2 + MKKA1 */
+ D(MKK4_FCCA), /* Japan UNI-1 even + UNI-2 + FCCA */
+ D(MKK9_MKKA), /* Japan UNI-1 even + 4.9GHz */
+ D(MKK10_MKKA), /* Japan UNI-1 even + UNI-2 + 4.9GHz */
+
+ D(APL1), /* LAT & Asia */
+ D(APL2), /* LAT & Asia */
+ D(APL3), /* Taiwan */
+ D(APL4), /* Jordan */
+ D(APL5), /* Chile */
+ D(APL6), /* Singapore */
+ D(APL8), /* Malaysia */
+ D(APL9), /* Korea (South) ROC 3 */
+
+ D(ETSI1), /* Europe & others */
+ D(ETSI2), /* Europe & others */
+ D(ETSI3), /* Europe & others */
+ D(ETSI4), /* Europe & others */
+ D(ETSI5), /* Europe & others */
+ D(ETSI6), /* Europe & others */
+ D(ETSIA), /* France */
+ D(ETSIB), /* Israel */
+ D(ETSIC), /* Latin America */
+
+ D(FCC1), /* US & others */
+ D(FCC2),
+ D(FCC3), /* US w/new middle band & DFS */
+ D(FCC4), /* US Public Safety */
+ D(FCCA),
+
+ D(APLD), /* South Korea */
+
+ D(MKK1), /* Japan (UNI-1 odd)*/
+ D(MKK2), /* Japan (4.9 GHz + UNI-1 odd) */
+ D(MKK3), /* Japan (UNI-1 even) */
+ D(MKK4), /* Japan (UNI-1 even + UNI-2) */
+ D(MKK5), /* Japan (UNI-1 even + UNI-2 + mid-band) */
+ D(MKK6), /* Japan (UNI-1 odd + UNI-1 even) */
+ D(MKK7), /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
+ D(MKK8), /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
+ D(MKK9), /* Japan (UNI-1 even + 4.9 GHZ) */
+ D(MKK10), /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
+ D(MKKA), /* Japan */
+ D(MKKC),
+
+ D(NULL1),
+ D(WORLD),
+ D(DEBUG_REG_DMN),
+#undef D
+};
+
+static HAL_BOOL
+rdlookup(const char *name, HAL_REG_DOMAIN *rd)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(domains); i++)
+ if (strcasecmp(domains[i].name, name) == 0) {
+ *rd = domains[i].rd;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+#undef N
+}
+
+static const char *
+getrdname(HAL_REG_DOMAIN rd)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(domains); i++)
+ if (domains[i].rd == rd)
+ return domains[i].name;
+ return NULL;
+#undef N
+}
+
+static void
+rdlist()
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ printf("\nRegulatory domains:\n\n");
+ for (i = 0; i < N(domains); i++)
+ printf("%-15s%s", domains[i].name,
+ ((i+1)%5) == 0 ? "\n" : "");
+ printf("\n");
+#undef N
+}
+
+typedef struct {
+ HAL_CTRY_CODE countryCode;
+ HAL_REG_DOMAIN regDmnEnum;
+ const char* isoName;
+ const char* name;
+} COUNTRY_CODE_TO_ENUM_RD;
+
+/*
+ * Country Code Table to Enumerated RD
+ */
+static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
+ {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG" },
+ {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET" },
+ {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA" },
+ {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA" },
+ {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA" },
+ {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA" },
+ {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA" },
+ {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA" },
+ {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN" },
+ {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN" },
+ {CTRY_BELARUS, NULL1_WORLD, "BY", "BELARUS" },
+ {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM" },
+ {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE" },
+ {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA" },
+ {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL" },
+ {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD,"BN", "BRUNEI DARUSSALAM" },
+ {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA" },
+ {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA" },
+ {CTRY_CHILE, APL6_WORLD, "CL", "CHILE" },
+ {CTRY_CHINA, APL1_WORLD, "CN", "CHINA" },
+ {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA" },
+ {CTRY_COSTA_RICA, NULL1_WORLD, "CR", "COSTA RICA" },
+ {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA" },
+ {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS" },
+ {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC" },
+ {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK" },
+ {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA,"DO", "DOMINICAN REPUBLIC" },
+ {CTRY_ECUADOR, NULL1_WORLD, "EC", "ECUADOR" },
+ {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT" },
+ {CTRY_EL_SALVADOR, NULL1_WORLD, "SV", "EL SALVADOR" },
+ {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA" },
+ {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND" },
+ {CTRY_FRANCE, ETSI3_WORLD, "FR", "FRANCE" },
+ {CTRY_FRANCE2, ETSI3_WORLD, "F2", "FRANCE_RES" },
+ {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA" },
+ {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY" },
+ {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE" },
+ {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA" },
+ {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS" },
+ {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG" },
+ {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY" },
+ {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND" },
+ {CTRY_INDIA, APL6_WORLD, "IN", "INDIA" },
+ {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA" },
+ {CTRY_IRAN, APL1_WORLD, "IR", "IRAN" },
+ {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND" },
+ {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL" },
+ {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY" },
+ {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN" },
+ {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1" },
+ {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2" },
+ {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3" },
+ {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4" },
+ {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5" },
+ {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6" },
+
+ {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7" },
+ {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8" },
+ {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9" },
+
+ {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10" },
+ {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11" },
+ {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12" },
+
+ {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13" },
+ {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14" },
+ {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15" },
+
+ {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16" },
+ {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17" },
+ {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18" },
+
+ {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19" },
+ {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20" },
+ {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21" },
+
+ {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22" },
+ {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23" },
+ {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24" },
+
+ {CTRY_JORDAN, APL4_WORLD, "JO", "JORDAN" },
+ {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN" },
+ {CTRY_KOREA_NORTH, APL2_WORLD, "KP", "NORTH KOREA" },
+ {CTRY_KOREA_ROC, APL2_WORLD, "KR", "KOREA REPUBLIC" },
+ {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2" },
+ {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3" },
+ {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT" },
+ {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA" },
+ {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON" },
+ {CTRY_LIECHTENSTEIN,ETSI1_WORLD, "LI", "LIECHTENSTEIN" },
+ {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA" },
+ {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG" },
+ {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU" },
+ {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA" },
+ {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA" },
+ {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA" },
+ {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO" },
+ {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO" },
+ {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO" },
+ {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS" },
+ {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND" },
+ {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY" },
+ {CTRY_OMAN, APL6_WORLD, "OM", "OMAN" },
+ {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN" },
+ {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA" },
+ {CTRY_PERU, APL1_WORLD, "PE", "PERU" },
+ {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES" },
+ {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND" },
+ {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL" },
+ {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO" },
+ {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR" },
+ {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA" },
+ {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA" },
+ {CTRY_SAUDI_ARABIA,NULL1_WORLD, "SA", "SAUDI ARABIA" },
+ {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE" },
+ {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC" },
+ {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA" },
+ {CTRY_SOUTH_AFRICA,FCC3_WORLD, "ZA", "SOUTH AFRICA" },
+ {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN" },
+ {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN" },
+ {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND" },
+ {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA" },
+ {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN" },
+ {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND" },
+ {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,"TT", "TRINIDAD & TOBAGO" },
+ {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA" },
+ {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY" },
+ {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE" },
+ {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES" },
+ {CTRY_UNITED_KINGDOM, ETSI1_WORLD,"GB", "UNITED KINGDOM" },
+ {CTRY_UNITED_STATES, FCC1_FCCA, "US", "UNITED STATES" },
+ {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)" },
+ {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY" },
+ {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN" },
+ {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA" },
+ {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM" },
+ {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN" },
+ {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE" }
+};
+
+static HAL_BOOL
+cclookup(const char *name, HAL_REG_DOMAIN *rd, HAL_CTRY_CODE *cc)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(allCountries); i++)
+ if (strcasecmp(allCountries[i].isoName, name) == 0 ||
+ strcasecmp(allCountries[i].name, name) == 0) {
+ *rd = allCountries[i].regDmnEnum;
+ *cc = allCountries[i].countryCode;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+#undef N
+}
+
+static const char *
+getccname(HAL_CTRY_CODE cc)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(allCountries); i++)
+ if (allCountries[i].countryCode == cc)
+ return allCountries[i].name;
+ return NULL;
+#undef N
+}
+
+static const char *
+getccisoname(HAL_CTRY_CODE cc)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(allCountries); i++)
+ if (allCountries[i].countryCode == cc)
+ return allCountries[i].isoName;
+ return NULL;
+#undef N
+}
+
+static void
+cclist()
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ printf("\nCountry codes:\n");
+ for (i = 0; i < N(allCountries); i++)
+ printf("%2s %-15.15s%s",
+ allCountries[i].isoName,
+ allCountries[i].name,
+ ((i+1)%4) == 0 ? "\n" : " ");
+ printf("\n");
+#undef N
+}
+
+static HAL_BOOL
+setRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ int16_t tpcScaleReduction, int16_t powerLimit,
+ int16_t *pMinPower, int16_t *pMaxPower);
+
+static void
+calctxpower(struct ath_hal *ah,
+ int nchan, const struct ieee80211_channel *chans,
+ int16_t tpcScaleReduction, int16_t powerLimit, int16_t *txpow)
+{
+ int16_t minpow;
+ int i;
+
+ for (i = 0; i < nchan; i++)
+ if (!setRateTable(ah, &chans[i],
+ tpcScaleReduction, powerLimit, &minpow, &txpow[i])) {
+ printf("unable to set rate table\n");
+ exit(-1);
+ }
+}
+
+int n = 1;
+const char *sep = "";
+int dopassive = 0;
+int showchannels = 0;
+int isdfs = 0;
+int is4ms = 0;
+
+static int
+anychan(const struct ieee80211_channel *chans, int nc, int flag)
+{
+ int i;
+
+ for (i = 0; i < nc; i++)
+ if ((chans[i].ic_flags & flag) != 0)
+ return 1;
+ return 0;
+}
+
+static __inline int
+mapgsm(u_int freq, u_int flags)
+{
+ freq *= 10;
+ if (flags & IEEE80211_CHAN_QUARTER)
+ freq += 5;
+ else if (flags & IEEE80211_CHAN_HALF)
+ freq += 10;
+ else
+ freq += 20;
+ return (freq - 24220) / 5;
+}
+
+static __inline int
+mappsb(u_int freq, u_int flags)
+{
+ return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
+}
+
+/*
+ * Convert GHz frequency to IEEE channel number.
+ */
+int
+ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
+{
+ if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */
+ if (freq == 2484)
+ return 14;
+ if (freq < 2484)
+ return ((int)freq - 2407) / 5;
+ else
+ return 15 + ((freq - 2512) / 20);
+ } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
+ if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq))
+ return mappsb(freq, flags);
+ else if ((flags & IEEE80211_CHAN_A) && (freq <= 5000))
+ return (freq - 4000) / 5;
+ else
+ return (freq - 5000) / 5;
+ } else { /* either, guess */
+ if (freq == 2484)
+ return 14;
+ if (freq < 2484)
+ return ((int)freq - 2407) / 5;
+ if (freq < 5000) {
+ if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq))
+ return mappsb(freq, flags);
+ else if (freq > 4900)
+ return (freq - 4000) / 5;
+ else
+ return 15 + ((freq - 2512) / 20);
+ }
+ return (freq - 5000) / 5;
+ }
+}
+
+#define IEEE80211_IS_CHAN_4MS(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_4MSXMIT) != 0)
+
+static void
+dumpchannels(struct ath_hal *ah, int nc,
+ const struct ieee80211_channel *chans, int16_t *txpow)
+{
+ int i;
+
+ for (i = 0; i < nc; i++) {
+ const struct ieee80211_channel *c = &chans[i];
+ int type;
+
+ if (showchannels)
+ printf("%s%3d", sep,
+ ath_hal_mhz2ieee(ah, c->ic_freq, c->ic_flags));
+ else
+ printf("%s%u", sep, c->ic_freq);
+ if (IEEE80211_IS_CHAN_HALF(c))
+ type = 'H';
+ else if (IEEE80211_IS_CHAN_QUARTER(c))
+ type = 'Q';
+ else if (IEEE80211_IS_CHAN_TURBO(c))
+ type = 'T';
+ else if (IEEE80211_IS_CHAN_HT(c))
+ type = 'N';
+ else if (IEEE80211_IS_CHAN_A(c))
+ type = 'A';
+ else if (IEEE80211_IS_CHAN_108G(c))
+ type = 'T';
+ else if (IEEE80211_IS_CHAN_G(c))
+ type = 'G';
+ else
+ type = 'B';
+ if (dopassive && IEEE80211_IS_CHAN_PASSIVE(c))
+ type = tolower(type);
+ if (isdfs && is4ms)
+ printf("%c%c%c %d.%d", type,
+ IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ',
+ IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ',
+ txpow[i]/2, (txpow[i]%2)*5);
+ else if (isdfs)
+ printf("%c%c %d.%d", type,
+ IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ',
+ txpow[i]/2, (txpow[i]%2)*5);
+ else if (is4ms)
+ printf("%c%c %d.%d", type,
+ IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ',
+ txpow[i]/2, (txpow[i]%2)*5);
+ else
+ printf("%c %d.%d", type, txpow[i]/2, (txpow[i]%2)*5);
+ if ((n++ % (showchannels ? 7 : 6)) == 0)
+ sep = "\n";
+ else
+ sep = " ";
+ }
+}
+
+static void
+intersect(struct ieee80211_channel *dst, int16_t *dtxpow, int *nd,
+ const struct ieee80211_channel *src, int16_t *stxpow, int ns)
+{
+ int i = 0, j, k, l;
+ while (i < *nd) {
+ for (j = 0; j < ns && dst[i].ic_freq != src[j].ic_freq; j++)
+ ;
+ if (j < ns && dtxpow[i] == stxpow[j]) {
+ for (k = i+1, l = i; k < *nd; k++, l++)
+ dst[l] = dst[k];
+ (*nd)--;
+ } else
+ i++;
+ }
+}
+
+static void
+usage(const char *progname)
+{
+ printf("usage: %s [-acdefoilpr4ABGT] [-m opmode] [cc | rd]\n", progname);
+ exit(-1);
+}
+
+static HAL_BOOL
+getChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
+{
+}
+
+static HAL_BOOL
+eepromRead(struct ath_hal *ah, u_int off, u_int16_t *data)
+{
+ /* emulate enough stuff to handle japan channel shift */
+ switch (off) {
+ case AR_EEPROM_VERSION:
+ *data = eeversion;
+ return AH_TRUE;
+ case AR_EEPROM_REG_CAPABILITIES_OFFSET:
+ *data = AR_EEPROM_EEREGCAP_EN_KK_NEW_11A;
+ return AH_TRUE;
+ case AR_EEPROM_REG_CAPABILITIES_OFFSET_PRE4_0:
+ *data = AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+}
+
+HAL_STATUS
+getCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
+ uint32_t capability, uint32_t *result)
+{
+ const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
+
+ switch (type) {
+ case HAL_CAP_REG_DMN: /* regulatory domain */
+ *result = AH_PRIVATE(ah)->ah_currentRD;
+ return HAL_OK;
+ default:
+ return HAL_EINVAL;
+ }
+}
+
+#define HAL_MODE_HT20 \
+ (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
+#define HAL_MODE_HT40 \
+ (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \
+ HAL_MODE_11NA_HT40PLUS | HAL_MODE_11NA_HT40MINUS)
+#define HAL_MODE_HT (HAL_MODE_HT20 | HAL_MODE_HT40)
+
+int
+main(int argc, char *argv[])
+{
+ static const u_int16_t tpcScaleReductionTable[5] =
+ { 0, 3, 6, 9, MAX_RATE_POWER };
+ struct ath_hal_private ahp;
+ struct ieee80211_channel achans[IEEE80211_CHAN_MAX];
+ int16_t atxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel bchans[IEEE80211_CHAN_MAX];
+ int16_t btxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel gchans[IEEE80211_CHAN_MAX];
+ int16_t gtxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel tchans[IEEE80211_CHAN_MAX];
+ int16_t ttxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel tgchans[IEEE80211_CHAN_MAX];
+ int16_t tgtxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel nchans[IEEE80211_CHAN_MAX];
+ int16_t ntxpow[IEEE80211_CHAN_MAX];
+ int i, na, nb, ng, nt, ntg, nn;
+ HAL_BOOL showall = AH_FALSE;
+ HAL_BOOL extendedChanMode = AH_TRUE;
+ int modes = 0;
+ int16_t tpcReduction, powerLimit;
+ int showdfs = 0;
+ int show4ms = 0;
+
+ memset(&ahp, 0, sizeof(ahp));
+ ahp.ah_getChannelEdges = getChannelEdges;
+ ahp.ah_getWirelessModes = getWirelessModes;
+ ahp.ah_eepromRead = eepromRead;
+ ahp.ah_getChipPowerLimits = getChipPowerLimits;
+ ahp.ah_caps.halWirelessModes = HAL_MODE_ALL;
+ ahp.ah_caps.halLow5GhzChan = 4920;
+ ahp.ah_caps.halHigh5GhzChan = 6100;
+ ahp.ah_caps.halLow2GhzChan = 2312;
+ ahp.ah_caps.halHigh2GhzChan = 2732;
+ ahp.ah_caps.halChanHalfRate = AH_TRUE;
+ ahp.ah_caps.halChanQuarterRate = AH_TRUE;
+ ahp.h.ah_getCapability = getCapability;
+ ahp.ah_opmode = HAL_M_STA;
+
+ tpcReduction = tpcScaleReductionTable[0];
+ powerLimit = MAX_RATE_POWER;
+
+ while ((i = getopt(argc, argv, "acdeflm:pr4ABGhHNT")) != -1)
+ switch (i) {
+ case 'a':
+ showall = AH_TRUE;
+ break;
+ case 'c':
+ showchannels = AH_TRUE;
+ break;
+ case 'd':
+ ath_hal_debug = HAL_DEBUG_ANY;
+ break;
+ case 'e':
+ extendedChanMode = AH_FALSE;
+ break;
+ case 'f':
+ showchannels = AH_FALSE;
+ break;
+ case 'l':
+ cclist();
+ rdlist();
+ exit(0);
+ case 'm':
+ if (strncasecmp(optarg, "sta", 2) == 0)
+ ahp.ah_opmode = HAL_M_STA;
+ else if (strncasecmp(optarg, "ibss", 2) == 0)
+ ahp.ah_opmode = HAL_M_IBSS;
+ else if (strncasecmp(optarg, "adhoc", 2) == 0)
+ ahp.ah_opmode = HAL_M_IBSS;
+ else if (strncasecmp(optarg, "ap", 2) == 0)
+ ahp.ah_opmode = HAL_M_HOSTAP;
+ else if (strncasecmp(optarg, "hostap", 2) == 0)
+ ahp.ah_opmode = HAL_M_HOSTAP;
+ else if (strncasecmp(optarg, "monitor", 2) == 0)
+ ahp.ah_opmode = HAL_M_MONITOR;
+ else
+ usage(argv[0]);
+ break;
+ case 'p':
+ dopassive = 1;
+ break;
+ case 'A':
+ modes |= HAL_MODE_11A;
+ break;
+ case 'B':
+ modes |= HAL_MODE_11B;
+ break;
+ case 'G':
+ modes |= HAL_MODE_11G;
+ break;
+ case 'h':
+ modes |= HAL_MODE_HT20;
+ break;
+ case 'H':
+ modes |= HAL_MODE_HT40;
+ break;
+ case 'N':
+ modes |= HAL_MODE_HT;
+ break;
+ case 'T':
+ modes |= HAL_MODE_TURBO | HAL_MODE_108G;
+ break;
+ case 'r':
+ showdfs = 1;
+ break;
+ case '4':
+ show4ms = 1;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ switch (argc - optind) {
+ case 0:
+ if (!cclookup("US", &rd, &cc)) {
+ printf("%s: unknown country code\n", "US");
+ exit(-1);
+ }
+ break;
+ case 1: /* cc/regdomain */
+ if (!cclookup(argv[optind], &rd, &cc)) {
+ if (!rdlookup(argv[optind], &rd)) {
+ const char* rdname;
+
+ rd = strtoul(argv[optind], NULL, 0);
+ rdname = getrdname(rd);
+ if (rdname == NULL) {
+ printf("%s: unknown country/regulatory "
+ "domain code\n", argv[optind]);
+ exit(-1);
+ }
+ }
+ cc = CTRY_DEFAULT;
+ }
+ break;
+ default: /* regdomain cc */
+ if (!rdlookup(argv[optind], &rd)) {
+ const char* rdname;
+
+ rd = strtoul(argv[optind], NULL, 0);
+ rdname = getrdname(rd);
+ if (rdname == NULL) {
+ printf("%s: unknown country/regulatory "
+ "domain code\n", argv[optind]);
+ exit(-1);
+ }
+ }
+ if (!cclookup(argv[optind+1], &rd, &cc))
+ cc = strtoul(argv[optind+1], NULL, 0);
+ break;
+ }
+ if (cc != CTRY_DEFAULT)
+ printf("\n%s (%s, 0x%x, %u) %s (0x%x, %u)\n",
+ getccname(cc), getccisoname(cc), cc, cc,
+ getrdname(rd), rd, rd);
+ else
+ printf("\n%s (0x%x, %u)\n",
+ getrdname(rd), rd, rd);
+
+ if (modes == 0) {
+ /* NB: no HAL_MODE_HT */
+ modes = HAL_MODE_11A | HAL_MODE_11B |
+ HAL_MODE_11G | HAL_MODE_TURBO | HAL_MODE_108G;
+ }
+ na = nb = ng = nt = ntg = nn = 0;
+ if (modes & HAL_MODE_11G) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, gchans, IEEE80211_CHAN_MAX, &ng,
+ HAL_MODE_11G, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, ng, gchans, tpcReduction, powerLimit, gtxpow);
+ if (showdfs)
+ isdfs |= anychan(gchans, ng, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(gchans, ng, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_11B) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, bchans, IEEE80211_CHAN_MAX, &nb,
+ HAL_MODE_11B, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, nb, bchans, tpcReduction, powerLimit, btxpow);
+ if (showdfs)
+ isdfs |= anychan(bchans, nb, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(bchans, nb, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_11A) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, achans, IEEE80211_CHAN_MAX, &na,
+ HAL_MODE_11A, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, na, achans, tpcReduction, powerLimit, atxpow);
+ if (showdfs)
+ isdfs |= anychan(achans, na, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(achans, na, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_TURBO) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, tchans, IEEE80211_CHAN_MAX, &nt,
+ HAL_MODE_TURBO, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, nt, tchans, tpcReduction, powerLimit, ttxpow);
+ if (showdfs)
+ isdfs |= anychan(tchans, nt, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(tchans, nt, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_108G) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, tgchans, IEEE80211_CHAN_MAX, &ntg,
+ HAL_MODE_108G, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, ntg, tgchans, tpcReduction, powerLimit, tgtxpow);
+ if (showdfs)
+ isdfs |= anychan(tgchans, ntg, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(tgchans, ntg, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_HT) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, nchans, IEEE80211_CHAN_MAX, &nn,
+ modes & HAL_MODE_HT, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, nn, nchans, tpcReduction, powerLimit, ntxpow);
+ if (showdfs)
+ isdfs |= anychan(nchans, nn, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(nchans, nn, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+
+ if (!showall) {
+#define CHECKMODES(_modes, _m) ((_modes & (_m)) == (_m))
+ if (CHECKMODES(modes, HAL_MODE_11B|HAL_MODE_11G)) {
+ /* b ^= g */
+ intersect(bchans, btxpow, &nb, gchans, gtxpow, ng);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_TURBO)) {
+ /* t ^= a */
+ intersect(tchans, ttxpow, &nt, achans, atxpow, na);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_108G)) {
+ /* tg ^= g */
+ intersect(tgchans, tgtxpow, &ntg, gchans, gtxpow, ng);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_HT)) {
+ /* g ^= n */
+ intersect(gchans, gtxpow, &ng, nchans, ntxpow, nn);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_HT)) {
+ /* a ^= n */
+ intersect(achans, atxpow, &na, nchans, ntxpow, nn);
+ }
+#undef CHECKMODES
+ }
+
+ if (modes & HAL_MODE_11G)
+ dumpchannels(&ahp.h, ng, gchans, gtxpow);
+ if (modes & HAL_MODE_11B)
+ dumpchannels(&ahp.h, nb, bchans, btxpow);
+ if (modes & HAL_MODE_11A)
+ dumpchannels(&ahp.h, na, achans, atxpow);
+ if (modes & HAL_MODE_108G)
+ dumpchannels(&ahp.h, ntg, tgchans, tgtxpow);
+ if (modes & HAL_MODE_TURBO)
+ dumpchannels(&ahp.h, nt, tchans, ttxpow);
+ if (modes & HAL_MODE_HT)
+ dumpchannels(&ahp.h, nn, nchans, ntxpow);
+ printf("\n");
+ return (0);
+}
+
+/*
+ * Search a list for a specified value v that is within
+ * EEP_DELTA of the search values. Return the closest
+ * values in the list above and below the desired value.
+ * EEP_DELTA is a factional value; everything is scaled
+ * so only integer arithmetic is used.
+ *
+ * NB: the input list is assumed to be sorted in ascending order
+ */
+static void
+ar5212GetLowerUpperValues(u_int16_t v, u_int16_t *lp, u_int16_t listSize,
+ u_int16_t *vlo, u_int16_t *vhi)
+{
+ u_int32_t target = v * EEP_SCALE;
+ u_int16_t *ep = lp+listSize;
+
+ /*
+ * Check first and last elements for out-of-bounds conditions.
+ */
+ if (target < (u_int32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) {
+ *vlo = *vhi = lp[0];
+ return;
+ }
+ if (target > (u_int32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) {
+ *vlo = *vhi = ep[-1];
+ return;
+ }
+
+ /* look for value being near or between 2 values in list */
+ for (; lp < ep; lp++) {
+ /*
+ * If value is close to the current value of the list
+ * then target is not between values, it is one of the values
+ */
+ if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {
+ *vlo = *vhi = lp[0];
+ return;
+ }
+ /*
+ * Look for value being between current value and next value
+ * if so return these 2 values
+ */
+ if (target < (u_int32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) {
+ *vlo = lp[0];
+ *vhi = lp[1];
+ return;
+ }
+ }
+}
+
+/*
+ * Find the maximum conformance test limit for the given channel and CTL info
+ */
+static u_int16_t
+ar5212GetMaxEdgePower(u_int16_t channel, RD_EDGES_POWER *pRdEdgesPower)
+{
+ /* temp array for holding edge channels */
+ u_int16_t tempChannelList[NUM_EDGES];
+ u_int16_t clo, chi, twiceMaxEdgePower;
+ int i, numEdges;
+
+ /* Get the edge power */
+ for (i = 0; i < NUM_EDGES; i++) {
+ if (pRdEdgesPower[i].rdEdge == 0)
+ break;
+ tempChannelList[i] = pRdEdgesPower[i].rdEdge;
+ }
+ numEdges = i;
+
+ ar5212GetLowerUpperValues(channel, tempChannelList,
+ numEdges, &clo, &chi);
+ /* Get the index for the lower channel */
+ for (i = 0; i < numEdges && clo != tempChannelList[i]; i++)
+ ;
+ /* Is lower channel ever outside the rdEdge? */
+ HALASSERT(i != numEdges);
+
+ if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) {
+ /*
+ * If there's an exact channel match or an inband flag set
+ * on the lower channel use the given rdEdgePower
+ */
+ twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
+ HALASSERT(twiceMaxEdgePower > 0);
+ } else
+ twiceMaxEdgePower = MAX_RATE_POWER;
+ return twiceMaxEdgePower;
+}
+
+/*
+ * Returns interpolated or the scaled up interpolated value
+ */
+static u_int16_t
+interpolate(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight,
+ u_int16_t targetLeft, u_int16_t targetRight)
+{
+ u_int16_t rv;
+ int16_t lRatio;
+
+ /* to get an accurate ratio, always scale, if want to scale, then don't scale back down */
+ if ((targetLeft * targetRight) == 0)
+ return 0;
+
+ if (srcRight != srcLeft) {
+ /*
+ * Note the ratio always need to be scaled,
+ * since it will be a fraction.
+ */
+ lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft);
+ if (lRatio < 0) {
+ /* Return as Left target if value would be negative */
+ rv = targetLeft;
+ } else if (lRatio > EEP_SCALE) {
+ /* Return as Right target if Ratio is greater than 100% (SCALE) */
+ rv = targetRight;
+ } else {
+ rv = (lRatio * targetRight + (EEP_SCALE - lRatio) *
+ targetLeft) / EEP_SCALE;
+ }
+ } else {
+ rv = targetLeft;
+ }
+ return rv;
+}
+
+/*
+ * Return the four rates of target power for the given target power table
+ * channel, and number of channels
+ */
+static void
+ar5212GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ TRGT_POWER_INFO *powInfo,
+ u_int16_t numChannels, TRGT_POWER_INFO *pNewPower)
+{
+ /* temp array for holding target power channels */
+ u_int16_t tempChannelList[NUM_TEST_FREQUENCIES];
+ u_int16_t clo, chi, ixlo, ixhi;
+ int i;
+
+ /* Copy the target powers into the temp channel list */
+ for (i = 0; i < numChannels; i++)
+ tempChannelList[i] = powInfo[i].testChannel;
+
+ ar5212GetLowerUpperValues(chan->ic_freq, tempChannelList,
+ numChannels, &clo, &chi);
+
+ /* Get the indices for the channel */
+ ixlo = ixhi = 0;
+ for (i = 0; i < numChannels; i++) {
+ if (clo == tempChannelList[i]) {
+ ixlo = i;
+ }
+ if (chi == tempChannelList[i]) {
+ ixhi = i;
+ break;
+ }
+ }
+
+ /*
+ * Get the lower and upper channels, target powers,
+ * and interpolate between them.
+ */
+ pNewPower->twicePwr6_24 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);
+ pNewPower->twicePwr36 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);
+ pNewPower->twicePwr48 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);
+ pNewPower->twicePwr54 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);
+}
+
+static RD_EDGES_POWER*
+findEdgePower(struct ath_hal *ah, u_int ctl)
+{
+ int i;
+
+ for (i = 0; i < _numCtls; i++)
+ if (_ctl[i] == ctl)
+ return &_rdEdgesPower[i * NUM_EDGES];
+ return AH_NULL;
+}
+
+/*
+ * Sets the transmit power in the baseband for the given
+ * operating channel and mode.
+ */
+static HAL_BOOL
+setRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ int16_t tpcScaleReduction, int16_t powerLimit,
+ int16_t *pMinPower, int16_t *pMaxPower)
+{
+ u_int16_t ratesArray[16];
+ u_int16_t *rpow = ratesArray;
+ u_int16_t twiceMaxRDPower, twiceMaxEdgePower, twiceMaxEdgePowerCck;
+ int8_t twiceAntennaGain, twiceAntennaReduction;
+ TRGT_POWER_INFO targetPowerOfdm, targetPowerCck;
+ RD_EDGES_POWER *rep;
+ int16_t scaledPower;
+ u_int8_t cfgCtl;
+
+ twiceMaxRDPower = chan->ic_maxregpower * 2;
+ *pMaxPower = -MAX_RATE_POWER;
+ *pMinPower = MAX_RATE_POWER;
+
+ /* Get conformance test limit maximum for this channel */
+ cfgCtl = ath_hal_getctl(ah, chan);
+ rep = findEdgePower(ah, cfgCtl);
+ if (rep != AH_NULL)
+ twiceMaxEdgePower = ar5212GetMaxEdgePower(chan->ic_freq, rep);
+ else
+ twiceMaxEdgePower = MAX_RATE_POWER;
+
+ if (IEEE80211_IS_CHAN_G(chan)) {
+ /* Check for a CCK CTL for 11G CCK powers */
+ cfgCtl = (cfgCtl & 0xFC) | 0x01;
+ rep = findEdgePower(ah, cfgCtl);
+ if (rep != AH_NULL)
+ twiceMaxEdgePowerCck = ar5212GetMaxEdgePower(chan->ic_freq, rep);
+ else
+ twiceMaxEdgePowerCck = MAX_RATE_POWER;
+ } else {
+ /* Set the 11B cck edge power to the one found before */
+ twiceMaxEdgePowerCck = twiceMaxEdgePower;
+ }
+
+ /* Get Antenna Gain reduction */
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
+ twiceAntennaGain = antennaGainMax[0];
+ } else {
+ twiceAntennaGain = antennaGainMax[1];
+ }
+ twiceAntennaReduction =
+ ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
+
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
+ /* Get final OFDM target powers */
+ if (IEEE80211_IS_CHAN_G(chan)) {
+ /* TODO - add Turbo 2.4 to this mode check */
+ ar5212GetTargetPowers(ah, chan, trgtPwr_11g,
+ numTargetPwr_11g, &targetPowerOfdm);
+ } else {
+ ar5212GetTargetPowers(ah, chan, trgtPwr_11a,
+ numTargetPwr_11a, &targetPowerOfdm);
+ }
+
+ /* Get Maximum OFDM power */
+ /* Minimum of target and edge powers */
+ scaledPower = AH_MIN(twiceMaxEdgePower,
+ twiceMaxRDPower - twiceAntennaReduction);
+
+ /*
+ * If turbo is set, reduce power to keep power
+ * consumption under 2 Watts. Note that we always do
+ * this unless specially configured. Then we limit
+ * power only for non-AP operation.
+ */
+ if (IEEE80211_IS_CHAN_TURBO(chan)
+#ifdef AH_ENABLE_AP_SUPPORT
+ && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
+#endif
+ ) {
+ /*
+ * If turbo is set, reduce power to keep power
+ * consumption under 2 Watts
+ */
+ if (eeversion >= AR_EEPROM_VER3_1)
+ scaledPower = AH_MIN(scaledPower,
+ turbo2WMaxPower5);
+ /*
+ * EEPROM version 4.0 added an additional
+ * constraint on 2.4GHz channels.
+ */
+ if (eeversion >= AR_EEPROM_VER4_0 &&
+ IEEE80211_IS_CHAN_2GHZ(chan))
+ scaledPower = AH_MIN(scaledPower,
+ turbo2WMaxPower2);
+ }
+ /* Reduce power by max regulatory domain allowed restrictions */
+ scaledPower -= (tpcScaleReduction * 2);
+ scaledPower = (scaledPower < 0) ? 0 : scaledPower;
+ scaledPower = AH_MIN(scaledPower, powerLimit);
+
+ scaledPower = AH_MIN(scaledPower, targetPowerOfdm.twicePwr6_24);
+
+ /* Set OFDM rates 9, 12, 18, 24, 36, 48, 54, XR */
+ rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower;
+ rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36);
+ rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48);
+ rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54);
+
+#ifdef notyet
+ if (eeversion >= AR_EEPROM_VER4_0) {
+ /* Setup XR target power from EEPROM */
+ rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ?
+ xrTargetPower2 : xrTargetPower5);
+ } else {
+ /* XR uses 6mb power */
+ rpow[15] = rpow[0];
+ }
+#else
+ rpow[15] = rpow[0];
+#endif
+
+ *pMinPower = rpow[7];
+ *pMaxPower = rpow[0];
+
+#if 0
+ ahp->ah_ofdmTxPower = rpow[0];
+#endif
+
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: MaxRD: %d TurboMax: %d MaxCTL: %d "
+ "TPC_Reduction %d\n", __func__,
+ twiceMaxRDPower, turbo2WMaxPower5,
+ twiceMaxEdgePower, tpcScaleReduction * 2);
+ }
+
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
+ /* Get final CCK target powers */
+ ar5212GetTargetPowers(ah, chan, trgtPwr_11b,
+ numTargetPwr_11b, &targetPowerCck);
+
+ /* Reduce power by max regulatory domain allowed restrictions */
+ scaledPower = AH_MIN(twiceMaxEdgePowerCck,
+ twiceMaxRDPower - twiceAntennaReduction);
+
+ scaledPower -= (tpcScaleReduction * 2);
+ scaledPower = (scaledPower < 0) ? 0 : scaledPower;
+ scaledPower = AH_MIN(scaledPower, powerLimit);
+
+ rpow[8] = (scaledPower < 1) ? 1 : scaledPower;
+
+ /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */
+ rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
+ rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
+ rpow[10] = rpow[9];
+ rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48);
+ rpow[12] = rpow[11];
+ rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
+ rpow[14] = rpow[13];
+
+ /* Set min/max power based off OFDM values or initialization */
+ if (rpow[13] < *pMinPower)
+ *pMinPower = rpow[13];
+ if (rpow[9] > *pMaxPower)
+ *pMaxPower = rpow[9];
+
+ }
+#if 0
+ ahp->ah_tx6PowerInHalfDbm = *pMaxPower;
+#endif
+ return AH_TRUE;
+}
+
+void*
+ath_hal_malloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+void
+ath_hal_free(void* p)
+{
+ return free(p);
+}
+
+void
+ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
+{
+ vprintf(fmt, ap);
+}
+
+void
+ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ ath_hal_vprintf(ah, fmt, ap);
+ va_end(ap);
+}
+
+void
+HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
+{
+ if (ath_hal_debug & mask) {
+ __va_list ap;
+ va_start(ap, fmt);
+ ath_hal_vprintf(ah, fmt, ap);
+ va_end(ap);
+ }
+}
diff --git a/tools/tools/ath/athrd/run.sh b/tools/tools/ath/athrd/run.sh
new file mode 100755
index 0000000..3e1e01a
--- /dev/null
+++ b/tools/tools/ath/athrd/run.sh
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+COUNTRIES=${@:-"
+ DB NA AL DZ AR AM AU AT AZ BH BY BE BZ BO BR BN BG
+ CA CL CN CO CR HR CY CZ DK DO EC EG SV EE FI FR GE
+ DE GR GT HN HK HU IS IN ID IR IE IL IT JP J1 J2 J3
+ J4 J5 JO KZ KP KR K2 KW LV LB LI LT LU MO MK MY MX
+ MC MA NL NZ NO OM PK PA PE PH PL PT PR QA RO RU SA
+ SG SK SI ZA ES SE CH SY TW TH TT TN TR UA AE GB US
+ UY UZ VE VN YE ZW WOR0_WORLD WOR1_WORLD WOR2_WORLD WOR3_WORLD
+ WOR4_WORLD, WOR5_ETSIC EU1_WORLD WOR01_WORLD WOR02_WORLD
+"}
+
+for i in $COUNTRIES
+do
+ ./athrd -o $i
+done
diff --git a/tools/tools/ath/athstats/Makefile b/tools/tools/ath/athstats/Makefile
index cd05e96..1a963e6 100644
--- a/tools/tools/ath/athstats/Makefile
+++ b/tools/tools/ath/athstats/Makefile
@@ -11,6 +11,7 @@ SRCDIR= ${.CURDIR}/../../../..
CLEANFILES+= opt_ah.h ah_osdep.h
CFLAGS+=-DATH_SUPPORT_ANI
+CFLAGS+=-DATH_SUPPORT_TDMA
CFLAGS+=-I${.CURDIR}
CFLAGS+=-I${SRCDIR}/sys/net80211
@@ -22,4 +23,6 @@ athstats.o: opt_ah.h ah_osdep.h
opt_ah.h:
touch opt_ah.h
ah_osdep.h:
- touch ah_osdep.h
+ echo 'typedef void *HAL_SOFTC;' >ah_osdep.h
+ echo 'typedef int HAL_BUS_TAG;' >>ah_osdep.h
+ echo 'typedef void *HAL_BUS_HANDLE;' >>ah_osdep.h
diff --git a/tools/tools/ath/athstats/athstats.c b/tools/tools/ath/athstats/athstats.c
index a7c397c..d644745 100644
--- a/tools/tools/ath/athstats/athstats.c
+++ b/tools/tools/ath/athstats/athstats.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -215,7 +215,11 @@ static const struct fmt athstats[] = {
{ 5, "tdmab", "tdmab", "TDMA slot update set beacon timers" },
#define S_TDMA_TSF AFTER(S_TDMA_TIMERS)
{ 5, "tdmat", "tdmat", "TDMA slot update set TSF" },
-#define S_RATE_CALLS AFTER(S_TDMA_TSF)
+#define S_TDMA_TSFADJ AFTER(S_TDMA_TSF)
+ { 8, "tdmadj", "tdmadj", "TDMA slot adjust (usecs, smoothed)" },
+#define S_TDMA_ACK AFTER(S_TDMA_TSFADJ)
+ { 5, "tdmack", "tdmack", "TDMA tx failed 'cuz ACK required" },
+#define S_RATE_CALLS AFTER(S_TDMA_ACK)
#else
#define S_RATE_CALLS AFTER(S_PER_RFGAIN)
#endif
@@ -234,7 +238,9 @@ static const struct fmt athstats[] = {
{ 5, "bmissphantom", "bmissphantom", "phantom beacon misses" },
#define S_TX_RAW AFTER(S_BMISS_PHANTOM)
{ 5, "txraw", "txraw", "tx frames through raw api" },
-#define S_RX_TOOBIG AFTER(S_TX_RAW)
+#define S_TX_RAW_FAIL AFTER(S_TX_RAW)
+ { 5, "txrawfail", "txrawfail", "raw tx failed 'cuz interface/hw down" },
+#define S_RX_TOOBIG AFTER(S_TX_RAW_FAIL)
{ 5, "rx2big", "rx2big", "rx failed 'cuz frame too large" },
#ifndef __linux__
#define S_CABQ_XMIT AFTER(S_RX_TOOBIG)
@@ -555,6 +561,8 @@ ath_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
case S_TX_SHORTPRE: STAT(tx_shortpre);
case S_TX_ALTRATE: STAT(tx_altrate);
case S_TX_PROTECT: STAT(tx_protect);
+ case S_TX_RAW: STAT(tx_raw);
+ case S_TX_RAW_FAIL: STAT(tx_raw_fail);
case S_RX_NOMBUF: STAT(rx_nombuf);
#ifdef S_RX_BUSDMA
case S_RX_BUSDMA: STAT(rx_busdma);
@@ -603,6 +611,11 @@ ath_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
case S_TDMA_UPDATE: STAT(tdma_update);
case S_TDMA_TIMERS: STAT(tdma_timers);
case S_TDMA_TSF: STAT(tdma_tsf);
+ case S_TDMA_TSFADJ:
+ snprintf(b, bs, "-%d/+%d",
+ wf->cur.ath.ast_tdma_tsfadjm, wf->cur.ath.ast_tdma_tsfadjp);
+ return 1;
+ case S_TDMA_ACK: STAT(tdma_ack);
#endif
case S_RATE_CALLS: STAT(rate_calls);
case S_RATE_RAISE: STAT(rate_raise);
@@ -765,6 +778,8 @@ ath_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
case S_TX_SHORTPRE: STAT(tx_shortpre);
case S_TX_ALTRATE: STAT(tx_altrate);
case S_TX_PROTECT: STAT(tx_protect);
+ case S_TX_RAW: STAT(tx_raw);
+ case S_TX_RAW_FAIL: STAT(tx_raw_fail);
case S_RX_NOMBUF: STAT(rx_nombuf);
#ifdef S_RX_BUSDMA
case S_RX_BUSDMA: STAT(rx_busdma);
@@ -813,6 +828,12 @@ ath_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
case S_TDMA_UPDATE: STAT(tdma_update);
case S_TDMA_TIMERS: STAT(tdma_timers);
case S_TDMA_TSF: STAT(tdma_tsf);
+ case S_TDMA_TSFADJ:
+ snprintf(b, bs, "-%d/+%d",
+ wf->total.ath.ast_tdma_tsfadjm,
+ wf->total.ath.ast_tdma_tsfadjp);
+ return 1;
+ case S_TDMA_ACK: STAT(tdma_ack);
#endif
case S_RATE_CALLS: STAT(rate_calls);
case S_RATE_RAISE: STAT(rate_raise);
diff --git a/tools/tools/ath/athstats/main.c b/tools/tools/ath/athstats/main.c
index 328d066..518b149 100644
--- a/tools/tools/ath/athstats/main.c
+++ b/tools/tools/ath/athstats/main.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -59,6 +59,9 @@ static struct {
{ "ani",
"avgbrssi,avgrssi,avgtxrssi,NI,SI,step,owsd,cwst,NI+,NI-,SI+,SI-,OFDM,CCK,LISTEN"
},
+ { "tdma",
+ "input,output,bexmit,tdmau,tdmadj,crcerr,phyerr,phytor,rssi,noise,rate"
+ },
};
static const char *
@@ -69,8 +72,7 @@ getfmt(const char *tag)
for (i = 0; i < N(tags); i++)
if (strcasecmp(tags[i].tag, tag) == 0)
return tags[i].fmt;
- errx(-1, "unknown tag \%s\"", tag);
- /*NOTREACHED*/
+ return tag;
#undef N
}
diff --git a/tools/tools/cfi/Makefile b/tools/tools/cfi/Makefile
new file mode 100644
index 0000000..9e3bbef
--- /dev/null
+++ b/tools/tools/cfi/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= cfi
+BINDIR= /usr/local/bin
+NO_MAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/cfi/cfi.c b/tools/tools/cfi/cfi.c
new file mode 100644
index 0000000..5b20094
--- /dev/null
+++ b/tools/tools/cfi/cfi.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2009 Sam Leffler, Errno Consulting
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * 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 NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * cfi [-f device] op
+ * (default device is /dev/cfi0).
+ */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/cfictl.h>
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+
+const char *progname;
+const char *dvname;
+
+static void
+usage(void)
+{
+ int i;
+
+ fprintf(stderr, "usage: %s [-f device] op...\n", progname);
+ fprintf(stderr, "where op's are:\n");
+ fprintf(stderr, "fact\t\tread factory PR segment\n");
+ fprintf(stderr, "oem\t\tread OEM segment\n");
+ fprintf(stderr, "woem value\twrite OEM segment\n");
+ fprintf(stderr, "plr\t\tread PLR\n");
+ fprintf(stderr, "wplr\t\twrite PLR\n");
+ exit(-1);
+}
+
+static int
+getfd(int mode)
+{
+ int fd = open(dvname, mode, 0);
+ if (fd < 0)
+ err(-1, "open");
+ return fd;
+}
+
+static uint64_t
+getfactorypr(void)
+{
+ uint64_t v;
+ int fd = getfd(O_RDONLY);
+ if (ioctl(fd, CFIOCGFACTORYPR, &v) < 0)
+ err(-1, "ioctl(CFIOCGFACTORYPR)");
+ close(fd);
+ return v;
+}
+
+static uint64_t
+getoempr(void)
+{
+ uint64_t v;
+ int fd = getfd(O_RDONLY);
+ if (ioctl(fd, CFIOCGOEMPR, &v) < 0)
+ err(-1, "ioctl(CFIOCGOEMPR)");
+ close(fd);
+ return v;
+}
+
+static void
+setoempr(uint64_t v)
+{
+ int fd = getfd(O_WRONLY);
+ if (ioctl(fd, CFIOCSOEMPR, &v) < 0)
+ err(-1, "ioctl(CFIOCGOEMPR)");
+ close(fd);
+}
+
+static uint32_t
+getplr(void)
+{
+ uint32_t plr;
+ int fd = getfd(O_RDONLY);
+ if (ioctl(fd, CFIOCGPLR, &plr) < 0)
+ err(-1, "ioctl(CFIOCGPLR)");
+ close(fd);
+ return plr;
+}
+
+static void
+setplr(void)
+{
+ int fd = getfd(O_WRONLY);
+ if (ioctl(fd, CFIOCSPLR, 0) < 0)
+ err(-1, "ioctl(CFIOCPLR)");
+ close(fd);
+}
+
+int
+main(int argc, char *argv[])
+{
+ dvname = getenv("CFI");
+ if (dvname == NULL)
+ dvname = "/dev/cfi0";
+ progname = argv[0];
+ if (argc > 1) {
+ if (strcmp(argv[1], "-f") == 0) {
+ if (argc < 2)
+ errx(1, "missing device name for -f option");
+ dvname = argv[2];
+ argc -= 2, argv += 2;
+ } else if (strcmp(argv[1], "-?") == 0)
+ usage();
+ }
+ for (; argc > 1; argc--, argv++) {
+ if (strcasecmp(argv[1], "fact") == 0) {
+ printf("0x%llx\n", (unsigned long long) getfactorypr());
+ } else if (strcasecmp(argv[1], "oem") == 0) {
+ printf("0x%llx\n", (unsigned long long) getoempr());
+ } else if (strcasecmp(argv[1], "woem") == 0) {
+ if (argc < 2)
+ errx(1, "missing value for woem");
+ setoempr((uint64_t) strtoull(argv[2], NULL, 0));
+ argc--, argv++;
+ } else if (strcasecmp(argv[1], "plr") == 0) {
+ printf("0x%x\n", getplr());
+ } else if (strcasecmp(argv[1], "wplr") == 0) {
+ setplr();
+ } else
+ usage();
+ }
+}
diff --git a/tools/tools/nanobsd/gateworks/Files/root/.profile b/tools/tools/nanobsd/gateworks/Files/root/.profile
new file mode 100644
index 0000000..e1efe6b
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/Files/root/.profile
@@ -0,0 +1,15 @@
+# $FreeBSD: src/etc/root/dot.profile,v 1.21 2007/05/29 06:33:10 dougb Exp $
+#
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:~/bin
+export PATH
+HOME=/root; export HOME
+TERM=${TERM:-cons25}; export TERM
+PAGER=more; export PAGER
+
+#set -o vi
+set -o emacs
+if [ `id -u` = 0 ]; then
+ PS1="`hostname -s`# "
+else
+ PS1="`hostname -s`% "
+fi
diff --git a/tools/tools/nanobsd/gateworks/G2348 b/tools/tools/nanobsd/gateworks/G2348
new file mode 100644
index 0000000..5a57112
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/G2348
@@ -0,0 +1,120 @@
+#
+# Gateworks Avila IXP425 XScale board
+# kernel configuration file for FreeBSD/arm
+#
+# $FreeBSD$
+
+machine arm
+ident G2348
+
+include "../xscale/ixp425/std.ixp425"
+include "../xscale/ixp425/std.avila"
+options XSCALE_CACHE_READ_WRITE_ALLOCATE
+#options ARM_USE_SMALL_ALLOC
+hints "AVILA.hints"
+makeoptions MODULES_OVERRIDE=""
+
+# NB: patched by boot2 to reflect boot/root partition
+options ROOTDEVNAME=\"ufs:ad0s1\"
+
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+makeoptions CONF_CFLAGS=-mcpu=xscale
+
+options HZ=100
+options DEVICE_POLLING
+
+# Debugging for use in -current
+options KDB
+options DDB #Enable the kernel debugger
+#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
+#options DIAGNOSTIC
+
+options SCHED_4BSD #4BSD scheduler
+#options PREEMPTION
+
+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 NFSCLIENT #Network Filesystem Client
+options NFSLOCKD #Network Lock Manager
+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 KBD_INSTALL_CDEV # install a CDEV entry in /dev
+#options VERBOSE_SYSINIT
+
+#device saarm
+
+device pci
+device uart
+
+# I2C Bus
+device iicbus
+device iicbb
+device iic
+
+device ixpiic
+device ixpwdog # watchdog timer
+device ds1672 # DS1672 on I2C bus
+device ad7418 # AD7418 on I2C bus
+
+device avila_led
+
+device ata
+device atadisk # ATA disk drives
+device avila_ata # Gateworks CF/IDE support
+
+device npe # Network Processing Engine
+device npe_fw
+device firmware
+device qmgr # Q Manager (required by npe)
+device miibus # NB: required by npe
+device ether
+device bpf
+
+device pty
+device loop
+device if_bridge
+
+device md
+device random # Entropy device
+
+# Wireless NIC cards
+device wlan # 802.11 support
+options IEEE80211_DEBUG # enable debugging msgs
+options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
+device wlan_wep # 802.11 WEP support
+device wlan_ccmp # 802.11 CCMP support
+device wlan_tkip # 802.11 TKIP support
+
+device ath # Atheros pci/cardbus NIC's
+device ath_rate_sample # SampleRate tx rate control for ath
+options ATH_DEBUG # enable athdebug msgs
+options ATH_DIAGAPI # enable api for athregs
+
+device ath_hal # Atheros HAL (includes binary component)
+options AH_DEBUG
+#options AH_ASSERT
+options AH_SUPPORT_AR5416
+
+#device crypto
+#device cryptodev
+#device hifn # NB: Soekris minipci card known to work
+
+device usb
+options USB_DEBUG
+device uhci
+device ohci
+device ehci
+device ugen
+device umass
+device scbus # SCSI bus (required for SCSI)
+device da # Direct Access (disks)
diff --git a/tools/tools/nanobsd/gateworks/G2358 b/tools/tools/nanobsd/gateworks/G2358
new file mode 100644
index 0000000..1d46ec5
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/G2358
@@ -0,0 +1,121 @@
+#
+# Gateworks Cambria IXP435 XScale board
+# kernel configuration file for FreeBSD/arm
+#
+# $FreeBSD$
+
+machine arm
+ident G2358
+
+include "../xscale/ixp425/std.ixp435"
+include "../xscale/ixp425/std.avila"
+options XSCALE_CACHE_READ_WRITE_ALLOCATE
+#options ARM_USE_SMALL_ALLOC
+hints "CAMBRIA.hints"
+makeoptions MODULES_OVERRIDE=""
+
+# NB: patched by boot2 to reflect boot/root partition
+options ROOTDEVNAME=\"ufs:ad0s1\"
+
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+makeoptions CONF_CFLAGS=-mcpu=xscale
+
+options HZ=100
+options DEVICE_POLLING
+
+# Debugging for use in -current
+options KDB
+options DDB #Enable the kernel debugger
+#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
+#options DIAGNOSTIC
+
+options SCHED_4BSD #4BSD scheduler
+#options PREEMPTION
+
+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 NFSCLIENT #Network Filesystem Client
+options NFSLOCKD #Network Lock Manager
+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 KBD_INSTALL_CDEV # install a CDEV entry in /dev
+#options VERBOSE_SYSINIT
+
+#device saarm
+
+device pci
+device uart
+
+# I2C Bus
+device iicbus
+device iicbb
+device iic
+
+device ixpiic
+device ixpwdog # watchdog timer
+device ds1672 # DS1672 on I2C bus
+device ad7418 # AD7418 on I2C bus
+
+device cambria_led
+device cambria_fled
+
+device ata
+device atadisk # ATA disk drives
+device avila_ata # Gateworks CF/IDE support
+
+device npe # Network Processing Engine
+device npe_fw
+device firmware
+device qmgr # Q Manager (required by npe)
+device miibus # NB: required by npe
+device ether
+device bpf
+
+device pty
+device loop
+device if_bridge
+
+device md
+device random # Entropy device
+
+# Wireless NIC cards
+device wlan # 802.11 support
+options IEEE80211_DEBUG # enable debugging msgs
+options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
+device wlan_wep # 802.11 WEP support
+device wlan_ccmp # 802.11 CCMP support
+device wlan_tkip # 802.11 TKIP support
+
+device ath # Atheros pci/cardbus NIC's
+device ath_rate_sample # SampleRate tx rate control for ath
+options ATH_DEBUG # enable athdebug msgs
+options ATH_DIAGAPI # enable api for athregs
+
+device ath_hal # Atheros HAL (includes binary component)
+options AH_DEBUG
+#options AH_ASSERT
+options AH_SUPPORT_AR5416
+
+#device crypto
+#device cryptodev
+#device hifn # NB: Soekris minipci card known to work
+
+device usb
+options USB_DEBUG
+device uhci
+device ohci
+device ehci
+device ugen
+device umass
+device scbus # SCSI bus (required for SCSI)
+device da # Direct Access (disks)
diff --git a/tools/tools/nanobsd/gateworks/avila b/tools/tools/nanobsd/gateworks/avila
new file mode 100644
index 0000000..4c387fc
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/avila
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+NANO_NAME="avila"
+NANO_SRC=`pwd | sed 's/.tools.tools.nanobsd.*//'`
+NANO_KERNEL="G2348"
+
+NANO_IMAGES=1
+FlashDevice Sandisk 64
+
+. common
diff --git a/tools/tools/nanobsd/gateworks/cambria b/tools/tools/nanobsd/gateworks/cambria
new file mode 100644
index 0000000..5e5966b
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/cambria
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+NANO_NAME="cambria"
+NANO_SRC=`pwd | sed 's/.tools.tools.nanobsd.*//'`
+NANO_KERNEL="G2358"
+
+NANO_IMAGES=1
+FlashDevice Sandisk 64
+
+. common
diff --git a/tools/tools/nanobsd/gateworks/cfg/motd b/tools/tools/nanobsd/gateworks/cfg/motd
new file mode 100644
index 0000000..e2aad3f
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/cfg/motd
@@ -0,0 +1 @@
+FreeBSD 7.1-PRERELEASE (G2348) #1: Fri Sep 26 14:37:41 PDT 2008
diff --git a/tools/tools/nanobsd/gateworks/cfg/rc.conf b/tools/tools/nanobsd/gateworks/cfg/rc.conf
new file mode 100644
index 0000000..5476831
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/cfg/rc.conf
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+hostname="avila"
+ifconfig_npe0="DHCP"
+background_dhclient_npe0="YES" # Start dhcp client in the background.
+#ifconfig_npe1="DHCP"
+background_dhclient_npe1="YES" # Start dhcp client in the background.
+
+wlans_ath0="wlan0"
+
+sshd_enable="YES"
+nfs_client_enable="YES"
+
+sendmail_enable="NO" # Run the sendmail inbound daemon (YES/NO).
+sendmail_submit_enable="NO" # Start a localhost-only MTA for mail submission
+sendmail_outbound_enable="NO" # Dequeue stuck mail (YES/NO).
+sendmail_msp_queue_enable="NO" # Dequeue stuck clientmqueue mail (YES/NO).
+
+dumpdev="NO" # Device to crashdump to (device name, AUTO, or NO).
+background_fsck="NO"
+
+harvest_interrupt="NO" # Entropy device harvests interrupt randomness
+harvest_ethernet="NO" # Entropy device harvests ethernet randomness
+harvest_p_to_p="NO" # Entropy device harvests point-to-point randomness
diff --git a/tools/tools/nanobsd/gateworks/cfg/ssh/sshd_config b/tools/tools/nanobsd/gateworks/cfg/ssh/sshd_config
new file mode 100644
index 0000000..5abb75c
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/cfg/ssh/sshd_config
@@ -0,0 +1,126 @@
+# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $
+# $FreeBSD: src/crypto/openssh/sshd_config,v 1.48 2008/08/01 02:48:36 des Exp $
+
+# This is the sshd server system-wide configuration file. See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented. Uncommented options change a
+# default value.
+
+# Note that some of FreeBSD's defaults differ from OpenBSD's, and
+# FreeBSD has a few additional options.
+
+#VersionAddendum FreeBSD-20080801
+
+#Port 22
+#Protocol 2
+#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
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+
+# Logging
+# obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+#LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 2m
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+#MaxSessions 10
+
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+#AuthorizedKeysFile .ssh/authorized_keys
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
+#HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+
+# Change to yes to enable built-in password authentication.
+PasswordAuthentication yes
+PermitEmptyPasswords yes
+
+# Change to no to disable PAM authentication
+ChallengeResponseAuthentication no
+
+# Kerberos options
+#KerberosAuthentication no
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+#GSSAPICleanupCredentials yes
+
+# Set this to 'no' to disable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication and
+# PasswordAuthentication. Depending on your PAM configuration,
+# PAM authentication via ChallengeResponseAuthentication may bypass
+# the setting of "PermitRootLogin without-password".
+# If you just want the PAM account and session checks to run without
+# PAM authentication, then enable this but set PasswordAuthentication
+# and ChallengeResponseAuthentication to 'no'.
+#UsePAM yes
+
+#AllowAgentForwarding yes
+#AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding yes
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+#PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+#UseLogin no
+#UsePrivilegeSeparation yes
+#PermitUserEnvironment no
+#Compression delayed
+#ClientAliveInterval 0
+#ClientAliveCountMax 3
+#UseDNS yes
+#PidFile /var/run/sshd.pid
+#MaxStartups 10
+#PermitTunnel no
+#ChrootDirectory none
+
+# no default banner path
+#Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/libexec/sftp-server
+
+# Example of overriding settings on a per-user basis
+#Match User anoncvs
+# X11Forwarding no
+# AllowTcpForwarding no
+# ForceCommand cvs server
diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common
new file mode 100644
index 0000000..4b78871
--- /dev/null
+++ b/tools/tools/nanobsd/gateworks/common
@@ -0,0 +1,346 @@
+# $FreeBSD$
+
+NANO_CFGDIR=${NANO_SRC}/${NANO_TOOLS}/gateworks/cfg
+test -d ${NANO_CFGDIR} || NANO_CFGDIR=/var/empty
+NANO_PMAKE="make" # NB: disable -j 3
+
+NANO_ARCH=arm
+TARGET_CPUTYPE=xscale; export TARGET_CPUTYPE # XXX
+TARGET_BIG_ENDIAN=true; export TARGET_BIG_ENDIAN # XXX
+
+NANO_CUSTOMIZE="cust_allow_ssh_root"
+
+clean_usr_local()
+{
+ LOCAL_DIR=${NANO_WORLDDIR}/usr/local
+ pprint 2 "Clean and create world directory (${LOCAL_DIR})"
+ if rm -rf ${LOCAL_DIR}/ > /dev/null 2>&1 ; then
+ true
+ else
+ chflags -R noschg ${LOCAL_DIR}/
+ rm -rf ${LOCAL_DIR}/
+ fi
+ for f in bin etc lib libdata libexec sbin share; do
+ mkdir -p ${LOCAL_DIR}/$f
+ done
+}
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE clean_usr_local"
+
+cust_install_machine_files()
+{
+ echo "cd ${NANO_TOOLS}/gateworks/Files"
+ cd ${NANO_TOOLS}/gateworks/Files
+ find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${NANO_WORLDDIR}
+}
+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} \
+ DESTDIR=${NANO_WORLDDIR} make buildenv
+}
+
+net80211_tools()
+{
+ for f in wlanstats wlanwds wlanwatch; do
+ echo "(cd tools/tools/net80211/$f; make $1)";
+ done | buildenv
+}
+net80211_clean_tools()
+{
+ net80211_tools "clean"
+}
+net80211_build_tools()
+{
+ net80211_tools ""
+}
+net80211_install_tools()
+{
+ net80211_tools "install"
+}
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE net80211_clean_tools"
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE net80211_build_tools"
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE net80211_install_tools"
+
+ath_clean_tools()
+{
+ echo "cd tools/tools/ath; make clean" | buildenv
+}
+ath_build_tools()
+{
+ echo "cd tools/tools/ath; make" | buildenv
+}
+ath_install_tools()
+{
+ echo "cd tools/tools/ath; make install" | buildenv
+}
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE ath_clean_tools"
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE ath_build_tools"
+NANO_CUSTOMIZE="$NANO_CUSTOMIZE ath_install_tools"
+
+NANO_MAKEFS="makefs -B big \
+ -o bsize=4096,fsize=512,density=8192,optimization=space"
+export NANO_MAKEFS
+
+# NB: leave c++ enabled so devd can be built
+CONF_BUILD="
+WITHOUT_ACPI=true
+WITHOUT_ATM=true
+WITHOUT_AUDIT=true
+WITHOUT_BIND_DNSSEC=true
+WITHOUT_BIND_ETC=true
+WITHOUT_BIND_LIBS_LWRES=true
+WITHOUT_BLUETOOTH=true
+WITHOUT_CALENDAR=true
+WITHOUT_CDDL=true
+WITHOUT_CVS=true
+WITHOUT_DICT=true
+WITHOUT_EXAMPLES=true
+WITHOUT_FORTRAN=true
+WITHOUT_GAMES=true
+WITHOUT_GCOV=true
+WITHOUT_GPIB=true
+WITHOUT_HTML=true
+WITHOUT_I4B=true
+WITHOUT_INET6=true
+WITHOUT_INFO=true
+WITHOUT_IPFILTER=true
+WITHOUT_IPX=true
+WITHOUT_KERBEROS=true
+WITHOUT_LIBKSE=true
+WITHOUT_LOCALES=true
+WITHOUT_LPR=true
+WITHOUT_MAN=true
+WITHOUT_NETCAT=true
+WITHOUT_NIS=true
+WITHOUT_NLS=true
+WITHOUT_NS_CACHING=true
+WITHOUT_OBJC=true
+WITHOUT_PROFILE=true
+WITHOUT_RCMDS=true
+WITHOUT_RCS=true
+WITHOUT_RESCUE=true
+WITHOUT_SENDMAIL=true
+WITHOUT_SHAREDOCS=true
+WITHOUT_SSP=true
+WITHOUT_SYSCONS=true
+WITHOUT_TCSH=true
+"
+CONF_INSTALL="$CONF_BUILD
+WITHOUT_TOOLCHAIN=true
+WITHOUT_INSTALLLIB=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()
+{
+ pprint 2 "configure nanobsd /etc"
+
+ (
+ cd ${NANO_WORLDDIR}
+
+ # create diskless marker file
+ touch etc/diskless
+
+ # Make root filesystem R/O by default
+ echo "root_rw_mount=NO" >> etc/defaults/rc.conf
+
+ # save config file for scripts
+ echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
+
+ echo "/dev/${NANO_DRIVE}s1 / ufs ro 1 1" > etc/fstab
+ echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab
+ mkdir -p cfg
+ )
+}
+
+create_arm_diskimage()
+{
+ pprint 2 "build diskimage"
+ pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.di"
+
+ (
+ echo "NANO_MEDIASIZE: $NANO_MEDIASIZE"
+ echo "NANO_IMAGES: $NANO_IMAGES"
+ echo "NANO_SECTS: $NANO_SECTS"
+ echo "NANO_HEADS: $NANO_HEADS"
+ echo "NANO_CODESIZE: $NANO_CODESIZE"
+ echo "NANO_CONFSIZE: $NANO_CONFSIZE"
+ echo "NANO_DATASIZE: $NANO_DATASIZE"
+
+ echo $NANO_MEDIASIZE $NANO_IMAGES \
+ $NANO_SECTS $NANO_HEADS \
+ $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE |
+ awk '
+ {
+ printf "# %s\n", $0
+
+ # size of cylinder in sectors
+ cs = $3 * $4
+
+ # number of full cylinders on media
+ cyl = int ($1 / cs)
+
+ # output fdisk geometry spec, truncate cyls to 1023
+ if (cyl <= 1023)
+ print "g c" cyl " h" $4 " s" $3
+ else
+ print "g c" 1023 " h" $4 " s" $3
+
+ if ($7 > 0) {
+ # size of data partition in full cylinders
+ dsl = int (($7 + cs - 1) / cs)
+ } else {
+ dsl = 0;
+ }
+
+ # size of config partition in full cylinders
+ csl = int (($6 + cs - 1) / cs)
+
+ if ($5 == 0) {
+ # size of image partition(s) in full cylinders
+ isl = int ((cyl - dsl - csl) / $2)
+ } else {
+ isl = int (($5 + cs - 1) / cs)
+ }
+
+ # First image partition start at second track
+ print "p 1 165 " $3, isl * cs - $3
+ c = isl * cs;
+
+ # Second image partition (if any) also starts offset one
+ # track to keep them identical.
+ if ($2 > 1) {
+ print "p 2 165 " $3 + c, isl * cs - $3
+ c += isl * cs;
+ }
+
+ # Config partition starts at cylinder boundary.
+ print "p 3 165 " c, csl * cs
+ c += csl * cs
+
+ # Data partition (if any) starts at cylinder boundary.
+ if ($7 > 0) {
+ print "p 4 165 " c, dsl * cs
+ } else if ($7 < 0 && $1 > c) {
+ print "p 4 165 " c, $1 - c
+ } else if ($1 < c) {
+ print "Disk space overcommitted by", \
+ c - $1, "sectors" > "/dev/stderr"
+ exit 2
+ }
+
+ # Force slice 1 to be marked active. This is necessary
+ # for booting the image from a USB device to work.
+ print "a 1"
+ }
+ ' > ${MAKEOBJDIRPREFIX}/_.fdisk
+
+ IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
+ BS=${NANO_SECTS}b
+
+ if [ "${NANO_MD_BACKING}" = "swap" ] ; then
+ MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \
+ -y ${NANO_HEADS}`
+ else
+ echo ""; echo "Creating md backing file ${IMG} ..."
+ _c=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}`
+ pprint 2 "dd if=/dev/zero of=${IMG} bs=${BS} count=${_c}"
+ dd if=/dev/zero of=${IMG} bs=${BS} count=${_c}
+ pprint 2 "mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} -y ${NANO_HEADS}"
+ MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
+ -y ${NANO_HEADS}`
+ fi
+
+ trap "mdconfig -d -u $MD" 1 2 15 EXIT
+
+ echo ""; echo "Write partition table ..."
+ FDISK=${MAKEOBJDIRPREFIX}/_.fdisk
+ pprint 2 "fdisk -i -f ${FDISK} ${MD}"
+ fdisk -i -f ${FDISK} ${MD}
+ pprint 2 "fdisk ${MD}"
+ fdisk ${MD}
+
+ # Create first image
+ IMG1=${NANO_DISKIMGDIR}/_.disk.image1
+ echo ""; echo "Create first image ${IMG1} ..."
+ SIZE=`awk '/^p 1/ { print $5 "b" }' ${FDISK}`
+ pprint 2 "${NANO_MAKEFS} -s ${SIZE} ${IMG1} ${NANO_WORLDDIR}"
+ ${NANO_MAKEFS} -s ${SIZE} ${IMG1} ${NANO_WORLDDIR}
+ pprint 2 "dd if=${IMG1} of=/dev/${MD}s1 bs=${BS}"
+ dd if=${IMG1} of=/dev/${MD}s1 bs=${BS}
+
+ if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
+ IMG2=${NANO_DISKIMGDIR}/_.disk.image2
+ echo ""; echo "Create second image ${IMG2}..."
+ for f in ${NANO_WORLDDIR}/etc/fstab ${NANO_WORLDDIR}/conf/base/etc/fstab
+ do
+ sed -i "" "s/${NANO_DRIVE}s1/${NANO_DRIVE}s2/g" $f
+ done
+
+ SIZE=`awk '/^p 2/ { print $5 "b" }' ${FDISK}`
+ pprint 2 "${NANO_MAKEFS} -s ${SIZE} ${IMG2} ${NANO_WORLDDIR}"
+ ${NANO_MAKEFS} -s ${SIZE} ${IMG2} ${NANO_WORLDDIR}
+ pprint 2 "dd if=${IMG2} of=/dev/${MD}s2 bs=${BS}"
+ dd if=${IMG2} of=/dev/${MD}s2 bs=${BS}
+ fi
+
+ # Create Config slice
+ CFG=${NANO_DISKIMGDIR}/_.disk.cfg
+ echo ""; echo "Creating config partition ${CFG}..."
+ SIZE=`awk '/^p 3/ { print $5 "b" }' ${FDISK}`
+ # XXX: fill from where ?
+ pprint 2 "${NANO_MAKEFS} -s ${SIZE} ${CFG} ${NANO_CFGDIR}"
+ ${NANO_MAKEFS} -s ${SIZE} ${CFG} ${NANO_CFGDIR}
+ pprint 2 "dd if=${CFG} of=/dev/${MD}s3 bs=${BS}"
+ dd if=${CFG} of=/dev/${MD}s3 bs=${BS}
+ pprint 2 "rm ${CFG}"
+ rm ${CFG}; CFG= # NB: disable printing below
+
+ # Create Data slice, if any.
+ if [ $NANO_DATASIZE -gt 0 ] ; then
+ DATA=${NANO_DISKIMGDIR}/_.disk.data
+ echo ""; echo "Creating data partition ${DATA}..."
+ SIZE=`awk '/^p 4/ { print $5 "b" }' ${FDISK}`
+ # XXX: fill from where ?
+ pprint 2 "${NANO_MAKEFS} -s ${SIZE} ${DATA} /var/empty"
+ ${NANO_MAKEFS} -s ${SIZE} ${DATA} /var/empty
+ pprint 2 "dd if=${DATA} of=/dev/${MD}s4 bs=${BS}"
+ dd if=${DATA} of=/dev/${MD}s4 bs=${BS}
+ pprint 2 "rm ${DATA}"
+ rm ${DATA}; DATA= # NB: disable printing below
+ fi
+
+ if [ "${NANO_MD_BACKING}" = "swap" ] ; then
+ echo "Writing out _.disk.full..."
+ dd if=/dev/${MD} of=${IMG} bs=${BS}
+ fi
+
+ echo ""
+ echo "Completed images in:"
+ echo ""
+ echo "Full disk: ${IMG}"
+ echo "Primary partition: ${IMG1}"
+ test "${IMG2}" && echo "2ndary partition: ${IMG2}"
+ test "${CFG}" && echo "/cfg partition: ${CFG}"
+ test "${DATA}" && echo "/data partition: ${DATA}"
+ echo ""
+ echo "Use dd if=<file> of=/dev/<somewhere> bs=${BS} to transfer an"
+ echo "image to bootable media /dev/<somewhere>."
+ ) > ${MAKEOBJDIRPREFIX}/_.di 2>&1
+}
diff --git a/tools/tools/net80211/Makefile b/tools/tools/net80211/Makefile
index 02edecd..c477ca2 100644
--- a/tools/tools/net80211/Makefile
+++ b/tools/tools/net80211/Makefile
@@ -1,5 +1,5 @@
# $FreeBSD$
-SUBDIR= stumbler w00t wesside wlaninject wlanstats wlanwatch wlanwds
+SUBDIR= stumbler w00t wesside wlaninject wlanstats wlantxtime wlanwatch wlanwds
.include <bsd.subdir.mk>
diff --git a/tools/tools/net80211/scripts/setup.tdma-master b/tools/tools/net80211/scripts/setup.tdma-master
new file mode 100644
index 0000000..f89f4ca
--- /dev/null
+++ b/tools/tools/net80211/scripts/setup.tdma-master
@@ -0,0 +1,20 @@
+#! /bin/sh
+#
+# Setup a TDMA master and bridge it to a wired NIC.
+#
+# $FreeBSD$
+#
+PATH=.:$PATH
+. config
+
+SSID='freebsd+tdma'
+
+WLAN=`ifconfig wlan create wlanmode tdma wlandev $WIRELESS`
+ifconfig $WLAN ssid "$SSID" tdmaslot 0 channel $CHANNEL
+wlandebug -i $WLAN state+scan+tdma
+
+BRIDGE=`ifconfig bridge create`
+ifconfig $BRIDGE addm $WLAN addm $WIRED 192.168.2.1/24
+
+ifconfig $WIRED up
+ifconfig $WLAN up
diff --git a/tools/tools/net80211/scripts/setup.tdma-slave b/tools/tools/net80211/scripts/setup.tdma-slave
new file mode 100644
index 0000000..dc6c29e
--- /dev/null
+++ b/tools/tools/net80211/scripts/setup.tdma-slave
@@ -0,0 +1,19 @@
+#! /bin/sh
+#
+# Setup a TDMA slave and hook it into a bridge.
+#
+# $FreeBSD$
+#
+PATH=.:$PATH
+. config
+
+SSID='freebsd+tdma'
+
+WLAN=`ifconfig wlan create wlanmode tdma wlandev $WIRELESS`
+ifconfig $WLAN ssid "$SSID" 0
+wlandebug -i $WLAN state+scan+tdma
+
+BRIDGE=`ifconfig bridge create`
+ifconfig $BRIDGE addm $WLAN 192.168.2.2/24
+
+ifconfig $WLAN up
diff --git a/tools/tools/net80211/wlanstats/main.c b/tools/tools/net80211/wlanstats/main.c
index 6c5e9f4..93843d5 100644
--- a/tools/tools/net80211/wlanstats/main.c
+++ b/tools/tools/net80211/wlanstats/main.c
@@ -48,10 +48,30 @@
#include "wlanstats.h"
-#define S_DEFAULT \
- "input,rx_mgmt,output,rx_badkeyid,scan_active,scan_bg,bmiss,rssi,noise,rate"
-#define S_AMPDU \
- "input,output,ampdu_reorder,ampdu_oor,rx_dup,ampdu_flush,ampdu_move,ampdu_drop,ampdu_bar,ampdu_baroow,ampdu_barmove,rssi,rate"
+static struct {
+ const char *tag;
+ const char *fmt;
+} tags[] = {
+ { "default",
+ "input,rx_mgmt,output,rx_badkeyid,scan_active,scan_bg,bmiss,rssi,noise,rate"
+ },
+ { "ampdu",
+ "input,output,ampdu_reorder,ampdu_oor,rx_dup,ampdu_flush,ampdu_move,"
+ "ampdu_drop,ampdu_bar,ampdu_baroow,ampdu_barmove,rssi,rate"
+ },
+};
+
+static const char *
+getfmt(const char *tag)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+ for (i = 0; i < N(tags); i++)
+ if (strcasecmp(tags[i].tag, tag) == 0)
+ return tags[i].fmt;
+ return tag;
+#undef N
+}
static int signalled;
@@ -138,10 +158,14 @@ main(int argc, char *argv[])
struct wlanstatfoo *wf;
struct ether_addr *ea;
const uint8_t *mac = NULL;
+ const char *ifname;
int allnodes = 0;
int c, mode;
- wf = wlanstats_new("wlan0", S_DEFAULT);
+ ifname = getenv("WLAN");
+ if (ifname == NULL)
+ ifname = "wlan0";
+ wf = wlanstats_new(ifname, getfmt("default"));
while ((c = getopt(argc, argv, "ai:lm:o:")) != -1) {
switch (c) {
case 'a':
@@ -160,10 +184,7 @@ main(int argc, char *argv[])
mac = ea->octet;
break;
case 'o':
- if (strcasecmp(optarg, "ampdu") == 0)
- wf->setfmt(wf, S_AMPDU);
- else
- wf->setfmt(wf, optarg);
+ wf->setfmt(wf, getfmt(optarg));
break;
default:
errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [interval]\n", argv[0]);
diff --git a/tools/tools/net80211/wlanstats/wlanstats.c b/tools/tools/net80211/wlanstats/wlanstats.c
index a48e11d..dd8e106 100644
--- a/tools/tools/net80211/wlanstats/wlanstats.c
+++ b/tools/tools/net80211/wlanstats/wlanstats.c
@@ -390,9 +390,12 @@ wlan_getopmode(struct wlanstatfoo *wf0)
strlcpy(ifmr.ifm_name, wf->ifr.ifr_name, sizeof(ifmr.ifm_name));
if (ioctl(wf->s, SIOCGIFMEDIA, &ifmr) < 0)
err(1, "%s (SIOCGIFMEDIA)", wf->ifr.ifr_name);
- if (ifmr.ifm_current & IFM_IEEE80211_ADHOC)
- wf->opmode = IEEE80211_M_IBSS; /* XXX ahdemo */
- else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
+ if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
+ if (ifmr.ifm_current & IFM_FLAG0)
+ wf->opmode = IEEE80211_M_AHDEMO;
+ else
+ wf->opmode = IEEE80211_M_IBSS;
+ } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
wf->opmode = IEEE80211_M_HOSTAP;
else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
wf->opmode = IEEE80211_M_MONITOR;
@@ -422,25 +425,41 @@ getlladdr(struct wlanstatfoo_p *wf)
freeifaddrs(ifp);
}
+static int
+getbssid(struct wlanstatfoo_p *wf)
+{
+ wf->ireq.i_type = IEEE80211_IOC_BSSID;
+ wf->ireq.i_data = wf->mac;
+ wf->ireq.i_len = IEEE80211_ADDR_LEN;
+ return ioctl(wf->s, SIOCG80211, &wf->ireq);
+}
+
static void
wlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac)
{
+ static const uint8_t zeromac[IEEE80211_ADDR_LEN];
struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
if (mac == NULL) {
switch (wlan_getopmode(wf0)) {
case IEEE80211_M_HOSTAP:
case IEEE80211_M_MONITOR:
+ getlladdr(wf);
+ break;
case IEEE80211_M_IBSS:
case IEEE80211_M_AHDEMO:
- getlladdr(wf);
+ /*
+ * NB: this may not work in which case the
+ * mac must be specified on the command line
+ */
+ if (getbssid(wf) < 0 ||
+ IEEE80211_ADDR_EQ(wf->mac, zeromac))
+ getlladdr(wf);
break;
case IEEE80211_M_STA:
- wf->ireq.i_type = IEEE80211_IOC_BSSID;
- wf->ireq.i_data = wf->mac;
- wf->ireq.i_len = IEEE80211_ADDR_LEN;
- if (ioctl(wf->s, SIOCG80211, &wf->ireq) <0)
- err(1, "%s (IEEE80211_IOC_BSSID)", wf->ireq.i_name);
+ if (getbssid(wf) < 0)
+ err(1, "%s (IEEE80211_IOC_BSSID)",
+ wf->ireq.i_name);
break;
}
} else
@@ -457,15 +476,18 @@ wlan_collect(struct wlanstatfoo_p *wf,
wf->ireq.i_type = IEEE80211_IOC_STA_INFO;
wf->ireq.i_data = (caddr_t) &wf->u_info;
wf->ireq.i_len = sizeof(wf->u_info);
- if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0)
- warn("%s (IEEE80211_IOC_STA_INFO)", wf->ireq.i_name);
+ if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) {
+ warn("%s:%s (IEEE80211_IOC_STA_INFO)", wf->ireq.i_name,
+ ether_ntoa((const struct ether_addr*) wf->mac));
+ }
IEEE80211_ADDR_COPY(nstats->is_u.macaddr, wf->mac);
wf->ireq.i_type = IEEE80211_IOC_STA_STATS;
wf->ireq.i_data = (caddr_t) nstats;
wf->ireq.i_len = sizeof(*nstats);
if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0)
- warn("%s (IEEE80211_IOC_STA_STATS)", wf->ireq.i_name);
+ warn("%s:%s (IEEE80211_IOC_STA_STATS)", wf->ireq.i_name,
+ ether_ntoa((const struct ether_addr*) wf->mac));
wf->ifr.ifr_data = (caddr_t) stats;
if (ioctl(wf->s, SIOCG80211STATS, &wf->ifr) < 0)
diff --git a/tools/tools/net80211/wlantxtime/Makefile b/tools/tools/net80211/wlantxtime/Makefile
new file mode 100644
index 0000000..a1105f2
--- /dev/null
+++ b/tools/tools/net80211/wlantxtime/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= wlantxtime
+BINDIR= /usr/local/bin
+NO_MAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/net80211/wlantxtime/wlantxtime.c b/tools/tools/net80211/wlantxtime/wlantxtime.c
new file mode 100644
index 0000000..ad9d18c
--- /dev/null
+++ b/tools/tools/net80211/wlantxtime/wlantxtime.c
@@ -0,0 +1,596 @@
+/*-
+ * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
+ * 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$");
+
+/*
+ * IEEE 802.11 PHY-related support.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <net/if_llc.h>
+
+#include <net80211/_ieee80211.h>
+#include <net80211/ieee80211.h>
+
+#define IEEE80211_F_SHPREAMBLE 0x00040000 /* STATUS: use short preamble */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+struct ieee80211_rate_table {
+ int rateCount; /* NB: for proper padding */
+ uint8_t rateCodeToIndex[256]; /* back mapping */
+ struct {
+ uint8_t phy; /* CCK/OFDM/TURBO */
+ uint32_t rateKbps; /* transfer rate in kbs */
+ uint8_t shortPreamble; /* mask for enabling short
+ * preamble in CCK rate code */
+ uint8_t dot11Rate; /* value for supported rates
+ * info element of MLME */
+ uint8_t ctlRateIndex; /* index of next lower basic
+ * rate; used for dur. calcs */
+ uint16_t lpAckDuration; /* long preamble ACK dur. */
+ uint16_t spAckDuration; /* short preamble ACK dur. */
+ } info[32];
+};
+
+uint16_t
+ieee80211_compute_duration(const struct ieee80211_rate_table *rt,
+ uint32_t frameLen, uint16_t rate, int isShortPreamble);
+
+#define KASSERT(c, msg) do { \
+ if (!(c)) { \
+ printf msg; \
+ putchar('\n'); \
+ exit(-1); \
+ } \
+} while (0)
+
+static void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ exit(-1);
+}
+
+/* shorthands to compact tables for readability */
+#define OFDM IEEE80211_T_OFDM
+#define CCK IEEE80211_T_CCK
+#define TURBO IEEE80211_T_TURBO
+#define PBCC (IEEE80211_T_HT+1) /* XXX */
+#define B(r) (0x80 | r)
+#define Mb(x) (x*1000)
+
+static struct ieee80211_rate_table ieee80211_11b_table = {
+ .rateCount = 4, /* XXX no PBCC */
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = CCK, 1000, 0x00, B(2), 0 },/* 1 Mb */
+ [1] = { .phy = CCK, 2000, 0x04, B(4), 1 },/* 2 Mb */
+ [2] = { .phy = CCK, 5500, 0x04, B(11), 1 },/* 5.5 Mb */
+ [3] = { .phy = CCK, 11000, 0x04, B(22), 1 },/* 11 Mb */
+ [4] = { .phy = PBCC, 22000, 0x04, 44, 3 } /* 22 Mb */
+ },
+};
+
+static struct ieee80211_rate_table ieee80211_11g_table = {
+ .rateCount = 12,
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = CCK, 1000, 0x00, B(2), 0 },
+ [1] = { .phy = CCK, 2000, 0x04, B(4), 1 },
+ [2] = { .phy = CCK, 5500, 0x04, B(11), 2 },
+ [3] = { .phy = CCK, 11000, 0x04, B(22), 3 },
+ [4] = { .phy = OFDM, 6000, 0x00, 12, 4 },
+ [5] = { .phy = OFDM, 9000, 0x00, 18, 4 },
+ [6] = { .phy = OFDM, 12000, 0x00, 24, 6 },
+ [7] = { .phy = OFDM, 18000, 0x00, 36, 6 },
+ [8] = { .phy = OFDM, 24000, 0x00, 48, 8 },
+ [9] = { .phy = OFDM, 36000, 0x00, 72, 8 },
+ [10] = { .phy = OFDM, 48000, 0x00, 96, 8 },
+ [11] = { .phy = OFDM, 54000, 0x00, 108, 8 }
+ },
+};
+
+static struct ieee80211_rate_table ieee80211_11a_table = {
+ .rateCount = 8,
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = OFDM, 6000, 0x00, B(12), 0 },
+ [1] = { .phy = OFDM, 9000, 0x00, 18, 0 },
+ [2] = { .phy = OFDM, 12000, 0x00, B(24), 2 },
+ [3] = { .phy = OFDM, 18000, 0x00, 36, 2 },
+ [4] = { .phy = OFDM, 24000, 0x00, B(48), 4 },
+ [5] = { .phy = OFDM, 36000, 0x00, 72, 4 },
+ [6] = { .phy = OFDM, 48000, 0x00, 96, 4 },
+ [7] = { .phy = OFDM, 54000, 0x00, 108, 4 }
+ },
+};
+
+static struct ieee80211_rate_table ieee80211_half_table = {
+ .rateCount = 8,
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = OFDM, 3000, 0x00, B(6), 0 },
+ [1] = { .phy = OFDM, 4500, 0x00, 9, 0 },
+ [2] = { .phy = OFDM, 6000, 0x00, B(12), 2 },
+ [3] = { .phy = OFDM, 9000, 0x00, 18, 2 },
+ [4] = { .phy = OFDM, 12000, 0x00, B(24), 4 },
+ [5] = { .phy = OFDM, 18000, 0x00, 36, 4 },
+ [6] = { .phy = OFDM, 24000, 0x00, 48, 4 },
+ [7] = { .phy = OFDM, 27000, 0x00, 54, 4 }
+ },
+};
+
+static struct ieee80211_rate_table ieee80211_quarter_table = {
+ .rateCount = 8,
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = OFDM, 1500, 0x00, B(3), 0 },
+ [1] = { .phy = OFDM, 2250, 0x00, 4, 0 },
+ [2] = { .phy = OFDM, 3000, 0x00, B(9), 2 },
+ [3] = { .phy = OFDM, 4500, 0x00, 9, 2 },
+ [4] = { .phy = OFDM, 6000, 0x00, B(12), 4 },
+ [5] = { .phy = OFDM, 9000, 0x00, 18, 4 },
+ [6] = { .phy = OFDM, 12000, 0x00, 24, 4 },
+ [7] = { .phy = OFDM, 13500, 0x00, 27, 4 }
+ },
+};
+
+static struct ieee80211_rate_table ieee80211_turbog_table = {
+ .rateCount = 7,
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = TURBO, 12000, 0x00, B(12), 0 },
+ [1] = { .phy = TURBO, 24000, 0x00, B(24), 1 },
+ [2] = { .phy = TURBO, 36000, 0x00, 36, 1 },
+ [3] = { .phy = TURBO, 48000, 0x00, B(48), 3 },
+ [4] = { .phy = TURBO, 72000, 0x00, 72, 3 },
+ [5] = { .phy = TURBO, 96000, 0x00, 96, 3 },
+ [6] = { .phy = TURBO, 108000, 0x00, 108, 3 }
+ },
+};
+
+static struct ieee80211_rate_table ieee80211_turboa_table = {
+ .rateCount = 8,
+ .info = {
+/* short ctrl */
+/* Preamble dot11Rate Rate */
+ [0] = { .phy = TURBO, 12000, 0x00, B(12), 0 },
+ [1] = { .phy = TURBO, 18000, 0x00, 18, 0 },
+ [2] = { .phy = TURBO, 24000, 0x00, B(24), 2 },
+ [3] = { .phy = TURBO, 36000, 0x00, 36, 2 },
+ [4] = { .phy = TURBO, 48000, 0x00, B(48), 4 },
+ [5] = { .phy = TURBO, 72000, 0x00, 72, 4 },
+ [6] = { .phy = TURBO, 96000, 0x00, 96, 4 },
+ [7] = { .phy = TURBO, 108000, 0x00, 108, 4 }
+ },
+};
+
+#undef Mb
+#undef B
+#undef OFDM
+#undef CCK
+#undef TURBO
+#undef XR
+
+/*
+ * Setup a rate table's reverse lookup table and fill in
+ * ack durations. The reverse lookup tables are assumed
+ * to be initialized to zero (or at least the first entry).
+ * We use this as a key that indicates whether or not
+ * we've previously setup the reverse lookup table.
+ *
+ * XXX not reentrant, but shouldn't matter
+ */
+static void
+ieee80211_setup_ratetable(struct ieee80211_rate_table *rt)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+#define WLAN_CTRL_FRAME_SIZE \
+ (sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN)
+
+ int i;
+
+ for (i = 0; i < N(rt->rateCodeToIndex); i++)
+ rt->rateCodeToIndex[i] = (uint8_t) -1;
+ for (i = 0; i < rt->rateCount; i++) {
+ uint8_t code = rt->info[i].dot11Rate;
+ uint8_t cix = rt->info[i].ctlRateIndex;
+ uint8_t ctl_rate = rt->info[cix].dot11Rate;
+
+ rt->rateCodeToIndex[code] = i;
+ if (code & IEEE80211_RATE_BASIC) {
+ /*
+ * Map w/o basic rate bit too.
+ */
+ code &= IEEE80211_RATE_VAL;
+ rt->rateCodeToIndex[code] = i;
+ }
+
+ /*
+ * XXX for 11g the control rate to use for 5.5 and 11 Mb/s
+ * depends on whether they are marked as basic rates;
+ * the static tables are setup with an 11b-compatible
+ * 2Mb/s rate which will work but is suboptimal
+ *
+ * NB: Control rate is always less than or equal to the
+ * current rate, so control rate's reverse lookup entry
+ * has been installed and following call is safe.
+ */
+ rt->info[i].lpAckDuration = ieee80211_compute_duration(rt,
+ WLAN_CTRL_FRAME_SIZE, ctl_rate, 0);
+ rt->info[i].spAckDuration = ieee80211_compute_duration(rt,
+ WLAN_CTRL_FRAME_SIZE, ctl_rate, IEEE80211_F_SHPREAMBLE);
+ }
+
+#undef WLAN_CTRL_FRAME_SIZE
+#undef N
+}
+
+/* Setup all rate tables */
+static void
+ieee80211_phy_init(void)
+{
+#define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
+ static struct ieee80211_rate_table * const ratetables[] = {
+ &ieee80211_half_table,
+ &ieee80211_quarter_table,
+ &ieee80211_11a_table,
+ &ieee80211_11g_table,
+ &ieee80211_turbog_table,
+ &ieee80211_turboa_table,
+ &ieee80211_turboa_table,
+ &ieee80211_11a_table,
+ &ieee80211_11g_table,
+ &ieee80211_11b_table
+ };
+ int i;
+
+ for (i = 0; i < N(ratetables); ++i)
+ ieee80211_setup_ratetable(ratetables[i]);
+
+#undef N
+}
+
+/*
+ * Compute the time to transmit a frame of length frameLen bytes
+ * using the specified rate, phy, and short preamble setting.
+ * SIFS is included.
+ */
+uint16_t
+ieee80211_compute_duration(const struct ieee80211_rate_table *rt,
+ uint32_t frameLen, uint16_t rate, int isShortPreamble)
+{
+ uint8_t rix = rt->rateCodeToIndex[rate];
+ uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+ uint32_t kbps;
+
+ KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
+ kbps = rt->info[rix].rateKbps;
+ if (kbps == 0) /* XXX bandaid for channel changes */
+ return 0;
+
+ switch (rt->info[rix].phy) {
+ case IEEE80211_T_CCK:
+#define CCK_SIFS_TIME 10
+#define CCK_PREAMBLE_BITS 144
+#define CCK_PLCP_BITS 48
+ phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
+ if (isShortPreamble && rt->info[rix].shortPreamble)
+ phyTime >>= 1;
+ numBits = frameLen << 3;
+ txTime = CCK_SIFS_TIME + phyTime
+ + ((numBits * 1000)/kbps);
+ break;
+#undef CCK_SIFS_TIME
+#undef CCK_PREAMBLE_BITS
+#undef CCK_PLCP_BITS
+
+ case IEEE80211_T_OFDM:
+#define OFDM_SIFS_TIME 16
+#define OFDM_PREAMBLE_TIME 20
+#define OFDM_PLCP_BITS 22
+#define OFDM_SYMBOL_TIME 4
+
+#define OFDM_SIFS_TIME_HALF 32
+#define OFDM_PREAMBLE_TIME_HALF 40
+#define OFDM_PLCP_BITS_HALF 22
+#define OFDM_SYMBOL_TIME_HALF 8
+
+#define OFDM_SIFS_TIME_QUARTER 64
+#define OFDM_PREAMBLE_TIME_QUARTER 80
+#define OFDM_PLCP_BITS_QUARTER 22
+#define OFDM_SYMBOL_TIME_QUARTER 16
+ if (rt == &ieee80211_half_table) {
+ bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
+ KASSERT(bitsPerSymbol != 0, ("1/2 rate bps"));
+
+ numBits = OFDM_PLCP_BITS + (frameLen << 3);
+ numSymbols = howmany(numBits, bitsPerSymbol);
+ txTime = OFDM_SIFS_TIME_QUARTER
+ + OFDM_PREAMBLE_TIME_QUARTER
+ + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
+ } else if (rt == &ieee80211_quarter_table) {
+ bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+ KASSERT(bitsPerSymbol != 0, ("1/4 rate bps"));
+
+ numBits = OFDM_PLCP_BITS + (frameLen << 3);
+ numSymbols = howmany(numBits, bitsPerSymbol);
+ txTime = OFDM_SIFS_TIME_HALF
+ + OFDM_PREAMBLE_TIME_HALF
+ + (numSymbols * OFDM_SYMBOL_TIME_HALF);
+ } else { /* full rate channel */
+ bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
+ KASSERT(bitsPerSymbol != 0, ("full rate bps"));
+
+ numBits = OFDM_PLCP_BITS + (frameLen << 3);
+ numSymbols = howmany(numBits, bitsPerSymbol);
+ txTime = OFDM_SIFS_TIME
+ + OFDM_PREAMBLE_TIME
+ + (numSymbols * OFDM_SYMBOL_TIME);
+ }
+ break;
+
+#undef OFDM_SIFS_TIME
+#undef OFDM_PREAMBLE_TIME
+#undef OFDM_PLCP_BITS
+#undef OFDM_SYMBOL_TIME
+
+ case IEEE80211_T_TURBO:
+#define TURBO_SIFS_TIME 8
+#define TURBO_PREAMBLE_TIME 14
+#define TURBO_PLCP_BITS 22
+#define TURBO_SYMBOL_TIME 4
+ /* we still save OFDM rates in kbps - so double them */
+ bitsPerSymbol = ((kbps << 1) * TURBO_SYMBOL_TIME) / 1000;
+ KASSERT(bitsPerSymbol != 0, ("turbo bps"));
+
+ numBits = TURBO_PLCP_BITS + (frameLen << 3);
+ numSymbols = howmany(numBits, bitsPerSymbol);
+ txTime = TURBO_SIFS_TIME + TURBO_PREAMBLE_TIME
+ + (numSymbols * TURBO_SYMBOL_TIME);
+ break;
+#undef TURBO_SIFS_TIME
+#undef TURBO_PREAMBLE_TIME
+#undef TURBO_PLCP_BITS
+#undef TURBO_SYMBOL_TIME
+
+ default:
+ panic("%s: unknown phy %u (rate %u)\n", __func__,
+ rt->info[rix].phy, rate);
+ break;
+ }
+ return txTime;
+}
+
+#define OFDM_PLCP_BITS 22
+#define HT_L_STF 8
+#define HT_L_LTF 8
+#define HT_L_SIG 4
+#define HT_SIG 8
+#define HT_STF 4
+#define HT_LTF(n) ((n) * 4)
+
+uint32_t
+ieee80211_compute_duration_ht(const struct ieee80211_rate_table *rt,
+ uint32_t frameLen, uint16_t rate,
+ int streams, int isht40, int isShortGI)
+{
+ static const uint16_t ht20_bps[16] = {
+ 26, 52, 78, 104, 156, 208, 234, 260,
+ 52, 104, 156, 208, 312, 416, 468, 520
+ };
+ static const uint16_t ht40_bps[16] = {
+ 54, 108, 162, 216, 324, 432, 486, 540,
+ 108, 216, 324, 432, 648, 864, 972, 1080,
+ };
+ uint32_t bitsPerSymbol, numBits, numSymbols, txTime;
+
+ KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate));
+ KASSERT((rate &~ IEEE80211_RATE_MCS) < 16, ("bad mcs 0x%x", rate));
+
+ if (isht40)
+ bitsPerSymbol = ht40_bps[rate & 0xf];
+ else
+ bitsPerSymbol = ht20_bps[rate & 0xf];
+ numBits = OFDM_PLCP_BITS + (frameLen << 3);
+ numSymbols = howmany(numBits, bitsPerSymbol);
+ if (isShortGI)
+ txTime = ((numSymbols * 18) + 4) / 5; /* 3.6us */
+ else
+ txTime = numSymbols * 4; /* 4us */
+ return txTime + HT_L_STF + HT_L_LTF +
+ HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+}
+
+static const struct ieee80211_rate_table *
+mode2table(const char *mode)
+{
+ if (strcasecmp(mode, "half") == 0)
+ return &ieee80211_half_table;
+ else if (strcasecmp(mode, "quarter") == 0)
+ return &ieee80211_quarter_table;
+ else if (strcasecmp(mode, "hta") == 0)
+ return &ieee80211_11a_table; /* XXX */
+ else if (strcasecmp(mode, "htg") == 0)
+ return &ieee80211_11g_table; /* XXX */
+ else if (strcasecmp(mode, "108g") == 0)
+ return &ieee80211_turbog_table;
+ else if (strcasecmp(mode, "sturbo") == 0)
+ return &ieee80211_turboa_table;
+ else if (strcasecmp(mode, "turbo") == 0)
+ return &ieee80211_turboa_table;
+ else if (strcasecmp(mode, "11a") == 0)
+ return &ieee80211_11a_table;
+ else if (strcasecmp(mode, "11g") == 0)
+ return &ieee80211_11g_table;
+ else if (strcasecmp(mode, "11b") == 0)
+ return &ieee80211_11b_table;
+ else
+ return NULL;
+}
+
+const char *
+srate(int rate)
+{
+ static char buf[32];
+ if (rate & 1)
+ snprintf(buf, sizeof(buf), "%u.5", rate/2);
+ else
+ snprintf(buf, sizeof(buf), "%u", rate/2);
+ return buf;
+}
+
+static int
+checkpreamble(const struct ieee80211_rate_table *rt, uint8_t rix,
+ int isShortPreamble, int verbose)
+{
+ if (isShortPreamble) {
+ if (rt->info[rix].phy != IEEE80211_T_CCK) {
+ if (verbose)
+ warnx("short preamble not meaningful, ignored");
+ isShortPreamble = 0;
+ } else if (!rt->info[rix].shortPreamble) {
+ if (verbose)
+ warnx("short preamble not meaningful with "
+ "rate %s, ignored",
+ srate(rt->info[rix].dot11Rate &~ IEEE80211_RATE_BASIC));
+ isShortPreamble = 0;
+ }
+ }
+ return isShortPreamble;
+}
+
+static void
+usage(const char *progname)
+{
+ fprintf(stderr, "usage: %s [-a] [-l framelen] [-m mode] [-r rate] [-s]\n",
+ progname);
+ fprintf(stderr, "-a display calculations for all possible rates\n");
+ fprintf(stderr, "-l framelen length in bytes of 802.11 payload (default 1536)\n");
+ fprintf(stderr, "-m 11a calculate for 11a channel\n");
+ fprintf(stderr, "-m 11b calculate for 11b channel\n");
+ fprintf(stderr, "-m 11g calculate for 11g channel (default)\n");
+ fprintf(stderr, "-m half calculate for 1/2 width channel\n");
+ fprintf(stderr, "-m quarter calculate for 1/4 width channel\n");
+ fprintf(stderr, "-m 108g calculate for dynamic turbo 11g channel\n");
+ fprintf(stderr, "-m sturbo calculate for static turbo channel\n");
+ fprintf(stderr, "-m turbo calculate for dynamic turbo 11a channel\n");
+ fprintf(stderr, "-r rate IEEE rate code (default 54)\n");
+ fprintf(stderr, "-s short preamble (default long)\n");
+ exit(0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const struct ieee80211_rate_table *rt;
+ const char *mode;
+ uint32_t frameLen;
+ uint16_t rate;
+ uint16_t time;
+ uint8_t rix;
+ int ch, allrates, isShortPreamble, isShort;
+ float frate;
+
+ ieee80211_phy_init();
+
+ mode = "11g";
+ isShortPreamble = 0;
+ frameLen = 1500
+ + sizeof(struct ieee80211_frame)
+ + LLC_SNAPFRAMELEN
+ + IEEE80211_CRC_LEN
+ ;
+ rate = 2*54;
+ allrates = 0;
+ while ((ch = getopt(argc, argv, "al:m:r:s")) != -1) {
+ switch (ch) {
+ case 'a':
+ allrates = 1;
+ break;
+ case 'l':
+ frameLen = strtoul(optarg, NULL, 0);
+ break;
+ case 'm':
+ mode = optarg;
+ break;
+ case 'r':
+ frate = atof(optarg);
+ rate = (int) 2*frate;
+ break;
+ case 's':
+ isShortPreamble = 1;
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+ rt = mode2table(mode);
+ if (rt == NULL)
+ errx(-1, "unknown mode %s", mode);
+ if (!allrates) {
+ rix = rt->rateCodeToIndex[rate];
+ if (rix == (uint8_t) -1)
+ errx(-1, "rate %s not valid for mode %s", srate(rate), mode);
+ isShort = checkpreamble(rt, rix, isShortPreamble, 1);
+
+ time = ieee80211_compute_duration(rt, frameLen, rate, isShort);
+ printf("%u usec to send %u bytes @ %s Mb/s, %s preamble\n",
+ time, frameLen, srate(rate),
+ isShort ? "short" : "long");
+ } else {
+ for (rix = 0; rix < rt->rateCount; rix++) {
+ rate = rt->info[rix].dot11Rate &~ IEEE80211_RATE_BASIC;
+ isShort = checkpreamble(rt, rix, isShortPreamble, 0);
+ time = ieee80211_compute_duration(rt, frameLen, rate,
+ isShort);
+ printf("%u usec to send %u bytes @ %s Mb/s, %s preamble\n",
+ time, frameLen, srate(rate),
+ isShort ? "short" : "long");
+ }
+ }
+ return 0;
+}
diff --git a/tools/tools/sysbuild/README b/tools/tools/sysbuild/README
new file mode 100644
index 0000000..56340b0
--- /dev/null
+++ b/tools/tools/sysbuild/README
@@ -0,0 +1,153 @@
+$FreeBSD$
+
+About sysbuild.sh
+=================
+
+I have been running -current on my laptop since before FreeBSD 2.0 was
+released and along the way developed this little trick to making the
+task easier.
+
+sysbuild.sh is a way to build a new FreeBSD system on a computer from
+a specification, while leaving the current installation intact.
+
+sysbuild.sh assume you have two partitions that can hold your rootfs
+and can be booted, and roughly speaking, all it does is build a new
+system into the one you don't use, from the one you do use.
+
+A partition named /freebsd is assumed to be part of your layout, and
+that is where the sources and ports will be found.
+
+If you know how nanobsd works, you will find a lot of similarity.
+
+HOWTO
+=====
+
+In all likelyhood, it is easier if we imagine you start with a blank
+computer.
+
+Grab a FreeBSD install ISO and boot it.
+
+Create four disk slices:
+
+ ad0s1 = 5GB
+ ad0s2 = 5GB
+ ad0s3 = 5GB
+ ad0s4 = the rest
+
+Create a root filesystem in s1a filling the entire ad0s1 slice.
+
+Create a swap partition, if you want one, in ad0s4b.
+
+Install the boot0 bootmanager.
+
+Install the "Minimal" FreeBSD system into ad0s1a.
+
+Reboot from the newly installed system.
+
+Run these commands to set up the other partitions sysbuild.sh cares about:
+
+ # /freebsd filesystem
+ newfs -b 4096 -f 512 -O2 -U /dev/ad0s3
+ echo "/dev/ad0s3 /freebsd ufs rw 2 2" >> /etc/fstab
+ mkdir /freebsd
+ mount /freebsd
+
+ # deputy rootfilesystem
+ bsdlabel -B -w /dev/ad0s2
+ newfs -O2 -U /dev/ad0s2a
+
+Next, install ports and sources:
+
+ cd /usr
+ rm -rf ports src
+ ln -s /freebsd/src
+ ln -s /freebsd/ports
+ cd /freebsd
+ mkdir ports src packages
+
+ # Or use svn if you prefer
+ csup -h cvsup.???.freebsd.org /usr/share/examples/cvsup/ports-supfile
+ csup -h cvsup.???.freebsd.org /usr/share/examples/cvsup/stable-supfile
+
+And we should be ready to try a shot:
+
+ cd /root
+ cp /usr/src/tools/tools/sysbuild/sysbuild.sh .
+ sh sysbuild.sh |& tee _.sb
+
+If it succeeds, you should be able to:
+
+ boot0cfg -s 2 -v /dev/ad0
+ reboot
+
+And come up with your newly built system.
+
+ Next time you want a new system, you just run sysbuild.sh again
+ and boot slice 1 when it's done.
+
+TWEAKS
+======
+
+The sysbuild.sh script takes various parameters:
+
+ -c specfile # configure stuff, see below.
+ -w # skip buildworld, assume it was done earlier.
+ -k # skip buildkernel, ---//---
+ -b # skip both buildworld & buildkernel
+ -p # install cached packacges if found.
+
+The specfile is a shellscript where you can override or set a number of
+shell variables and functions.
+
+A partial example:
+
+ # use a kernel different from GENERIC
+ KERNCONF=SMP
+
+ # Cache built packages, so we can use -p
+ PKG_DIR=/freebsd/packages
+
+ # Mount ports distfiles from another machine
+ REMOTEDISTFILES=fs:/rdonly/distfiles
+
+ # Fetch distfiles through a proxy
+ FTP_PROXY=http://127.0.0.1:3128/
+ HTTP_PROXY=http://127.0.0.1:3128/
+ export FTP_PROXY HTTP_PROXY
+
+ # We want these ports
+ PORTS_WE_WANT='
+ /usr/ports/archivers/unzip
+ /usr/ports/archivers/zip
+ /usr/ports/cad/linux-eagle
+ /usr/ports/comms/lrzsz
+ /usr/ports/databases/rrdtool
+ /usr/ports/devel/subversion-freebsd
+ '
+
+ # Files to move over
+ CONFIGFILES='
+ /root/.ssh
+ /etc/X11/xorg.conf
+ /etc/ssh/ssh_host*
+ /etc/rc.conf
+ /etc/rc.local
+ '
+
+ # Shell functions to tweak things
+ # (This makes commits to /etc mostly painless)
+ final_chroot() (
+ chpass -p "\$1\$IgMjWs2L\$Nu12OCsjfiwHHj0I7TmUN1" root
+
+ pw useradd phk -u 488 -d /home/phk -c "Poul-Henning Kamp" \
+ -G "wheel,operator,dialer" -s /bin/csh -w none
+
+ chpass -p "\$1\$VcM.9Ow8\$IcXHs0h9jsk27b8N64lOm/" phk
+
+ sed -i "" -e 's/^DS/DSorigo.freebsd.dk/' /etc/mail/sendmail.cf
+ sed -i "" -e '/console/s/^/#/' /etc/syslog.conf
+ echo "beastie_disable=YES" >> /boot/loader.conf
+ touch /root/.hushlogin
+ )
+
+
diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh
new file mode 100644
index 0000000..c9ae016
--- /dev/null
+++ b/tools/tools/sysbuild/sysbuild.sh
@@ -0,0 +1,529 @@
+#!/bin/sh
+#
+# Copyright (c) 1994-2009 Poul-Henning Kamp.
+# 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$
+#
+
+set -e
+
+exec < /dev/null
+
+if [ `uname -m` = "i386" ] ; then
+ TARGET_PART=`df / | sed '
+ 1d
+ s/[ ].*//
+ s,/dev/,,
+ s,s1a,s3a,
+ s,s2a,s1a,
+ s,s3a,s2a,
+ '`
+
+ # Where our build-bits are to be found
+ FREEBSD_PART=`echo $TARGET_PART | sed 's/s[12]a/s3/'`
+else
+ TARGET_PART=unknown
+ FREEBSD_PART=unknown
+fi
+
+# Relative to /freebsd
+PORTS_PATH=ports
+SRC_PATH=src
+# OBJ_PATH=obj
+
+# Name of kernel
+KERNCONF=GENERIC
+
+# srcconf
+#SRCCONF="SRCCONF=/usr/src/src.conf"
+
+# -j arg to make(1)
+
+ncpu=`sysctl -n kern.smp.cpus`
+if [ $ncpu -gt 1 ] ; then
+ JARG="-j $ncpu"
+fi
+
+# serial console ?
+SERCONS=false
+
+# Remotely mounted distfiles
+# REMOTEDISTFILES=fs:/rdonly/distfiles
+
+# Proxy
+#FTP_PROXY=http://127.0.0.1:3128/
+#HTTP_PROXY=http://127.0.0.1:3128/
+#export FTP_PROXY HTTP_PROXY
+
+PORTS_WE_WANT='
+'
+
+PORTS_OPTS="BATCH=YES MAKE_IDEA=YES A4=yes"
+
+CONFIGFILES='
+'
+
+cleanup() (
+)
+
+before_ports() (
+)
+
+before_ports_chroot() (
+)
+
+final_root() (
+)
+
+final_chroot() (
+)
+
+#######################################################################
+#######################################################################
+
+usage () {
+ (
+ echo "Usage: $0 [-b/-k/-w] [-c config_file]"
+ echo " -b suppress builds (both kernel and world)"
+ echo " -k suppress buildkernel"
+ echo " -w suppress buildworld"
+ echo " -p used cached packages"
+ echo " -c specify config file"
+ ) 1>&2
+ exit 2
+}
+
+#######################################################################
+#######################################################################
+
+if [ ! -f $0 ] ; then
+ echo "Must be able to access self ($0)" 1>&2
+ exit 1
+fi
+
+if grep -q 'Magic String: 0`0nQT40W%l,CX&' $0 ; then
+ true
+else
+ echo "self ($0) does not contain magic string" 1>&2
+ exit 1
+fi
+
+#######################################################################
+
+set -e
+
+log_it() (
+ set +x
+ a="$*"
+ set `cat /tmp/_sb_log`
+ TX=`date +%s`
+ echo "$1 $TX" > /tmp/_sb_log
+ DT=`expr $TX - $1 || true`
+ DL=`expr $TX - $2 || true`
+ echo -n "### `date +%H:%M:%S`"
+ printf " ### %5d ### %5d ### %s\n" $DT $DL "$a"
+)
+
+#######################################################################
+
+
+ports_recurse() (
+ set +x
+ for d
+ do
+ if [ ! -d $d ] ; then
+ echo "Missing port $d" 1>&2
+ exit 2
+ fi
+ if grep -q "^$d\$" /tmp/_.plist ; then
+ true
+ else
+ (
+ cd $d
+ ports_recurse `make -V _DEPEND_DIRS`
+ )
+ echo $d >> /tmp/_.plist
+ fi
+ done
+)
+
+ports_build() (
+ set +x
+
+ true > /tmp/_.plist
+ ports_recurse $PORTS_WE_WANT
+
+ # Now build & install them
+ for p in `cat /tmp/_.plist`
+ do
+ t=`echo $p | sed 's,/usr/ports/,,'`
+ pn=`cd $p && make package-name`
+ if [ "x${PKG_DIR}" != "x" -a -f ${PKG_DIR}/$pn.tbz ] ; then
+ if [ "x$use_pkg" = "x-p" ] ; then
+ log_it "install $p from ${PKG_DIR}/$pn.tbz"
+ pkg_add ${PKG_DIR}/$pn.tbz
+ fi
+ fi
+ i=`pkg_info -qO $t`
+ if [ -z "$i" ] ; then
+ log_it "build $p"
+ b=`echo $p | tr / _`
+ (
+ set -x
+ cd /usr/ports
+ cd $p
+ set +e
+ make clean
+ if make install ${PORTS_OPTS} ; then
+ if [ "x${PKG_DIR}" != "x" ] ; then
+ make package ${PORTS_OPTS}
+ mv *.tbz ${PKG_DIR}
+ fi
+ else
+ log_it FAIL build $p
+ fi
+ make clean
+ ) > _.$b 2>&1 < /dev/null
+ date
+ fi
+ done
+)
+
+ports_prefetch() (
+ (
+ set +x
+ ports_recurse $PORTS_WE_WANT
+
+ # Now checksump/fetch them
+ for p in `cat /tmp/_.plist`
+ do
+ b=`echo $p | tr / _`
+ (
+ cd $p
+ if make checksum $PORTS_OPTS ; then
+ true
+ else
+ make distclean
+ make checksum $PORTS_OPTS || true
+ fi
+ ) > /mnt/_.prefetch.$b 2>&1
+ done
+ )
+)
+
+#######################################################################
+
+do_world=true
+do_kernel=true
+use_pkg=""
+c_arg=""
+
+set +e
+args=`getopt bc:hkpw $*`
+if [ $? -ne 0 ] ; then
+ usage
+fi
+set -e
+
+set -- $args
+for i
+do
+ case "$i"
+ in
+ -b)
+ shift;
+ do_world=false
+ do_kernel=false
+ ;;
+ -c)
+ c_arg=$2
+ if [ ! -f "$c_arg" ] ; then
+ echo "Cannot read $c_arg" 1>&2
+ usage
+ fi
+ . "$2"
+ shift
+ shift
+ ;;
+ -h)
+ usage
+ ;;
+ -k)
+ shift;
+ do_kernel=false
+ ;;
+ -p)
+ shift;
+ use_pkg="-p"
+ ;;
+ -w)
+ shift;
+ do_world=false
+ ;;
+ --)
+ shift
+ break;
+ ;;
+ esac
+done
+
+#######################################################################
+
+if [ "x$1" = "xchroot_script" ] ; then
+ set +x
+ set -e
+
+ shift
+
+ before_ports_chroot
+
+ ports_build
+
+ exit 0
+fi
+
+if [ "x$1" = "xfinal_chroot" ] ; then
+ final_chroot
+ exit 0
+fi
+
+if [ $# -gt 0 ] ; then
+ echo "$0: Extraneous arguments supplied"
+ usage
+fi
+
+#######################################################################
+
+T0=`date +%s`
+echo $T0 $T0 > /tmp/_sb_log
+
+log_it Unmount everything
+(
+ ( cleanup )
+ umount /freebsd/distfiles || true
+ umount /mnt/freebsd/distfiles || true
+ umount /dev/${FREEBSD_PART} || true
+ umount /mnt/freebsd || true
+ umount /mnt/dev || true
+ umount /mnt || true
+ umount /dev/${TARGET_PART} || true
+) # > /dev/null 2>&1
+
+log_it Prepare running image
+mkdir -p /freebsd
+mount /dev/${FREEBSD_PART} /freebsd
+
+#######################################################################
+
+if [ ! -d /freebsd/${PORTS_PATH} ] ; then
+ echo PORTS_PATH does not exist 1>&2
+ exit 1
+fi
+
+if [ ! -d /freebsd/${SRC_PATH} ] ; then
+ echo SRC_PATH does not exist 1>&2
+ exit 1
+fi
+
+log_it TARGET_PART $TARGET_PART
+sleep 5
+
+rm -rf /usr/ports
+ln -s /freebsd/${PORTS_PATH} /usr/ports
+
+rm -rf /usr/src
+ln -s /freebsd/${SRC_PATH} /usr/src
+
+if $do_world ; then
+ if [ "x${OBJ_PATH}" != "x" ] ; then
+ rm -rf /usr/obj
+ mkdir -p /freebsd/${OBJ_PATH}
+ ln -s /freebsd/${OBJ_PATH} /usr/obj
+ else
+ rm -rf /usr/obj
+ mkdir -p /usr/obj
+ fi
+fi
+
+#######################################################################
+
+for i in ${PORTS_WE_WANT}
+do
+ if [ ! -d $i ] ; then
+ echo "Port $i not found" 1>&2
+ exit 2
+ fi
+done
+
+export PORTS_WE_WANT
+export PORTS_OPTS
+
+#######################################################################
+
+log_it Prepare destination partition
+newfs -O2 -U /dev/${TARGET_PART} > /dev/null
+mount /dev/${TARGET_PART} /mnt
+mkdir -p /mnt/dev
+mount -t devfs devfs /mnt/dev
+
+if [ "x${REMOTEDISTFILES}" != "x" ] ; then
+ rm -rf /freebsd/${PORTS_PATH}/distfiles
+ ln -s /freebsd/distfiles /freebsd/${PORTS_PATH}/distfiles
+ mkdir -p /freebsd/distfiles
+ mount ${REMOTEDISTFILES} /freebsd/distfiles
+fi
+
+log_it "Start prefetch of ports distfiles"
+ports_prefetch &
+
+if $do_world ; then
+ (
+ cd /usr/src
+ log_it "Buildworld"
+ make ${JARG} -s buildworld ${SRCCONF} > /mnt/_.bw 2>&1
+ )
+fi
+
+if $do_kernel ; then
+ (
+ cd /usr/src
+ log_it "Buildkernel"
+ make ${JARG} -s buildkernel KERNCONF=$KERNCONF > /mnt/_.bk 2>&1
+ )
+fi
+
+
+log_it Installworld
+(cd /usr/src && make ${JARG} installworld DESTDIR=/mnt ${SRCCONF} ) \
+ > /mnt/_.iw 2>&1
+
+log_it distribution
+(cd /usr/src/etc && make -m /usr/src/share/mk distribution \
+ DESTDIR=/mnt ${SRCCONF} ) \
+ > /mnt/_.dist 2>&1
+
+log_it Installkernel
+(cd /usr/src && make ${JARG} installkernel DESTDIR=/mnt KERNCONF=$KERNCONF ) \
+ > /mnt/_.ik 2>&1
+
+if [ "x${OBJ_PATH}" != "x" ] ; then
+ rmdir /mnt/usr/obj
+ ln -s /freebsd/${OBJ_PATH} /mnt/usr/obj
+fi
+
+log_it Wait for ports prefetch
+wait
+
+log_it Move filesystems
+
+if [ "x${REMOTEDISTFILES}" != "x" ] ; then
+ umount /freebsd/distfiles
+fi
+umount /dev/${FREEBSD_PART} || true
+mkdir -p /mnt/freebsd
+mount /dev/${FREEBSD_PART} /mnt/freebsd
+if [ "x${REMOTEDISTFILES}" != "x" ] ; then
+ mount ${REMOTEDISTFILES} /mnt/freebsd/distfiles
+fi
+
+rm -rf /mnt/usr/ports || true
+ln -s /freebsd/${PORTS_PATH} /mnt/usr/ports
+
+rm -rf /mnt/usr/src || true
+ln -s /freebsd/${SRC_PATH} /mnt/usr/src
+
+log_it Build and install ports
+
+# Make sure fetching will work in the chroot
+if [ -f /etc/resolv.conf ] ; then
+ log_it copy resolv.conf
+ cp /etc/resolv.conf /mnt/etc
+ chflags schg /mnt/etc/resolv.conf
+fi
+
+if [ -f /etc/localtime ] ; then
+ log_it copy localtime
+ cp /etc/localtime /mnt/etc
+fi
+
+log_it copy ports config files
+(cd / ; find var/db/ports -print | cpio -dumpv /mnt )
+
+log_it ldconfig in chroot
+chroot /mnt sh /etc/rc.d/ldconfig start
+
+log_it before_ports
+(
+ before_ports
+)
+
+log_it build ports
+pwd
+cp $0 /mnt/root
+cp /tmp/_sb_log /mnt/tmp
+b=`basename $0`
+if [ "x$c_arg" != "x" ] ; then
+ cp $c_arg /mnt/root
+ chroot /mnt sh /root/$0 -c /root/`basename $c_arg` $use_pkg chroot_script
+else
+ chroot /mnt sh /root/$0 $use_pkg chroot_script
+fi
+cp /mnt/tmp/_sb_log /tmp
+
+log_it fixing fstab
+sed "/[ ]\/[ ]/s;^[^ ]*[ ];/dev/${TARGET_PART} ;" \
+ /etc/fstab > /mnt/etc/fstab
+
+log_it create all mountpoints
+grep -v '^[ ]*#' /mnt/etc/fstab |
+while read a b c
+do
+ mkdir -p /mnt/$b
+done
+
+if [ "x$SERCONS" != "xfalse" ] ; then
+ log_it serial console
+ echo " -h" > /mnt/boot.config
+ sed -i "" -e /ttyd0/s/off/on/ /mnt/etc/ttys
+ sed -i "" -e /ttyu0/s/off/on/ /mnt/etc/ttys
+ sed -i "" -e '/^ttyv[0-8]/s/ on/ off/' /mnt/etc/ttys
+fi
+
+log_it move config files
+(cd / && find ${CONFIGFILES} -print | cpio -dumpv /mnt)
+
+log_it final_root
+( final_root )
+log_it final_chroot
+cp /tmp/_sb_log /mnt/tmp
+if [ "x$c_arg" != "x" ] ; then
+ chroot /mnt sh /root/$0 -c /root/`basename $c_arg` final_chroot
+else
+ chroot /mnt sh /root/$0 final_chroot
+fi
+cp /mnt/tmp/_sb_log /tmp
+log_it "Check these messages (if any):"
+grep '^Stop' /mnt/_* || true
+log_it DONE
diff --git a/tools/tools/usb/print-usb-if-vids.sh b/tools/tools/usb/print-usb-if-vids.sh
index ffe8693..17d8e05 100644
--- a/tools/tools/usb/print-usb-if-vids.sh
+++ b/tools/tools/usb/print-usb-if-vids.sh
@@ -27,5 +27,5 @@
# $FreeBSD$
-fetch -o /tmp/usb.if http://www.usb.org/app/pub/dump/comp_dump/
+fetch -o /tmp/usb.if http://www.usb.org/developers/tools/comp_dump/
awk -F '|' '{ printf "%#06x\t%s\n", $1, $2 }' < /tmp/usb.if | sort
diff --git a/usr.bin/basename/basename.1 b/usr.bin/basename/basename.1
index b2ad95d..05900fa 100644
--- a/usr.bin/basename/basename.1
+++ b/usr.bin/basename/basename.1
@@ -52,6 +52,7 @@
.Op Ar ...
.Nm dirname
.Ar string
+.Op Ar ...
.Sh DESCRIPTION
The
.Nm
diff --git a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c
index 314149e..4e0d04b 100644
--- a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c
+++ b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c
@@ -281,22 +281,8 @@ main(int argc, char *argv[])
}
/* Became daemon if required */
- if (background) {
- switch (fork()) {
- case -1:
- err(1, "Could not fork()");
- /* NOT REACHED */
-
- case 0:
- exit(0);
- /* NOT REACHED */
-
- default:
- if (daemon(0, 0) < 0)
- err(1, "Could not daemon()");
- break;
- }
- }
+ if (background && daemon(0, 0) < 0)
+ err(1, "Could not daemon()");
openlog(SPPD_IDENT, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_DAEMON);
syslog(LOG_INFO, "Starting on %s...", (tty != NULL)? tty : "stdin/stdout");
diff --git a/usr.bin/csplit/csplit.1 b/usr.bin/csplit/csplit.1
index 0f389a2..58e58d8 100644
--- a/usr.bin/csplit/csplit.1
+++ b/usr.bin/csplit/csplit.1
@@ -51,22 +51,39 @@ a dash
.Nm
reads from standard input.
.Pp
+Files are created with a prefix of
+.Dq xx
+and two decimal digits.
+The size of each file is written to standard output
+as it is created.
+If an error occurs whilst files are being created,
+or a
+.Dv HUP ,
+.Dv INT ,
+or
+.Dv TERM
+signal is received,
+all files previously written are removed.
+.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl f Ar prefix
-Give created files names beginning with
-.Ar prefix .
-The default is
+Create file names beginning with
+.Ar prefix ,
+instead of
.Dq Pa xx .
.It Fl k
-Do not remove output files.
+Do not remove previously created files if an error occurs or a
+.Dv HUP ,
+.Dv INT ,
+or
+.Dv TERM
+signal is received.
.It Fl n Ar number
-Use
+Create file names beginning with
.Ar number
-of decimal digits after the
-.Ar prefix
-to form the file name.
-The default is 2.
+of decimal digits after the prefix,
+instead of 2.
.It Fl s
Do not write the size of each output file to standard output as it is
created.
diff --git a/usr.bin/csup/Makefile b/usr.bin/csup/Makefile
index b37e261..37536fa 100644
--- a/usr.bin/csup/Makefile
+++ b/usr.bin/csup/Makefile
@@ -13,6 +13,7 @@ SRCS= attrstack.c \
globtree.c \
idcache.c \
keyword.c \
+ lex.rcs.c \
lister.c \
main.c \
misc.c \
@@ -20,6 +21,9 @@ SRCS= attrstack.c \
parse.y \
pathcomp.c \
proto.c \
+ rcsfile.c \
+ rcsparse.c \
+ rsyncfile.c \
status.c \
stream.c \
threads.c \
@@ -28,7 +32,7 @@ SRCS= attrstack.c \
CFLAGS+= -I. -I${.CURDIR}/../../contrib/csup
CFLAGS+= -DHAVE_FFLAGS -DNDEBUG
-WARNS?= 6
+WARNS?= 1
DPADD= ${LIBCRYPTO} ${LIBZ} ${LIBPTHREAD}
LDADD= -lcrypto -lz -lpthread
diff --git a/usr.bin/dirname/dirname.c b/usr.bin/dirname/dirname.c
index 3018f2f..93b135d 100644
--- a/usr.bin/dirname/dirname.c
+++ b/usr.bin/dirname/dirname.c
@@ -66,12 +66,15 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
- if (argc != 1)
+ if (argc < 1)
usage();
- if ((p = dirname(*argv)) == NULL)
- err(1, "%s", *argv);
- (void)printf("%s\n", p);
+ while (argc--) {
+ if ((p = dirname(*argv)) == NULL)
+ err(1, "%s", *argv);
+ argv++;
+ (void)printf("%s\n", p);
+ }
exit(0);
}
@@ -79,6 +82,6 @@ void
usage(void)
{
- (void)fprintf(stderr, "usage: dirname string\n");
+ (void)fprintf(stderr, "usage: dirname string [...]\n");
exit(1);
}
diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c
index bc5268c..2512a2e 100644
--- a/usr.bin/fetch/fetch.c
+++ b/usr.bin/fetch/fetch.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <fetch.h>
#define MINBUFSIZE 4096
+#define TIMEOUT 120
/* Option flags */
int A_flag; /* -A: do not follow 302 redirects */
@@ -75,7 +76,7 @@ int R_flag; /* -R: don't delete partially transferred files */
int r_flag; /* -r: restart previously interrupted transfer */
off_t S_size; /* -S: require size to match */
int s_flag; /* -s: show size, don't fetch */
-long T_secs = 120; /* -T: transfer timeout in seconds */
+long T_secs; /* -T: transfer timeout in seconds */
int t_flag; /*! -t: workaround TCP bug */
int U_flag; /* -U: do not use high ports */
int v_level = 1; /* -v: verbosity level */
@@ -88,8 +89,8 @@ int sigalrm; /* SIGALRM received */
int siginfo; /* SIGINFO received */
int sigint; /* SIGINT received */
-long ftp_timeout; /* default timeout for FTP transfers */
-long http_timeout; /* default timeout for HTTP transfers */
+long ftp_timeout = TIMEOUT; /* default timeout for FTP transfers */
+long http_timeout = TIMEOUT; /* default timeout for HTTP transfers */
char *buf; /* transfer buffer */
diff --git a/usr.bin/fstat/zfs.c b/usr.bin/fstat/zfs.c
index c5508eb..fc23261 100644
--- a/usr.bin/fstat/zfs.c
+++ b/usr.bin/fstat/zfs.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#define _KERNEL
#include <sys/mount.h>
#undef _KERNEL
diff --git a/usr.bin/gprof/gprof.c b/usr.bin/gprof/gprof.c
index cfb9fab..dc9e8a5 100644
--- a/usr.bin/gprof/gprof.c
+++ b/usr.bin/gprof/gprof.c
@@ -165,7 +165,7 @@ main(argc, argv)
* get information from the executable file.
*/
if ((Kflag && kernel_getnfile(a_outname, &defaultEs) == -1) ||
- (elf_getnfile(a_outname, &defaultEs) == -1 &&
+ (!Kflag && elf_getnfile(a_outname, &defaultEs) == -1 &&
aout_getnfile(a_outname, &defaultEs) == -1))
errx(1, "%s: bad format", a_outname);
/*
diff --git a/usr.bin/mail/Makefile b/usr.bin/mail/Makefile
index 491d06f..5fa455b 100644
--- a/usr.bin/mail/Makefile
+++ b/usr.bin/mail/Makefile
@@ -2,9 +2,9 @@
# $FreeBSD$
PROG= mail
-SRCS= version.c aux.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c edit.c fio.c \
+SRCS= version.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c edit.c fio.c \
getname.c head.c v7.local.c lex.c list.c main.c names.c popen.c \
- quit.c send.c strings.c temp.c tty.c vars.c
+ quit.c send.c strings.c temp.c tty.c util.c vars.c
FILES= mail.help mail.tildehelp
FILESDIR= ${SHAREDIR}/misc
EFILES= mail.rc
diff --git a/usr.bin/mail/aux.c b/usr.bin/mail/util.c
index e764aac..e764aac 100644
--- a/usr.bin/mail/aux.c
+++ b/usr.bin/mail/util.c
diff --git a/usr.bin/make/Makefile b/usr.bin/make/Makefile
index e5be06d..deb076f 100644
--- a/usr.bin/make/Makefile
+++ b/usr.bin/make/Makefile
@@ -8,7 +8,6 @@ SRCS= arch.c buf.c cond.c dir.c for.c hash.c hash_tables.c job.c \
lst.c main.c make.c parse.c proc.c shell.c str.c suff.c targ.c \
util.c var.c
-NO_WERROR=
WARNS?= 6
NO_SHARED?= YES
diff --git a/usr.bin/make/buf.c b/usr.bin/make/buf.c
index 6453abf..7c6c01f 100644
--- a/usr.bin/make/buf.c
+++ b/usr.bin/make/buf.c
@@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$");
* Returns the number of bytes in the buffer. Doesn't include the
* null-terminating byte.
*/
-inline size_t
+size_t
Buf_Size(const Buffer *buf)
{
@@ -70,7 +70,7 @@ Buf_Size(const Buffer *buf)
*
* @note Adding data to the Buffer object may invalidate the reference.
*/
-inline char *
+char *
Buf_Data(const Buffer *bp)
{
@@ -98,7 +98,7 @@ BufExpand(Buffer *bp, size_t nb)
/**
* Add a single byte to the buffer.
*/
-inline void
+void
Buf_AddByte(Buffer *bp, Byte byte)
{
diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c
index b035238..8df5471 100644
--- a/usr.bin/make/for.c
+++ b/usr.bin/make/for.c
@@ -254,7 +254,7 @@ For_Run(int lineno)
LST_FOREACH(ln, &values) {
val = Lst_Datum(ln);
- Var_Set(var, val, VAR_GLOBAL);
+ Var_SetGlobal(var, val);
DEBUGF(FOR, ("--- %s = %s\n", var, val));
str = Buf_Peel(Var_SubstOnly(var, Buf_Data(buf), FALSE));
diff --git a/usr.bin/make/globals.h b/usr.bin/make/globals.h
index 5e42a4a..c2e1f11 100644
--- a/usr.bin/make/globals.h
+++ b/usr.bin/make/globals.h
@@ -76,6 +76,7 @@ extern Boolean compatMake; /* True if we are make compatible */
extern Boolean ignoreErrors; /* True if should ignore all errors */
extern Boolean beSilent; /* True if should print no commands */
extern Boolean beVerbose; /* True if should print extra cruft */
+extern Boolean beQuiet; /* True if want quiet headers with -j */
extern Boolean noExecute; /* True if should execute nothing */
extern Boolean allPrecious; /* True if every target is precious */
extern Boolean is_posix; /* .POSIX target seen */
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index 7cc575e..e722010 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -321,10 +321,11 @@ static GNode *lastNode; /* The node for which output was most recently
static const char *targFmt; /* Format string to use to head output from a
* job when it's not the most-recent job heard
* from */
+static char *targPrefix = NULL; /* What we print at the start of targFmt */
-#define TARG_FMT "--- %s ---\n" /* Default format */
+#define TARG_FMT "%s %s ---\n" /* Default format */
#define MESSAGE(fp, gn) \
- fprintf(fp, targFmt, gn->name);
+ fprintf(fp, targFmt, targPrefix, gn->name);
/*
* When JobStart attempts to run a job but isn't allowed to
@@ -2283,6 +2284,18 @@ Job_Make(GNode *gn)
JobStart(gn, 0, NULL);
}
+void
+Job_SetPrefix(void)
+{
+
+ if (targPrefix) {
+ free(targPrefix);
+ } else if (!Var_Exists(MAKE_JOB_PREFIX, VAR_GLOBAL)) {
+ Var_SetGlobal(MAKE_JOB_PREFIX, "---");
+ }
+ targPrefix = Var_Subst("${" MAKE_JOB_PREFIX "}", VAR_GLOBAL, 0)->buf;
+}
+
/**
* Job_Init
* Initialize the process module, given a maximum number of jobs.
@@ -2349,8 +2362,7 @@ Job_Init(int maxproc)
makeErrors = 0;
lastNode = NULL;
-
- if ((maxJobs == 1 && fifoFd < 0) || beVerbose == 0) {
+ if ((maxJobs == 1 && fifoFd < 0) || !beVerbose || is_posix || beQuiet) {
/*
* If only one job can run at a time, there's no need for a
* banner, no is there?
diff --git a/usr.bin/make/job.h b/usr.bin/make/job.h
index 57c99de..31e1cb7 100644
--- a/usr.bin/make/job.h
+++ b/usr.bin/make/job.h
@@ -67,6 +67,7 @@ Boolean Job_Empty(void);
void Job_Finish(void);
void Job_Wait(void);
void Job_AbortAll(void);
+void Job_SetPrefix(void);
void Proc_Init(void);
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 7ba0bae..6ccc59b 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -126,6 +126,7 @@ Boolean is_posix; /* .POSIX target seen */
Boolean mfAutoDeps; /* .MAKEFILEDEPS target seen */
Boolean beSilent; /* -s flag */
Boolean beVerbose; /* -v flag */
+Boolean beQuiet; /* -Q flag */
Boolean compatMake; /* -B argument */
int debug; /* -d flag */
Boolean ignoreErrors; /* -i flag */
@@ -370,7 +371,7 @@ MainParseArgs(int argc, char **argv)
rearg:
optind = 1; /* since we're called more than once */
optreset = 1;
-#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:npqrstvx:"
+#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:"
for (;;) {
if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
found_dd = TRUE;
@@ -384,6 +385,11 @@ rearg:
arch_fatal = FALSE;
MFLAGS_append("-A", NULL);
break;
+ case 'B':
+ compatMake = TRUE;
+ MFLAGS_append("-B", NULL);
+ unsetenv("MAKE_JOBS_FIFO");
+ break;
case 'C':
if (chdir(optarg) == -1)
err(1, "chdir %s", optarg);
@@ -392,30 +398,6 @@ rearg:
Var_SetGlobal(optarg, "1");
MFLAGS_append("-D", optarg);
break;
- case 'I':
- Parse_AddIncludeDir(optarg);
- MFLAGS_append("-I", optarg);
- break;
- case 'V':
- Lst_AtEnd(&variables, estrdup(optarg));
- MFLAGS_append("-V", optarg);
- break;
- case 'X':
- expandVars = FALSE;
- break;
- case 'B':
- compatMake = TRUE;
- MFLAGS_append("-B", NULL);
- unsetenv("MAKE_JOBS_FIFO");
- break;
- case 'P':
- usePipes = FALSE;
- MFLAGS_append("-P", NULL);
- break;
- case 'S':
- keepgoing = FALSE;
- MFLAGS_append("-S", NULL);
- break;
case 'd': {
char *modules = optarg;
@@ -483,6 +465,10 @@ rearg:
case 'f':
Lst_AtEnd(&makefiles, estrdup(optarg));
break;
+ case 'I':
+ Parse_AddIncludeDir(optarg);
+ MFLAGS_append("-I", optarg);
+ break;
case 'i':
ignoreErrors = TRUE;
MFLAGS_append("-i", NULL);
@@ -512,10 +498,19 @@ rearg:
noExecute = TRUE;
MFLAGS_append("-n", NULL);
break;
+ case 'P':
+ usePipes = FALSE;
+ MFLAGS_append("-P", NULL);
+ break;
case 'p':
printGraphOnly = TRUE;
debug |= DEBUG_GRAPH1;
break;
+ case 'Q':
+ beQuiet = TRUE;
+ beVerbose = FALSE;
+ MFLAGS_append("-Q", NULL);
+ break;
case 'q':
queryFlag = TRUE;
/* Kind of nonsensical, wot? */
@@ -525,6 +520,10 @@ rearg:
noBuiltins = TRUE;
MFLAGS_append("-r", NULL);
break;
+ case 'S':
+ keepgoing = FALSE;
+ MFLAGS_append("-S", NULL);
+ break;
case 's':
beSilent = TRUE;
MFLAGS_append("-s", NULL);
@@ -533,10 +532,18 @@ rearg:
touchFlag = TRUE;
MFLAGS_append("-t", NULL);
break;
+ case 'V':
+ Lst_AtEnd(&variables, estrdup(optarg));
+ MFLAGS_append("-V", optarg);
+ break;
case 'v':
beVerbose = TRUE;
+ beQuiet = FALSE;
MFLAGS_append("-v", NULL);
break;
+ case 'X':
+ expandVars = FALSE;
+ break;
case 'x':
if (Main_ParseWarn(optarg, 1) != -1)
MFLAGS_append("-x", optarg);
@@ -1029,6 +1036,16 @@ main(int argc, char **argv)
#ifdef MAKE_VERSION
Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
#endif
+ Var_SetGlobal(".newline", "\n"); /* handy for :@ loops */
+ {
+ char tmp[64];
+
+ snprintf(tmp, sizeof(tmp), "%u", getpid());
+ Var_SetGlobal(".MAKE.PID", tmp);
+ snprintf(tmp, sizeof(tmp), "%u", getppid());
+ Var_SetGlobal(".MAKE.PPID", tmp);
+ }
+ Job_SetPrefix();
/*
* First snag things out of the MAKEFLAGS environment
diff --git a/usr.bin/make/make.1 b/usr.bin/make/make.1
index cd9d913..736f279 100644
--- a/usr.bin/make/make.1
+++ b/usr.bin/make/make.1
@@ -32,7 +32,7 @@
.\" @(#)make.1 8.8 (Berkeley) 6/13/95
.\" $FreeBSD$
.\"
-.Dd December 26, 2008
+.Dd December 29, 2008
.Dt MAKE 1
.Os
.Sh NAME
@@ -258,6 +258,9 @@ When combined with
only the builtin rules of
.Nm
are displayed.
+.It Fl Q
+Be extra quiet.
+For multi-job makes, this will cause file banners not to be generated.
.It Fl q
Do not execute any commands, but exit 0 if the specified targets are
up-to-date and 1, otherwise.
@@ -289,7 +292,7 @@ the variables will be printed one per line,
with a blank line for each null or undefined variable.
.It Fl v
Be extra verbose.
-For multi-job makes, this will cause file banners to be generated.
+Print any extra information.
.It Fl X
When using the
.Fl V
@@ -763,6 +766,31 @@ contains all the options from the
environment variable plus any options specified on
.Nm Ns 's
command line.
+.It Va .MAKE.PID
+The process-id of
+.Nm .
+.It Va .MAKE.PPID
+The parent process-id of
+.Nm .
+.It Va .MAKE.JOB.PREFIX
+If
+.Nm
+is run with
+.Fl j Fl v
+then output for each target is prefixed with a token
+.Ql --- target ---
+the first part of which can be controlled via
+.Va .MAKE.JOB.PREFIX .
+.br
+For example:
+.Li .MAKE.JOB.PREFIX=${.newline}---${MAKE:T}[${.MAKE.PID}]
+would produce tokens like
+.Ql ---make[1234] target ---
+or
+.Li .MAKE.JOB.PREFIX=---pid[${.MAKE.PID}],ppid[${.MAKE.PPID}]
+would produce tokens like
+.Ql ---pid[56789],ppid[1234] target ---
+making it easier to track the degree of parallelism being achieved.
.It Va .TARGETS
List of targets
.Nm
diff --git a/usr.bin/make/make.h b/usr.bin/make/make.h
index 2386cd7..6e2813d 100644
--- a/usr.bin/make/make.h
+++ b/usr.bin/make/make.h
@@ -49,6 +49,8 @@
#include "util.h"
+#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX"
+
struct GNode;
struct Lst;
struct Buffer;
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index 3e8cb93..2c65164 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -1076,7 +1076,7 @@ ParseDoDependency(char *line)
break;
case Posix:
is_posix = TRUE;
- Var_Set("%POSIX", "1003.2", VAR_GLOBAL);
+ Var_SetGlobal("%POSIX", "1003.2");
break;
default:
break;
@@ -1533,6 +1533,8 @@ Parse_DoVar(char *line, GNode *ctxt)
*/
Var_Set(line, cp, ctxt);
}
+ if (strcmp(line, MAKE_JOB_PREFIX) == 0)
+ Job_SetPrefix();
}
/*-
diff --git a/usr.bin/make/suff.c b/usr.bin/make/suff.c
index 7aa96f6..bed6c7a 100644
--- a/usr.bin/make/suff.c
+++ b/usr.bin/make/suff.c
@@ -514,6 +514,7 @@ Suff_AddTransform(char *line)
Suff *s; /* source suffix */
Suff *t; /* target suffix */
+ s = t = NULL; /* silence gcc */
gn = SuffTransFind(line);
if (gn == NULL) {
/*
@@ -785,11 +786,11 @@ Suff_DoPaths(void)
}
ptr = Path_MakeFlags("-I", &inIncludes);
- Var_Set(".INCLUDES", ptr, VAR_GLOBAL);
+ Var_SetGlobal(".INCLUDES", ptr);
free(ptr);
ptr = Path_MakeFlags("-L", &inLibs);
- Var_Set(".LIBS", ptr, VAR_GLOBAL);
+ Var_SetGlobal(".LIBS", ptr);
free(ptr);
Path_Clear(&inIncludes);
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 259a672..983bb2a 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -946,12 +946,14 @@ VarFindAny(const char name[], GNode *ctxt)
* The name and val arguments are duplicated so they may
* safely be freed.
*/
-static void
+static Var *
VarAdd(const char *name, const char *val, GNode *ctxt)
{
+ Var *v;
- Lst_AtFront(&ctxt->context, VarCreate(name, val, 0));
+ Lst_AtFront(&ctxt->context, v = VarCreate(name, val, 0));
DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
+ return (v);
}
/**
@@ -1004,30 +1006,22 @@ Var_Set(const char *name, const char *val, GNode *ctxt)
n = VarPossiblyExpand(name, ctxt);
v = VarFindOnly(n, ctxt);
if (v == NULL) {
- VarAdd(n, val, ctxt);
- if (ctxt == VAR_CMD) {
- /*
- * Any variables given on the command line
- * are automatically exported to the
- * environment (as per POSIX standard)
- */
- setenv(n, val, 1);
- }
+ v = VarAdd(n, val, ctxt);
} else {
Buf_Clear(v->val);
Buf_Append(v->val, val);
-
- if (ctxt == VAR_CMD || (v->flags & VAR_TO_ENV)) {
- /*
- * Any variables given on the command line
- * are automatically exported to the
- * environment (as per POSIX standard)
- */
- setenv(n, val, 1);
- }
DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, val));
}
+ if (ctxt == VAR_CMD || (v->flags & VAR_TO_ENV)) {
+ /*
+ * Any variables given on the command line
+ * are automatically exported to the
+ * environment (as per POSIX standard)
+ */
+ setenv(n, val, 1);
+ }
+
free(n);
}
diff --git a/usr.bin/netstat/inet6.c b/usr.bin/netstat/inet6.c
index 561ce6a..83a31c7f 100644
--- a/usr.bin/netstat/inet6.c
+++ b/usr.bin/netstat/inet6.c
@@ -512,8 +512,6 @@ ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
}
}
- p1a(ip6s_forward_cachehit, "\t%ju forward cache hit\n");
- p1a(ip6s_forward_cachemiss, "\t%ju forward cache miss\n");
printf("\tSource addresses selection rule applied:\n");
for (i = 0; i < 16; i++) {
if (ip6stat.ip6s_sources_rule[i])
@@ -866,7 +864,8 @@ icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
#define p(f, m) if (icmp6stat.f || sflag <= 1) \
printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
-#define p_5(f, m) printf(m, (uintmax_t)icmp6stat.f)
+#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
+ printf(m, (uintmax_t)icmp6stat.f)
p(icp6s_error, "\t%ju call%s to icmp6_error\n");
p(icp6s_canterror,
diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c
index 1f2f0e1..642a63b 100644
--- a/usr.bin/netstat/main.c
+++ b/usr.bin/netstat/main.c
@@ -507,7 +507,7 @@ main(int argc, char *argv[])
exit(0);
}
if (mflag) {
- if (memf != NULL) {
+ if (!live) {
if (kread(0, NULL, 0) == 0)
mbpr(kvmd, nl[N_MBSTAT].n_value);
} else
@@ -593,7 +593,7 @@ main(int argc, char *argv[])
for (tp = netgraphprotox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
#endif /* NETGRAPH */
- if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag)
+ if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value);
exit(0);
@@ -770,17 +770,18 @@ static void
usage(void)
{
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
-"usage: netstat [-AaLnSW] [-f protocol_family | -p protocol]\n"
+"usage: netstat [-AaLnSWx] [-f protocol_family | -p protocol]\n"
" [-M core] [-N system]",
-" netstat -i | -I interface [-abdhnt] [-f address_family]\n"
+" netstat -i | -I interface [-abdhntW] [-f address_family]\n"
" [-M core] [-N system]",
" netstat -w wait [-I interface] [-d] [-M core] [-N system]",
-" netstat -s [-s] [-z] [-f protocol_family | -p protocol] [-M core]",
+" netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n"
+" [-M core] [-N system]",
" netstat -i | -I interface -s [-f protocol_family | -p protocol]\n"
" [-M core] [-N system]",
" netstat -m [-M core] [-N system]",
-" netstat -B [ -I interface]",
-" netstat -r [-AenW] [-f address_family] [-M core] [-N system]",
+" netstat -B [-I interface]",
+" netstat -r [-AanW] [-f address_family] [-M core] [-N system]",
" netstat -rs [-s] [-M core] [-N system]",
" netstat -g [-W] [-f address_family] [-M core] [-N system]",
" netstat -gs [-s] [-f address_family] [-M core] [-N system]");
diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1
index de87477..e4b9117 100644
--- a/usr.bin/netstat/netstat.1
+++ b/usr.bin/netstat/netstat.1
@@ -32,7 +32,7 @@
.\" @(#)netstat.1 8.8 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd June 10, 2007
+.Dd May 16, 2008
.Dt NETSTAT 1
.Os
.Sh NAME
@@ -460,12 +460,15 @@ For more information about these flags, please refer to
.Pp
The
.Fl x
-flag causes netstat to output all the information recorded about data
-stored in the socket buffers. The fields are:
+flag causes
+.Nm
+to output all the information recorded about data
+stored in the socket buffers.
+The fields are:
.Bl -column ".Li R-MBUF"
.It Li R-MBUF Ta Number of mbufs in the receive queue.
.It Li S-MBUF Ta Number of mbufs in the send queue.
-.It Li R-CLUS Ta Number of clusters, of any type, in the recieve
+.It Li R-CLUS Ta Number of clusters, of any type, in the receive
queue.
.It Li S-CLUS Ta Number of clusters, of any type, in the send queue.
.It Li R-HIWA Ta Receive buffer high water mark, in bytes.
diff --git a/usr.bin/netstat/unix.c b/usr.bin/netstat/unix.c
index 0778bac..209fc8d 100644
--- a/usr.bin/netstat/unix.c
+++ b/usr.bin/netstat/unix.c
@@ -247,6 +247,7 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
struct unpcb *unp;
struct sockaddr_un *sa;
static int first = 1;
+ char buf1[15];
unp = &xunp->xu_unp;
if (unp->unp_addr)
@@ -254,7 +255,7 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
else
sa = (struct sockaddr_un *)0;
- if (first) {
+ if (first && !Lflag) {
printf("Active UNIX domain sockets\n");
printf(
"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
@@ -262,11 +263,21 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
"Inode", "Conn", "Refs", "Nextref");
first = 0;
}
- printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx",
- (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
- so->so_snd.sb_cc,
- (long)unp->unp_vnode, (long)unp->unp_conn,
- (long)LIST_FIRST(&unp->unp_refs), (long)LIST_NEXT(unp, unp_reflink));
+
+ if (Lflag && so->so_qlimit == 0)
+ return;
+
+ if (Lflag) {
+ snprintf(buf1, 15, "%d/%d/%d", so->so_qlen,
+ so->so_incqlen, so->so_qlimit);
+ printf("unix %-14.14s", buf1);
+ } else {
+ printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx",
+ (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
+ so->so_snd.sb_cc, (long)unp->unp_vnode, (long)unp->unp_conn,
+ (long)LIST_FIRST(&unp->unp_refs),
+ (long)LIST_NEXT(unp, unp_reflink));
+ }
if (sa)
printf(" %.*s",
(int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c
index 48f7051..bc02682 100644
--- a/usr.bin/procstat/procstat.c
+++ b/usr.bin/procstat/procstat.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_args.c b/usr.bin/procstat/procstat_args.c
index 84da1d8..e5a7acd 100644
--- a/usr.bin/procstat/procstat_args.c
+++ b/usr.bin/procstat/procstat_args.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_basic.c b/usr.bin/procstat/procstat_basic.c
index 7d7928c..2775172 100644
--- a/usr.bin/procstat/procstat_basic.c
+++ b/usr.bin/procstat/procstat_basic.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_bin.c b/usr.bin/procstat/procstat_bin.c
index 178d0a4..8ed5efe 100644
--- a/usr.bin/procstat/procstat_bin.c
+++ b/usr.bin/procstat/procstat_bin.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_cred.c b/usr.bin/procstat/procstat_cred.c
index 82ac6ad..a84924a 100644
--- a/usr.bin/procstat/procstat_cred.c
+++ b/usr.bin/procstat/procstat_cred.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c
index 74ec590..debb0e4 100644
--- a/usr.bin/procstat/procstat_files.c
+++ b/usr.bin/procstat/procstat_files.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/un.h>
diff --git a/usr.bin/procstat/procstat_kstack.c b/usr.bin/procstat/procstat_kstack.c
index bd7c34c..9d5f71e 100644
--- a/usr.bin/procstat/procstat_kstack.c
+++ b/usr.bin/procstat/procstat_kstack.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_threads.c b/usr.bin/procstat/procstat_threads.c
index 2f34012..64e0a36 100644
--- a/usr.bin/procstat/procstat_threads.c
+++ b/usr.bin/procstat/procstat_threads.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/procstat/procstat_vm.c b/usr.bin/procstat/procstat_vm.c
index 1873c4f..11b5ed1 100644
--- a/usr.bin/procstat/procstat_vm.c
+++ b/usr.bin/procstat/procstat_vm.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 627c958..2cc3de2 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -596,25 +596,25 @@ display(void)
continue;
pos = 0;
if ((pwd = getpwuid(xf->xf_uid)) == NULL)
- pos += xprintf("%lu", (u_long)xf->xf_uid);
+ pos += xprintf("%lu ", (u_long)xf->xf_uid);
else
- pos += xprintf("%s", pwd->pw_name);
+ pos += xprintf("%s ", pwd->pw_name);
while (pos < 9)
pos += xprintf(" ");
pos += xprintf("%.10s", getprocname(xf->xf_pid));
while (pos < 20)
pos += xprintf(" ");
- pos += xprintf("%lu", (u_long)xf->xf_pid);
+ pos += xprintf("%lu ", (u_long)xf->xf_pid);
while (pos < 26)
pos += xprintf(" ");
- pos += xprintf("%d", xf->xf_fd);
+ pos += xprintf("%d ", xf->xf_fd);
while (pos < 29)
pos += xprintf(" ");
pos += xprintf("%s", s->protoname);
if (s->vflag & INP_IPV4)
- pos += xprintf("4");
+ pos += xprintf("4 ");
if (s->vflag & INP_IPV6)
- pos += xprintf("6");
+ pos += xprintf("6 ");
while (pos < 36)
pos += xprintf(" ");
switch (s->family) {
diff --git a/usr.bin/split/split.1 b/usr.bin/split/split.1
index 7825219..e55bb87 100644
--- a/usr.bin/split/split.1
+++ b/usr.bin/split/split.1
@@ -32,7 +32,7 @@
.\" @(#)split.1 8.3 (Berkeley) 4/16/94
.\" $FreeBSD$
.\"
-.Dd March 16, 2008
+.Dd January 23, 2009
.Dt SPLIT 1
.Os
.Sh NAME
@@ -88,7 +88,7 @@ letters to form the suffix of the file name.
.Cm K | k | M | m | G | g
.Sm on
.Oc
-Create smaller files
+Create split files
.Ar byte_count
bytes in length.
If
@@ -113,7 +113,7 @@ is appended to the number, the file is split into
.Ar byte_count
gigabyte pieces.
.It Fl l Ar line_count
-Create smaller files
+Create split files
.Ar line_count
lines in length.
.It Fl n Ar chunk_count
diff --git a/usr.bin/truss/truss.1 b/usr.bin/truss/truss.1
index ddff08b..28e474e 100644
--- a/usr.bin/truss/truss.1
+++ b/usr.bin/truss/truss.1
@@ -1,6 +1,6 @@
.\" $FreeBSD$
.\"
-.Dd January 2, 2004
+.Dd January 22, 2009
.Dt TRUSS 1
.Os
.Sh NAME
@@ -85,7 +85,7 @@ options are mutually exclusive.)
# Do the same, but put the output into a file
.Dl $ truss -o /tmp/truss.out /bin/echo hello
# Follow an already-running process
-.Dl $ truss -p 1
+.Dl $ truss -p 34
.Sh SEE ALSO
.Xr kdump 1 ,
.Xr ktrace 1 ,
diff --git a/usr.bin/usbhidaction/usbhidaction.c b/usr.bin/usbhidaction/usbhidaction.c
index e0d459d..a3aa3c5 100644
--- a/usr.bin/usbhidaction/usbhidaction.c
+++ b/usr.bin/usbhidaction/usbhidaction.c
@@ -46,9 +46,7 @@
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
+#include <dev/usb2/include/usb2_hid.h>
#include <usbhid.h>
#include <syslog.h>
#include <signal.h>
@@ -155,8 +153,7 @@ main(int argc, char **argv)
fd = open(dev, O_RDWR);
if (fd < 0)
err(1, "%s", dev);
- if (ioctl(fd, USB_GET_REPORT_ID, &reportid) < 0)
- reportid = -1;
+ reportid = hid_get_report_id(fd);
repd = hid_get_report_desc(fd);
if (repd == NULL)
err(1, "hid_get_report_desc() failed");
diff --git a/usr.bin/usbhidctl/usbhid.c b/usr.bin/usbhidctl/usbhid.c
index ff7c544..917666e 100644
--- a/usr.bin/usbhidctl/usbhid.c
+++ b/usr.bin/usbhidctl/usbhid.c
@@ -42,14 +42,12 @@
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
-#include <sys/ioctl.h>
#include <unistd.h>
#include <err.h>
#include <ctype.h>
#include <errno.h>
#include <usbhid.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
+#include <dev/usb2/include/usb2_hid.h>
int verbose = 0;
int all = 0;
@@ -207,7 +205,6 @@ dumpdata(int f, report_desc_t rd, int loop)
struct hid_item h, *hids, *n;
int r, dlen;
u_char *dbuf;
- static int one = 1;
u_int32_t colls[100];
int sp = 0;
char namebuf[10000], *namep;
@@ -231,7 +228,7 @@ dumpdata(int f, report_desc_t rd, int loop)
dlen = hid_report_size(rd, hid_input, 0);
dbuf = malloc(dlen);
if (!loop)
- if (ioctl(f, USB_SET_IMMED, &one) < 0) {
+ if (hid_set_immed(f, 1) < 0) {
if (errno == EOPNOTSUPP)
warnx("device does not support immediate mode, only changes reported.");
else
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 26da845..5a4efcc 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -65,6 +65,7 @@ SUBDIR= ${_ac} \
getpmac \
gstat \
${_gssd} \
+ i2c \
ifmcstat \
inetd \
iostat \
diff --git a/usr.sbin/auditd/Makefile b/usr.sbin/auditd/Makefile
index 114d89c..839458d 100644
--- a/usr.sbin/auditd/Makefile
+++ b/usr.sbin/auditd/Makefile
@@ -8,10 +8,10 @@ OPENBSMDIR=${.CURDIR}/../../contrib/openbsm
CFLAGS+= -I${OPENBSMDIR}
PROG= auditd
-SRCS= auditd.c audit_warn.c
+SRCS= auditd.c audit_warn.c auditd_fbsd.c
MAN= auditd.8
-DPADD= ${LIBBSM}
-LDADD= -lbsm
+DPADD= ${LIBBSM} ${LIBAUDITD}
+LDADD= -lbsm -lauditd
.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/Makefile b/usr.sbin/bluetooth/Makefile
index ed6f83a..ad193d0 100644
--- a/usr.sbin/bluetooth/Makefile
+++ b/usr.sbin/bluetooth/Makefile
@@ -6,6 +6,7 @@ SUBDIR= \
bt3cfw \
bthidcontrol \
bthidd \
+ btpand \
hccontrol \
hcsecd \
hcseriald \
diff --git a/usr.sbin/bluetooth/btpand/Makefile b/usr.sbin/bluetooth/btpand/Makefile
new file mode 100644
index 0000000..5e4bb0b
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/Makefile
@@ -0,0 +1,13 @@
+# $NetBSD: Makefile,v 1.2 2008/08/18 08:25:32 plunky Exp $
+# $FreeBSD$
+
+PROG= btpand
+MAN= btpand.8
+SRCS= btpand.c bnep.c channel.c client.c event.c packet.c server.c sdp.c tap.c
+
+WARNS?= 3
+
+DPADD+= ${LIBBLUETOOTH} ${LIBSDP} ${LIBUTIL}
+LDADD+= -lbluetooth -lsdp -lutil
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/btpand/bnep.c b/usr.sbin/bluetooth/btpand/bnep.c
new file mode 100644
index 0000000..200a723
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/bnep.c
@@ -0,0 +1,755 @@
+/* $NetBSD: bnep.c,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: bnep.c,v 1.1 2008/08/17 13:20:57 plunky Exp $");
+
+#include <sys/uio.h>
+#include <bluetooth.h>
+#include <sdp.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "btpand.h"
+#include "bnep.h"
+
+static bool bnep_recv_extension(packet_t *);
+static size_t bnep_recv_control(channel_t *, uint8_t *, size_t, bool);
+static size_t bnep_recv_control_command_not_understood(channel_t *, uint8_t *, size_t);
+static size_t bnep_recv_setup_connection_req(channel_t *, uint8_t *, size_t);
+static size_t bnep_recv_setup_connection_rsp(channel_t *, uint8_t *, size_t);
+static size_t bnep_recv_filter_net_type_set(channel_t *, uint8_t *, size_t);
+static size_t bnep_recv_filter_net_type_rsp(channel_t *, uint8_t *, size_t);
+static size_t bnep_recv_filter_multi_addr_set(channel_t *, uint8_t *, size_t);
+static size_t bnep_recv_filter_multi_addr_rsp(channel_t *, uint8_t *, size_t);
+
+static bool bnep_pfilter(channel_t *, packet_t *);
+static bool bnep_mfilter(channel_t *, packet_t *);
+
+static uint8_t NAP_UUID[] = {
+ 0x00, 0x00, 0x11, 0x16,
+ 0x00, 0x00,
+ 0x10, 0x00,
+ 0x80, 0x00,
+ 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb
+};
+
+static uint8_t GN_UUID[] = {
+ 0x00, 0x00, 0x11, 0x17,
+ 0x00, 0x00,
+ 0x10, 0x00,
+ 0x80, 0x00,
+ 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb,
+};
+
+static uint8_t PANU_UUID[] = {
+ 0x00, 0x00, 0x11, 0x15,
+ 0x00, 0x00,
+ 0x10, 0x00,
+ 0x80, 0x00,
+ 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb
+};
+
+/*
+ * receive BNEP packet
+ * return true if packet is to be forwarded
+ */
+bool
+bnep_recv(packet_t *pkt)
+{
+ size_t len;
+ uint8_t type;
+
+ if (pkt->len < 1)
+ return false;
+
+ type = pkt->ptr[0];
+ packet_adj(pkt, 1);
+
+ switch (BNEP_TYPE(type)) {
+ case BNEP_GENERAL_ETHERNET:
+ if (pkt->len < (ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN) {
+ log_debug("dropped short packet (type 0x%2.2x)", type);
+ return false;
+ }
+
+ pkt->dst = pkt->ptr;
+ packet_adj(pkt, ETHER_ADDR_LEN);
+ pkt->src = pkt->ptr;
+ packet_adj(pkt, ETHER_ADDR_LEN);
+ pkt->type = pkt->ptr;
+ packet_adj(pkt, ETHER_TYPE_LEN);
+ break;
+
+ case BNEP_CONTROL:
+ len = bnep_recv_control(pkt->chan, pkt->ptr, pkt->len, false);
+ if (len == 0)
+ return false;
+
+ packet_adj(pkt, len);
+ break;
+
+ case BNEP_COMPRESSED_ETHERNET:
+ if (pkt->len < ETHER_TYPE_LEN) {
+ log_debug("dropped short packet (type 0x%2.2x)", type);
+ return false;
+ }
+
+ pkt->dst = pkt->chan->laddr;
+ pkt->src = pkt->chan->raddr;
+ pkt->type = pkt->ptr;
+ packet_adj(pkt, ETHER_TYPE_LEN);
+ break;
+
+ case BNEP_COMPRESSED_ETHERNET_SRC_ONLY:
+ if (pkt->len < ETHER_ADDR_LEN + ETHER_TYPE_LEN) {
+ log_debug("dropped short packet (type 0x%2.2x)", type);
+ return false;
+ }
+
+ pkt->dst = pkt->chan->laddr;
+ pkt->src = pkt->ptr;
+ packet_adj(pkt, ETHER_ADDR_LEN);
+ pkt->type = pkt->ptr;
+ packet_adj(pkt, ETHER_TYPE_LEN);
+ break;
+
+ case BNEP_COMPRESSED_ETHERNET_DST_ONLY:
+ if (pkt->len < ETHER_ADDR_LEN + ETHER_TYPE_LEN) {
+ log_debug("dropped short packet (type 0x%2.2x)", type);
+ return false;
+ }
+
+ pkt->dst = pkt->ptr;
+ packet_adj(pkt, ETHER_ADDR_LEN);
+ pkt->src = pkt->chan->raddr;
+ pkt->type = pkt->ptr;
+ packet_adj(pkt, ETHER_TYPE_LEN);
+ break;
+
+ default:
+ /*
+ * Any packet containing a reserved BNEP
+ * header packet type SHALL be dropped.
+ */
+
+ log_debug("dropped packet with reserved type 0x%2.2x", type);
+ return false;
+ }
+
+ if (BNEP_TYPE_EXT(type)
+ && !bnep_recv_extension(pkt))
+ return false; /* invalid extensions */
+
+ if (BNEP_TYPE(type) == BNEP_CONTROL
+ || pkt->chan->state != CHANNEL_OPEN)
+ return false; /* no forwarding */
+
+ return true;
+}
+
+static bool
+bnep_recv_extension(packet_t *pkt)
+{
+ exthdr_t *eh;
+ size_t len, size;
+ uint8_t type;
+
+ do {
+ if (pkt->len < 2)
+ return false;
+
+ type = pkt->ptr[0];
+ size = pkt->ptr[1];
+
+ if (pkt->len < size + 2)
+ return false;
+
+ switch (type) {
+ case BNEP_EXTENSION_CONTROL:
+ len = bnep_recv_control(pkt->chan, pkt->ptr + 2, size, true);
+ if (len != size)
+ log_err("ignored spurious data in exthdr");
+
+ break;
+
+ default:
+ /* Unknown extension headers in data packets */
+ /* SHALL be forwarded irrespective of any */
+ /* network protocol or multicast filter settings */
+ /* and any local filtering policy. */
+
+ eh = malloc(sizeof(exthdr_t));
+ if (eh == NULL) {
+ log_err("exthdr malloc() failed: %m");
+ break;
+ }
+
+ eh->ptr = pkt->ptr;
+ eh->len = size;
+ STAILQ_INSERT_TAIL(&pkt->extlist, eh, next);
+ break;
+ }
+
+ packet_adj(pkt, size + 2);
+ } while (BNEP_TYPE_EXT(type));
+
+ return true;
+}
+
+static size_t
+bnep_recv_control(channel_t *chan, uint8_t *ptr, size_t size, bool isext)
+{
+ uint8_t type;
+ size_t len;
+
+ if (size-- < 1)
+ return 0;
+
+ type = *ptr++;
+
+ switch (type) {
+ case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
+ len = bnep_recv_control_command_not_understood(chan, ptr, size);
+ break;
+
+ case BNEP_SETUP_CONNECTION_REQUEST:
+ if (isext)
+ return 0; /* not allowed in extension headers */
+
+ len = bnep_recv_setup_connection_req(chan, ptr, size);
+ break;
+
+ case BNEP_SETUP_CONNECTION_RESPONSE:
+ if (isext)
+ return 0; /* not allowed in extension headers */
+
+ len = bnep_recv_setup_connection_rsp(chan, ptr, size);
+ break;
+
+ case BNEP_FILTER_NET_TYPE_SET:
+ len = bnep_recv_filter_net_type_set(chan, ptr, size);
+ break;
+
+ case BNEP_FILTER_NET_TYPE_RESPONSE:
+ len = bnep_recv_filter_net_type_rsp(chan, ptr, size);
+ break;
+
+ case BNEP_FILTER_MULTI_ADDR_SET:
+ len = bnep_recv_filter_multi_addr_set(chan, ptr, size);
+ break;
+
+ case BNEP_FILTER_MULTI_ADDR_RESPONSE:
+ len = bnep_recv_filter_multi_addr_rsp(chan, ptr, size);
+ break;
+
+ default:
+ len = 0;
+ break;
+ }
+
+ if (len == 0)
+ bnep_send_control(chan, BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD, type);
+
+ return len;
+}
+
+static size_t
+bnep_recv_control_command_not_understood(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ uint8_t type;
+
+ if (size < 1)
+ return 0;
+
+ type = *ptr++;
+ log_err("received Control Command Not Understood (0x%2.2x)", type);
+
+ /* we didn't send any reserved commands, just cut them off */
+ channel_close(chan);
+
+ return 1;
+}
+
+static size_t
+bnep_recv_setup_connection_req(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ uint8_t off;
+ int src, dst, rsp;
+ size_t len;
+
+ if (size < 1)
+ return 0;
+
+ len = *ptr++;
+ if (size < (len * 2 + 1))
+ return 0;
+
+ if (chan->state != CHANNEL_WAIT_CONNECT_REQ
+ && chan->state != CHANNEL_OPEN) {
+ log_debug("ignored");
+ return (len * 2 + 1);
+ }
+
+ if (len == 2)
+ off = 2;
+ else if (len == 4)
+ off = 0;
+ else if (len == 16)
+ off = 0;
+ else {
+ rsp = BNEP_SETUP_INVALID_UUID_SIZE;
+ goto done;
+ }
+
+ if (memcmp(ptr, NAP_UUID + off, len) == 0)
+ dst = SDP_SERVICE_CLASS_NAP;
+ else if (memcmp(ptr, GN_UUID + off, len) == 0)
+ dst = SDP_SERVICE_CLASS_GN;
+ else if (memcmp(ptr, PANU_UUID + off, len) == 0)
+ dst = SDP_SERVICE_CLASS_PANU;
+ else
+ dst = 0;
+
+ if (dst != service_class) {
+ rsp = BNEP_SETUP_INVALID_DST_UUID;
+ goto done;
+ }
+
+ ptr += len;
+
+ if (memcmp(ptr, NAP_UUID + off, len) == 0)
+ src = SDP_SERVICE_CLASS_NAP;
+ else if (memcmp(ptr, GN_UUID + off, len) == 0)
+ src = SDP_SERVICE_CLASS_GN;
+ else if (memcmp(ptr, PANU_UUID + off, len) == 0)
+ src = SDP_SERVICE_CLASS_PANU;
+ else
+ src = 0;
+
+ if ((dst != SDP_SERVICE_CLASS_PANU && src != SDP_SERVICE_CLASS_PANU)
+ || src == 0) {
+ rsp = BNEP_SETUP_INVALID_SRC_UUID;
+ goto done;
+ }
+
+ rsp = BNEP_SETUP_SUCCESS;
+ chan->state = CHANNEL_OPEN;
+ channel_timeout(chan, 0);
+
+done:
+ log_debug("addr %s response 0x%2.2x",
+ ether_ntoa((struct ether_addr *)chan->raddr), rsp);
+
+ bnep_send_control(chan, BNEP_SETUP_CONNECTION_RESPONSE, rsp);
+ return (len * 2 + 1);
+}
+
+static size_t
+bnep_recv_setup_connection_rsp(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ int rsp;
+
+ if (size < 2)
+ return 0;
+
+ rsp = be16dec(ptr);
+
+ if (chan->state != CHANNEL_WAIT_CONNECT_RSP) {
+ log_debug("ignored");
+ return 2;
+ }
+
+ log_debug("addr %s response 0x%2.2x",
+ ether_ntoa((struct ether_addr *)chan->raddr), rsp);
+
+ if (rsp == BNEP_SETUP_SUCCESS) {
+ chan->state = CHANNEL_OPEN;
+ channel_timeout(chan, 0);
+ } else {
+ channel_close(chan);
+ }
+
+ return 2;
+}
+
+static size_t
+bnep_recv_filter_net_type_set(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ pfilter_t *pf;
+ int i, nf, rsp;
+ size_t len;
+
+ if (size < 2)
+ return 0;
+
+ len = be16dec(ptr);
+ ptr += 2;
+
+ if (size < (len + 2))
+ return 0;
+
+ if (chan->state != CHANNEL_OPEN) {
+ log_debug("ignored");
+ return (len + 2);
+ }
+
+ nf = len / 4;
+ pf = malloc(nf * sizeof(pfilter_t));
+ if (pf == NULL) {
+ rsp = BNEP_FILTER_TOO_MANY_FILTERS;
+ goto done;
+ }
+
+ log_debug("nf = %d", nf);
+
+ for (i = 0; i < nf; i++) {
+ pf[i].start = be16dec(ptr);
+ ptr += 2;
+ pf[i].end = be16dec(ptr);
+ ptr += 2;
+
+ if (pf[i].start > pf[i].end) {
+ free(pf);
+ rsp = BNEP_FILTER_INVALID_RANGE;
+ goto done;
+ }
+
+ log_debug("pf[%d] = %#4.4x, %#4.4x", i, pf[i].start, pf[i].end);
+ }
+
+ if (chan->pfilter)
+ free(chan->pfilter);
+
+ chan->pfilter = pf;
+ chan->npfilter = nf;
+
+ rsp = BNEP_FILTER_SUCCESS;
+
+done:
+ log_debug("addr %s response 0x%2.2x",
+ ether_ntoa((struct ether_addr *)chan->raddr), rsp);
+
+ bnep_send_control(chan, BNEP_FILTER_NET_TYPE_RESPONSE, rsp);
+ return (len + 2);
+}
+
+static size_t
+bnep_recv_filter_net_type_rsp(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ int rsp;
+
+ if (size < 2)
+ return 0;
+
+ if (chan->state != CHANNEL_OPEN) {
+ log_debug("ignored");
+ return 2;
+ }
+
+ rsp = be16dec(ptr);
+
+ log_debug("addr %s response 0x%2.2x",
+ ether_ntoa((struct ether_addr *)chan->raddr), rsp);
+
+ /* we did not send any filter_net_type_set message */
+ return 2;
+}
+
+static size_t
+bnep_recv_filter_multi_addr_set(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ mfilter_t *mf;
+ int i, nf, rsp;
+ size_t len;
+
+ if (size < 2)
+ return 0;
+
+ len = be16dec(ptr);
+ ptr += 2;
+
+ if (size < (len + 2))
+ return 0;
+
+ if (chan->state != CHANNEL_OPEN) {
+ log_debug("ignored");
+ return (len + 2);
+ }
+
+ nf = len / (ETHER_ADDR_LEN * 2);
+ mf = malloc(nf * sizeof(mfilter_t));
+ if (mf == NULL) {
+ rsp = BNEP_FILTER_TOO_MANY_FILTERS;
+ goto done;
+ }
+
+ log_debug("nf = %d", nf);
+
+ for (i = 0; i < nf; i++) {
+ memcpy(mf[i].start, ptr, ETHER_ADDR_LEN);
+ ptr += ETHER_ADDR_LEN;
+
+ memcpy(mf[i].end, ptr, ETHER_ADDR_LEN);
+ ptr += ETHER_ADDR_LEN;
+
+ if (memcmp(mf[i].start, mf[i].end, ETHER_ADDR_LEN) > 0) {
+ free(mf);
+ rsp = BNEP_FILTER_INVALID_RANGE;
+ goto done;
+ }
+
+ log_debug("pf[%d] = "
+ "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+ "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", i,
+ mf[i].start[0], mf[i].start[1], mf[i].start[2],
+ mf[i].start[3], mf[i].start[4], mf[i].start[5],
+ mf[i].end[0], mf[i].end[1], mf[i].end[2],
+ mf[i].end[3], mf[i].end[4], mf[i].end[5]);
+ }
+
+ if (chan->mfilter)
+ free(chan->mfilter);
+
+ chan->mfilter = mf;
+ chan->nmfilter = nf;
+
+ rsp = BNEP_FILTER_SUCCESS;
+
+done:
+ log_debug("addr %s response 0x%2.2x",
+ ether_ntoa((struct ether_addr *)chan->raddr), rsp);
+
+ bnep_send_control(chan, BNEP_FILTER_MULTI_ADDR_RESPONSE, rsp);
+ return (len + 2);
+}
+
+static size_t
+bnep_recv_filter_multi_addr_rsp(channel_t *chan, uint8_t *ptr, size_t size)
+{
+ int rsp;
+
+ if (size < 2)
+ return false;
+
+ if (chan->state != CHANNEL_OPEN) {
+ log_debug("ignored");
+ return 2;
+ }
+
+ rsp = be16dec(ptr);
+ log_debug("addr %s response 0x%2.2x",
+ ether_ntoa((struct ether_addr *)chan->raddr), rsp);
+
+ /* we did not send any filter_multi_addr_set message */
+ return 2;
+}
+
+void
+bnep_send_control(channel_t *chan, uint8_t type, ...)
+{
+ packet_t *pkt;
+ uint8_t *p;
+ va_list ap;
+
+ assert(chan->state != CHANNEL_CLOSED);
+
+ pkt = packet_alloc(chan);
+ if (pkt == NULL)
+ return;
+
+ p = pkt->ptr;
+ va_start(ap, type);
+
+ *p++ = BNEP_CONTROL;
+ *p++ = type;
+
+ switch(type) {
+ case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
+ *p++ = va_arg(ap, int);
+ break;
+
+ case BNEP_SETUP_CONNECTION_REQUEST:
+ *p++ = va_arg(ap, int);
+ be16enc(p, va_arg(ap, int));
+ p += 2;
+ be16enc(p, va_arg(ap, int));
+ p += 2;
+ break;
+
+ case BNEP_SETUP_CONNECTION_RESPONSE:
+ case BNEP_FILTER_NET_TYPE_RESPONSE:
+ case BNEP_FILTER_MULTI_ADDR_RESPONSE:
+ be16enc(p, va_arg(ap, int));
+ p += 2;
+ break;
+
+ case BNEP_FILTER_NET_TYPE_SET: /* TODO */
+ case BNEP_FILTER_MULTI_ADDR_SET: /* TODO */
+ default:
+ log_err("Can't send control type 0x%2.2x", type);
+ break;
+ }
+
+ va_end(ap);
+ pkt->len = p - pkt->ptr;
+
+ channel_put(chan, pkt);
+ packet_free(pkt);
+}
+
+/*
+ * BNEP send packet routine
+ * return true if packet can be removed from queue
+ */
+bool
+bnep_send(channel_t *chan, packet_t *pkt)
+{
+ struct iovec iov[2];
+ uint8_t *p, *type, *proto;
+ exthdr_t *eh;
+ bool src, dst;
+ size_t nw;
+
+ if (pkt->type == NULL) {
+ iov[0].iov_base = pkt->ptr;
+ iov[0].iov_len = pkt->len;
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+ } else {
+ p = chan->sendbuf;
+
+ dst = (memcmp(pkt->dst, chan->raddr, ETHER_ADDR_LEN) != 0);
+ src = (memcmp(pkt->src, chan->laddr, ETHER_ADDR_LEN) != 0);
+
+ type = p;
+ p += 1;
+
+ if (dst && src)
+ *type = BNEP_GENERAL_ETHERNET;
+ else if (dst && !src)
+ *type = BNEP_COMPRESSED_ETHERNET_DST_ONLY;
+ else if (!dst && src)
+ *type = BNEP_COMPRESSED_ETHERNET_SRC_ONLY;
+ else /* (!dst && !src) */
+ *type = BNEP_COMPRESSED_ETHERNET;
+
+ if (dst) {
+ memcpy(p, pkt->dst, ETHER_ADDR_LEN);
+ p += ETHER_ADDR_LEN;
+ }
+
+ if (src) {
+ memcpy(p, pkt->src, ETHER_ADDR_LEN);
+ p += ETHER_ADDR_LEN;
+ }
+
+ proto = p;
+ memcpy(p, pkt->type, ETHER_TYPE_LEN);
+ p += ETHER_TYPE_LEN;
+
+ STAILQ_FOREACH(eh, &pkt->extlist, next) {
+ if (p + eh->len > chan->sendbuf + chan->mtu)
+ break;
+
+ *type |= BNEP_EXT;
+ type = p;
+
+ memcpy(p, eh->ptr, eh->len);
+ p += eh->len;
+ }
+
+ *type &= ~BNEP_EXT;
+
+ iov[0].iov_base = chan->sendbuf;
+ iov[0].iov_len = (p - chan->sendbuf);
+
+ if ((chan->npfilter == 0 || bnep_pfilter(chan, pkt))
+ && (chan->nmfilter == 0 || bnep_mfilter(chan, pkt))) {
+ iov[1].iov_base = pkt->ptr;
+ iov[1].iov_len = pkt->len;
+ } else if (be16dec(proto) == ETHERTYPE_VLAN
+ && pkt->len >= ETHER_VLAN_ENCAP_LEN) {
+ iov[1].iov_base = pkt->ptr;
+ iov[1].iov_len = ETHER_VLAN_ENCAP_LEN;
+ } else {
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+ memset(proto, 0, ETHER_TYPE_LEN);
+ }
+ }
+
+ if (iov[0].iov_len + iov[1].iov_len > chan->mtu) {
+ log_err("packet exceeded MTU (dropped)");
+ return false;
+ }
+
+ nw = writev(chan->fd, iov, __arraycount(iov));
+ return (nw > 0);
+}
+
+static bool
+bnep_pfilter(channel_t *chan, packet_t *pkt)
+{
+ int proto, i;
+
+ proto = be16dec(pkt->type);
+ if (proto == ETHERTYPE_VLAN) { /* IEEE 802.1Q tag header */
+ if (pkt->len < 4)
+ return false;
+
+ proto = be16dec(pkt->ptr + 2);
+ }
+
+ for (i = 0; i < chan->npfilter; i++) {
+ if (chan->pfilter[i].start <= proto
+ && chan->pfilter[i].end >=proto)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+bnep_mfilter(channel_t *chan, packet_t *pkt)
+{
+ int i;
+
+ if (!ETHER_IS_MULTICAST(pkt->dst))
+ return true;
+
+ for (i = 0; i < chan->nmfilter; i++) {
+ if (memcmp(pkt->dst, chan->mfilter[i].start, ETHER_ADDR_LEN) >= 0
+ && memcmp(pkt->dst, chan->mfilter[i].end, ETHER_ADDR_LEN) <= 0)
+ return true;
+ }
+
+ return false;
+}
diff --git a/usr.sbin/bluetooth/btpand/bnep.h b/usr.sbin/bluetooth/btpand/bnep.h
new file mode 100644
index 0000000..2fc6a77
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/bnep.h
@@ -0,0 +1,72 @@
+/* $NetBSD: bnep.h,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+/*
+ * Constants defined in the Bluetooth Network Encapsulation
+ * Protocol (BNEP) specification v1.0
+ */
+
+#define BNEP_MTU_MIN 1691
+
+#define BNEP_EXT 0x80
+#define BNEP_TYPE(x) ((x) & 0x7f)
+#define BNEP_TYPE_EXT(x) (((x) & BNEP_EXT) == BNEP_EXT)
+
+/* BNEP packet types */
+#define BNEP_GENERAL_ETHERNET 0x00
+#define BNEP_CONTROL 0x01
+#define BNEP_COMPRESSED_ETHERNET 0x02
+#define BNEP_COMPRESSED_ETHERNET_SRC_ONLY 0x03
+#define BNEP_COMPRESSED_ETHERNET_DST_ONLY 0x04
+
+/* BNEP extension header types */
+#define BNEP_EXTENSION_CONTROL 0x00
+
+/* BNEP control types */
+#define BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD 0x00
+#define BNEP_SETUP_CONNECTION_REQUEST 0x01
+#define BNEP_SETUP_CONNECTION_RESPONSE 0x02
+#define BNEP_FILTER_NET_TYPE_SET 0x03
+#define BNEP_FILTER_NET_TYPE_RESPONSE 0x04
+#define BNEP_FILTER_MULTI_ADDR_SET 0x05
+#define BNEP_FILTER_MULTI_ADDR_RESPONSE 0x06
+
+/* BNEP setup response codes */
+#define BNEP_SETUP_SUCCESS 0x0000
+#define BNEP_SETUP_INVALID_SRC_UUID 0x0001
+#define BNEP_SETUP_INVALID_DST_UUID 0x0002
+#define BNEP_SETUP_INVALID_UUID_SIZE 0x0003
+#define BNEP_SETUP_NOT_ALLOWED 0x0004
+
+/* BNEP filter return codes */
+#define BNEP_FILTER_SUCCESS 0x0000
+#define BNEP_FILTER_UNSUPPORTED_REQUEST 0x0001
+#define BNEP_FILTER_INVALID_RANGE 0x0002
+#define BNEP_FILTER_TOO_MANY_FILTERS 0x0003
+#define BNEP_FILTER_SECURITY_FAILURE 0x0004
diff --git a/usr.sbin/bluetooth/btpand/btpand.8 b/usr.sbin/bluetooth/btpand/btpand.8
new file mode 100644
index 0000000..ece16c2
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/btpand.8
@@ -0,0 +1,241 @@
+.\" $NetBSD: btpand.8,v 1.3 2008/08/17 14:43:07 plunky Exp $
+.\" $FreeBSD$
+.\"
+.\" Copyright (c) 2008 Iain Hibbert
+.\" 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.
+.\"
+.Dd August 17, 2008
+.Dt BTPAND 8
+.Os
+.Sh NAME
+.Nm btpand
+.Nd Bluetooth PAN daemon
+.Sh SYNOPSIS
+.Nm
+.Op Fl i Ar ifname
+.Op Fl m Ar mode
+.Fl a Ar addr
+.Fl d Ar device
+.Brq Fl s Ar service | Fl S Ar service Op Fl p Ar psm
+.Nm
+.Op Fl c Ar path
+.Op Fl i Ar ifname
+.Op Fl l Ar limit
+.Op Fl m Ar mode
+.Op Fl p Ar psm
+.Fl d Ar device
+.Brq Fl s Ar service | Fl S Ar service
+.Sh DESCRIPTION
+The
+.Nm
+daemon handles Bluetooth Personal Area Networking services
+in the system.
+It can operate in client mode as a Personal Area Networking User
+.Pq PANU
+or in server mode as Network Access Point
+.Pq NAP ,
+Group ad-hoc Network
+.Pq GN
+or PANU host.
+.Nm
+connects to the system via a
+.Xr tap 4
+virtual Ethernet device and forwards Ethernet packets to
+remote Bluetooth devices using the Bluetooth Network Encapsulation
+Protocol
+.Pq BNEP .
+.Pp
+The PANU client is the device that uses either the NAP or GN
+service, or can talk directly to a PANU host in a crossover
+cable fashion.
+.Pp
+A GN host forwards Ethernet packets to each of the connected PAN
+users as needed but does not provide access to any additional networks.
+.Pp
+The NAP service provides some of the features of an Ethernet bridge,
+with the NAP host forwarding Ethernet packets between each of the
+connected PAN users, and a different network
+media.
+.Pp
+Note, the only differences between NAP and GN services as implemented by
+.Nm
+are in the SDP service record.
+The bridging of packets by the NAP must be configured separately.
+.Pp
+The options are as follows:
+.Bl -tag -width ".Fl a Ar address"
+.It Fl a Ar address
+In client mode, address of remote server.
+May be given as BDADDR or name, in which case
+.Nm
+will attempt to resolve the address via the
+.Xr bt_gethostbyname 3
+call.
+.It Fl c Ar path
+In server mode, specify
+.Ar path
+to the
+.Xr sdpd 8
+control socket.
+The default path is
+.Pa /var/run/sdp .
+.It Fl d Ar device
+Restrict connections to the local
+.Ar device .
+May be given as BDADDR or name, in which case
+.Nm
+will attempt to resolve the address via the
+.Xr bt_devaddr 3
+call.
+.Nm
+will set the
+.Xr tap 4
+interface physical address to the BDADDR
+of the Bluetooth radio.
+.It Fl i Ar ifname
+.Nm
+uses the
+.Xr tap 4
+driver to create a new network interface for use.
+Use this option to select a specific
+.Xr tap 4
+device interface which must already be created.
+.It Fl l Ar limit
+In server mode, limit the number of simultaneous connections.
+The default limit is 7 for NAP and GN servers,
+and 1 for a PANU server.
+.It Fl m Ar mode
+Set L2CAP connection link mode.
+Supported modes are:
+.Pp
+.Bl -tag -compact
+.It auth
+require devices to be paired.
+.It encrypt
+auth, plus enable encryption.
+.It secure
+encryption, plus change of link key.
+.El
+.Pp
+NOT YET SUPPORTED.
+Use global device settings to set authentication and encryption.
+.It Fl p Ar psm
+Use an alternative L2CAP Protocol/Service Multiplexer
+.Pq PSM
+for server mode or client mode
+.Pq when not using Service Discovery .
+The default PSM for BNEP is 15
+.Pq 0x000f .
+.It Fl s Ar service
+Name of
+.Ar service
+to provide or connect to, the following services are recognised:
+.Pp
+.Bl -tag -compact
+.It GN
+Group ad-hoc Network.
+.It NAP
+Network Access Point.
+.It PANU
+Personal Area Networking User.
+.El
+.Pp
+.It Fl S Ar service
+As per
+.Fl s
+except that
+.Nm
+will not use SDP services for connection setup.
+.El
+.Pp
+When providing networking services, the Bluetooth PAN profile says that the
+.Sq Class of Device
+property of the bluetooth controller SHALL include Networking capability
+.Pq set bit 0x020000 .
+See
+.Xr hccontrol 8
+for details.
+.Pp
+After
+.Nm
+has set up the client or server connection and opened the
+.Xr tap 4
+interface, it will create a pid file and detach.
+.Sh EXIT STATUS
+.Ex -std
+.Sh FILES
+.Bl -tag -compact
+.It Pa /dev/tap
+.It Pa /etc/bluetooth/hosts
+.It Pa /var/run/sdp
+.It Pa /var/run/tap Ns Em N Ns No .pid
+.El
+.Sh EXAMPLES
+.Dl ifconfig tap1 create
+.Dl btpand -a host -d mydevice -s NAP -i tap1
+.Dl dhclient tap1
+.Pp
+Will create a connection to the NAP on
+.Ar host ,
+and link that to the
+.Ar tap1
+interface.
+.Pp
+.Dl btpand -d mydevice -s GN
+.Pp
+Will create a Group Network and register the GN service with the local
+SDP server.
+.Sh SEE ALSO
+.Xr bluetooth 3 ,
+.Xr tap 4 ,
+.Xr bridge 4 ,
+.Xr hccontrol 8 ,
+.Xr dhclient 8 ,
+.Xr ifconfig 8 ,
+.Xr sdpd 8
+.Pp
+The
+.Qq Personal Area Networking Profile
+and
+.Qq Bluetooth Network Encapsulation Protocol
+specifications are available at
+.Dl http://www.bluetooth.com/
+.Sh AUTHORS
+.An Iain Hibbert
+.Sh BUGS
+There is no way to supply alternative values for the SDP record.
+.Pp
+There is no way to set net type or multicast address filters.
+.Pp
+.Nm
+does not do any address routing except to directly connected
+unicast addresses.
+All other packets are multicast.
+.Pp
+As
+.Nm
+uses the BDADDR of the Bluetooth radio as the physical address
+of the tap, only one instance can be run per radio.
+.Pp
+.Nm
+can only provide a single service.
diff --git a/usr.sbin/bluetooth/btpand/btpand.c b/usr.sbin/bluetooth/btpand/btpand.c
new file mode 100644
index 0000000..99a3bc7
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/btpand.c
@@ -0,0 +1,293 @@
+/* $NetBSD: btpand.c,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008 Iain Hibbert. All rights reserved.");
+__RCSID("$NetBSD: btpand.c,v 1.1 2008/08/17 13:20:57 plunky Exp $");
+
+#include <sys/wait.h>
+
+#include <bluetooth.h>
+#include <err.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <sdp.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "btpand.h"
+
+/* global variables */
+const char * control_path; /* -c <path> */
+const char * interface_name; /* -i <ifname> */
+const char * service_name; /* -s <service> */
+uint16_t service_class;
+
+bdaddr_t local_bdaddr; /* -d <addr> */
+bdaddr_t remote_bdaddr; /* -a <addr> */
+uint16_t l2cap_psm; /* -p <psm> */
+int l2cap_mode; /* -m <mode> */
+
+int server_limit; /* -n <limit> */
+
+static const struct {
+ const char * name;
+ uint16_t class;
+ const char * desc;
+} services[] = {
+ { "PANU", SDP_SERVICE_CLASS_PANU, "Personal Area Networking User" },
+ { "NAP", SDP_SERVICE_CLASS_NAP, "Network Acess Point" },
+ { "GN", SDP_SERVICE_CLASS_GN, "Group Network" },
+};
+
+static void main_exit(int);
+static void main_detach(void);
+static void usage(void);
+
+int
+main(int argc, char *argv[])
+{
+ unsigned long ul;
+ char * ep;
+ int ch, status;
+
+ while ((ch = getopt(argc, argv, "a:c:d:i:l:m:p:S:s:")) != -1) {
+ switch (ch) {
+ case 'a': /* remote address */
+ if (!bt_aton(optarg, &remote_bdaddr)) {
+ struct hostent *he;
+
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ errx(EXIT_FAILURE, "%s: %s",
+ optarg, hstrerror(h_errno));
+
+ bdaddr_copy(&remote_bdaddr,
+ (bdaddr_t *)he->h_addr);
+ }
+
+ break;
+
+ case 'c': /* control socket path */
+ control_path = optarg;
+ break;
+
+ case 'd': /* local address */
+ if (!bt_aton(optarg, &local_bdaddr)) {
+ struct hostent *he;
+
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ errx(EXIT_FAILURE, "%s: %s",
+ optarg, hstrerror(h_errno));
+
+ bdaddr_copy(&local_bdaddr,
+ (bdaddr_t *)he->h_addr);
+ }
+ break;
+
+ case 'i': /* tap interface name */
+ if (strchr(optarg, '/') == NULL) {
+ asprintf(&ep, "/dev/%s", optarg);
+ interface_name = ep;
+ } else
+ interface_name = optarg;
+ break;
+
+ case 'l': /* limit server sessions */
+ ul = strtoul(optarg, &ep, 10);
+ if (*optarg == '\0' || *ep != '\0' || ul == 0)
+ errx(EXIT_FAILURE, "%s: invalid session limit",
+ optarg);
+
+ server_limit = ul;
+ break;
+
+ case 'm': /* link mode */
+ warnx("Setting link mode is not yet supported");
+ break;
+
+ case 'p': /* protocol/service multiplexer */
+ ul = strtoul(optarg, &ep, 0);
+ if (*optarg == '\0' || *ep != '\0'
+ || ul > 0xffff || L2CAP_PSM_INVALID(ul))
+ errx(EXIT_FAILURE, "%s: invalid PSM", optarg);
+
+ l2cap_psm = ul;
+ break;
+
+ case 's': /* service */
+ case 'S': /* service (no SDP) */
+ for (ul = 0; strcasecmp(optarg, services[ul].name); ul++) {
+ if (ul == __arraycount(services))
+ errx(EXIT_FAILURE, "%s: unknown service", optarg);
+ }
+
+ if (ch == 's')
+ service_name = services[ul].name;
+
+ service_class = services[ul].class;
+ break;
+
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* validate options */
+ if (bdaddr_any(&local_bdaddr) || service_class == 0)
+ usage();
+
+ if (!bdaddr_any(&remote_bdaddr) && (server_limit != 0 ||
+ control_path != 0 || (service_name != NULL && l2cap_psm != 0)))
+ usage();
+
+ /* default options */
+ if (interface_name == NULL)
+ interface_name = "/dev/tap";
+
+ if (l2cap_psm == 0)
+ l2cap_psm = L2CAP_PSM_BNEP;
+
+ if (bdaddr_any(&remote_bdaddr) && server_limit == 0) {
+ if (service_class == SDP_SERVICE_CLASS_PANU)
+ server_limit = 1;
+ else
+ server_limit = 7;
+ }
+
+#ifdef L2CAP_LM_MASTER
+ if (server_limit > 1 && service_class != SDP_SERVICE_CLASS_PANU)
+ l2cap_mode |= L2CAP_LM_MASTER;
+#endif
+
+ /*
+ * fork() now so that the setup can be done in the child process
+ * (as kqueue is not inherited) but block in the parent until the
+ * setup is finished so we can return an error if necessary.
+ */
+ switch(fork()) {
+ case -1: /* bad */
+ err(EXIT_FAILURE, "fork() failed");
+
+ case 0: /* child */
+ signal(SIGPIPE, SIG_IGN);
+
+ openlog(getprogname(), LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_DAEMON);
+
+ channel_init();
+ server_init();
+ event_init();
+ client_init();
+ tap_init();
+
+ main_detach();
+
+ event_dispatch();
+ break;
+
+ default: /* parent */
+ signal(SIGUSR1, main_exit);
+ wait(&status);
+
+ if (WIFEXITED(status))
+ exit(WEXITSTATUS(status));
+
+ break;
+ }
+
+ err(EXIT_FAILURE, "exiting");
+}
+
+static void
+main_exit(int s)
+{
+
+ /* child is all grown up */
+ _exit(EXIT_SUCCESS);
+}
+
+static void
+main_detach(void)
+{
+ int fd;
+
+ if (kill(getppid(), SIGUSR1) == -1)
+ log_err("Could not signal main process: %m");
+
+ if (setsid() == -1)
+ log_err("setsid() failed");
+
+ fd = open(_PATH_DEVNULL, O_RDWR, 0);
+ if (fd == -1) {
+ log_err("Could not open %s", _PATH_DEVNULL);
+ } else {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+ close(fd);
+ }
+}
+
+static void
+usage(void)
+{
+ const char *p = getprogname();
+ int n = strlen(p);
+
+ fprintf(stderr,
+ "usage: %s [-i ifname] [-m mode] -a address -d device\n"
+ " %*s {-s service | -S service [-p psm]}\n"
+ " %s [-c path] [-i ifname] [-l limit] [-m mode] [-p psm] -d device\n"
+ " %*s {-s service | -S service}\n"
+ "\n"
+ "Where:\n"
+ "\t-a address remote bluetooth device\n"
+ "\t-c path SDP server socket\n"
+ "\t-d device local bluetooth device\n"
+ "\t-i ifname tap interface\n"
+ "\t-l limit limit server sessions\n"
+ "\t-m mode L2CAP link mode (NOT YET SUPPORTED)\n"
+ "\t-p psm L2CAP PSM\n"
+ "\t-S service service name (no SDP)\n"
+ "\t-s service service name\n"
+ "\n"
+ "Known services:\n"
+ "", p, n, "", p, n, "");
+
+ for (n = 0; n < __arraycount(services); n++)
+ fprintf(stderr, "\t%s\t%s\n", services[n].name, services[n].desc);
+
+ exit(EXIT_FAILURE);
+}
diff --git a/usr.sbin/bluetooth/btpand/btpand.h b/usr.sbin/bluetooth/btpand/btpand.h
new file mode 100644
index 0000000..c5f7204
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/btpand.h
@@ -0,0 +1,212 @@
+/* $NetBSD: btpand.h,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+
+#include <assert.h>
+#include <bluetooth.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "event.h"
+
+#ifndef __arraycount
+#define __arraycount(__x) (int)(sizeof((__x)) / sizeof((__x)[0]))
+#endif
+
+#ifndef L2CAP_PSM_INVALID
+#define L2CAP_PSM_INVALID(psm) (((psm) & 0x0101) != 0x0001)
+#endif
+
+#ifndef L2CAP_PSM_BNEP
+#define L2CAP_PSM_BNEP 15
+#endif
+
+typedef struct channel channel_t;
+typedef struct pfilter pfilter_t;
+typedef struct mfilter mfilter_t;
+typedef struct packet packet_t;
+typedef struct pkthdr pkthdr_t;
+typedef struct pktlist pktlist_t;
+typedef struct exthdr exthdr_t;
+typedef struct extlist extlist_t;
+
+LIST_HEAD(chlist, channel);
+STAILQ_HEAD(extlist, exthdr);
+STAILQ_HEAD(pktlist, pkthdr);
+
+enum channel_state {
+ CHANNEL_CLOSED,
+ CHANNEL_WAIT_CONNECT_REQ,
+ CHANNEL_WAIT_CONNECT_RSP,
+ CHANNEL_OPEN,
+};
+
+#define CHANNEL_MAXQLEN 128
+
+/* BNEP or tap channel */
+struct channel {
+ enum channel_state state;
+ bool oactive;
+
+ uint8_t laddr[ETHER_ADDR_LEN];
+ uint8_t raddr[ETHER_ADDR_LEN];
+ size_t mru;
+ size_t mtu;
+
+ int npfilter;
+ pfilter_t * pfilter;
+
+ int nmfilter;
+ mfilter_t * mfilter;
+
+ pktlist_t pktlist;
+ int qlen;
+
+ int fd;
+ struct event rd_ev;
+ struct event wr_ev;
+ uint8_t * sendbuf;
+
+ bool (*send)(channel_t *, packet_t *);
+ bool (*recv)(packet_t *);
+
+ int tick;
+
+ struct pidfh *pfh;
+
+ int refcnt;
+ LIST_ENTRY(channel) next;
+};
+
+/* network protocol type filter */
+struct pfilter {
+ uint16_t start;
+ uint16_t end;
+};
+
+/* multicast address filter */
+struct mfilter {
+ uint8_t start[ETHER_ADDR_LEN];
+ uint8_t end[ETHER_ADDR_LEN];
+};
+
+/* packet data buffer */
+struct packet {
+ channel_t * chan; /* source channel */
+ uint8_t * dst; /* dest address */
+ uint8_t * src; /* source address */
+ uint8_t * type; /* protocol type */
+ uint8_t * ptr; /* data pointer */
+ size_t len; /* data length */
+ int refcnt; /* reference count */
+ extlist_t extlist;/* extension headers */
+ uint8_t buf[0]; /* data starts here */
+};
+
+/* extension header */
+struct exthdr {
+ STAILQ_ENTRY(exthdr) next;
+ uint8_t * ptr;
+ uint8_t len;
+};
+
+/* packet header */
+struct pkthdr {
+ STAILQ_ENTRY(pkthdr) next;
+ packet_t * data;
+};
+
+/* global variables */
+extern const char * control_path;
+extern const char * service_name;
+extern const char * interface_name;
+extern bdaddr_t local_bdaddr;
+extern bdaddr_t remote_bdaddr;
+extern uint16_t l2cap_psm;
+extern int l2cap_mode;
+extern uint16_t service_class;
+extern int server_limit;
+
+/*
+ * Bluetooth addresses are stored the other way around than
+ * Ethernet addresses even though they are of the same family
+ */
+static inline void
+b2eaddr(void *dst, bdaddr_t *src)
+{
+ uint8_t *d = dst;
+ int i;
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ d[i] = src->b[ETHER_ADDR_LEN - i - 1];
+}
+
+#define log_err(fmt, args...) syslog(LOG_ERR, fmt , ##args)
+#define log_info(fmt, args...) syslog(LOG_INFO, fmt , ##args)
+#define log_notice(fmt, args...) syslog(LOG_NOTICE, fmt , ##args)
+#define log_debug(fmt, args...) syslog(LOG_DEBUG, "%s: " fmt, __func__ , ##args)
+
+/* bnep.c */
+bool bnep_send(channel_t *, packet_t *);
+bool bnep_recv(packet_t *);
+void bnep_send_control(channel_t *, uint8_t, ...);
+
+/* channel.c */
+void channel_init(void);
+channel_t * channel_alloc(void);
+bool channel_open(channel_t *, int);
+void channel_close(channel_t *);
+void channel_free(channel_t *);
+void channel_timeout(channel_t *, int);
+void channel_put(channel_t *, packet_t *);
+
+/* client.c */
+void client_init(void);
+
+/* packet.c */
+packet_t * packet_alloc(channel_t *);
+void packet_free(packet_t *);
+void packet_adj(packet_t *, size_t);
+pkthdr_t * pkthdr_alloc(packet_t *);
+void pkthdr_free(pkthdr_t *);
+
+/* server.c */
+void server_init(void);
+void server_update(int);
+
+/* tap.c */
+void tap_init(void);
diff --git a/usr.sbin/bluetooth/btpand/channel.c b/usr.sbin/bluetooth/btpand/channel.c
new file mode 100644
index 0000000..b4eb4ab
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/channel.c
@@ -0,0 +1,335 @@
+/* $NetBSD: channel.c,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: channel.c,v 1.1 2008/08/17 13:20:57 plunky Exp $");
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+
+#include <libutil.h>
+#include <unistd.h>
+
+#include "btpand.h"
+
+static struct chlist channel_list;
+static int channel_count;
+static int channel_tick;
+
+static void channel_start(int, short, void *);
+static void channel_read(int, short, void *);
+static void channel_dispatch(packet_t *);
+static void channel_watchdog(int, short, void *);
+
+void
+channel_init(void)
+{
+
+ LIST_INIT(&channel_list);
+}
+
+channel_t *
+channel_alloc(void)
+{
+ channel_t *chan;
+
+ chan = malloc(sizeof(channel_t));
+ if (chan == NULL) {
+ log_err("%s() failed: %m", __func__);
+ return NULL;
+ }
+
+ memset(chan, 0, sizeof(channel_t));
+ STAILQ_INIT(&chan->pktlist);
+ chan->state = CHANNEL_CLOSED;
+ LIST_INSERT_HEAD(&channel_list, chan, next);
+
+ server_update(++channel_count);
+
+ return chan;
+}
+
+bool
+channel_open(channel_t *chan, int fd)
+{
+ int n;
+
+ assert(chan->refcnt == 0);
+ assert(chan->state != CHANNEL_CLOSED);
+
+ if (chan->mtu > 0) {
+ chan->sendbuf = malloc(chan->mtu);
+ if (chan->sendbuf == NULL) {
+ log_err("Could not malloc channel sendbuf: %m");
+ return false;
+ }
+ }
+
+ n = 1;
+ if (ioctl(fd, FIONBIO, &n) == -1) {
+ log_err("Could not set non-blocking IO: %m");
+ return false;
+ }
+
+ event_set(&chan->rd_ev, fd, EV_READ | EV_PERSIST, channel_read, chan);
+ if (event_add(&chan->rd_ev, NULL) == -1) {
+ log_err("Could not add channel read event: %m");
+ return false;
+ }
+
+ event_set(&chan->wr_ev, fd, EV_WRITE, channel_start, chan);
+
+ chan->refcnt++;
+ chan->fd = fd;
+
+ log_debug("(fd#%d)", chan->fd);
+
+ return true;
+}
+
+void
+channel_close(channel_t *chan)
+{
+ pkthdr_t *ph;
+
+ assert(chan->state != CHANNEL_CLOSED);
+
+ log_debug("(fd#%d)", chan->fd);
+
+ chan->state = CHANNEL_CLOSED;
+ event_del(&chan->rd_ev);
+ event_del(&chan->wr_ev);
+ close(chan->fd);
+ chan->refcnt--;
+ chan->tick = 0;
+
+ while ((ph = STAILQ_FIRST(&chan->pktlist)) != NULL) {
+ STAILQ_REMOVE_HEAD(&chan->pktlist, next);
+ pkthdr_free(ph);
+ chan->qlen--;
+ }
+
+ if (chan->pfh != NULL) {
+ pidfile_remove(chan->pfh);
+ chan->pfh = NULL;
+ }
+
+ if (chan->refcnt == 0)
+ channel_free(chan);
+}
+
+void
+channel_free(channel_t *chan)
+{
+
+ assert(chan->refcnt == 0);
+ assert(chan->state == CHANNEL_CLOSED);
+ assert(chan->qlen == 0);
+ assert(STAILQ_EMPTY(&chan->pktlist));
+
+ LIST_REMOVE(chan, next);
+ free(chan->pfilter);
+ free(chan->mfilter);
+ free(chan->sendbuf);
+ free(chan);
+
+ server_update(--channel_count);
+
+ if (server_limit == 0) {
+ log_info("connection closed, exiting");
+ exit(EXIT_SUCCESS);
+ }
+}
+
+static void
+channel_start(int fd, short ev, void *arg)
+{
+ channel_t *chan = arg;
+ pkthdr_t *ph;
+
+ chan->oactive = true;
+
+ while (chan->qlen > 0) {
+ ph = STAILQ_FIRST(&chan->pktlist);
+
+ channel_timeout(chan, 10);
+ if (chan->send(chan, ph->data) == false) {
+ if (event_add(&chan->wr_ev, NULL) == -1) {
+ log_err("Could not add channel write event: %m");
+ channel_close(chan);
+ }
+ return;
+ }
+
+ STAILQ_REMOVE_HEAD(&chan->pktlist, next);
+ pkthdr_free(ph);
+ chan->qlen--;
+ }
+
+ channel_timeout(chan, 0);
+ chan->oactive = false;
+}
+
+static void
+channel_read(int fd, short ev, void *arg)
+{
+ channel_t *chan = arg;
+ packet_t *pkt;
+ ssize_t nr;
+
+ pkt = packet_alloc(chan);
+ if (pkt == NULL) {
+ channel_close(chan);
+ return;
+ }
+
+ nr = read(fd, pkt->buf, chan->mru);
+ if (nr == -1) {
+ log_err("channel read error: %m");
+ packet_free(pkt);
+ channel_close(chan);
+ return;
+ }
+ if (nr == 0) { /* EOF */
+ log_debug("(fd#%d) EOF", fd);
+ packet_free(pkt);
+ channel_close(chan);
+ return;
+ }
+ pkt->len = nr;
+
+ if (chan->recv(pkt) == true)
+ channel_dispatch(pkt);
+
+ packet_free(pkt);
+}
+
+static void
+channel_dispatch(packet_t *pkt)
+{
+ channel_t *chan;
+
+ /*
+ * This is simple routing. I'm not sure if its allowed by
+ * the PAN or BNEP specifications, but it seems logical
+ * to send unicast packets to connected destinations where
+ * possible.
+ */
+ if (!ETHER_IS_MULTICAST(pkt->dst)) {
+ LIST_FOREACH(chan, &channel_list, next) {
+ if (chan == pkt->chan
+ || chan->state != CHANNEL_OPEN)
+ continue;
+
+ if (memcmp(pkt->dst, chan->raddr, ETHER_ADDR_LEN) == 0) {
+ if (chan->qlen > CHANNEL_MAXQLEN)
+ log_notice("Queue overflow");
+ else
+ channel_put(chan, pkt);
+
+ return;
+ }
+ }
+ }
+
+ LIST_FOREACH(chan, &channel_list, next) {
+ if (chan == pkt->chan
+ || chan->state != CHANNEL_OPEN)
+ continue;
+
+ if (chan->qlen > CHANNEL_MAXQLEN) {
+ log_notice("Queue overflow");
+ continue;
+ }
+
+ channel_put(chan, pkt);
+ }
+}
+
+void
+channel_put(channel_t *chan, packet_t *pkt)
+{
+ pkthdr_t *ph;
+
+ ph = pkthdr_alloc(pkt);
+ if (ph == NULL)
+ return;
+
+ chan->qlen++;
+ STAILQ_INSERT_TAIL(&chan->pktlist, ph, next);
+
+ if (!chan->oactive)
+ channel_start(chan->fd, EV_WRITE, chan);
+}
+
+/*
+ * Simple watchdog timer, only ticks when it is required and
+ * closes the channel down if it times out.
+ */
+void
+channel_timeout(channel_t *chan, int to)
+{
+ static struct event ev;
+
+ if (to == 0)
+ chan->tick = 0;
+ else
+ chan->tick = (channel_tick + to) % 60;
+
+ if (channel_tick == 0) {
+ evtimer_set(&ev, channel_watchdog, &ev);
+ channel_watchdog(0, 0, &ev);
+ }
+}
+
+static void
+channel_watchdog(int fd, short ev, void *arg)
+{
+ static struct timeval tv = { .tv_sec = 1 };
+ channel_t *chan, *next;
+ int tick;
+
+ tick = (channel_tick % 60) + 1;
+ channel_tick = 0;
+
+ next = LIST_FIRST(&channel_list);
+ while ((chan = next) != NULL) {
+ next = LIST_NEXT(chan, next);
+
+ if (chan->tick == tick)
+ channel_close(chan);
+ else if (chan->tick != 0)
+ channel_tick = tick;
+ }
+
+ if (channel_tick != 0 && evtimer_add(arg, &tv) < 0) {
+ log_err("Could not add watchdog event: %m");
+ exit(EXIT_FAILURE);
+ }
+}
diff --git a/usr.sbin/bluetooth/btpand/client.c b/usr.sbin/bluetooth/btpand/client.c
new file mode 100644
index 0000000..97064db
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/client.c
@@ -0,0 +1,192 @@
+/* $NetBSD: client.c,v 1.2 2008/12/06 20:01:14 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: client.c,v 1.2 2008/12/06 20:01:14 plunky Exp $");
+
+#include <bluetooth.h>
+#include <errno.h>
+#include <sdp.h>
+#include <unistd.h>
+
+#include "btpand.h"
+#include "bnep.h"
+#include "sdp.h"
+
+static void client_query(void);
+
+void
+client_init(void)
+{
+ struct sockaddr_l2cap sa;
+ channel_t *chan;
+ socklen_t len;
+ int fd;
+ uint16_t mru, mtu;
+
+ if (bdaddr_any(&remote_bdaddr))
+ return;
+
+ if (service_name)
+ client_query();
+
+ fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP);
+ if (fd == -1) {
+ log_err("Could not open L2CAP socket: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.l2cap_family = AF_BLUETOOTH;
+ sa.l2cap_len = sizeof(sa);
+ bdaddr_copy(&sa.l2cap_bdaddr, &local_bdaddr);
+ if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
+ log_err("Could not bind client socket: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ mru = BNEP_MTU_MIN;
+ if (setsockopt(fd, SOL_L2CAP, SO_L2CAP_IMTU, &mru, sizeof(mru)) == -1) {
+ log_err("Could not set L2CAP IMTU (%d): %m", mru);
+ exit(EXIT_FAILURE);
+ }
+
+ log_info("Opening connection to service 0x%4.4x at %s",
+ service_class, bt_ntoa(&remote_bdaddr, NULL));
+
+ sa.l2cap_psm = htole16(l2cap_psm);
+ bdaddr_copy(&sa.l2cap_bdaddr, &remote_bdaddr);
+ if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
+ log_err("Could not connect: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ len = sizeof(mru);
+ if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_IMTU, &mru, &len) == -1) {
+ log_err("Could not get IMTU: %m");
+ exit(EXIT_FAILURE);
+ }
+ if (mru < BNEP_MTU_MIN) {
+ log_err("L2CAP IMTU too small (%d)", mru);
+ exit(EXIT_FAILURE);
+ }
+
+ len = sizeof(mtu);
+ if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_OMTU, &mtu, &len) == -1) {
+ log_err("Could not get L2CAP OMTU: %m");
+ exit(EXIT_FAILURE);
+ }
+ if (mtu < BNEP_MTU_MIN) {
+ log_err("L2CAP OMTU too small (%d)", mtu);
+ exit(EXIT_FAILURE);
+ }
+
+ chan = channel_alloc();
+ if (chan == NULL)
+ exit(EXIT_FAILURE);
+
+ chan->send = bnep_send;
+ chan->recv = bnep_recv;
+ chan->mru = mru;
+ chan->mtu = mtu;
+ b2eaddr(chan->raddr, &remote_bdaddr);
+ b2eaddr(chan->laddr, &local_bdaddr);
+ chan->state = CHANNEL_WAIT_CONNECT_RSP;
+ channel_timeout(chan, 10);
+ if (!channel_open(chan, fd))
+ exit(EXIT_FAILURE);
+
+ bnep_send_control(chan, BNEP_SETUP_CONNECTION_REQUEST,
+ 2, service_class, SDP_SERVICE_CLASS_PANU);
+}
+
+static void
+client_query(void)
+{
+ uint8_t buffer[512];
+ sdp_attr_t attr;
+ uint32_t range;
+ void *ss;
+ int rv;
+ uint8_t *seq0, *seq1;
+
+ attr.flags = SDP_ATTR_INVALID;
+ attr.attr = 0;
+ attr.vlen = sizeof(buffer);
+ attr.value = buffer;
+
+ range = SDP_ATTR_RANGE(SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
+ SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
+
+ ss = sdp_open(&local_bdaddr, &remote_bdaddr);
+ if (ss == NULL || (errno = sdp_error(ss)) != 0) {
+ log_err("%s: %m", service_name);
+ exit(EXIT_FAILURE);
+ }
+
+ log_info("Searching for %s service at %s",
+ service_name, bt_ntoa(&remote_bdaddr, NULL));
+
+ rv = sdp_search(ss, 1, &service_class, 1, &range, 1, &attr);
+ if (rv != 0) {
+ log_err("%s: %s", service_name, strerror(sdp_error(ss)));
+ exit(EXIT_FAILURE);
+ }
+
+ sdp_close(ss);
+
+ if (attr.flags != SDP_ATTR_OK
+ || attr.attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST) {
+ log_err("%s service not found", service_name);
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * we expect the following protocol descriptor list
+ *
+ * seq len
+ * seq len
+ * uuid value == L2CAP
+ * uint16 value16 => PSM
+ * seq len
+ * uuid value == BNEP
+ */
+ if (_sdp_get_seq(&attr.value, attr.value + attr.vlen, &seq0)
+ && _sdp_get_seq(&seq0, attr.value, &seq1)
+ && _sdp_match_uuid16(&seq1, seq0, SDP_UUID_PROTOCOL_L2CAP)
+ && _sdp_get_uint16(&seq1, seq0, &l2cap_psm)
+ && _sdp_get_seq(&seq0, attr.value, &seq1)
+ && _sdp_match_uuid16(&seq1, seq0, SDP_UUID_PROTOCOL_BNEP)) {
+ log_info("Found PSM %d for service %s", l2cap_psm, service_name);
+ return;
+ }
+
+ log_err("%s query failed", service_name);
+ exit(EXIT_FAILURE);
+}
diff --git a/usr.sbin/bluetooth/btpand/event.c b/usr.sbin/bluetooth/btpand/event.c
new file mode 100644
index 0000000..253084e
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/event.c
@@ -0,0 +1,309 @@
+/*
+ * event.h
+ */
+
+/*-
+ * Copyright (c) 2009 Maksim Yevmenkin <m_evmenkin@yahoo.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:
+ * 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$ */
+
+/*
+ * Hack to provide libevent (see devel/libevent port) like API.
+ * Should be removed if FreeBSD ever decides to import libevent into base.
+ */
+
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "event.h"
+#include "btpand.h"
+
+#define __event_link(ev) \
+do { \
+ TAILQ_INSERT_TAIL(&pending, ev, next); \
+ ev->flags |= EV_PENDING; \
+} while (0)
+
+static void tv_add(struct timeval *, struct timeval const *);
+static void tv_sub(struct timeval *, struct timeval const *);
+static int tv_cmp(struct timeval const *, struct timeval const *);
+static int __event_dispatch(void);
+static void __event_add_current(struct event *);
+static void __event_del_current(struct event *);
+
+
+static TAILQ_HEAD(, event) pending;
+static TAILQ_HEAD(, event) current;
+
+void
+event_init(void)
+{
+ TAILQ_INIT(&pending);
+}
+
+int
+event_dispatch(void)
+{
+ while (__event_dispatch() == 0)
+ ;
+
+ return (-1);
+}
+
+static int
+__event_dispatch(void)
+{
+ fd_set r, w;
+ int nfd;
+ struct event *ev;
+ struct timeval now, timeout, t;
+
+ FD_ZERO(&r);
+ FD_ZERO(&w);
+
+ nfd = 0;
+
+ gettimeofday(&now, NULL);
+
+ timeout.tv_sec = 10; /* arbitrary */
+ timeout.tv_usec = 0;
+
+ TAILQ_INIT(&current);
+
+ /*
+ * Build fd_set's
+ */
+
+ event_log_debug("%s: building fd set...", __func__);
+
+ while (!TAILQ_EMPTY(&pending)) {
+ ev = TAILQ_FIRST(&pending);
+ event_del(ev);
+
+ if (ev->flags & EV_HAS_TIMEOUT) {
+ t = now;
+
+ if (tv_cmp(&t, &ev->expire) <= 0)
+ t.tv_sec = t.tv_usec = 0;
+ else
+ tv_sub(&t, &ev->expire);
+
+ if (tv_cmp(&t, &timeout) < 0)
+ timeout = t;
+ }
+
+ if (ev->fd >= 0) {
+ if (ev->flags & EV_READ) {
+ FD_SET(ev->fd, &r);
+ nfd = (nfd > ev->fd) ? nfd : ev->fd;
+ }
+
+ if (ev->flags & EV_WRITE) {
+ FD_SET(ev->fd, &w);
+ nfd = (nfd > ev->fd) ? nfd : ev->fd;
+ }
+ }
+
+ __event_add_current(ev);
+ }
+
+ event_log_debug("%s: waiting for events...", __func__);
+
+ nfd = select(nfd + 1, &r, &w, NULL, &timeout);
+ if (nfd < 0)
+ return (-1);
+
+ /*
+ * Process current pending
+ */
+
+ event_log_debug("%s: processing events...", __func__);
+
+ gettimeofday(&now, NULL);
+
+ while (!TAILQ_EMPTY(&current)) {
+ ev = TAILQ_FIRST(&current);
+ __event_del_current(ev);
+
+ /* check if fd is ready for reading/writing */
+ if (nfd > 0 && ev->fd >= 0) {
+ if (FD_ISSET(ev->fd, &r) || FD_ISSET(ev->fd, &w)) {
+ if (ev->flags & EV_PERSIST) {
+ if (ev->flags & EV_HAS_TIMEOUT)
+ event_add(ev, &ev->timeout);
+ else
+ event_add(ev, NULL);
+ }
+
+ nfd --;
+
+ event_log_debug("%s: calling %p(%d, %p), " \
+ "ev=%p", __func__, ev->cb, ev->fd,
+ ev->cbarg, ev);
+
+ (ev->cb)(ev->fd,
+ (ev->flags & (EV_READ|EV_WRITE)),
+ ev->cbarg);
+
+ continue;
+ }
+ }
+
+ /* if event has no timeout - just requeue */
+ if ((ev->flags & EV_HAS_TIMEOUT) == 0) {
+ event_add(ev, NULL);
+ continue;
+ }
+
+ /* check if event has expired */
+ if (tv_cmp(&now, &ev->expire) >= 0) {
+ if (ev->flags & EV_PERSIST)
+ event_add(ev, &ev->timeout);
+
+ event_log_debug("%s: calling %p(%d, %p), ev=%p",
+ __func__, ev->cb, ev->fd, ev->cbarg, ev);
+
+ (ev->cb)(ev->fd,
+ (ev->flags & (EV_READ|EV_WRITE)),
+ ev->cbarg);
+
+ continue;
+ }
+
+ assert((ev->flags & (EV_PENDING|EV_CURRENT)) == 0);
+ __event_link(ev);
+ }
+
+ return (0);
+}
+
+void
+__event_set(struct event *ev, int fd, short flags,
+ void (*cb)(int, short, void *), void *cbarg)
+{
+ ev->fd = fd;
+ ev->flags = flags;
+ ev->cb = cb;
+ ev->cbarg = cbarg;
+}
+
+int
+__event_add(struct event *ev, const struct timeval *timeout)
+{
+ assert((ev->flags & (EV_PENDING|EV_CURRENT)) == 0);
+
+ if (timeout != NULL) {
+ gettimeofday(&ev->expire, NULL);
+ tv_add(&ev->expire, timeout);
+ ev->timeout = *timeout;
+ ev->flags |= EV_HAS_TIMEOUT;
+ } else
+ ev->flags &= ~EV_HAS_TIMEOUT;
+
+ __event_link(ev);
+
+ return (0);
+}
+
+int
+__event_del(struct event *ev)
+{
+ assert((ev->flags & EV_CURRENT) == 0);
+
+ if ((ev->flags & EV_PENDING) != 0) {
+ TAILQ_REMOVE(&pending, ev, next);
+ ev->flags &= ~EV_PENDING;
+ }
+
+ return (0);
+}
+
+static void
+__event_add_current(struct event *ev)
+{
+ assert((ev->flags & (EV_PENDING|EV_CURRENT)) == 0);
+
+ TAILQ_INSERT_TAIL(&current, ev, next);
+ ev->flags |= EV_CURRENT;
+}
+
+static void
+__event_del_current(struct event *ev)
+{
+ assert((ev->flags & (EV_CURRENT|EV_PENDING)) == EV_CURRENT);
+
+ TAILQ_REMOVE(&current, ev, next);
+ ev->flags &= ~EV_CURRENT;
+}
+
+static void
+tv_add(struct timeval *a, struct timeval const *b)
+{
+ a->tv_sec += b->tv_sec;
+ a->tv_usec += b->tv_usec;
+
+ if(a->tv_usec >= 1000000) {
+ a->tv_usec -= 1000000;
+ a->tv_sec += 1;
+ }
+}
+
+static void
+tv_sub(struct timeval *a, struct timeval const *b)
+{
+ if (a->tv_usec < b->tv_usec) {
+ a->tv_usec += 1000000;
+ a->tv_sec -= 1;
+ }
+
+ a->tv_usec -= b->tv_usec;
+ a->tv_sec -= b->tv_sec;
+}
+
+static int
+tv_cmp(struct timeval const *a, struct timeval const *b)
+{
+ if (a->tv_sec > b->tv_sec)
+ return (1);
+
+ if (a->tv_sec < b->tv_sec)
+ return (-1);
+
+ if (a->tv_usec > b->tv_usec)
+ return (1);
+
+ if (a->tv_usec < b->tv_usec)
+ return (-1);
+
+ return (0);
+}
+
diff --git a/usr.sbin/bluetooth/btpand/event.h b/usr.sbin/bluetooth/btpand/event.h
new file mode 100644
index 0000000..75515e3
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/event.h
@@ -0,0 +1,147 @@
+/*
+ * event.h
+ */
+
+/*-
+ * Copyright (c) 2009 Maksim Yevmenkin <m_evmenkin@yahoo.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:
+ * 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$ */
+
+/*
+ * Hack to provide libevent (see devel/libevent port) like API.
+ * Should be removed if FreeBSD ever decides to import libevent into base.
+ */
+
+#ifndef _EVENT_H_
+#define _EVENT_H_ 1
+
+#define EV_READ 0x02
+#define EV_WRITE 0x04
+#define EV_PERSIST 0x10 /* Persistant event */
+#define EV_PENDING (1 << 13) /* internal use only! */
+#define EV_HAS_TIMEOUT (1 << 14) /* internal use only! */
+#define EV_CURRENT (1 << 15) /* internal use only! */
+
+struct event
+{
+ int fd;
+ short flags;
+ void (*cb)(int, short, void *);
+ void *cbarg;
+ struct timeval timeout;
+ struct timeval expire;
+
+#ifdef EVENT_DEBUG
+ char const *files[3];
+ int lines[3];
+#endif
+
+ TAILQ_ENTRY(event) next;
+};
+
+void event_init (void);
+int event_dispatch (void);
+
+void __event_set (struct event *, int, short,
+ void (*)(int, short, void *), void *);
+int __event_add (struct event *, struct timeval const *);
+int __event_del (struct event *);
+
+#ifdef EVENT_DEBUG
+#define event_log_err(fmt, args...) syslog(LOG_ERR, fmt, ##args)
+#define event_log_info(fmt, args...) syslog(LOG_INFO, fmt, ##args)
+#define event_log_notice(fmt, args...) syslog(LOG_NOTICE, fmt, ##args)
+#define event_log_debug(fmt, args...) syslog(LOG_DEBUG, fmt, ##args)
+
+#define event_set(ev, fd, flags, cb, cbarg) \
+ _event_set(__FILE__, __LINE__, ev, fd, flags, cb, cbarg)
+#define event_add(ev, timeout) \
+ _event_add(__FILE__, __LINE__, ev, timeout)
+#define event_del(ev) \
+ _event_del(__FILE__, __LINE__, ev)
+
+#define evtimer_set(ev, cb, cbarg) \
+ _event_set(__FILE__, __LINE__, ev, -1, 0, cb, cbarg)
+#define evtimer_add(ev, timeout) \
+ _event_add(__FILE__, __LINE__, ev, timeout)
+
+static inline void
+_event_set(char const *file, int line, struct event *ev, int fd, short flags,
+ void (*cb)(int, short, void *), void *cbarg)
+{
+ event_log_debug("set %s:%d ev=%p, fd=%d, flags=%#x, cb=%p, cbarg=%p",
+ file, line, ev, fd, flags, cb, cbarg);
+
+ ev->files[0] = file;
+ ev->lines[0] = line;
+
+ __event_set(ev, fd, flags, cb, cbarg);
+}
+
+static inline int
+_event_add(char const *file, int line, struct event *ev,
+ struct timeval const *timeout) {
+ event_log_debug("add %s:%d ev=%p, fd=%d, flags=%#x, cb=%p, cbarg=%p, " \
+ "timeout=%p", file, line, ev, ev->fd, ev->flags, ev->cb,
+ ev->cbarg, timeout);
+
+ ev->files[1] = file;
+ ev->lines[1] = line;
+
+ return (__event_add(ev, timeout));
+}
+
+static inline int
+_event_del(char const *file, int line, struct event *ev)
+{
+ event_log_debug("del %s:%d ev=%p, fd=%d, flags=%#x, cb=%p, cbarg=%p",
+ file, line, ev, ev->fd, ev->flags, ev->cb, ev->cbarg);
+
+ ev->files[2] = file;
+ ev->lines[2] = line;
+
+ return (__event_del(ev));
+}
+#else
+#define event_log_err(fmt, args...)
+#define event_log_info(fmt, args...)
+#define event_log_notice(fmt, args...)
+#define event_log_debug(fmt, args...)
+
+#define event_set(ev, fd, flags, cb, cbarg) \
+ __event_set(ev, fd, flags, cb, cbarg)
+#define event_add(ev, timeout) \
+ __event_add(ev, timeout)
+#define event_del(ev) \
+ __event_del(ev)
+
+#define evtimer_set(ev, cb, cbarg) \
+ __event_set(ev, -1, 0, cb, cbarg)
+#define evtimer_add(ev, timeout) \
+ __event_add(ev, timeout)
+#endif /* EVENT_DEBUG */
+
+#endif /* ndef _EVENT_H_ */
diff --git a/usr.sbin/bluetooth/btpand/packet.c b/usr.sbin/bluetooth/btpand/packet.c
new file mode 100644
index 0000000..e42e5c5
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/packet.c
@@ -0,0 +1,110 @@
+/* $NetBSD: packet.c,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: packet.c,v 1.1 2008/08/17 13:20:57 plunky Exp $");
+
+#include "btpand.h"
+
+packet_t *
+packet_alloc(channel_t *chan)
+{
+ packet_t *pkt;
+
+ pkt = malloc(sizeof(packet_t) + chan->mru);
+ if (pkt == NULL) {
+ log_err("%s() failed: %m", __func__);
+ return NULL;
+ }
+
+ memset(pkt, 0, sizeof(packet_t));
+ STAILQ_INIT(&pkt->extlist);
+ pkt->ptr = pkt->buf;
+
+ pkt->chan = chan;
+ chan->refcnt++;
+
+ return pkt;
+}
+
+void
+packet_free(packet_t *pkt)
+{
+ exthdr_t *eh;
+
+ if (pkt->refcnt-- > 0)
+ return;
+
+ while ((eh = STAILQ_FIRST(&pkt->extlist)) != NULL) {
+ STAILQ_REMOVE_HEAD(&pkt->extlist, next);
+ free(eh);
+ }
+
+ pkt->chan->refcnt--;
+ if (pkt->chan->refcnt == 0)
+ channel_free(pkt->chan);
+
+ free(pkt);
+}
+
+void
+packet_adj(packet_t *pkt, size_t size)
+{
+
+ assert(pkt->refcnt == 0);
+ assert(pkt->len >= size);
+
+ pkt->ptr += size;
+ pkt->len -= size;
+}
+
+pkthdr_t *
+pkthdr_alloc(packet_t *pkt)
+{
+ pkthdr_t *ph;
+
+ ph = malloc(sizeof(pkthdr_t));
+ if (ph == NULL) {
+ log_err("%s() failed: %m", __func__);
+ return NULL;
+ }
+
+ ph->data = pkt;
+ pkt->refcnt++;
+
+ return ph;
+}
+
+void
+pkthdr_free(pkthdr_t *ph)
+{
+
+ packet_free(ph->data);
+ free(ph);
+}
diff --git a/usr.sbin/bluetooth/btpand/sdp.c b/usr.sbin/bluetooth/btpand/sdp.c
new file mode 100644
index 0000000..e5aec1c
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/sdp.c
@@ -0,0 +1,209 @@
+/* $NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $");
+
+#include <string.h>
+
+#include "sdp.h"
+
+/*
+ * SDP data stream manipulation routines
+ */
+
+/* Bluetooth Base UUID */
+static const uuid_t BASE_UUID = {
+ 0x00000000,
+ 0x0000,
+ 0x1000,
+ 0x80,
+ 0x00,
+ { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
+};
+
+/*
+ * _sdp_match_uuid16(ptr, limit, uuid)
+ *
+ * examine SDP data stream at ptr for a UUID, and return
+ * true if it matches the supplied short alias bluetooth UUID.
+ * limit is the first address past the end of valid data.
+ */
+bool
+_sdp_match_uuid16(uint8_t **ptr, uint8_t *limit, uint16_t uuid)
+{
+ uint8_t *p = *ptr;
+ uuid_t u1, u2;
+
+ memcpy(&u1, &BASE_UUID, sizeof(uuid_t));
+ u1.time_low = uuid;
+
+ if (!_sdp_get_uuid(&p, limit, &u2)
+ || !uuid_equal(&u1, &u2, NULL))
+ return false;
+
+ *ptr = p;
+ return true;
+}
+
+/*
+ * _sdp_get_uuid(ptr, limit, uuid)
+ *
+ * examine SDP data stream at ptr for a UUID, and extract
+ * to given storage, advancing ptr.
+ * limit is the first address past the end of valid data.
+ */
+bool
+_sdp_get_uuid(uint8_t **ptr, uint8_t *limit, uuid_t *uuid)
+{
+ uint8_t *p = *ptr;
+
+ if (p + 1 > limit)
+ return false;
+
+ switch (*p++) {
+ case SDP_DATA_UUID16:
+ if (p + 2 > limit)
+ return false;
+
+ memcpy(uuid, &BASE_UUID, sizeof(uuid_t));
+ uuid->time_low = be16dec(p);
+ p += 2;
+ break;
+
+ case SDP_DATA_UUID32:
+ if (p + 4 > limit)
+ return false;
+
+ memcpy(uuid, &BASE_UUID, sizeof(uuid_t));
+ uuid->time_low = be32dec(p);
+ p += 4;
+ break;
+
+ case SDP_DATA_UUID128:
+ if (p + 16 > limit)
+ return false;
+
+ uuid_dec_be(p, uuid);
+ p += 16;
+ break;
+
+ default:
+ return false;
+ }
+
+ *ptr = p;
+ return true;
+}
+
+/*
+ * _sdp_get_seq(ptr, limit, seq)
+ *
+ * examine SDP data stream at ptr for a sequence. return
+ * seq pointer if found and advance ptr to next object.
+ * limit is the first address past the end of valid data.
+ */
+bool
+_sdp_get_seq(uint8_t **ptr, uint8_t *limit, uint8_t **seq)
+{
+ uint8_t *p = *ptr;
+ int32_t l;
+
+ if (p + 1 > limit)
+ return false;
+
+ switch (*p++) {
+ case SDP_DATA_SEQ8:
+ if (p + 1 > limit)
+ return false;
+
+ l = *p;
+ p += 1;
+ break;
+
+ case SDP_DATA_SEQ16:
+ if (p + 2 > limit)
+ return false;
+
+ l = be16dec(p);
+ p += 2;
+ break;
+
+ case SDP_DATA_SEQ32:
+ if (p + 4 > limit)
+ return false;
+
+ l = be32dec(p);
+ p += 4;
+ break;
+
+ default:
+ return false;
+ }
+ if (p + l > limit)
+ return false;
+
+ *seq = p;
+ *ptr = p + l;
+ return true;
+}
+
+/*
+ * _sdp_get_uint16(ptr, limit, value)
+ *
+ * examine SDP data stream at ptr for a uint16_t, and
+ * extract to given storage, advancing ptr.
+ * limit is the first address past the end of valid data.
+ */
+bool
+_sdp_get_uint16(uint8_t **ptr, uint8_t *limit, uint16_t *value)
+{
+ uint8_t *p = *ptr;
+ uint16_t v;
+
+ if (p + 1 > limit)
+ return false;
+
+ switch (*p++) {
+ case SDP_DATA_UINT16:
+ if (p + 2 > limit)
+ return false;
+
+ v = be16dec(p);
+ p += 2;
+ break;
+
+ default:
+ return false;
+ }
+
+ *value = v;
+ *ptr = p;
+ return true;
+}
diff --git a/usr.sbin/bluetooth/btpand/sdp.h b/usr.sbin/bluetooth/btpand/sdp.h
new file mode 100644
index 0000000..32dd95d
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/sdp.h
@@ -0,0 +1,38 @@
+/* $NetBSD: sdp.h,v 1.2 2008/12/06 20:01:15 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <bluetooth.h>
+#include <sdp.h>
+#include <stdbool.h>
+#include <uuid.h>
+
+bool _sdp_match_uuid16(uint8_t **, uint8_t *, uint16_t);
+bool _sdp_get_uuid(uint8_t **, uint8_t *, uuid_t *);
+bool _sdp_get_seq(uint8_t **, uint8_t *, uint8_t **);
+bool _sdp_get_uint16(uint8_t **, uint8_t *, uint16_t *);
diff --git a/usr.sbin/bluetooth/btpand/server.c b/usr.sbin/bluetooth/btpand/server.c
new file mode 100644
index 0000000..0843d0c
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/server.c
@@ -0,0 +1,277 @@
+/* $NetBSD: server.c,v 1.2 2009/01/24 17:29:28 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: server.c,v 1.2 2009/01/24 17:29:28 plunky Exp $");
+
+#include <sys/ioctl.h>
+
+#include <bluetooth.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <sdp.h>
+#include <unistd.h>
+
+#include "btpand.h"
+#include "bnep.h"
+
+static struct event server_ev;
+static int server_fd;
+static int server_avail;
+
+static void * server_ss;
+static uint32_t server_handle;
+
+static void server_open(void);
+static void server_close(void);
+static void server_read(int, short, void *);
+static void server_register(void);
+
+void
+server_init(void)
+{
+
+ server_fd = -1;
+}
+
+/*
+ * The server_update() function is called whenever the channel count is
+ * changed. We maintain the SDP record and open or close the server socket
+ * as required.
+ */
+void
+server_update(int count)
+{
+
+ if (server_limit == 0)
+ return;
+
+ log_debug("count %d", count);
+
+ server_avail = UINT8_MAX - (count - 1) * UINT8_MAX / server_limit;
+ log_info("Service Availability: %d/%d", server_avail, UINT8_MAX);
+
+ if (server_avail == 0 && server_fd != -1)
+ server_close();
+
+ if (server_avail > 0 && server_fd == -1)
+ server_open();
+
+ if (service_name)
+ server_register();
+}
+
+static void
+server_open(void)
+{
+ struct sockaddr_l2cap sa;
+ uint16_t mru;
+
+ server_fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP);
+ if (server_fd == -1) {
+ log_err("Could not open L2CAP socket: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.l2cap_family = AF_BLUETOOTH;
+ sa.l2cap_len = sizeof(sa);
+ sa.l2cap_psm = htole16(l2cap_psm);
+ bdaddr_copy(&sa.l2cap_bdaddr, &local_bdaddr);
+ if (bind(server_fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
+ log_err("Could not bind server socket: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ mru = BNEP_MTU_MIN;
+ if (setsockopt(server_fd, SOL_L2CAP,
+ SO_L2CAP_IMTU, &mru, sizeof(mru)) == -1) {
+ log_err("Could not set L2CAP IMTU (%d): %m", mru);
+ exit(EXIT_FAILURE);
+ }
+
+ if (listen(server_fd, 0) == -1) {
+ log_err("Could not listen on server socket: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ event_set(&server_ev, server_fd, EV_READ | EV_PERSIST, server_read, NULL);
+ if (event_add(&server_ev, NULL) == -1) {
+ log_err("Could not add server event: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ log_info("server socket open");
+}
+
+static void
+server_close(void)
+{
+
+ event_del(&server_ev);
+ close(server_fd);
+ server_fd = -1;
+
+ log_info("server socket closed");
+}
+
+/*
+ * handle connection request
+ */
+static void
+server_read(int s, short ev, void *arg)
+{
+ struct sockaddr_l2cap ra, la;
+ channel_t *chan;
+ socklen_t len;
+ int fd, n;
+ uint16_t mru, mtu;
+
+ len = sizeof(ra);
+ fd = accept(s, (struct sockaddr *)&ra, &len);
+ if (fd == -1)
+ return;
+
+ n = 1;
+ if (ioctl(fd, FIONBIO, &n) == -1) {
+ log_err("Could not set NonBlocking IO: %m");
+ close(fd);
+ return;
+ }
+
+ len = sizeof(mru);
+ if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_IMTU, &mru, &len) == -1) {
+ log_err("Could not get L2CAP IMTU: %m");
+ close(fd);
+ return;
+ }
+ if(mru < BNEP_MTU_MIN) {
+ log_err("L2CAP IMTU too small (%d)", mru);
+ close(fd);
+ return;
+ }
+
+ len = sizeof(mtu);
+ if (getsockopt(fd, SOL_L2CAP, SO_L2CAP_OMTU, &mtu, &len) == -1) {
+ log_err("Could not get L2CAP OMTU: %m");
+ close(fd);
+ return;
+ }
+ if (mtu < BNEP_MTU_MIN) {
+ log_err("L2CAP OMTU too small (%d)", mtu);
+ close(fd);
+ return;
+ }
+
+ len = sizeof(n);
+ if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &n, &len) == -1) {
+ log_err("Could not get socket send buffer size: %m");
+ close(fd);
+ return;
+ }
+
+ if (n < (mtu * 2)) {
+ n = mtu * 2;
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) == -1) {
+ log_err("Could not set socket send buffer size (%d): %m", n);
+ close(fd);
+ return;
+ }
+ }
+
+ n = mtu;
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &n, sizeof(n)) == -1) {
+ log_err("Could not set socket low water mark (%d): %m", n);
+ close(fd);
+ return;
+ }
+
+ len = sizeof(la);
+ if (getsockname(fd, (struct sockaddr *)&la, &len) == -1) {
+ log_err("Could not get socket address: %m");
+ close(fd);
+ return;
+ }
+
+ log_info("Accepted connection from %s", bt_ntoa(&ra.l2cap_bdaddr, NULL));
+
+ chan = channel_alloc();
+ if (chan == NULL) {
+ close(fd);
+ return;
+ }
+
+ chan->send = bnep_send;
+ chan->recv = bnep_recv;
+ chan->mru = mru;
+ chan->mtu = mtu;
+ b2eaddr(chan->raddr, &ra.l2cap_bdaddr);
+ b2eaddr(chan->laddr, &la.l2cap_bdaddr);
+ chan->state = CHANNEL_WAIT_CONNECT_REQ;
+ channel_timeout(chan, 10);
+ if (!channel_open(chan, fd)) {
+ chan->state = CHANNEL_CLOSED;
+ channel_free(chan);
+ close(fd);
+ return;
+ }
+}
+
+static void
+server_register(void)
+{
+ sdp_nap_profile_t p;
+ int rv;
+
+ if (server_ss == NULL) {
+ server_ss = sdp_open_local(control_path);
+ if (server_ss == NULL || sdp_error(server_ss) != 0) {
+ log_err("failed to contact SDP server");
+ return;
+ }
+ }
+
+ memset(&p, 0, sizeof(p));
+ p.psm = l2cap_psm;
+ p.load_factor = server_avail;
+ p.security_description = (l2cap_mode == 0 ? 0x0000 : 0x0001);
+
+ if (server_handle)
+ rv = sdp_change_service(server_ss, server_handle,
+ (uint8_t *)&p, sizeof(p));
+ else
+ rv = sdp_register_service(server_ss, service_class,
+ &local_bdaddr, (uint8_t *)&p, sizeof(p), &server_handle);
+
+ if (rv != 0) {
+ errno = sdp_error(server_ss);
+ log_err("%s: %m", service_name);
+ exit(EXIT_FAILURE);
+ }
+}
diff --git a/usr.sbin/bluetooth/btpand/tap.c b/usr.sbin/bluetooth/btpand/tap.c
new file mode 100644
index 0000000..c965633
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/tap.c
@@ -0,0 +1,167 @@
+/* $NetBSD: tap.c,v 1.1 2008/08/17 13:20:57 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2008 Iain Hibbert
+ * 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$ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: tap.c,v 1.1 2008/08/17 13:20:57 plunky Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <net/if_tap.h>
+
+#include <fcntl.h>
+#include <libutil.h>
+#include <paths.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "btpand.h"
+
+static bool tap_send(channel_t *, packet_t *);
+static bool tap_recv(packet_t *);
+
+void
+tap_init(void)
+{
+ channel_t *chan;
+ struct ifreq ifr;
+ int fd, s;
+ char pidfile[PATH_MAX];
+
+ fd = open(interface_name, O_RDWR);
+ if (fd == -1) {
+ log_err("Could not open \"%s\": %m", interface_name);
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ if (ioctl(fd, TAPGIFNAME, &ifr) == -1) {
+ log_err("Could not get interface name: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1) {
+ log_err("Could not open PF_LINK socket: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ ifr.ifr_addr.sa_family = AF_LINK;
+ ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ b2eaddr(ifr.ifr_addr.sa_data, &local_bdaddr);
+
+ if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
+ log_err("Could not set %s physical address: %m", ifr.ifr_name);
+ exit(EXIT_FAILURE);
+ }
+
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
+ log_err("Could not get interface flags: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ if ((ifr.ifr_flags & IFF_UP) == 0) {
+ ifr.ifr_flags |= IFF_UP;
+
+ if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
+ log_err("Could not set IFF_UP: %m");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ close(s);
+
+ log_info("Using interface %s with addr %s", ifr.ifr_name,
+ ether_ntoa((struct ether_addr *)&ifr.ifr_addr.sa_data));
+
+ chan = channel_alloc();
+ if (chan == NULL)
+ exit(EXIT_FAILURE);
+
+ chan->send = tap_send;
+ chan->recv = tap_recv;
+ chan->mru = ETHER_HDR_LEN + ETHER_MAX_LEN;
+ memcpy(chan->raddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
+ memcpy(chan->laddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
+ chan->state = CHANNEL_OPEN;
+ if (!channel_open(chan, fd))
+ exit(EXIT_FAILURE);
+
+ snprintf(pidfile, sizeof(pidfile), "%s/%s.pid",
+ _PATH_VARRUN, ifr.ifr_name);
+ chan->pfh = pidfile_open(pidfile, 0600, NULL);
+ if (chan->pfh == NULL)
+ log_err("can't create pidfile");
+ else if (pidfile_write(chan->pfh) < 0) {
+ log_err("can't write pidfile");
+ pidfile_remove(chan->pfh);
+ chan->pfh = NULL;
+ }
+}
+
+static bool
+tap_send(channel_t *chan, packet_t *pkt)
+{
+ struct iovec iov[4];
+ ssize_t nw;
+
+ iov[0].iov_base = pkt->dst;
+ iov[0].iov_len = ETHER_ADDR_LEN;
+ iov[1].iov_base = pkt->src;
+ iov[1].iov_len = ETHER_ADDR_LEN;
+ iov[2].iov_base = pkt->type;
+ iov[2].iov_len = ETHER_TYPE_LEN;
+ iov[3].iov_base = pkt->ptr;
+ iov[3].iov_len = pkt->len;
+
+ /* tap device write never fails */
+ nw = writev(chan->fd, iov, __arraycount(iov));
+ assert(nw > 0);
+
+ return true;
+}
+
+static bool
+tap_recv(packet_t *pkt)
+{
+
+ if (pkt->len < ETHER_HDR_LEN)
+ return false;
+
+ pkt->dst = pkt->ptr;
+ packet_adj(pkt, ETHER_ADDR_LEN);
+ pkt->src = pkt->ptr;
+ packet_adj(pkt, ETHER_ADDR_LEN);
+ pkt->type = pkt->ptr;
+ packet_adj(pkt, ETHER_TYPE_LEN);
+
+ return true;
+}
diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.c b/usr.sbin/bluetooth/hcsecd/hcsecd.c
index de7a775..72f9c8c 100644
--- a/usr.sbin/bluetooth/hcsecd/hcsecd.c
+++ b/usr.sbin/bluetooth/hcsecd/hcsecd.c
@@ -128,9 +128,8 @@ main(int argc, char *argv[])
(void * const) &filter, sizeof(filter)) < 0)
err(1, "Could not set HCI socket filter");
- if (detach)
- if (daemon(0, 0) < 0)
- err(1, "Could not daemon()ize");
+ if (detach && daemon(0, 0) < 0)
+ err(1, "Could not daemon()ize");
openlog(HCSECD_IDENT, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_DAEMON);
diff --git a/usr.sbin/bluetooth/hcseriald/hcseriald.c b/usr.sbin/bluetooth/hcseriald/hcseriald.c
index ee8d19c..b811c1d 100644
--- a/usr.sbin/bluetooth/hcseriald/hcseriald.c
+++ b/usr.sbin/bluetooth/hcseriald/hcseriald.c
@@ -101,23 +101,10 @@ main(int argc, char *argv[])
/* Open device */
n = open_device(device, speed, name);
- if (detach) {
- pid_t pid = fork();
-
- if (pid == (pid_t) -1) {
- syslog(LOG_ERR, "Could not fork(). %s (%d)",
- strerror(errno), errno);
- exit(1);
- }
-
- if (pid != 0)
- exit(0);
-
- if (daemon(0, 0) < 0) {
- syslog(LOG_ERR, "Could not daemon(0, 0). %s (%d)",
- strerror(errno), errno);
- exit(1);
- }
+ if (detach && daemon(0, 0) < 0) {
+ syslog(LOG_ERR, "Could not daemon(0, 0). %s (%d)",
+ strerror(errno), errno);
+ exit(1);
}
/* Write PID file */
diff --git a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c
index cea2e3b..956dc4d 100644
--- a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c
+++ b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c
@@ -166,22 +166,10 @@ main(int argc, char *argv[])
openlog(RFCOMM_PPPD, LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_USER);
- if (detach) {
- pid = fork();
- if (pid == (pid_t) -1) {
- syslog(LOG_ERR, "Could not fork(). %s (%d)",
- strerror(errno), errno);
- exit(1);
- }
-
- if (pid != 0)
- exit(0);
-
- if (daemon(0, 0) < 0) {
- syslog(LOG_ERR, "Could not daemon(0, 0). %s (%d)",
- strerror(errno), errno);
- exit(1);
- }
+ if (detach && daemon(0, 0) < 0) {
+ syslog(LOG_ERR, "Could not daemon(0, 0). %s (%d)",
+ strerror(errno), errno);
+ exit(1);
}
s = socket(PF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_RFCOMM);
diff --git a/usr.sbin/boot0cfg/boot0cfg.8 b/usr.sbin/boot0cfg/boot0cfg.8
index 1aa8d2b..c7e664c 100644
--- a/usr.sbin/boot0cfg/boot0cfg.8
+++ b/usr.sbin/boot0cfg/boot0cfg.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 7, 2007
+.Dd January 13, 2009
.Dt BOOT0CFG 8
.Os
.Sh NAME
@@ -153,6 +153,21 @@ Set the timeout value to
.It Fl v
Verbose: display information about the slices defined, etc.
.El
+.Sh NOTE
+Protection mechanisms in the
+.Xr geom 4
+subsystem might prevent
+.Nm
+from being able to update the MBR on a mounted disk.
+Instructions for temporarily disabling these protection mechanisms
+can be found in the
+.Xr geom 4
+manpage. Specifically, do a
+.Pp
+.Dl sysctl kern.geom.debugflags=0x10
+.Pp
+to allow writing to the MBR, and restore it to 0 afterwards.
+.Pp
.Sh FILES
.Bl -tag -width /boot/boot0sio -compact
.It Pa /boot/boot0
@@ -186,16 +201,6 @@ to install the default MBR:
.Sh AUTHORS
.An Robert Nordier Aq rnordier@FreeBSD.org .
.Sh BUGS
-Protection mechanisms in the
-.Xr geom 4
-subsystem might prevent
-.Nm
-from being able to update the MBR on a mounted disk.
-Instructions for temporarily disabling these protection mechanisms
-can be found in the
-.Xr geom 4
-manpage.
-.Pp
Use of the
.Sq packet
option may cause
@@ -204,6 +209,6 @@ to fail, depending on the nature of BIOS support.
.Pp
Use of the
.Sq setdrv
-option with an incorrect -d operand may cause the MBR to be written
-to the wrong disk.
-Be careful!
+option with an incorrect -d operand may cause the boot0 code
+to write the MBR to the wrong disk, thus trashing its previous
+content. Be careful.
diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index 0835686..c4d1648 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -59,7 +59,7 @@ struct track_info {
};
static struct track_info tracks[100];
static int quiet, verbose, saved_block_size, notracks;
-static volatile int global_fd_for_cleanup;
+static volatile sig_atomic_t global_fd_for_cleanup;
void add_track(char *, int, int, int);
void do_DAO(int fd, int, int);
diff --git a/usr.sbin/config/config.8 b/usr.sbin/config/config.8
index 01abc94..904ef6b 100644
--- a/usr.sbin/config/config.8
+++ b/usr.sbin/config/config.8
@@ -42,20 +42,6 @@
.Nm
.Op Fl x Ar kernel
.Sh DESCRIPTION
-.\" This is the old version of the
-.\" .Nm
-.\" utility.
-.\" It understands the old autoconfiguration scheme
-.\" used on the HP300, i386, DECstation, and derivative platforms.
-.\" The new version of
-.\" .Nm
-.\" is used with the
-.\" SPARC platform.
-.\" Only the version of
-.\" .Nm
-.\" applicable to the architecture that you are running
-.\" will be installed on your machine.
-.\" .Pp
The
.Nm
utility builds a set of system configuration files from the file
diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
index 24b4396..34806ab 100644
--- a/usr.sbin/config/main.c
+++ b/usr.sbin/config/main.c
@@ -466,6 +466,11 @@ configfile_filebased(struct sbuf *sb)
struct cfgfile *cf;
int i;
+ /*
+ * Try to read all configuration files. Since those will be present as
+ * C string in the macro, we have to slash their ends then the line
+ * wraps.
+ */
STAILQ_FOREACH(cf, &cfgfiles, cfg_next) {
cff = fopen(cf->cfg_path, "r");
if (cff == NULL) {
@@ -500,11 +505,6 @@ configfile(void)
sb = sbuf_new(NULL, NULL, 2048, SBUF_AUTOEXTEND);
assert(sb != NULL);
sbuf_clear(sb);
- /*
- * Try to read all configuration files. Since those will be present as
- * C string in the macro, we have to slash their ends then the line
- * wraps.
- */
if (filebased) {
/* Is needed, can be used for backward compatibility. */
configfile_filebased(sb);
@@ -565,9 +565,6 @@ moveifchanged(const char *from_name, const char *to_name)
if (!changed) {
p = mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
-#ifndef MAP_FAILED
-#define MAP_FAILED ((caddr_t) -1)
-#endif
if (p == MAP_FAILED)
err(EX_OSERR, "mmap %s", from_name);
q = mmap(NULL, tsize, PROT_READ, MAP_SHARED, to_fd, (off_t)0);
@@ -669,7 +666,7 @@ kernconfdump(const char *file)
struct stat st;
FILE *fp, *pp;
int error, len, osz, r;
- unsigned int off, size;
+ unsigned int i, off, size;
char *cmd, *o;
r = open(file, O_RDONLY);
@@ -707,7 +704,18 @@ kernconfdump(const char *file)
r = fseek(fp, off, SEEK_CUR);
if (r != 0)
errx(EXIT_FAILURE, "fseek() failed");
- while ((r = fgetc(fp)) != EOF && size-- > 0)
+ for (i = 0; i < size - 1; i++) {
+ r = fgetc(fp);
+ if (r == EOF)
+ break;
+ /*
+ * If '\0' is present in the middle of the configuration
+ * string, this means something very weird is happening.
+ * Make such case very visible.
+ */
+ assert(r != '\0' && ("Char present in the configuration "
+ "string mustn't be equal to 0"));
fputc(r, stdout);
+ }
fclose(fp);
}
diff --git a/usr.sbin/cpucontrol/cpucontrol.8 b/usr.sbin/cpucontrol/cpucontrol.8
index cc753e0..b049f14 100644
--- a/usr.sbin/cpucontrol/cpucontrol.8
+++ b/usr.sbin/cpucontrol/cpucontrol.8
@@ -55,33 +55,36 @@ device.
.Sh DESCRIPTION
The
.Nm
-utility can be used to read and write an arbitrary machine-specific
-CPU registers via
+utility can be used to read and write arbitrary machine-specific
+CPU registers via the
.Xr cpuctl 4
-controlled special device and apply the CPU firmware updates.
+special device.
+It can also be used to apply CPU firmware updates.
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl d Ar datadir
-Where to look for microcode images. The option can be specified multiple times.
+Where to look for microcode images.
+The option can be specified multiple times.
.It Fl m Ar msr Ns Op = Ns Ar value
-Read/write the specified MSR. Both the MSR and the value should be given as a hex number.
+Read/write the specified MSR.
+Both the MSR and the value should be given as a hex number.
.It Fl i Ar level
-Retrieve CPUID info. Level should be given as a hex number.
+Retrieve CPUID info.
+Level should be given as a hex number.
.It Fl u
-Apply CPU firmware updates. The
+Apply CPU firmware updates.
+The
.Nm
utility will walk through the configured data directories
-and will apply all firmware patches available for this CPU.
+and apply all firmware updates available for this CPU.
.It Fl v
Increase the verbosity level.
.It Fl h
Show help message.
.El
.Sh EXIT STATUS
-The
-.Nm
-utility exits 0 on success, and >0 if an error occurs.
+.Ex -std
.Sh EXAMPLES
The command
.Pp
@@ -93,20 +96,24 @@ To set the CPU 0 TSC MSR register value to 0x1 issue
.Pp
.Dq Li "cpucontrol -m 0x10=0x1 /dev/cpuctl0"
.Pp
-.Pp
The command
.Pp
.Dq Li "cpucontrol -i 0x1 /dev/cpuctl1"
.Pp
will retrieve the CPUID level 0x1 from CPU 1.
.Pp
-To perform firmware updated on CPU 0 from images located at
+To perform firmware updates on CPU 0 from images located at
.Pa /usr/local/share/cpuctl/
use the following command:
.Pp
.Dq Li "cpucontrol -d /usr/local/share/cpuctl/ -u /dev/cpuctl0"
.Sh SEE ALSO
.Xr cpuctl 4
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 8.0 .
.Sh BUGS
Yes, probably, report if any.
.Sh AUTHORS
diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c
index 71f6d5b..752acc6 100644
--- a/usr.sbin/crunch/crunchgen/crunchgen.c
+++ b/usr.sbin/crunch/crunchgen/crunchgen.c
@@ -709,12 +709,13 @@ void fillin_program_objs(prog_t *p, char *path)
if (outhdrname[0] != '\0')
fprintf(f, ".include \"%s\"\n", outhdrname);
fprintf(f, ".include \"%s\"\n", path);
+ fprintf(f, ".POSIX:\n");
if (buildopts) {
fprintf(f, "BUILDOPTS+=");
output_strlst(f, buildopts);
}
- fprintf(f, ".if defined(PROG) && !defined(%s)\n", objvar);
- fprintf(f, "%s=${PROG}.o\n", objvar);
+ fprintf(f, ".if defined(PROG)\n");
+ fprintf(f, "%s?=${PROG}.o\n", objvar);
fprintf(f, ".endif\n");
fprintf(f, "loop:\n\t@echo 'OBJS= '${%s}\n", objvar);
@@ -727,7 +728,7 @@ void fillin_program_objs(prog_t *p, char *path)
fclose(f);
- snprintf(line, MAXLINELEN, "cd %s && make -f %s crunchgen_objs",
+ snprintf(line, MAXLINELEN, "cd %s && make -f %s -B crunchgen_objs",
p->srcdir, tempfname);
if ((f = popen(line, "r")) == NULL) {
warn("submake pipe");
diff --git a/usr.sbin/fifolog/lib/fifolog_reader.c b/usr.sbin/fifolog/lib/fifolog_reader.c
index fde2a07..77e586f 100644
--- a/usr.sbin/fifolog/lib/fifolog_reader.c
+++ b/usr.sbin/fifolog/lib/fifolog_reader.c
@@ -155,6 +155,7 @@ fifolog_reader_seek(const struct fifolog_reader *fr, time_t t0)
retval = fifolog_int_findend(fr->ff, &s);
if (retval != NULL)
err(1, "%s", retval);
+ s++;
e = fifolog_reader_findsync(fr->ff, &s);
if (e == 0)
return (0); /* empty fifolog */
diff --git a/usr.sbin/fifolog/lib/fifolog_write_poll.c b/usr.sbin/fifolog/lib/fifolog_write_poll.c
index afff022..4fc5204 100644
--- a/usr.sbin/fifolog/lib/fifolog_write_poll.c
+++ b/usr.sbin/fifolog/lib/fifolog_write_poll.c
@@ -152,15 +152,16 @@ fifolog_write_open(struct fifolog_writer *f, const char *fn, unsigned writerate,
es = fifolog_int_findend(f->ff, &o);
if (es != NULL)
return (es);
- if (o == 0) {
- f->seq = 0;
- f->recno = 0;
+ i = fifolog_int_read(f->ff, o);
+ if (i)
+ return ("Read error, looking for seq");
+ f->seq = be32dec(f->ff->recbuf);
+ if (f->seq == 0) {
+ /* Empty fifolog */
+ f->seq = random();
} else {
- i = fifolog_int_read(f->ff, o);
- if (i)
- return ("Read error, looking for seq");
- f->seq = be32dec(f->ff->recbuf) + 1;
f->recno = o + 1;
+ f->seq++;
}
f->ibufsize = 32768;
diff --git a/usr.sbin/fwcontrol/fwcontrol.c b/usr.sbin/fwcontrol/fwcontrol.c
index b55cf2a..eabbc23 100644
--- a/usr.sbin/fwcontrol/fwcontrol.c
+++ b/usr.sbin/fwcontrol/fwcontrol.c
@@ -1065,6 +1065,7 @@ main(int argc, char **argv)
if (recvfn == NULL) { /* guess... */
recvfn = detect_recv_fn(fd, TAG | CHANNEL);
close(fd);
+ fd = -1;
}
snprintf(devbase, sizeof(devbase), "%s%d.0", device_string, current_board);
if (open_dev(&fd, devbase) < 0)
diff --git a/usr.sbin/fwcontrol/fwdv.c b/usr.sbin/fwcontrol/fwdv.c
index 7b749e6..23237e5 100644
--- a/usr.sbin/fwcontrol/fwdv.c
+++ b/usr.sbin/fwcontrol/fwdv.c
@@ -202,15 +202,20 @@ again:
(dv->payload[0] & DV_DSF_12) == 0)
dv->payload[0] |= DV_DSF_12;
nb = nblocks[system];
- fprintf(stderr, "%d", k%10);
+ fprintf(stderr, "%d:%02d:%02d %d\r",
+ k / (3600 * frame_rate[system]),
+ (k / (60 * frame_rate[system])) % 60,
+ (k / frame_rate[system]) % 60,
+ k % frame_rate[system]);
+
#if FIX_FRAME
if (m > 0 && m != nb) {
/* padding bad frame */
npad = ((nb - m) % nb);
if (npad < 0)
npad += nb;
- fprintf(stderr, "(%d blocks padded)",
- npad);
+ fprintf(stderr, "\n%d blocks padded\n",
+ npad);
npad *= DSIZE;
wbuf[vec].iov_base = pad;
wbuf[vec++].iov_len = npad;
@@ -221,10 +226,6 @@ again:
}
#endif
k++;
- if (k % frame_rate[system] == 0) {
- /* every second */
- fprintf(stderr, "\n");
- }
fflush(stderr);
m = 0;
}
@@ -245,9 +246,8 @@ next:
if (vec > 0)
writev(fd, wbuf, vec);
}
- if(fd != STDOUT_FILENO) {
+ if (fd != STDOUT_FILENO)
close(fd);
- }
fprintf(stderr, "\n");
}
diff --git a/usr.sbin/fwcontrol/fwmpegts.c b/usr.sbin/fwcontrol/fwmpegts.c
index d485819..e92b799 100644
--- a/usr.sbin/fwcontrol/fwmpegts.c
+++ b/usr.sbin/fwcontrol/fwmpegts.c
@@ -195,10 +195,9 @@ mpegtsrecv(int d, const char *filename, char ich, int count)
if (len < 0) {
if (errno == EAGAIN) {
fprintf(stderr, "(EAGAIN) - push 'Play'?\n");
- if (len <= 0)
- continue;
- } else
- err(1, "read failed");
+ continue;
+ }
+ err(1, "read failed");
}
ptr = (uint32_t *) buf;
diff --git a/usr.sbin/gssd/Makefile b/usr.sbin/gssd/Makefile
index ffdb5aa..45d8de4 100644
--- a/usr.sbin/gssd/Makefile
+++ b/usr.sbin/gssd/Makefile
@@ -2,7 +2,7 @@
PROG= gssd
MAN= gssd.8
-SRCS= gssd.c gssd_svc.c gssd_xdr.c gssd_prot.c
+SRCS= gssd.c gssd.h gssd_svc.c gssd_xdr.c gssd_prot.c
CFLAGS+= -I.
WARNS?= 1
diff --git a/usr.sbin/gssd/gssd.8 b/usr.sbin/gssd/gssd.8
index 4a53f6d..c4704a1 100644
--- a/usr.sbin/gssd/gssd.8
+++ b/usr.sbin/gssd/gssd.8
@@ -25,8 +25,6 @@
.\"
.\" $FreeBSD$
.\"
-.\" Note: The date here should be updated whenever a non-trivial
-.\" change is made to the manual page.
.Dd November 5, 2008
.Dt GSSD 8
.Os
diff --git a/usr.sbin/i2c/Makefile b/usr.sbin/i2c/Makefile
new file mode 100644
index 0000000..9f377e6
--- /dev/null
+++ b/usr.sbin/i2c/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= i2c
+MAN= i2c.8
+
+WARNS?= 2
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/i2c/i2c.8 b/usr.sbin/i2c/i2c.8
new file mode 100644
index 0000000..0067be7
--- /dev/null
+++ b/usr.sbin/i2c/i2c.8
@@ -0,0 +1,168 @@
+.\"
+.\" Copyright (C) 2008-2009 Semihalf, Michal Hajduk and Bartlomiej Sieka
+.\" 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 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 Jan 23, 2009
+.Dt I2C 8
+.Os
+.Sh NAME
+.Nm i2c
+.Nd test I2C bus and slave devices
+.Sh SYNOPSIS
+.Nm
+.Cm -a Ar address
+.Op Fl f Ar device
+.Op Fl d Ar r|w
+.Op Fl w Ar 0|8|16
+.Op Fl o Ar offset
+.Op Fl c Ar count
+.Op Fl m Ar ss|rs|no
+.Op Fl b
+.Op Fl v
+.Nm
+.Cm -s
+.Op Fl f Ar device
+.Op Fl n Ar skip_addr
+.Op Fl v
+.Nm
+.Cm -r
+.Op Fl f Ar device
+.Op Fl v
+.Sh DESCRIPTION
+The
+.Nm
+utility can be used to perform raw data transfers (read or write) with devices
+on the I2C bus. It can also scan the bus for available devices and reset the
+I2C controller.
+.Pp
+The options are as follows:
+.Bl -tag -width ".Fl d Ar direction"
+.It Fl a Ar address
+7-bit address on the I2C device to operate on (hex).
+.It Fl b
+binary mode - when performing a read operation, the data read from the device
+is output in binary format on stdout; when doing a write, the binary data to
+be written to the device is read from stdin.
+.It Fl c Ar count
+number of bytes to transfer (dec).
+.It Fl d Ar r|w
+transfer direction: r - read, w - write.
+.It Fl f Ar device
+I2C bus to use (default is /dev/iic0).
+.It Fl m Ar ss|rs|no
+addressing mode, i.e., I2C bus operations performed after the offset for the
+transfer has been written to the device and before the actual read/write
+operation. rs - repeated start; ss - stop start; no - none.
+.It Fl n Ar skip_addr
+skip address - address(es) to be skipped during bus scan.
+The are two ways to specify addresses to ignore: by range 'a..b' or
+using selected addresses 'a:b:c'. This option is available only when "-s" is
+used.
+.It Fl o Ar offset
+offset within the device for data transfer (hex).
+.It Fl r
+reset the controller.
+.It Fl s
+scan the bus for devices.
+.It Fl v
+be verbose
+.It Fl w Ar 0|8|16
+device addressing width (in bits).
+.El
+.Sh WARNINGS
+Great care must be taken when manipulating slave I2C devices with the
+.Nm
+utility. Often times important configuration data for the system is kept in
+non-volatile but write enabled memories located on the I2C bus, for example
+Ethernet hardware addresses, RAM module parameters (SPD), processor reset
+configuration word etc.
+.Pp
+It is very easy to render the whole system unusable when such configuration
+data is deleted or altered, so use the
+.Dq -d w
+(write) command only if you know exactly what you are doing.
+.Pp
+Also avoid ungraceful interrupting of an ongoing transaction on the I2C bus,
+as it can lead to potentially dangerous effects. Consider the following
+scenario: when the host CPU is reset (for whatever reason) in the middle of a
+started I2C transaction, the I2C slave device could be left in write mode
+waiting for data or offset to arrive. When the CPU reinitializes itself and
+talks to this I2C slave device again, the commands and other control info it
+sends are treated by the slave device as data or offset it was waiting for,
+and there's great potential for corruption if such a write is performed.
+.Sh EXAMPLES
+.Pp
+.Bl -bullet
+.It
+Scan the default bus (/dev/iic0) for devices:
+.Pp
+i2c -s
+.It
+Scan the default bus (/dev/iic0) for devices and skip addresses 0x56 and
+0x45.
+.Pp
+i2c -s -n 0x56:0x45
+.It
+Scan the default bus (/dev/iic0) for devices and skip address range
+0x34 to 0x56.
+.Pp
+i2c -s -n 0x34..0x56
+.It
+Read 8 bytes of data from device at address 0x56 (e.g., an EEPROM):
+.Pp
+i2c -a 0x56 -d r -c 8
+.It
+Write 16 bytes of data from file data.bin to device 0x56 at offset 0x10:
+.Pp
+i2c -a 0x56 -d w -c 16 -o 0x10 -b < data.bin
+.It
+Copy 4 bytes between two EEPROMs (0x56 on /dev/iic1 to 0x57 on /dev/iic0):
+.Pp
+i2c -a 0x56 -f /dev/iic1 -d r -c 0x4 -b | i2c -a 0x57 -f /dev/iic0 -d w -c 4 -b
+.It
+Reset the controller:
+.Pp
+i2c -f /dev/iic1 -r
+.El
+.Sh SEE ALSO
+.Xr iic 4 ,
+.Xr iicbus 4
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+utility and this manual page were written by
+.An Bartlomiej Sieka
+.Aq tur@semihalf.com
+and
+.An Michal Hajduk
+.Aq mih@semihalf.com .
diff --git a/usr.sbin/i2c/i2c.c b/usr.sbin/i2c/i2c.c
new file mode 100644
index 0000000..c0b3663
--- /dev/null
+++ b/usr.sbin/i2c/i2c.c
@@ -0,0 +1,633 @@
+/*-
+ * Copyright (C) 2008-2009 Semihalf, Michal Hajduk and Bartlomiej Sieka
+ * 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 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 <err.h>
+#include <errno.h>
+#include <sysexits.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include <dev/iicbus/iic.h>
+
+#define I2C_DEV "/dev/iic0"
+#define I2C_MODE_NOTSET 0
+#define I2C_MODE_NONE 1
+#define I2C_MODE_STOP_START 2
+#define I2C_MODE_REPEATED_START 3
+
+struct options {
+ int width;
+ int count;
+ int verbose;
+ int addr_set;
+ int binary;
+ int scan;
+ int skip;
+ int reset;
+ int mode;
+ char dir;
+ uint32_t addr;
+ uint32_t off;
+};
+
+struct skip_range {
+ int start;
+ int end;
+};
+
+__dead2 static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: %s -a addr [-f device] [-d [r|w]] [-o offset] "
+ "[-w [0|8|16]] [-c count] [-m [ss|rs|no]] [-b] [-v]\n",
+ getprogname());
+ fprintf(stderr, " %s -s [-f device] [-n skip_addr] -v\n",
+ getprogname());
+ fprintf(stderr, " %s -r [-f device] -v\n", getprogname());
+ exit(EX_USAGE);
+}
+
+static struct skip_range
+skip_get_range(char *skip_addr)
+{
+ struct skip_range addr_range;
+ char *token;
+
+ addr_range.start = 0;
+ addr_range.end = 0;
+
+ token = strsep(&skip_addr, "..");
+ if (token) {
+ addr_range.start = strtoul(token, 0, 16);
+ token = strsep(&skip_addr, "..");
+ if ((token != NULL) && !atoi(token)) {
+ token = strsep(&skip_addr, "..");
+ if (token)
+ addr_range.end = strtoul(token, 0, 16);
+ }
+ }
+
+ return (addr_range);
+}
+
+/* Parse the string to get hex 7 bits addresses */
+static int
+skip_get_tokens(char *skip_addr, int *sk_addr, int max_index)
+{
+ char *token;
+ int i;
+
+ for (i = 0; i < max_index; i++) {
+ token = strsep(&skip_addr, ":");
+ if (token == NULL)
+ break;
+ sk_addr[i] = strtoul(token, 0, 16);
+ }
+ return (i);
+}
+
+static int
+scan_bus(struct iiccmd cmd, char *dev, int skip, char *skip_addr)
+{
+ struct skip_range addr_range = { 0, 0 };
+ int *tokens, fd, error, i, index, j;
+ int len = 0, do_skip = 0, no_range = 1;
+
+ fd = open(dev, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "Error opening I2C controller (%s) for "
+ "scanning: %s\n", dev, strerror(errno));
+ return (EX_NOINPUT);
+ }
+
+ if (skip) {
+ len = strlen(skip_addr);
+ if (strstr(skip_addr, "..") != NULL) {
+ addr_range = skip_get_range(skip_addr);
+ no_range = 0;
+ } else {
+ tokens = (int *)malloc((len / 2 + 1) * sizeof(int));
+ if (tokens == NULL) {
+ fprintf(stderr, "Error allocating tokens "
+ "buffer\n");
+ goto out;
+ }
+ index = skip_get_tokens(skip_addr, tokens,
+ len / 2 + 1);
+ }
+
+ if (!no_range && (addr_range.start > addr_range.end)) {
+ fprintf(stderr, "Skip address out of range\n");
+ goto out;
+ }
+ }
+
+ printf("Scanning I2C devices on %s: ", dev);
+ for (i = 1; i < 127; i++) {
+
+ if (skip && ( addr_range.start < addr_range.end)) {
+ if (i >= addr_range.start && i <= addr_range.end)
+ continue;
+
+ } else if (skip && no_range)
+ for (j = 0; j < index; j++) {
+ if (tokens[j] == i) {
+ do_skip = 1;
+ break;
+ }
+ }
+
+ if (do_skip) {
+ do_skip = 0;
+ continue;
+ }
+
+ cmd.slave = i << 1;
+ cmd.last = 1;
+ cmd.count = 0;
+ error = ioctl(fd, I2CRSTCARD, &cmd);
+ if (error)
+ goto out;
+
+ cmd.slave = i << 1;
+ cmd.last = 1;
+ error = ioctl(fd, I2CSTART, &cmd);
+ if (!error)
+ printf("%x ", i);
+ cmd.slave = i << 1;
+ cmd.last = 1;
+ error = ioctl(fd, I2CSTOP, &cmd);
+ }
+ printf("\n");
+
+ error = ioctl(fd, I2CRSTCARD, &cmd);
+out:
+ close(fd);
+ if (skip && no_range)
+ free(tokens);
+
+ if (error) {
+ fprintf(stderr, "Error scanning I2C controller (%s): %s\n",
+ dev, strerror(errno));
+ return (EX_NOINPUT);
+ } else
+ return (EX_OK);
+}
+
+static int
+reset_bus(struct iiccmd cmd, char *dev)
+{
+ int fd, error;
+
+ fd = open(dev, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "Error opening I2C controller (%s) for "
+ "resetting: %s\n", dev, strerror(errno));
+ return (EX_NOINPUT);
+ }
+
+ printf("Resetting I2C controller on %s: ", dev);
+ error = ioctl(fd, I2CRSTCARD, &cmd);
+ close (fd);
+
+ if (error) {
+ printf("error: %s\n", strerror(errno));
+ return (EX_IOERR);
+ } else {
+ printf("OK\n");
+ return (EX_OK);
+ }
+}
+
+static char *
+prepare_buf(int size, uint32_t off)
+{
+ char *buf;
+
+ buf = malloc(size);
+ if (buf == NULL)
+ return (buf);
+
+ if (size == 1)
+ buf[0] = off & 0xff;
+ else if (size == 2) {
+ buf[0] = (off >> 8) & 0xff;
+ buf[1] = off & 0xff;
+ }
+
+ return (buf);
+}
+
+static int
+i2c_write(char *dev, struct options i2c_opt, char *i2c_buf)
+{
+ struct iiccmd cmd;
+ int ch, i, error, fd, bufsize;
+ char *err_msg, *buf;
+
+ /*
+ * Read data to be written to the chip from stdin
+ */
+ if (i2c_opt.verbose && !i2c_opt.binary)
+ fprintf(stderr, "Enter %u bytes of data: ", i2c_opt.count);
+
+ for (i = 0; i < i2c_opt.count; i++) {
+ ch = getchar();
+ if (ch == EOF) {
+ free(i2c_buf);
+ err(1, "not enough data, exiting\n");
+ }
+ i2c_buf[i] = ch;
+ }
+
+ fd = open(dev, O_RDWR);
+ if (fd == -1) {
+ free(i2c_buf);
+ err(1, "open failed");
+ }
+
+ /*
+ * Write offset where the data will go
+ */
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTART, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending start condition";
+ goto err1;
+ }
+
+ if (i2c_opt.width) {
+ bufsize = i2c_opt.width / 8;
+ buf = prepare_buf(bufsize, i2c_opt.off);
+ if (buf == NULL) {
+ err_msg = "error: offset malloc";
+ goto err1;
+ }
+
+ cmd.count = bufsize;
+ cmd.buf = buf;
+ error = ioctl(fd, I2CWRITE, &cmd);
+ free(buf);
+ if (error == -1) {
+ err_msg = "ioctl: error when write offset";
+ goto err1;
+ }
+ }
+
+ /* Mode - stop start */
+ if (i2c_opt.mode == I2C_MODE_STOP_START) {
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTOP, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending stop condition";
+ goto err2;
+ }
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTART, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending start condition";
+ goto err1;
+ }
+ }
+ /* Mode - repeated start */
+ if (i2c_opt.mode == I2C_MODE_REPEATED_START) {
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CRPTSTART, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending repeated start "
+ "condition";
+ goto err1;
+ }
+ }
+
+ /*
+ * Write the data
+ */
+ cmd.count = i2c_opt.count;
+ cmd.buf = i2c_buf;
+ cmd.last = 0;
+ error = ioctl(fd, I2CWRITE, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error when write";
+ goto err1;
+ }
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTOP, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending stop condition";
+ goto err2;
+ }
+
+ close(fd);
+ return (0);
+
+err1:
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTOP, &cmd);
+ if (error == -1)
+ fprintf(stderr, "error sending stop condtion\n");
+err2:
+ if (err_msg)
+ fprintf(stderr, err_msg);
+
+ close(fd);
+ return (1);
+}
+
+static int
+i2c_read(char *dev, struct options i2c_opt, char *i2c_buf)
+{
+ struct iiccmd cmd;
+ int i, fd, error, bufsize;
+ char *err_msg, data = 0, *buf;
+
+ fd = open(dev, O_RDWR);
+ if (fd == -1)
+ err(1, "open failed");
+
+ bzero(&cmd, sizeof(cmd));
+
+ if (i2c_opt.width) {
+ cmd.slave = i2c_opt.addr;
+ cmd.count = 1;
+ cmd.last = 0;
+ cmd.buf = &data;
+ error = ioctl(fd, I2CSTART, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending start condition";
+ goto err1;
+ }
+ bufsize = i2c_opt.width / 8;
+ buf = prepare_buf(bufsize, i2c_opt.off);
+ if (buf == NULL) {
+ err_msg = "error: offset malloc";
+ goto err1;
+ }
+
+ cmd.count = bufsize;
+ cmd.buf = buf;
+ cmd.last = 0;
+ error = ioctl(fd, I2CWRITE, &cmd);
+ free(buf);
+ if (error == -1) {
+ err_msg = "ioctl: error when write offset";
+ goto err1;
+ }
+
+ if (i2c_opt.mode == I2C_MODE_STOP_START) {
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTOP, &cmd);
+ if (error == -1)
+ goto err2;
+ }
+ }
+ cmd.slave = i2c_opt.addr;
+ cmd.count = 1;
+ cmd.last = 0;
+ cmd.buf = &data;
+ if (i2c_opt.mode == I2C_MODE_STOP_START) {
+ error = ioctl(fd, I2CSTART, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending start condition";
+ goto err1;
+ }
+ } else if (i2c_opt.mode == I2C_MODE_REPEATED_START) {
+ error = ioctl(fd, I2CRPTSTART, &cmd);
+ if (error == -1) {
+ err_msg = "ioctl: error sending repeated start "
+ "condition";
+ goto err1;
+ }
+ }
+ error = ioctl(fd, I2CSTOP, &cmd);
+ if (error == -1)
+ goto err2;
+
+ for (i = 0; i < i2c_opt.count; i++) {
+ error = read(fd, &i2c_buf[i], 1);
+ if (error == -1) {
+ err_msg = "ioctl: error while reading";
+ goto err1;
+ }
+ }
+
+ close(fd);
+ return (0);
+
+err1:
+ cmd.slave = i2c_opt.addr;
+ error = ioctl(fd, I2CSTOP, &cmd);
+ if (error == -1)
+ fprintf(stderr, "error sending stop condtion\n");
+err2:
+ if (err_msg)
+ fprintf(stderr, err_msg);
+
+ close(fd);
+ return (1);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct iiccmd cmd;
+ struct options i2c_opt;
+ char *dev, *skip_addr, *err_msg, *i2c_buf;
+ int error, chunk_size, i, j, ch;
+
+ errno = 0;
+ error = 0;
+
+ /* Line-break the output every chunk_size bytes */
+ chunk_size = 16;
+
+ dev = I2C_DEV;
+ err_msg = NULL;
+
+ /* Default values */
+ i2c_opt.addr_set = 0;
+ i2c_opt.off = 0;
+ i2c_opt.verbose = 0;
+ i2c_opt.dir = 'r'; /* direction = read */
+ i2c_opt.width = 8;
+ i2c_opt.count = 1;
+ i2c_opt.binary = 0; /* ASCII text output */
+ i2c_opt.scan = 0; /* no bus scan */
+ i2c_opt.skip = 0; /* scan all addresses */
+ i2c_opt.reset = 0; /* no bus reset */
+ i2c_opt.mode = I2C_MODE_NOTSET;
+
+ while ((ch = getopt(argc, argv, "a:f:d:o:w:c:m:n:sbvrh")) != -1) {
+ switch(ch) {
+ case 'a':
+ i2c_opt.addr = (strtoul(optarg, 0, 16) << 1);
+ if (i2c_opt.addr == 0 && errno == EINVAL)
+ i2c_opt.addr_set = 0;
+ else
+ i2c_opt.addr_set = 1;
+ break;
+ case 'f':
+ dev = optarg;
+ break;
+ case 'd':
+ i2c_opt.dir = optarg[0];
+ break;
+ case 'o':
+ i2c_opt.off = strtoul(optarg, 0, 16);
+ if (i2c_opt.off == 0 && errno == EINVAL)
+ error = 1;
+ break;
+ case 'w':
+ i2c_opt.width = atoi(optarg);
+ break;
+ case 'c':
+ i2c_opt.count = atoi(optarg);
+ break;
+ case 'm':
+ if (!strcmp(optarg, "no"))
+ i2c_opt.mode = I2C_MODE_NONE;
+ else if (!strcmp(optarg, "ss"))
+ i2c_opt.mode = I2C_MODE_STOP_START;
+ else if (!strcmp(optarg, "rs"))
+ i2c_opt.mode = I2C_MODE_REPEATED_START;
+ else
+ usage();
+ break;
+ case 'n':
+ i2c_opt.skip = 1;
+ skip_addr = optarg;
+ break;
+ case 's':
+ i2c_opt.scan = 1;
+ break;
+ case 'b':
+ i2c_opt.binary = 1;
+ break;
+ case 'v':
+ i2c_opt.verbose = 1;
+ break;
+ case 'r':
+ i2c_opt.reset = 1;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /* Set default mode if option -m is not specified */
+ if (i2c_opt.mode == I2C_MODE_NOTSET) {
+ if (i2c_opt.dir == 'r')
+ i2c_opt.mode = I2C_MODE_STOP_START;
+ else if (i2c_opt.dir == 'w')
+ i2c_opt.mode = I2C_MODE_NONE;
+ }
+
+ /* Basic sanity check of command line arguments */
+ if (i2c_opt.scan) {
+ if (i2c_opt.addr_set)
+ usage();
+ } else if (i2c_opt.reset) {
+ if (i2c_opt.addr_set)
+ usage();
+ } else if (error) {
+ usage();
+ } else if ((i2c_opt.dir == 'r' || i2c_opt.dir == 'w')) {
+ if ((i2c_opt.addr_set == 0) ||
+ !(i2c_opt.width == 0 || i2c_opt.width == 8 ||
+ i2c_opt.width == 16))
+ usage();
+ }
+
+ if (i2c_opt.verbose)
+ fprintf(stderr, "dev: %s, addr: 0x%x, r/w: %c, "
+ "offset: 0x%02x, width: %u, count: %u\n", dev,
+ i2c_opt.addr >> 1, i2c_opt.dir, i2c_opt.off,
+ i2c_opt.width, i2c_opt.count);
+
+ if (i2c_opt.scan)
+ exit(scan_bus(cmd, dev, i2c_opt.skip, skip_addr));
+
+ if (i2c_opt.reset)
+ exit(reset_bus(cmd, dev));
+
+ i2c_buf = malloc(i2c_opt.count);
+ if (i2c_buf == NULL)
+ err(1, "data malloc");
+
+ if (i2c_opt.dir == 'w') {
+ error = i2c_write(dev, i2c_opt, i2c_buf);
+ if (error) {
+ free(i2c_buf);
+ return (1);
+ }
+ }
+ if (i2c_opt.dir == 'r') {
+ error = i2c_read(dev, i2c_opt, i2c_buf);
+ if (error) {
+ free(i2c_buf);
+ return (1);
+ }
+ }
+
+ if (i2c_opt.verbose)
+ fprintf(stderr, "\nData %s (hex):\n", i2c_opt.dir == 'r' ?
+ "read" : "written");
+
+ i = 0;
+ j = 0;
+ while (i < i2c_opt.count) {
+ if (i2c_opt.verbose || (i2c_opt.dir == 'r' &&
+ !i2c_opt.binary))
+ fprintf (stderr, "%02hhx ", i2c_buf[i++]);
+
+ if (i2c_opt.dir == 'r' && i2c_opt.binary) {
+ fprintf(stdout, "%c", i2c_buf[j++]);
+ if(!i2c_opt.verbose)
+ i++;
+ }
+ if (!i2c_opt.verbose && (i2c_opt.dir == 'w'))
+ break;
+ if ((i % chunk_size) == 0)
+ fprintf(stderr, "\n");
+ }
+ if ((i % chunk_size) != 0)
+ fprintf(stderr, "\n");
+
+ free(i2c_buf);
+ return (0);
+}
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 95af6ec..3a0767e 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 29, 2008
+.Dd January 24, 2009
.Dt JAIL 8
.Os
.Sh NAME
@@ -63,9 +63,11 @@ to the list of
for this prison.
This may affect default address selection for outgoing IPv4 connections
of prisons.
-The address first returned by the resolver for the IPv4 address family
-will be used as default.
-For IPv6 source address selection is done by a well defined algorithm.
+The address first returned by the resolver for each address family
+will be used as primary address.
+See
+.Va ip-addresses
+further down for details.
.It Fl i
Output the jail identifier of the newly created jail.
.It Fl n Ar jailname
@@ -480,6 +482,29 @@ pkill -j 3
or:
.Pp
.Dl "killall -j 3"
+.Ss "Jails and File Systems"
+It is not possible to
+.Xr mount 8
+or
+.Xr umount 8
+any file system inside a jail unless the file system is marked
+jail-friendly.
+See
+.Va security.jail.mount_allowed
+in the
+.Va "Sysctl MIB Entries"
+section.
+.Pp
+Multiple jails sharing the same file system can influence each other.
+For example a user in one jail can fill the file system also
+leaving no space for processes in the other jail.
+Trying to use
+.Xr quota 1
+to prevent this will not work either as the file system quotas
+are not aware of jails but only look at the user and group IDs.
+This means the same user ID in two jails share the same file
+system quota.
+One would need to use one file system per jail to make this working.
.Ss "Sysctl MIB Entries"
Certain aspects of the jail containments environment may be modified from
the host environment using
@@ -614,6 +639,7 @@ and
.Xr pgrep 1 ,
.Xr pkill 1 ,
.Xr ps 1 ,
+.Xr quota 1 ,
.Xr chroot 2 ,
.Xr jail 2 ,
.Xr jail_attach 2 ,
@@ -632,7 +658,8 @@ and
.Xr sendmail 8 ,
.Xr shutdown 8 ,
.Xr sysctl 8 ,
-.Xr syslogd 8
+.Xr syslogd 8 ,
+.Xr umount 8
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/kldxref/ef_i386.c b/usr.sbin/kldxref/ef_i386.c
index 4917354..9b10c7d 100644
--- a/usr.sbin/kldxref/ef_i386.c
+++ b/usr.sbin/kldxref/ef_i386.c
@@ -43,12 +43,13 @@
*/
int
ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase,
- Elf_Off dataoff, size_t len, void *dest)
+ Elf_Off dataoff, size_t len, void *_dest)
{
Elf_Addr *where, addr, addend;
Elf_Size rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
+ char *dest = _dest;
switch (reltype) {
case EF_RELOC_REL:
diff --git a/usr.sbin/kldxref/ef_obj.c b/usr.sbin/kldxref/ef_obj.c
index f58fa37..5a4ae22 100644
--- a/usr.sbin/kldxref/ef_obj.c
+++ b/usr.sbin/kldxref/ef_obj.c
@@ -133,7 +133,7 @@ static struct elf_file_ops ef_obj_file_ops = {
};
static int
-ef_obj_get_type(elf_file_t ef)
+ef_obj_get_type(elf_file_t __unused ef)
{
return (EFT_KLD);
@@ -180,7 +180,7 @@ ef_obj_symaddr(elf_file_t ef, Elf_Size symidx)
{
const Elf_Sym *sym;
- if (symidx >= ef->ddbsymcnt)
+ if (symidx >= (size_t) ef->ddbsymcnt)
return (0);
sym = ef->ddbsymtab + symidx;
diff --git a/usr.sbin/kldxref/fileformat b/usr.sbin/kldxref/fileformat
index 2eddcca..81d115c 100644
--- a/usr.sbin/kldxref/fileformat
+++ b/usr.sbin/kldxref/fileformat
@@ -1,7 +1,9 @@
$FreeBSD$
- linker.hints file consists from the one or more records. First record of
-file is special and determines its version:
+linker.hints file consists from the one or more records,
+and is processed by sys/kern/kern_linker.c::linker_hints_lookup()
+
+First record of file is special and determines its version:
int version;
@@ -16,25 +18,28 @@ struct record {
'data' determines its type:
struct data {
- int type; /* type of data. currently MTD_* values */
+ int type; /* type of data. currently MDT_* values */
};
The rest of record depends on the type.
struct string {
- int length; /* length of string */
+ uint8_t length; /* length of string */
char val[]; /* string itself (no terminating zero) */
};
struct data_mdt_version {
int type = MDT_VERSION;
struct string modname;
+ /* padding */
int version;
struct string kldname;
+ /* padding */
};
struct data_mdt_module {
- int type = MDT_VERSION;
+ int type = MDT_MODULE;
struct string modname;
struct string kldname;
+ /* padding */
};
diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c
index 3ad0bd8..b4de191 100644
--- a/usr.sbin/kldxref/kldxref.c
+++ b/usr.sbin/kldxref/kldxref.c
@@ -57,37 +57,19 @@
#define MAXRECSIZE 1024
#define check(val) if ((error = (val)) != 0) break
-#ifndef min
-#define min(a,b) (((a)<(b)) ? (a) : (b))
-#endif
+static int dflag; /* do not create a hint file, only write on stdout */
+static int verbose;
-struct mod_info {
- char* mi_name;
- int mi_ver;
- SLIST_ENTRY(mod_info) mi_next;
-};
-
-#ifdef notnow
-struct kld_info {
- char* k_filename;
- SLIST_HEAD(mod_list_head, mod_info) k_modules;
- SLIST_ENTRY(kld_info) k_next;
-};
-
-SLIST_HEAD(kld_list_head, kld_info) kldlist;
-#endif
-
-static int dflag, verbose;
-
-FILE *fxref;
+static FILE *fxref; /* current hints file */
static const char *xref_file = "linker.hints";
+/*
+ * A record is stored in the static buffer recbuf before going to disk.
+ */
static char recbuf[MAXRECSIZE];
-static int recpos, reccnt;
-
-FILE *maketempfile(char *, const char *);
-static void usage(void);
+static int recpos; /* current write position */
+static int reccnt; /* total record written to this file so far */
static void
intalign(void)
@@ -105,7 +87,7 @@ record_start(void)
static int
record_end(void)
{
- if (dflag || recpos == 0)
+ if (recpos == 0)
return 0;
reccnt++;
intalign();
@@ -123,6 +105,9 @@ record_buf(const void *buf, int size)
return 0;
}
+/*
+ * An int is stored in host order and aligned
+ */
static int
record_int(int val)
{
@@ -130,21 +115,21 @@ record_int(int val)
return record_buf(&val, sizeof(val));
}
-static int
-record_byte(u_char val)
-{
- return record_buf(&val, sizeof(val));
-}
-
+/*
+ * A string is stored as 1-byte length plus data, no padding
+ */
static int
record_string(const char *str)
{
- int len = strlen(str);
- int error;
-
+ int len, error;
+ u_char val;
+
if (dflag)
return 0;
- error = record_byte(len);
+ val = len = strlen(str);
+ if (len > 255)
+ errx(1, "string %s too long", str);
+ error = record_buf(&val, sizeof(val));
if (error)
return error;
return record_buf(str, len);
@@ -170,21 +155,23 @@ parse_entry(struct mod_metadata *md, const char *cval,
break;
case MDT_VERSION:
check(EF_SEG_READ(ef, data, sizeof(mdv), &mdv));
- record_int(MDT_VERSION);
- record_string(cval);
- record_int(mdv.mv_version);
- record_string(kldname);
- if (!dflag)
- break;
- printf(" interface %s.%d\n", cval, mdv.mv_version);
+ if (dflag) {
+ printf(" interface %s.%d\n", cval, mdv.mv_version);
+ } else {
+ record_int(MDT_VERSION);
+ record_string(cval);
+ record_int(mdv.mv_version);
+ record_string(kldname);
+ }
break;
case MDT_MODULE:
- record_int(MDT_MODULE);
- record_string(cval);
- record_string(kldname);
- if (!dflag)
- break;
- printf(" module %s\n", cval);
+ if (dflag) {
+ printf(" module %s\n", cval);
+ } else {
+ record_int(MDT_MODULE);
+ record_string(cval);
+ record_string(kldname);
+ }
break;
default:
warnx("unknown metadata record %d in file %s", md->md_type, kldname);
@@ -199,8 +186,6 @@ read_kld(char *filename, char *kldname)
{
struct mod_metadata md;
struct elf_file ef;
-/* struct kld_info *kip;
- struct mod_info *mip;*/
void **p, **orgp;
int error, eftype, nmlen;
long start, finish, entries;
@@ -224,8 +209,9 @@ read_kld(char *filename, char *kldname)
}
if (!dflag) {
cp = strrchr(kldname, '.');
- nmlen = cp ? min(MAXMODNAME, cp - kldname) :
- min(MAXMODNAME, strlen(kldname));
+ nmlen = (cp != NULL) ? cp - kldname : (int)strlen(kldname);
+ if (nmlen > MAXMODNAME)
+ nmlen = MAXMODNAME;
strlcpy(kldmodname, kldname, nmlen);
/* fprintf(fxref, "%s:%s:%d\n", kldmodname, kldname, 0);*/
}
@@ -252,27 +238,43 @@ read_kld(char *filename, char *kldname)
return error;
}
-FILE *
+/*
+ * Create a temp file in directory root, make sure we don't
+ * overflow the buffer for the destination name
+ */
+static FILE *
maketempfile(char *dest, const char *root)
{
char *p;
- int fd;
-
- strlcpy(dest, root, MAXPATHLEN);
+ int n, fd;
+
+ p = strrchr(root, '/');
+ n = p != NULL ? p - root + 1 : 0;
+ if (snprintf(dest, MAXPATHLEN, "%.*slhint.XXXXXX", n, root) >=
+ MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ return NULL;
+ }
- if ((p = strrchr(dest, '/')) != 0)
- p++;
- else
- p = dest;
- strcpy(p, "lhint.XXXXXX");
fd = mkstemp(dest);
- if (fd >= 0)
- fchmod(fd, 0644); /* nothing secret in the file */
- return ((fd == -1) ? NULL : fdopen(fd, "w+"));
+ if (fd < 0)
+ return NULL;
+ fchmod(fd, 0644); /* nothing secret in the file */
+ return fdopen(fd, "w+");
}
static char xrefname[MAXPATHLEN], tempname[MAXPATHLEN];
+static void
+usage(void)
+{
+
+ fprintf(stderr, "%s\n",
+ "usage: kldxref [-Rdv] [-f hintsfile] path ..."
+ );
+ exit(1);
+}
+
int
main(int argc, char *argv[])
{
@@ -282,20 +284,19 @@ main(int argc, char *argv[])
struct stat sb;
fts_options = FTS_PHYSICAL;
-/* SLIST_INIT(&kldlist);*/
while ((opt = getopt(argc, argv, "Rdf:v")) != -1) {
switch (opt) {
- case 'd':
+ case 'd': /* no hint file, only print on stdout */
dflag = 1;
break;
- case 'f':
+ case 'f': /* use this name instead of linker.hints */
xref_file = optarg;
break;
case 'v':
verbose++;
break;
- case 'R':
+ case 'R': /* recurse on directories */
fts_options |= FTS_COMFOLLOW;
break;
default:
@@ -321,19 +322,22 @@ main(int argc, char *argv[])
for (;;) {
p = fts_read(ftsp);
- if ((p == NULL || p->fts_info == FTS_D) && !dflag && fxref) {
+ if ((p == NULL || p->fts_info == FTS_D) && fxref) {
+ /* close and rename the current hint file */
fclose(fxref);
fxref = NULL;
if (reccnt) {
rename(tempname, xrefname);
} else {
+ /* didn't find any entry, ignore this file */
unlink(tempname);
unlink(xrefname);
}
}
if (p == NULL)
break;
- if (p && p->fts_info == FTS_D && !dflag) {
+ if (p->fts_info == FTS_D && !dflag) {
+ /* visiting a new directory, create a new hint file */
snprintf(xrefname, sizeof(xrefname), "%s/%s",
ftsp->fts_path, xref_file);
fxref = maketempfile(tempname, ftsp->fts_path);
@@ -343,6 +347,7 @@ main(int argc, char *argv[])
fwrite(&ival, sizeof(ival), 1, fxref);
reccnt = 0;
}
+ /* skip non-files or .symbols entries */
if (p->fts_info != FTS_F)
continue;
if (p->fts_namelen >= 8 &&
@@ -353,13 +358,3 @@ main(int argc, char *argv[])
fts_close(ftsp);
return 0;
}
-
-static void
-usage(void)
-{
-
- fprintf(stderr, "%s\n",
- "usage: kldxref [-Rdv] [-f hintsfile] path ..."
- );
- exit(1);
-}
diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8
index 1d7b260..aaf7e54 100644
--- a/usr.sbin/mergemaster/mergemaster.8
+++ b/usr.sbin/mergemaster/mergemaster.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1998-2003 Douglas Barton
+.\" Copyright (c) 1998-2009 Douglas Barton
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 4, 2006
+.Dd January 2, 2009
.Dt MERGEMASTER 8
.Os
.Sh NAME
@@ -32,14 +32,14 @@
.Nd merge configuration files, et al during an upgrade
.Sh SYNOPSIS
.Nm
-.Op Fl scrvahipCPU
+.Op Fl achiprsvCPU
+.Op Fl A Ar Target architecture
+.Op Fl D Ar /destdir/path
.Op Fl m Ar /path/to/sources
.Op Fl t Ar /path/to/temp/root
.Op Fl d
.Op Fl u Ar N
.Op Fl w Ar N
-.Op Fl A Ar architecture
-.Op Fl D Ar /path
.Sh DESCRIPTION
The
.Nm
@@ -54,7 +54,7 @@ recommended that you back up your
directory before beginning this process.
.Pp
The script uses
-.Pa /usr/src/etc/Makefile
+.Pa /usr/src/Makefile
to build a temporary root environment from
.Pa /
down, populating that environment with the various
@@ -218,6 +218,14 @@ Specify the path to the directory where you want to do the
.Xr make 1 .
(In other words, where your sources are, but -s was already
taken.)
+In previous versions of
+.Nm
+you needed to specify the path all the way to
+.Pa src/etc .
+Starting with r186678 you only need to specify the path to
+.Pa src .
+.Nm
+will convert the path for you if you use the old method.
.It Fl t Ar /path/to/temp/root
Create the temporary root environment in
.Pa /path/to/temp/root
@@ -236,7 +244,7 @@ Supply an alternate screen width to the
.Xr sdiff 1
command in numbers of columns.
The default is 80.
-.It Fl A Ar architecture
+.It Fl A Ar Target architecture
Specify an alternative
.Ev TARGET_ARCH
architecture name.
@@ -294,18 +302,24 @@ with all values commented out:
# These are options for mergemaster, with their default values listed
# The following options have command line overrides
#
+# The target architecture (unset by default)
+#ARCHSTRING='TARGET_ARCH=<foo>'
+#
+# Sourcedir is the directory to do the 'make' in (where the new files are)
+#SOURCEDIR='/usr/src'
+#
# Directory to install the temporary root environment into
#TEMPROOT='/var/tmp/temproot'
#
+# Specify the destination directory for the installed files
+#DESTDIR=
+#
# Strict comparison bypasses the CVS $Id tests and compares every file
#STRICT=no
#
# Type of diff, such as unified, context, etc.
#DIFF_FLAG='-u'
#
-# Additional options for diff. This will get unset when using -s.
-#DIFF_OPTIONS='-I$\&FreeBSD:.*[$]' # Ignores CVS Id tags
-#
# Verbose mode includes more details and additional checks
#VERBOSE=
#
@@ -322,25 +336,26 @@ with all values commented out:
#PRESERVE_FILES=yes
#PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
#
-# Sourcedir is the directory to do the 'make' in (where the new files are)
-#SOURCEDIR='/usr/src/etc'
-#
# The umask for mergemaster to compare the default file's modes to
#NEW_UMASK=022
#
-# Specify the destination directory for the installed files
-#DESTDIR=
-#
# The following options have no command line overrides
+#
+# Files to always avoid comparing
+#IGNORE_FILES='/etc/motd /etc/printcap foo bar'
+#
+# Additional options for diff. This will get unset when using -s.
+#DIFF_OPTIONS='-I$\&FreeBSD:.*[$]' # Ignores CVS Id tags
+#
+# Location to store the list of mtree values for AUTO_UPGRADE purposes
+#MTREEDB='/var/db'
+#
# For those who just cannot stand including the full path to PAGER
#DONT_CHECK_PAGER=
#
# If you set 'yes' above, make sure to include the PATH to your pager
#PATH=/bin:/usr/bin:/usr/sbin
#
-# Don't compare the old and new motd files
-#IGNORE_MOTD=yes
-#
# Specify the path to scripts to run before the comparison starts,
# and/or after the script has finished its work
#MM_PRE_COMPARE_SCRIPT=
@@ -357,6 +372,11 @@ Invalid command line option
Failure to create the temporary root environment
.Pp
Failure to populate the temporary root
+.Pp
+Presence of the 'nodev' option in
+.Pa <DESTDIR>/etc/fstab
+.Pp
+Failure to install a file
.Sh EXAMPLES
Typically all you will need to do is type
.Nm
diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh
index f8504ec..2f2f55b 100755
--- a/usr.sbin/mergemaster/mergemaster.sh
+++ b/usr.sbin/mergemaster/mergemaster.sh
@@ -5,7 +5,7 @@
# Compare files created by /usr/src/etc/Makefile (or the directory
# the user specifies) with the currently installed copies.
-# Copyright 1998-2004 Douglas Barton
+# Copyright 1998-2009 Douglas Barton
# DougB@FreeBSD.org
# $FreeBSD$
@@ -244,10 +244,6 @@ press_to_continue () {
#
TEMPROOT='/var/tmp/temproot'
-# Assign the location of the mtree database
-#
-MTREEDB='/var/db/mergemaster.mtree'
-
# Read /etc/mergemaster.rc first so the one in $HOME can override
#
if [ -r /etc/mergemaster.rc ]; then
@@ -260,12 +256,17 @@ if [ -r "$HOME/.mergemasterrc" ]; then
. "$HOME/.mergemasterrc"
fi
+# Assign the location of the mtree database
+#
+MTREEDB=${MTREEDB:-/var/db}
+MTREEFILE="${MTREEDB}/mergemaster.mtree"
+
# Check the command line options
#
while getopts ":ascrvhipCPm:t:du:w:D:A:U" COMMAND_LINE_ARGUMENT ; do
case "${COMMAND_LINE_ARGUMENT}" in
A)
- ARCHSTRING='MACHINE_ARCH='${OPTARG}
+ ARCHSTRING='TARGET_ARCH='${OPTARG}
;;
U)
AUTO_UPGRADE=yes
@@ -338,10 +339,30 @@ if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then
PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
fi
-# Check the for the mtree database in DESTDIR.
-if [ ! -f ${DESTDIR}${MTREEDB} ]; then
- echo "*** Unable to find mtree database. Skipping auto-upgrade."
- unset AUTO_UPGRADE
+# Check for the mtree database in DESTDIR
+case "${AUTO_UPGRADE}" in
+'') ;; # If the option is not set no need to run the test or warn the user
+*)
+ if [ ! -f "${DESTDIR}${MTREEFILE}" ]; then
+ echo ''
+ echo "*** Unable to find mtree database. Skipping auto-upgrade."
+ echo ''
+ press_to_continue
+ unset AUTO_UPGRADE
+ fi
+ ;;
+esac
+
+if [ -e "${DESTDIR}/etc/fstab" ]; then
+ if grep -q nodev ${DESTDIR}/etc/fstab; then
+ echo ''
+ echo "*** You have the deprecated 'nodev' option in ${DESTDIR}/etc/fstab."
+ echo " This can prevent the filesystem from being mounted on reboot."
+ echo " Please update your fstab before continuing."
+ echo " See fstab(5) for more information."
+ echo ''
+ exit 1
+ fi
fi
echo ''
@@ -350,7 +371,8 @@ echo ''
#
case "${DONT_CHECK_PAGER}" in
'')
- while ! type "${PAGER%% *}" >/dev/null && [ -n "${PAGER}" ]; do
+check_pager () {
+ while ! type "${PAGER%% *}" >/dev/null; do
echo " *** Your PAGER environment variable specifies '${PAGER}', but"
echo " due to the limited PATH that I use for security reasons,"
echo " I cannot execute it. So, what would you like to do?"
@@ -392,6 +414,10 @@ case "${DONT_CHECK_PAGER}" in
esac
echo ''
done
+}
+ if [ -n "${PAGER}" ]; then
+ check_pager
+ fi
;;
esac
@@ -412,14 +438,25 @@ DIFF_FLAG=${DIFF_FLAG:--u}
# Assign the source directory
#
-SOURCEDIR=${SOURCEDIR:-/usr/src/etc}
+SOURCEDIR=${SOURCEDIR:-/usr/src}
+if [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \
+ -f ${SOURCEDIR}/../Makefile.inc1 ]; then
+ echo " *** The source directory you specified (${SOURCEDIR})"
+ echo " will be reset to ${SOURCEDIR}/.."
+ echo ''
+ sleep 3
+ SOURCEDIR=${SOURCEDIR}/..
+fi
+
+# Setup make to use system files from SOURCEDIR
+MM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk"
# Check DESTDIR against the mergemaster mtree database to see what
# files the user changed from the reference files.
#
CHANGED=
-if [ -n "${AUTO_UPGRADE}" -a -f "${DESTDIR}${MTREEDB}" ]; then
- for file in `mtree -eq -f ${DESTDIR}${MTREEDB} -p ${DESTDIR}/ \
+if [ -n "${AUTO_UPGRADE}" -a -f "${DESTDIR}${MTREEFILE}" ]; then
+ for file in `mtree -eq -f ${DESTDIR}${MTREEFILE} -p ${DESTDIR}/ \
2>/dev/null | awk '($2 == "changed") {print $1}'`; do
if [ -f "${DESTDIR}/$file" ]; then
CHANGED="${CHANGED} ${DESTDIR}/$file"
@@ -552,14 +589,14 @@ case "${RERUN}" in
case "${DESTDIR}" in
'') ;;
*)
- make DESTDIR=${DESTDIR} ${ARCHSTRING} distrib-dirs
+ ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs
;;
esac
- make DESTDIR=${TEMPROOT} ${ARCHSTRING} distrib-dirs &&
- MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj make ${ARCHSTRING} obj &&
- MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj make ${ARCHSTRING} all &&
- MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj make ${ARCHSTRING} \
- DESTDIR=${TEMPROOT} distribution;} ||
+ od=${TEMPROOT}/usr/obj
+ ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs &&
+ MAKEOBJDIRPREFIX=$od ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc &&
+ MAKEOBJDIRPREFIX=$od ${MM_MAKE} everything SUBDIR_OVERRIDE=etc &&
+ MAKEOBJDIRPREFIX=$od ${MM_MAKE} DESTDIR=${TEMPROOT} distribution;} ||
{ echo '';
echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to";
echo " the temproot environment";
@@ -569,8 +606,8 @@ case "${RERUN}" in
*)
# Only set up files that are crucial to {build|install}world
{ mkdir -p ${TEMPROOT}/etc &&
- cp -p ${SOURCEDIR}/master.passwd ${TEMPROOT}/etc &&
- cp -p ${SOURCEDIR}/group ${TEMPROOT}/etc;} ||
+ cp -p ${SOURCEDIR}/etc/master.passwd ${TEMPROOT}/etc &&
+ cp -p ${SOURCEDIR}/etc/group ${TEMPROOT}/etc;} ||
{ echo '';
echo ' *** FATAL ERROR: Cannot copy files to the temproot environment';
echo '';
@@ -599,17 +636,23 @@ case "${RERUN}" in
esac
# Avoid comparing the motd if the user specifies it in .mergemasterrc
+ # Compatibility shim to be removed in FreeBSD 9.x
case "${IGNORE_MOTD}" in
'') ;;
- *) rm -f ${TEMPROOT}/etc/motd
+ *) IGNORE_FILES="${IGNORE_FILES} /etc/motd"
+ echo ''
+ echo "*** You have the IGNORE_MOTD option set in your mergemaster rc file."
+ echo " This option is deprecated in favor of the IGNORE_FILES option."
+ echo " Please update your rc file accordingly."
+ echo ''
+ press_to_continue
;;
esac
- # Avoid trying to update MAKEDEV if /dev is on a devfs
- if /sbin/sysctl vfs.devfs.generation > /dev/null 2>&1 ; then
- rm -f ${TEMPROOT}/dev/MAKEDEV ${TEMPROOT}/dev/MAKEDEV.local
- fi
-
+ # Avoid comparing the following user specified files
+ for file in ${IGNORE_FILES}; do
+ test -e ${TEMPROOT}/${file} && unlink ${TEMPROOT}/${file}
+ done
;; # End of the "RERUN" test
esac
@@ -626,9 +669,9 @@ find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
# Build the mtree database in a temporary location.
-# TODO: Possibly use mktemp instead for security reasons?
+MTREENEW=`mktemp -t mergemaster.mtree`
case "${PRE_WORLD}" in
-'') mtree -ci -p ${TEMPROOT} -k size,md5digest > ${DESTDIR}${MTREEDB}.new 2>/dev/null
+'') mtree -ci -p ${TEMPROOT} -k size,md5digest > ${DESTDIR}${MTREENEW} 2>/dev/null
;;
*) # We don't want to mess with the mtree database on a pre-world run.
;;
@@ -647,7 +690,7 @@ if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then
echo ''
echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script"
echo " installs all files with the same user, group and modes that"
- echo " they are created with by ${SOURCEDIR}/Makefile, compared to"
+ echo " they are created with by ${SOURCEDIR}/etc/Makefile, compared to"
echo " a umask of 022. This umask allows world read permission when"
echo " the file's default permissions have it."
echo ''
@@ -714,6 +757,12 @@ esac
# Use the umask/mode information to install the files
# Create directories as needed
#
+install_error () {
+ echo "*** FATAL ERROR: Unable to install ${1} to ${2}"
+ echo ''
+ exit 1
+}
+
do_install_and_rm () {
case "${PRESERVE_FILES}" in
[Yy][Ee][Ss])
@@ -724,8 +773,15 @@ do_install_and_rm () {
;;
esac
- install -m "${1}" "${2}" "${3}" &&
- rm -f "${2}"
+ if [ ! -d "${3}/${2##*/}" ]; then
+ if install -m ${1} ${2} ${3}; then
+ unlink ${2}
+ else
+ install_error ${2} ${3}
+ fi
+ else
+ install_error ${2} ${3}
+ fi
}
# 4095 = "obase=10;ibase=8;07777" | bc
@@ -828,11 +884,6 @@ mm_install () {
;;
esac
else # File matched -x
- case "${1#.}" in
- /dev/MAKEDEV)
- NEED_MAKEDEV=yes
- ;;
- esac
do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
fi
return $?
@@ -904,7 +955,7 @@ if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then
fi
# Using -size +0 avoids uselessly checking the empty log files created
-# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does
+# by ${SOURCEDIR}/etc/Makefile and the device entries in ./dev, but does
# check the scripts in ./dev, as we'd like (assuming no devfs of course).
#
for COMPFILE in `find . -type f -size +0`; do
@@ -947,25 +998,6 @@ for COMPFILE in `find . -type f -size +0`; do
echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting"
rm "${COMPFILE}"
;;
-
- *)
- tempfoo=`basename $0`
- TMPFILE1=`mktemp -t ${tempfoo}` || break
- TMPFILE2=`mktemp -t ${tempfoo}` || break
- sed "s/[$]${CVS_ID_TAG}:.*[$]//g" "${DESTDIR}${COMPFILE#.}" > "${TMPFILE1}"
- sed "s/[$]${CVS_ID_TAG}:.*[$]//g" "${COMPFILE}" > "${TMPFILE2}"
- if diff -q ${DIFF_OPTIONS} "${TMPFILE1}" "${TMPFILE2}" > \
- /dev/null 2>&1; then
- echo " *** Temp ${COMPFILE} and installed are the same except CVS Id, replacing"
- if mm_install "${COMPFILE}"; then
- echo " *** ${COMPFILE} upgraded successfully"
- echo ''
- else
- echo " *** Problem upgrading ${COMPFILE}, it will remain to merge by hand"
- fi
- fi
- rm -f "${TMPFILE1}" "${TMPFILE2}"
- ;;
esac
;;
esac
@@ -1005,9 +1037,10 @@ done # This is for the do way up there at the beginning of the comparison
echo ''
echo "*** Comparison complete"
-if [ -f "${DESTDIR}${MTREEDB}.new" ]; then
+if [ -f "${DESTDIR}${MTREENEW}" ]; then
echo "*** Saving mtree database for future upgrades"
- mv -f ${DESTDIR}${MTREEDB}.new ${DESTDIR}${MTREEDB} 2>/dev/null
+ test -e "${MTREEFILE}" && unlink ${MTREEFILE}
+ mv ${DESTDIR}${MTREENEW} ${DESTDIR}${MTREEFILE}
fi
echo ''
@@ -1115,16 +1148,6 @@ run_it_now () {
esac
}
-case "${NEED_MAKEDEV}" in
-'') ;;
-*)
- echo ''
- echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script, so make sure that you run"
- echo " 'cd ${DESTDIR}/dev && /bin/sh MAKEDEV all' to rebuild your devices"
- run_it_now "cd ${DESTDIR}/dev && /bin/sh MAKEDEV all"
- ;;
-esac
-
case "${NEED_NEWALIASES}" in
'') ;;
*)
@@ -1206,7 +1229,7 @@ esac
case "${PRE_WORLD}" in
'') ;;
*)
- MAKE_CONF="${SOURCEDIR%etc}share/examples/etc/make.conf"
+ MAKE_CONF="${SOURCEDIR}/share/examples/etc/make.conf"
(echo ''
echo '*** Comparing make variables'
diff --git a/usr.sbin/mld6query/mld6query.8 b/usr.sbin/mld6query/mld6query.8
index 8ec867f..1516c2e 100644
--- a/usr.sbin/mld6query/mld6query.8
+++ b/usr.sbin/mld6query/mld6query.8
@@ -75,7 +75,7 @@ similarly, MLD report packet will be transmitted.
.Fl dr
options are for debugging purposes only.
.\"
-.Sh RETURN VALUES
+.Sh EXIT STATUS
The program exits with 0 on success, non-zero on failures.
.\"
.\" .Sh SEE ALSO
diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c
index f1b0313..eee5037 100644
--- a/usr.sbin/mtree/create.c
+++ b/usr.sbin/mtree/create.c
@@ -212,7 +212,7 @@ statf(int indent, FTSENT *p)
output(indent, &offset, "size=%jd",
(intmax_t)p->fts_statp->st_size);
if (keys & F_TIME)
- output(indent, &offset, "time=%ld.%ld",
+ output(indent, &offset, "time=%ld.%09ld",
(long)p->fts_statp->st_mtimespec.tv_sec,
p->fts_statp->st_mtimespec.tv_nsec);
if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
diff --git a/usr.sbin/mtree/mtree.5 b/usr.sbin/mtree/mtree.5
index db54943..375cc78 100644
--- a/usr.sbin/mtree/mtree.5
+++ b/usr.sbin/mtree/mtree.5
@@ -200,7 +200,9 @@ The size, in bytes, of the file.
.It Cm link
The file the symbolic link is expected to reference.
.It Cm time
-The last modification time of the file.
+The last modification time of the file, in seconds and nanoseconds.
+The value should include a period character and exactly nine digits
+after the period.
.It Cm type
The type of the file; may be set to any one of the following:
.Pp
diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8
index 439eaab..f0a93ed 100644
--- a/usr.sbin/mtree/mtree.8
+++ b/usr.sbin/mtree/mtree.8
@@ -233,7 +233,9 @@ The size, in bytes, of the file.
.It Cm link
The file the symbolic link is expected to reference.
.It Cm time
-The last modification time of the file.
+The last modification time of the file, in seconds and nanoseconds.
+The value should include a period character and exactly nine digits
+after the period.
.It Cm type
The type of the file; may be set to any one of the following:
.Pp
diff --git a/usr.sbin/mtree/spec.c b/usr.sbin/mtree/spec.c
index cb86f94..c7c6460 100644
--- a/usr.sbin/mtree/spec.c
+++ b/usr.sbin/mtree/spec.c
@@ -254,14 +254,17 @@ set(char *t, NODE *ip)
break;
case F_TIME:
ip->st_mtimespec.tv_sec = strtoul(val, &ep, 10);
- if (*ep != '.')
- errx(1, "line %d: invalid time %s",
- lineno, val);
- val = ep + 1;
- ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
+ if (*ep == '.') {
+ /* Note: we require exactly nine
+ * digits after the decimal point. */
+ val = ep + 1;
+ ip->st_mtimespec.tv_nsec
+ = strtoul(val, &ep, 10);
+ } else
+ ip->st_mtimespec.tv_nsec = 0;
if (*ep)
errx(1, "line %d: invalid time %s",
- lineno, val);
+ lineno, val);
break;
case F_TYPE:
switch(*val) {
diff --git a/usr.sbin/pciconf/pciconf.8 b/usr.sbin/pciconf/pciconf.8
index 64d2f21..7492b5d 100644
--- a/usr.sbin/pciconf/pciconf.8
+++ b/usr.sbin/pciconf/pciconf.8
@@ -33,7 +33,7 @@
.Nd diagnostic utility for the PCI bus
.Sh SYNOPSIS
.Nm
-.Fl l Op Fl cv
+.Fl l Op Fl bcv
.Nm
.Fl a Ar selector
.Nm
@@ -112,6 +112,32 @@ device, which contains several (similar or independent) functions on
one chip.
.Pp
If the
+.Fl b
+option is supplied,
+.Nm
+will list any base address registers
+.Pq BARs
+that are assigned resources for each device.
+Each BAR will be enumerated via a line in the following format:
+.Bd -literal
+ bar [10] = type Memory, range 32, base 0xda060000, size 131072, enabled
+.Ed
+.Pp
+The first value after the
+.Dq Li bar
+prefix in the square brackets is the offset of the BAR in config space in
+hexadecimal.
+The type of a BAR is one of
+.Dq Memory ,
+.Dq Prefetchable Memory ,
+or
+.Dq I/O Port .
+The range indicates the maximum address the BAR decodes.
+The base and size indicate the start and length of the BAR's address window,
+respectively.
+Finally, the last flag indicates if the BAR is enabled or disabled.
+.Pp
+If the
.Fl c
option is supplied,
.Nm
diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c
index 4234a84..7d1da2d 100644
--- a/usr.sbin/pciconf/pciconf.c
+++ b/usr.sbin/pciconf/pciconf.c
@@ -37,6 +37,7 @@ static const char rcsid[] =
#include <ctype.h>
#include <err.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -66,7 +67,8 @@ struct pci_vendor_info
TAILQ_HEAD(,pci_vendor_info) pci_vendors;
-static void list_devs(int verbose, int caps);
+static void list_bars(int fd, struct pci_conf *p);
+static void list_devs(int verbose, int bars, int caps);
static void list_verbose(struct pci_conf *p);
static const char *guess_class(struct pci_conf *p);
static const char *guess_subclass(struct pci_conf *p);
@@ -81,7 +83,7 @@ static void
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n",
- "usage: pciconf -l [-cv]",
+ "usage: pciconf -l [-bcv]",
" pciconf -a selector",
" pciconf -r [-b | -h] selector addr[:addr2]",
" pciconf -w [-b | -h] selector addr value");
@@ -92,10 +94,10 @@ int
main(int argc, char **argv)
{
int c;
- int listmode, readmode, writemode, attachedmode, caps, verbose;
+ int listmode, readmode, writemode, attachedmode, bars, caps, verbose;
int byte, isshort;
- listmode = readmode = writemode = attachedmode = caps = verbose = byte = isshort = 0;
+ listmode = readmode = writemode = attachedmode = bars = caps = verbose = byte = isshort = 0;
while ((c = getopt(argc, argv, "abchlrwv")) != -1) {
switch(c) {
@@ -104,6 +106,7 @@ main(int argc, char **argv)
break;
case 'b':
+ bars = 1;
byte = 1;
break;
@@ -143,7 +146,7 @@ main(int argc, char **argv)
usage();
if (listmode) {
- list_devs(verbose, caps);
+ list_devs(verbose, bars, caps);
} else if (attachedmode) {
chkattached(argv[optind],
byte ? 1 : isshort ? 2 : 4);
@@ -161,7 +164,7 @@ main(int argc, char **argv)
}
static void
-list_devs(int verbose, int caps)
+list_devs(int verbose, int bars, int caps)
{
int fd;
struct pci_conf_io pc;
@@ -217,6 +220,8 @@ list_devs(int verbose, int caps)
p->pc_revid, p->pc_hdr);
if (verbose)
list_verbose(p);
+ if (bars)
+ list_bars(fd, p);
if (caps)
list_caps(fd, p);
}
@@ -226,6 +231,64 @@ list_devs(int verbose, int caps)
}
static void
+list_bars(int fd, struct pci_conf *p)
+{
+ struct pci_bar_io bar;
+ uint64_t base;
+ const char *type;
+ int i, range, max;
+
+ switch (p->pc_hdr & PCIM_HDRTYPE) {
+ case PCIM_HDRTYPE_NORMAL:
+ max = PCIR_MAX_BAR_0;
+ break;
+ case PCIM_HDRTYPE_BRIDGE:
+ max = PCIR_MAX_BAR_1;
+ break;
+ case PCIM_HDRTYPE_CARDBUS:
+ max = PCIR_MAX_BAR_2;
+ break;
+ default:
+ return;
+ }
+
+ for (i = 0; i <= max; i++) {
+ bar.pbi_sel = p->pc_sel;
+ bar.pbi_reg = PCIR_BAR(i);
+ if (ioctl(fd, PCIOCGETBAR, &bar) < 0)
+ continue;
+ if (PCI_BAR_IO(bar.pbi_base)) {
+ type = "I/O Port";
+ range = 32;
+ base = bar.pbi_base & PCIM_BAR_IO_BASE;
+ } else {
+ if (bar.pbi_base & PCIM_BAR_MEM_PREFETCH)
+ type = "Prefetchable Memory";
+ else
+ type = "Memory";
+ switch (bar.pbi_base & PCIM_BAR_MEM_TYPE) {
+ case PCIM_BAR_MEM_32:
+ range = 32;
+ break;
+ case PCIM_BAR_MEM_1MB:
+ range = 20;
+ break;
+ case PCIM_BAR_MEM_64:
+ range = 64;
+ break;
+ default:
+ range = -1;
+ }
+ base = bar.pbi_base & ~((uint64_t)0xf);
+ }
+ printf(" bar [%02x] = type %s, range %2d, base %#jx, ",
+ PCIR_BAR(i), type, range, (uintmax_t)base);
+ printf("size %2d, %s\n", (int)bar.pbi_length,
+ bar.pbi_enabled ? "enabled" : "disabled");
+ }
+}
+
+static void
list_verbose(struct pci_conf *p)
{
struct pci_vendor_info *vi;
diff --git a/usr.sbin/pkg_install/add/pkg_add.1 b/usr.sbin/pkg_install/add/pkg_add.1
index 8194758..d090cb5 100644
--- a/usr.sbin/pkg_install/add/pkg_add.1
+++ b/usr.sbin/pkg_install/add/pkg_add.1
@@ -15,7 +15,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 30, 2008
+.Dd January 4, 2009
.Dt PKG_ADD 1
.Os
.Sh NAME
@@ -90,7 +90,7 @@ if it is defined or in current directory by default.
.It Fl i , -no-deps
Install the package without fetching and installing
dependencies.
-.It Fl I , -no-scripts
+.It Fl I , -no-script
If any installation scripts (pre-install or post-install) exist for a given
package, do not execute them.
.It Fl n , -dry-run
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index 5f66a3a..422912e 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -105,7 +105,7 @@
* Version of the package tools - increase only when some
* functionality used by bsd.port.mk is changed, added or removed
*/
-#define PKG_INSTALL_VERSION 20081227
+#define PKG_INSTALL_VERSION 20090106
#define PKG_WRAPCONF_FNAME "/var/db/pkg_install.conf"
#define main(argc, argv) real_main(argc, argv)
diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c
index 8cb33aa..283b87f 100644
--- a/usr.sbin/pkg_install/lib/plist.c
+++ b/usr.sbin/pkg_install/lib/plist.c
@@ -544,82 +544,45 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
int
delete_hierarchy(const char *dir, Boolean ign_err, Boolean nukedirs)
{
- char *cp1, *cp2, realdir[FILENAME_MAX];
+ char *cp1, *cp2;
- if (realdir == NULL) {
- warnx("Couldn't allocate enough memory\n");
- return (ign_err ? SUCCESS : FAIL);
- }
-
- if (issymlink(dir) && readlink(dir, realdir, FILENAME_MAX-1) == -1)
- return (ign_err ? SUCCESS : FAIL);
-
- strlcpy(realdir, dir, FILENAME_MAX-1);
-
- cp1 = cp2 = strdup(realdir);
- if (cp1 == NULL) {
- warnx("Couldn't allocate enough memory\n");
- return (ign_err ? SUCCESS : FAIL);
- }
-
- if (!fexists(realdir)) {
+ cp1 = cp2 = strdup(dir);
+ if (!fexists(dir)) {
if (!ign_err)
warnx("%s '%s' doesn't exist",
- isdir(realdir) ? "directory" : "file", realdir);
- free(cp1);
- return (ign_err ? SUCCESS : FAIL);
+ isdir(dir) ? "directory" : "file", dir);
+ return !ign_err;
}
else if (nukedirs) {
- if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), realdir)) {
- free(cp1);
- return (ign_err ? SUCCESS : FAIL);
- }
+ if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
+ return 1;
}
- else if (isdir(realdir)) {
- if (RMDIR(realdir)) {
- free(cp1);
- return (ign_err ? SUCCESS : FAIL);
- }
+ else if (isdir(dir) && !issymlink(dir)) {
+ if (RMDIR(dir) && !ign_err)
+ return 1;
}
else {
- if (REMOVE(realdir, ign_err)) {
- free(cp1);
- return (ign_err ? SUCCESS : FAIL);
- }
+ if (REMOVE(dir, ign_err))
+ return 1;
}
- if (!nukedirs) {
- free(cp1);
- return (SUCCESS);
- }
+ if (!nukedirs)
+ return 0;
while (cp2) {
if ((cp2 = strrchr(cp1, '/')) != NULL)
*cp2 = '\0';
- if (!isemptydir(realdir)) {
- free(cp1);
- return (SUCCESS);
- }
- if (RMDIR(realdir) && !ign_err) {
- if (!fexists(realdir)) {
- warnx("directory '%s' doesn't exist", realdir);
- free(cp1);
- return (SUCCESS);
- } else {
- free(cp1);
- return (FAIL);
- }
+ if (!isemptydir(dir))
+ return 0;
+ if (RMDIR(dir) && !ign_err) {
+ if (!fexists(dir))
+ warnx("directory '%s' doesn't exist", dir);
+ else
+ return 1;
}
/* back up the pathname one component */
if (cp2) {
- free(cp1);
- cp1 = strdup(realdir);
- if (cp1 == NULL) {
- warnx("Couldn't allocate enough memory\n");
- return (ign_err ? SUCCESS : FAIL);
- }
+ cp1 = strdup(dir);
}
}
- free(cp1);
- return (SUCCESS);
+ return 0;
}
-
diff --git a/usr.sbin/pstat/pstat.8 b/usr.sbin/pstat/pstat.8
index 5474f8b..b92abd8 100644
--- a/usr.sbin/pstat/pstat.8
+++ b/usr.sbin/pstat/pstat.8
@@ -183,6 +183,8 @@ init/lock-state device nodes present
callout device nodes present
.It O
opened
+.It c
+console in use
.It G
gone
.It B
diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c
index a33bd0a..2cb52fe 100644
--- a/usr.sbin/pstat/pstat.c
+++ b/usr.sbin/pstat/pstat.c
@@ -288,33 +288,34 @@ static struct {
char val;
} ttystates[] = {
#if 0
- { TF_NOPREFIX, 'N' },
+ { TF_NOPREFIX, 'N' },
#endif
- { TF_INITLOCK, 'I' },
- { TF_CALLOUT, 'C' },
+ { TF_INITLOCK, 'I' },
+ { TF_CALLOUT, 'C' },
/* Keep these together -> 'Oi' and 'Oo'. */
- { TF_OPENED, 'O' },
- { TF_OPENED_IN, 'i' },
- { TF_OPENED_OUT,'o' },
+ { TF_OPENED, 'O' },
+ { TF_OPENED_IN, 'i' },
+ { TF_OPENED_OUT, 'o' },
+ { TF_OPENED_CONS, 'c' },
- { TF_GONE, 'G' },
- { TF_OPENCLOSE, 'B' },
- { TF_ASYNC, 'Y' },
- { TF_LITERAL, 'L' },
+ { TF_GONE, 'G' },
+ { TF_OPENCLOSE, 'B' },
+ { TF_ASYNC, 'Y' },
+ { TF_LITERAL, 'L' },
/* Keep these together -> 'Hi' and 'Ho'. */
- { TF_HIWAT, 'H' },
- { TF_HIWAT_IN, 'i' },
- { TF_HIWAT_OUT, 'o' },
+ { TF_HIWAT, 'H' },
+ { TF_HIWAT_IN, 'i' },
+ { TF_HIWAT_OUT, 'o' },
- { TF_STOPPED, 'S' },
- { TF_EXCLUDE, 'X' },
- { TF_BYPASS, 'l' },
- { TF_ZOMBIE, 'Z' },
- { TF_HOOK, 's' },
+ { TF_STOPPED, 'S' },
+ { TF_EXCLUDE, 'X' },
+ { TF_BYPASS, 'l' },
+ { TF_ZOMBIE, 'Z' },
+ { TF_HOOK, 's' },
- { 0, '\0' },
+ { 0, '\0'},
};
static void
diff --git a/usr.sbin/rrenumd/rrenumd.8 b/usr.sbin/rrenumd/rrenumd.8
index 887c0e6..cc13a01 100644
--- a/usr.sbin/rrenumd/rrenumd.8
+++ b/usr.sbin/rrenumd/rrenumd.8
@@ -82,7 +82,7 @@ Configuration information is obtained from standard input.
.It Fl c Ar conf_file
Specify a configuration file where configuration information is kept.
.El
-.Sh RETURN VALUES
+.Sh EXIT STATUS
The program exits with 0 on success, and non-zero on failures.
.Sh SEE ALSO
.Xr rrenumd.conf 5 ,
diff --git a/usr.sbin/rtadvd/rtadvd.8 b/usr.sbin/rtadvd/rtadvd.8
index d5c7061..b2c0aad 100644
--- a/usr.sbin/rtadvd/rtadvd.8
+++ b/usr.sbin/rtadvd/rtadvd.8
@@ -162,10 +162,8 @@ In this case,
will transmit router advertisement with router lifetime 0
to all the interfaces
.Pq in accordance with RFC2461 6.2.5 .
-.Sh RETURN VALUES
-The
-.Nm
-program exits 0 on success, and >0 on failures.
+.Sh EXIT STATUS
+.Ex -std
.Sh FILES
.Bl -tag -width Pa -compact
.It Pa /etc/rtadvd.conf
diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8
index d6ab3d8..1ee932d 100644
--- a/usr.sbin/rtsold/rtsold.8
+++ b/usr.sbin/rtsold/rtsold.8
@@ -220,10 +220,8 @@ must be the absolute path from root to the script file, be a regular
file, and be created by the same owner who runs
.Nm .
.El
-.Sh RETURN VALUES
-The
-.Nm
-program exits 0 on success, and >0 on failures.
+.Sh EXIT STATUS
+.Ex -std
.\"
.Sh FILES
.Bl -tag -width /var/run/rtsold.dump -compact
diff --git a/usr.sbin/sade/disks.c b/usr.sbin/sade/disks.c
index 9a9048b..b802e12 100644
--- a/usr.sbin/sade/disks.c
+++ b/usr.sbin/sade/disks.c
@@ -103,6 +103,46 @@ record_chunks(Disk *d)
static daddr_t Total;
static void
+check_geometry(Disk *d)
+{
+ int sg;
+
+#ifdef PC98
+ if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
+#else
+ if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
+#endif
+ {
+ dialog_clear_norefresh();
+ sg = msgYesNo("WARNING: It is safe to use a geometry of %lu/%lu/%lu for %s on\n"
+ "computers with modern BIOS versions. If this disk is to be used\n"
+ "on an old machine it is recommended that it does not have more\n"
+ "than 65535 cylinders, more than 255 heads, or more than\n"
+#ifdef PC98
+ "255"
+#else
+ "63"
+#endif
+ " sectors per track.\n"
+ "\n"
+ "Would you like to keep using the current geometry?\n",
+ d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
+ if (sg == 1) {
+ Sanitize_Bios_Geom(d);
+ msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
+ "\n"
+ "If you are not sure about this, please consult the Hardware Guide\n"
+ "in the Documentation submenu or use the (G)eometry command to\n"
+ "change it. Remember: you need to enter whatever your BIOS thinks\n"
+ "the geometry is! For IDE, it's what you were told in the BIOS\n"
+ "setup. For SCSI, it's the translation mode your controller is\n"
+ "using. Do NOT use a ``physical geometry''.\n",
+ d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
+ }
+ }
+}
+
+static void
print_chunks(Disk *d, int u)
{
int row;
@@ -116,26 +156,6 @@ print_chunks(Disk *d, int u)
Total = 0;
for (i = 0; chunk_info[i]; i++)
Total += chunk_info[i]->size;
-#ifdef PC98
- if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
-#else
- if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
-#endif
- dialog_clear_norefresh();
- msgConfirm("WARNING: A geometry of %lu/%lu/%lu for %s is incorrect. Using\n"
- "a more likely geometry. If this geometry is incorrect or you\n"
- "are unsure as to whether or not it's correct, please consult\n"
- "the Hardware Guide in the Documentation submenu or use the\n"
- "(G)eometry command to change it now.\n\n"
- "Remember: you need to enter whatever your BIOS thinks the\n"
- "geometry is! For IDE, it's what you were told in the BIOS\n"
- "setup. For SCSI, it's the translation mode your controller is\n"
- "using. Do NOT use a ``physical geometry''.",
- d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
- Sanitize_Bios_Geom(d);
- msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
- d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
- }
attrset(A_NORMAL);
mvaddstr(0, 0, "Disk name:\t");
clrtobot();
@@ -339,6 +359,9 @@ diskPartition(Device *dev)
/* Set up the chunk array */
record_chunks(d);
+ /* Give the user a chance to sanitize the disk geometry, if necessary */
+ check_geometry(d);
+
while (chunking) {
char *val, geometry[80];
@@ -909,22 +932,25 @@ diskPartitionNonInteractive(Device *dev)
record_chunks(d);
cp = variable_get(VAR_GEOMETRY);
if (cp) {
- msgDebug("Setting geometry from script to: %s\n", cp);
- d->bios_cyl = strtol(cp, &cp, 0);
- d->bios_hd = strtol(cp + 1, &cp, 0);
- d->bios_sect = strtol(cp + 1, 0, 0);
- }
-
+ if (!strcasecmp(cp, "sane")) {
#ifdef PC98
- if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
+ if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
#else
- if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
+ if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
#endif
- msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
- d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
- Sanitize_Bios_Geom(d);
- msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
- d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
+ {
+ msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
+ d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
+ Sanitize_Bios_Geom(d);
+ msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
+ d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
+ }
+ } else {
+ msgDebug("Setting geometry from script to: %s\n", cp);
+ d->bios_cyl = strtol(cp, &cp, 0);
+ d->bios_hd = strtol(cp + 1, &cp, 0);
+ d->bios_sect = strtol(cp + 1, 0, 0);
+ }
}
cp = variable_get(VAR_PARTITION);
diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c
index f5b16e5..c4438e1 100644
--- a/usr.sbin/sysinstall/devices.c
+++ b/usr.sbin/sysinstall/devices.c
@@ -89,7 +89,7 @@ static struct _devname {
DISK("mfid%d", "LSI MegaRAID SAS array", 4),
FLOPPY("fd%d", "floppy drive unit A", 4),
SERIAL("cuad%d", "%s on device %s (COM%d)", 16),
- NETWORK("ae", "Attansic/Atheros L2 FastEthernet"),
+ NETWORK("ae", "Attansic/Atheros L2 Fast Ethernet"),
NETWORK("age", "Attansic/Atheros L1 Gigabit Ethernet"),
NETWORK("ale", "Atheros AR8121/AR8113/AR8114 PCIe Ethernet"),
NETWORK("an", "Aironet 4500/4800 802.11 wireless adapter"),
@@ -111,14 +111,18 @@ static struct _devname {
NETWORK("ed", "Novell NE1000/2000; 3C503; NE2000-compatible PCMCIA"),
NETWORK("ep", "3Com 3C509 Ethernet card/3C589 PCMCIA"),
NETWORK("em", "Intel(R) PRO/1000 Ethernet card"),
+ NETWORK("et", "Agere ET1310 based PCI Express Gigabit Ethernet card"),
NETWORK("ex", "Intel EtherExpress Pro/10 Ethernet card"),
NETWORK("fe", "Fujitsu MB86960A/MB86965A Ethernet card"),
NETWORK("gem", "Apple GMAC or Sun ERI/GEM Ethernet adapter"),
NETWORK("hme", "Sun HME (Happy Meal Ethernet) Ethernet adapter"),
NETWORK("ie", "AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210"),
+ NETWORK("igb", "Intel(R) PRO/1000 PCI Express Gigabit Ethernet card"),
NETWORK("ipw", "Intel PRO/Wireless 2100 IEEE 802.11 adapter"),
NETWORK("iwi", "Intel PRO/Wireless 2200BG/2225BG/2915ABG adapter"),
+ NETWORK("iwn", "Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapter"),
NETWORK("ixgb", "Intel(R) PRO/10Gb Ethernet card"),
+ NETWORK("ixgbe", "Intel(R) PRO/10Gb Ethernet card"),
NETWORK("jme", "JMicron JMC250 Gigabit/JMC260 Fast Ethernet"),
NETWORK("kue", "Kawasaki LSI USB Ethernet adapter"),
NETWORK("le", "AMD Am7900 LANCE or Am79C9xx PCnet Ethernet adapter"),
@@ -129,6 +133,7 @@ static struct _devname {
NETWORK("nfe", "NVIDIA nForce MCP Ethernet"),
NETWORK("nge", "NatSemi PCI Gigabit Ethernet card"),
NETWORK("nve", "NVIDIA nForce MCP Ethernet"),
+ NETWORK("nxge", "Neterion Xframe 10GbE Server/Storage adapter"),
NETWORK("pcn", "AMD Am79c79x PCI Ethernet card"),
NETWORK("ral", "Ralink Technology IEEE 802.11 wireless adapter"),
NETWORK("ray", "Raytheon Raylink 802.11 wireless adapter"),
@@ -151,6 +156,7 @@ static struct _devname {
NETWORK("tl", "Texas Instruments ThunderLAN PCI Ethernet card"),
NETWORK("upgt", "Conexant/Intersil PrismGT USB wireless adapter"),
NETWORK("ural", "Ralink Technology RT2500USB 802.11 wireless adapter"),
+ NETWORK("urtw", "Realtek 8187L USB wireless adapter"),
NETWORK("vge", "VIA VT612x PCI Gigabit Ethernet card"),
NETWORK("vr", "VIA VT3043/VT86C100A Rhine PCI Ethernet card"),
NETWORK("vlan", "IEEE 802.1Q VLAN network interface"),
diff --git a/usr.sbin/sysinstall/disks.c b/usr.sbin/sysinstall/disks.c
index 576eeff..ba7bbff 100644
--- a/usr.sbin/sysinstall/disks.c
+++ b/usr.sbin/sysinstall/disks.c
@@ -106,6 +106,46 @@ record_chunks(Disk *d)
static daddr_t Total;
static void
+check_geometry(Disk *d)
+{
+ int sg;
+
+#ifdef PC98
+ if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
+#else
+ if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
+#endif
+ {
+ dialog_clear_norefresh();
+ sg = msgYesNo("WARNING: It is safe to use a geometry of %lu/%lu/%lu for %s on\n"
+ "computers with modern BIOS versions. If this disk is to be used\n"
+ "on an old machine it is recommended that it does not have more\n"
+ "than 65535 cylinders, more than 255 heads, or more than\n"
+#ifdef PC98
+ "255"
+#else
+ "63"
+#endif
+ " sectors per track.\n"
+ "\n"
+ "Would you like to keep using the current geometry?\n",
+ d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
+ if (sg == 1) {
+ Sanitize_Bios_Geom(d);
+ msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
+ "\n"
+ "If you are not sure about this, please consult the Hardware Guide\n"
+ "in the Documentation submenu or use the (G)eometry command to\n"
+ "change it. Remember: you need to enter whatever your BIOS thinks\n"
+ "the geometry is! For IDE, it's what you were told in the BIOS\n"
+ "setup. For SCSI, it's the translation mode your controller is\n"
+ "using. Do NOT use a ``physical geometry''.\n",
+ d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
+ }
+ }
+}
+
+static void
print_chunks(Disk *d, int u)
{
int row;
@@ -119,24 +159,6 @@ print_chunks(Disk *d, int u)
Total = 0;
for (i = 0; chunk_info[i]; i++)
Total += chunk_info[i]->size;
-#ifdef PC98
- if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
-#else
- if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
-#endif
- dialog_clear_norefresh();
- msgConfirm("WARNING: A geometry of %lu/%lu/%lu for %s is incorrect. Using\n"
- "a more likely geometry. If this geometry is incorrect or you\n"
- "are unsure as to whether or not it's correct, please consult\n"
- "the Hardware Guide in the Documentation submenu or use the\n"
- "(G)eometry command to change it now.\n\n"
- "Remember: you need to enter whatever your BIOS thinks the\n"
- "geometry is! For IDE, it's what you were told in the BIOS\n"
- "setup. For SCSI, it's the translation mode your controller is\n"
- "using. Do NOT use a ``physical geometry''.",
- d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
- Sanitize_Bios_Geom(d);
- }
attrset(A_NORMAL);
mvaddstr(0, 0, "Disk name:\t");
clrtobot();
@@ -341,6 +363,9 @@ diskPartition(Device *dev)
/* Set up the chunk array */
record_chunks(d);
+ /* Give the user a chance to sanitize the disk geometry, if necessary */
+ check_geometry(d);
+
while (chunking) {
char *val, geometry[80];
@@ -916,21 +941,24 @@ diskPartitionNonInteractive(Device *dev)
record_chunks(d);
cp = variable_get(VAR_GEOMETRY);
if (cp) {
- msgDebug("Setting geometry from script to: %s\n", cp);
- d->bios_cyl = strtol(cp, &cp, 0);
- d->bios_hd = strtol(cp + 1, &cp, 0);
- d->bios_sect = strtol(cp + 1, 0, 0);
- } else {
+ if (!strcasecmp(cp, "sane")) {
#ifdef PC98
- if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
+ if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
#else
- if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
+ if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
#endif
- msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
- d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
- Sanitize_Bios_Geom(d);
- msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
- d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
+ {
+ msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
+ d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
+ Sanitize_Bios_Geom(d);
+ msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
+ d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
+ }
+ } else {
+ msgDebug("Setting geometry from script to: %s\n", cp);
+ d->bios_cyl = strtol(cp, &cp, 0);
+ d->bios_hd = strtol(cp + 1, &cp, 0);
+ d->bios_sect = strtol(cp + 1, 0, 0);
}
}
diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
index 7cec25a..ae09392 100644
--- a/usr.sbin/sysinstall/menus.c
+++ b/usr.sbin/sysinstall/menus.c
@@ -1074,21 +1074,24 @@ 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"
+ "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",
"drives",
- { { "BootMgr", "Install the FreeBSD Boot Manager",
- dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr },
- { "Standard", "Install a standard MBR (no boot manager)",
+ { { "Standard", "Install a standard MBR (no 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",
dmenuRadioCheck, dmenuSetValue, NULL, &BootMgr, '(', '*', ')', 2 },
{ NULL } },
diff --git a/usr.sbin/sysinstall/sysinstall.8 b/usr.sbin/sysinstall/sysinstall.8
index 3a9a20a..ab1cc12 100644
--- a/usr.sbin/sysinstall/sysinstall.8
+++ b/usr.sbin/sysinstall/sysinstall.8
@@ -249,6 +249,12 @@ Invokes the disk partition (MBR) editor.
.Bl -tag -width findx
.It geometry
The disk geometry, as a cyls/heads/sectors formatted string.
+The word "sane" instructs
+.Nm
+to calculate a safe (not necessarily optimal) geometry if the
+current one has more than 65535 cylinders, more than 256 heads or
+more than 63 sectors per track (255 sectors on the PC98
+architecture).
Default: no
change to geometry.
.It partition
diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8
index 6e178c6..b6116f0 100644
--- a/usr.sbin/traceroute6/traceroute6.8
+++ b/usr.sbin/traceroute6/traceroute6.8
@@ -162,7 +162,7 @@ This was more interesting in the IPv4 case,
where some IP stack bugs could be identified by this behaviour.
.El
.\"
-.Sh RETURN VALUES
+.Sh EXIT STATUS
The
.Nm
utility will exit with 0 on success, and non-zero on errors.
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
index 5aa9102..e0f03dd 100644
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -327,7 +327,7 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
opt->got_power_save +
opt->got_power_on +
opt->got_power_off) > 1) {
- err(1, "cannot only specify one of 'set_config', "
+ err(1, "can only specify one of 'set_config', "
"'set_alt', 'reset', 'suspend', 'resume', "
"'power_save', 'power_on' and 'power_off' "
"at the same time!");
@@ -562,7 +562,7 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
}
if (matches == 0) {
- printf("No device match\n");
+ printf("No device match or lack of permissions.\n");
}
done:
reset_options(opt);
diff --git a/usr.sbin/usbdevs/usbdevs.c b/usr.sbin/usbdevs/usbdevs.c
index 640dd51..eea8167 100644
--- a/usr.sbin/usbdevs/usbdevs.c
+++ b/usr.sbin/usbdevs/usbdevs.c
@@ -65,7 +65,7 @@ int main(int, char **);
void
usage()
{
- fprintf(stderr, "usage: %s [-a addr] [-d] [-f dev] [-v]\n",
+ fprintf(stderr, "usage: %s [-a addr] [-d] [-f dev] [-o] [-v]\n",
getprogname());
exit(1);
}
diff --git a/usr.sbin/wlandebug/wlandebug.c b/usr.sbin/wlandebug/wlandebug.c
index c421cf8..b342875 100644
--- a/usr.sbin/wlandebug/wlandebug.c
+++ b/usr.sbin/wlandebug/wlandebug.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -77,7 +77,7 @@ const char *progname;
#define IEEE80211_MSG_ACTION 0x00000010 /* action frame handling */
#define IEEE80211_MSG_WDS 0x00000008 /* WDS handling */
#define IEEE80211_MSG_IOCTL 0x00000004 /* ioctl handling */
-#define IEEE80211_MSG_ADDBA 0x00000002 /* ADDBA handling */
+#define IEEE80211_MSG_TDMA 0x00000002 /* TDMA handling */
static struct {
const char *name;
@@ -113,7 +113,7 @@ static struct {
{ "action", IEEE80211_MSG_ACTION },
{ "wds", IEEE80211_MSG_WDS },
{ "ioctl", IEEE80211_MSG_IOCTL },
- { "addba", IEEE80211_MSG_ADDBA },
+ { "tdma", IEEE80211_MSG_TDMA },
};
static u_int
OpenPOWER on IntegriCloud